summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn H Terpstra <jht@samba.org>2009-07-23 09:33:06 -0500
committerJohn H Terpstra <jht@samba.org>2009-07-23 09:33:06 -0500
commit94717ae8e5dfe2ccdb7f3557d5490708b00ae471 (patch)
treea39f669faf23ad05497963cf5ccf611467d0145b
parent14952c72a29ec92badb1bcf16d2a15fe100f060d (diff)
parent7bad4b48c82fed4263c2bfe97a4d00b47913604a (diff)
downloadsamba-94717ae8e5dfe2ccdb7f3557d5490708b00ae471.tar.gz
samba-94717ae8e5dfe2ccdb7f3557d5490708b00ae471.tar.bz2
samba-94717ae8e5dfe2ccdb7f3557d5490708b00ae471.zip
Merge branch 'master' of ssh://jht@git.samba.org/data/git/samba
-rw-r--r--Roadmap2
-rw-r--r--WHATSNEW.txt35
-rw-r--r--client/cifs.upcall.c87
-rw-r--r--examples/LDAP/samba-schema-FDS.ldif8
-rwxr-xr-xexamples/VFS/config.guess152
-rwxr-xr-xexamples/VFS/config.sub205
-rw-r--r--lib/replace/libreplace.m41
-rw-r--r--lib/replace/replace.h4
-rw-r--r--lib/tdb/common/lock.c17
-rw-r--r--lib/tdb/common/tdb_private.h2
-rw-r--r--lib/tdb/common/traverse.c22
-rw-r--r--lib/tevent/testsuite.c12
-rw-r--r--lib/tevent/tevent_req.c2
-rw-r--r--lib/torture/torture.c8
-rw-r--r--lib/torture/torture.h3
-rw-r--r--lib/tsocket/tsocket_bsd.c42
-rw-r--r--lib/util/genrand.c3
-rw-r--r--lib/util/tests/genrand.c2
-rw-r--r--lib/util/util_file.c1
-rw-r--r--libcli/security/secacl.c2
-rw-r--r--libds/common/flag_mapping.c (renamed from source4/dsdb/common/flag_mapping.c)44
-rw-r--r--libds/common/flags.h (renamed from source4/dsdb/common/flags.h)98
-rw-r--r--librpc/gen_ndr/cli_lsa.c17
-rw-r--r--librpc/gen_ndr/cli_lsa.h10
-rw-r--r--librpc/gen_ndr/cli_spoolss.c9
-rw-r--r--librpc/gen_ndr/cli_spoolss.h4
-rw-r--r--librpc/gen_ndr/lsa.h19
-rw-r--r--librpc/gen_ndr/ndr_lsa.c175
-rw-r--r--librpc/gen_ndr/ndr_samr.c2
-rw-r--r--librpc/gen_ndr/ndr_spoolss.c116
-rw-r--r--librpc/gen_ndr/samr.h6
-rw-r--r--librpc/gen_ndr/spoolss.h22
-rw-r--r--librpc/gen_ndr/srv_lsa.c4
-rw-r--r--librpc/gen_ndr/srv_spoolss.c17
-rw-r--r--librpc/idl/frsapi.idl23
-rw-r--r--librpc/idl/frsrpc.idl425
-rw-r--r--librpc/idl/frstrans.idl83
-rw-r--r--librpc/idl/lsa.idl18
-rw-r--r--librpc/idl/samr.idl4
-rw-r--r--librpc/idl/spoolss.idl19
-rw-r--r--librpc/ndr/ndr_frsrpc.c94
-rw-r--r--librpc/ndr/ndr_frsrpc.h35
-rw-r--r--librpc/ndr_standard.pc.in11
-rw-r--r--nsswitch/pam_winbind.c40
-rw-r--r--pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm14
-rw-r--r--pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm11
-rw-r--r--pidl/lib/Parse/Pidl/Samba4/Python.pm30
-rw-r--r--pidl/lib/Parse/Pidl/Typelist.pm7
-rw-r--r--source3/Makefile.in22
-rw-r--r--source3/auth/auth.c10
-rw-r--r--source3/auth/auth_sam.c5
-rw-r--r--source3/client/client.c4
-rw-r--r--source3/include/ads.h127
-rw-r--r--source3/include/passdb.h22
-rw-r--r--source3/include/proto.h185
-rw-r--r--source3/include/smb.h16
-rw-r--r--source3/include/smb_macros.h1
-rw-r--r--source3/include/util_tdb.h2
-rw-r--r--source3/lib/account_pol.c148
-rw-r--r--source3/lib/ads_flags.c150
-rw-r--r--source3/lib/charcnv.c8
-rw-r--r--source3/lib/ctdbd_conn.c2
-rw-r--r--source3/lib/dbwrap_tdb.c2
-rw-r--r--source3/lib/dbwrap_util.c173
-rw-r--r--source3/lib/errmap_unix.c1
-rw-r--r--source3/lib/events.c2
-rw-r--r--source3/lib/gencache.c529
-rw-r--r--source3/lib/ldap_escape.c25
-rw-r--r--source3/lib/netapi/netapi.c1
-rw-r--r--source3/lib/netapi/user.c2
-rw-r--r--source3/lib/smbldap_util.c12
-rw-r--r--source3/lib/system.c4
-rw-r--r--source3/lib/tldap.c6
-rw-r--r--source3/lib/util_sock.c3
-rw-r--r--source3/lib/util_str.c36
-rw-r--r--source3/lib/util_tdb.c19
-rw-r--r--source3/libads/dns.c8
-rw-r--r--source3/libads/ldap_user.c6
-rw-r--r--source3/libnet/libnet_samsync_passdb.c23
-rw-r--r--source3/libsmb/clidgram.c3
-rw-r--r--source3/libsmb/clifile.c543
-rw-r--r--source3/libsmb/clikrb5.c4
-rw-r--r--source3/libsmb/clispnego.c18
-rw-r--r--source3/libsmb/dsgetdcname.c33
-rw-r--r--source3/libsmb/libsmb_context.c1
-rw-r--r--source3/libsmb/libsmb_thread_posix.c2
-rw-r--r--source3/libsmb/namecache.c34
-rw-r--r--source3/libsmb/namequery.c12
-rw-r--r--source3/libsmb/spnego.c23
-rw-r--r--source3/libsmb/trustdom_cache.c67
-rw-r--r--source3/locking/brlock.c4
-rw-r--r--source3/locking/locking.c29
-rw-r--r--source3/locking/posix.c37
-rw-r--r--source3/modules/nfs4_acls.c34
-rw-r--r--source3/modules/onefs_acl.c51
-rw-r--r--source3/modules/onefs_open.c18
-rw-r--r--source3/modules/onefs_streams.c10
-rw-r--r--source3/modules/vfs_acl_tdb.c98
-rw-r--r--source3/modules/vfs_acl_xattr.c263
-rw-r--r--source3/modules/vfs_afsacl.c35
-rw-r--r--source3/modules/vfs_aixacl2.c16
-rw-r--r--source3/modules/vfs_audit.c4
-rw-r--r--source3/modules/vfs_cacheprime.c2
-rw-r--r--source3/modules/vfs_cap.c10
-rw-r--r--source3/modules/vfs_catia.c3
-rw-r--r--source3/modules/vfs_default.c67
-rw-r--r--source3/modules/vfs_dirsort.c3
-rw-r--r--source3/modules/vfs_extd_audit.c8
-rw-r--r--source3/modules/vfs_full_audit.c97
-rw-r--r--source3/modules/vfs_gpfs.c38
-rw-r--r--source3/modules/vfs_hpuxacl.c20
-rw-r--r--source3/modules/vfs_hpuxacl.h2
-rw-r--r--source3/modules/vfs_shadow_copy2.c7
-rw-r--r--source3/modules/vfs_smb_traffic_analyzer.c18
-rw-r--r--source3/modules/vfs_streams_xattr.c25
-rw-r--r--source3/modules/vfs_tsmsm.c6
-rw-r--r--source3/modules/vfs_zfsacl.c11
-rw-r--r--source3/nmbd/nmbd.c2
-rw-r--r--source3/param/loadparm.c3
-rw-r--r--source3/passdb/passdb.c16
-rw-r--r--source3/passdb/pdb_ads.c24
-rw-r--r--source3/passdb/pdb_get_set.c6
-rw-r--r--source3/passdb/pdb_interface.c16
-rw-r--r--source3/passdb/pdb_ldap.c119
-rw-r--r--source3/passdb/pdb_wbc_sam.c11
-rw-r--r--source3/printing/printfsp.c10
-rw-r--r--source3/registry/reg_backend_db.c904
-rw-r--r--source3/registry/reg_backend_netlogon_params.c2
-rw-r--r--source3/registry/reg_objects.c29
-rw-r--r--source3/rpc_parse/parse_prs.c318
-rw-r--r--source3/rpc_server/srv_lsa_nt.c287
-rw-r--r--source3/rpc_server/srv_samr_nt.c104
-rw-r--r--source3/rpc_server/srv_samr_util.c2
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c10
-rw-r--r--source3/rpc_server/srv_srvsvc_nt.c12
-rw-r--r--source3/rpcclient/cmd_lsarpc.c366
-rw-r--r--source3/rpcclient/cmd_spoolss.c43
-rwxr-xr-xsource3/script/tests/test_smbtorture_s3.sh4
-rw-r--r--source3/smbd/aio.c28
-rw-r--r--source3/smbd/blocking.c15
-rw-r--r--source3/smbd/chgpasswd.c6
-rw-r--r--source3/smbd/close.c160
-rw-r--r--source3/smbd/dosmode.c6
-rw-r--r--source3/smbd/error.c30
-rw-r--r--source3/smbd/fake_file.c29
-rw-r--r--source3/smbd/file_access.c10
-rw-r--r--source3/smbd/fileio.c58
-rw-r--r--source3/smbd/filename.c502
-rw-r--r--source3/smbd/filename_util.c206
-rw-r--r--source3/smbd/files.c89
-rw-r--r--source3/smbd/globals.c5
-rw-r--r--source3/smbd/globals.h50
-rw-r--r--source3/smbd/ipc.c2
-rw-r--r--source3/smbd/msdfs.c20
-rw-r--r--source3/smbd/notify.c7
-rw-r--r--source3/smbd/nttrans.c173
-rw-r--r--source3/smbd/open.c98
-rw-r--r--source3/smbd/oplock.c24
-rw-r--r--source3/smbd/oplock_irix.c13
-rw-r--r--source3/smbd/oplock_linux.c9
-rw-r--r--source3/smbd/oplock_onefs.c41
-rw-r--r--source3/smbd/password.c37
-rw-r--r--source3/smbd/pipes.c42
-rw-r--r--source3/smbd/posix_acls.c271
-rw-r--r--source3/smbd/process.c5
-rw-r--r--source3/smbd/reply.c776
-rw-r--r--source3/smbd/server.c2
-rw-r--r--source3/smbd/service.c4
-rw-r--r--source3/smbd/sesssetup.c1
-rw-r--r--source3/smbd/smb2_close.c7
-rw-r--r--source3/smbd/smb2_create.c22
-rw-r--r--source3/smbd/smb2_flush.c2
-rw-r--r--source3/smbd/smb2_getinfo.c172
-rw-r--r--source3/smbd/smb2_lock.c180
-rw-r--r--source3/smbd/smb2_notify.c2
-rw-r--r--source3/smbd/smb2_read.c4
-rw-r--r--source3/smbd/smb2_server.c4
-rw-r--r--source3/smbd/smb2_setinfo.c118
-rw-r--r--source3/smbd/smb2_write.c6
-rw-r--r--source3/smbd/statcache.c15
-rw-r--r--source3/smbd/trans2.c1954
-rw-r--r--source3/smbd/vfs.c110
-rw-r--r--source3/torture/cmd_vfs.c13
-rw-r--r--source3/torture/locktest.c4
-rw-r--r--source3/torture/locktest2.c2
-rw-r--r--source3/torture/pdbtest.c6
-rw-r--r--source3/torture/torture.c104
-rw-r--r--source3/utils/net.c45
-rw-r--r--source3/utils/net.h9
-rw-r--r--source3/utils/net_ads.c93
-rw-r--r--source3/utils/net_cache.c27
-rw-r--r--source3/utils/net_dom.c8
-rw-r--r--source3/utils/net_help.c1
-rw-r--r--source3/utils/net_proto.h3
-rw-r--r--source3/utils/net_rpc.c74
-rw-r--r--source3/utils/net_rpc_join.c3
-rw-r--r--source3/utils/net_rpc_samsync.c15
-rw-r--r--source3/utils/net_rpc_shell.c9
-rw-r--r--source3/utils/net_sam.c8
-rw-r--r--source3/utils/net_usershare.c33
-rw-r--r--source3/utils/net_util.c109
-rw-r--r--source3/utils/pdbedit.c2
-rw-r--r--source3/winbindd/winbindd.c2
-rw-r--r--source3/winbindd/winbindd_ads.c8
-rw-r--r--source3/winbindd/winbindd_dual.c4
-rw-r--r--source3/winbindd/winbindd_passdb.c10
-rw-r--r--source3/winbindd/winbindd_sid.c5
-rw-r--r--source3/winbindd/winbindd_util.c3
-rw-r--r--source4/auth/auth.h2
-rw-r--r--source4/auth/gensec/gensec_krb5.c68
-rw-r--r--source4/auth/sam.c42
-rw-r--r--source4/cldap_server/netlogon.c2
-rw-r--r--source4/configure.ac1
-rw-r--r--source4/dsdb/common/sidmap.c6
-rw-r--r--source4/dsdb/common/util.c6
-rw-r--r--source4/dsdb/config.mk4
-rw-r--r--source4/dsdb/samdb/ldb_modules/instancetype.c2
-rw-r--r--source4/dsdb/samdb/ldb_modules/linked_attributes.c11
-rw-r--r--source4/dsdb/samdb/ldb_modules/password_hash.c22
-rw-r--r--source4/dsdb/samdb/ldb_modules/repl_meta_data.c2
-rw-r--r--source4/dsdb/samdb/ldb_modules/rootdse.c140
-rw-r--r--source4/dsdb/samdb/ldb_modules/samldb.c8
-rw-r--r--source4/dsdb/samdb/samdb.c2
-rw-r--r--source4/dsdb/samdb/samdb.h2
-rw-r--r--source4/heimdal/kdc/kaserver.c16
-rw-r--r--source4/heimdal/kdc/kerberos5.c24
-rw-r--r--source4/heimdal/kdc/krb5tgs.c83
-rw-r--r--source4/heimdal/lib/gssapi/gssapi/gssapi.h67
-rw-r--r--source4/heimdal/lib/gssapi/krb5/8003.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/accept_sec_context.c10
-rw-r--r--source4/heimdal/lib/gssapi/krb5/acquire_cred.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/add_cred.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/aeap.c219
-rw-r--r--source4/heimdal/lib/gssapi/krb5/arcfour.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/canonicalize_name.c2
-rwxr-xr-xsource4/heimdal/lib/gssapi/krb5/cfx.c773
-rw-r--r--source4/heimdal/lib/gssapi/krb5/compare_name.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/compat.c3
-rw-r--r--source4/heimdal/lib/gssapi/krb5/context_time.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/copy_ccache.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/decapsulate.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/delete_sec_context.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/display_name.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/display_status.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/duplicate_name.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/encapsulate.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/export_name.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/export_sec_context.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/external.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/get_mic.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/import_name.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/import_sec_context.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/indicate_mechs.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/init.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/init_sec_context.c4
-rw-r--r--source4/heimdal/lib/gssapi/krb5/inquire_context.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/inquire_cred.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c3
-rw-r--r--source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/prf.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/process_context_token.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/release_buffer.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/release_cred.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/release_name.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/sequence.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/set_cred_option.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/unwrap.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/verify_mic.c2
-rw-r--r--source4/heimdal/lib/gssapi/krb5/wrap.c4
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c2
-rw-r--r--source4/heimdal/lib/gssapi/mech/gss_aeap.c58
-rw-r--r--source4/heimdal/lib/gssapi/spnego/accept_sec_context.c66
-rw-r--r--source4/heimdal/lib/hcrypto/des.h10
-rw-r--r--source4/heimdal/lib/hcrypto/evp.h9
-rw-r--r--source4/heimdal/lib/hdb/db.c3
-rw-r--r--source4/heimdal/lib/hdb/dbinfo.c2
-rw-r--r--source4/heimdal/lib/hdb/ext.c2
-rw-r--r--source4/heimdal/lib/hdb/hdb.asn14
-rw-r--r--source4/heimdal/lib/hdb/hdb.c1
-rw-r--r--source4/heimdal/lib/hdb/hdb.h36
-rw-r--r--source4/heimdal/lib/hdb/keys.c2
-rw-r--r--source4/heimdal/lib/hdb/keytab.c87
-rw-r--r--source4/heimdal/lib/hdb/mkey.c2
-rw-r--r--source4/heimdal/lib/hdb/ndbm.c3
-rw-r--r--source4/heimdal/lib/hx509/crypto.c4
-rw-r--r--source4/heimdal/lib/krb5/crypto.c277
-rw-r--r--source4/heimdal/lib/krb5/get_addrs.c2
-rw-r--r--source4/heimdal/lib/krb5/init_creds_pw.c2
-rw-r--r--source4/heimdal/lib/krb5/krb5.h6
-rw-r--r--source4/heimdal/lib/krb5/log.c13
-rw-r--r--source4/heimdal/lib/krb5/store_emem.c7
-rw-r--r--source4/heimdal_build/ifaddrs.hin1
-rw-r--r--source4/heimdal_build/internal.m49
-rw-r--r--source4/heimdal_build/replace.c5
-rw-r--r--source4/heimdal_build/roken.h16
-rw-r--r--source4/kdc/hdb-samba4.c263
-rw-r--r--source4/kdc/pac-glue.c2
-rw-r--r--source4/lib/ldb/common/ldb.c2
-rw-r--r--source4/lib/ldb/common/ldb_debug.c1
-rw-r--r--source4/lib/ldb/common/ldb_ldif.c12
-rw-r--r--source4/lib/ldb/common/ldb_match.c2
-rw-r--r--source4/lib/ldb/common/ldb_modules.c24
-rw-r--r--source4/lib/ldb/ldb.mk7
-rw-r--r--source4/lib/ldb/ldb.pc.in2
-rw-r--r--source4/lib/ldb/ldb_ildap/ldb_ildap.c6
-rw-r--r--source4/lib/ldb/ldb_ldap/ldb_ldap.c6
-rw-r--r--source4/lib/ldb/ldb_map/ldb_map.c16
-rw-r--r--source4/lib/ldb/ldb_map/ldb_map_inbound.c8
-rw-r--r--source4/lib/ldb/ldb_map/ldb_map_outbound.c8
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_cache.c6
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_index.c6
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_pack.c2
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.c2
-rw-r--r--source4/lib/ldb/modules/asq.c2
-rw-r--r--source4/lib/ldb/modules/operational.c4
-rw-r--r--source4/lib/ldb/modules/paged_results.c2
-rw-r--r--source4/lib/ldb/modules/rdn_name.c4
-rw-r--r--source4/lib/ldb/modules/sort.c2
-rw-r--r--source4/lib/ldb/pyldb.c10
-rw-r--r--source4/lib/ldb/pyldb.h1
-rw-r--r--source4/lib/ldb/pyldb_util.c39
-rw-r--r--source4/lib/ldb/python.mk8
-rw-r--r--source4/lib/ldb/rules.mk1
-rw-r--r--source4/lib/registry/patchfile.c1
-rw-r--r--source4/lib/samba3/README3
-rw-r--r--source4/lib/samba3/STATUS68
-rw-r--r--source4/lib/samba3/samba3.h1
-rw-r--r--source4/libcli/security/security_token.c2
-rw-r--r--source4/libcli/smb2/request.c10
-rw-r--r--source4/libcli/smb2/smb2.h1
-rw-r--r--source4/libcli/smb2/transport.c7
-rw-r--r--source4/libnet/libnet_become_dc.c2
-rw-r--r--source4/libnet/libnet_group.c2
-rw-r--r--source4/libnet/libnet_group.h4
-rw-r--r--source4/libnet/libnet_samdump.c1
-rw-r--r--source4/libnet/libnet_unbecome_dc.c2
-rw-r--r--source4/libnet/libnet_user.c2
-rw-r--r--source4/libnet/libnet_user.h4
-rw-r--r--source4/librpc/config.mk166
-rw-r--r--source4/ntptr/simple_ldb/ntptr_simple_ldb.c9
-rw-r--r--source4/ntvfs/ipc/vfs_ipc.c3
-rw-r--r--source4/ntvfs/posix/pvfs_resolve.c5
-rw-r--r--source4/ntvfs/unixuid/vfs_unixuid.c2
-rw-r--r--source4/rpc_server/config.mk12
-rw-r--r--source4/rpc_server/lsa/dcesrv_lsa.c2
-rw-r--r--source4/rpc_server/lsa/lsa_lookup.c4
-rw-r--r--source4/rpc_server/netlogon/dcerpc_netlogon.c18
-rw-r--r--source4/rpc_server/samr/dcesrv_samr.c8
-rw-r--r--source4/rpc_server/samr/samr_password.c2
-rwxr-xr-xsource4/script/installmisc.sh10
-rw-r--r--source4/scripting/python/pyglue.c74
-rw-r--r--source4/scripting/python/samba/__init__.py8
-rw-r--r--source4/scripting/python/samba/getopt.py2
-rw-r--r--source4/scripting/python/samba/idmap.py2
-rw-r--r--source4/scripting/python/samba/ms_schema.py1
-rw-r--r--source4/scripting/python/samba/provision.py27
-rw-r--r--source4/scripting/python/samba/samba3.py4
-rw-r--r--source4/scripting/python/samba/samdb.py8
-rw-r--r--source4/scripting/python/samba/tests/shares.py74
-rw-r--r--source4/scripting/python/samba/upgrade.py9
-rw-r--r--source4/selftest/knownfail1
-rwxr-xr-xsource4/setup/provision4
-rw-r--r--source4/setup/provision.ldif184
-rw-r--r--source4/setup/provision_basedn_modify.ldif10
-rw-r--r--source4/setup/provision_computers_modify.ldif6
-rw-r--r--source4/setup/provision_configuration.ldif3
-rw-r--r--source4/setup/provision_group_policy.ldif11
-rw-r--r--source4/setup/provision_rootdse_add.ldif3
-rw-r--r--source4/setup/provision_self_join.ldif9
-rw-r--r--source4/setup/provision_users.ldif26
-rw-r--r--source4/setup/provision_users_modify.ldif6
-rw-r--r--source4/setup/schema_samba4.ldif3
-rw-r--r--source4/torture/auth/pac.c1
-rw-r--r--source4/torture/rpc/frsapi.c18
-rw-r--r--source4/torture/rpc/lsa.c532
-rw-r--r--source4/torture/rpc/object_uuid.c1
-rw-r--r--source4/torture/rpc/rpc.c3
-rw-r--r--source4/torture/rpc/spoolss.c1082
-rw-r--r--source4/torture/smb2/config.mk1
-rw-r--r--source4/torture/smb2/connect.c2
-rw-r--r--source4/torture/smb2/dir.c1289
-rw-r--r--source4/torture/smb2/getinfo.c4
-rw-r--r--source4/torture/smb2/smb2.c1
-rw-r--r--source4/winbind/wb_cmd_list_users.c2
388 files changed, 13066 insertions, 6755 deletions
diff --git a/Roadmap b/Roadmap
index 1132f6391c..c5b8a4d115 100644
--- a/Roadmap
+++ b/Roadmap
@@ -12,7 +12,7 @@ are in progress:
Samba-3.0.x This release turned into maintenance mode since we
released 3.2.
-Samba-3.2.x This is the current stable Samba 3 release intended
+Samba-3.4.x This is the current stable Samba 3 release intended
for all Samba production server.
Samba-4 Danger Will Robinson, a big code clean up with major
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index fe8d541de8..066f718999 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -14,9 +14,6 @@ Authentication Changes:
o Changed the way smbd handles untrusted domain names given during user
authentication
-net Command Changes:
-o parameter syntax made more consistent
-
Authentication Changes
======================
@@ -35,38 +32,6 @@ on smbd to always pass through bogus names to the DC for verification. A new
parameter "map untrusted to domain" can be enabled to revert to the legacy
behavior.
-net Command Changes
-===================
-
-The net command now accepts the common command line parameters most other Samba
-command line utilities use, with a couple of remaining differences:
-
--l still gives long output for net commands supporting the --long flag. This was
-more useful than the common --log-base parameter.
-
--i still tells net to read data from stdin (like --stdin) instead of toggling
-the common --scope flag.
-
--S still tells net the server to connect to (like --server) instead of
-negotiating the common --signing flag. As -S is probably used by most scripts
-doing net rpc commands, this would have been a high-impact change for little
-gain.
-
-This change was mainly done to unify the authentification options. Here, one
-flag changed it's meaning and one useful flag was added.
-
--N used to be the short version of --ntname. It now matches the Samba default of
---no-pass. Use this to stop net from prompting for a password if you want
-anonymous authentication.
-
--A --authentication-file now takes an authentication file with the username and
-password you want net to use, avoiding a password prompt as with plain -U user
-or having to give a password on the command line as in -U user%pass.
-
-Last but not least net now always falls back to your local unix username if no
--U is specified and a username is needed. net rpc commands will now prompt for a
-password unless one is specified using either -U user%pass or -A auth_file.
-
######################################################################
Reporting bugs & Development Discussion
#######################################
diff --git a/client/cifs.upcall.c b/client/cifs.upcall.c
index 4110de35fd..82b9f7b91b 100644
--- a/client/cifs.upcall.c
+++ b/client/cifs.upcall.c
@@ -1,6 +1,7 @@
/*
* CIFS user-space helper.
* Copyright (C) Igor Mammedov (niallain@gmail.com) 2007
+* Copyright (C) Jeff Layton (jlayton@redhat.com) 2009
*
* Used by /sbin/request-key for handling
* cifs upcall for kerberos authorization of access to share and
@@ -38,6 +39,54 @@ typedef enum _secType {
} secType_t;
/*
+ * given a process ID, get the value of the KRB5CCNAME environment variable
+ * in the context of that process. On error, just return NULL.
+ */
+static char *
+get_krb5_ccname(pid_t pid)
+{
+ int fd;
+ ssize_t len, left;
+
+ /*
+ * FIXME: sysconf for ARG_MAX instead? Kernel seems to be limited to a
+ * page however, so it may not matter.
+ */
+ char buf[4096];
+ char *p, *value = NULL;
+
+ buf[4095] = '\0';
+ snprintf(buf, 4095, "/proc/%d/environ", pid);
+ fd = open(buf, O_RDONLY);
+ if (fd < 0)
+ return NULL;
+
+ /* FIXME: don't assume that we get it all in the first read? */
+ len = read(fd, buf, 4096);
+ close(fd);
+ if (len < 0)
+ return NULL;
+
+ left = len;
+ p = buf;
+
+ /* can't have valid KRB5CCNAME if there are < 13 bytes left */
+ while (left > 12) {
+ if (strncmp("KRB5CCNAME=", p, 11)) {
+ p += strnlen(p, left);
+ ++p;
+ left = buf + len - p;
+ continue;
+ }
+ p += 11;
+ left -= 11;
+ value = SMB_STRNDUP(p, left);
+ break;
+ }
+ return value;
+}
+
+/*
* Prepares AP-REQ data for mechToken and gets session key
* Uses credentials from cache. It will not ask for password
* you should receive credentials for yuor name manually using
@@ -58,15 +107,15 @@ typedef enum _secType {
* ret: 0 - success, others - failure
*/
static int
-handle_krb5_mech(const char *oid, const char *principal,
- DATA_BLOB * secblob, DATA_BLOB * sess_key)
+handle_krb5_mech(const char *oid, const char *principal, DATA_BLOB *secblob,
+ DATA_BLOB *sess_key, const char *ccname)
{
int retval;
DATA_BLOB tkt, tkt_wrapped;
/* get a kerberos ticket for the service and extract the session key */
- retval = cli_krb5_get_ticket(principal, 0,
- &tkt, sess_key, 0, NULL, NULL);
+ retval = cli_krb5_get_ticket(principal, 0, &tkt, sess_key, 0, ccname,
+ NULL);
if (retval)
return retval;
@@ -88,11 +137,12 @@ handle_krb5_mech(const char *oid, const char *principal,
#define DKD_HAVE_IPV4 8
#define DKD_HAVE_IPV6 16
#define DKD_HAVE_UID 32
+#define DKD_HAVE_PID 64
#define DKD_MUSTHAVE_SET (DKD_HAVE_HOSTNAME|DKD_HAVE_VERSION|DKD_HAVE_SEC)
static int
-decode_key_description(const char *desc, int *ver, secType_t * sec,
- char **hostname, uid_t * uid)
+decode_key_description(const char *desc, int *ver, secType_t *sec,
+ char **hostname, uid_t *uid, pid_t *pid)
{
int retval = 0;
char *pos;
@@ -117,6 +167,16 @@ decode_key_description(const char *desc, int *ver, secType_t * sec,
/* BB: do we need it if we have hostname already? */
} else if (strncmp(tkn, "ipv6=", 5) == 0) {
/* BB: do we need it if we have hostname already? */
+ } else if (strncmp(tkn, "pid=", 4) == 0) {
+ errno = 0;
+ *pid = strtol(tkn + 4, NULL, 0);
+ if (errno != 0) {
+ syslog(LOG_WARNING, "Invalid pid format: %s",
+ strerror(errno));
+ return 1;
+ } else {
+ retval |= DKD_HAVE_PID;
+ }
} else if (strncmp(tkn, "sec=", 4) == 0) {
if (strncmp(tkn + 4, "krb5", 4) == 0) {
retval |= DKD_HAVE_SEC;
@@ -224,9 +284,10 @@ int main(const int argc, char *const argv[])
size_t datalen;
long rc = 1;
uid_t uid = 0;
+ pid_t pid = 0;
int kernel_upcall_version = 0;
int c, use_cifs_service_prefix = 0;
- char *buf, *hostname = NULL;
+ char *buf, *ccname = NULL, *hostname = NULL;
const char *oid;
openlog(prog, 0, LOG_DAEMON);
@@ -278,7 +339,7 @@ int main(const int argc, char *const argv[])
}
rc = decode_key_description(buf, &kernel_upcall_version, &sectype,
- &hostname, &uid);
+ &hostname, &uid, &pid);
if ((rc & DKD_MUSTHAVE_SET) != DKD_MUSTHAVE_SET) {
syslog(LOG_WARNING,
"unable to get from description necessary params");
@@ -296,6 +357,9 @@ int main(const int argc, char *const argv[])
goto out;
}
+ if (rc & DKD_HAVE_PID)
+ ccname = get_krb5_ccname(pid);
+
if (rc & DKD_HAVE_UID) {
rc = setuid(uid);
if (rc == -1) {
@@ -304,9 +368,6 @@ int main(const int argc, char *const argv[])
}
}
- /* BB: someday upcall SPNEGO blob could be checked here to decide
- * what mech to use */
-
// do mech specific authorization
switch (sectype) {
case MS_KRB5:
@@ -333,7 +394,8 @@ int main(const int argc, char *const argv[])
else
oid = OID_KERBEROS5;
- rc = handle_krb5_mech(oid, princ, &secblob, &sess_key);
+ rc = handle_krb5_mech(oid, princ, &secblob, &sess_key,
+ ccname);
SAFE_FREE(princ);
break;
}
@@ -385,6 +447,7 @@ out:
keyctl_negate(key, 1, KEY_REQKEY_DEFL_DEFAULT);
data_blob_free(&secblob);
data_blob_free(&sess_key);
+ SAFE_FREE(ccname);
SAFE_FREE(hostname);
SAFE_FREE(keydata);
return rc;
diff --git a/examples/LDAP/samba-schema-FDS.ldif b/examples/LDAP/samba-schema-FDS.ldif
index e88559fc8a..fb16486374 100644
--- a/examples/LDAP/samba-schema-FDS.ldif
+++ b/examples/LDAP/samba-schema-FDS.ldif
@@ -115,6 +115,10 @@ attributeTypes: ( 1.3.6.1.4.1.7165.2.1.65 NAME 'sambaLockoutThreshold' DESC 'Loc
attributeTypes: ( 1.3.6.1.4.1.7165.2.1.66 NAME 'sambaForceLogoff' DESC 'Disconnect Users outside logon hours (default: -1 => off, 0 => on)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
# "refuse machine password change"
attributeTypes: ( 1.3.6.1.4.1.7165.2.1.67 NAME 'sambaRefuseMachinePwdChange' DESC 'Allow Machine Password changes (default: 0 => off)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+#
+attributeTypes: ( 1.3.6.1.4.1.7165.2.1.68 NAME 'sambaClearTextPassword' DESC 'Clear text password (used for trusted domain passwords)' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
+#
+attributeTypes: ( 1.3.6.1.4.1.7165.2.1.69 NAME 'sambaPreviousClearTextPassword' DESC 'Previous clear text password (used for trusted domain passwords)' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
##
#######################################################################
## objectClasses: used by Samba 3.0 schema ##
@@ -154,3 +158,7 @@ objectClasses: ( 1.3.6.1.4.1.7165.2.2.12 NAME 'sambaConfigOption' SUP top STRUCT
## DESC 'Samba Privilege'
## MUST ( sambaSID )
## MAY ( sambaPrivilegeList ) )
+##
+## Trusted Domain Relationships
+##
+objectClasses: ( 1.3.6.1.4.1.7165.2.2.15 NAME 'sambaTrustedDomainPassword' SUP top STRUCTURAL DESC 'Samba Trusted Domain Password' MUST ( sambaDomainName $ sambaSID $ sambaClearTextPassword $ sambaPwdLastSet ) MAY ( sambaPreviousClearTextPassword ) )
diff --git a/examples/VFS/config.guess b/examples/VFS/config.guess
index 600580b1aa..da83314608 100755
--- a/examples/VFS/config.guess
+++ b/examples/VFS/config.guess
@@ -1,13 +1,14 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# Free Software Foundation, Inc.
-timestamp='2005-09-19'
+timestamp='2009-04-27'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
+# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
@@ -16,7 +17,9 @@ timestamp='2005-09-19'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -53,8 +56,8 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -104,7 +107,7 @@ set_cc_for_build='
trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
: ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
@@ -158,6 +161,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
@@ -204,8 +208,11 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:ekkoBSD:*:*)
echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
macppc:MirBSD:*:*)
- echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
exit ;;
*:MirBSD:*:*)
echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
@@ -317,14 +324,30 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
case `/usr/bin/uname -p` in
sparc) echo sparc-icl-nx7; exit ;;
esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
- i86pc:SunOS:5.*:*)
- echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
@@ -525,7 +548,7 @@ EOF
echo rs6000-ibm-aix3.2
fi
exit ;;
- *:AIX:*:[45])
+ *:AIX:*:[456])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
@@ -762,12 +785,19 @@ EOF
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit ;;
*:FreeBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ case ${UNAME_MACHINE} in
+ pc98)
+ echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
exit ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit ;;
- i*:MINGW*:*)
+ *:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
i*:windows32*:*)
@@ -777,9 +807,18 @@ EOF
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit ;;
- x86:Interix*:[34]*)
- echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
- exit ;;
+ *:Interix*:[3456]*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ EM64T | authenticamd | genuineintel)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
exit ;;
@@ -813,6 +852,16 @@ EOF
echo ${UNAME_MACHINE}-pc-minix
exit ;;
arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
cris:Linux:*:*)
@@ -849,7 +898,11 @@ EOF
#endif
#endif
EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+ /^CPU/{
+ s: ::g
+ p
+ }'`"
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
;;
mips64:Linux:*:*)
@@ -868,7 +921,11 @@ EOF
#endif
#endif
EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+ /^CPU/{
+ s: ::g
+ p
+ }'`"
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
;;
or32:Linux:*:*)
@@ -894,6 +951,9 @@ EOF
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-gnu
+ exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
@@ -917,9 +977,15 @@ EOF
sparc:Linux:*:* | sparc64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-gnu
+ exit ;;
x86_64:Linux:*:*)
echo x86_64-unknown-linux-gnu
exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
i*86:Linux:*:*)
# The BFD linker knows what the default object file format is, so
# first see if it will tell us. cd to the root directory to prevent
@@ -938,9 +1004,6 @@ EOF
a.out-i386-linux)
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
exit ;;
- coff-i386)
- echo "${UNAME_MACHINE}-pc-linux-gnucoff"
- exit ;;
"")
# Either a pre-BFD a.out linker (linux-gnuoldld) or
# one that does not give us useful --help.
@@ -962,7 +1025,7 @@ EOF
LIBC=gnulibc1
# endif
#else
- #ifdef __INTEL_COMPILER
+ #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
LIBC=gnu
#else
LIBC=gnuaout
@@ -972,7 +1035,11 @@ EOF
LIBC=dietlibc
#endif
EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+ eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+ /^LIBC/{
+ s: ::g
+ p
+ }'`"
test x"${LIBC}" != x && {
echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
exit
@@ -1051,8 +1118,11 @@ EOF
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
- # the processor, so we play safe by assuming i386.
- echo i386-pc-msdosdjgpp
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
exit ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
@@ -1090,6 +1160,16 @@ EOF
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
exit ;;
@@ -1165,6 +1245,9 @@ EOF
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
echo i586-pc-beos
exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
exit ;;
@@ -1174,6 +1257,15 @@ EOF
SX-6:SUPER-UX:*:*)
echo sx6-nec-superux${UNAME_RELEASE}
exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit ;;
@@ -1261,6 +1353,12 @@ EOF
i*86:skyos:*:*)
echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
@@ -1421,9 +1519,9 @@ This script, last modified $timestamp, has failed to recognize
the operating system you are using. It is advised that you
download the most up to date version of the config scripts from
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
and
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
If the version you run ($0) is already up to date, please
send the following data and any information you think might be
diff --git a/examples/VFS/config.sub b/examples/VFS/config.sub
index 23cd6fd75c..a39437d015 100755
--- a/examples/VFS/config.sub
+++ b/examples/VFS/config.sub
@@ -1,9 +1,10 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# Free Software Foundation, Inc.
-timestamp='2005-07-08'
+timestamp='2009-04-17'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@@ -11,7 +12,7 @@ timestamp='2005-07-08'
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
+# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@@ -20,7 +21,9 @@ timestamp='2005-07-08'
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -69,8 +72,8 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -117,8 +120,10 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
- nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
- kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
+ nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
@@ -169,6 +174,10 @@ case $os in
-hiux*)
os=-hiuxwe2
;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
-sco5)
os=-sco3.2v5
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -185,6 +194,10 @@ case $os in
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
-sco*)
os=-sco3.2v2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -229,20 +242,24 @@ case $basic_machine in
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
- | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
| bfin \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
- | fr30 | frv \
+ | fido | fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
- | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | mcore | mep | metag \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
- | mips64vr | mips64vrel \
+ | mips64octeon | mips64octeonel \
| mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
@@ -255,26 +272,26 @@ case $basic_machine in
| mipsisa64sr71k | mipsisa64sr71kel \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
- | ms1 \
+ | moxie \
+ | mt \
| msp430 \
+ | nios | nios2 \
| ns16k | ns32k \
| or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
- | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
- | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \
- | sparcv8 | sparcv9 | sparcv9b \
- | strongarm \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu | strongarm \
| tahoe | thumb | tic4x | tic80 | tron \
| v850 | v850e \
| we32k \
- | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
- | z8k)
- basic_machine=$basic_machine-unknown
- ;;
- m32c)
+ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+ | z8k | z80)
basic_machine=$basic_machine-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12)
@@ -284,6 +301,9 @@ case $basic_machine in
;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
@@ -303,25 +323,28 @@ case $basic_machine in
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
- | avr-* \
+ | avr-* | avr32-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
| clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
- | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
- | m32r-* | m32rle-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | maxq-* | mcore-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
- | mips64vr-* | mips64vrel-* \
+ | mips64octeon-* | mips64octeonel-* \
| mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
@@ -334,30 +357,33 @@ case $basic_machine in
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipstx39-* | mipstx39el-* \
| mmix-* \
- | ms1-* \
+ | mt-* \
| msp430-* \
+ | nios-* | nios2-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| romp-* | rs6000-* \
- | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
- | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
- | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* \
- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
| tron-* \
| v850-* | v850e-* | vax-* \
| we32k-* \
- | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
- | xstormy16-* | xtensa-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+ | xstormy16-* | xtensa*-* \
| ymp-* \
- | z8k-*)
+ | z8k-* | z80-*)
;;
- m32c-*)
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
@@ -421,6 +447,10 @@ case $basic_machine in
basic_machine=m68k-apollo
os=-bsd
;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
aux)
basic_machine=m68k-apple
os=-aux
@@ -429,10 +459,22 @@ case $basic_machine in
basic_machine=ns32k-sequent
os=-dynix
;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
c90)
basic_machine=c90-cray
os=-unicos
;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
convex-c1)
basic_machine=c1-convex
os=-bsd
@@ -461,8 +503,8 @@ case $basic_machine in
basic_machine=craynv-cray
os=-unicosmp
;;
- cr16c)
- basic_machine=cr16c-unknown
+ cr16)
+ basic_machine=cr16-unknown
os=-elf
;;
crds | unos)
@@ -500,6 +542,10 @@ case $basic_machine in
basic_machine=m88k-motorola
os=-sysv3
;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
djgpp)
basic_machine=i586-pc
os=-msdosdjgpp
@@ -654,6 +700,14 @@ case $basic_machine in
basic_machine=m68k-isi
os=-sysv
;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
m88k-omron*)
basic_machine=m88k-omron
;;
@@ -669,6 +723,10 @@ case $basic_machine in
basic_machine=i386-pc
os=-mingw32
;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
miniframe)
basic_machine=m68000-convergent
;;
@@ -694,6 +752,9 @@ case $basic_machine in
basic_machine=i386-pc
os=-msdos
;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
mvs)
basic_machine=i370-ibm
os=-mvs
@@ -792,6 +853,14 @@ case $basic_machine in
basic_machine=i860-intel
os=-osf
;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
pbd)
basic_machine=sparc-tti
;;
@@ -801,6 +870,12 @@ case $basic_machine in
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
;;
@@ -857,6 +932,10 @@ case $basic_machine in
basic_machine=i586-unknown
os=-pw32
;;
+ rdos)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
rom68k)
basic_machine=m68k-rom68k
os=-coff
@@ -883,6 +962,10 @@ case $basic_machine in
sb1el)
basic_machine=mipsisa64sb1el-unknown
;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
sei)
basic_machine=mips-sei
os=-seiux
@@ -894,6 +977,9 @@ case $basic_machine in
basic_machine=sh-hitachi
os=-hms
;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
sh64)
basic_machine=sh64-unknown
;;
@@ -983,6 +1069,10 @@ case $basic_machine in
basic_machine=tic6x-unknown
os=-coff
;;
+ tile*)
+ basic_machine=tile-unknown
+ os=-linux-gnu
+ ;;
tx39)
basic_machine=mipstx39-unknown
;;
@@ -1058,6 +1148,10 @@ case $basic_machine in
basic_machine=z8k-unknown
os=-sim
;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
none)
basic_machine=none-none
os=-none
@@ -1096,10 +1190,10 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
- sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
- sparc | sparcv8 | sparcv9 | sparcv9b)
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
basic_machine=sparc-sun
;;
cydra)
@@ -1168,25 +1262,28 @@ case $os in
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -kopensolaris* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* \
+ | -aos* | -aros* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -openbsd* | -solidbsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -chorusos* | -chorusrdb* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku*)
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1316,6 +1413,9 @@ case $os in
-zvmoe)
os=-zvmoe
;;
+ -dicos*)
+ os=-dicos
+ ;;
-none)
;;
*)
@@ -1338,6 +1438,12 @@ else
# system, and we'll never get to this point.
case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
*-acorn)
os=-riscix1.2
;;
@@ -1347,9 +1453,9 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
- c4x-* | tic4x-*)
- os=-coff
- ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
# This must come before the *-dec entry.
pdp10-*)
os=-tops20
@@ -1375,6 +1481,9 @@ case $basic_machine in
m68*-cisco)
os=-aout
;;
+ mep-*)
+ os=-elf
+ ;;
mips*-cisco)
os=-elf
;;
diff --git a/lib/replace/libreplace.m4 b/lib/replace/libreplace.m4
index 2d90d9c7e8..a3a26ef43e 100644
--- a/lib/replace/libreplace.m4
+++ b/lib/replace/libreplace.m4
@@ -103,6 +103,7 @@ AC_CHECK_HEADERS(sys/time.h time.h)
AC_CHECK_HEADERS(stdarg.h vararg.h)
AC_CHECK_HEADERS(sys/mount.h mntent.h)
AC_CHECK_HEADERS(stropts.h)
+AC_CHECK_HEADERS(unix.h)
AC_CHECK_FUNCS(seteuid setresuid setegid setresgid chroot bzero strerror)
AC_CHECK_FUNCS(vsyslog setlinebuf mktime ftruncate chsize rename)
diff --git a/lib/replace/replace.h b/lib/replace/replace.h
index fe1f732acb..2db6aa1226 100644
--- a/lib/replace/replace.h
+++ b/lib/replace/replace.h
@@ -258,6 +258,10 @@ char *rep_realpath(const char *path, char *resolved_path);
int rep_lchown(const char *fname,uid_t uid,gid_t gid);
#endif
+#ifdef HAVE_UNIX_H
+#include <unix.h>
+#endif
+
#ifndef HAVE_SETLINEBUF
#define setlinebuf rep_setlinebuf
void rep_setlinebuf(FILE *);
diff --git a/lib/tdb/common/lock.c b/lib/tdb/common/lock.c
index f156c0fa7b..2c72ae1f0d 100644
--- a/lib/tdb/common/lock.c
+++ b/lib/tdb/common/lock.c
@@ -301,16 +301,21 @@ int tdb_unlock(struct tdb_context *tdb, int list, int ltype)
*/
int tdb_transaction_lock(struct tdb_context *tdb, int ltype)
{
- if (tdb->have_transaction_lock || tdb->global_lock.count) {
+ if (tdb->global_lock.count) {
+ return 0;
+ }
+ if (tdb->transaction_lock_count > 0) {
+ tdb->transaction_lock_count++;
return 0;
}
+
if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, ltype,
F_SETLKW, 0, 1) == -1) {
TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_lock: failed to get transaction lock\n"));
tdb->ecode = TDB_ERR_LOCK;
return -1;
}
- tdb->have_transaction_lock = 1;
+ tdb->transaction_lock_count++;
return 0;
}
@@ -320,12 +325,16 @@ int tdb_transaction_lock(struct tdb_context *tdb, int ltype)
int tdb_transaction_unlock(struct tdb_context *tdb)
{
int ret;
- if (!tdb->have_transaction_lock) {
+ if (tdb->global_lock.count) {
+ return 0;
+ }
+ if (tdb->transaction_lock_count > 1) {
+ tdb->transaction_lock_count--;
return 0;
}
ret = tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);
if (ret == 0) {
- tdb->have_transaction_lock = 0;
+ tdb->transaction_lock_count = 0;
}
return ret;
}
diff --git a/lib/tdb/common/tdb_private.h b/lib/tdb/common/tdb_private.h
index ffac89ff0e..45b85f4c93 100644
--- a/lib/tdb/common/tdb_private.h
+++ b/lib/tdb/common/tdb_private.h
@@ -166,7 +166,7 @@ struct tdb_context {
struct tdb_transaction *transaction;
int page_size;
int max_dead_records;
- bool have_transaction_lock;
+ int transaction_lock_count;
volatile sig_atomic_t *interrupt_sig_ptr;
};
diff --git a/lib/tdb/common/traverse.c b/lib/tdb/common/traverse.c
index 69c81e6e98..07b0c23858 100644
--- a/lib/tdb/common/traverse.c
+++ b/lib/tdb/common/traverse.c
@@ -204,23 +204,18 @@ int tdb_traverse_read(struct tdb_context *tdb,
{
struct tdb_traverse_lock tl = { NULL, 0, 0, F_RDLCK };
int ret;
- bool in_transaction = (tdb->transaction != NULL);
/* we need to get a read lock on the transaction lock here to
cope with the lock ordering semantics of solaris10 */
- if (!in_transaction) {
- if (tdb_transaction_lock(tdb, F_RDLCK)) {
- return -1;
- }
+ if (tdb_transaction_lock(tdb, F_RDLCK)) {
+ return -1;
}
tdb->traverse_read++;
ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
tdb->traverse_read--;
- if (!in_transaction) {
- tdb_transaction_unlock(tdb);
- }
+ tdb_transaction_unlock(tdb);
return ret;
}
@@ -237,25 +232,20 @@ int tdb_traverse(struct tdb_context *tdb,
{
struct tdb_traverse_lock tl = { NULL, 0, 0, F_WRLCK };
int ret;
- bool in_transaction = (tdb->transaction != NULL);
if (tdb->read_only || tdb->traverse_read) {
return tdb_traverse_read(tdb, fn, private_data);
}
- if (!in_transaction) {
- if (tdb_transaction_lock(tdb, F_WRLCK)) {
- return -1;
- }
+ if (tdb_transaction_lock(tdb, F_WRLCK)) {
+ return -1;
}
tdb->traverse_write++;
ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
tdb->traverse_write--;
- if (!in_transaction) {
- tdb_transaction_unlock(tdb);
- }
+ tdb_transaction_unlock(tdb);
return ret;
}
diff --git a/lib/tevent/testsuite.c b/lib/tevent/testsuite.c
index d964fb33d3..f9aca91aa1 100644
--- a/lib/tevent/testsuite.c
+++ b/lib/tevent/testsuite.c
@@ -66,7 +66,13 @@ static bool test_event_context(struct torture_context *test,
const char *backend = (const char *)test_data;
int alarm_count=0, info_count=0;
struct tevent_fd *fde;
- struct signal_event *se1, *se2, *se3;
+#ifdef SA_RESTART
+ struct tevent_signal *se1 = NULL;
+#endif
+ struct tevent_signal *se2 = NULL;
+#ifdef SA_SIGINFO
+ struct tevent_signal *se3 = NULL;
+#endif
int finished=0;
struct timeval t;
char c = 0;
@@ -92,7 +98,9 @@ static bool test_event_context(struct torture_context *test,
event_add_timed(ev_ctx, ev_ctx, timeval_current_ofs(2,0),
finished_handler, &finished);
+#ifdef SA_RESTART
se1 = event_add_signal(ev_ctx, ev_ctx, SIGALRM, SA_RESTART, count_handler, &alarm_count);
+#endif
se2 = event_add_signal(ev_ctx, ev_ctx, SIGALRM, SA_RESETHAND, count_handler, &alarm_count);
#ifdef SA_SIGINFO
se3 = event_add_signal(ev_ctx, ev_ctx, SIGUSR1, SA_SIGINFO, count_handler, &info_count);
@@ -120,7 +128,9 @@ static bool test_event_context(struct torture_context *test,
torture_comment(test, "Got %.2f pipe events/sec\n", fde_count/timeval_elapsed(&t));
+#ifdef SA_RESTART
talloc_free(se1);
+#endif
torture_assert_int_equal(test, alarm_count, 1+fde_count, "alarm count mismatch");
diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c
index 541f93f99c..0feabb5f1f 100644
--- a/lib/tevent/tevent_req.c
+++ b/lib/tevent/tevent_req.c
@@ -104,7 +104,7 @@ struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx,
return NULL;
}
- data = talloc_size(req, data_size);
+ data = talloc_zero_size(req, data_size);
if (data == NULL) {
talloc_free(req);
return NULL;
diff --git a/lib/torture/torture.c b/lib/torture/torture.c
index 99447e7e53..392cb0ad4c 100644
--- a/lib/torture/torture.c
+++ b/lib/torture/torture.c
@@ -65,7 +65,6 @@ struct torture_context *torture_context_child(struct torture_context *parent)
if (subtorture == NULL)
return NULL;
- subtorture->level = parent->level+1;
subtorture->ev = talloc_reference(subtorture, parent->ev);
subtorture->lp_ctx = talloc_reference(subtorture, parent->lp_ctx);
subtorture->outputdir = talloc_reference(subtorture, parent->outputdir);
@@ -257,7 +256,6 @@ bool torture_run_suite(struct torture_context *context,
struct torture_suite *tsuite;
char *old_testname;
- context->level++;
if (context->results->ui_ops->suite_start)
context->results->ui_ops->suite_start(context, suite);
@@ -282,8 +280,6 @@ bool torture_run_suite(struct torture_context *context,
if (context->results->ui_ops->suite_finish)
context->results->ui_ops->suite_finish(context, suite);
- context->level--;
-
return ret;
}
@@ -378,8 +374,6 @@ bool torture_run_tcase(struct torture_context *context,
char *old_testname;
struct torture_test *test;
- context->level++;
-
context->active_tcase = tcase;
if (context->results->ui_ops->tcase_start)
context->results->ui_ops->tcase_start(context, tcase);
@@ -415,8 +409,6 @@ done:
if (context->results->ui_ops->tcase_finish)
context->results->ui_ops->tcase_finish(context, tcase);
- context->level--;
-
return ret;
}
diff --git a/lib/torture/torture.h b/lib/torture/torture.h
index bc6365351e..e28801e269 100644
--- a/lib/torture/torture.h
+++ b/lib/torture/torture.h
@@ -86,9 +86,6 @@ struct torture_context
/** Directory used for temporary test data */
const char *outputdir;
- /** Indentation level */
- int level;
-
/** Event context */
struct tevent_context *ev;
diff --git a/lib/tsocket/tsocket_bsd.c b/lib/tsocket/tsocket_bsd.c
index 78bca4b0b5..8f1ccbeb43 100644
--- a/lib/tsocket/tsocket_bsd.c
+++ b/lib/tsocket/tsocket_bsd.c
@@ -203,7 +203,7 @@ struct tsocket_address_bsd {
static int _tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx,
struct sockaddr *sa,
- socklen_t sa_len,
+ socklen_t sa_socklen,
struct tsocket_address **_addr,
const char *location)
{
@@ -212,20 +212,20 @@ static int _tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx,
switch (sa->sa_family) {
case AF_UNIX:
- if (sa_len < sizeof(struct sockaddr_un)) {
+ if (sa_socklen < sizeof(struct sockaddr_un)) {
errno = EINVAL;
return -1;
}
break;
case AF_INET:
- if (sa_len < sizeof(struct sockaddr_in)) {
+ if (sa_socklen < sizeof(struct sockaddr_in)) {
errno = EINVAL;
return -1;
}
break;
#ifdef HAVE_IPV6
case AF_INET6:
- if (sa_len < sizeof(struct sockaddr_in6)) {
+ if (sa_socklen < sizeof(struct sockaddr_in6)) {
errno = EINVAL;
return -1;
}
@@ -236,7 +236,7 @@ static int _tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx,
return -1;
}
- if (sa_len > sizeof(struct sockaddr_storage)) {
+ if (sa_socklen > sizeof(struct sockaddr_storage)) {
errno = EINVAL;
return -1;
}
@@ -253,7 +253,7 @@ static int _tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx,
ZERO_STRUCTP(bsda);
- memcpy(&bsda->u.ss, sa, sa_len);
+ memcpy(&bsda->u.ss, sa, sa_socklen);
*_addr = addr;
return 0;
@@ -773,7 +773,7 @@ static void tdgram_bsd_recvfrom_handler(void *private_data)
struct tsocket_address_bsd *bsda;
ssize_t ret;
struct sockaddr *sa = NULL;
- socklen_t sa_len = 0;
+ socklen_t sa_socklen = 0;
int err;
bool retry;
@@ -809,16 +809,16 @@ static void tdgram_bsd_recvfrom_handler(void *private_data)
ZERO_STRUCTP(bsda);
sa = &bsda->u.sa;
- sa_len = sizeof(bsda->u.ss);
+ sa_socklen = sizeof(bsda->u.ss);
/*
* for unix sockets we can't use the size of sockaddr_storage
* we would get EINVAL
*/
if (bsda->u.sa.sa_family == AF_UNIX) {
- sa_len = sizeof(bsda->u.un);
+ sa_socklen = sizeof(bsda->u.un);
}
- ret = recvfrom(bsds->fd, state->buf, state->len, 0, sa, &sa_len);
+ ret = recvfrom(bsds->fd, state->buf, state->len, 0, sa, &sa_socklen);
err = tsocket_bsd_error_from_errno(ret, errno, &retry);
if (retry) {
/* retry later */
@@ -946,7 +946,7 @@ static void tdgram_bsd_sendto_handler(void *private_data)
struct tdgram_context *dgram = state->dgram;
struct tdgram_bsd *bsds = tdgram_context_data(dgram, struct tdgram_bsd);
struct sockaddr *sa = NULL;
- socklen_t sa_len = 0;
+ socklen_t sa_socklen = 0;
ssize_t ret;
int err;
bool retry;
@@ -957,17 +957,17 @@ static void tdgram_bsd_sendto_handler(void *private_data)
struct tsocket_address_bsd);
sa = &bsda->u.sa;
- sa_len = sizeof(bsda->u.ss);
+ sa_socklen = sizeof(bsda->u.ss);
/*
* for unix sockets we can't use the size of sockaddr_storage
* we would get EINVAL
*/
if (bsda->u.sa.sa_family == AF_UNIX) {
- sa_len = sizeof(bsda->u.un);
+ sa_socklen = sizeof(bsda->u.un);
}
}
- ret = sendto(bsds->fd, state->buf, state->len, 0, sa, sa_len);
+ ret = sendto(bsds->fd, state->buf, state->len, 0, sa, sa_socklen);
err = tsocket_bsd_error_from_errno(ret, errno, &retry);
if (retry) {
/* retry later */
@@ -1087,7 +1087,7 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local,
int ret;
bool do_bind = false;
bool do_reuseaddr = false;
- socklen_t sa_len = sizeof(lbsda->u.ss);
+ socklen_t sa_socklen = sizeof(lbsda->u.ss);
if (remote) {
rbsda = talloc_get_type_abort(remote->private_data,
@@ -1108,7 +1108,7 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local,
* for unix sockets we can't use the size of sockaddr_storage
* we would get EINVAL
*/
- sa_len = sizeof(lbsda->u.un);
+ sa_socklen = sizeof(lbsda->u.un);
break;
case AF_INET:
if (lbsda->u.in.sin_port != 0) {
@@ -1189,7 +1189,7 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local,
}
if (do_bind) {
- ret = bind(fd, &lbsda->u.sa, sa_len);
+ ret = bind(fd, &lbsda->u.sa, sa_socklen);
if (ret == -1) {
int saved_errno = errno;
talloc_free(dgram);
@@ -1199,7 +1199,7 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local,
}
if (rbsda) {
- ret = connect(fd, &rbsda->u.sa, sa_len);
+ ret = connect(fd, &rbsda->u.sa, sa_socklen);
if (ret == -1) {
int saved_errno = errno;
talloc_free(dgram);
@@ -1889,7 +1889,7 @@ static struct tevent_req * tstream_bsd_connect_send(TALLOC_CTX *mem_ctx,
bool retry;
bool do_bind = false;
bool do_reuseaddr = false;
- socklen_t sa_len = sizeof(rbsda->u.ss);
+ socklen_t sa_socklen = sizeof(rbsda->u.ss);
req = tevent_req_create(mem_ctx, &state,
struct tstream_bsd_connect_state);
@@ -1917,7 +1917,7 @@ static struct tevent_req * tstream_bsd_connect_send(TALLOC_CTX *mem_ctx,
* for unix sockets we can't use the size of sockaddr_storage
* we would get EINVAL
*/
- sa_len = sizeof(rbsda->u.un);
+ sa_socklen = sizeof(rbsda->u.un);
break;
case AF_INET:
if (lbsda->u.in.sin_port != 0) {
@@ -1977,7 +1977,7 @@ static struct tevent_req * tstream_bsd_connect_send(TALLOC_CTX *mem_ctx,
}
}
- ret = connect(state->fd, &rbsda->u.sa, sa_len);
+ ret = connect(state->fd, &rbsda->u.sa, sa_socklen);
err = tsocket_bsd_error_from_errno(ret, errno, &retry);
if (retry) {
/* retry later */
diff --git a/lib/util/genrand.c b/lib/util/genrand.c
index cd1823a9a0..5b8456547a 100644
--- a/lib/util/genrand.c
+++ b/lib/util/genrand.c
@@ -294,6 +294,7 @@ _PUBLIC_ uint32_t generate_random(void)
_PUBLIC_ bool check_password_quality(const char *s)
{
int has_digit=0, has_capital=0, has_lower=0, has_special=0, has_high=0;
+ const char* reals = s;
while (*s) {
if (isdigit((unsigned char)*s)) {
has_digit |= 1;
@@ -310,7 +311,7 @@ _PUBLIC_ bool check_password_quality(const char *s)
}
return ((has_digit + has_lower + has_capital + has_special) >= 3
- || (has_high > strlen(s)/2));
+ || (has_high > strlen(reals)/2));
}
/**
diff --git a/lib/util/tests/genrand.c b/lib/util/tests/genrand.c
index 5fe229c089..20a20ac7fa 100644
--- a/lib/util/tests/genrand.c
+++ b/lib/util/tests/genrand.c
@@ -40,6 +40,8 @@ static bool test_check_password_quality(struct torture_context *tctx)
torture_assert(tctx, !check_password_quality("aaaaaaaaaaaa"), "same char password");
torture_assert(tctx, !check_password_quality("BLA"), "multiple upcases password");
torture_assert(tctx, !check_password_quality("123"), "digits only");
+ torture_assert(tctx, !check_password_quality("matthiéu"), "not enough high symbols");
+ torture_assert(tctx, check_password_quality("abcdééàçè"), "valid");
torture_assert(tctx, check_password_quality("A2e"), "valid");
torture_assert(tctx, check_password_quality("BA2eLi443"), "valid");
return true;
diff --git a/lib/util/util_file.c b/lib/util/util_file.c
index 0275e78c54..7466004e5c 100644
--- a/lib/util/util_file.c
+++ b/lib/util/util_file.c
@@ -380,6 +380,7 @@ _PUBLIC_ bool file_save(const char *fname, const void *packet, size_t length)
return false;
}
if (write(fd, packet, length) != (size_t)length) {
+ close(fd);
return false;
}
close(fd);
diff --git a/libcli/security/secacl.c b/libcli/security/secacl.c
index 9373ef5812..29afe460b1 100644
--- a/libcli/security/secacl.c
+++ b/libcli/security/secacl.c
@@ -51,7 +51,7 @@ struct security_acl *make_sec_acl(TALLOC_CTX *ctx,
positive number. */
if ((num_aces) &&
- ((dst->aces = talloc_array(ctx, struct security_ace, num_aces))
+ ((dst->aces = talloc_array(dst, struct security_ace, num_aces))
== NULL)) {
return NULL;
}
diff --git a/source4/dsdb/common/flag_mapping.c b/libds/common/flag_mapping.c
index dceb41be67..dc7d80185a 100644
--- a/source4/dsdb/common/flag_mapping.c
+++ b/libds/common/flag_mapping.c
@@ -1,33 +1,31 @@
-/*
+/*
Unix SMB/CIFS implementation.
- helper mapping functions for the SAMDB server
-
+ helper mapping functions for the UF and ACB flags
+
Copyright (C) Stefan (metze) Metzmacher 2002
Copyright (C) Andrew Tridgell 2004
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#include "librpc/gen_ndr/samr.h"
-#include "dsdb/common/flags.h"
-#include "lib/ldb/include/ldb.h"
-#include "dsdb/common/proto.h"
+#include "../libds/common/flags.h"
-/*
-translated the ACB_CTRL Flags to UserFlags (userAccountControl)
-*/
+/*
+translated the ACB_CTRL Flags to UserFlags (userAccountControl)
+*/
/* mapping between ADS userAccountControl and SAMR acct_flags */
static const struct {
uint32_t uf;
@@ -54,7 +52,7 @@ static const struct {
{ UF_NO_AUTH_DATA_REQUIRED, ACB_NO_AUTH_DATA_REQD }
};
-uint32_t samdb_acb2uf(uint32_t acb)
+uint32_t ds_acb2uf(uint32_t acb)
{
uint32_t i, ret = 0;
for (i=0;i<ARRAY_SIZE(acct_flags_map);i++) {
@@ -68,7 +66,7 @@ uint32_t samdb_acb2uf(uint32_t acb)
/*
translated the UserFlags (userAccountControl) to ACB_CTRL Flags
*/
-uint32_t samdb_uf2acb(uint32_t uf)
+uint32_t ds_uf2acb(uint32_t uf)
{
uint32_t i;
uint32_t ret = 0;
@@ -80,13 +78,13 @@ uint32_t samdb_uf2acb(uint32_t uf)
return ret;
}
-/*
+/*
get the accountType from the UserFlags
*/
-uint32_t samdb_uf2atype(uint32_t uf)
+uint32_t ds_uf2atype(uint32_t uf)
{
uint32_t atype = 0x00000000;
-
+
if (uf & UF_NORMAL_ACCOUNT) atype = ATYPE_NORMAL_ACCOUNT;
else if (uf & UF_TEMP_DUPLICATE_ACCOUNT) atype = ATYPE_NORMAL_ACCOUNT;
else if (uf & UF_SERVER_TRUST_ACCOUNT) atype = ATYPE_WORKSTATION_TRUST;
@@ -94,15 +92,15 @@ uint32_t samdb_uf2atype(uint32_t uf)
else if (uf & UF_INTERDOMAIN_TRUST_ACCOUNT) atype = ATYPE_INTERDOMAIN_TRUST;
return atype;
-}
+}
-/*
+/*
get the accountType from the groupType
*/
-uint32_t samdb_gtype2atype(uint32_t gtype)
+uint32_t ds_gtype2atype(uint32_t gtype)
{
uint32_t atype = 0x00000000;
-
+
switch(gtype) {
case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
atype = ATYPE_SECURITY_LOCAL_GROUP;
@@ -113,7 +111,7 @@ uint32_t samdb_gtype2atype(uint32_t gtype)
case GTYPE_SECURITY_GLOBAL_GROUP:
atype = ATYPE_SECURITY_GLOBAL_GROUP;
break;
-
+
case GTYPE_DISTRIBUTION_GLOBAL_GROUP:
atype = ATYPE_DISTRIBUTION_GLOBAL_GROUP;
break;
@@ -129,7 +127,7 @@ uint32_t samdb_gtype2atype(uint32_t gtype)
}
/* turn a sAMAccountType into a SID_NAME_USE */
-enum lsa_SidType samdb_atype_map(uint32_t atype)
+enum lsa_SidType ds_atype_map(uint32_t atype)
{
switch (atype & 0xF0000000) {
case ATYPE_GLOBAL_GROUP:
diff --git a/source4/dsdb/common/flags.h b/libds/common/flags.h
index dd8081732c..2b342af8d6 100644
--- a/source4/dsdb/common/flags.h
+++ b/libds/common/flags.h
@@ -21,23 +21,23 @@
/* UserFlags for userAccountControl */
#define UF_SCRIPT 0x00000001 /* NT or Lan Manager Login script must be executed */
#define UF_ACCOUNTDISABLE 0x00000002
-#define UF_00000004 0x00000004
+#define UF_00000004 0x00000004
#define UF_HOMEDIR_REQUIRED 0x00000008
-#define UF_LOCKOUT 0x00000010
-#define UF_PASSWD_NOTREQD 0x00000020
-#define UF_PASSWD_CANT_CHANGE 0x00000040
+#define UF_LOCKOUT 0x00000010
+#define UF_PASSWD_NOTREQD 0x00000020
+#define UF_PASSWD_CANT_CHANGE 0x00000040
#define UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED 0x00000080
-#define UF_TEMP_DUPLICATE_ACCOUNT 0x00000100 /* Local user account in usrmgr */
-#define UF_NORMAL_ACCOUNT 0x00000200
-#define UF_00000400 0x00000400
-#define UF_INTERDOMAIN_TRUST_ACCOUNT 0x00000800
+#define UF_TEMP_DUPLICATE_ACCOUNT 0x00000100 /* Local user account in usrmgr */
+#define UF_NORMAL_ACCOUNT 0x00000200
+#define UF_00000400 0x00000400
+#define UF_INTERDOMAIN_TRUST_ACCOUNT 0x00000800
-#define UF_WORKSTATION_TRUST_ACCOUNT 0x00001000
-#define UF_SERVER_TRUST_ACCOUNT 0x00002000
-#define UF_00004000 0x00004000
-#define UF_00008000 0x00008000
+#define UF_WORKSTATION_TRUST_ACCOUNT 0x00001000
+#define UF_SERVER_TRUST_ACCOUNT 0x00002000
+#define UF_00004000 0x00004000
+#define UF_00008000 0x00008000
#define UF_DONT_EXPIRE_PASSWD 0x00010000
#define UF_MNS_LOGON_ACCOUNT 0x00020000
@@ -50,21 +50,53 @@
#define UF_PASSWORD_EXPIRED 0x00800000
#define UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION 0x01000000
-#define UF_NO_AUTH_DATA_REQUIRED 0x02000000
+#define UF_NO_AUTH_DATA_REQUIRED 0x02000000
+
+#define UF_MACHINE_ACCOUNT_MASK (\
+ UF_INTERDOMAIN_TRUST_ACCOUNT |\
+ UF_WORKSTATION_TRUST_ACCOUNT |\
+ UF_SERVER_TRUST_ACCOUNT \
+ )
+
+#define UF_ACCOUNT_TYPE_MASK (\
+ UF_TEMP_DUPLICATE_ACCOUNT |\
+ UF_NORMAL_ACCOUNT |\
+ UF_INTERDOMAIN_TRUST_ACCOUNT |\
+ UF_WORKSTATION_TRUST_ACCOUNT |\
+ UF_SERVER_TRUST_ACCOUNT \
+ )
+
+#define UF_SETTABLE_BITS (\
+ UF_SCRIPT |\
+ UF_ACCOUNTDISABLE |\
+ UF_HOMEDIR_REQUIRED |\
+ UF_LOCKOUT |\
+ UF_PASSWD_NOTREQD |\
+ UF_PASSWD_CANT_CHANGE |\
+ UF_ACCOUNT_TYPE_MASK | \
+ UF_DONT_EXPIRE_PASSWD | \
+ UF_MNS_LOGON_ACCOUNT |\
+ UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED |\
+ UF_SMARTCARD_REQUIRED |\
+ UF_TRUSTED_FOR_DELEGATION |\
+ UF_NOT_DELEGATED |\
+ UF_USE_DES_KEY_ONLY |\
+ UF_DONT_REQUIRE_PREAUTH \
+ )
/* sAMAccountType */
#define ATYPE_NORMAL_ACCOUNT 0x30000000 /* 805306368 */
#define ATYPE_WORKSTATION_TRUST 0x30000001 /* 805306369 */
-#define ATYPE_INTERDOMAIN_TRUST 0x30000002 /* 805306370 */
+#define ATYPE_INTERDOMAIN_TRUST 0x30000002 /* 805306370 */
#define ATYPE_SECURITY_GLOBAL_GROUP 0x10000000 /* 268435456 */
#define ATYPE_DISTRIBUTION_GLOBAL_GROUP 0x10000001 /* 268435457 */
-#define ATYPE_DISTRIBUTION_UNIVERSAL_GROUP ATYPE_DISTRIBUTION_GLOBAL_GROUP
+#define ATYPE_DISTRIBUTION_UNIVERSAL_GROUP ATYPE_DISTRIBUTION_GLOBAL_GROUP
#define ATYPE_SECURITY_LOCAL_GROUP 0x20000000 /* 536870912 */
#define ATYPE_DISTRIBUTION_LOCAL_GROUP 0x20000001 /* 536870913 */
-#define ATYPE_ACCOUNT ATYPE_NORMAL_ACCOUNT /* 0x30000000 805306368 */
-#define ATYPE_GLOBAL_GROUP ATYPE_SECURITY_GLOBAL_GROUP /* 0x10000000 268435456 */
-#define ATYPE_LOCAL_GROUP ATYPE_SECURITY_LOCAL_GROUP /* 0x20000000 536870912 */
+#define ATYPE_ACCOUNT ATYPE_NORMAL_ACCOUNT /* 0x30000000 805306368 */
+#define ATYPE_GLOBAL_GROUP ATYPE_SECURITY_GLOBAL_GROUP /* 0x10000000 268435456 */
+#define ATYPE_LOCAL_GROUP ATYPE_SECURITY_LOCAL_GROUP /* 0x20000000 536870912 */
/* groupType */
#define GROUP_TYPE_BUILTIN_LOCAL_GROUP 0x00000001
@@ -111,7 +143,7 @@
#define SYSTEM_FLAG_CR_NTDS_DOMAIN 0x00000002
#define SYSTEM_FLAG_CR_NTDS_NOT_GC_REPLICATED 0x00000004
#define SYSTEM_FLAG_SCHEMA_BASE_OBJECT 0x00000010
-#define SYSTEM_FLAG_ATTR_IS_RDN 0x00000020
+#define SYSTEM_FLAG_ATTR_IS_RDN 0x00000020
#define SYSTEM_FLAG_DISALLOW_MOVE_ON_DELETE 0x02000000
#define SYSTEM_FLAG_DOMAIN_DISALLOW_MOVE 0x04000000
#define SYSTEM_FLAG_DOMAIN_DISALLOW_RENAME 0x08000000
@@ -120,18 +152,26 @@
#define SYSTEM_FLAG_CONFIG_ALLOW_RENAME 0x40000000
#define SYSTEM_FLAG_DISALLOW_DELTE 0x80000000
-#define SEARCH_FLAG_ATTINDEX 0x0000001
-#define SEARCH_FLAG_PDNTATTINDEX 0x0000002
-#define SEARCH_FLAG_ANR 0x0000004
-#define SEARCH_FLAG_PRESERVEONDELETE 0x0000008
-#define SEARCH_FLAG_COPY 0x0000010
-#define SEARCH_FLAG_TUPLEINDEX 0x0000020
-#define SEARCH_FLAG_SUBTREEATTRINDEX 0x0000040
-#define SEARCH_FLAG_CONFIDENTIAL 0x0000080
-#define SEARCH_FLAG_NEVERVALUEAUDIT 0x0000100
-#define SEARCH_FLAG_RODC_ATTRIBUTE 0x0000200
+#define SEARCH_FLAG_ATTINDEX 0x0000001
+#define SEARCH_FLAG_PDNTATTINDEX 0x0000002
+#define SEARCH_FLAG_ANR 0x0000004
+#define SEARCH_FLAG_PRESERVEONDELETE 0x0000008
+#define SEARCH_FLAG_COPY 0x0000010
+#define SEARCH_FLAG_TUPLEINDEX 0x0000020
+#define SEARCH_FLAG_SUBTREEATTRINDEX 0x0000040
+#define SEARCH_FLAG_CONFIDENTIAL 0x0000080
+#define SEARCH_FLAG_NEVERVALUEAUDIT 0x0000100
+#define SEARCH_FLAG_RODC_ATTRIBUTE 0x0000200
#define DS_BEHAVIOR_WIN2000 0
#define DS_BEHAVIOR_WIN2003_INTERIM 1
#define DS_BEHAVIOR_WIN2003 2
#define DS_BEHAVIOR_WIN2008 3
+
+/* Settings for the domainFunctionality attribute in the rootDSE */
+
+#define DS_DOMAIN_FUNCTION_2000 0
+#define DS_DOMAIN_FUCNTION_2003_MIXED 1
+#define DS_DOMAIN_FUNCTION_2003 2
+#define DS_DOMAIN_FUNCTION_2008 3
+
diff --git a/librpc/gen_ndr/cli_lsa.c b/librpc/gen_ndr/cli_lsa.c
index 93362537b4..04cf38aaf3 100644
--- a/librpc/gen_ndr/cli_lsa.c
+++ b/librpc/gen_ndr/cli_lsa.c
@@ -1796,12 +1796,18 @@ NTSTATUS rpccli_lsa_DeleteTrustedDomain(struct rpc_pipe_client *cli,
}
NTSTATUS rpccli_lsa_StorePrivateData(struct rpc_pipe_client *cli,
- TALLOC_CTX *mem_ctx)
+ TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle /* [in] [ref] */,
+ struct lsa_String *name /* [in] [ref] */,
+ struct lsa_DATA_BUF *val /* [in] [unique] */)
{
struct lsa_StorePrivateData r;
NTSTATUS status;
/* In parameters */
+ r.in.handle = handle;
+ r.in.name = name;
+ r.in.val = val;
if (DEBUGLEVEL >= 10) {
NDR_PRINT_IN_DEBUG(lsa_StorePrivateData, &r);
@@ -1832,12 +1838,18 @@ NTSTATUS rpccli_lsa_StorePrivateData(struct rpc_pipe_client *cli,
}
NTSTATUS rpccli_lsa_RetrievePrivateData(struct rpc_pipe_client *cli,
- TALLOC_CTX *mem_ctx)
+ TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle /* [in] [ref] */,
+ struct lsa_String *name /* [in] [ref] */,
+ struct lsa_DATA_BUF **val /* [in,out] [ref] */)
{
struct lsa_RetrievePrivateData r;
NTSTATUS status;
/* In parameters */
+ r.in.handle = handle;
+ r.in.name = name;
+ r.in.val = val;
if (DEBUGLEVEL >= 10) {
NDR_PRINT_IN_DEBUG(lsa_RetrievePrivateData, &r);
@@ -1862,6 +1874,7 @@ NTSTATUS rpccli_lsa_RetrievePrivateData(struct rpc_pipe_client *cli,
}
/* Return variables */
+ *val = *r.out.val;
/* Return result */
return r.out.result;
diff --git a/librpc/gen_ndr/cli_lsa.h b/librpc/gen_ndr/cli_lsa.h
index 8dbd7330b4..10c408528f 100644
--- a/librpc/gen_ndr/cli_lsa.h
+++ b/librpc/gen_ndr/cli_lsa.h
@@ -214,9 +214,15 @@ NTSTATUS rpccli_lsa_DeleteTrustedDomain(struct rpc_pipe_client *cli,
struct policy_handle *handle /* [in] [ref] */,
struct dom_sid2 *dom_sid /* [in] [ref] */);
NTSTATUS rpccli_lsa_StorePrivateData(struct rpc_pipe_client *cli,
- TALLOC_CTX *mem_ctx);
+ TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle /* [in] [ref] */,
+ struct lsa_String *name /* [in] [ref] */,
+ struct lsa_DATA_BUF *val /* [in] [unique] */);
NTSTATUS rpccli_lsa_RetrievePrivateData(struct rpc_pipe_client *cli,
- TALLOC_CTX *mem_ctx);
+ TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle /* [in] [ref] */,
+ struct lsa_String *name /* [in] [ref] */,
+ struct lsa_DATA_BUF **val /* [in,out] [ref] */);
NTSTATUS rpccli_lsa_OpenPolicy2(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
const char *system_name /* [in] [unique,charset(UTF16)] */,
diff --git a/librpc/gen_ndr/cli_spoolss.c b/librpc/gen_ndr/cli_spoolss.c
index 66083e6856..38031b615d 100644
--- a/librpc/gen_ndr/cli_spoolss.c
+++ b/librpc/gen_ndr/cli_spoolss.c
@@ -2006,12 +2006,17 @@ NTSTATUS rpccli_spoolss_DeletePort(struct rpc_pipe_client *cli,
NTSTATUS rpccli_spoolss_CreatePrinterIC(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle /* [in] [ref] */,
+ struct policy_handle *gdi_handle /* [out] [ref] */,
+ struct spoolss_DevmodeContainer *devmode_ctr /* [in] [ref] */,
WERROR *werror)
{
struct spoolss_CreatePrinterIC r;
NTSTATUS status;
/* In parameters */
+ r.in.handle = handle;
+ r.in.devmode_ctr = devmode_ctr;
if (DEBUGLEVEL >= 10) {
NDR_PRINT_IN_DEBUG(spoolss_CreatePrinterIC, &r);
@@ -2036,6 +2041,7 @@ NTSTATUS rpccli_spoolss_CreatePrinterIC(struct rpc_pipe_client *cli,
}
/* Return variables */
+ *gdi_handle = *r.out.gdi_handle;
/* Return result */
if (werror) {
@@ -2088,12 +2094,14 @@ NTSTATUS rpccli_spoolss_PlayGDIScriptOnPrinterIC(struct rpc_pipe_client *cli,
NTSTATUS rpccli_spoolss_DeletePrinterIC(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
+ struct policy_handle *gdi_handle /* [in,out] [ref] */,
WERROR *werror)
{
struct spoolss_DeletePrinterIC r;
NTSTATUS status;
/* In parameters */
+ r.in.gdi_handle = gdi_handle;
if (DEBUGLEVEL >= 10) {
NDR_PRINT_IN_DEBUG(spoolss_DeletePrinterIC, &r);
@@ -2118,6 +2126,7 @@ NTSTATUS rpccli_spoolss_DeletePrinterIC(struct rpc_pipe_client *cli,
}
/* Return variables */
+ *gdi_handle = *r.out.gdi_handle;
/* Return result */
if (werror) {
diff --git a/librpc/gen_ndr/cli_spoolss.h b/librpc/gen_ndr/cli_spoolss.h
index baf5d61e2a..b171c69fbd 100644
--- a/librpc/gen_ndr/cli_spoolss.h
+++ b/librpc/gen_ndr/cli_spoolss.h
@@ -294,12 +294,16 @@ NTSTATUS rpccli_spoolss_DeletePort(struct rpc_pipe_client *cli,
WERROR *werror);
NTSTATUS rpccli_spoolss_CreatePrinterIC(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
+ struct policy_handle *handle /* [in] [ref] */,
+ struct policy_handle *gdi_handle /* [out] [ref] */,
+ struct spoolss_DevmodeContainer *devmode_ctr /* [in] [ref] */,
WERROR *werror);
NTSTATUS rpccli_spoolss_PlayGDIScriptOnPrinterIC(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
WERROR *werror);
NTSTATUS rpccli_spoolss_DeletePrinterIC(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
+ struct policy_handle *gdi_handle /* [in,out] [ref] */,
WERROR *werror);
NTSTATUS rpccli_spoolss_AddPrinterConnection(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
diff --git a/librpc/gen_ndr/lsa.h b/librpc/gen_ndr/lsa.h
index 3c9a5d80a6..9ee5fab4c8 100644
--- a/librpc/gen_ndr/lsa.h
+++ b/librpc/gen_ndr/lsa.h
@@ -445,7 +445,7 @@ enum lsa_TrustDomInfoEnum
LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL=10,
LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL=11,
LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL=12,
- LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES=13
+ LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES=13
}
#else
{ __donnot_use_enum_lsa_TrustDomInfoEnum=0x7FFFFFFF}
@@ -461,7 +461,7 @@ enum lsa_TrustDomInfoEnum
#define LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL ( 10 )
#define LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL ( 11 )
#define LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL ( 12 )
-#define LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES ( 13 )
+#define LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES ( 13 )
#endif
;
@@ -603,7 +603,7 @@ union lsa_TrustedDomainInfo {
struct lsa_TrustDomainInfoFullInfoInternal full_info_internal;/* [case(LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL)] */
struct lsa_TrustDomainInfoInfoEx2Internal info_ex2_internal;/* [case(LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL)] */
struct lsa_TrustDomainInfoFullInfo2Internal full_info2_internal;/* [case(LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL)] */
- struct lsa_TrustDomainInfoSupportedEncTypes enc_types;/* [case(LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES)] */
+ struct lsa_TrustDomainInfoSupportedEncTypes enc_types;/* [case(LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES)] */
}/* [switch_type(lsa_TrustDomInfoEnum)] */;
struct lsa_DATA_BUF_PTR {
@@ -1333,6 +1333,12 @@ struct lsa_DeleteTrustedDomain {
struct lsa_StorePrivateData {
struct {
+ struct policy_handle *handle;/* [ref] */
+ struct lsa_String *name;/* [ref] */
+ struct lsa_DATA_BUF *val;/* [unique] */
+ } in;
+
+ struct {
NTSTATUS result;
} out;
@@ -1341,6 +1347,13 @@ struct lsa_StorePrivateData {
struct lsa_RetrievePrivateData {
struct {
+ struct policy_handle *handle;/* [ref] */
+ struct lsa_String *name;/* [ref] */
+ struct lsa_DATA_BUF **val;/* [ref] */
+ } in;
+
+ struct {
+ struct lsa_DATA_BUF **val;/* [ref] */
NTSTATUS result;
} out;
diff --git a/librpc/gen_ndr/ndr_lsa.c b/librpc/gen_ndr/ndr_lsa.c
index 3ad9c41fd7..b8ba679378 100644
--- a/librpc/gen_ndr/ndr_lsa.c
+++ b/librpc/gen_ndr/ndr_lsa.c
@@ -2735,7 +2735,7 @@ _PUBLIC_ void ndr_print_lsa_TrustDomInfoEnum(struct ndr_print *ndr, const char *
case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL: val = "LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL"; break;
case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL: val = "LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL"; break;
case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL: val = "LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL"; break;
- case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES: val = "LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES"; break;
+ case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES: val = "LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES"; break;
}
ndr_print_enum(ndr, name, "ENUM", val, r);
}
@@ -3662,7 +3662,7 @@ static enum ndr_err_code ndr_push_lsa_TrustedDomainInfo(struct ndr_push *ndr, in
NDR_CHECK(ndr_push_lsa_TrustDomainInfoFullInfo2Internal(ndr, NDR_SCALARS, &r->full_info2_internal));
break; }
- case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES: {
+ case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES: {
NDR_CHECK(ndr_push_lsa_TrustDomainInfoSupportedEncTypes(ndr, NDR_SCALARS, &r->enc_types));
break; }
@@ -3720,7 +3720,7 @@ static enum ndr_err_code ndr_push_lsa_TrustedDomainInfo(struct ndr_push *ndr, in
NDR_CHECK(ndr_push_lsa_TrustDomainInfoFullInfo2Internal(ndr, NDR_BUFFERS, &r->full_info2_internal));
break;
- case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES:
+ case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
break;
default:
@@ -3789,7 +3789,7 @@ static enum ndr_err_code ndr_pull_lsa_TrustedDomainInfo(struct ndr_pull *ndr, in
NDR_CHECK(ndr_pull_lsa_TrustDomainInfoFullInfo2Internal(ndr, NDR_SCALARS, &r->full_info2_internal));
break; }
- case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES: {
+ case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES: {
NDR_CHECK(ndr_pull_lsa_TrustDomainInfoSupportedEncTypes(ndr, NDR_SCALARS, &r->enc_types));
break; }
@@ -3846,7 +3846,7 @@ static enum ndr_err_code ndr_pull_lsa_TrustedDomainInfo(struct ndr_pull *ndr, in
NDR_CHECK(ndr_pull_lsa_TrustDomainInfoFullInfo2Internal(ndr, NDR_BUFFERS, &r->full_info2_internal));
break;
- case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES:
+ case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
break;
default:
@@ -3910,7 +3910,7 @@ _PUBLIC_ void ndr_print_lsa_TrustedDomainInfo(struct ndr_print *ndr, const char
ndr_print_lsa_TrustDomainInfoFullInfo2Internal(ndr, "full_info2_internal", &r->full_info2_internal);
break;
- case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES:
+ case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
ndr_print_lsa_TrustDomainInfoSupportedEncTypes(ndr, "enc_types", &r->enc_types);
break;
@@ -9225,6 +9225,18 @@ _PUBLIC_ void ndr_print_lsa_DeleteTrustedDomain(struct ndr_print *ndr, const cha
static enum ndr_err_code ndr_push_lsa_StorePrivateData(struct ndr_push *ndr, int flags, const struct lsa_StorePrivateData *r)
{
if (flags & NDR_IN) {
+ if (r->in.handle == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->in.handle));
+ if (r->in.name == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.name));
+ NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.val));
+ if (r->in.val) {
+ NDR_CHECK(ndr_push_lsa_DATA_BUF(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.val));
+ }
}
if (flags & NDR_OUT) {
NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result));
@@ -9234,7 +9246,37 @@ static enum ndr_err_code ndr_push_lsa_StorePrivateData(struct ndr_push *ndr, int
static enum ndr_err_code ndr_pull_lsa_StorePrivateData(struct ndr_pull *ndr, int flags, struct lsa_StorePrivateData *r)
{
+ uint32_t _ptr_val;
+ TALLOC_CTX *_mem_save_handle_0;
+ TALLOC_CTX *_mem_save_name_0;
+ TALLOC_CTX *_mem_save_val_0;
if (flags & NDR_IN) {
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->in.handle);
+ }
+ _mem_save_handle_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->in.handle, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->in.handle));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC);
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->in.name);
+ }
+ _mem_save_name_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->in.name, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.name));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_name_0, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_val));
+ if (_ptr_val) {
+ NDR_PULL_ALLOC(ndr, r->in.val);
+ } else {
+ r->in.val = NULL;
+ }
+ if (r->in.val) {
+ _mem_save_val_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->in.val, 0);
+ NDR_CHECK(ndr_pull_lsa_DATA_BUF(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.val));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_val_0, 0);
+ }
}
if (flags & NDR_OUT) {
NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result));
@@ -9252,6 +9294,20 @@ _PUBLIC_ void ndr_print_lsa_StorePrivateData(struct ndr_print *ndr, const char *
if (flags & NDR_IN) {
ndr_print_struct(ndr, "in", "lsa_StorePrivateData");
ndr->depth++;
+ ndr_print_ptr(ndr, "handle", r->in.handle);
+ ndr->depth++;
+ ndr_print_policy_handle(ndr, "handle", r->in.handle);
+ ndr->depth--;
+ ndr_print_ptr(ndr, "name", r->in.name);
+ ndr->depth++;
+ ndr_print_lsa_String(ndr, "name", r->in.name);
+ ndr->depth--;
+ ndr_print_ptr(ndr, "val", r->in.val);
+ ndr->depth++;
+ if (r->in.val) {
+ ndr_print_lsa_DATA_BUF(ndr, "val", r->in.val);
+ }
+ ndr->depth--;
ndr->depth--;
}
if (flags & NDR_OUT) {
@@ -9266,8 +9322,30 @@ _PUBLIC_ void ndr_print_lsa_StorePrivateData(struct ndr_print *ndr, const char *
static enum ndr_err_code ndr_push_lsa_RetrievePrivateData(struct ndr_push *ndr, int flags, const struct lsa_RetrievePrivateData *r)
{
if (flags & NDR_IN) {
+ if (r->in.handle == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->in.handle));
+ if (r->in.name == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.name));
+ if (r->in.val == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_unique_ptr(ndr, *r->in.val));
+ if (*r->in.val) {
+ NDR_CHECK(ndr_push_lsa_DATA_BUF(ndr, NDR_SCALARS|NDR_BUFFERS, *r->in.val));
+ }
}
if (flags & NDR_OUT) {
+ if (r->out.val == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.val));
+ if (*r->out.val) {
+ NDR_CHECK(ndr_push_lsa_DATA_BUF(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.val));
+ }
NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result));
}
return NDR_ERR_SUCCESS;
@@ -9275,9 +9353,68 @@ static enum ndr_err_code ndr_push_lsa_RetrievePrivateData(struct ndr_push *ndr,
static enum ndr_err_code ndr_pull_lsa_RetrievePrivateData(struct ndr_pull *ndr, int flags, struct lsa_RetrievePrivateData *r)
{
+ uint32_t _ptr_val;
+ TALLOC_CTX *_mem_save_handle_0;
+ TALLOC_CTX *_mem_save_name_0;
+ TALLOC_CTX *_mem_save_val_0;
+ TALLOC_CTX *_mem_save_val_1;
if (flags & NDR_IN) {
+ ZERO_STRUCT(r->out);
+
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->in.handle);
+ }
+ _mem_save_handle_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->in.handle, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->in.handle));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC);
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->in.name);
+ }
+ _mem_save_name_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->in.name, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.name));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_name_0, LIBNDR_FLAG_REF_ALLOC);
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->in.val);
+ }
+ _mem_save_val_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->in.val, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_val));
+ if (_ptr_val) {
+ NDR_PULL_ALLOC(ndr, *r->in.val);
+ } else {
+ *r->in.val = NULL;
+ }
+ if (*r->in.val) {
+ _mem_save_val_1 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, *r->in.val, 0);
+ NDR_CHECK(ndr_pull_lsa_DATA_BUF(ndr, NDR_SCALARS|NDR_BUFFERS, *r->in.val));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_val_1, 0);
+ }
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_val_0, LIBNDR_FLAG_REF_ALLOC);
+ NDR_PULL_ALLOC(ndr, r->out.val);
+ *r->out.val = *r->in.val;
}
if (flags & NDR_OUT) {
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->out.val);
+ }
+ _mem_save_val_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->out.val, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_val));
+ if (_ptr_val) {
+ NDR_PULL_ALLOC(ndr, *r->out.val);
+ } else {
+ *r->out.val = NULL;
+ }
+ if (*r->out.val) {
+ _mem_save_val_1 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, *r->out.val, 0);
+ NDR_CHECK(ndr_pull_lsa_DATA_BUF(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.val));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_val_1, 0);
+ }
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_val_0, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result));
}
return NDR_ERR_SUCCESS;
@@ -9293,11 +9430,37 @@ _PUBLIC_ void ndr_print_lsa_RetrievePrivateData(struct ndr_print *ndr, const cha
if (flags & NDR_IN) {
ndr_print_struct(ndr, "in", "lsa_RetrievePrivateData");
ndr->depth++;
+ ndr_print_ptr(ndr, "handle", r->in.handle);
+ ndr->depth++;
+ ndr_print_policy_handle(ndr, "handle", r->in.handle);
+ ndr->depth--;
+ ndr_print_ptr(ndr, "name", r->in.name);
+ ndr->depth++;
+ ndr_print_lsa_String(ndr, "name", r->in.name);
+ ndr->depth--;
+ ndr_print_ptr(ndr, "val", r->in.val);
+ ndr->depth++;
+ ndr_print_ptr(ndr, "val", *r->in.val);
+ ndr->depth++;
+ if (*r->in.val) {
+ ndr_print_lsa_DATA_BUF(ndr, "val", *r->in.val);
+ }
+ ndr->depth--;
+ ndr->depth--;
ndr->depth--;
}
if (flags & NDR_OUT) {
ndr_print_struct(ndr, "out", "lsa_RetrievePrivateData");
ndr->depth++;
+ ndr_print_ptr(ndr, "val", r->out.val);
+ ndr->depth++;
+ ndr_print_ptr(ndr, "val", *r->out.val);
+ ndr->depth++;
+ if (*r->out.val) {
+ ndr_print_lsa_DATA_BUF(ndr, "val", *r->out.val);
+ }
+ ndr->depth--;
+ ndr->depth--;
ndr_print_NTSTATUS(ndr, "result", r->out.result);
ndr->depth--;
}
diff --git a/librpc/gen_ndr/ndr_samr.c b/librpc/gen_ndr/ndr_samr.c
index 58b7ae2413..258aba9bb6 100644
--- a/librpc/gen_ndr/ndr_samr.c
+++ b/librpc/gen_ndr/ndr_samr.c
@@ -4831,12 +4831,14 @@ _PUBLIC_ void ndr_print_samr_ValidationStatus(struct ndr_print *ndr, const char
case SAMR_VALIDATION_STATUS_SUCCESS: val = "SAMR_VALIDATION_STATUS_SUCCESS"; break;
case SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE: val = "SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE"; break;
case SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT: val = "SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT"; break;
+ case SAMR_VALIDATION_STATUS_PASSWORD_EXPIRED: val = "SAMR_VALIDATION_STATUS_PASSWORD_EXPIRED"; break;
case SAMR_VALIDATION_STATUS_BAD_PASSWORD: val = "SAMR_VALIDATION_STATUS_BAD_PASSWORD"; break;
case SAMR_VALIDATION_STATUS_PWD_HISTORY_CONFLICT: val = "SAMR_VALIDATION_STATUS_PWD_HISTORY_CONFLICT"; break;
case SAMR_VALIDATION_STATUS_PWD_TOO_SHORT: val = "SAMR_VALIDATION_STATUS_PWD_TOO_SHORT"; break;
case SAMR_VALIDATION_STATUS_PWD_TOO_LONG: val = "SAMR_VALIDATION_STATUS_PWD_TOO_LONG"; break;
case SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH: val = "SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH"; break;
case SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT: val = "SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT"; break;
+ case SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR: val = "SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR"; break;
}
ndr_print_enum(ndr, name, "ENUM", val, r);
}
diff --git a/librpc/gen_ndr/ndr_spoolss.c b/librpc/gen_ndr/ndr_spoolss.c
index a1be2fd92c..fedebb2d56 100644
--- a/librpc/gen_ndr/ndr_spoolss.c
+++ b/librpc/gen_ndr/ndr_spoolss.c
@@ -14464,7 +14464,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_OSVersion(struct ndr_pull *ndr, int
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->major));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->minor));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->build));
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->platform_id));
{
uint32_t _flags_save_string = ndr->flags;
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
@@ -14490,7 +14490,7 @@ _PUBLIC_ void ndr_print_spoolss_OSVersion(struct ndr_print *ndr, const char *nam
ndr_print_uint32(ndr, "major", r->major);
ndr_print_uint32(ndr, "minor", r->minor);
ndr_print_uint32(ndr, "build", r->build);
- ndr_print_uint32(ndr, "unknown", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2:r->unknown);
+ ndr_print_uint32(ndr, "platform_id", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2:r->platform_id);
ndr_print_string(ndr, "extra_string", r->extra_string);
ndr->depth--;
}
@@ -14520,8 +14520,11 @@ _PUBLIC_ enum ndr_err_code ndr_push_spoolss_OSVersionEx(struct ndr_push *ndr, in
}
ndr->flags = _flags_save_string;
}
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->unknown2));
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->unknown3));
+ NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->service_pack_major));
+ NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->service_pack_minor));
+ NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->suite_mask));
+ NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->product_type));
+ NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->reserved));
}
if (ndr_flags & NDR_BUFFERS) {
}
@@ -14536,7 +14539,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_OSVersionEx(struct ndr_pull *ndr, in
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->major));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->minor));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->build));
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown1));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->platform_id));
{
uint32_t _flags_save_string = ndr->flags;
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
@@ -14548,8 +14551,11 @@ _PUBLIC_ enum ndr_err_code ndr_pull_spoolss_OSVersionEx(struct ndr_pull *ndr, in
}
ndr->flags = _flags_save_string;
}
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown2));
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown3));
+ NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->service_pack_major));
+ NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->service_pack_minor));
+ NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->suite_mask));
+ NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->product_type));
+ NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->reserved));
}
if (ndr_flags & NDR_BUFFERS) {
}
@@ -14564,10 +14570,13 @@ _PUBLIC_ void ndr_print_spoolss_OSVersionEx(struct ndr_print *ndr, const char *n
ndr_print_uint32(ndr, "major", r->major);
ndr_print_uint32(ndr, "minor", r->minor);
ndr_print_uint32(ndr, "build", r->build);
- ndr_print_uint32(ndr, "unknown1", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2:r->unknown1);
+ ndr_print_uint32(ndr, "platform_id", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2:r->platform_id);
ndr_print_string(ndr, "extra_string", r->extra_string);
- ndr_print_uint32(ndr, "unknown2", r->unknown2);
- ndr_print_uint32(ndr, "unknown3", r->unknown3);
+ ndr_print_uint16(ndr, "service_pack_major", r->service_pack_major);
+ ndr_print_uint16(ndr, "service_pack_minor", r->service_pack_minor);
+ ndr_print_uint16(ndr, "suite_mask", r->suite_mask);
+ ndr_print_uint8(ndr, "product_type", r->product_type);
+ ndr_print_uint8(ndr, "reserved", r->reserved);
ndr->depth--;
}
@@ -23702,8 +23711,20 @@ _PUBLIC_ void ndr_print_spoolss_DeletePort(struct ndr_print *ndr, const char *na
static enum ndr_err_code ndr_push_spoolss_CreatePrinterIC(struct ndr_push *ndr, int flags, const struct spoolss_CreatePrinterIC *r)
{
if (flags & NDR_IN) {
+ if (r->in.handle == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->in.handle));
+ if (r->in.devmode_ctr == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_spoolss_DevmodeContainer(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.devmode_ctr));
}
if (flags & NDR_OUT) {
+ if (r->out.gdi_handle == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->out.gdi_handle));
NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result));
}
return NDR_ERR_SUCCESS;
@@ -23711,9 +23732,37 @@ static enum ndr_err_code ndr_push_spoolss_CreatePrinterIC(struct ndr_push *ndr,
static enum ndr_err_code ndr_pull_spoolss_CreatePrinterIC(struct ndr_pull *ndr, int flags, struct spoolss_CreatePrinterIC *r)
{
+ TALLOC_CTX *_mem_save_handle_0;
+ TALLOC_CTX *_mem_save_gdi_handle_0;
+ TALLOC_CTX *_mem_save_devmode_ctr_0;
if (flags & NDR_IN) {
+ ZERO_STRUCT(r->out);
+
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->in.handle);
+ }
+ _mem_save_handle_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->in.handle, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->in.handle));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC);
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->in.devmode_ctr);
+ }
+ _mem_save_devmode_ctr_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->in.devmode_ctr, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_spoolss_DevmodeContainer(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.devmode_ctr));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_devmode_ctr_0, LIBNDR_FLAG_REF_ALLOC);
+ NDR_PULL_ALLOC(ndr, r->out.gdi_handle);
+ ZERO_STRUCTP(r->out.gdi_handle);
}
if (flags & NDR_OUT) {
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->out.gdi_handle);
+ }
+ _mem_save_gdi_handle_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->out.gdi_handle, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->out.gdi_handle));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_gdi_handle_0, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result));
}
return NDR_ERR_SUCCESS;
@@ -23729,11 +23778,23 @@ _PUBLIC_ void ndr_print_spoolss_CreatePrinterIC(struct ndr_print *ndr, const cha
if (flags & NDR_IN) {
ndr_print_struct(ndr, "in", "spoolss_CreatePrinterIC");
ndr->depth++;
+ ndr_print_ptr(ndr, "handle", r->in.handle);
+ ndr->depth++;
+ ndr_print_policy_handle(ndr, "handle", r->in.handle);
+ ndr->depth--;
+ ndr_print_ptr(ndr, "devmode_ctr", r->in.devmode_ctr);
+ ndr->depth++;
+ ndr_print_spoolss_DevmodeContainer(ndr, "devmode_ctr", r->in.devmode_ctr);
+ ndr->depth--;
ndr->depth--;
}
if (flags & NDR_OUT) {
ndr_print_struct(ndr, "out", "spoolss_CreatePrinterIC");
ndr->depth++;
+ ndr_print_ptr(ndr, "gdi_handle", r->out.gdi_handle);
+ ndr->depth++;
+ ndr_print_policy_handle(ndr, "gdi_handle", r->out.gdi_handle);
+ ndr->depth--;
ndr_print_WERROR(ndr, "result", r->out.result);
ndr->depth--;
}
@@ -23784,8 +23845,16 @@ _PUBLIC_ void ndr_print_spoolss_PlayGDIScriptOnPrinterIC(struct ndr_print *ndr,
static enum ndr_err_code ndr_push_spoolss_DeletePrinterIC(struct ndr_push *ndr, int flags, const struct spoolss_DeletePrinterIC *r)
{
if (flags & NDR_IN) {
+ if (r->in.gdi_handle == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->in.gdi_handle));
}
if (flags & NDR_OUT) {
+ if (r->out.gdi_handle == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->out.gdi_handle));
NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result));
}
return NDR_ERR_SUCCESS;
@@ -23793,9 +23862,28 @@ static enum ndr_err_code ndr_push_spoolss_DeletePrinterIC(struct ndr_push *ndr,
static enum ndr_err_code ndr_pull_spoolss_DeletePrinterIC(struct ndr_pull *ndr, int flags, struct spoolss_DeletePrinterIC *r)
{
+ TALLOC_CTX *_mem_save_gdi_handle_0;
if (flags & NDR_IN) {
+ ZERO_STRUCT(r->out);
+
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->in.gdi_handle);
+ }
+ _mem_save_gdi_handle_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->in.gdi_handle, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->in.gdi_handle));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_gdi_handle_0, LIBNDR_FLAG_REF_ALLOC);
+ NDR_PULL_ALLOC(ndr, r->out.gdi_handle);
+ *r->out.gdi_handle = *r->in.gdi_handle;
}
if (flags & NDR_OUT) {
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC(ndr, r->out.gdi_handle);
+ }
+ _mem_save_gdi_handle_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->out.gdi_handle, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS, r->out.gdi_handle));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_gdi_handle_0, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result));
}
return NDR_ERR_SUCCESS;
@@ -23811,11 +23899,19 @@ _PUBLIC_ void ndr_print_spoolss_DeletePrinterIC(struct ndr_print *ndr, const cha
if (flags & NDR_IN) {
ndr_print_struct(ndr, "in", "spoolss_DeletePrinterIC");
ndr->depth++;
+ ndr_print_ptr(ndr, "gdi_handle", r->in.gdi_handle);
+ ndr->depth++;
+ ndr_print_policy_handle(ndr, "gdi_handle", r->in.gdi_handle);
+ ndr->depth--;
ndr->depth--;
}
if (flags & NDR_OUT) {
ndr_print_struct(ndr, "out", "spoolss_DeletePrinterIC");
ndr->depth++;
+ ndr_print_ptr(ndr, "gdi_handle", r->out.gdi_handle);
+ ndr->depth++;
+ ndr_print_policy_handle(ndr, "gdi_handle", r->out.gdi_handle);
+ ndr->depth--;
ndr_print_WERROR(ndr, "result", r->out.result);
ndr->depth--;
}
diff --git a/librpc/gen_ndr/samr.h b/librpc/gen_ndr/samr.h
index e44de1b037..ce84b45a9e 100644
--- a/librpc/gen_ndr/samr.h
+++ b/librpc/gen_ndr/samr.h
@@ -834,24 +834,28 @@ enum samr_ValidationStatus
SAMR_VALIDATION_STATUS_SUCCESS=0,
SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE=1,
SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT=2,
+ SAMR_VALIDATION_STATUS_PASSWORD_EXPIRED=3,
SAMR_VALIDATION_STATUS_BAD_PASSWORD=4,
SAMR_VALIDATION_STATUS_PWD_HISTORY_CONFLICT=5,
SAMR_VALIDATION_STATUS_PWD_TOO_SHORT=6,
SAMR_VALIDATION_STATUS_PWD_TOO_LONG=7,
SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH=8,
- SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT=9
+ SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT=9,
+ SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR=10
}
#else
{ __donnot_use_enum_samr_ValidationStatus=0x7FFFFFFF}
#define SAMR_VALIDATION_STATUS_SUCCESS ( 0 )
#define SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE ( 1 )
#define SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT ( 2 )
+#define SAMR_VALIDATION_STATUS_PASSWORD_EXPIRED ( 3 )
#define SAMR_VALIDATION_STATUS_BAD_PASSWORD ( 4 )
#define SAMR_VALIDATION_STATUS_PWD_HISTORY_CONFLICT ( 5 )
#define SAMR_VALIDATION_STATUS_PWD_TOO_SHORT ( 6 )
#define SAMR_VALIDATION_STATUS_PWD_TOO_LONG ( 7 )
#define SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH ( 8 )
#define SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT ( 9 )
+#define SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR ( 10 )
#endif
;
diff --git a/librpc/gen_ndr/spoolss.h b/librpc/gen_ndr/spoolss.h
index 9446193863..1a9d393e09 100644
--- a/librpc/gen_ndr/spoolss.h
+++ b/librpc/gen_ndr/spoolss.h
@@ -1058,7 +1058,7 @@ struct spoolss_OSVersion {
uint32_t major;
uint32_t minor;
uint32_t build;
- uint32_t unknown;/* [value(2)] */
+ uint32_t platform_id;/* [value(2)] */
const char * extra_string;/* [subcontext_size(256),subcontext(0),flag(LIBNDR_FLAG_STR_NULLTERM)] */
}/* [gensize,public] */;
@@ -1067,10 +1067,13 @@ struct spoolss_OSVersionEx {
uint32_t major;
uint32_t minor;
uint32_t build;
- uint32_t unknown1;/* [value(2)] */
+ uint32_t platform_id;/* [value(2)] */
const char * extra_string;/* [subcontext_size(256),subcontext(0),flag(LIBNDR_FLAG_STR_NULLTERM)] */
- uint32_t unknown2;
- uint32_t unknown3;
+ uint16_t service_pack_major;
+ uint16_t service_pack_minor;
+ uint16_t suite_mask;
+ uint8_t product_type;
+ uint8_t reserved;
}/* [gensize,public] */;
union spoolss_PrinterData {
@@ -2516,6 +2519,12 @@ struct spoolss_DeletePort {
struct spoolss_CreatePrinterIC {
struct {
+ struct policy_handle *handle;/* [ref] */
+ struct spoolss_DevmodeContainer *devmode_ctr;/* [ref] */
+ } in;
+
+ struct {
+ struct policy_handle *gdi_handle;/* [ref] */
WERROR result;
} out;
@@ -2532,6 +2541,11 @@ struct spoolss_PlayGDIScriptOnPrinterIC {
struct spoolss_DeletePrinterIC {
struct {
+ struct policy_handle *gdi_handle;/* [ref] */
+ } in;
+
+ struct {
+ struct policy_handle *gdi_handle;/* [ref] */
WERROR result;
} out;
diff --git a/librpc/gen_ndr/srv_lsa.c b/librpc/gen_ndr/srv_lsa.c
index c86d0857f8..f1b4a06d0d 100644
--- a/librpc/gen_ndr/srv_lsa.c
+++ b/librpc/gen_ndr/srv_lsa.c
@@ -3366,6 +3366,8 @@ static bool api_lsa_RetrievePrivateData(pipes_struct *p)
NDR_PRINT_IN_DEBUG(lsa_RetrievePrivateData, r);
}
+ ZERO_STRUCT(r->out);
+ r->out.val = r->in.val;
r->out.result = _lsa_RetrievePrivateData(p, r);
if (p->rng_fault_state) {
@@ -6810,6 +6812,8 @@ NTSTATUS rpc_lsarpc_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, c
case NDR_LSA_RETRIEVEPRIVATEDATA: {
struct lsa_RetrievePrivateData *r = (struct lsa_RetrievePrivateData *)_r;
+ ZERO_STRUCT(r->out);
+ r->out.val = r->in.val;
r->out.result = _lsa_RetrievePrivateData(cli->pipes_struct, r);
return NT_STATUS_OK;
}
diff --git a/librpc/gen_ndr/srv_spoolss.c b/librpc/gen_ndr/srv_spoolss.c
index 41a79b4a79..ae99f098a6 100644
--- a/librpc/gen_ndr/srv_spoolss.c
+++ b/librpc/gen_ndr/srv_spoolss.c
@@ -3245,6 +3245,13 @@ static bool api_spoolss_CreatePrinterIC(pipes_struct *p)
NDR_PRINT_IN_DEBUG(spoolss_CreatePrinterIC, r);
}
+ ZERO_STRUCT(r->out);
+ r->out.gdi_handle = talloc_zero(r, struct policy_handle);
+ if (r->out.gdi_handle == NULL) {
+ talloc_free(r);
+ return false;
+ }
+
r->out.result = _spoolss_CreatePrinterIC(p, r);
if (p->rng_fault_state) {
@@ -3391,6 +3398,8 @@ static bool api_spoolss_DeletePrinterIC(pipes_struct *p)
NDR_PRINT_IN_DEBUG(spoolss_DeletePrinterIC, r);
}
+ ZERO_STRUCT(r->out);
+ r->out.gdi_handle = r->in.gdi_handle;
r->out.result = _spoolss_DeletePrinterIC(p, r);
if (p->rng_fault_state) {
@@ -8068,6 +8077,12 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
case NDR_SPOOLSS_CREATEPRINTERIC: {
struct spoolss_CreatePrinterIC *r = (struct spoolss_CreatePrinterIC *)_r;
+ ZERO_STRUCT(r->out);
+ r->out.gdi_handle = talloc_zero(mem_ctx, struct policy_handle);
+ if (r->out.gdi_handle == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
r->out.result = _spoolss_CreatePrinterIC(cli->pipes_struct, r);
return NT_STATUS_OK;
}
@@ -8080,6 +8095,8 @@ NTSTATUS rpc_spoolss_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
case NDR_SPOOLSS_DELETEPRINTERIC: {
struct spoolss_DeletePrinterIC *r = (struct spoolss_DeletePrinterIC *)_r;
+ ZERO_STRUCT(r->out);
+ r->out.gdi_handle = r->in.gdi_handle;
r->out.result = _spoolss_DeletePrinterIC(cli->pipes_struct, r);
return NT_STATUS_OK;
}
diff --git a/librpc/idl/frsapi.idl b/librpc/idl/frsapi.idl
index 11593f479a..ea7880c9f8 100644
--- a/librpc/idl/frsapi.idl
+++ b/librpc/idl/frsapi.idl
@@ -98,24 +98,31 @@ interface frsapi
WERROR frsapi_IsPathReplicated(
[in,unique] [string,charset(UTF16)] uint16 *path,
[in] frsapi_ReplicaSetType replica_set_type,
- [out] uint32 *unknown1,
- [out] uint32 *unknown2,
- [out] uint32 *unknown3,
+ [out] uint32 *replicated,
+ [out] uint32 *primary,
+ [out] uint32 *root,
[out] GUID *replica_set_guid
);
/****************/
/* Function 0x09 */
- [todo] void FRSAPI_WRITER_COMMAND();
+ typedef [v1_enum] enum {
+ FRSAPI_WRITER_COMMAND_FREEZE = 0x00000001,
+ FRSAPI_WRITER_COMMAND_THAW = 0x00000002
+ } frsapi_WriterCommandsValues;
+
+ WERROR frsapi_WriterCommand(
+ [in] frsapi_WriterCommandsValues command
+ );
/****************/
/* Function 0x0a */
/* not supported before w2k3 sp2 */
WERROR frsapi_ForceReplication(
- [in,unique] GUID *guid1,
- [in,unique] GUID *guid2,
- [in,unique] [charset(UTF16),string] uint16 *replica_set,
- [in,unique] [charset(UTF16),string] uint16 *partner_name
+ [in,unique] GUID *replica_set_guid,
+ [in,unique] GUID *connection_guid,
+ [in,unique] [charset(UTF16),string] uint16 *replica_set_name,
+ [in,unique] [charset(UTF16),string] uint16 *partner_dns_name
);
}
diff --git a/librpc/idl/frsrpc.idl b/librpc/idl/frsrpc.idl
index 1019a25b28..cab155295d 100644
--- a/librpc/idl/frsrpc.idl
+++ b/librpc/idl/frsrpc.idl
@@ -7,6 +7,7 @@ import "misc.idl";
version(1.1),
endpoint("ncacn_ip_tcp:", "ncalrpc:"),
helpstring("File Replication Service"),
+ helper("../librpc/ndr/ndr_frsrpc.h"),
pointer_default(unique)
]
interface frsrpc
@@ -14,112 +15,337 @@ interface frsrpc
/*****************/
/* Function 0x00 */
- /* TAG:3 this TLV contains a GUID and the name of the server sending
- * the call
- */
typedef struct {
- [subcontext(4)] GUID unknown1;
- [subcontext(4)] nstring source_server;
- } frsrpc_FrsSendCommPktChunkDataSSRV;
+ [subcontext(4)] GUID guid;
+ [subcontext(4)] nstring name;
+ } frsrpc_CommPktChunkGuidName;
- /* TAG:4 this TLV contains a GUID and the name of the destination
- * server the PDU is sent to
- */
typedef struct {
- [subcontext(4)] GUID unknown1;
- [subcontext(4)] nstring dest_server;
- } frsrpc_FrsSendCommPktChunkDataDSRV;
+ hyper vsn;
+ GUID guid;
+ } frsrpc_CommPktGSVN;
+
+ typedef [bitmap32bit,flag(NDR_PAHEX)] bitmap {
+ FRSRPC_CO_FLAG_ABORT_CO = 0x00000001,
+ FRSRPC_CO_FLAG_VV_ACTIVATED = 0x00000002,
+ FRSRPC_CO_FLAG_CONTENT_CMD = 0x00000004,
+ FRSRPC_CO_FLAG_LOCATION_CMD = 0x00000008,
+ FRSRPC_CO_FLAG_ONLIST = 0x00000010,
+ FRSRPC_CO_FLAG_LOCALCO = 0x00000020,
+ FRSRPC_CO_FLAG_RETRY = 0x00000040,
+ FRSRPC_CO_FLAG_OUT_OF_ORDER = 0x00000200,
+ FRSRPC_CO_FLAG_NEW_FILE = 0x00000400,
+ FRSRPC_CO_FLAG_CONTROL = 0x00001000,
+ FRSRPC_CO_FLAG_DIRECTED_CO = 0x00002000,
+ FRSRPC_CO_FLAG_VVJOIN_TO_ORIG = 0x00040000,
+ FRSRPC_CO_FLAG_SKIP_ORIG_REC_C = 0x00100000,
+ FRSRPC_CO_FLAG_MOVEIN_GEN = 0x00200000,
+ FRSRPC_CO_FLAG_MORPH_GEN_HEAD = 0x00400000,
+ FRSRPC_CO_FLAG_JUST_OID_RESET = 0x00800000,
+ FRSRPC_CO_FLAG_COMPRESSED_STAGE = 0x01000000,
+ FRSRPC_CO_FLAG_COMPRESSED_STAGE = 0x01000000,
+ FRSRPC_CO_FLAG_SKIP_VV_UPDATE = 0x02000000
+ } frsrpc_CommPktCoCmdFlags;
+
+ const uint32 FRSRPC_CO_IFLAG_NONE = 0x0000000;
+
+ typedef [bitmap32bit,flag(NDR_PAHEX)] bitmap {
+ FRSRPC_CO_IFLAG_VVRETIRE_EXEC = 0x00000001,
+ FRSRPC_CO_IFLAG_CO_ABORT = 0x00000002,
+ FRSRPC_CO_IFLAG_DIR_ENUM_PENDING= 0x00000004
+ } frsrpc_CommPktCoCmdIFlags;
+
+ typedef [v1_enum,flag(NDR_PAHEX)] enum {
+ FRSRPC_CO_STATUS_CO_ENTERED_LOG = 0x00000000,
+ FRSRPC_CO_STATUS_ALLOC_STAGING_LOCAL_CO = 0x00000001,
+ FRSRPC_CO_STATUS_LOCAL_CO_STAGING_STARTED = 0x00000002,
+ FRSRPC_CO_STATUS_LOCAL_CO_STAGING_COMPLETED = 0x00000003,
+ FRSRPC_CO_STATUS_WAIT_RETRY_LOCAL_CO_STAGING = 0x00000004,
+ FRSRPC_CO_STATUS_ALLOC_STAGING_REMOTE_CO = 0x00000005,
+ FRSRPC_CO_STATUS_REMOTE_CO_STAGING_STARTED = 0x00000006,
+ FRSRPC_CO_STATUS_REMOTE_CO_STAGING_COMPLETED = 0x00000007,
+ FRSRPC_CO_STATUS_WAIT_RETRY_REMOTE_CO_STAGING = 0x00000008,
+ FRSRPC_CO_STATUS_FILE_INSTALL_REQUESTED = 0x00000009,
+ FRSRPC_CO_STATUS_FILE_INSTALL_STARTED = 0x0000000A,
+ FRSRPC_CO_STATUS_FILE_INSTALL_COMPLETED = 0x0000000B,
+ FRSRPC_CO_STATUS_FILE_INSTALL_WAIT_RETRY = 0x0000000C,
+ FRSRPC_CO_STATUS_FILE_INSTALL_RETRYING = 0x0000000D,
+ FRSRPC_CO_STATUS_FILE_INSTALL_RENAME_RETRYING = 0x0000000E,
+ FRSRPC_CO_STATUS_FILE_INSTALL_DELETE_RETRYING = 0x0000000F,
+ FRSRPC_CO_STATUS_CO_RECYCLED_FOR_ENUM = 0x00000013,
+ FRSRPC_CO_STATUS_REQUEST_OUTBOUND_PROPAGATION = 0x00000014,
+ FRSRPC_CO_STATUS_REQUEST_ACCEPTED_OUTBOUND_LOG = 0x00000015,
+ FRSRPC_CO_STATUS_DB_STATE_UPDATE_STARTED = 0x00000016,
+ FRSRPC_CO_STATUS_DB_STATE_UPDATE_COMPLETED = 0x00000017,
+ FRSRPC_CO_STATUS_CO_ABORTED = 0x00000018
+ } frsrpc_CommPktCoCmdStatus;
+
+ typedef [bitmap32bit,flag(NDR_PAHEX)] bitmap {
+ FRSRPC_CONTENT_REASON_DATA_OVERWRITE = 0x00000001,
+ FRSRPC_CONTENT_REASON_DATA_EXTEND = 0x00000002,
+ FRSRPC_CONTENT_REASON_DATA_TRUNCATION = 0x00000004,
+ FRSRPC_CONTENT_REASON_NAMED_DATA_OVERWRITE = 0x00000010,
+ FRSRPC_CONTENT_REASON_NAMED_DATA_EXTEND = 0x00000020,
+ FRSRPC_CONTENT_REASON_NAMED_DATA_TRUNCATION = 0x00000040,
+ FRSRPC_CONTENT_REASON_FILE_CREATE = 0x00000100,
+ FRSRPC_CONTENT_REASON_FILE_DELETE = 0x00000200,
+ FRSRPC_CONTENT_REASON_EA_CHANGE = 0x00000400,
+ FRSRPC_CONTENT_REASON_SECURITY_CHANGE = 0x00000800,
+ FRSRPC_CONTENT_REASON_OLD_NAME = 0x00001000,
+ FRSRPC_CONTENT_REASON_NEW_NAME = 0x00002000,
+ FRSRPC_CONTENT_REASON_BASIC_INFO_CHANGE = 0x00004000,
+ FRSRPC_CONTENT_REASON_COMPRESSION_CHANGE = 0x00020000
+ } frsrpc_CommPktCoCmdContentCmd;
+
+ typedef [v1_enum,flag(NDR_PAHEX)] enum {
+ FRSRPC_CO_LOCATION_FILE_CREATE = 0x00000000,
+ FRSRPC_CO_LOCATION_DIR_CREATE = 0x00000000 | 0x00000001,
+ FRSRPC_CO_LOCATION_FILE_DELETE = 0x00000002,
+ FRSRPC_CO_LOCATION_DIR_DELETE = 0x00000002 | 0x00000001,
+ FRSRPC_CO_LOCATION_FILE_MOVEIN = 0x00000004,
+ FRSRPC_CO_LOCATION_DIR_MOVEIN = 0x00000004 | 0x00000001,
+ FRSRPC_CO_LOCATION_FILE_MOVEIN2 = 0x00000006,
+ FRSRPC_CO_LOCATION_DIR_MOVEIN2 = 0x00000006 | 0x00000001,
+ FRSRPC_CO_LOCATION_FILE_MOVEOUT = 0x00000008,
+ FRSRPC_CO_LOCATION_DIR_MOVEOUT = 0x00000008 | 0x00000001,
+ FRSRPC_CO_LOCATION_FILE_MOVERS = 0x0000000a,
+ FRSRPC_CO_LOCATION_DIR_MOVERS = 0x0000000a | 0x00000001,
+ FRSRPC_CO_LOCATION_FILE_MOVEDIR = 0x0000000c,
+ FRSRPC_CO_LOCATION_DIR_MOVEDIR = 0x0000000c | 0x00000001,
+ FRSRPC_CO_LOCATION_FILE_NO_CMD = 0x0000000e,
+ FRSRPC_CO_LOCATION_DIR_NO_CMD = 0x0000000e | 0x00000001
+ } frsrpc_CommPktCoCmdLocationCmd;
- /* TAG:18 this TLV contains a timestamp
- */
typedef struct {
- [subcontext(4)] NTTIME time;
- } frsrpc_FrsSendCommPktChunkDataTS;
+ uint32 sequence_number;
+ frsrpc_CommPktCoCmdFlags flags;
+ frsrpc_CommPktCoCmdIFlags iflags;
+ frsrpc_CommPktCoCmdStatus status;
+ frsrpc_CommPktCoCmdContentCmd content_cmd;
+ frsrpc_CommPktCoCmdLocationCmd location_cmd;
+ uint32 file_attributes;
+ uint32 file_version_number;
+ uint32 partern_ack_sequence_number;
+ [value(0)] uint32 not_used;
+ hyper file_size;
+ hyper file_offset;
+ hyper frs_vsn;
+ hyper file_usn;
+ hyper jrnl_usn;
+ hyper jrnl_first_usn;
+ uint32 original_replica_num;
+ uint32 new_replica_num;
+ GUID change_order_guid;
+ GUID originator_guid;
+ GUID file_guid;
+ GUID old_parent_guid;
+ GUID new_parent_guid;
+ GUID connection_guid;
+ hyper ack_version;
+ [value(0)] hyper spare2ul1;
+ [value(0)] hyper spare1guid_p1;
+ [value(0)] hyper spare1guid_p2;
+ [value(0)] hyper spare2guid_p1;
+ [value(0)] hyper spare3guid_p2;
+ [value(0)] uint32 spare1wcs;
+ [value(0)] uint32 spare2wcs;
+ [value(0)] uint32 extension;
+ [value(0)] uint32 spare2bin;
+ NTTIME event_time;
+ [value(2*strlen_m(file_name))] uint16 file_name_length;
+#define FRSRPC_MAX_PATH 260
+ [charset(UTF16)] uint16 file_name[FRSRPC_MAX_PATH+1];
+ [value(0)] uint8 padding1;
+ [value(0)] uint8 padding2;
+ [value(0)] uint8 padding3;
+ [value(0)] uint8 padding4;
+ } frsrpc_CommPktChangeOrderCommand;
+
+ typedef [v1_enum,flag(NDR_PAHEX)] enum {
+ FRSRPC_DATA_EXTENSION_TERMINATOR = 0x00000000,
+ FRSRPC_DATA_EXTENSION_MD5_CHECKSUM = 0x00000001,
+ FRSRPC_DATA_EXTENSION_RETRY_TIMEOUT = 0x00000002
+ } frsrpc_CommPktDataExtensionType;
+ typedef [flag(NDR_PAHEX)] struct {
+ [value(0x00000018)] uint32 prefix_size;
+ [value(FRSRPC_DATA_EXTENSION_MD5_CHECKSUM)]
+ frsrpc_CommPktDataExtensionType prefix_type;
+ uint8 data[16];
+ } frsrpc_CommPktDataExtensionChecksum;
typedef struct {
- uint32 unknown1;
- } frsrpc_FrsSendCommPktChunkDataA;
+ [value(0x00000018)] uint32 prefix_size;
+ [value(FRSRPC_DATA_EXTENSION_RETRY_TIMEOUT)]
+ frsrpc_CommPktDataExtensionType prefix_type;
+ uint32 count;
+ [value(0)] uint32 not_used;
+ NTTIME first_try_time;
+ } frsrpc_CommPktDataExtensionRetryTimeout;
+
+ typedef [flag(NDR_PAHEX)] enum {
+ FRSRPC_CO_RECORD_EXTENSION_VERSION_WIN2K = 0x0000,
+ FRSRPC_CO_RECORD_EXTENSION_VERSION_1 = 0x0001
+ } frsrpc_CommPktCoRecordExtensionMajor;
typedef struct {
- uint32 unknown1;
- GUID unknown2;
- [subcontext(4)] nstring unknown3;
- } frsrpc_FrsSendCommPktChunkDataB;
+ [value(0x00000028)] uint32 field_size;
+ [value(FRSRPC_CO_RECORD_EXTENSION_VERSION_WIN2K)]
+ frsrpc_CommPktCoRecordExtensionMajor major;
+ [value(0x0001)] uint16 offset_count;
+ [value(0x00000010)] uint32 offset;
+ [value(0)] uint32 offset_last;
+ frsrpc_CommPktDataExtensionChecksum data_checksum;
+ } frsrpc_CommPktCoRecordExtensionWin2k;
typedef struct {
- uint32 unknown1;
- GUID unknown2;
- } frsrpc_FrsSendCommPktChunkDataC;
+ [value(0x00000048)] uint32 field_size;
+ frsrpc_CommPktCoRecordExtensionMajor major;
+ [value(0x0002)] uint16 offset_count;
+ [value(0x00000018)] uint32 offset0;
+ [value(0x00000030)] uint32 offset1;/*TODO: is this correct??? */
+ [value(0)] uint32 offset_last;
+ [value(0)] uint32 not_used;
+ frsrpc_CommPktDataExtensionChecksum data_checksum;
+ frsrpc_CommPktDataExtensionRetryTimeout data_retry_timeout;
+ } frsrpc_CommPktChangeOrderRecordExtension;
+
+ typedef [v1_enum,flag(NDR_PAHEX)] enum {
+ FRSRPC_COMMAND_REMOTE_CO = 0x00000218,
+ FRSRPC_COMMAND_RECEIVING_STATE = 0x00000238,
+ FRSRPC_COMMAND_REMOTE_CO_DONE = 0x00000250,
+ FRSRPC_COMMAND_ABORT_FETCH = 0x00000246,
+ FRSRPC_COMMAND_RETRY_FETCH = 0x00000244,
+ FRSRPC_COMMAND_NEED_JOIN = 0x00000121,
+ FRSRPC_COMMAND_START_JOIN = 0x00000122,
+ FRSRPC_COMMAND_JOINING = 0x00000130,
+ FRSRPC_COMMAND_JOINED = 0x00000128,
+ FRSRPC_COMMAND_UNJOIN_REMOTE = 0x00000148,
+ FRSRPC_COMMAND_WJOIN_DONE = 0x00000136,
+ FRSRPC_COMMAND_SEND_STAGE = 0x00000228
+ } frsrpc_CommPktCommand;
+
+ typedef [flag(NDR_PAHEX)] enum {
+ FRSRPC_COMM_PKT_CHUNK_BOP = 0x0001,
+ FRSRPC_COMM_PKT_CHUNK_COMMAND = 0x0002,
+ FRSRPC_COMM_PKT_CHUNK_TO = 0x0003,
+ FRSRPC_COMM_PKT_CHUNK_FROM = 0x0004,
+ FRSRPC_COMM_PKT_CHUNK_REPLICA = 0x0005,
+ FRSRPC_COMM_PKT_CHUNK_CONNECTION = 0x0008,
+ FRSRPC_COMM_PKT_CHUNK_JOIN_GUID = 0x0006,
+ FRSRPC_COMM_PKT_CHUNK_LAST_JOIN_TIME = 0x0012,
+
+ FRSRPC_COMM_PKT_CHUNK_VVECTOR = 0x0007,
+ FRSRPC_COMM_PKT_CHUNK_JOIN_TIME = 0x0011,
+ FRSRPC_COMM_PKT_CHUNK_REPLICA_VERSION_GUID = 0x0014,
+ FRSRPC_COMM_PKT_CHUNK_COMPRESSION_GUID = 0x0018,
+
+ FRSRPC_COMM_PKT_CHUNK_BLOCK = 0x0009,
+ FRSRPC_COMM_PKT_CHUNK_BLOCK_SIZE = 0x000A,
+ FRSRPC_COMM_PKT_CHUNK_FILE_SIZE = 0x000B,
+ FRSRPC_COMM_PKT_CHUNK_FILE_OFFSET = 0x000C,
+ FRSRPC_COMM_PKT_CHUNK_GVSN = 0x000E,
+ FRSRPC_COMM_PKT_CHUNK_CO_GUID = 0x000F,
+ FRSRPC_COMM_PKT_CHUNK_CO_SEQUENCE_NUMBER = 0x0010,
+
+ FRSRPC_COMM_PKT_CHUNK_REMOTE_CO = 0x000D,
+ FRSRPC_COMM_PKT_CHUNK_CO_EXT_WIN2K = 0x0016,
+ FRSRPC_COMM_PKT_CHUNK_CO_EXTENTION_2 = 0x0017,
+
+ FRSRPC_COMM_PKT_CHUNK_EOP = 0x0013
+ } frsrpc_CommPktChunkType;
typedef [nodiscriminant] union {
[default,flag(NDR_REMAINING)] DATA_BLOB blob;
- [case(1)] frsrpc_FrsSendCommPktChunkDataA A;
- [case(2)] frsrpc_FrsSendCommPktChunkDataA A;
- [case(3)] frsrpc_FrsSendCommPktChunkDataSSRV SSRV;
- [case(4)] frsrpc_FrsSendCommPktChunkDataDSRV DSRV;
- [case(5)] frsrpc_FrsSendCommPktChunkDataB B;
- [case(8)] frsrpc_FrsSendCommPktChunkDataB B;
- [case(6)] frsrpc_FrsSendCommPktChunkDataC C;
- [case(18)] frsrpc_FrsSendCommPktChunkDataTS TS;
- [case(19)] frsrpc_FrsSendCommPktChunkDataA A;
- } frsrpc_FrsSendCommPktChunkData;
+ [case(FRSRPC_COMM_PKT_CHUNK_BOP)]
+ [value(0)] uint32 bop;
+ [case(FRSRPC_COMM_PKT_CHUNK_COMMAND)]
+ frsrpc_CommPktCommand command;
+ [case(FRSRPC_COMM_PKT_CHUNK_TO)]
+ frsrpc_CommPktChunkGuidName to;
+ [case(FRSRPC_COMM_PKT_CHUNK_FROM)]
+ frsrpc_CommPktChunkGuidName from;
+ [case(FRSRPC_COMM_PKT_CHUNK_REPLICA)]
+ frsrpc_CommPktChunkGuidName replica;
+ [case(FRSRPC_COMM_PKT_CHUNK_CONNECTION)]
+ frsrpc_CommPktChunkGuidName connection;
+ [case(FRSRPC_COMM_PKT_CHUNK_JOIN_GUID)][subcontext(4)]
+ GUID join_guid;
+ [case(FRSRPC_COMM_PKT_CHUNK_LAST_JOIN_TIME)]
+ NTTIME last_join_time;
+ [case(FRSRPC_COMM_PKT_CHUNK_VVECTOR)][subcontext(4)]
+ frsrpc_CommPktGSVN vvector;
+ [case(FRSRPC_COMM_PKT_CHUNK_JOIN_TIME)][subcontext(4)]
+ NTTIME join_time;
+ [case(FRSRPC_COMM_PKT_CHUNK_REPLICA_VERSION_GUID)][subcontext(4)]
+ GUID replica_version_guid;
+ [case(FRSRPC_COMM_PKT_CHUNK_COMPRESSION_GUID)]
+ GUID compression_guid;
+ [case(FRSRPC_COMM_PKT_CHUNK_BLOCK)]
+ [flag(NDR_REMAINING)] DATA_BLOB block;
+ [case(FRSRPC_COMM_PKT_CHUNK_BLOCK_SIZE)]
+ hyper block_size;
+ [case(FRSRPC_COMM_PKT_CHUNK_FILE_SIZE)]
+ hyper file_size;
+ [case(FRSRPC_COMM_PKT_CHUNK_FILE_OFFSET)]
+ hyper file_offset;
+ [case(FRSRPC_COMM_PKT_CHUNK_GVSN)][subcontext(4)]
+ frsrpc_CommPktGSVN gvsn;
+ [case(FRSRPC_COMM_PKT_CHUNK_CO_GUID)][subcontext(4)]
+ GUID co_guid;
+ [case(FRSRPC_COMM_PKT_CHUNK_CO_SEQUENCE_NUMBER)]
+ uint32 co_sequnence_number;
+ [case(FRSRPC_COMM_PKT_CHUNK_REMOTE_CO)][subcontext(4)]
+ frsrpc_CommPktChangeOrderCommand remote_co;
+ [case(FRSRPC_COMM_PKT_CHUNK_CO_EXT_WIN2K)][subcontext(4)]
+ frsrpc_CommPktCoRecordExtensionWin2k co_ext_win2k;
+ [case(FRSRPC_COMM_PKT_CHUNK_CO_EXTENTION_2)][subcontext(4)]
+ frsrpc_CommPktChangeOrderRecordExtension co_extension2;
+ [case(FRSRPC_COMM_PKT_CHUNK_EOP)]
+ [value(0xFFFFFFFF)] uint32 bop;
+ } frsrpc_CommPktChunkData;
- typedef struct {
- uint16 type;
- [subcontext(4),switch_is(type)] frsrpc_FrsSendCommPktChunkData data;
- } frsrpc_FrsSendCommPktChunk;
-
- typedef [flag(NDR_NOALIGN)] struct {
- frsrpc_FrsSendCommPktChunk chunk1;
- frsrpc_FrsSendCommPktChunk chunk2;
- frsrpc_FrsSendCommPktChunk chunk3;
- frsrpc_FrsSendCommPktChunk chunk4;
- frsrpc_FrsSendCommPktChunk chunk5;
- frsrpc_FrsSendCommPktChunk chunk6;
- frsrpc_FrsSendCommPktChunk chunk7;
- frsrpc_FrsSendCommPktChunk chunk8;
- frsrpc_FrsSendCommPktChunk chunk9;
- } frsrpc_FrsSendCommPktChunkCtr;
+ typedef [public,flag(NDR_NOALIGN)] struct {
+ frsrpc_CommPktChunkType type;
+ [subcontext(4),switch_is(type)] frsrpc_CommPktChunkData data;
+ } frsrpc_CommPktChunk;
+
+ typedef [nopull,nopush,flag(NDR_NOALIGN)] struct {
+ uint32 num_chunks; /* this doesn't appear on the wire */
+ frsrpc_CommPktChunk chunks[num_chunks];
+ } frsrpc_CommPktChunkCtr;
+
+ typedef [v1_enum] enum {
+ FRSRPC_COMM_PKT_MAJOR_0 = 0x00000000
+ } frsrpc_CommPktMajor;
+
+ typedef [v1_enum] enum {
+ FRSRPC_COMM_PKT_MINOR_0 = 0x00000000,
+ FRSRPC_COMM_PKT_MINOR_1 = 0x00000001,
+ FRSRPC_COMM_PKT_MINOR_2 = 0x00000002,
+ FRSRPC_COMM_PKT_MINOR_3 = 0x00000003,
+ FRSRPC_COMM_PKT_MINOR_4 = 0x00000004,
+ FRSRPC_COMM_PKT_MINOR_5 = 0x00000005,
+ FRSRPC_COMM_PKT_MINOR_6 = 0x00000006,
+ FRSRPC_COMM_PKT_MINOR_7 = 0x00000007,
+ FRSRPC_COMM_PKT_MINOR_8 = 0x00000008,
+ FRSRPC_COMM_PKT_MINOR_9 = 0x00000009
+ } frsrpc_CommPktMinor;
typedef struct {
- uint32 unknown1;
- uint32 unknown2;
- uint32 unknown3;
- uint32 unknown4;
- uint32 tlv_size;
- uint32 unknown6;
- uint32 unknown7; /* This may be a UNIQUE pointer? */
- uint32 unknown8;
- uint32 unknown9;
- /*
- * The format of this blob is this a concatenation
- * of TLVs which are not really NDR encoded.
- *
- * The individual TLVs are encoded as :
- * struct {
- * uint16 type;
- * [subcontext(4),switch_is(type)] chunk_data data;
- * } chunk;
- *
- * some of the chunk are like this:
- *
- * struct {
- * uint32 unknown; // 0x00000010
- * struct GUID guid;
- * lstring string;
- * } ...;
- *
- *
- * The tags are (might be) :
- * 3: Source server sending the PDU
- * 4: Destination server the PDU is sent to
- * 18: Timestamp
- *
- */
- [subcontext(4)/*,size_is(tlv_size)*/] frsrpc_FrsSendCommPktChunkCtr *chunks;
- uint32 unknown10;
- uint32 unknown11;
+ frsrpc_CommPktMajor major;
+ frsrpc_CommPktMinor minor;
+ [value(1)] uint32 cs_id;
+ [value(pkt_len+12)] uint32 memory_len;
+ [value(ndr_size_frsrpc_CommPktChunkCtr(r->ctr,
+ ndr->iconv_convenience, ndr->flags))]
+ [range(0, 262144)]
+ uint32 pkt_len;
+ [value(0)] uint32 upk_len;
+ [subcontext(4),subcontext_size(pkt_len)]
+ frsrpc_CommPktChunkCtr *ctr;
+ [value(0)] uint32 data_name;
+ [value(0)] uint32 data_handle;
} frsrpc_FrsSendCommPktReq;
WERROR frsrpc_FrsSendCommPkt(
@@ -132,7 +358,28 @@ interface frsrpc
/*****************/
/* Function 0x02 */
- [todo] void FRSRPC_START_PROMOTION_PARENT();
+ typedef [v1_enum,flag(NDR_PAHEX)] enum {
+ FRSRPC_PARENT_AUTH_LEVEL_ENCRYPTED_KERBEROS = 0x00000000,
+ FRSRPC_PARENT_AUTH_LEVEL_NO_AUTHENTICATION = 0x00000001
+ } frsrpc_PartnerAuthLevel;
+
+ WERROR frsrpc_FrsStartPromotionParent(
+ [in,unique,string,charset(UTF16)] uint16 *parent_account,
+ [in,unique,string,charset(UTF16)] uint16 *parent_password,
+ [in,unique,string,charset(UTF16)] uint16 *replica_set_name,
+ [in,unique,string,charset(UTF16)] uint16 *replica_set_type,
+ [in,unique,string,charset(UTF16)] uint16 *connection_name,
+ [in,unique,string,charset(UTF16)] uint16 *partner_name,
+ [in,unique,string,charset(UTF16)] uint16 *partner_princ_name,
+ [in] frsrpc_PartnerAuthLevel partner_auth_level,
+ [in,value(16),range(16,16)] uint32 __ndr_guid_size,
+ [in,unique,subcontext(4),subcontext_size(16)]
+ GUID *connection_guid,
+ [in,unique,subcontext(4),subcontext_size(16)]
+ GUID *partner_guid,
+ [in,out,unique,subcontext(4),subcontext_size(16)]
+ GUID *parent_guid
+ );
/*****************/
/* Function 0x03 */
diff --git a/librpc/idl/frstrans.idl b/librpc/idl/frstrans.idl
new file mode 100644
index 0000000000..c79aabf773
--- /dev/null
+++ b/librpc/idl/frstrans.idl
@@ -0,0 +1,83 @@
+#include "idl_types.h"
+
+import "misc.idl";
+
+[
+ uuid("897e2e5f-93f3-4376-9c9c-fd2277495c27"),
+ version(1.0),
+ endpoint("ncacn_ip_tcp:", "ncalrpc:"),
+ helpstring("File Replication Service DFS-R"),
+ pointer_default(unique)
+]
+interface frstrans
+{
+ /*****************/
+ /* Function 0x00 */
+ [todo] void FRSTRANS_CHECK_CONNECTIVITY();
+
+ /*****************/
+ /* Function 0x01 */
+ [todo] void FRSTRANS_ESTABLISH_CONNECTION();
+
+ /*****************/
+ /* Function 0x02 */
+ [todo] void FRSTRANS_ESTABLISH_SESSION();
+
+ /*****************/
+ /* Function 0x03 */
+ [todo] void FRSTRANS_REQUEST_UPDATES();
+
+ /*****************/
+ /* Function 0x04 */
+ [todo] void FRSTRANS_REQUEST_VERSION_VECTOR();
+
+ /*****************/
+ /* Function 0x05 */
+ [todo] void FRSTRANS_ASYNC_POLL();
+
+ /*****************/
+ /* Function 0x06 */
+ [todo] void FRSTRANS_REQUEST_RECORDS();
+
+ /*****************/
+ /* Function 0x07 */
+ [todo] void FRSTRANS_UPDATE_CANCEL();
+
+ /*****************/
+ /* Function 0x08 */
+ [todo] void FRSTRANS_RAW_GET_FILE_DATA();
+
+ /*****************/
+ /* Function 0x09 */
+ [todo] void FRSTRANS_RDC_GET_SIGNATURES();
+
+ /*****************/
+ /* Function 0x0a */
+ [todo] void FRSTRANS_RDC_PUSH_SOURCE_NEEDS();
+
+ /*****************/
+ /* Function 0x0b */
+ [todo] void FRSTRANS_RDC_GET_FILE_DATA();
+
+ /*****************/
+ /* Function 0x0c */
+ [todo] void FRSTRANS_RDC_CLOSE();
+
+ /*****************/
+ /* Function 0x0d */
+ [todo] void FRSTRANS_INITIALIZE_FILE_TRANSFER_ASYNC();
+
+ /*****************/
+ /* Function 0x0e */
+ [todo] void FRSTRANS_OPNUM_0E_NOT_USED_ON_THE_WIRE();
+
+ /* The following functions are new in Windows 2008 */
+
+ /*****************/
+ /* Function 0x0f */
+ [todo] void FRSTRANS_RAW_GET_FILE_DATA_ASYNC();
+
+ /*****************/
+ /* Function 0x10 */
+ [todo] void FRSTRANS_RDC_GET_FILE_DATA_ASYNC();
+}
diff --git a/librpc/idl/lsa.idl b/librpc/idl/lsa.idl
index 9e3b7d6048..7f8ed4afe3 100644
--- a/librpc/idl/lsa.idl
+++ b/librpc/idl/lsa.idl
@@ -651,7 +651,7 @@ import "misc.idl", "security.idl";
LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL = 10,
LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL = 11,
LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL = 12,
- LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES = 13
+ LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES = 13
} lsa_TrustDomInfoEnum;
typedef [public,bitmap32bit] bitmap {
@@ -788,7 +788,7 @@ import "misc.idl", "security.idl";
lsa_TrustDomainInfoInfoEx2Internal info_ex2_internal;
[case(LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL)]
lsa_TrustDomainInfoFullInfo2Internal full_info2_internal;
- [case(LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES)]
+ [case(LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES)]
lsa_TrustDomainInfoSupportedEncTypes enc_types;
} lsa_TrustedDomainInfo;
@@ -935,10 +935,18 @@ import "misc.idl", "security.idl";
);
/* Function: 0x2a */
- [todo] NTSTATUS lsa_StorePrivateData();
- /* Function: 0x2b */
- [todo] NTSTATUS lsa_RetrievePrivateData();
+ NTSTATUS lsa_StorePrivateData(
+ [in] policy_handle *handle,
+ [in,ref] lsa_String *name,
+ [in,unique] lsa_DATA_BUF *val
+ );
+ /* Function: 0x2b */
+ NTSTATUS lsa_RetrievePrivateData(
+ [in] policy_handle *handle,
+ [in,ref] lsa_String *name,
+ [in,out,ref] lsa_DATA_BUF **val
+ );
/**********************/
/* Function: 0x2c */
diff --git a/librpc/idl/samr.idl b/librpc/idl/samr.idl
index b7c151d413..8a5692fe17 100644
--- a/librpc/idl/samr.idl
+++ b/librpc/idl/samr.idl
@@ -1544,12 +1544,14 @@ import "misc.idl", "lsa.idl", "security.idl";
SAMR_VALIDATION_STATUS_SUCCESS = 0,
SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE = 1,
SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT = 2,
+ SAMR_VALIDATION_STATUS_PASSWORD_EXPIRED = 3,
SAMR_VALIDATION_STATUS_BAD_PASSWORD = 4,
SAMR_VALIDATION_STATUS_PWD_HISTORY_CONFLICT = 5,
SAMR_VALIDATION_STATUS_PWD_TOO_SHORT = 6,
SAMR_VALIDATION_STATUS_PWD_TOO_LONG = 7,
SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH = 8,
- SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT = 9
+ SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT = 9,
+ SAMR_VALIDATION_STATUS_PASSWORD_FILTER_ERROR = 10
} samr_ValidationStatus;
typedef struct {
diff --git a/librpc/idl/spoolss.idl b/librpc/idl/spoolss.idl
index f37424634d..0c68dffcd1 100644
--- a/librpc/idl/spoolss.idl
+++ b/librpc/idl/spoolss.idl
@@ -1311,7 +1311,7 @@ import "misc.idl", "security.idl", "winreg.idl";
uint32 major;
uint32 minor;
uint32 build;
- [value(2)] uint32 unknown;
+ [value(2)] uint32 platform_id;
[subcontext(0),subcontext_size(256)] nstring extra_string;
} spoolss_OSVersion;
@@ -1320,10 +1320,13 @@ import "misc.idl", "security.idl", "winreg.idl";
uint32 major;
uint32 minor;
uint32 build;
- [value(2)] uint32 unknown1;
+ [value(2)] uint32 platform_id;
[subcontext(0),subcontext_size(256)] nstring extra_string;
- uint32 unknown2;/* service pack number? I saw 0 from w2k3 and 1 from winxp sp1*/
- uint32 unknown3;/* hmm? w2k3: 131346(0x20112) winxp sp1: 503382272 0x1E010100 */
+ uint16 service_pack_major;
+ uint16 service_pack_minor;
+ uint16 suite_mask;
+ uint8 product_type;
+ uint8 reserved;
} spoolss_OSVersionEx;
typedef [nodiscriminant,public,gensize] union {
@@ -1683,7 +1686,10 @@ import "misc.idl", "security.idl", "winreg.idl";
/******************/
/* Function: 0x28 */
- [todo] WERROR spoolss_CreatePrinterIC(
+ WERROR spoolss_CreatePrinterIC(
+ [in,ref] policy_handle *handle,
+ [out,ref] policy_handle *gdi_handle,
+ [in,ref] spoolss_DevmodeContainer *devmode_ctr
);
/******************/
@@ -1693,7 +1699,8 @@ import "misc.idl", "security.idl", "winreg.idl";
/******************/
/* Function: 0x2a */
- [todo] WERROR spoolss_DeletePrinterIC(
+ WERROR spoolss_DeletePrinterIC(
+ [in,out,ref] policy_handle *gdi_handle
);
/******************/
diff --git a/librpc/ndr/ndr_frsrpc.c b/librpc/ndr/ndr_frsrpc.c
new file mode 100644
index 0000000000..e0c7f1cd75
--- /dev/null
+++ b/librpc/ndr/ndr_frsrpc.c
@@ -0,0 +1,94 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ helper routines for FRSRPC marshalling
+
+ Copyright (C) Stefan (metze) Metzmacher 2009
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "librpc/gen_ndr/ndr_frsrpc.h"
+
+enum ndr_err_code ndr_push_frsrpc_CommPktChunkCtr(struct ndr_push *ndr,
+ int ndr_flags,
+ const struct frsrpc_CommPktChunkCtr *r)
+{
+ uint32_t cntr_chunks_0;
+ {
+ uint32_t _flags_save_STRUCT = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_push_align(ndr, 2));
+ for (cntr_chunks_0 = 0; cntr_chunks_0 < r->num_chunks; cntr_chunks_0++) {
+ NDR_CHECK(ndr_push_frsrpc_CommPktChunk(ndr, NDR_SCALARS, &r->chunks[cntr_chunks_0]));
+ }
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ }
+ ndr->flags = _flags_save_STRUCT;
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+#define _TMP_PULL_REALLOC_N(ndr, s, t, n) do { \
+ _NDR_PULL_FIX_CURRENT_MEM_CTX(ndr);\
+ (s) = talloc_realloc(ndr->current_mem_ctx, (s), t, n); \
+ if (!(s)) { \
+ return ndr_pull_error(ndr, NDR_ERR_ALLOC, \
+ "Alloc %u * %s failed: %s\n", \
+ (unsigned)n, # s, __location__); \
+ } \
+} while (0)
+
+enum ndr_err_code ndr_pull_frsrpc_CommPktChunkCtr(struct ndr_pull *ndr,
+ int ndr_flags,
+ struct frsrpc_CommPktChunkCtr *r)
+{
+ uint32_t cntr_chunks_0;
+ {
+ uint32_t _flags_save_STRUCT = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
+ if (ndr_flags & NDR_SCALARS) {
+ uint32_t remaining = ndr->data_size - ndr->offset;
+ r->num_chunks = 0;
+ r->chunks = NULL;
+ for (cntr_chunks_0 = 0; remaining > 0; cntr_chunks_0++) {
+ r->num_chunks += 1;
+ _TMP_PULL_REALLOC_N(ndr, r->chunks,
+ struct frsrpc_CommPktChunk,
+ r->num_chunks);
+ NDR_CHECK(ndr_pull_frsrpc_CommPktChunk(ndr,
+ NDR_SCALARS,
+ &r->chunks[cntr_chunks_0]));
+ remaining = ndr->data_size - ndr->offset;
+ }
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ }
+ ndr->flags = _flags_save_STRUCT;
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+size_t ndr_size_frsrpc_CommPktChunkCtr(const struct frsrpc_CommPktChunkCtr *r,
+ struct smb_iconv_convenience *ic,
+ int flags)
+{
+ flags |= LIBNDR_FLAG_NOALIGN;
+ return ndr_size_struct(r, flags,
+ (ndr_push_flags_fn_t)ndr_push_frsrpc_CommPktChunkCtr,
+ ic);
+}
diff --git a/librpc/ndr/ndr_frsrpc.h b/librpc/ndr/ndr_frsrpc.h
new file mode 100644
index 0000000000..e8dc76959b
--- /dev/null
+++ b/librpc/ndr/ndr_frsrpc.h
@@ -0,0 +1,35 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ helper routines for FRSRPC marshalling
+
+ Copyright (C) Stefan (metze) Metzmacher 2009
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _LIBRPC_NDR_NDR_FRSRPC_H
+#define _LIBRPC_NDR_NDR_FRSRPC_H
+
+enum ndr_err_code ndr_push_frsrpc_CommPktChunkCtr(struct ndr_push *ndr,
+ int ndr_flags,
+ const struct frsrpc_CommPktChunkCtr *r);
+enum ndr_err_code ndr_pull_frsrpc_CommPktChunkCtr(struct ndr_pull *ndr,
+ int ndr_flags,
+ struct frsrpc_CommPktChunkCtr *r);
+size_t ndr_size_frsrpc_CommPktChunkCtr(const struct frsrpc_CommPktChunkCtr *r,
+ struct smb_iconv_convenience *ic,
+ int flags);
+
+#endif /* _LIBRPC_NDR_NDR_FRSRPC_H */
diff --git a/librpc/ndr_standard.pc.in b/librpc/ndr_standard.pc.in
new file mode 100644
index 0000000000..80eace1bef
--- /dev/null
+++ b/librpc/ndr_standard.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ndr-standard
+Description: NDR marshallers for the standard set of DCE/RPC interfaces
+Requires: ndr
+Version: 0.0.1
+Libs: -L${libdir} -lndr-standard
+Cflags: -I${includedir} -DHAVE_IMMEDIATE_STRUCTURES=1 -D_GNU_SOURCE=1
diff --git a/nsswitch/pam_winbind.c b/nsswitch/pam_winbind.c
index e90f1b75ad..4e84574d25 100644
--- a/nsswitch/pam_winbind.c
+++ b/nsswitch/pam_winbind.c
@@ -11,6 +11,8 @@
*/
#include "pam_winbind.h"
+#define CONST_DISCARD(type,ptr) ((type)(void *)ptr)
+
static int wbc_error_to_pam_error(wbcErr status)
{
@@ -410,49 +412,51 @@ static int _pam_parse(const pam_handle_t *pamh,
config_file = PAM_WINBIND_CONFIG_FILE;
}
- d = iniparser_load(config_file);
+ d = iniparser_load(CONST_DISCARD(char *, config_file));
if (d == NULL) {
goto config_from_pam;
}
- if (iniparser_getboolean(d, "global:debug", false)) {
+ if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:debug"), false)) {
ctrl |= WINBIND_DEBUG_ARG;
}
- if (iniparser_getboolean(d, "global:debug_state", false)) {
+ if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:debug_state"), false)) {
ctrl |= WINBIND_DEBUG_STATE;
}
- if (iniparser_getboolean(d, "global:cached_login", false)) {
+ if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:cached_login"), false)) {
ctrl |= WINBIND_CACHED_LOGIN;
}
- if (iniparser_getboolean(d, "global:krb5_auth", false)) {
+ if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:krb5_auth"), false)) {
ctrl |= WINBIND_KRB5_AUTH;
}
- if (iniparser_getboolean(d, "global:silent", false)) {
+ if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:silent"), false)) {
ctrl |= WINBIND_SILENT;
}
- if (iniparser_getstr(d, "global:krb5_ccache_type") != NULL) {
+ if (iniparser_getstr(d, CONST_DISCARD(char *, "global:krb5_ccache_type")) != NULL) {
ctrl |= WINBIND_KRB5_CCACHE_TYPE;
}
- if ((iniparser_getstr(d, "global:require-membership-of") != NULL) ||
- (iniparser_getstr(d, "global:require_membership_of") != NULL)) {
+ if ((iniparser_getstr(d, CONST_DISCARD(char *, "global:require-membership-of"))
+ != NULL) ||
+ (iniparser_getstr(d, CONST_DISCARD(char *, "global:require_membership_of"))
+ != NULL)) {
ctrl |= WINBIND_REQUIRED_MEMBERSHIP;
}
- if (iniparser_getboolean(d, "global:try_first_pass", false)) {
+ if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:try_first_pass"), false)) {
ctrl |= WINBIND_TRY_FIRST_PASS_ARG;
}
- if (iniparser_getint(d, "global:warn_pwd_expire", 0)) {
+ if (iniparser_getint(d, CONST_DISCARD(char *, "global:warn_pwd_expire"), 0)) {
ctrl |= WINBIND_WARN_PWD_EXPIRE;
}
- if (iniparser_getboolean(d, "global:mkhomedir", false)) {
+ if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:mkhomedir"), false)) {
ctrl |= WINBIND_MKHOMEDIR;
}
@@ -2284,6 +2288,7 @@ static char* winbind_upn_to_username(struct pwb_context *ctx,
enum wbcSidType type;
char *domain;
char *name;
+ char *p;
/* This cannot work when the winbind separator = @ */
@@ -2292,9 +2297,18 @@ static char* winbind_upn_to_username(struct pwb_context *ctx,
return NULL;
}
+ name = talloc_strdup(ctx, upn);
+ if (!name) {
+ return NULL;
+ }
+ if ((p = strchr(name, '@')) != NULL) {
+ *p = 0;
+ domain = p + 1;
+ }
+
/* Convert the UPN to a SID */
- wbc_status = wbcLookupName("", upn, &sid, &type);
+ wbc_status = wbcLookupName(domain, name, &sid, &type);
if (!WBC_ERROR_IS_OK(wbc_status)) {
return NULL;
}
diff --git a/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm b/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
index ed1b71a236..a2a61d87d0 100644
--- a/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
+++ b/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
@@ -96,11 +96,17 @@ sub ParseOutputArgument($$$)
# structure, the user should be able to know the size beforehand
# to allocate a structure of the right size.
my $env = GenerateFunctionInEnv($fn, "r.");
- my $size_is = ParseExpr($e->{LEVELS}[$level]->{SIZE_IS}, $env, $e->{ORIGINAL});
- if (has_property($e, "charset")) {
- $self->pidl("memcpy(CONST_DISCARD(char *, $e->{NAME}), r.out.$e->{NAME}, $size_is * sizeof(*$e->{NAME}));");
+ my $l = $e->{LEVELS}[$level];
+ unless (defined($l->{SIZE_IS})) {
+ error($e->{ORIGINAL}, "no size known for [out] array `$e->{NAME}'");
+ $self->pidl('#error No size known for [out] array `$e->{NAME}');
} else {
- $self->pidl("memcpy($e->{NAME}, r.out.$e->{NAME}, $size_is * sizeof(*$e->{NAME}));");
+ my $size_is = ParseExpr($l->{SIZE_IS}, $env, $e->{ORIGINAL});
+ if (has_property($e, "charset")) {
+ $self->pidl("memcpy(CONST_DISCARD(char *, $e->{NAME}), r.out.$e->{NAME}, $size_is * sizeof(*$e->{NAME}));");
+ } else {
+ $self->pidl("memcpy($e->{NAME}, r.out.$e->{NAME}, $size_is * sizeof(*$e->{NAME}));");
+ }
}
} else {
$self->pidl("*$e->{NAME} = *r.out.$e->{NAME};");
diff --git a/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm b/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
index c9a8eea59f..5599de9d79 100644
--- a/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
+++ b/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
@@ -11,7 +11,7 @@ use Exporter;
@EXPORT_OK = qw(DeclLevel);
use strict;
-use Parse::Pidl qw(warning fatal);
+use Parse::Pidl qw(warning error fatal);
use Parse::Pidl::Typelist qw(mapTypeName scalar_is_reference);
use Parse::Pidl::Util qw(ParseExpr has_property is_constant);
use Parse::Pidl::NDR qw(GetNextLevel);
@@ -72,8 +72,13 @@ sub AllocOutVar($$$$$)
}
if ($l->{TYPE} eq "ARRAY") {
- my $size = ParseExpr($l->{SIZE_IS}, $env, $e);
- pidl "$name = talloc_zero_array($mem_ctx, " . DeclLevel($e, 1) . ", $size);";
+ unless(defined($l->{SIZE_IS})) {
+ error($e->{ORIGINAL}, "No size known for array `$e->{NAME}'");
+ pidl "#error No size known for array `$e->{NAME}'";
+ } else {
+ my $size = ParseExpr($l->{SIZE_IS}, $env, $e);
+ pidl "$name = talloc_zero_array($mem_ctx, " . DeclLevel($e, 1) . ", $size);";
+ }
} else {
pidl "$name = talloc_zero($mem_ctx, " . DeclLevel($e, 1) . ");";
}
diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm b/pidl/lib/Parse/Pidl/Samba4/Python.pm
index 81869b0da5..d27192d6dd 100644
--- a/pidl/lib/Parse/Pidl/Samba4/Python.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm
@@ -431,7 +431,7 @@ sub PythonFunctionUnpackOut($$$)
} elsif (defined($fn->{RETURN_TYPE}) and $fn->{RETURN_TYPE} eq "WERROR") {
$self->handle_werror("r->out.result", "NULL", undef);
} elsif (defined($fn->{RETURN_TYPE})) {
- my $conv = $self->ConvertObjectToPythonData("r", $fn->{RETURN_TYPE}, "r->out.result");
+ my $conv = $self->ConvertObjectToPythonData("r", $fn->{RETURN_TYPE}, "r->out.result", $fn);
if ($result_size > 1) {
$self->pidl("PyTuple_SetItem(result, $i, $conv);");
} else {
@@ -815,11 +815,11 @@ sub assign($$$)
}
}
-sub ConvertObjectFromPythonData($$$$$$)
+sub ConvertObjectFromPythonData($$$$$$;$)
{
- my ($self, $mem_ctx, $cvar, $ctype, $target, $fail) = @_;
+ my ($self, $mem_ctx, $cvar, $ctype, $target, $fail, $location) = @_;
- die("undef type for $cvar") unless(defined($ctype));
+ fatal($location, "undef type for $cvar") unless(defined($ctype));
$ctype = resolveType($ctype);
@@ -839,7 +839,7 @@ sub ConvertObjectFromPythonData($$$$$$)
if ($actual_ctype->{TYPE} eq "STRUCT" or $actual_ctype->{TYPE} eq "INTERFACE") {
my $ctype_name = $self->use_type_variable($ctype);
unless (defined ($ctype_name)) {
- error(undef, "Unable to determine origin of type " . mapTypeName($ctype));
+ error($location, "Unable to determine origin of type `" . mapTypeName($ctype) . "'");
$self->assign($target, "NULL");
# FIXME:
return;
@@ -886,7 +886,7 @@ sub ConvertObjectFromPythonData($$$$$$)
return;
}
- fatal($ctype, "unknown type $actual_ctype->{TYPE} for ".mapTypeName($ctype) . ": $cvar");
+ fatal($location, "unknown type `$actual_ctype->{TYPE}' for ".mapTypeName($ctype) . ": $cvar");
}
@@ -946,7 +946,7 @@ sub ConvertObjectFromPythonLevel($$$$$$$$)
if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE})) {
$var_name = get_pointer_to($var_name);
}
- $self->ConvertObjectFromPythonData($mem_ctx, $py_var, $l->{DATA_TYPE}, $var_name, $fail);
+ $self->ConvertObjectFromPythonData($mem_ctx, $py_var, $l->{DATA_TYPE}, $var_name, $fail, $e->{ORIGINAL});
} elsif ($l->{TYPE} eq "SWITCH") {
$var_name = get_pointer_to($var_name);
my $switch = ParseExpr($l->{SWITCH_IS}, $env, $e);
@@ -954,7 +954,7 @@ sub ConvertObjectFromPythonLevel($$$$$$$$)
} elsif ($l->{TYPE} eq "SUBCONTEXT") {
$self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, GetNextLevel($e, $l), $var_name, $fail);
} else {
- die("unknown level type $l->{TYPE}");
+ fatal($e->{ORIGINAL}, "unknown level type $l->{TYPE}");
}
}
@@ -1003,9 +1003,9 @@ sub ConvertScalarToPython($$$)
die("Unknown scalar type $ctypename");
}
-sub ConvertObjectToPythonData($$$$$)
+sub ConvertObjectToPythonData($$$$$;$)
{
- my ($self, $mem_ctx, $ctype, $cvar) = @_;
+ my ($self, $mem_ctx, $ctype, $cvar, $location) = @_;
die("undef type for $cvar") unless(defined($ctype));
@@ -1027,13 +1027,13 @@ sub ConvertObjectToPythonData($$$$$)
} elsif ($actual_ctype->{TYPE} eq "STRUCT" or $actual_ctype->{TYPE} eq "INTERFACE") {
my $ctype_name = $self->use_type_variable($ctype);
unless (defined($ctype_name)) {
- error(undef, "Unable to determine origin of type " . mapTypeName($ctype));
+ error($location, "Unable to determine origin of type `" . mapTypeName($ctype) . "'");
return "NULL"; # FIXME!
}
return "py_talloc_import_ex($ctype_name, $mem_ctx, $cvar)";
}
- fatal($ctype, "unknown type $actual_ctype->{TYPE} for ".mapTypeName($ctype) . ": $cvar");
+ fatal($location, "unknown type $actual_ctype->{TYPE} for ".mapTypeName($ctype) . ": $cvar");
}
sub fail_on_null($$$)
@@ -1113,12 +1113,12 @@ sub ConvertObjectToPythonLevel($$$$$$)
if (not Parse::Pidl::Typelist::is_scalar($l->{DATA_TYPE})) {
$var_name = get_pointer_to($var_name);
}
- my $conv = $self->ConvertObjectToPythonData($mem_ctx, $l->{DATA_TYPE}, $var_name);
+ my $conv = $self->ConvertObjectToPythonData($mem_ctx, $l->{DATA_TYPE}, $var_name, $e->{ORIGINAL});
$self->pidl("$py_var = $conv;");
} elsif ($l->{TYPE} eq "SUBCONTEXT") {
$self->ConvertObjectToPythonLevel($mem_ctx, $env, $e, GetNextLevel($e, $l), $var_name, $py_var, $fail);
} else {
- die("Unknown level type $l->{TYPE} $var_name");
+ fatal($e->{ORIGINAL}, "Unknown level type $l->{TYPE} $var_name");
}
}
@@ -1223,7 +1223,7 @@ sub Parse($$$$$)
} elsif ($cvar =~ /^".*"$/) {
$py_obj = "PyString_FromString($cvar)";
} else {
- $py_obj = $self->ConvertObjectToPythonData("NULL", expandAlias($ctype), $cvar);
+ $py_obj = $self->ConvertObjectToPythonData("NULL", expandAlias($ctype), $cvar, undef);
}
$self->pidl("PyModule_AddObject(m, \"$name\", $py_obj);");
diff --git a/pidl/lib/Parse/Pidl/Typelist.pm b/pidl/lib/Parse/Pidl/Typelist.pm
index e63b3c990f..12ffa92bf6 100644
--- a/pidl/lib/Parse/Pidl/Typelist.pm
+++ b/pidl/lib/Parse/Pidl/Typelist.pm
@@ -273,12 +273,15 @@ sub mapTypeName($)
my $dt;
$t = expandAlias($t);
- unless ($dt or ($dt = getType($t))) {
+ if ($dt = getType($t)) {
+ return mapType($dt, $dt->{NAME});
+ } elsif (ref($t) eq "HASH" and defined($t->{NAME})) {
+ return mapType($t, $t->{NAME});
+ } else {
# Best guess
return "struct $t";
}
- return mapType($dt, $dt->{NAME});
}
sub LoadIdl($;$)
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 4c927e7346..e6d0cf00dd 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -381,7 +381,7 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \
lib/interface.o lib/pidfile.o \
lib/system.o lib/sendfile.o lib/recvfile.o lib/time.o \
lib/username.o \
- lib/ads_flags.o \
+ ../libds/common/flag_mapping.o \
lib/util_pw.o lib/access.o lib/smbrun.o \
lib/bitmap.o lib/dprintf.o $(UTIL_REG_OBJ) \
lib/wins_srv.o \
@@ -667,6 +667,8 @@ OPLOCK_OBJ = smbd/oplock.o smbd/oplock_irix.o smbd/oplock_linux.o \
NOTIFY_OBJ = smbd/notify.o smbd/notify_inotify.o smbd/notify_internal.o
+FNAME_UTIL_OBJ = smbd/filename_util.o
+
VFS_DEFAULT_OBJ = modules/vfs_default.o
VFS_AUDIT_OBJ = modules/vfs_audit.o
VFS_EXTD_AUDIT_OBJ = modules/vfs_extd_audit.o
@@ -786,7 +788,7 @@ SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \
$(RPC_SERVER_OBJ) $(RPC_PARSE_OBJ) \
$(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) \
$(LIB_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) \
- $(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \
+ $(NOTIFY_OBJ) $(FNAME_UTIL_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \
$(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) $(AVAHI_OBJ) \
$(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(LIBADS_SERVER_OBJ) \
$(REG_FULL_OBJ) $(POPT_LIB_OBJ) $(BUILDOPT_OBJ) \
@@ -828,16 +830,16 @@ SWAT_OBJ = $(SWAT_OBJ1) $(PARAM_OBJ) $(PRINTING_OBJ) $(PRINTBASE_OBJ) $(LIBSMB_O
$(LOCKING_OBJ) $(PASSDB_OBJ) $(KRBCLIENT_OBJ) \
$(LIB_NONSMBD_OBJ) $(GROUPDB_OBJ) $(PLAINTEXT_AUTH_OBJ) \
$(POPT_LIB_OBJ) $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_GEN_OBJ) $(LIBMSRPC_OBJ) \
- $(PASSCHANGE_OBJ) $(LDB_OBJ)
+ $(PASSCHANGE_OBJ) $(LDB_OBJ) $(FNAME_UTIL_OBJ)
STATUS_OBJ = utils/status.o utils/status_profile.o \
$(LOCKING_OBJ) $(PARAM_OBJ) \
$(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
- $(LIBSAMBA_OBJ)
+ $(LIBSAMBA_OBJ) $(FNAME_UTIL_OBJ)
SMBCONTROL_OBJ = utils/smbcontrol.o $(LOCKING_OBJ) $(PARAM_OBJ) \
$(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
- $(LIBSAMBA_OBJ) \
+ $(LIBSAMBA_OBJ) $(FNAME_UTIL_OBJ) \
$(PRINTBASE_OBJ)
SMBTREE_OBJ = utils/smbtree.o $(PARAM_OBJ) \
@@ -1033,7 +1035,7 @@ MSGTEST_OBJ = torture/msgtest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIEN
LOCKTEST_OBJ = torture/locktest.o $(PARAM_OBJ) $(LOCKING_OBJ) $(KRBCLIENT_OBJ) \
$(LIBSMB_OBJ) $(LDB_OBJ) $(LIB_NONSMBD_OBJ) \
- $(LIBNDR_GEN_OBJ0)
+ $(LIBNDR_GEN_OBJ0) $(FNAME_UTIL_OBJ)
NSSTEST_OBJ = torture/nsstest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) \
$(LIB_NONSMBD_OBJ) \
@@ -1052,7 +1054,7 @@ LOG2PCAP_OBJ = utils/log2pcaphex.o
LOCKTEST2_OBJ = torture/locktest2.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) \
$(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \
- $(LIBNDR_GEN_OBJ0)
+ $(LIBNDR_GEN_OBJ0) $(FNAME_UTIL_OBJ)
SMBCACLS_OBJ = utils/smbcacls.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
$(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(RPC_PARSE_OBJ) \
@@ -1476,10 +1478,10 @@ bin/swat@EXEEXT@: $(BINARY_PREREQS) $(SWAT_OBJ) @BUILD_POPT@ @LIBTALLOC_TARGET@
bin/rpcclient@EXEEXT@: $(BINARY_PREREQS) $(RPCCLIENT_OBJ) @BUILD_POPT@ @LIBTALLOC_TARGET@ @LIBTDB_TARGET@ @LIBWBCLIENT_TARGET@
@echo Linking $@
- @$(CC) -o $@ $(LDFLAGS) $(PASSDB_LIBS) $(RPCCLIENT_OBJ) \
+ @$(CC) -o $@ $(LDFLAGS) $(RPCCLIENT_OBJ) \
$(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) $(POPT_LIBS) \
$(KRB5LIBS) $(LDAP_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) \
- $(LIBWBCLIENT_LIBS) $(ZLIB_LIBS)
+ $(LIBWBCLIENT_LIBS) $(ZLIB_LIBS) $(PASSDB_LIBS)
bin/smbclient@EXEEXT@: $(BINARY_PREREQS) $(CLIENT_OBJ) @BUILD_POPT@ @LIBTALLOC_TARGET@ @LIBTDB_TARGET@ @LIBWBCLIENT_TARGET@
@echo Linking $@
@@ -1517,7 +1519,7 @@ bin/umount.cifs@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UMOUNT_OBJ)
bin/cifs.upcall@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UPCALL_OBJ) $(LIBSMBCLIENT_OBJ1) @LIBTALLOC_TARGET@ @LIBTDB_TARGET@ @LIBWBCLIENT_TARGET@
@echo Linking $@
@$(CC) -o $@ $(CIFS_UPCALL_OBJ) $(DYNEXP) $(LDFLAGS) \
- -lkeyutils $(LIBS) $(LIBSMBCLIENT_OBJ1) $(KRB5LIBS) \
+ $(LIBSMBCLIENT_OBJ1) $(LIBS) -lkeyutils $(KRB5LIBS) \
$(LDAP_LIBS) $(LIBTALLOC_LIBS) $(LIBWBCLIENT_LIBS) \
$(LIBTDB_LIBS) $(NSCD_LIBS) $(ZLIB_LIBS)
diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index fd4c503752..ce8722a1b4 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -82,7 +82,6 @@ static void get_ntlm_challenge(struct auth_context *auth_context,
DATA_BLOB challenge = data_blob_null;
const char *challenge_set_by = NULL;
auth_methods *auth_method;
- TALLOC_CTX *mem_ctx;
if (auth_context->challenge.length) {
DEBUG(5, ("get_ntlm_challenge (auth subsystem): returning previous challenge by module %s (normal)\n",
@@ -106,12 +105,8 @@ static void get_ntlm_challenge(struct auth_context *auth_context,
continue;
}
- mem_ctx = talloc_init("auth_get_challenge for module %s", auth_method->name);
- if (!mem_ctx) {
- smb_panic("talloc_init() failed!");
- }
-
- challenge = auth_method->get_chal(auth_context, &auth_method->private_data, mem_ctx);
+ challenge = auth_method->get_chal(auth_context, &auth_method->private_data,
+ auth_context->mem_ctx);
if (!challenge.length) {
DEBUG(3, ("auth_get_challenge: getting challenge from authentication method %s FAILED.\n",
auth_method->name));
@@ -121,7 +116,6 @@ static void get_ntlm_challenge(struct auth_context *auth_context,
challenge_set_by = auth_method->name;
auth_context->challenge_set_method = auth_method;
}
- talloc_destroy(mem_ctx);
}
if (!challenge_set_by) {
diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c
index a2634feb6c..26b45e47e5 100644
--- a/source3/auth/auth_sam.c
+++ b/source3/auth/auth_sam.c
@@ -226,10 +226,10 @@ static NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx,
if (*workstation_list) {
bool invalid_ws = True;
- char *tok;
+ char *tok = NULL;
const char *s = workstation_list;
+ char *machine_name = talloc_asprintf(mem_ctx, "%s$", user_info->wksta_name);
- const char *machine_name = talloc_asprintf(mem_ctx, "%s$", user_info->wksta_name);
if (machine_name == NULL)
return NT_STATUS_NO_MEMORY;
@@ -251,6 +251,7 @@ static NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx,
TALLOC_FREE(tok);
}
TALLOC_FREE(tok);
+ TALLOC_FREE(machine_name);
if (invalid_ws)
return NT_STATUS_INVALID_WORKSTATION;
diff --git a/source3/client/client.c b/source3/client/client.c
index ed45f4e2ca..6b273b47b0 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -2605,7 +2605,7 @@ static int cmd_lock(void)
len = (uint64_t)strtol(buf, (char **)NULL, 16);
- if (!cli_posix_lock(cli, fnum, start, len, true, lock_type)) {
+ if (!NT_STATUS_IS_OK(cli_posix_lock(cli, fnum, start, len, true, lock_type))) {
d_printf("lock failed %d: %s\n", fnum, cli_errstr(cli));
}
@@ -2639,7 +2639,7 @@ static int cmd_unlock(void)
len = (uint64_t)strtol(buf, (char **)NULL, 16);
- if (!cli_posix_unlock(cli, fnum, start, len)) {
+ if (!NT_STATUS_IS_OK(cli_posix_unlock(cli, fnum, start, len))) {
d_printf("unlock failed %d: %s\n", fnum, cli_errstr(cli));
}
diff --git a/source3/include/ads.h b/source3/include/ads.h
index afa4e12175..9761d54086 100644
--- a/source3/include/ads.h
+++ b/source3/include/ads.h
@@ -6,6 +6,8 @@
basically this is a wrapper around ldap
*/
+#include "../libds/common/flags.h"
+
enum wb_posix_mapping {
WB_POSIX_MAP_UNKNOWN = -1,
WB_POSIX_MAP_TEMPLATE = 0,
@@ -202,124 +204,6 @@ typedef void **ADS_MODLIST;
#define ADS_LDAP_MATCHING_RULE_BIT_AND "1.2.840.113556.1.4.803"
#define ADS_LDAP_MATCHING_RULE_BIT_OR "1.2.840.113556.1.4.804"
-/* UserFlags for userAccountControl */
-#define UF_SCRIPT 0x00000001
-#define UF_ACCOUNTDISABLE 0x00000002
-#define UF_UNUSED_1 0x00000004
-#define UF_HOMEDIR_REQUIRED 0x00000008
-
-#define UF_LOCKOUT 0x00000010
-#define UF_PASSWD_NOTREQD 0x00000020
-#define UF_PASSWD_CANT_CHANGE 0x00000040
-#define UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED 0x00000080
-
-#define UF_TEMP_DUPLICATE_ACCOUNT 0x00000100
-#define UF_NORMAL_ACCOUNT 0x00000200
-#define UF_UNUSED_2 0x00000400
-#define UF_INTERDOMAIN_TRUST_ACCOUNT 0x00000800
-
-#define UF_WORKSTATION_TRUST_ACCOUNT 0x00001000
-#define UF_SERVER_TRUST_ACCOUNT 0x00002000
-#define UF_UNUSED_3 0x00004000
-#define UF_UNUSED_4 0x00008000
-
-#define UF_DONT_EXPIRE_PASSWD 0x00010000
-#define UF_MNS_LOGON_ACCOUNT 0x00020000
-#define UF_SMARTCARD_REQUIRED 0x00040000
-#define UF_TRUSTED_FOR_DELEGATION 0x00080000
-
-#define UF_NOT_DELEGATED 0x00100000
-#define UF_USE_DES_KEY_ONLY 0x00200000
-#define UF_DONT_REQUIRE_PREAUTH 0x00400000
-#define UF_PASSWORD_EXPIRED 0x00800000
-
-#define UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION 0x01000000
-#define UF_NO_AUTH_DATA_REQUIRED 0x02000000
-#define UF_UNUSED_8 0x04000000
-#define UF_UNUSED_9 0x08000000
-
-#define UF_UNUSED_10 0x10000000
-#define UF_UNUSED_11 0x20000000
-#define UF_UNUSED_12 0x40000000
-#define UF_UNUSED_13 0x80000000
-
-#define UF_MACHINE_ACCOUNT_MASK (\
- UF_INTERDOMAIN_TRUST_ACCOUNT |\
- UF_WORKSTATION_TRUST_ACCOUNT |\
- UF_SERVER_TRUST_ACCOUNT \
- )
-
-#define UF_ACCOUNT_TYPE_MASK (\
- UF_TEMP_DUPLICATE_ACCOUNT |\
- UF_NORMAL_ACCOUNT |\
- UF_INTERDOMAIN_TRUST_ACCOUNT |\
- UF_WORKSTATION_TRUST_ACCOUNT |\
- UF_SERVER_TRUST_ACCOUNT \
- )
-
-#define UF_SETTABLE_BITS (\
- UF_SCRIPT |\
- UF_ACCOUNTDISABLE |\
- UF_HOMEDIR_REQUIRED |\
- UF_LOCKOUT |\
- UF_PASSWD_NOTREQD |\
- UF_PASSWD_CANT_CHANGE |\
- UF_ACCOUNT_TYPE_MASK | \
- UF_DONT_EXPIRE_PASSWD | \
- UF_MNS_LOGON_ACCOUNT |\
- UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED |\
- UF_SMARTCARD_REQUIRED |\
- UF_TRUSTED_FOR_DELEGATION |\
- UF_NOT_DELEGATED |\
- UF_USE_DES_KEY_ONLY |\
- UF_DONT_REQUIRE_PREAUTH \
- )
-
-/* sAMAccountType */
-#define ATYPE_NORMAL_ACCOUNT 0x30000000 /* 805306368 */
-#define ATYPE_WORKSTATION_TRUST 0x30000001 /* 805306369 */
-#define ATYPE_INTERDOMAIN_TRUST 0x30000002 /* 805306370 */
-#define ATYPE_SECURITY_GLOBAL_GROUP 0x10000000 /* 268435456 */
-#define ATYPE_DISTRIBUTION_GLOBAL_GROUP 0x10000001 /* 268435457 */
-#define ATYPE_DISTRIBUTION_UNIVERSAL_GROUP ATYPE_DISTRIBUTION_GLOBAL_GROUP
-#define ATYPE_SECURITY_LOCAL_GROUP 0x20000000 /* 536870912 */
-#define ATYPE_DISTRIBUTION_LOCAL_GROUP 0x20000001 /* 536870913 */
-
-#define ATYPE_ACCOUNT ATYPE_NORMAL_ACCOUNT /* 0x30000000 805306368 */
-#define ATYPE_GLOBAL_GROUP ATYPE_SECURITY_GLOBAL_GROUP /* 0x10000000 268435456 */
-#define ATYPE_LOCAL_GROUP ATYPE_SECURITY_LOCAL_GROUP /* 0x20000000 536870912 */
-
-/* groupType */
-#define GROUP_TYPE_BUILTIN_LOCAL_GROUP 0x00000001
-#define GROUP_TYPE_ACCOUNT_GROUP 0x00000002
-#define GROUP_TYPE_RESOURCE_GROUP 0x00000004
-#define GROUP_TYPE_UNIVERSAL_GROUP 0x00000008
-#define GROUP_TYPE_APP_BASIC_GROUP 0x00000010
-#define GROUP_TYPE_APP_QUERY_GROUP 0x00000020
-#define GROUP_TYPE_SECURITY_ENABLED 0x80000000
-
-#define GTYPE_SECURITY_BUILTIN_LOCAL_GROUP ( /* 0x80000005 -2147483643 */ \
- GROUP_TYPE_BUILTIN_LOCAL_GROUP| \
- GROUP_TYPE_RESOURCE_GROUP| \
- GROUP_TYPE_SECURITY_ENABLED \
- )
-#define GTYPE_SECURITY_DOMAIN_LOCAL_GROUP ( /* 0x80000004 -2147483644 */ \
- GROUP_TYPE_RESOURCE_GROUP| \
- GROUP_TYPE_SECURITY_ENABLED \
- )
-#define GTYPE_SECURITY_GLOBAL_GROUP ( /* 0x80000002 -2147483646 */ \
- GROUP_TYPE_ACCOUNT_GROUP| \
- GROUP_TYPE_SECURITY_ENABLED \
- )
-#define GTYPE_SECURITY_UNIVERSAL_GROUP ( /* 0x80000008 -2147483656 */ \
- GROUP_TYPE_UNIVERSAL_GROUP| \
- GROUP_TYPE_SECURITY_ENABLED \
- )
-
-#define GTYPE_DISTRIBUTION_GLOBAL_GROUP 0x00000002 /* 2 */
-#define GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP 0x00000004 /* 4 */
-#define GTYPE_DISTRIBUTION_UNIVERSAL_GROUP 0x00000008 /* 8 */
-
#define ADS_PINGS 0x0000FFFF /* Ping response */
#define ADS_DNS_CONTROLLER 0x20000000 /* DomainControllerName is a DNS name*/
#define ADS_DNS_DOMAIN 0x40000000 /* DomainName is a DNS name */
@@ -411,11 +295,4 @@ typedef struct {
#define ADS_IGNORE_PRINCIPAL "not_defined_in_RFC4178@please_ignore"
-/* Settings for the domainFunctionality attribute in the rootDSE */
-
-#define DS_DOMAIN_FUNCTION_2000 0
-#define DS_DOMAIN_FUCNTION_2003_MIXED 1
-#define DS_DOMAIN_FUNCTION_2003 2
-#define DS_DOMAIN_FUNCTION_2008 3
-
#endif /* _INCLUDE_ADS_H_ */
diff --git a/source3/include/passdb.h b/source3/include/passdb.h
index 4e53311eba..2b4f9c2e43 100644
--- a/source3/include/passdb.h
+++ b/source3/include/passdb.h
@@ -205,6 +205,22 @@ struct pdb_domain_info {
struct GUID guid;
};
+/*
+ * Types of account policy.
+ */
+enum pdb_policy_type {
+ PDB_POLICY_MIN_PASSWORD_LEN = 1,
+ PDB_POLICY_PASSWORD_HISTORY = 2,
+ PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS = 3,
+ PDB_POLICY_MAX_PASSWORD_AGE = 4,
+ PDB_POLICY_MIN_PASSWORD_AGE = 5,
+ PDB_POLICY_LOCK_ACCOUNT_DURATION = 6,
+ PDB_POLICY_RESET_COUNT_TIME = 7,
+ PDB_POLICY_BAD_ATTEMPT_LOCKOUT = 8,
+ PDB_POLICY_TIME_TO_LOGOUT = 9,
+ PDB_POLICY_REFUSE_MACHINE_PW_CHANGE = 10
+};
+
#define PDB_CAP_STORE_RIDS 0x0001
#define PDB_CAP_ADS 0x0002
@@ -351,10 +367,12 @@ struct pdb_methods
enum lsa_SidType *attrs);
NTSTATUS (*get_account_policy)(struct pdb_methods *methods,
- int policy_index, uint32 *value);
+ enum pdb_policy_type type,
+ uint32_t *value);
NTSTATUS (*set_account_policy)(struct pdb_methods *methods,
- int policy_index, uint32 value);
+ enum pdb_policy_type type,
+ uint32_t value);
NTSTATUS (*get_seq_num)(struct pdb_methods *methods, time_t *seq_num);
diff --git a/source3/include/proto.h b/source3/include/proto.h
index f887b4e796..77283d9cf0 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -290,16 +290,16 @@ bool check_access(int sock, const char **allow_list, const char **deny_list);
/* The following definitions come from lib/account_pol.c */
void account_policy_names_list(const char ***names, int *num_names);
-const char *decode_account_policy_name(int field);
-const char *get_account_policy_attr(int field);
-const char *account_policy_get_desc(int field);
-int account_policy_name_to_fieldnum(const char *name);
-bool account_policy_get_default(int account_policy, uint32 *val);
+const char *decode_account_policy_name(enum pdb_policy_type type);
+const char *get_account_policy_attr(enum pdb_policy_type type);
+const char *account_policy_get_desc(enum pdb_policy_type type);
+enum pdb_policy_type account_policy_name_to_typenum(const char *name);
+bool account_policy_get_default(enum pdb_policy_type type, uint32_t *val);
bool init_account_policy(void);
-bool account_policy_get(int field, uint32 *value);
-bool account_policy_set(int field, uint32 value);
-bool cache_account_policy_set(int field, uint32 value);
-bool cache_account_policy_get(int field, uint32 *value);
+bool account_policy_get(enum pdb_policy_type type, uint32_t *value);
+bool account_policy_set(enum pdb_policy_type type, uint32_t value);
+bool cache_account_policy_set(enum pdb_policy_type type, uint32_t value);
+bool cache_account_policy_get(enum pdb_policy_type type, uint32_t *value);
struct db_context *get_account_pol_db( void );
/* The following definitions come from lib/adt_tree.c */
@@ -454,6 +454,14 @@ NTSTATUS dbwrap_trans_store_uint32(struct db_context *db, const char *keystr,
NTSTATUS dbwrap_trans_store_bystring(struct db_context *db, const char *key,
TDB_DATA data, int flags);
NTSTATUS dbwrap_trans_delete_bystring(struct db_context *db, const char *key);
+NTSTATUS dbwrap_trans_do(struct db_context *db,
+ NTSTATUS (*action)(struct db_context *, void *),
+ void *private_data);
+NTSTATUS dbwrap_delete_bystring_upper(struct db_context *db, const char *key);
+NTSTATUS dbwrap_store_bystring_upper(struct db_context *db, const char *key,
+ TDB_DATA data, int flags);
+TDB_DATA dbwrap_fetch_bystring_upper(struct db_context *db, TALLOC_CTX *mem_ctx,
+ const char *key);
/* The following definitions come from lib/debug.c */
@@ -515,17 +523,15 @@ void pull_file_id_24(char *buf, struct file_id *id);
/* The following definitions come from lib/gencache.c */
-bool gencache_init(void);
-bool gencache_shutdown(void);
bool gencache_set(const char *keystr, const char *value, time_t timeout);
bool gencache_del(const char *keystr);
bool gencache_get(const char *keystr, char **valstr, time_t *timeout);
-bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, bool *expired);
+bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob,
+ time_t *timeout);
+bool gencache_stabilize(void);
bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, time_t timeout);
void gencache_iterate(void (*fn)(const char* key, const char *value, time_t timeout, void* dptr),
void* data, const char* keystr_pattern);
-int gencache_lock_entry( const char *key );
-void gencache_unlock_entry( const char *key );
/* The following definitions come from lib/interface.c */
@@ -554,7 +560,7 @@ void init_ldap_debugging(void);
/* The following definitions come from lib/ldap_escape.c */
-char *escape_ldap_string_alloc(const char *s);
+char *escape_ldap_string(TALLOC_CTX *mem_ctx, const char *s);
char *escape_rdn_val_string_alloc(const char *s);
/* The following definitions come from lib/module.c */
@@ -1678,13 +1684,6 @@ ADS_STRUCT *ads_init(const char *realm,
const char *ldap_server);
void ads_destroy(ADS_STRUCT **ads);
-/* The following definitions come from libads/ads_utils.c */
-
-uint32 ads_acb2uf(uint32 acb);
-uint32 ads_uf2acb(uint32 uf);
-uint32 ads_uf2atype(uint32 uf);
-uint32 ads_gtype2atype(uint32 gtype);
-enum lsa_SidType ads_atype_map(uint32 atype);
const char *ads_get_ldap_server_name(ADS_STRUCT *ads);
/* The following definitions come from libads/authdata.c */
@@ -2271,13 +2270,6 @@ bool cli_resolve_path(TALLOC_CTX *ctx,
/* The following definitions come from libsmb/clidgram.c */
-bool cli_send_mailslot(struct messaging_context *msg_ctx,
- bool unique, const char *mailslot,
- uint16 priority,
- char *buf, int len,
- const char *srcname, int src_type,
- const char *dstname, int dest_type,
- const struct sockaddr_storage *dest_ss);
bool send_getdc_request(TALLOC_CTX *mem_ctx,
struct messaging_context *msg_ctx,
struct sockaddr_storage *dc_ss,
@@ -2519,15 +2511,44 @@ NTSTATUS cli_locktype(struct cli_state *cli, uint16_t fnum,
int timeout, unsigned char locktype);
bool cli_lock(struct cli_state *cli, uint16_t fnum,
uint32_t offset, uint32_t len, int timeout, enum brl_type lock_type);
-bool cli_unlock(struct cli_state *cli, uint16_t fnum, uint32_t offset, uint32_t len);
+struct tevent_req *cli_unlock_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ uint16_t fnum,
+ uint64_t offset,
+ uint64_t len);
+NTSTATUS cli_unlock_recv(struct tevent_req *req);
+NTSTATUS cli_unlock(struct cli_state *cli, uint16_t fnum, uint32_t offset, uint32_t len);
bool cli_lock64(struct cli_state *cli, uint16_t fnum,
uint64_t offset, uint64_t len, int timeout, enum brl_type lock_type);
-bool cli_unlock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len);
-bool cli_posix_lock(struct cli_state *cli, uint16_t fnum,
+struct tevent_req *cli_unlock64_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ uint16_t fnum,
+ uint64_t offset,
+ uint64_t len);
+NTSTATUS cli_unlock64_recv(struct tevent_req *req);
+NTSTATUS cli_unlock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len);
+struct tevent_req *cli_posix_lock_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ uint16_t fnum,
+ uint64_t offset,
+ uint64_t len,
+ bool wait_lock,
+ enum brl_type lock_type);
+NTSTATUS cli_posix_lock_recv(struct tevent_req *req);
+NTSTATUS cli_posix_lock(struct cli_state *cli, uint16_t fnum,
uint64_t offset, uint64_t len,
bool wait_lock, enum brl_type lock_type);
-bool cli_posix_unlock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len);
-bool cli_posix_getlock(struct cli_state *cli, uint16_t fnum, uint64_t *poffset, uint64_t *plen);
+struct tevent_req *cli_posix_unlock_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ uint16_t fnum,
+ uint64_t offset,
+ uint64_t len);
+NTSTATUS cli_posix_unlock_recv(struct tevent_req *req);
+NTSTATUS cli_posix_unlock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len);
struct tevent_req *cli_getattrE_send(TALLOC_CTX *mem_ctx,
struct event_context *ev,
struct cli_state *cli,
@@ -4587,8 +4608,8 @@ NTSTATUS pdb_lookup_names(const DOM_SID *domain_sid,
const char **names,
uint32 *rids,
enum lsa_SidType *attrs);
-bool pdb_get_account_policy(int policy_index, uint32 *value);
-bool pdb_set_account_policy(int policy_index, uint32 value);
+bool pdb_get_account_policy(enum pdb_policy_type type, uint32_t *value);
+bool pdb_set_account_policy(enum pdb_policy_type type, uint32_t value);
bool pdb_get_seq_num(time_t *seq_num);
bool pdb_uid_to_rid(uid_t uid, uint32 *rid);
bool pdb_uid_to_sid(uid_t uid, DOM_SID *sid);
@@ -5083,6 +5104,7 @@ WERROR registry_init_smbconf(const char *keyname);
/* The following definitions come from registry/reg_objects.c */
WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr);
+WERROR regsubkey_ctr_reinit(struct regsubkey_ctr *ctr);
WERROR regsubkey_ctr_set_seqnum(struct regsubkey_ctr *ctr, int seqnum);
int regsubkey_ctr_get_seqnum(struct regsubkey_ctr *ctr);
WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname );
@@ -5647,32 +5669,16 @@ void prs_switch_type(prs_struct *ps, bool io);
void prs_force_dynamic(prs_struct *ps);
void prs_set_session_key(prs_struct *ps, const char sess_key[16]);
bool prs_uint8(const char *name, prs_struct *ps, int depth, uint8 *data8);
-bool prs_pointer( const char *name, prs_struct *ps, int depth,
- void *dta, size_t data_size,
- bool (*prs_fn)(const char*, prs_struct*, int, void*) );
bool prs_uint16(const char *name, prs_struct *ps, int depth, uint16 *data16);
bool prs_uint32(const char *name, prs_struct *ps, int depth, uint32 *data32);
bool prs_int32(const char *name, prs_struct *ps, int depth, int32 *data32);
bool prs_uint64(const char *name, prs_struct *ps, int depth, uint64 *data64);
-bool prs_ntstatus(const char *name, prs_struct *ps, int depth, NTSTATUS *status);
bool prs_dcerpc_status(const char *name, prs_struct *ps, int depth, NTSTATUS *status);
-bool prs_werror(const char *name, prs_struct *ps, int depth, WERROR *status);
bool prs_uint8s(bool charmode, const char *name, prs_struct *ps, int depth, uint8 *data8s, int len);
bool prs_uint16s(bool charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len);
-bool prs_uint16uni(bool charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len);
bool prs_uint32s(bool charmode, const char *name, prs_struct *ps, int depth, uint32 *data32s, int len);
bool prs_unistr(const char *name, prs_struct *ps, int depth, UNISTR *str);
bool prs_string(const char *name, prs_struct *ps, int depth, char *str, int max_buf_size);
-bool prs_string_alloc(const char *name, prs_struct *ps, int depth, const char **str);
-bool prs_uint16_pre(const char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset);
-bool prs_uint16_post(const char *name, prs_struct *ps, int depth, uint16 *data16,
- uint32 ptr_uint16, uint32 start_offset);
-bool prs_uint32_pre(const char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset);
-bool prs_uint32_post(const char *name, prs_struct *ps, int depth, uint32 *data32,
- uint32 ptr_uint32, uint32 data_size);
-int tdb_prs_store(TDB_CONTEXT *tdb, TDB_DATA kbuf, prs_struct *ps);
-int tdb_prs_fetch(TDB_CONTEXT *tdb, TDB_DATA kbuf, prs_struct *ps, TALLOC_CTX *mem_ctx);
-bool prs_hash1(prs_struct *ps, uint32 offset, int len);
void schannel_encode(struct schannel_auth_struct *a, enum pipe_auth_level auth_level,
enum schannel_direction direction,
RPC_AUTH_SCHANNEL_CHK * verf,
@@ -5877,7 +5883,6 @@ void copy_id26_to_sam_passwd(struct samu *to,
/* The following definitions come from rpc_server/srv_spoolss_nt.c */
-WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename );
void do_drv_upgrade_printer(struct messaging_context *msg,
void *private_data,
uint32_t msg_type,
@@ -5966,9 +5971,7 @@ void construct_info_data(struct spoolss_Notify *info_data,
int id);
struct spoolss_DeviceMode *construct_dev_mode(TALLOC_CTX *mem_ctx,
const char *servicename);
-WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri );
bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer);
-WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines );
/* The following definitions come from rpc_server/srv_srvsvc_nt.c */
@@ -6260,16 +6263,14 @@ void reply_dos_error(struct smb_request *req, uint8 eclass, uint32 ecode,
void reply_both_error(struct smb_request *req, uint8 eclass, uint32 ecode,
NTSTATUS status, int line, const char *file);
void reply_openerror(struct smb_request *req, NTSTATUS status);
-void reply_unix_error(struct smb_request *req, uint8 defclass, uint32 defcode,
- NTSTATUS defstatus, int line, const char *file);
/* The following definitions come from smbd/fake_file.c */
-enum FAKE_FILE_TYPE is_fake_file(const char *fname);
+enum FAKE_FILE_TYPE is_fake_file(const struct smb_filename *smb_fname);
NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn,
uint16_t current_vuid,
enum FAKE_FILE_TYPE fake_file_type,
- const char *fname,
+ const struct smb_filename *smb_fname,
uint32 access_mask,
files_struct **result);
NTSTATUS close_fake_file(struct smb_request *req, files_struct *fsp);
@@ -6306,6 +6307,23 @@ int fsp_stat(files_struct *fsp, SMB_STRUCT_STAT *pst);
/* The following definitions come from smbd/filename.c */
+NTSTATUS unix_convert(TALLOC_CTX *ctx,
+ connection_struct *conn,
+ const char *orig_path,
+ struct smb_filename **smb_fname,
+ uint32_t ucf_flags);
+NTSTATUS check_name(connection_struct *conn, const char *name);
+int get_real_filename(connection_struct *conn, const char *path,
+ const char *name, TALLOC_CTX *mem_ctx,
+ char **found_name);
+NTSTATUS filename_convert(TALLOC_CTX *mem_ctx,
+ connection_struct *conn,
+ bool dfs_path,
+ const char *name_in,
+ struct smb_filename **pp_smb_fname);
+
+/* The following definitions come from smbd/filename_utils.c */
+
NTSTATUS get_full_smb_filename(TALLOC_CTX *ctx, const struct smb_filename *smb_fname,
char **full_name);
NTSTATUS create_synthetic_smb_fname(TALLOC_CTX *ctx, const char *base_name,
@@ -6316,29 +6334,13 @@ NTSTATUS create_synthetic_smb_fname_split(TALLOC_CTX *ctx,
const char *fname,
const SMB_STRUCT_STAT *psbuf,
struct smb_filename **smb_fname_out);
-int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
- SMB_STRUCT_STAT *psbuf);
-int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
- SMB_STRUCT_STAT *psbuf);
const char *smb_fname_str_dbg(const struct smb_filename *smb_fname);
+const char *fsp_str_dbg(const struct files_struct *fsp);
NTSTATUS copy_smb_filename(TALLOC_CTX *ctx,
const struct smb_filename *smb_fname_in,
struct smb_filename **smb_fname_out);
-NTSTATUS unix_convert(TALLOC_CTX *ctx,
- connection_struct *conn,
- const char *orig_path,
- struct smb_filename **smb_fname,
- uint32_t ucf_flags);
-NTSTATUS check_name(connection_struct *conn, const char *name);
-int get_real_filename(connection_struct *conn, const char *path,
- const char *name, TALLOC_CTX *mem_ctx,
- char **found_name);
-NTSTATUS filename_convert(TALLOC_CTX *mem_ctx,
- connection_struct *conn,
- bool dfs_path,
- const char *name_in,
- struct smb_filename **pp_smb_fname,
- char **pp_name);
+bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname);
+bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname);
/* The following definitions come from smbd/files.c */
@@ -6364,9 +6366,11 @@ void file_sync_all(connection_struct *conn);
void file_free(struct smb_request *req, files_struct *fsp);
files_struct *file_fnum(uint16 fnum);
files_struct *file_fsp(struct smb_request *req, uint16 fid);
-void dup_file_fsp(struct smb_request *req, files_struct *from,
+NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *from,
uint32 access_mask, uint32 share_access,
uint32 create_options, files_struct *to);
+NTSTATUS fsp_set_smb_fname(struct files_struct *fsp,
+ const struct smb_filename *smb_fname_in);
/* The following definitions come from smbd/ipc.c */
@@ -6544,8 +6548,6 @@ void send_nt_replies(connection_struct *conn,
struct smb_request *req, NTSTATUS nt_error,
char *params, int paramsize,
char *pdata, int datasize);
-bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname);
-bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname);
void reply_ntcreate_and_X(struct smb_request *req);
void reply_ntcancel(struct smb_request *req);
void reply_ntrename(struct smb_request *req);
@@ -6586,7 +6588,8 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req,
uint32 access_mask,
uint32 share_access,
uint32 create_options);
-bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func,
+bool map_open_params_to_ntcreate(const struct smb_filename *smb_fname,
+ int deny_mode, int open_func,
uint32 *paccess_mask,
uint32 *pshare_mode,
uint32 *pcreate_disposition,
@@ -7113,6 +7116,10 @@ char *vfs_readdirname(connection_struct *conn, void *p, SMB_STRUCT_STAT *sbuf);
int vfs_ChDir(connection_struct *conn, const char *path);
char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn);
NTSTATUS check_reduced_name(connection_struct *conn, const char *fname);
+int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
+ SMB_STRUCT_STAT *psbuf);
+int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
+ SMB_STRUCT_STAT *psbuf);
/* The following definitions come from torture/denytest.c */
@@ -7262,6 +7269,16 @@ NTSTATUS access_check_object( SEC_DESC *psd, NT_USER_TOKEN *token,
SE_PRIV *rights, uint32 rights_mask,
uint32 des_access, uint32 *acc_granted,
const char *debug);
-void map_max_allowed_access(const NT_USER_TOKEN *token,
- uint32_t *pacc_requested);
+void map_max_allowed_access(const NT_USER_TOKEN *nt_token,
+ const struct unix_user_token *unix_token,
+ uint32_t *pacc_requested);
+
+/* The following definitions come from ../libds/common/flag_mapping.c */
+
+uint32_t ds_acb2uf(uint32_t acb);
+uint32_t ds_uf2acb(uint32_t uf);
+uint32_t ds_uf2atype(uint32_t uf);
+uint32_t ds_gtype2atype(uint32_t gtype);
+enum lsa_SidType ds_atype_map(uint32_t atype);
+
#endif /* _PROTO_H_ */
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 9afeb67b00..94ed2186fb 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -452,7 +452,7 @@ typedef struct files_struct {
bool lockdb_clean;
bool initial_delete_on_close; /* Only set at NTCreateX if file was created. */
bool posix_open;
- char *fsp_name;
+ struct smb_filename *fsp_name;
struct vfs_fsp_data *vfs_extension;
struct fake_file_handle *fake_file_handle;
@@ -834,20 +834,6 @@ struct pipe_open_rec {
#define MAX_PW_HISTORY_LEN 24
/*
- * Flags for account policy.
- */
-#define AP_MIN_PASSWORD_LEN 1
-#define AP_PASSWORD_HISTORY 2
-#define AP_USER_MUST_LOGON_TO_CHG_PASS 3
-#define AP_MAX_PASSWORD_AGE 4
-#define AP_MIN_PASSWORD_AGE 5
-#define AP_LOCK_ACCOUNT_DURATION 6
-#define AP_RESET_COUNT_TIME 7
-#define AP_BAD_ATTEMPT_LOCKOUT 8
-#define AP_TIME_TO_LOGOUT 9
-#define AP_REFUSE_MACHINE_PW_CHANGE 10
-
-/*
* Flags for local user manipulation.
*/
diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h
index 7528883c2d..10ee78b394 100644
--- a/source3/include/smb_macros.h
+++ b/source3/include/smb_macros.h
@@ -115,7 +115,6 @@
#define reply_force_nterror(req,status) reply_force_nt_error(req,status,__LINE__,__FILE__)
#define reply_doserror(req,eclass,ecode) reply_dos_error(req,eclass,ecode,__LINE__,__FILE__)
#define reply_botherror(req,status,eclass,ecode) reply_both_error(req,eclass,ecode,status,__LINE__,__FILE__)
-#define reply_unixerror(req,defclass,deferror) reply_unix_error(req,defclass,deferror,NT_STATUS_OK,__LINE__,__FILE__)
#if 0
/* defined in IDL */
diff --git a/source3/include/util_tdb.h b/source3/include/util_tdb.h
index c79436434f..80b95921d7 100644
--- a/source3/include/util_tdb.h
+++ b/source3/include/util_tdb.h
@@ -59,4 +59,6 @@ struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *mem_ctx,
NTSTATUS map_nt_error_from_tdb(enum TDB_ERROR err);
+int tdb_data_cmp(TDB_DATA t1, TDB_DATA t2);
+
#endif /* __TDBUTIL_H__ */
diff --git a/source3/lib/account_pol.c b/source3/lib/account_pol.c
index 1e435ca53e..f4101e96bc 100644
--- a/source3/lib/account_pol.c
+++ b/source3/lib/account_pol.c
@@ -1,20 +1,20 @@
-/*
+/*
* Unix SMB/CIFS implementation.
* account policy storage
* Copyright (C) Jean François Micouleau 1998-2001.
* Copyright (C) Andrew Bartlett 2002
* Copyright (C) Guenther Deschner 2004-2005
- *
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
@@ -31,7 +31,7 @@ static struct db_context *db;
struct ap_table {
- int field;
+ enum pdb_policy_type type;
const char *string;
uint32 default_val;
const char *description;
@@ -39,51 +39,51 @@ struct ap_table {
};
static const struct ap_table account_policy_names[] = {
- {AP_MIN_PASSWORD_LEN, "min password length", MINPASSWDLENGTH,
- "Minimal password length (default: 5)",
+ {PDB_POLICY_MIN_PASSWORD_LEN, "min password length", MINPASSWDLENGTH,
+ "Minimal password length (default: 5)",
"sambaMinPwdLength" },
- {AP_PASSWORD_HISTORY, "password history", 0,
- "Length of Password History Entries (default: 0 => off)",
+ {PDB_POLICY_PASSWORD_HISTORY, "password history", 0,
+ "Length of Password History Entries (default: 0 => off)",
"sambaPwdHistoryLength" },
-
- {AP_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password", 0,
+
+ {PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password", 0,
"Force Users to logon for password change (default: 0 => off, 2 => on)",
"sambaLogonToChgPwd" },
-
- {AP_MAX_PASSWORD_AGE, "maximum password age", (uint32) -1,
- "Maximum password age, in seconds (default: -1 => never expire passwords)",
+
+ {PDB_POLICY_MAX_PASSWORD_AGE, "maximum password age", (uint32) -1,
+ "Maximum password age, in seconds (default: -1 => never expire passwords)",
"sambaMaxPwdAge" },
-
- {AP_MIN_PASSWORD_AGE,"minimum password age", 0,
- "Minimal password age, in seconds (default: 0 => allow immediate password change)",
+
+ {PDB_POLICY_MIN_PASSWORD_AGE,"minimum password age", 0,
+ "Minimal password age, in seconds (default: 0 => allow immediate password change)",
"sambaMinPwdAge" },
-
- {AP_LOCK_ACCOUNT_DURATION, "lockout duration", 30,
+
+ {PDB_POLICY_LOCK_ACCOUNT_DURATION, "lockout duration", 30,
"Lockout duration in minutes (default: 30, -1 => forever)",
"sambaLockoutDuration" },
-
- {AP_RESET_COUNT_TIME, "reset count minutes", 30,
- "Reset time after lockout in minutes (default: 30)",
+
+ {PDB_POLICY_RESET_COUNT_TIME, "reset count minutes", 30,
+ "Reset time after lockout in minutes (default: 30)",
"sambaLockoutObservationWindow" },
-
- {AP_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt", 0,
- "Lockout users after bad logon attempts (default: 0 => off)",
+
+ {PDB_POLICY_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt", 0,
+ "Lockout users after bad logon attempts (default: 0 => off)",
"sambaLockoutThreshold" },
-
- {AP_TIME_TO_LOGOUT, "disconnect time", (uint32) -1,
- "Disconnect Users outside logon hours (default: -1 => off, 0 => on)",
- "sambaForceLogoff" },
-
- {AP_REFUSE_MACHINE_PW_CHANGE, "refuse machine password change", 0,
+
+ {PDB_POLICY_TIME_TO_LOGOUT, "disconnect time", (uint32) -1,
+ "Disconnect Users outside logon hours (default: -1 => off, 0 => on)",
+ "sambaForceLogoff" },
+
+ {PDB_POLICY_REFUSE_MACHINE_PW_CHANGE, "refuse machine password change", 0,
"Allow Machine Password changes (default: 0 => off)",
"sambaRefuseMachinePwdChange" },
-
+
{0, NULL, 0, "", NULL}
};
void account_policy_names_list(const char ***names, int *num_names)
-{
+{
const char **nl;
int i, count;
@@ -106,11 +106,11 @@ void account_policy_names_list(const char ***names, int *num_names)
Get the account policy name as a string from its #define'ed number
****************************************************************************/
-const char *decode_account_policy_name(int field)
+const char *decode_account_policy_name(enum pdb_policy_type type)
{
int i;
for (i=0; account_policy_names[i].string; i++) {
- if (field == account_policy_names[i].field) {
+ if (type == account_policy_names[i].type) {
return account_policy_names[i].string;
}
}
@@ -121,11 +121,11 @@ const char *decode_account_policy_name(int field)
Get the account policy LDAP attribute as a string from its #define'ed number
****************************************************************************/
-const char *get_account_policy_attr(int field)
+const char *get_account_policy_attr(enum pdb_policy_type type)
{
int i;
- for (i=0; account_policy_names[i].field; i++) {
- if (field == account_policy_names[i].field) {
+ for (i=0; account_policy_names[i].type; i++) {
+ if (type == account_policy_names[i].type) {
return account_policy_names[i].ldap_attr;
}
}
@@ -136,11 +136,11 @@ const char *get_account_policy_attr(int field)
Get the account policy description as a string from its #define'ed number
****************************************************************************/
-const char *account_policy_get_desc(int field)
+const char *account_policy_get_desc(enum pdb_policy_type type)
{
int i;
for (i=0; account_policy_names[i].string; i++) {
- if (field == account_policy_names[i].field) {
+ if (type == account_policy_names[i].type) {
return account_policy_names[i].description;
}
}
@@ -151,12 +151,12 @@ const char *account_policy_get_desc(int field)
Get the account policy name as a string from its #define'ed number
****************************************************************************/
-int account_policy_name_to_fieldnum(const char *name)
+enum pdb_policy_type account_policy_name_to_typenum(const char *name)
{
int i;
for (i=0; account_policy_names[i].string; i++) {
if (strcmp(name, account_policy_names[i].string) == 0) {
- return account_policy_names[i].field;
+ return account_policy_names[i].type;
}
}
return 0;
@@ -166,35 +166,35 @@ int account_policy_name_to_fieldnum(const char *name)
Get default value for account policy
*****************************************************************************/
-bool account_policy_get_default(int account_policy, uint32 *val)
+bool account_policy_get_default(enum pdb_policy_type type, uint32_t *val)
{
int i;
- for (i=0; account_policy_names[i].field; i++) {
- if (account_policy_names[i].field == account_policy) {
+ for (i=0; account_policy_names[i].type; i++) {
+ if (account_policy_names[i].type == type) {
*val = account_policy_names[i].default_val;
return True;
}
}
- DEBUG(0,("no default for account_policy index %d found. This should never happen\n",
- account_policy));
+ DEBUG(0,("no default for account_policy index %d found. This should never happen\n",
+ type));
return False;
}
/*****************************************************************************
- Set default for a field if it is empty
+ Set default for a type if it is empty
*****************************************************************************/
-static bool account_policy_set_default_on_empty(int account_policy)
+static bool account_policy_set_default_on_empty(enum pdb_policy_type type)
{
uint32 value;
- if (!account_policy_get(account_policy, &value) &&
- !account_policy_get_default(account_policy, &value)) {
+ if (!account_policy_get(type, &value) &&
+ !account_policy_get_default(type, &value)) {
return False;
}
- return account_policy_set(account_policy, value);
+ return account_policy_set(type, value);
}
/*****************************************************************************
@@ -255,9 +255,9 @@ bool init_account_policy(void)
goto cancel;
}
- for (i=0; account_policy_names[i].field; i++) {
+ for (i=0; account_policy_names[i].type; i++) {
- if (!account_policy_set_default_on_empty(account_policy_names[i].field)) {
+ if (!account_policy_set_default_on_empty(account_policy_names[i].type)) {
DEBUG(0,("failed to set default value in account policy tdb\n"));
goto cancel;
}
@@ -299,10 +299,10 @@ bool init_account_policy(void)
}
/*****************************************************************************
-Get an account policy (from tdb)
+Get an account policy (from tdb)
*****************************************************************************/
-bool account_policy_get(int field, uint32 *value)
+bool account_policy_get(enum pdb_policy_type type, uint32_t *value)
{
const char *name;
uint32 regval;
@@ -315,17 +315,17 @@ bool account_policy_get(int field, uint32 *value)
*value = 0;
}
- name = decode_account_policy_name(field);
+ name = decode_account_policy_name(type);
if (name == NULL) {
- DEBUG(1, ("account_policy_get: Field %d is not a valid account policy type! Cannot get, returning 0.\n", field));
+ DEBUG(1, ("account_policy_get: Field %d is not a valid account policy type! Cannot get, returning 0.\n", type));
return False;
}
-
+
if (!dbwrap_fetch_uint32(db, name, &regval)) {
- DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for field %d (%s), returning 0\n", field, name));
+ DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for type %d (%s), returning 0\n", type, name));
return False;
}
-
+
if (value) {
*value = regval;
}
@@ -336,10 +336,10 @@ bool account_policy_get(int field, uint32 *value)
/****************************************************************************
-Set an account policy (in tdb)
+Set an account policy (in tdb)
****************************************************************************/
-bool account_policy_set(int field, uint32 value)
+bool account_policy_set(enum pdb_policy_type type, uint32_t value)
{
const char *name;
NTSTATUS status;
@@ -348,36 +348,36 @@ bool account_policy_set(int field, uint32 value)
return False;
}
- name = decode_account_policy_name(field);
+ name = decode_account_policy_name(type);
if (name == NULL) {
- DEBUG(1, ("Field %d is not a valid account policy type! Cannot set.\n", field));
+ DEBUG(1, ("Field %d is not a valid account policy type! Cannot set.\n", type));
return False;
}
status = dbwrap_trans_store_uint32(db, name, value);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("store_uint32 failed for field %d (%s) on value "
- "%u: %s\n", field, name, value, nt_errstr(status)));
+ DEBUG(1, ("store_uint32 failed for type %d (%s) on value "
+ "%u: %s\n", type, name, value, nt_errstr(status)));
return False;
}
DEBUG(10,("account_policy_set: name: %s, value: %d\n", name, value));
-
+
return True;
}
/****************************************************************************
-Set an account policy in the cache
+Set an account policy in the cache
****************************************************************************/
-bool cache_account_policy_set(int field, uint32 value)
+bool cache_account_policy_set(enum pdb_policy_type type, uint32_t value)
{
const char *policy_name = NULL;
char *cache_key = NULL;
char *cache_value = NULL;
bool ret = False;
- policy_name = decode_account_policy_name(field);
+ policy_name = decode_account_policy_name(type);
if (policy_name == NULL) {
DEBUG(0,("cache_account_policy_set: no policy found\n"));
return False;
@@ -404,17 +404,17 @@ bool cache_account_policy_set(int field, uint32 value)
}
/*****************************************************************************
-Get an account policy from the cache
+Get an account policy from the cache
*****************************************************************************/
-bool cache_account_policy_get(int field, uint32 *value)
+bool cache_account_policy_get(enum pdb_policy_type type, uint32_t *value)
{
const char *policy_name = NULL;
char *cache_key = NULL;
char *cache_value = NULL;
bool ret = False;
- policy_name = decode_account_policy_name(field);
+ policy_name = decode_account_policy_name(type);
if (policy_name == NULL) {
DEBUG(0,("cache_account_policy_set: no policy found\n"));
return False;
diff --git a/source3/lib/ads_flags.c b/source3/lib/ads_flags.c
deleted file mode 100644
index a8fa062f2a..0000000000
--- a/source3/lib/ads_flags.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- ads (active directory) utility library
-
- Copyright (C) Stefan (metze) Metzmacher 2002
- Copyright (C) Andrew Tridgell 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-
-/*
-translated the ACB_CTRL Flags to UserFlags (userAccountControl)
-*/
-uint32 ads_acb2uf(uint32 acb)
-{
- uint32 uf = 0x00000000;
-
- if (acb & ACB_DISABLED) uf |= UF_ACCOUNTDISABLE;
- if (acb & ACB_HOMDIRREQ) uf |= UF_HOMEDIR_REQUIRED;
- if (acb & ACB_PWNOTREQ) uf |= UF_PASSWD_NOTREQD;
- if (acb & ACB_TEMPDUP) uf |= UF_TEMP_DUPLICATE_ACCOUNT;
- if (acb & ACB_NORMAL) uf |= UF_NORMAL_ACCOUNT;
- if (acb & ACB_MNS) uf |= UF_MNS_LOGON_ACCOUNT;
- if (acb & ACB_DOMTRUST) uf |= UF_INTERDOMAIN_TRUST_ACCOUNT;
- if (acb & ACB_WSTRUST) uf |= UF_WORKSTATION_TRUST_ACCOUNT;
- if (acb & ACB_SVRTRUST) uf |= UF_SERVER_TRUST_ACCOUNT;
- if (acb & ACB_PWNOEXP) uf |= UF_DONT_EXPIRE_PASSWD;
- if (acb & ACB_AUTOLOCK) uf |= UF_LOCKOUT;
- if (acb & ACB_USE_DES_KEY_ONLY) uf |= UF_USE_DES_KEY_ONLY;
- if (acb & ACB_SMARTCARD_REQUIRED) uf |= UF_SMARTCARD_REQUIRED;
- if (acb & ACB_TRUSTED_FOR_DELEGATION) uf |= UF_TRUSTED_FOR_DELEGATION;
- if (acb & ACB_DONT_REQUIRE_PREAUTH) uf |= UF_DONT_REQUIRE_PREAUTH;
- if (acb & ACB_NO_AUTH_DATA_REQD) uf |= UF_NO_AUTH_DATA_REQUIRED;
- if (acb & ACB_NOT_DELEGATED) uf |= UF_NOT_DELEGATED;
- if (acb & ACB_ENC_TXT_PWD_ALLOWED) uf |= UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED;
-
- return uf;
-}
-
-/*
-translated the UserFlags (userAccountControl) to ACB_CTRL Flags
-*/
-uint32 ads_uf2acb(uint32 uf)
-{
- uint32 acb = 0x00000000;
-
- if (uf & UF_ACCOUNTDISABLE) acb |= ACB_DISABLED;
- if (uf & UF_HOMEDIR_REQUIRED) acb |= ACB_HOMDIRREQ;
- if (uf & UF_PASSWD_NOTREQD) acb |= ACB_PWNOTREQ;
- if (uf & UF_MNS_LOGON_ACCOUNT) acb |= ACB_MNS;
- if (uf & UF_DONT_EXPIRE_PASSWD) acb |= ACB_PWNOEXP;
- if (uf & UF_LOCKOUT) acb |= ACB_AUTOLOCK;
- if (uf & UF_USE_DES_KEY_ONLY) acb |= ACB_USE_DES_KEY_ONLY;
- if (uf & UF_SMARTCARD_REQUIRED) acb |= ACB_SMARTCARD_REQUIRED;
- if (uf & UF_TRUSTED_FOR_DELEGATION) acb |= ACB_TRUSTED_FOR_DELEGATION;
- if (uf & UF_DONT_REQUIRE_PREAUTH) acb |= ACB_DONT_REQUIRE_PREAUTH;
- if (uf & UF_NO_AUTH_DATA_REQUIRED) acb |= ACB_NO_AUTH_DATA_REQD;
- if (uf & UF_NOT_DELEGATED) acb |= ACB_NOT_DELEGATED;
- if (uf & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED) acb |= ACB_ENC_TXT_PWD_ALLOWED;
-
- switch (uf & UF_ACCOUNT_TYPE_MASK)
- {
- case UF_TEMP_DUPLICATE_ACCOUNT: acb |= ACB_TEMPDUP;break;
- case UF_NORMAL_ACCOUNT: acb |= ACB_NORMAL;break;
- case UF_INTERDOMAIN_TRUST_ACCOUNT: acb |= ACB_DOMTRUST;break;
- case UF_WORKSTATION_TRUST_ACCOUNT: acb |= ACB_WSTRUST;break;
- case UF_SERVER_TRUST_ACCOUNT: acb |= ACB_SVRTRUST;break;
- /*Fix Me: what should we do here? */
- default: acb |= ACB_NORMAL;break;
- }
-
- return acb;
-}
-
-/*
-get the accountType from the UserFlags
-*/
-uint32 ads_uf2atype(uint32 uf)
-{
- uint32 atype = 0x00000000;
-
- if (uf & UF_NORMAL_ACCOUNT) atype = ATYPE_NORMAL_ACCOUNT;
- else if (uf & UF_TEMP_DUPLICATE_ACCOUNT) atype = ATYPE_NORMAL_ACCOUNT;
- else if (uf & UF_SERVER_TRUST_ACCOUNT) atype = ATYPE_WORKSTATION_TRUST;
- else if (uf & UF_WORKSTATION_TRUST_ACCOUNT) atype = ATYPE_WORKSTATION_TRUST;
- else if (uf & UF_INTERDOMAIN_TRUST_ACCOUNT) atype = ATYPE_INTERDOMAIN_TRUST;
-
- return atype;
-}
-
-/*
-get the accountType from the groupType
-*/
-uint32 ads_gtype2atype(uint32 gtype)
-{
- uint32 atype = 0x00000000;
-
- switch(gtype) {
- case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
- atype = ATYPE_SECURITY_LOCAL_GROUP;
- break;
- case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
- atype = ATYPE_SECURITY_LOCAL_GROUP;
- break;
- case GTYPE_SECURITY_GLOBAL_GROUP:
- atype = ATYPE_SECURITY_GLOBAL_GROUP;
- break;
-
- case GTYPE_DISTRIBUTION_GLOBAL_GROUP:
- atype = ATYPE_DISTRIBUTION_GLOBAL_GROUP;
- break;
- case GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP:
- atype = ATYPE_DISTRIBUTION_UNIVERSAL_GROUP;
- break;
- case GTYPE_DISTRIBUTION_UNIVERSAL_GROUP:
- atype = ATYPE_DISTRIBUTION_LOCAL_GROUP;
- break;
- }
-
- return atype;
-}
-
-/* turn a sAMAccountType into a SID_NAME_USE */
-enum lsa_SidType ads_atype_map(uint32 atype)
-{
- switch (atype & 0xF0000000) {
- case ATYPE_GLOBAL_GROUP:
- return SID_NAME_DOM_GRP;
- case ATYPE_SECURITY_LOCAL_GROUP:
- return SID_NAME_ALIAS;
- case ATYPE_ACCOUNT:
- return SID_NAME_USER;
- default:
- DEBUG(1,("hmm, need to map account type 0x%x\n", atype));
- }
- return SID_NAME_UNKNOWN;
-}
diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c
index a1663c1f38..272f107138 100644
--- a/source3/lib/charcnv.c
+++ b/source3/lib/charcnv.c
@@ -753,7 +753,7 @@ size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
size_t size;
smb_ucs2_t *buffer;
- if (!push_ucs2_talloc(NULL, &buffer, src, &size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &size)) {
return (size_t)-1;
}
@@ -837,7 +837,7 @@ size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
size_t size;
smb_ucs2_t *buffer = NULL;
- if (!convert_string_talloc(NULL, CH_UNIX, CH_UTF16LE, src, srclen,
+ if (!convert_string_talloc(talloc_tos(), CH_UNIX, CH_UTF16LE, src, srclen,
(void **)(void *)&buffer, &size,
True))
{
@@ -951,7 +951,7 @@ size_t push_ascii_nstring(void *dest, const char *src)
smb_ucs2_t *buffer;
conv_silent = True;
- if (!push_ucs2_talloc(NULL, &buffer, src, &buffer_len)) {
+ if (!push_ucs2_talloc(talloc_tos(), &buffer, src, &buffer_len)) {
smb_panic("failed to create UCS2 buffer");
}
@@ -1268,7 +1268,7 @@ static size_t push_utf8(void *dest, const char *src, size_t dest_len, int flags)
}
if (flags & STR_UPPER) {
- tmpbuf = strupper_talloc(NULL, src);
+ tmpbuf = strupper_talloc(talloc_tos(), src);
if (!tmpbuf) {
return (size_t)-1;
}
diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c
index dde377581b..449e049ffa 100644
--- a/source3/lib/ctdbd_conn.c
+++ b/source3/lib/ctdbd_conn.c
@@ -358,7 +358,7 @@ static NTSTATUS ctdb_read_req(struct ctdbd_connection *conn, uint32 reqid,
goto next_pkt;
}
- if (!(msg_state = TALLOC_P(NULL, struct deferred_msg_state))) {
+ if (!(msg_state = TALLOC_P(talloc_autofree_context(), struct deferred_msg_state))) {
DEBUG(0, ("talloc failed\n"));
TALLOC_FREE(hdr);
goto next_pkt;
diff --git a/source3/lib/dbwrap_tdb.c b/source3/lib/dbwrap_tdb.c
index c71e073b41..297a351764 100644
--- a/source3/lib/dbwrap_tdb.c
+++ b/source3/lib/dbwrap_tdb.c
@@ -94,7 +94,7 @@ static struct db_record *db_tdb_fetch_locked(struct db_context *db,
/* Do not accidently allocate/deallocate w/o need when debug level is lower than needed */
if(DEBUGLEVEL >= 10) {
- char *keystr = hex_encode_talloc(NULL, (unsigned char*)key.dptr, key.dsize);
+ char *keystr = hex_encode_talloc(talloc_tos(), (unsigned char*)key.dptr, key.dsize);
DEBUG(10, (DEBUGLEVEL > 10
? "Locking key %s\n" : "Locking key %.20s\n",
keystr));
diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c
index 3be3a49e7d..c3ab93c4df 100644
--- a/source3/lib/dbwrap_util.c
+++ b/source3/lib/dbwrap_util.c
@@ -2,6 +2,7 @@
Unix SMB/CIFS implementation.
Utility functions for the dbwrap API
Copyright (C) Volker Lendecke 2007
+ Copyright (C) Michael Adam 2009
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
@@ -178,96 +179,77 @@ int32 dbwrap_change_int32_atomic(struct db_context *db, const char *keystr,
return 0;
}
-NTSTATUS dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf,
- int flag)
+struct dbwrap_store_context {
+ TDB_DATA *key;
+ TDB_DATA *dbuf;
+ int flag;
+};
+
+static NTSTATUS dbwrap_store_action(struct db_context *db, void *private_data)
{
- int res;
struct db_record *rec = NULL;
NTSTATUS status;
+ struct dbwrap_store_context *store_ctx;
- res = db->transaction_start(db);
- if (res != 0) {
- DEBUG(5, ("transaction_start failed\n"));
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
+ store_ctx = (struct dbwrap_store_context *)private_data;
- rec = db->fetch_locked(db, talloc_tos(), key);
+ rec = db->fetch_locked(db, talloc_tos(), *(store_ctx->key));
if (rec == NULL) {
DEBUG(5, ("fetch_locked failed\n"));
- status = NT_STATUS_NO_MEMORY;
- goto cancel;
+ return NT_STATUS_NO_MEMORY;
}
- status = rec->store(rec, dbuf, flag);
+ status = rec->store(rec, *(store_ctx->dbuf), store_ctx->flag);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5, ("store returned %s\n", nt_errstr(status)));
- goto cancel;
}
TALLOC_FREE(rec);
+ return status;
+}
- res = db->transaction_commit(db);
- if (res != 0) {
- DEBUG(5, ("tdb_transaction_commit failed\n"));
- status = NT_STATUS_INTERNAL_DB_CORRUPTION;
- TALLOC_FREE(rec);
- return status;
- }
+NTSTATUS dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf,
+ int flag)
+{
+ NTSTATUS status;
+ struct dbwrap_store_context store_ctx;
- return NT_STATUS_OK;
+ store_ctx.key = &key;
+ store_ctx.dbuf = &dbuf;
+ store_ctx.flag = flag;
- cancel:
- TALLOC_FREE(rec);
+ status = dbwrap_trans_do(db, dbwrap_store_action, &store_ctx);
- if (db->transaction_cancel(db) != 0) {
- smb_panic("Cancelling transaction failed");
- }
return status;
}
-NTSTATUS dbwrap_trans_delete(struct db_context *db, TDB_DATA key)
+static NTSTATUS dbwrap_delete_action(struct db_context * db, void *private_data)
{
- int res;
- struct db_record *rec = NULL;
NTSTATUS status;
+ struct db_record *rec;
+ TDB_DATA *key = (TDB_DATA *)private_data;
- res = db->transaction_start(db);
- if (res != 0) {
- DEBUG(5, ("transaction_start failed\n"));
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
-
- rec = db->fetch_locked(db, talloc_tos(), key);
+ rec = db->fetch_locked(db, talloc_tos(), *key);
if (rec == NULL) {
DEBUG(5, ("fetch_locked failed\n"));
- status = NT_STATUS_NO_MEMORY;
- goto cancel;
+ return NT_STATUS_NO_MEMORY;
}
status = rec->delete_rec(rec);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5, ("delete_rec returned %s\n", nt_errstr(status)));
- goto cancel;
}
- TALLOC_FREE(rec);
-
- res = db->transaction_commit(db);
- if (res != 0) {
- DEBUG(5, ("tdb_transaction_commit failed\n"));
- status = NT_STATUS_INTERNAL_DB_CORRUPTION;
- TALLOC_FREE(rec);
- return status;
- }
+ talloc_free(rec);
+ return status;
+}
- return NT_STATUS_OK;
+NTSTATUS dbwrap_trans_delete(struct db_context *db, TDB_DATA key)
+{
+ NTSTATUS status;
- cancel:
- TALLOC_FREE(rec);
+ status = dbwrap_trans_do(db, dbwrap_delete_action, &key);
- if (db->transaction_cancel(db) != 0) {
- smb_panic("Cancelling transaction failed");
- }
return status;
}
@@ -307,3 +289,86 @@ NTSTATUS dbwrap_trans_delete_bystring(struct db_context *db, const char *key)
{
return dbwrap_trans_delete(db, string_term_tdb_data(key));
}
+
+/**
+ * Wrap db action(s) into a transaction.
+ */
+NTSTATUS dbwrap_trans_do(struct db_context *db,
+ NTSTATUS (*action)(struct db_context *, void *),
+ void *private_data)
+{
+ int res;
+ NTSTATUS status;
+
+ res = db->transaction_start(db);
+ if (res != 0) {
+ DEBUG(5, ("transaction_start failed\n"));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ status = action(db, private_data);
+ if (!NT_STATUS_IS_OK(status)) {
+ if (db->transaction_cancel(db) != 0) {
+ smb_panic("Cancelling transaction failed");
+ }
+ return status;
+ }
+
+ res = db->transaction_commit(db);
+ if (res == 0) {
+ return NT_STATUS_OK;
+ }
+
+ DEBUG(2, ("transaction_commit failed\n"));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+}
+
+NTSTATUS dbwrap_delete_bystring_upper(struct db_context *db, const char *key)
+{
+ char *key_upper;
+ NTSTATUS status;
+
+ key_upper = talloc_strdup_upper(talloc_tos(), key);
+ if (key_upper == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = dbwrap_delete_bystring(db, key_upper);
+
+ talloc_free(key_upper);
+ return status;
+}
+
+NTSTATUS dbwrap_store_bystring_upper(struct db_context *db, const char *key,
+ TDB_DATA data, int flags)
+{
+ char *key_upper;
+ NTSTATUS status;
+
+ key_upper = talloc_strdup_upper(talloc_tos(), key);
+ if (key_upper == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = dbwrap_store_bystring(db, key_upper, data, flags);
+
+ talloc_free(key_upper);
+ return status;
+}
+
+TDB_DATA dbwrap_fetch_bystring_upper(struct db_context *db, TALLOC_CTX *mem_ctx,
+ const char *key)
+{
+ char *key_upper;
+ TDB_DATA result;
+
+ key_upper = talloc_strdup_upper(talloc_tos(), key);
+ if (key_upper == NULL) {
+ return make_tdb_data(NULL, 0);
+ }
+
+ result = dbwrap_fetch_bystring(db, mem_ctx, key_upper);
+
+ talloc_free(key_upper);
+ return result;
+}
diff --git a/source3/lib/errmap_unix.c b/source3/lib/errmap_unix.c
index 0c39a572ad..00c5475394 100644
--- a/source3/lib/errmap_unix.c
+++ b/source3/lib/errmap_unix.c
@@ -40,6 +40,7 @@ const struct unix_error_map unix_dos_nt_errmap[] = {
{ EISDIR, ERRDOS, ERRnoaccess, NT_STATUS_FILE_IS_A_DIRECTORY},
{ EMLINK, ERRDOS, ERRgeneral, NT_STATUS_TOO_MANY_LINKS },
{ EINTR, ERRHRD, ERRgeneral, NT_STATUS_RETRY },
+ { ENOSYS, ERRDOS, ERRunsup, NT_STATUS_NOT_SUPPORTED },
#ifdef ELOOP
{ ELOOP, ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND },
#endif
diff --git a/source3/lib/events.c b/source3/lib/events.c
index 08debb4252..7a06ad0829 100644
--- a/source3/lib/events.c
+++ b/source3/lib/events.c
@@ -286,7 +286,7 @@ static void s3_event_debug(void *context, enum tevent_debug_level level,
samba_level = 2;
break;
case TEVENT_DEBUG_TRACE:
- samba_level = 10;
+ samba_level = 11;
break;
};
diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c
index 7f133f20b0..ee1f4b70b3 100644
--- a/source3/lib/gencache.c
+++ b/source3/lib/gencache.c
@@ -26,12 +26,13 @@
#define DBGC_CLASS DBGC_TDB
#define TIMEOUT_LEN 12
-#define CACHE_DATA_FMT "%12u/%s"
+#define CACHE_DATA_FMT "%12u/"
#define READ_CACHE_DATA_FMT_TEMPLATE "%%12u/%%%us"
#define BLOB_TYPE "DATA_BLOB"
#define BLOB_TYPE_LEN 9
-static TDB_CONTEXT *cache;
+static struct tdb_context *cache;
+static struct tdb_context *cache_notrans;
/**
* @file gencache.c
@@ -49,9 +50,10 @@ static TDB_CONTEXT *cache;
* false on failure
**/
-bool gencache_init(void)
+static bool gencache_init(void)
{
char* cache_fname = NULL;
+ int open_flags = O_RDWR|O_CREAT;
/* skip file open if it's already opened */
if (cache) return True;
@@ -60,11 +62,12 @@ bool gencache_init(void)
DEBUG(5, ("Opening cache file at %s\n", cache_fname));
- cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT,
- O_RDWR|O_CREAT, 0644);
+ cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT, open_flags, 0644);
if (!cache && (errno == EACCES)) {
- cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT, O_RDONLY, 0644);
+ open_flags = O_RDONLY;
+ cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT, open_flags,
+ 0644);
if (cache) {
DEBUG(5, ("gencache_init: Opening cache file %s read-only.\n", cache_fname));
}
@@ -74,65 +77,123 @@ bool gencache_init(void)
DEBUG(5, ("Attempt to open gencache.tdb has failed.\n"));
return False;
}
- return True;
-}
+ cache_fname = lock_path("gencache_notrans.tdb");
-/**
- * Cache shutdown function. Closes opened cache tdb file.
- *
- * @return true on successful closing the cache or
- * false on failure during cache shutdown
- **/
+ DEBUG(5, ("Opening cache file at %s\n", cache_fname));
-bool gencache_shutdown(void)
-{
- int ret;
- /* tdb_close routine returns -1 on error */
- if (!cache) return False;
- DEBUG(5, ("Closing cache file\n"));
- ret = tdb_close(cache);
- cache = NULL;
- return ret != -1;
+ cache_notrans = tdb_open_log(cache_fname, 0, TDB_CLEAR_IF_FIRST,
+ open_flags, 0644);
+ if (cache_notrans == NULL) {
+ DEBUG(5, ("Opening %s failed: %s\n", cache_fname,
+ strerror(errno)));
+ tdb_close(cache);
+ return false;
+ }
+
+ return True;
}
+static TDB_DATA last_stabilize_key(void)
+{
+ TDB_DATA result;
+ result.dptr = (uint8_t *)"@LAST_STABILIZED";
+ result.dsize = 17;
+ return result;
+}
/**
* Set an entry in the cache file. If there's no such
* one, then add it.
*
* @param keystr string that represents a key of this entry
- * @param value text representation value being cached
+ * @param blob DATA_BLOB value being cached
* @param timeout time when the value is expired
*
* @retval true when entry is successfuly stored
* @retval false on failure
**/
-bool gencache_set(const char *keystr, const char *value, time_t timeout)
+bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob,
+ time_t timeout)
{
int ret;
TDB_DATA databuf;
- char* valstr = NULL;
+ char* val;
+ time_t last_stabilize;
+ static int writecount;
+
+ if (tdb_data_cmp(string_term_tdb_data(keystr),
+ last_stabilize_key()) == 0) {
+ DEBUG(10, ("Can't store %s as a key\n", keystr));
+ return false;
+ }
- /* fail completely if get null pointers passed */
- SMB_ASSERT(keystr && value);
+ if ((keystr == NULL) || (blob == NULL)) {
+ return false;
+ }
if (!gencache_init()) return False;
- if (asprintf(&valstr, CACHE_DATA_FMT, (int)timeout, value) == -1) {
+ val = talloc_asprintf(talloc_tos(), CACHE_DATA_FMT, (int)timeout);
+ if (val == NULL) {
return False;
}
+ val = talloc_realloc(NULL, val, char, talloc_array_length(val)-1);
+ if (val == NULL) {
+ return false;
+ }
+ val = (char *)talloc_append_blob(NULL, val, *blob);
+ if (val == NULL) {
+ return false;
+ }
- databuf = string_term_tdb_data(valstr);
- DEBUG(10, ("Adding cache entry with key = %s; value = %s and timeout ="
- " %s (%d seconds %s)\n", keystr, value,ctime(&timeout),
+ DEBUG(10, ("Adding cache entry with key = %s and timeout ="
+ " %s (%d seconds %s)\n", keystr, ctime(&timeout),
(int)(timeout - time(NULL)),
timeout > time(NULL) ? "ahead" : "in the past"));
- ret = tdb_store_bystring(cache, keystr, databuf, 0);
- SAFE_FREE(valstr);
+ ret = tdb_store_bystring(
+ cache_notrans, keystr,
+ make_tdb_data((uint8_t *)val, talloc_array_length(val)),
+ 0);
+ TALLOC_FREE(val);
+ if (ret != 0) {
+ return false;
+ }
+
+ /*
+ * Every 100 writes within a single process, stabilize the cache with
+ * a transaction. This is done to prevent a single transaction to
+ * become huge and chew lots of memory.
+ */
+ writecount += 1;
+ if (writecount > lp_parm_int(-1, "gencache", "stabilize_count", 100)) {
+ gencache_stabilize();
+ writecount = 0;
+ goto done;
+ }
+
+ /*
+ * Every 5 minutes, call gencache_stabilize() to not let grow
+ * gencache_notrans.tdb too large.
+ */
+
+ last_stabilize = 0;
+ databuf = tdb_fetch(cache_notrans, last_stabilize_key());
+ if ((databuf.dptr != NULL)
+ && (databuf.dptr[databuf.dsize-1] == '\0')) {
+ last_stabilize = atoi((char *)databuf.dptr);
+ SAFE_FREE(databuf.dptr);
+ }
+ if ((last_stabilize
+ + lp_parm_int(-1, "gencache", "stabilize_interval", 300))
+ < time(NULL)) {
+ gencache_stabilize();
+ }
+
+done:
return ret == 0;
}
@@ -147,26 +208,63 @@ bool gencache_set(const char *keystr, const char *value, time_t timeout)
bool gencache_del(const char *keystr)
{
- int ret;
+ bool exists;
+ bool ret = false;
+ char *value;
- /* fail completely if get null pointers passed */
- SMB_ASSERT(keystr);
+ if (keystr == NULL) {
+ return false;
+ }
if (!gencache_init()) return False;
DEBUG(10, ("Deleting cache entry (key = %s)\n", keystr));
- ret = tdb_delete_bystring(cache, keystr);
- return ret == 0;
+ if (tdb_lock_bystring(cache_notrans, keystr) == -1) {
+ DEBUG(5, ("Could not lock key for %s\n", keystr));
+ return false;
+ }
+
+ /*
+ * We delete an element by setting its timeout to 0. This way we don't
+ * have to do a transaction on gencache.tdb every time we delete an
+ * element.
+ */
+
+ exists = gencache_get(keystr, &value, NULL);
+ if (exists) {
+ SAFE_FREE(value);
+ ret = gencache_set(keystr, "", 0);
+ }
+ tdb_unlock_bystring(cache_notrans, keystr);
+ return ret;
}
+static bool gencache_pull_timeout(char *val, time_t *pres, char **pendptr)
+{
+ time_t res;
+ char *endptr;
+
+ res = strtol(val, &endptr, 10);
+
+ if ((endptr == NULL) || (*endptr != '/')) {
+ DEBUG(2, ("Invalid gencache data format: %s\n", val));
+ return false;
+ }
+ if (pres != NULL) {
+ *pres = res;
+ }
+ if (pendptr != NULL) {
+ *pendptr = endptr;
+ }
+ return true;
+}
/**
* Get existing entry from the cache file.
*
* @param keystr string that represents a key of this entry
- * @param valstr buffer that is allocated and filled with the entry value
- * buffer's disposing must be done outside
+ * @param blob DATA_BLOB that is filled with entry's blob
* @param timeout pointer to a time_t that is filled with entry's
* timeout
*
@@ -174,31 +272,40 @@ bool gencache_del(const char *keystr)
* @retval False for failure
**/
-bool gencache_get(const char *keystr, char **valstr, time_t *timeout)
+bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob,
+ time_t *timeout)
{
TDB_DATA databuf;
time_t t;
char *endptr;
- /* fail completely if get null pointers passed */
- SMB_ASSERT(keystr);
+ if (keystr == NULL) {
+ return false;
+ }
+
+ if (tdb_data_cmp(string_term_tdb_data(keystr),
+ last_stabilize_key()) == 0) {
+ DEBUG(10, ("Can't get %s as a key\n", keystr));
+ return false;
+ }
if (!gencache_init()) {
return False;
}
- databuf = tdb_fetch_bystring(cache, keystr);
+ databuf = tdb_fetch_bystring(cache_notrans, keystr);
if (databuf.dptr == NULL) {
- DEBUG(10, ("Cache entry with key = %s couldn't be found\n",
+ databuf = tdb_fetch_bystring(cache, keystr);
+ }
+
+ if (databuf.dptr == NULL) {
+ DEBUG(10, ("Cache entry with key = %s couldn't be found \n",
keystr));
return False;
}
- t = strtol((const char *)databuf.dptr, &endptr, 10);
-
- if ((endptr == NULL) || (*endptr != '/')) {
- DEBUG(2, ("Invalid gencache data format: %s\n", databuf.dptr));
+ if (!gencache_pull_timeout((char *)databuf.dptr, &t, &endptr)) {
SAFE_FREE(databuf.dptr);
return False;
}
@@ -207,20 +314,33 @@ bool gencache_get(const char *keystr, char **valstr, time_t *timeout)
"timeout = %s", t > time(NULL) ? "valid" :
"expired", keystr, endptr+1, ctime(&t)));
+ if (t == 0) {
+ /* Deleted */
+ SAFE_FREE(databuf.dptr);
+ return False;
+ }
+
if (t <= time(NULL)) {
- /* We're expired, delete the entry */
- tdb_delete_bystring(cache, keystr);
+ /*
+ * We're expired, delete the entry. We can't use gencache_del
+ * here, because that uses gencache_get_data_blob for checking
+ * the existence of a record. We know the thing exists and
+ * directly store an empty value with 0 timeout.
+ */
+ gencache_set(keystr, "", 0);
SAFE_FREE(databuf.dptr);
return False;
}
- if (valstr) {
- *valstr = SMB_STRDUP(endptr+1);
- if (*valstr == NULL) {
+ if (blob != NULL) {
+ *blob = data_blob(
+ endptr+1,
+ databuf.dsize - PTR_DIFF(endptr+1, databuf.dptr));
+ if (blob->data == NULL) {
SAFE_FREE(databuf.dptr);
- DEBUG(0, ("strdup failed\n"));
+ DEBUG(0, ("memdup failed\n"));
return False;
}
}
@@ -234,155 +354,192 @@ bool gencache_get(const char *keystr, char **valstr, time_t *timeout)
return True;
}
+struct stabilize_state {
+ bool written;
+ bool error;
+};
+static int stabilize_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA val,
+ void *priv);
+
/**
- * Get existing entry from the cache file.
- *
- * @param keystr string that represents a key of this entry
- * @param blob DATA_BLOB that is filled with entry's blob
- * @param expired pointer to a bool that indicates whether the entry is expired
+ * Stabilize gencache
*
- * @retval true when entry is successfuly fetched
- * @retval False for failure
- **/
+ * Migrate the clear-if-first gencache data to the stable,
+ * transaction-based gencache.tdb
+ */
-bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, bool *expired)
+bool gencache_stabilize(void)
{
- TDB_DATA databuf;
- time_t t;
- char *blob_type;
- unsigned char *buf = NULL;
- bool ret = False;
- fstring valstr;
- int buflen = 0, len = 0, blob_len = 0;
- unsigned char *blob_buf = NULL;
-
- /* fail completely if get null pointers passed */
- SMB_ASSERT(keystr);
+ struct stabilize_state state;
+ int res;
+ char *now;
if (!gencache_init()) {
- return False;
+ return false;
}
- databuf = tdb_fetch_bystring(cache, keystr);
- if (!databuf.dptr) {
- DEBUG(10,("Cache entry with key = %s couldn't be found\n",
- keystr));
- return False;
+ res = tdb_transaction_start(cache);
+ if (res == -1) {
+ DEBUG(10, ("Could not start transaction on gencache.tdb: "
+ "%s\n", tdb_errorstr(cache)));
+ return false;
+ }
+ res = tdb_transaction_start(cache_notrans);
+ if (res == -1) {
+ tdb_transaction_cancel(cache);
+ DEBUG(10, ("Could not start transaction on "
+ "gencache_notrans.tdb: %s\n",
+ tdb_errorstr(cache_notrans)));
+ return false;
}
- buf = (unsigned char *)databuf.dptr;
- buflen = databuf.dsize;
+ state.error = false;
+ state.written = false;
- len += tdb_unpack(buf+len, buflen-len, "fB",
- &valstr,
- &blob_len, &blob_buf);
- if (len == -1) {
- goto out;
+ res = tdb_traverse(cache_notrans, stabilize_fn, &state);
+ if ((res == -1) || state.error) {
+ if ((tdb_transaction_cancel(cache_notrans) == -1)
+ || (tdb_transaction_cancel(cache) == -1)) {
+ smb_panic("tdb_transaction_cancel failed\n");
+ }
+ return false;
}
- t = strtol(valstr, &blob_type, 10);
+ if (!state.written) {
+ if ((tdb_transaction_cancel(cache_notrans) == -1)
+ || (tdb_transaction_cancel(cache) == -1)) {
+ smb_panic("tdb_transaction_cancel failed\n");
+ }
+ return true;
+ }
- if (strcmp(blob_type+1, BLOB_TYPE) != 0) {
- goto out;
+ res = tdb_transaction_commit(cache);
+ if (res == -1) {
+ DEBUG(10, ("tdb_transaction_commit on gencache.tdb failed: "
+ "%s\n", tdb_errorstr(cache)));
+ if (tdb_transaction_cancel(cache_notrans) == -1) {
+ smb_panic("tdb_transaction_cancel failed\n");
+ }
+ return false;
}
- DEBUG(10,("Returning %s cache entry: key = %s, "
- "timeout = %s", t > time(NULL) ? "valid" :
- "expired", keystr, ctime(&t)));
+ res = tdb_transaction_commit(cache_notrans);
+ if (res == -1) {
+ DEBUG(10, ("tdb_transaction_commit on gencache.tdb failed: "
+ "%s\n", tdb_errorstr(cache)));
+ return false;
+ }
- if (t <= time(NULL)) {
- /* We're expired */
- if (expired) {
- *expired = True;
- }
+ now = talloc_asprintf(talloc_tos(), "%d", (int)time(NULL));
+ if (now != NULL) {
+ tdb_store(cache_notrans, last_stabilize_key(),
+ string_term_tdb_data(now), 0);
+ TALLOC_FREE(now);
}
- if (blob) {
- *blob = data_blob(blob_buf, blob_len);
- if (!blob->data) {
- goto out;
+ return true;
+}
+
+static int stabilize_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA val,
+ void *priv)
+{
+ struct stabilize_state *state = (struct stabilize_state *)priv;
+ int res;
+ time_t timeout;
+
+ if (tdb_data_cmp(key, last_stabilize_key()) == 0) {
+ return 0;
+ }
+
+ if (!gencache_pull_timeout((char *)val.dptr, &timeout, NULL)) {
+ DEBUG(10, ("Ignoring invalid entry\n"));
+ return 0;
+ }
+ if ((timeout < time(NULL)) || (val.dsize == 0)) {
+ res = tdb_delete(cache, key);
+ if ((res == -1) && (tdb_error(cache) == TDB_ERR_NOEXIST)) {
+ res = 0;
+ } else {
+ state->written = true;
+ }
+ } else {
+ res = tdb_store(cache, key, val, 0);
+ if (res == 0) {
+ state->written = true;
}
}
- ret = True;
- out:
- SAFE_FREE(blob_buf);
- SAFE_FREE(databuf.dptr);
+ if (res == -1) {
+ DEBUG(10, ("Transfer to gencache.tdb failed: %s\n",
+ tdb_errorstr(cache)));
+ state->error = true;
+ return -1;
+ }
- return ret;
+ if (tdb_delete(cache_notrans, key) == -1) {
+ DEBUG(10, ("tdb_delete from gencache_notrans.tdb failed: "
+ "%s\n", tdb_errorstr(cache_notrans)));
+ state->error = true;
+ return -1;
+ }
+ return 0;
}
/**
- * Set an entry in the cache file. If there's no such
- * one, then add it.
+ * Get existing entry from the cache file.
*
* @param keystr string that represents a key of this entry
- * @param blob DATA_BLOB value being cached
- * @param timeout time when the value is expired
+ * @param valstr buffer that is allocated and filled with the entry value
+ * buffer's disposing must be done outside
+ * @param timeout pointer to a time_t that is filled with entry's
+ * timeout
*
- * @retval true when entry is successfuly stored
- * @retval false on failure
+ * @retval true when entry is successfuly fetched
+ * @retval False for failure
**/
-bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, time_t timeout)
+bool gencache_get(const char *keystr, char **value, time_t *ptimeout)
{
+ DATA_BLOB blob;
bool ret = False;
- int tdb_ret;
- TDB_DATA databuf;
- char *valstr = NULL;
- unsigned char *buf = NULL;
- int len = 0, buflen = 0;
- /* fail completely if get null pointers passed */
- SMB_ASSERT(keystr && blob);
-
- if (!gencache_init()) {
- return False;
+ ret = gencache_get_data_blob(keystr, &blob, ptimeout);
+ if (!ret) {
+ return false;
}
-
- if (asprintf(&valstr, "%12u/%s", (int)timeout, BLOB_TYPE) == -1) {
- return False;
+ if ((blob.data == NULL) || (blob.length == 0)) {
+ SAFE_FREE(blob.data);
+ return false;
}
-
- again:
- len = 0;
-
- len += tdb_pack(buf+len, buflen-len, "fB",
- valstr,
- blob->length, blob->data);
-
- if (len == -1) {
- goto out;
+ if (blob.data[blob.length-1] != '\0') {
+ /* Not NULL terminated, can't be a string */
+ SAFE_FREE(blob.data);
+ return false;
}
-
- if (buflen < len) {
- SAFE_FREE(buf);
- buf = SMB_MALLOC_ARRAY(unsigned char, len);
- if (!buf) {
- goto out;
- }
- buflen = len;
- goto again;
- }
-
- databuf = make_tdb_data(buf, len);
-
- DEBUG(10,("Adding cache entry with key = %s; "
- "blob size = %d and timeout = %s"
- "(%d seconds %s)\n", keystr, (int)databuf.dsize,
- ctime(&timeout), (int)(timeout - time(NULL)),
- timeout > time(NULL) ? "ahead" : "in the past"));
-
- tdb_ret = tdb_store_bystring(cache, keystr, databuf, 0);
- if (tdb_ret == 0) {
- ret = True;
+ *value = SMB_STRDUP((char *)blob.data);
+ data_blob_free(&blob);
+ if (*value == NULL) {
+ return false;
}
+ return true;
+}
- out:
- SAFE_FREE(valstr);
- SAFE_FREE(buf);
+/**
+ * Set an entry in the cache file. If there's no such
+ * one, then add it.
+ *
+ * @param keystr string that represents a key of this entry
+ * @param value text representation value being cached
+ * @param timeout time when the value is expired
+ *
+ * @retval true when entry is successfuly stored
+ * @retval false on failure
+ **/
- return ret;
+bool gencache_set(const char *keystr, const char *value, time_t timeout)
+{
+ DATA_BLOB blob = data_blob_const(value, strlen(value)+1);
+ return gencache_set_data_blob(keystr, &blob, timeout);
}
/**
@@ -401,6 +558,7 @@ struct gencache_iterate_state {
void *priv);
const char *pattern;
void *priv;
+ bool in_persistent;
};
static int gencache_iterate_fn(struct tdb_context *tdb, TDB_DATA key,
@@ -416,6 +574,14 @@ static int gencache_iterate_fn(struct tdb_context *tdb, TDB_DATA key,
time_t timeout;
char *timeout_endp;
+ if (tdb_data_cmp(key, last_stabilize_key()) == 0) {
+ return 0;
+ }
+
+ if (state->in_persistent && tdb_exists(cache_notrans, key)) {
+ return 0;
+ }
+
if (key.dptr[key.dsize-1] == '\0') {
keystr = (char *)key.dptr;
} else {
@@ -465,8 +631,9 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time
{
struct gencache_iterate_state state;
- /* fail completely if get null pointers passed */
- SMB_ASSERT(fn && keystr_pattern);
+ if ((fn == NULL) || (keystr_pattern == NULL)) {
+ return;
+ }
if (!gencache_init()) return;
@@ -475,30 +642,10 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time
state.fn = fn;
state.pattern = keystr_pattern;
state.priv = data;
- tdb_traverse(cache, gencache_iterate_fn, &state);
-}
-/********************************************************************
- lock a key
-********************************************************************/
+ state.in_persistent = false;
+ tdb_traverse(cache_notrans, gencache_iterate_fn, &state);
-int gencache_lock_entry( const char *key )
-{
- if (!gencache_init())
- return -1;
-
- return tdb_lock_bystring(cache, key);
-}
-
-/********************************************************************
- unlock a key
-********************************************************************/
-
-void gencache_unlock_entry( const char *key )
-{
- if (!gencache_init())
- return;
-
- tdb_unlock_bystring(cache, key);
- return;
+ state.in_persistent = true;
+ tdb_traverse(cache, gencache_iterate_fn, &state);
}
diff --git a/source3/lib/ldap_escape.c b/source3/lib/ldap_escape.c
index d101bc5ecd..a731cb9864 100644
--- a/source3/lib/ldap_escape.c
+++ b/source3/lib/ldap_escape.c
@@ -32,10 +32,10 @@
* and to be free()ed by the caller.
**/
-char *escape_ldap_string_alloc(const char *s)
+char *escape_ldap_string(TALLOC_CTX *mem_ctx, const char *s)
{
size_t len = strlen(s)+1;
- char *output = (char *)SMB_MALLOC(len);
+ char *output = talloc_array(mem_ctx, char, len);
const char *sub;
int i = 0;
char *p = output;
@@ -43,7 +43,7 @@ char *escape_ldap_string_alloc(const char *s)
if (output == NULL) {
return NULL;
}
-
+
while (*s)
{
switch (*s)
@@ -64,14 +64,17 @@ char *escape_ldap_string_alloc(const char *s)
sub = NULL;
break;
}
-
+
if (sub) {
+ char *tmp;
len = len + 3;
- output = (char *)SMB_REALLOC(output, len);
- if (!output) {
+ tmp = talloc_realloc(mem_ctx, output, char, len);
+ if (tmp == NULL) {
+ TALLOC_FREE(output);
return NULL;
}
-
+ output = tmp;
+
p = &output[i];
strncpy (p, sub, 3);
p += 3;
@@ -84,7 +87,7 @@ char *escape_ldap_string_alloc(const char *s)
}
s++;
}
-
+
*p = '\0';
return output;
}
@@ -101,7 +104,7 @@ char *escape_rdn_val_string_alloc(const char *s)
}
p = output;
-
+
while (*s)
{
switch (*s)
@@ -122,10 +125,10 @@ char *escape_rdn_val_string_alloc(const char *s)
*p = *s;
p++;
}
-
+
s++;
}
-
+
*p = '\0';
/* resize the string to the actual final size */
diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c
index 2f8474b37f..e80879a1d2 100644
--- a/source3/lib/netapi/netapi.c
+++ b/source3/lib/netapi/netapi.c
@@ -170,7 +170,6 @@ NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx)
gfree_charcnv();
gfree_interfaces();
- gencache_shutdown();
secrets_shutdown();
TALLOC_FREE(ctx);
diff --git a/source3/lib/netapi/user.c b/source3/lib/netapi/user.c
index 39472b20d7..9fa3ddd9a8 100644
--- a/source3/lib/netapi/user.c
+++ b/source3/lib/netapi/user.c
@@ -770,7 +770,7 @@ static uint32_t samr_acb_flags_to_netapi_flags(uint32_t acb)
{
uint32_t fl = UF_SCRIPT; /* god knows why */
- fl |= ads_acb2uf(acb);
+ fl |= ds_acb2uf(acb);
return fl;
}
diff --git a/source3/lib/smbldap_util.c b/source3/lib/smbldap_util.c
index 66aef6ba66..478a3d24ca 100644
--- a/source3/lib/smbldap_util.c
+++ b/source3/lib/smbldap_util.c
@@ -126,7 +126,7 @@ static NTSTATUS add_new_domain_info(struct smbldap_state *ldap_state,
char *escape_domain_name;
/* escape for filter */
- escape_domain_name = escape_ldap_string_alloc(domain_name);
+ escape_domain_name = escape_ldap_string(talloc_tos(), domain_name);
if (!escape_domain_name) {
DEBUG(0, ("Out of memory!\n"));
return NT_STATUS_NO_MEMORY;
@@ -135,11 +135,11 @@ static NTSTATUS add_new_domain_info(struct smbldap_state *ldap_state,
if (asprintf(&filter, "(&(%s=%s)(objectclass=%s))",
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
escape_domain_name, LDAP_OBJ_DOMINFO) < 0) {
- SAFE_FREE(escape_domain_name);
+ TALLOC_FREE(escape_domain_name);
return NT_STATUS_NO_MEMORY;
}
- SAFE_FREE(escape_domain_name);
+ TALLOC_FREE(escape_domain_name);
attr_list = get_attr_list(NULL, dominfo_attr_list );
rc = smbldap_search_suffix(ldap_state, filter, attr_list, &result);
@@ -258,7 +258,7 @@ NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state,
int count;
char *escape_domain_name;
- escape_domain_name = escape_ldap_string_alloc(domain_name);
+ escape_domain_name = escape_ldap_string(talloc_tos(), domain_name);
if (!escape_domain_name) {
DEBUG(0, ("Out of memory!\n"));
return NT_STATUS_NO_MEMORY;
@@ -268,11 +268,11 @@ NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state,
LDAP_OBJ_DOMINFO,
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
escape_domain_name) < 0) {
- SAFE_FREE(escape_domain_name);
+ TALLOC_FREE(escape_domain_name);
return NT_STATUS_NO_MEMORY;
}
- SAFE_FREE(escape_domain_name);
+ TALLOC_FREE(escape_domain_name);
DEBUG(2, ("smbldap_search_domain_info: Searching for:[%s]\n", filter));
diff --git a/source3/lib/system.c b/source3/lib/system.c
index ffc236e93b..6a4f5d5413 100644
--- a/source3/lib/system.c
+++ b/source3/lib/system.c
@@ -458,8 +458,6 @@ static struct timespec calc_create_time_stat_ex(const struct stat_ex *st)
static void get_create_timespec(const struct stat *pst, struct stat_ex *dst)
{
- struct timespec ret;
-
if (S_ISDIR(pst->st_mode) && lp_fake_dir_create_times()) {
dst->st_ex_btime.tv_sec = 315493200L; /* 1/1/1980 */
dst->st_ex_btime.tv_nsec = 0;
@@ -483,7 +481,7 @@ static void get_create_timespec(const struct stat *pst, struct stat_ex *dst)
/* Deal with systems that don't initialize birthtime correctly.
* Pointed out by SATOH Fumiyasu <fumiyas@osstech.jp>.
*/
- if (null_timespec(ret)) {
+ if (null_timespec(dst->st_ex_btime)) {
dst->st_ex_btime = calc_create_time_stat(pst);
dst->st_ex_calculated_birthtime = true;
}
diff --git a/source3/lib/tldap.c b/source3/lib/tldap.c
index 451bc18d2e..fa56763a33 100644
--- a/source3/lib/tldap.c
+++ b/source3/lib/tldap.c
@@ -1618,7 +1618,7 @@ struct tevent_req *tldap_add_send(TALLOC_CTX *mem_ctx,
static void tldap_add_done(struct tevent_req *subreq)
{
- return tldap_simple_done(subreq, TLDAP_RES_ADD);
+ tldap_simple_done(subreq, TLDAP_RES_ADD);
}
int tldap_add_recv(struct tevent_req *req)
@@ -1718,7 +1718,7 @@ struct tevent_req *tldap_modify_send(TALLOC_CTX *mem_ctx,
static void tldap_modify_done(struct tevent_req *subreq)
{
- return tldap_simple_done(subreq, TLDAP_RES_MODIFY);
+ tldap_simple_done(subreq, TLDAP_RES_MODIFY);
}
int tldap_modify_recv(struct tevent_req *req)
@@ -1795,7 +1795,7 @@ struct tevent_req *tldap_delete_send(TALLOC_CTX *mem_ctx,
static void tldap_delete_done(struct tevent_req *subreq)
{
- return tldap_simple_done(subreq, TLDAP_RES_DELETE);
+ tldap_simple_done(subreq, TLDAP_RES_DELETE);
}
int tldap_delete_recv(struct tevent_req *req)
diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c
index 31261afd72..af64f370ba 100644
--- a/source3/lib/util_sock.c
+++ b/source3/lib/util_sock.c
@@ -349,6 +349,9 @@ static const smb_socket_option socket_options[] = {
#ifdef TCP_FASTACK
{"TCP_FASTACK", IPPROTO_TCP, TCP_FASTACK, 0, OPT_INT},
#endif
+#ifdef TCP_QUICKACK
+ {"TCP_QUICKACK", IPPROTO_TCP, TCP_QUICKACK, 0, OPT_BOOL},
+#endif
{NULL,0,0,0,0}};
/****************************************************************************
diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c
index cdd7d0a300..c197fd7515 100644
--- a/source3/lib/util_str.c
+++ b/source3/lib/util_str.c
@@ -96,14 +96,14 @@ int StrCaseCmp(const char *s, const char *t)
return +1;
}
- if (!push_ucs2_talloc(NULL, &buffer_s, ps, &size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &buffer_s, ps, &size)) {
return strcmp(ps, pt);
/* Not quite the right answer, but finding the right one
under this failure case is expensive, and it's pretty
close */
}
- if (!push_ucs2_talloc(NULL, &buffer_t, pt, &size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &buffer_t, pt, &size)) {
TALLOC_FREE(buffer_s);
return strcmp(ps, pt);
/* Not quite the right answer, but finding the right one
@@ -157,14 +157,14 @@ int StrnCaseCmp(const char *s, const char *t, size_t len)
return 0;
}
- if (!push_ucs2_talloc(NULL, &buffer_s, ps, &size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &buffer_s, ps, &size)) {
return strncmp(ps, pt, len-n);
/* Not quite the right answer, but finding the right one
under this failure case is expensive,
and it's pretty close */
}
- if (!push_ucs2_talloc(NULL, &buffer_t, pt, &size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &buffer_t, pt, &size)) {
TALLOC_FREE(buffer_s);
return strncmp(ps, pt, len-n);
/* Not quite the right answer, but finding the right one
@@ -366,7 +366,7 @@ size_t str_charnum(const char *s)
{
size_t ret, converted_size;
smb_ucs2_t *tmpbuf2 = NULL;
- if (!push_ucs2_talloc(NULL, &tmpbuf2, s, &converted_size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &tmpbuf2, s, &converted_size)) {
return 0;
}
ret = strlen_w(tmpbuf2);
@@ -384,7 +384,7 @@ size_t str_ascii_charnum(const char *s)
{
size_t ret, converted_size;
char *tmpbuf2 = NULL;
- if (!push_ascii_talloc(NULL, &tmpbuf2, s, &converted_size)) {
+ if (!push_ascii_talloc(talloc_tos(), &tmpbuf2, s, &converted_size)) {
return 0;
}
ret = strlen(tmpbuf2);
@@ -455,7 +455,7 @@ bool strhasupper(const char *s)
bool ret;
size_t converted_size;
- if (!push_ucs2_talloc(NULL, &tmp, s, &converted_size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &tmp, s, &converted_size)) {
return false;
}
@@ -480,7 +480,7 @@ bool strhaslower(const char *s)
bool ret;
size_t converted_size;
- if (!push_ucs2_talloc(NULL, &tmp, s, &converted_size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &tmp, s, &converted_size)) {
return false;
}
@@ -1177,7 +1177,7 @@ char *strchr_m(const char *src, char c)
s = src;
#endif
- if (!push_ucs2_talloc(NULL, &ws, s, &converted_size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
/* Wrong answer, but what can we do... */
return strchr(src, c);
}
@@ -1187,7 +1187,7 @@ char *strchr_m(const char *src, char c)
return NULL;
}
*p = 0;
- if (!pull_ucs2_talloc(NULL, &s2, ws, &converted_size)) {
+ if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
SAFE_FREE(ws);
/* Wrong answer, but what can we do... */
return strchr(src, c);
@@ -1248,7 +1248,7 @@ char *strrchr_m(const char *s, char c)
char *ret;
size_t converted_size;
- if (!push_ucs2_talloc(NULL, &ws, s, &converted_size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
/* Wrong answer, but what can we do. */
return strrchr(s, c);
}
@@ -1258,7 +1258,7 @@ char *strrchr_m(const char *s, char c)
return NULL;
}
*p = 0;
- if (!pull_ucs2_talloc(NULL, &s2, ws, &converted_size)) {
+ if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
TALLOC_FREE(ws);
/* Wrong answer, but what can we do. */
return strrchr(s, c);
@@ -1283,7 +1283,7 @@ char *strnrchr_m(const char *s, char c, unsigned int n)
char *ret;
size_t converted_size;
- if (!push_ucs2_talloc(NULL, &ws, s, &converted_size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
/* Too hard to try and get right. */
return NULL;
}
@@ -1293,7 +1293,7 @@ char *strnrchr_m(const char *s, char c, unsigned int n)
return NULL;
}
*p = 0;
- if (!pull_ucs2_talloc(NULL, &s2, ws, &converted_size)) {
+ if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
TALLOC_FREE(ws);
/* Too hard to try and get right. */
return NULL;
@@ -1352,12 +1352,12 @@ char *strstr_m(const char *src, const char *findstr)
s = src;
#endif
- if (!push_ucs2_talloc(NULL, &src_w, src, &converted_size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &src_w, src, &converted_size)) {
DEBUG(0,("strstr_m: src malloc fail\n"));
return NULL;
}
- if (!push_ucs2_talloc(NULL, &find_w, findstr, &converted_size)) {
+ if (!push_ucs2_talloc(talloc_tos(), &find_w, findstr, &converted_size)) {
TALLOC_FREE(src_w);
DEBUG(0,("strstr_m: find malloc fail\n"));
return NULL;
@@ -1372,7 +1372,7 @@ char *strstr_m(const char *src, const char *findstr)
}
*p = 0;
- if (!pull_ucs2_talloc(NULL, &s2, src_w, &converted_size)) {
+ if (!pull_ucs2_talloc(talloc_tos(), &s2, src_w, &converted_size)) {
TALLOC_FREE(src_w);
TALLOC_FREE(find_w);
DEBUG(0,("strstr_m: dest malloc fail\n"));
@@ -1932,7 +1932,7 @@ char *base64_encode_data_blob(TALLOC_CTX *mem_ctx, DATA_BLOB data)
result = TALLOC_ARRAY(mem_ctx, char, output_len); /* get us plenty of space */
SMB_ASSERT(result != NULL);
- while (len-- && out_cnt < (data.length * 2) - 5) {
+ while (len--) {
int c = (unsigned char) *(data.data++);
bits += c;
char_count++;
diff --git a/source3/lib/util_tdb.c b/source3/lib/util_tdb.c
index 78fa7cd0a1..5b3d94dabe 100644
--- a/source3/lib/util_tdb.c
+++ b/source3/lib/util_tdb.c
@@ -630,3 +630,22 @@ NTSTATUS map_nt_error_from_tdb(enum TDB_ERROR err)
return NT_STATUS_INTERNAL_ERROR;
}
+
+int tdb_data_cmp(TDB_DATA t1, TDB_DATA t2)
+{
+ int ret;
+ if (t1.dptr == NULL && t2.dptr != NULL) {
+ return -1;
+ }
+ if (t1.dptr != NULL && t2.dptr == NULL) {
+ return 1;
+ }
+ if (t1.dptr == t2.dptr) {
+ return t1.dsize - t2.dsize;
+ }
+ ret = memcmp(t1.dptr, t2.dptr, MIN(t1.dsize, t2.dsize));
+ if (ret == 0) {
+ return t1.dsize - t2.dsize;
+ }
+ return ret;
+}
diff --git a/source3/libads/dns.c b/source3/libads/dns.c
index 3a9e849668..5cf768de67 100644
--- a/source3/libads/dns.c
+++ b/source3/libads/dns.c
@@ -754,10 +754,6 @@ bool sitename_store(const char *realm, const char *sitename)
bool ret = False;
char *key;
- if (!gencache_init()) {
- return False;
- }
-
if (!realm || (strlen(realm) == 0)) {
DEBUG(0,("sitename_store: no realm\n"));
return False;
@@ -795,10 +791,6 @@ char *sitename_fetch(const char *realm)
const char *query_realm;
char *key;
- if (!gencache_init()) {
- return NULL;
- }
-
if (!realm || (strlen(realm) == 0)) {
query_realm = lp_realm();
} else {
diff --git a/source3/libads/ldap_user.c b/source3/libads/ldap_user.c
index eecd9045e5..69dc05335e 100644
--- a/source3/libads/ldap_user.c
+++ b/source3/libads/ldap_user.c
@@ -30,18 +30,18 @@
ADS_STATUS status;
char *ldap_exp;
const char *attrs[] = {"*", NULL};
- char *escaped_user = escape_ldap_string_alloc(user);
+ char *escaped_user = escape_ldap_string(talloc_tos(), user);
if (!escaped_user) {
return ADS_ERROR(LDAP_NO_MEMORY);
}
if (asprintf(&ldap_exp, "(samAccountName=%s)", escaped_user) == -1) {
- SAFE_FREE(escaped_user);
+ TALLOC_FREE(escaped_user);
return ADS_ERROR(LDAP_NO_MEMORY);
}
status = ads_search(ads, res, ldap_exp, attrs);
SAFE_FREE(ldap_exp);
- SAFE_FREE(escaped_user);
+ TALLOC_FREE(escaped_user);
return status;
}
diff --git a/source3/libnet/libnet_samsync_passdb.c b/source3/libnet/libnet_samsync_passdb.c
index 27c7aac7e7..41a9b3d9f3 100644
--- a/source3/libnet/libnet_samsync_passdb.c
+++ b/source3/libnet/libnet_samsync_passdb.c
@@ -676,21 +676,24 @@ static NTSTATUS fetch_domain_info(TALLOC_CTX *mem_ctx,
}
- if (!pdb_set_account_policy(AP_PASSWORD_HISTORY,
+ if (!pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY,
r->password_history_length))
return nt_status;
- if (!pdb_set_account_policy(AP_MIN_PASSWORD_LEN,
+ if (!pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
r->min_password_length))
return nt_status;
- if (!pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (uint32)u_max_age))
+ if (!pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE,
+ (uint32)u_max_age))
return nt_status;
- if (!pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (uint32)u_min_age))
+ if (!pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE,
+ (uint32)u_min_age))
return nt_status;
- if (!pdb_set_account_policy(AP_TIME_TO_LOGOUT, (uint32)u_logout))
+ if (!pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT,
+ (uint32)u_logout))
return nt_status;
if (lockstr) {
@@ -699,21 +702,23 @@ static NTSTATUS fetch_domain_info(TALLOC_CTX *mem_ctx,
u_lockoutreset = uint64s_nt_time_to_unix_abs(&lockstr->reset_count);
u_lockouttime = uint64s_nt_time_to_unix_abs((uint64_t *)&lockstr->lockout_duration);
- if (!pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
+ if (!pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT,
lockstr->bad_attempt_lockout))
return nt_status;
- if (!pdb_set_account_policy(AP_RESET_COUNT_TIME, (uint32_t)u_lockoutreset/60))
+ if (!pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME,
+ (uint32_t)u_lockoutreset/60))
return nt_status;
if (u_lockouttime != -1)
u_lockouttime /= 60;
- if (!pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (uint32_t)u_lockouttime))
+ if (!pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION,
+ (uint32_t)u_lockouttime))
return nt_status;
}
- if (!pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
+ if (!pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
r->logon_to_chgpass))
return nt_status;
diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c
index 349a8331b4..f5dbd72f22 100644
--- a/source3/libsmb/clidgram.c
+++ b/source3/libsmb/clidgram.c
@@ -25,7 +25,7 @@
* cli_send_mailslot, send a mailslot for client code ...
*/
-bool cli_send_mailslot(struct messaging_context *msg_ctx,
+static bool cli_send_mailslot(struct messaging_context *msg_ctx,
bool unique, const char *mailslot,
uint16 priority,
char *buf, int len,
@@ -309,4 +309,3 @@ bool receive_getdc_response(TALLOC_CTX *mem_ctx,
return True;
}
-
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index af67fcb746..5ea0579839 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -1893,7 +1893,6 @@ struct tevent_req *cli_nt_delete_on_close_send(TALLOC_CTX *mem_ctx,
SSVAL(&state->setup, 0, TRANSACT2_SETFILEINFO);
/* Setup param array. */
- memset(state->param, '\0', 6);
SSVAL(state->param,0,fnum);
SSVAL(state->param,2,SMB_SET_FILE_DISPOSITION_INFO);
@@ -2010,6 +2009,7 @@ struct tevent_req *cli_ntcreate_send(TALLOC_CTX *mem_ctx,
if (req == NULL) {
return NULL;
}
+
vwv = state->vwv;
SCVAL(vwv+0, 0, 0xFF);
@@ -2367,6 +2367,7 @@ struct tevent_req *cli_close_create(TALLOC_CTX *mem_ctx,
if (req == NULL) {
return NULL;
}
+
SSVAL(state->vwv+0, 0, fnum);
SIVALS(state->vwv+1, 0, -1);
@@ -2708,42 +2709,114 @@ bool cli_lock(struct cli_state *cli, uint16_t fnum,
Unlock a file.
****************************************************************************/
-bool cli_unlock(struct cli_state *cli, uint16_t fnum, uint32_t offset, uint32_t len)
+struct cli_unlock_state {
+ uint16_t vwv[8];
+ uint8_t data[10];
+};
+
+static void cli_unlock_done(struct tevent_req *subreq);
+
+struct tevent_req *cli_unlock_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ uint16_t fnum,
+ uint64_t offset,
+ uint64_t len)
+
{
- char *p;
+ struct tevent_req *req = NULL, *subreq = NULL;
+ struct cli_unlock_state *state = NULL;
+ uint8_t additional_flags = 0;
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
+ req = tevent_req_create(mem_ctx, &state, struct cli_unlock_state);
+ if (req == NULL) {
+ return NULL;
+ }
- cli_set_message(cli->outbuf,8,0,True);
+ SCVAL(state->vwv+0, 0, 0xFF);
+ SSVAL(state->vwv+2, 0, fnum);
+ SCVAL(state->vwv+3, 0, 0);
+ SIVALS(state->vwv+4, 0, 0);
+ SSVAL(state->vwv+6, 0, 1);
+ SSVAL(state->vwv+7, 0, 0);
- SCVAL(cli->outbuf,smb_com,SMBlockingX);
- SSVAL(cli->outbuf,smb_tid,cli->cnum);
- cli_setup_packet(cli);
+ SSVAL(state->data, 0, cli->pid);
+ SIVAL(state->data, 2, offset);
+ SIVAL(state->data, 6, len);
- SCVAL(cli->outbuf,smb_vwv0,0xFF);
- SSVAL(cli->outbuf,smb_vwv2,fnum);
- SCVAL(cli->outbuf,smb_vwv3,0);
- SIVALS(cli->outbuf, smb_vwv4, 0);
- SSVAL(cli->outbuf,smb_vwv6,1);
- SSVAL(cli->outbuf,smb_vwv7,0);
+ subreq = cli_smb_send(state, ev, cli, SMBlockingX, additional_flags,
+ 8, state->vwv, 10, state->data);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq, cli_unlock_done, req);
+ return req;
+}
- p = smb_buf(cli->outbuf);
- SSVAL(p, 0, cli->pid);
- SIVAL(p, 2, offset);
- SIVAL(p, 6, len);
- p += 10;
- cli_setup_bcc(cli, p);
- cli_send_smb(cli);
- if (!cli_receive_smb(cli)) {
- return False;
+static void cli_unlock_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ NTSTATUS status;
+
+ status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
}
+ tevent_req_done(req);
+}
- if (cli_is_error(cli)) {
- return False;
+NTSTATUS cli_unlock_recv(struct tevent_req *req)
+{
+ return tevent_req_simple_recv_ntstatus(req);
+}
+
+NTSTATUS cli_unlock(struct cli_state *cli,
+ uint16_t fnum,
+ uint32_t offset,
+ uint32_t len)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev;
+ struct tevent_req *req;
+ NTSTATUS status = NT_STATUS_OK;
+
+ if (cli_has_async_calls(cli)) {
+ /*
+ * Can't use sync call while an async call is in flight
+ */
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
}
- return True;
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ req = cli_unlock_send(frame, ev, cli,
+ fnum, offset, len);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ if (!tevent_req_poll(req, ev)) {
+ status = map_nt_error_from_unix(errno);
+ goto fail;
+ }
+
+ status = cli_unlock_recv(req);
+
+ fail:
+ TALLOC_FREE(frame);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_set_error(cli, status);
+ }
+ return status;
}
/****************************************************************************
@@ -2811,149 +2884,378 @@ bool cli_lock64(struct cli_state *cli, uint16_t fnum,
Unlock a file with 64 bit offsets.
****************************************************************************/
-bool cli_unlock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len)
+struct cli_unlock64_state {
+ uint16_t vwv[8];
+ uint8_t data[20];
+};
+
+static void cli_unlock64_done(struct tevent_req *subreq);
+
+struct tevent_req *cli_unlock64_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ uint16_t fnum,
+ uint64_t offset,
+ uint64_t len)
+
{
- char *p;
+ struct tevent_req *req = NULL, *subreq = NULL;
+ struct cli_unlock64_state *state = NULL;
+ uint8_t additional_flags = 0;
- if (! (cli->capabilities & CAP_LARGE_FILES)) {
- return cli_unlock(cli, fnum, offset, len);
+ req = tevent_req_create(mem_ctx, &state, struct cli_unlock64_state);
+ if (req == NULL) {
+ return NULL;
}
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
+ SCVAL(state->vwv+0, 0, 0xff);
+ SSVAL(state->vwv+2, 0, fnum);
+ SCVAL(state->vwv+3, 0,LOCKING_ANDX_LARGE_FILES);
+ SIVALS(state->vwv+4, 0, 0);
+ SSVAL(state->vwv+6, 0, 1);
+ SSVAL(state->vwv+7, 0, 0);
- cli_set_message(cli->outbuf,8,0,True);
+ SIVAL(state->data, 0, cli->pid);
+ SOFF_T_R(state->data, 4, offset);
+ SOFF_T_R(state->data, 12, len);
- SCVAL(cli->outbuf,smb_com,SMBlockingX);
- SSVAL(cli->outbuf,smb_tid,cli->cnum);
- cli_setup_packet(cli);
+ subreq = cli_smb_send(state, ev, cli, SMBlockingX, additional_flags,
+ 8, state->vwv, 20, state->data);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq, cli_unlock64_done, req);
+ return req;
+}
- SCVAL(cli->outbuf,smb_vwv0,0xFF);
- SSVAL(cli->outbuf,smb_vwv2,fnum);
- SCVAL(cli->outbuf,smb_vwv3,LOCKING_ANDX_LARGE_FILES);
- SIVALS(cli->outbuf, smb_vwv4, 0);
- SSVAL(cli->outbuf,smb_vwv6,1);
- SSVAL(cli->outbuf,smb_vwv7,0);
+static void cli_unlock64_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ NTSTATUS status;
- p = smb_buf(cli->outbuf);
- SIVAL(p, 0, cli->pid);
- SOFF_T_R(p, 4, offset);
- SOFF_T_R(p, 12, len);
- p += 20;
- cli_setup_bcc(cli, p);
- cli_send_smb(cli);
- if (!cli_receive_smb(cli)) {
- return False;
+ status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
}
+ tevent_req_done(req);
+}
- if (cli_is_error(cli)) {
- return False;
+NTSTATUS cli_unlock64_recv(struct tevent_req *req)
+{
+ return tevent_req_simple_recv_ntstatus(req);
+}
+
+NTSTATUS cli_unlock64(struct cli_state *cli,
+ uint16_t fnum,
+ uint64_t offset,
+ uint64_t len)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev;
+ struct tevent_req *req;
+ NTSTATUS status = NT_STATUS_OK;
+
+ if (! (cli->capabilities & CAP_LARGE_FILES)) {
+ return cli_unlock(cli, fnum, offset, len);
}
- return True;
+ if (cli_has_async_calls(cli)) {
+ /*
+ * Can't use sync call while an async call is in flight
+ */
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ req = cli_unlock64_send(frame, ev, cli,
+ fnum, offset, len);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ if (!tevent_req_poll(req, ev)) {
+ status = map_nt_error_from_unix(errno);
+ goto fail;
+ }
+
+ status = cli_unlock64_recv(req);
+
+ fail:
+ TALLOC_FREE(frame);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_set_error(cli, status);
+ }
+ return status;
}
/****************************************************************************
Get/unlock a POSIX lock on a file - internal function.
****************************************************************************/
-static bool cli_posix_lock_internal(struct cli_state *cli, uint16_t fnum,
- uint64_t offset, uint64_t len, bool wait_lock, enum brl_type lock_type)
+struct posix_lock_state {
+ uint16_t setup;
+ uint8_t param[4];
+ uint8_t data[POSIX_LOCK_DATA_SIZE];
+};
+
+static void cli_posix_unlock_internal_done(struct tevent_req *subreq)
{
- unsigned int param_len = 4;
- unsigned int data_len = POSIX_LOCK_DATA_SIZE;
- uint16_t setup = TRANSACT2_SETFILEINFO;
- char param[4];
- unsigned char data[POSIX_LOCK_DATA_SIZE];
- char *rparam=NULL, *rdata=NULL;
- int saved_timeout = cli->timeout;
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct posix_lock_state *state = tevent_req_data(req, struct posix_lock_state);
+ NTSTATUS status;
- SSVAL(param,0,fnum);
- SSVAL(param,2,SMB_SET_POSIX_LOCK);
+ status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ tevent_req_done(req);
+}
+static struct tevent_req *cli_posix_lock_internal_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ uint16_t fnum,
+ uint64_t offset,
+ uint64_t len,
+ bool wait_lock,
+ enum brl_type lock_type)
+{
+ struct tevent_req *req = NULL, *subreq = NULL;
+ struct posix_lock_state *state = NULL;
+
+ req = tevent_req_create(mem_ctx, &state, struct posix_lock_state);
+ if (req == NULL) {
+ return NULL;
+ }
+
+ /* Setup setup word. */
+ SSVAL(&state->setup, 0, TRANSACT2_SETFILEINFO);
+
+ /* Setup param array. */
+ SSVAL(&state->param, 0, fnum);
+ SSVAL(&state->param, 2, SMB_SET_POSIX_LOCK);
+
+ /* Setup data array. */
switch (lock_type) {
case READ_LOCK:
- SSVAL(data, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_READ);
+ SSVAL(&state->data, POSIX_LOCK_TYPE_OFFSET,
+ POSIX_LOCK_TYPE_READ);
break;
case WRITE_LOCK:
- SSVAL(data, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_WRITE);
+ SSVAL(&state->data, POSIX_LOCK_TYPE_OFFSET,
+ POSIX_LOCK_TYPE_WRITE);
break;
case UNLOCK_LOCK:
- SSVAL(data, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK);
+ SSVAL(&state->data, POSIX_LOCK_TYPE_OFFSET,
+ POSIX_LOCK_TYPE_UNLOCK);
break;
default:
- return False;
+ return NULL;
}
if (wait_lock) {
- SSVAL(data, POSIX_LOCK_FLAGS_OFFSET, POSIX_LOCK_FLAG_WAIT);
- cli->timeout = 0x7FFFFFFF;
+ SSVAL(&state->data, POSIX_LOCK_FLAGS_OFFSET,
+ POSIX_LOCK_FLAG_WAIT);
} else {
- SSVAL(data, POSIX_LOCK_FLAGS_OFFSET, POSIX_LOCK_FLAG_NOWAIT);
- }
-
- SIVAL(data, POSIX_LOCK_PID_OFFSET, cli->pid);
- SOFF_T(data, POSIX_LOCK_START_OFFSET, offset);
- SOFF_T(data, POSIX_LOCK_LEN_OFFSET, len);
+ SSVAL(state->data, POSIX_LOCK_FLAGS_OFFSET,
+ POSIX_LOCK_FLAG_NOWAIT);
+ }
+
+ SIVAL(&state->data, POSIX_LOCK_PID_OFFSET, cli->pid);
+ SOFF_T(&state->data, POSIX_LOCK_START_OFFSET, offset);
+ SOFF_T(&state->data, POSIX_LOCK_LEN_OFFSET, len);
+
+ subreq = cli_trans_send(state, /* mem ctx. */
+ ev, /* event ctx. */
+ cli, /* cli_state. */
+ SMBtrans2, /* cmd. */
+ NULL, /* pipe name. */
+ -1, /* fid. */
+ 0, /* function. */
+ 0, /* flags. */
+ &state->setup, /* setup. */
+ 1, /* num setup uint16_t words. */
+ 0, /* max returned setup. */
+ state->param, /* param. */
+ 4, /* num param. */
+ 2, /* max returned param. */
+ state->data, /* data. */
+ POSIX_LOCK_DATA_SIZE, /* num data. */
+ 0); /* max returned data. */
- if (!cli_send_trans(cli, SMBtrans2,
- NULL, /* name */
- -1, 0, /* fid, flags */
- &setup, 1, 0, /* setup, length, max */
- param, param_len, 2, /* param, length, max */
- (char *)&data, data_len, cli->max_xmit /* data, length, max */
- )) {
- cli->timeout = saved_timeout;
- return False;
- }
-
- if (!cli_receive_trans(cli, SMBtrans2,
- &rparam, &param_len,
- &rdata, &data_len)) {
- cli->timeout = saved_timeout;
- SAFE_FREE(rdata);
- SAFE_FREE(rparam);
- return False;
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
}
-
- cli->timeout = saved_timeout;
-
- SAFE_FREE(rdata);
- SAFE_FREE(rparam);
-
- return True;
+ tevent_req_set_callback(subreq, cli_posix_unlock_internal_done, req);
+ return req;
}
/****************************************************************************
POSIX Lock a file.
****************************************************************************/
-bool cli_posix_lock(struct cli_state *cli, uint16_t fnum,
+struct tevent_req *cli_posix_lock_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ uint16_t fnum,
+ uint64_t offset,
+ uint64_t len,
+ bool wait_lock,
+ enum brl_type lock_type)
+{
+ return cli_posix_lock_internal_send(mem_ctx, ev, cli, fnum, offset, len,
+ wait_lock, lock_type);
+}
+
+NTSTATUS cli_posix_lock_recv(struct tevent_req *req)
+{
+ NTSTATUS status;
+
+ if (tevent_req_is_nterror(req, &status)) {
+ return status;
+ }
+ return NT_STATUS_OK;
+}
+
+NTSTATUS cli_posix_lock(struct cli_state *cli, uint16_t fnum,
uint64_t offset, uint64_t len,
bool wait_lock, enum brl_type lock_type)
{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev = NULL;
+ struct tevent_req *req = NULL;
+ NTSTATUS status = NT_STATUS_OK;
+
+ if (cli_has_async_calls(cli)) {
+ /*
+ * Can't use sync call while an async call is in flight
+ */
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+
if (lock_type != READ_LOCK && lock_type != WRITE_LOCK) {
- return False;
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ req = cli_posix_lock_send(frame,
+ ev,
+ cli,
+ fnum,
+ offset,
+ len,
+ wait_lock,
+ lock_type);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ if (!tevent_req_poll(req, ev)) {
+ status = map_nt_error_from_unix(errno);
+ goto fail;
+ }
+
+ status = cli_posix_lock_recv(req);
+
+ fail:
+ TALLOC_FREE(frame);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_set_error(cli, status);
}
- return cli_posix_lock_internal(cli, fnum, offset, len, wait_lock, lock_type);
+ return status;
}
/****************************************************************************
POSIX Unlock a file.
****************************************************************************/
-bool cli_posix_unlock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len)
+struct tevent_req *cli_posix_unlock_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ uint16_t fnum,
+ uint64_t offset,
+ uint64_t len)
{
- return cli_posix_lock_internal(cli, fnum, offset, len, False, UNLOCK_LOCK);
+ return cli_posix_lock_internal_send(mem_ctx, ev, cli, fnum, offset, len,
+ false, UNLOCK_LOCK);
}
-/****************************************************************************
- POSIX Get any lock covering a file.
-****************************************************************************/
+NTSTATUS cli_posix_unlock_recv(struct tevent_req *req)
+{
+ NTSTATUS status;
+
+ if (tevent_req_is_nterror(req, &status)) {
+ return status;
+ }
+ return NT_STATUS_OK;
+}
-bool cli_posix_getlock(struct cli_state *cli, uint16_t fnum, uint64_t *poffset, uint64_t *plen)
+NTSTATUS cli_posix_unlock(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len)
{
- return True;
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev = NULL;
+ struct tevent_req *req = NULL;
+ NTSTATUS status = NT_STATUS_OK;
+
+ if (cli_has_async_calls(cli)) {
+ /*
+ * Can't use sync call while an async call is in flight
+ */
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ req = cli_posix_unlock_send(frame,
+ ev,
+ cli,
+ fnum,
+ offset,
+ len);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ if (!tevent_req_poll(req, ev)) {
+ status = map_nt_error_from_unix(errno);
+ goto fail;
+ }
+
+ status = cli_posix_unlock_recv(req);
+
+ fail:
+ TALLOC_FREE(frame);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_set_error(cli, status);
+ }
+ return status;
}
/****************************************************************************
@@ -3264,7 +3566,7 @@ NTSTATUS cli_getatr(struct cli_state *cli,
static void cli_setattrE_done(struct tevent_req *subreq);
struct cli_setattrE_state {
- int dummy;
+ uint16_t vwv[7];
};
struct tevent_req *cli_setattrE_send(TALLOC_CTX *mem_ctx,
@@ -3278,21 +3580,19 @@ struct tevent_req *cli_setattrE_send(TALLOC_CTX *mem_ctx,
struct tevent_req *req = NULL, *subreq = NULL;
struct cli_setattrE_state *state = NULL;
uint8_t additional_flags = 0;
- uint16_t vwv[7];
req = tevent_req_create(mem_ctx, &state, struct cli_setattrE_state);
if (req == NULL) {
return NULL;
}
- memset(vwv, '\0', sizeof(vwv));
- SSVAL(vwv+0, 0, fnum);
- cli_put_dos_date2(cli, (char *)&vwv[1], 0, change_time);
- cli_put_dos_date2(cli, (char *)&vwv[3], 0, access_time);
- cli_put_dos_date2(cli, (char *)&vwv[5], 0, write_time);
+ SSVAL(state->vwv+0, 0, fnum);
+ cli_put_dos_date2(cli, (char *)&state->vwv[1], 0, change_time);
+ cli_put_dos_date2(cli, (char *)&state->vwv[3], 0, access_time);
+ cli_put_dos_date2(cli, (char *)&state->vwv[5], 0, write_time);
subreq = cli_smb_send(state, ev, cli, SMBsetattrE, additional_flags,
- 7, vwv, 0, NULL);
+ 7, state->vwv, 0, NULL);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
@@ -3399,7 +3699,6 @@ struct tevent_req *cli_setatr_send(TALLOC_CTX *mem_ctx,
return NULL;
}
- memset(state->vwv, '\0', sizeof(state->vwv));
SSVAL(state->vwv+0, 0, attr);
cli_put_dos_date3(cli, (char *)&state->vwv[1], 0, mtime);
diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c
index 8a567dc751..152c23bd15 100644
--- a/source3/libsmb/clikrb5.c
+++ b/source3/libsmb/clikrb5.c
@@ -346,7 +346,7 @@ bool unwrap_edata_ntstatus(TALLOC_CTX *mem_ctx,
}
asn1_start_tag(data, ASN1_CONTEXT(2));
- asn1_read_OctetString(data, NULL, &edata_contents);
+ asn1_read_OctetString(data, talloc_autofree_context(), &edata_contents);
asn1_end_tag(data);
asn1_end_tag(data);
asn1_end_tag(data);
@@ -389,7 +389,7 @@ bool unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_
asn1_end_tag(data);
asn1_start_tag(data, ASN1_CONTEXT(1));
- asn1_read_OctetString(data, NULL, &pac_contents);
+ asn1_read_OctetString(data, talloc_autofree_context(), &pac_contents);
asn1_end_tag(data);
asn1_end_tag(data);
asn1_end_tag(data);
diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c
index fb95d71925..e586d976cf 100644
--- a/source3/libsmb/clispnego.c
+++ b/source3/libsmb/clispnego.c
@@ -151,7 +151,7 @@ bool spnego_parse_negTokenInit(DATA_BLOB blob,
asn1_start_tag(data,ASN1_SEQUENCE(0));
for (i=0; asn1_tag_remaining(data) > 0 && i < ASN1_MAX_OIDS-1; i++) {
const char *oid_str = NULL;
- asn1_read_OID(data,NULL,&oid_str);
+ asn1_read_OID(data,talloc_autofree_context(),&oid_str);
OIDs[i] = CONST_DISCARD(char *, oid_str);
}
OIDs[i] = NULL;
@@ -163,7 +163,7 @@ bool spnego_parse_negTokenInit(DATA_BLOB blob,
asn1_start_tag(data, ASN1_CONTEXT(3));
asn1_start_tag(data, ASN1_SEQUENCE(0));
asn1_start_tag(data, ASN1_CONTEXT(0));
- asn1_read_GeneralString(data,NULL,principal);
+ asn1_read_GeneralString(data,talloc_autofree_context(),principal);
asn1_end_tag(data);
asn1_end_tag(data);
asn1_end_tag(data);
@@ -256,7 +256,7 @@ bool parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se
asn1_start_tag(data, ASN1_SEQUENCE(0));
for (i=0; asn1_tag_remaining(data) > 0 && i < ASN1_MAX_OIDS-1; i++) {
const char *oid_str = NULL;
- asn1_read_OID(data,NULL,&oid_str);
+ asn1_read_OID(data,talloc_autofree_context(),&oid_str);
OIDs[i] = CONST_DISCARD(char *, oid_str);
}
OIDs[i] = NULL;
@@ -276,7 +276,7 @@ bool parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se
}
asn1_start_tag(data, ASN1_CONTEXT(2));
- asn1_read_OctetString(data,NULL,secblob);
+ asn1_read_OctetString(data,talloc_autofree_context(),secblob);
asn1_end_tag(data);
asn1_end_tag(data);
@@ -436,13 +436,13 @@ bool spnego_parse_challenge(const DATA_BLOB blob,
asn1_end_tag(data);
asn1_start_tag(data,ASN1_CONTEXT(2));
- asn1_read_OctetString(data, NULL, chal1);
+ asn1_read_OctetString(data, talloc_autofree_context(), chal1);
asn1_end_tag(data);
/* the second challenge is optional (XP doesn't send it) */
if (asn1_tag_remaining(data)) {
asn1_start_tag(data,ASN1_CONTEXT(3));
- asn1_read_OctetString(data, NULL, chal2);
+ asn1_read_OctetString(data, talloc_autofree_context(), chal2);
asn1_end_tag(data);
}
@@ -505,7 +505,7 @@ bool spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth)
asn1_start_tag(data, ASN1_CONTEXT(1));
asn1_start_tag(data, ASN1_SEQUENCE(0));
asn1_start_tag(data, ASN1_CONTEXT(2));
- asn1_read_OctetString(data, NULL, auth);
+ asn1_read_OctetString(data, talloc_autofree_context(), auth);
asn1_end_tag(data);
asn1_end_tag(data);
asn1_end_tag(data);
@@ -609,7 +609,7 @@ bool spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status,
if (asn1_tag_remaining(data)) {
asn1_start_tag(data,ASN1_CONTEXT(2));
- asn1_read_OctetString(data, NULL, auth);
+ asn1_read_OctetString(data, talloc_autofree_context(), auth);
asn1_end_tag(data);
}
} else if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) {
@@ -623,7 +623,7 @@ bool spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status,
if (asn1_tag_remaining(data)) {
DATA_BLOB mechList = data_blob_null;
asn1_start_tag(data, ASN1_CONTEXT(3));
- asn1_read_OctetString(data, NULL, &mechList);
+ asn1_read_OctetString(data, talloc_autofree_context(), &mechList);
asn1_end_tag(data);
data_blob_free(&mechList);
DEBUG(5,("spnego_parse_auth_response received mechListMIC, "
diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c
index fb87b4dc9a..3e0f4977aa 100644
--- a/source3/libsmb/dsgetdcname.c
+++ b/source3/libsmb/dsgetdcname.c
@@ -133,10 +133,6 @@ static NTSTATUS dsgetdcname_cache_delete(TALLOC_CTX *mem_ctx,
{
char *key;
- if (!gencache_init()) {
- return NT_STATUS_INTERNAL_DB_ERROR;
- }
-
key = dsgetdcname_cache_key(mem_ctx, domain_name);
if (!key) {
return NT_STATUS_NO_MEMORY;
@@ -160,10 +156,6 @@ static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx,
char *key;
bool ret = false;
- if (!gencache_init()) {
- return NT_STATUS_INTERNAL_DB_ERROR;
- }
-
key = dsgetdcname_cache_key(mem_ctx, domain_name);
if (!key) {
return NT_STATUS_NO_MEMORY;
@@ -171,14 +163,8 @@ static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx,
expire_time = time(NULL) + DSGETDCNAME_CACHE_TTL;
- if (gencache_lock_entry(key) != 0) {
- return NT_STATUS_LOCK_NOT_GRANTED;
- }
-
ret = gencache_set_data_blob(key, blob, expire_time);
- gencache_unlock_entry(key);
-
return ret ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
@@ -353,8 +339,7 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx,
struct GUID *domain_guid,
uint32_t flags,
const char *site_name,
- struct netr_DsRGetDCNameInfo **info_p,
- bool *expired)
+ struct netr_DsRGetDCNameInfo **info_p)
{
char *key;
DATA_BLOB blob;
@@ -363,17 +348,13 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx,
struct NETLOGON_SAM_LOGON_RESPONSE_EX r;
NTSTATUS status;
- if (!gencache_init()) {
- return NT_STATUS_INTERNAL_DB_ERROR;
- }
-
key = dsgetdcname_cache_key(mem_ctx, domain_name);
if (!key) {
return NT_STATUS_NO_MEMORY;
}
- if (!gencache_get_data_blob(key, &blob, expired)) {
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ if (!gencache_get_data_blob(key, &blob, NULL)) {
+ return NT_STATUS_NOT_FOUND;
}
info = TALLOC_ZERO_P(mem_ctx, struct netr_DsRGetDCNameInfo);
@@ -428,11 +409,11 @@ static NTSTATUS dsgetdcname_cached(TALLOC_CTX *mem_ctx,
struct netr_DsRGetDCNameInfo **info)
{
NTSTATUS status;
- bool expired = false;
status = dsgetdcname_cache_fetch(mem_ctx, domain_name, domain_guid,
- flags, site_name, info, &expired);
- if (!NT_STATUS_IS_OK(status)) {
+ flags, site_name, info);
+ if (!NT_STATUS_IS_OK(status)
+ && !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
DEBUG(10,("dsgetdcname_cached: cache fetch failed with: %s\n",
nt_errstr(status)));
return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
@@ -442,7 +423,7 @@ static NTSTATUS dsgetdcname_cached(TALLOC_CTX *mem_ctx,
return status;
}
- if (expired) {
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
status = dsgetdcname_cache_refresh(mem_ctx, msg_ctx,
domain_name,
domain_guid, flags,
diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c
index 98885876b3..8b22ee5023 100644
--- a/source3/libsmb/libsmb_context.c
+++ b/source3/libsmb/libsmb_context.c
@@ -123,7 +123,6 @@ SMBC_module_init(void * punused)
static void
SMBC_module_terminate(void)
{
- gencache_shutdown();
secrets_shutdown();
gfree_all();
SMBC_initialized = false;
diff --git a/source3/libsmb/libsmb_thread_posix.c b/source3/libsmb/libsmb_thread_posix.c
index 411ffbdfbb..6519659c25 100644
--- a/source3/libsmb/libsmb_thread_posix.c
+++ b/source3/libsmb/libsmb_thread_posix.c
@@ -17,8 +17,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <pthread.h>
#include "includes.h"
+#include <pthread.h>
#include "libsmbclient.h"
#include "libsmb_internal.h"
diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c
index d3230cffef..dcfc609dcd 100644
--- a/source3/libsmb/namecache.c
+++ b/source3/libsmb/namecache.c
@@ -45,14 +45,6 @@ bool namecache_enable(void)
return False;
}
- /* Init namecache by calling gencache initialisation */
-
- if (!gencache_init()) {
- DEBUG(2, ("namecache_enable: "
- "Couldn't initialise namecache on top of gencache.\n"));
- return False;
- }
-
/* I leave it for now, though I don't think we really
* need this (mimir, 27.09.2002) */
DEBUG(5, ("namecache_enable: enabling netbios namecache, timeout %d "
@@ -102,14 +94,6 @@ bool namecache_store(const char *name,
int i;
bool ret;
- /*
- * we use gecache call to avoid annoying debug messages about
- * initialised namecache again and again...
- */
- if (!gencache_init()) {
- return False;
- }
-
if (name_type > 255) {
return False; /* Don't store non-real name types. */
}
@@ -186,10 +170,6 @@ bool namecache_fetch(const char *name,
return False;
}
- if (!gencache_init()) {
- return False;
- }
-
if (name_type > 255) {
return False; /* Don't fetch non-real name types. */
}
@@ -233,9 +213,6 @@ bool namecache_delete(const char *name, int name_type)
bool ret;
char *key;
- if (!gencache_init())
- return False;
-
if (name_type > 255) {
return False; /* Don't fetch non-real name types. */
}
@@ -274,10 +251,6 @@ static void flush_netbios_name(const char *key,
void namecache_flush(void)
{
- if (!gencache_init()) {
- return;
- }
-
/*
* iterate through each NBT cache's entry and flush it
* by flush_netbios_name function
@@ -312,10 +285,6 @@ bool namecache_status_store(const char *keyname, int keyname_type,
time_t expiry;
bool ret;
- if (!gencache_init()) {
- return False;
- }
-
key = namecache_status_record_key(keyname, keyname_type,
name_type, keyip);
if (!key)
@@ -348,9 +317,6 @@ bool namecache_status_fetch(const char *keyname,
char *value = NULL;
time_t timeout;
- if (!gencache_init())
- return False;
-
key = namecache_status_record_key(keyname, keyname_type,
name_type, keyip);
if (!key)
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index 50fb9f1620..05143270b9 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -76,9 +76,6 @@ bool saf_store( const char *domain, const char *servername )
return False;
}
- if ( !gencache_init() )
- return False;
-
key = saf_key( domain );
expire = time( NULL ) + lp_parm_int(-1, "saf","ttl", SAF_TTL);
@@ -108,9 +105,6 @@ bool saf_join_store( const char *domain, const char *servername )
return False;
}
- if ( !gencache_init() )
- return False;
-
key = saf_join_key( domain );
expire = time( NULL ) + lp_parm_int(-1, "saf","join ttl", SAFJOIN_TTL);
@@ -134,9 +128,6 @@ bool saf_delete( const char *domain )
return False;
}
- if ( !gencache_init() )
- return False;
-
key = saf_join_key(domain);
ret = gencache_del(key);
SAFE_FREE(key);
@@ -171,9 +162,6 @@ char *saf_fetch( const char *domain )
return NULL;
}
- if ( !gencache_init() )
- return False;
-
key = saf_join_key( domain );
ret = gencache_get( key, &server, &timeout );
diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c
index ee2c3c3d5a..528c7f4009 100644
--- a/source3/libsmb/spnego.c
+++ b/source3/libsmb/spnego.c
@@ -41,17 +41,18 @@ static bool read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token)
asn1_start_tag(asn1, ASN1_CONTEXT(0));
asn1_start_tag(asn1, ASN1_SEQUENCE(0));
- token->mechTypes = TALLOC_P(NULL, const char *);
+ token->mechTypes = TALLOC_P(talloc_autofree_context(), const char *);
for (i = 0; !asn1->has_error &&
0 < asn1_tag_remaining(asn1); i++) {
const char *p_oid = NULL;
token->mechTypes =
- TALLOC_REALLOC_ARRAY(NULL, token->mechTypes, const char *, i + 2);
+ TALLOC_REALLOC_ARRAY(talloc_autofree_context(),
+ token->mechTypes, const char *, i + 2);
if (!token->mechTypes) {
asn1->has_error = True;
return False;
}
- asn1_read_OID(asn1, NULL, &p_oid);
+ asn1_read_OID(asn1, talloc_autofree_context(), &p_oid);
token->mechTypes[i] = p_oid;
}
token->mechTypes[i] = NULL;
@@ -69,14 +70,15 @@ static bool read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token)
/* Read mechToken */
case ASN1_CONTEXT(2):
asn1_start_tag(asn1, ASN1_CONTEXT(2));
- asn1_read_OctetString(asn1, NULL, &token->mechToken);
+ asn1_read_OctetString(asn1,
+ talloc_autofree_context(), &token->mechToken);
asn1_end_tag(asn1);
break;
/* Read mecListMIC */
case ASN1_CONTEXT(3):
asn1_start_tag(asn1, ASN1_CONTEXT(3));
if (asn1->data[asn1->ofs] == ASN1_OCTET_STRING) {
- asn1_read_OctetString(asn1, NULL,
+ asn1_read_OctetString(asn1, talloc_autofree_context(),
&token->mechListMIC);
} else {
/* RFC 2478 says we have an Octet String here,
@@ -84,7 +86,8 @@ static bool read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token)
char *mechListMIC;
asn1_push_tag(asn1, ASN1_SEQUENCE(0));
asn1_push_tag(asn1, ASN1_CONTEXT(0));
- asn1_read_GeneralString(asn1, NULL, &mechListMIC);
+ asn1_read_GeneralString(asn1,
+ talloc_autofree_context(), &mechListMIC);
asn1_pop_tag(asn1);
asn1_pop_tag(asn1);
@@ -188,19 +191,21 @@ static bool read_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token)
case ASN1_CONTEXT(1): {
const char *mech = NULL;
asn1_start_tag(asn1, ASN1_CONTEXT(1));
- asn1_read_OID(asn1, NULL, &mech);
+ asn1_read_OID(asn1, talloc_autofree_context(), &mech);
asn1_end_tag(asn1);
token->supportedMech = CONST_DISCARD(char *, mech);
}
break;
case ASN1_CONTEXT(2):
asn1_start_tag(asn1, ASN1_CONTEXT(2));
- asn1_read_OctetString(asn1, NULL, &token->responseToken);
+ asn1_read_OctetString(asn1,
+ talloc_autofree_context(), &token->responseToken);
asn1_end_tag(asn1);
break;
case ASN1_CONTEXT(3):
asn1_start_tag(asn1, ASN1_CONTEXT(3));
- asn1_read_OctetString(asn1, NULL, &token->mechListMIC);
+ asn1_read_OctetString(asn1,
+ talloc_autofree_context(), &token->mechListMIC);
asn1_end_tag(asn1);
break;
default:
diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c
index 6755de3814..eb52b3588d 100644
--- a/source3/libsmb/trustdom_cache.c
+++ b/source3/libsmb/trustdom_cache.c
@@ -4,17 +4,17 @@
Trusted domain names cache on top of gencache.
Copyright (C) Rafal Szczesniak 2002
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -38,7 +38,6 @@
* list of trusted domains
**/
-
/**
* Initialise trustdom name caching system. Call gencache
* initialisation routine to perform necessary activities.
@@ -46,15 +45,9 @@
* @return true upon successful cache initialisation or
* false if cache init failed
**/
-
+
bool trustdom_cache_enable(void)
{
- /* Init trustdom cache by calling gencache initialisation */
- if (!gencache_init()) {
- DEBUG(2, ("trustdomcache_enable: Couldn't initialise trustdom cache on top of gencache.\n"));
- return False;
- }
-
return True;
}
@@ -66,15 +59,9 @@ bool trustdom_cache_enable(void)
* @return true upon successful cache close or
* false if it failed
**/
-
+
bool trustdom_cache_shutdown(void)
{
- /* Close trustdom cache by calling gencache shutdown */
- if (!gencache_shutdown()) {
- DEBUG(2, ("trustdomcache_shutdown: Couldn't shutdown trustdom cache on top of gencache.\n"));
- return False;
- }
-
return True;
}
@@ -91,7 +78,7 @@ static char* trustdom_cache_key(const char* name)
{
char* keystr = NULL;
asprintf_strupper_m(&keystr, TDOMKEY_FMT, name);
-
+
return keystr;
}
@@ -115,13 +102,6 @@ bool trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid,
fstring sid_string;
bool ret;
- /*
- * we use gecache call to avoid annoying debug messages
- * about initialised trustdom
- */
- if (!gencache_init())
- return False;
-
DEBUG(5, ("trustdom_store: storing SID %s of domain %s\n",
sid_string_dbg(sid), name));
@@ -160,16 +140,12 @@ bool trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid,
* @return true if entry is found or
* false if has expired/doesn't exist
**/
-
+
bool trustdom_cache_fetch(const char* name, DOM_SID* sid)
{
char *key = NULL, *value = NULL;
time_t timeout;
- /* init the cache */
- if (!gencache_init())
- return False;
-
/* exit now if null pointers were passed as they're required further */
if (!sid)
return False;
@@ -178,7 +154,7 @@ bool trustdom_cache_fetch(const char* name, DOM_SID* sid)
key = trustdom_cache_key(name);
if (!key)
return False;
-
+
if (!gencache_get(key, &value, &timeout)) {
DEBUG(5, ("no entry for trusted domain %s found.\n", name));
SAFE_FREE(key);
@@ -194,7 +170,7 @@ bool trustdom_cache_fetch(const char* name, DOM_SID* sid)
SAFE_FREE(value);
return False;
}
-
+
SAFE_FREE(value);
return True;
}
@@ -210,10 +186,6 @@ uint32 trustdom_cache_fetch_timestamp( void )
time_t timeout;
uint32 timestamp;
- /* init the cache */
- if (!gencache_init())
- return False;
-
if (!gencache_get(TDOMTSKEY, &value, &timeout)) {
DEBUG(5, ("no timestamp for trusted domain cache located.\n"));
SAFE_FREE(value);
@@ -221,7 +193,7 @@ uint32 trustdom_cache_fetch_timestamp( void )
}
timestamp = atoi(value);
-
+
SAFE_FREE(value);
return timestamp;
}
@@ -234,12 +206,8 @@ bool trustdom_cache_store_timestamp( uint32 t, time_t timeout )
{
fstring value;
- /* init the cache */
- if (!gencache_init())
- return False;
-
fstr_sprintf(value, "%d", t );
-
+
if (!gencache_set(TDOMTSKEY, value, timeout)) {
DEBUG(5, ("failed to set timestamp for trustdom_cache\n"));
return False;
@@ -268,9 +236,6 @@ static void flush_trustdom_name(const char* key, const char *value, time_t timeo
void trustdom_cache_flush(void)
{
- if (!gencache_init())
- return;
-
/*
* iterate through each TDOM cache's entry and flush it
* by flush_trustdom_name function
@@ -294,13 +259,13 @@ void update_trustdom_cache( void )
TALLOC_CTX *mem_ctx = NULL;
time_t now = time(NULL);
int i;
-
+
/* get the timestamp. We have to initialise it if the last timestamp == 0 */
if ( (last_check = trustdom_cache_fetch_timestamp()) == 0 )
trustdom_cache_store_timestamp(0, now+TRUSTDOM_UPDATE_INTERVAL);
time_diff = (int) (now - last_check);
-
+
if ( (time_diff > 0) && (time_diff < TRUSTDOM_UPDATE_INTERVAL) ) {
DEBUG(10,("update_trustdom_cache: not time to update trustdom_cache yet\n"));
return;
@@ -310,14 +275,14 @@ void update_trustdom_cache( void )
smbd from blocking all other smbd daemons while we
enumerate the trusted domains */
trustdom_cache_store_timestamp(now, now+TRUSTDOM_UPDATE_INTERVAL);
-
+
if ( !(mem_ctx = talloc_init("update_trustdom_cache")) ) {
DEBUG(0,("update_trustdom_cache: talloc_init() failed!\n"));
goto done;
}
/* get the domains and store them */
-
+
if ( enumerate_domain_trusts(mem_ctx, lp_workgroup(), &domain_names,
&num_domains, &dom_sids)) {
for ( i=0; i<num_domains; i++ ) {
@@ -333,6 +298,6 @@ void update_trustdom_cache( void )
done:
talloc_destroy( mem_ctx );
-
+
return;
}
diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c
index be2948c531..e238ec959b 100644
--- a/source3/locking/brlock.c
+++ b/source3/locking/brlock.c
@@ -1196,7 +1196,7 @@ bool brl_locktest(struct byte_range_lock *br_lck,
DEBUG(10,("brl_locktest: posix start=%.0f len=%.0f %s for fnum %d file %s\n",
(double)start, (double)size, ret ? "locked" : "unlocked",
- fsp->fnum, fsp->fsp_name ));
+ fsp->fnum, fsp_str_dbg(fsp)));
/* We need to return the inverse of is_posix_locked. */
ret = !ret;
@@ -1262,7 +1262,7 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck,
DEBUG(10,("brl_lockquery: posix start=%.0f len=%.0f %s for fnum %d file %s\n",
(double)*pstart, (double)*psize, ret ? "locked" : "unlocked",
- fsp->fnum, fsp->fsp_name ));
+ fsp->fnum, fsp_str_dbg(fsp)));
if (ret) {
/* Hmmm. No clue what to set smbpid to - use -1. */
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index 91fe137fdc..fba871c704 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -109,11 +109,11 @@ bool strict_lock_default(files_struct *fsp, struct lock_struct *plock)
if (strict_locking == Auto) {
if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (plock->lock_type == READ_LOCK || plock->lock_type == WRITE_LOCK)) {
- DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name ));
+ DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp_str_dbg(fsp)));
ret = True;
} else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
(plock->lock_type == READ_LOCK)) {
- DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name ));
+ DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp_str_dbg(fsp)));
ret = True;
} else {
struct byte_range_lock *br_lck = brl_get_locks_readonly(talloc_tos(), fsp);
@@ -149,7 +149,7 @@ bool strict_lock_default(files_struct *fsp, struct lock_struct *plock)
lock_flav_name(plock->lock_flav),
(double)plock->start, (double)plock->size,
ret ? "unlocked" : "locked",
- plock->fnum, fsp->fsp_name ));
+ plock->fnum, fsp_str_dbg(fsp)));
return ret;
}
@@ -259,7 +259,7 @@ struct byte_range_lock *do_lock(struct messaging_context *msg_ctx,
"blocking_lock=%s requested for fnum %d file %s\n",
lock_flav_name(lock_flav), lock_type_name(lock_type),
(double)offset, (double)count, blocking_lock ? "true" :
- "false", fsp->fnum, fsp->fsp_name));
+ "false", fsp->fnum, fsp_str_dbg(fsp)));
br_lck = brl_get_locks(talloc_tos(), fsp);
if (!br_lck) {
@@ -308,7 +308,8 @@ NTSTATUS do_unlock(struct messaging_context *msg_ctx,
}
DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
- (double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
+ (double)offset, (double)count, fsp->fnum,
+ fsp_str_dbg(fsp)));
br_lck = brl_get_locks(talloc_tos(), fsp);
if (!br_lck) {
@@ -358,7 +359,8 @@ NTSTATUS do_lock_cancel(files_struct *fsp,
}
DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n",
- (double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
+ (double)offset, (double)count, fsp->fnum,
+ fsp_str_dbg(fsp)));
br_lck = brl_get_locks(talloc_tos(), fsp);
if (!br_lck) {
@@ -1311,7 +1313,7 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, bool delete_on_close,
!lp_delete_readonly(SNUM(fsp->conn))) {
DEBUG(10,("can_set_delete_on_close: file %s delete on close "
"flag set but file attribute is readonly.\n",
- fsp->fsp_name ));
+ fsp_str_dbg(fsp)));
return NT_STATUS_CANNOT_DELETE;
}
@@ -1322,7 +1324,7 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, bool delete_on_close,
if (!CAN_WRITE(fsp->conn)) {
DEBUG(10,("can_set_delete_on_close: file %s delete on "
"close flag set but write access denied on share.\n",
- fsp->fsp_name ));
+ fsp_str_dbg(fsp)));
return NT_STATUS_ACCESS_DENIED;
}
@@ -1334,13 +1336,15 @@ NTSTATUS can_set_delete_on_close(files_struct *fsp, bool delete_on_close,
if (!(fsp->access_mask & DELETE_ACCESS)) {
DEBUG(10,("can_set_delete_on_close: file %s delete on "
"close flag set but delete access denied.\n",
- fsp->fsp_name ));
+ fsp_str_dbg(fsp)));
return NT_STATUS_ACCESS_DENIED;
}
/* Don't allow delete on close for non-empty directories. */
if (fsp->is_directory) {
- return can_delete_directory(fsp->conn, fsp->fsp_name);
+ SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
+ return can_delete_directory(fsp->conn,
+ fsp->fsp_name->base_name);
}
return NT_STATUS_OK;
@@ -1422,7 +1426,7 @@ bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const UNIX_USE
DEBUG(10,("set_delete_on_close: %s delete on close flag for "
"fnum = %d, file %s\n",
delete_on_close ? "Adding" : "Removing", fsp->fnum,
- fsp->fsp_name ));
+ fsp_str_dbg(fsp)));
lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
NULL);
@@ -1443,7 +1447,8 @@ bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const UNIX_USE
set_delete_on_close_lck(lck, delete_on_close, tok);
if (fsp->is_directory) {
- send_stat_cache_delete_message(fsp->fsp_name);
+ SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
+ send_stat_cache_delete_message(fsp->fsp_name->base_name);
}
TALLOC_FREE(lck);
diff --git a/source3/locking/posix.c b/source3/locking/posix.c
index 9b51c3aa6a..33ffaf95ca 100644
--- a/source3/locking/posix.c
+++ b/source3/locking/posix.c
@@ -280,8 +280,9 @@ bool is_posix_locked(files_struct *fsp,
SMB_OFF_T count;
int posix_lock_type = map_posix_lock_type(fsp,*plock_type);
- DEBUG(10,("is_posix_locked: File %s, offset = %.0f, count = %.0f, type = %s\n",
- fsp->fsp_name, (double)*pu_offset, (double)*pu_count, posix_lock_type_name(*plock_type) ));
+ DEBUG(10,("is_posix_locked: File %s, offset = %.0f, count = %.0f, "
+ "type = %s\n", fsp_str_dbg(fsp), (double)*pu_offset,
+ (double)*pu_count, posix_lock_type_name(*plock_type)));
/*
* If the requested lock won't fit in the POSIX range, we will
@@ -424,7 +425,7 @@ static void increment_windows_lock_ref_count(files_struct *fsp)
TALLOC_FREE(rec);
DEBUG(10,("increment_windows_lock_ref_count for file now %s = %d\n",
- fsp->fsp_name, lock_ref_count ));
+ fsp_str_dbg(fsp), lock_ref_count));
}
/****************************************************************************
@@ -460,7 +461,7 @@ void reduce_windows_lock_ref_count(files_struct *fsp, unsigned int dcount)
TALLOC_FREE(rec);
DEBUG(10,("reduce_windows_lock_ref_count for file now %s = %d\n",
- fsp->fsp_name, lock_ref_count ));
+ fsp_str_dbg(fsp), lock_ref_count));
}
static void decrement_windows_lock_ref_count(files_struct *fsp)
@@ -492,7 +493,7 @@ static int get_windows_lock_ref_count(files_struct *fsp)
}
DEBUG(10,("get_windows_lock_count for file %s = %d\n",
- fsp->fsp_name, lock_ref_count ));
+ fsp_str_dbg(fsp), lock_ref_count));
return lock_ref_count;
}
@@ -518,7 +519,7 @@ static void delete_windows_lock_ref_count(files_struct *fsp)
TALLOC_FREE(rec);
DEBUG(10,("delete_windows_lock_ref_count for file %s\n",
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
}
/****************************************************************************
@@ -555,7 +556,7 @@ static void add_fd_to_close_entry(files_struct *fsp)
TALLOC_FREE(rec);
DEBUG(10,("add_fd_to_close_entry: added fd %d file %s\n",
- fsp->fh->fd, fsp->fsp_name ));
+ fsp->fh->fd, fsp_str_dbg(fsp)));
}
/****************************************************************************
@@ -945,8 +946,10 @@ bool set_posix_lock_windows_flavour(files_struct *fsp,
struct lock_list *llist = NULL;
struct lock_list *ll = NULL;
- DEBUG(5,("set_posix_lock_windows_flavour: File %s, offset = %.0f, count = %.0f, type = %s\n",
- fsp->fsp_name, (double)u_offset, (double)u_count, posix_lock_type_name(lock_type) ));
+ DEBUG(5,("set_posix_lock_windows_flavour: File %s, offset = %.0f, "
+ "count = %.0f, type = %s\n", fsp_str_dbg(fsp),
+ (double)u_offset, (double)u_count,
+ posix_lock_type_name(lock_type)));
/*
* If the requested lock won't fit in the POSIX range, we will
@@ -1079,8 +1082,9 @@ bool release_posix_lock_windows_flavour(files_struct *fsp,
struct lock_list *ulist = NULL;
struct lock_list *ul = NULL;
- DEBUG(5,("release_posix_lock_windows_flavour: File %s, offset = %.0f, count = %.0f\n",
- fsp->fsp_name, (double)u_offset, (double)u_count ));
+ DEBUG(5,("release_posix_lock_windows_flavour: File %s, offset = %.0f, "
+ "count = %.0f\n", fsp_str_dbg(fsp),
+ (double)u_offset, (double)u_count));
/* Remember the number of Windows locks we have on this dev/ino pair. */
decrement_windows_lock_ref_count(fsp);
@@ -1197,8 +1201,10 @@ bool set_posix_lock_posix_flavour(files_struct *fsp,
SMB_OFF_T count;
int posix_lock_type = map_posix_lock_type(fsp,lock_type);
- DEBUG(5,("set_posix_lock_posix_flavour: File %s, offset = %.0f, count = %.0f, type = %s\n",
- fsp->fsp_name, (double)u_offset, (double)u_count, posix_lock_type_name(lock_type) ));
+ DEBUG(5,("set_posix_lock_posix_flavour: File %s, offset = %.0f, count "
+ "= %.0f, type = %s\n", fsp_str_dbg(fsp),
+ (double)u_offset, (double)u_count,
+ posix_lock_type_name(lock_type)));
/*
* If the requested lock won't fit in the POSIX range, we will
@@ -1241,8 +1247,9 @@ bool release_posix_lock_posix_flavour(files_struct *fsp,
struct lock_list *ulist = NULL;
struct lock_list *ul = NULL;
- DEBUG(5,("release_posix_lock_posix_flavour: File %s, offset = %.0f, count = %.0f\n",
- fsp->fsp_name, (double)u_offset, (double)u_count ));
+ DEBUG(5,("release_posix_lock_posix_flavour: File %s, offset = %.0f, "
+ "count = %.0f\n", fsp_str_dbg(fsp),
+ (double)u_offset, (double)u_count));
/*
* If the requested lock won't fit in the POSIX range, we will
diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c
index 9b3c8725d5..748f17d457 100644
--- a/source3/modules/nfs4_acls.c
+++ b/source3/modules/nfs4_acls.c
@@ -183,7 +183,8 @@ static int smbacl4_fGetFileOwner(files_struct *fsp, SMB_STRUCT_STAT *psbuf)
memset(psbuf, 0, sizeof(SMB_STRUCT_STAT));
if (fsp->is_directory || fsp->fh->fd == -1) {
- return smbacl4_GetFileOwner(fsp->conn, fsp->fsp_name, psbuf);
+ return smbacl4_GetFileOwner(fsp->conn,
+ fsp->fsp_name->base_name, psbuf);
}
if (SMB_VFS_FSTAT(fsp, psbuf) != 0)
{
@@ -327,7 +328,7 @@ NTSTATUS smb_fget_nt_acl_nfs4(files_struct *fsp,
{
SMB_STRUCT_STAT sbuf;
- DEBUG(10, ("smb_fget_nt_acl_nfs4 invoked for %s\n", fsp->fsp_name));
+ DEBUG(10, ("smb_fget_nt_acl_nfs4 invoked for %s\n", fsp_str_dbg(fsp)));
if (smbacl4_fGetFileOwner(fsp, &sbuf)) {
return map_nt_error_from_unix(errno);
@@ -717,7 +718,7 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
gid_t newGID = (gid_t)-1;
int saved_errno;
- DEBUG(10, ("smb_set_nt_acl_nfs4 invoked for %s\n", fsp->fsp_name));
+ DEBUG(10, ("smb_set_nt_acl_nfs4 invoked for %s\n", fsp_str_dbg(fsp)));
if ((security_info_sent & (DACL_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION)) == 0)
@@ -743,26 +744,23 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
}
if (((newUID != (uid_t)-1) && (sbuf.st_ex_uid != newUID)) ||
((newGID != (gid_t)-1) && (sbuf.st_ex_gid != newGID))) {
- struct smb_filename *smb_fname = NULL;
- NTSTATUS status;
- status = create_synthetic_smb_fname_split(talloc_tos(),
- fsp->fsp_name, NULL, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
- if(try_chown(fsp->conn, smb_fname, newUID, newGID)) {
- DEBUG(3,("chown %s, %u, %u failed. Error = %s.\n",
- fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID,
+ if(try_chown(fsp->conn, fsp->fsp_name, newUID,
+ newGID)) {
+ DEBUG(3,("chown %s, %u, %u failed. Error = "
+ "%s.\n", fsp_str_dbg(fsp),
+ (unsigned int)newUID,
+ (unsigned int)newGID,
strerror(errno)));
- TALLOC_FREE(smb_fname);
return map_nt_error_from_unix(errno);
}
- TALLOC_FREE(smb_fname);
DEBUG(10,("chown %s, %u, %u succeeded.\n",
- fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID));
- if (smbacl4_GetFileOwner(fsp->conn, fsp->fsp_name, &sbuf))
+ fsp_str_dbg(fsp), (unsigned int)newUID,
+ (unsigned int)newGID));
+ if (smbacl4_GetFileOwner(fsp->conn,
+ fsp->fsp_name->base_name,
+ &sbuf))
return map_nt_error_from_unix(errno);
/* If we successfully chowned, we know we must
@@ -777,7 +775,7 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
return NT_STATUS_OK;
}
- theacl = smbacl4_win2nfs4(fsp->fsp_name, psd->dacl, &params,
+ theacl = smbacl4_win2nfs4(fsp->fsp_name->base_name, psd->dacl, &params,
sbuf.st_ex_uid, sbuf.st_ex_gid);
if (!theacl)
return map_nt_error_from_unix(errno);
diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c
index 5c72d10a6b..2753a9e885 100644
--- a/source3/modules/onefs_acl.c
+++ b/source3/modules/onefs_acl.c
@@ -395,8 +395,8 @@ onefs_canon_acl(files_struct *fsp, struct ifs_security_descriptor *sd)
if ((sbuf.st_ex_flags & SF_HASNTFSACL) != 0) {
DEBUG(10, ("Did not canonicalize ACLs because a "
- "Windows ACL set was found for file %s\n",
- fsp->fsp_name));
+ "Windows ACL set was found for file %s\n",
+ fsp_str_dbg(fsp)));
return true;
}
break;
@@ -436,7 +436,7 @@ onefs_canon_acl(files_struct *fsp, struct ifs_security_descriptor *sd)
SMB_ASSERT(new_aces_count == sd->dacl->num_aces);
DEBUG(10, ("Performed canonicalization of ACLs for file %s\n",
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
/*
* At this point you would think we could just do this:
@@ -535,32 +535,21 @@ static bool add_sfs_aces(files_struct *fsp, struct ifs_security_descriptor *sd)
if (error) {
DEBUG(0, ("Failed to stat %s in simple files sharing "
"compatibility mode. errno=%d\n",
- fsp->fsp_name, errno));
+ fsp_str_dbg(fsp), errno));
return false;
}
/* Only continue if this is a synthetic ACL and a directory. */
if (S_ISDIR(sbuf.st_ex_mode) &&
(sbuf.st_ex_flags & SF_HASNTFSACL) == 0) {
- struct smb_filename *smb_fname = NULL;
struct ifs_ace new_aces[6];
struct ifs_ace *old_aces;
int i, num_aces_to_add = 0;
mode_t file_mode = 0, dir_mode = 0;
- NTSTATUS status;
-
- status = create_synthetic_smb_fname_split(talloc_tos(),
- fsp->fsp_name, NULL,
- &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- return false;
- }
/* Use existing samba logic to derive the mode bits. */
- file_mode = unix_mode(fsp->conn, 0, smb_fname, NULL);
- dir_mode = unix_mode(fsp->conn, aDIR, smb_fname, NULL);
-
- TALLOC_FREE(smb_fname);
+ file_mode = unix_mode(fsp->conn, 0, fsp->fsp_name, NULL);
+ dir_mode = unix_mode(fsp->conn, aDIR, fsp->fsp_name, NULL);
/* Initialize ACEs. */
new_aces[0] = onefs_init_ace(fsp->conn, file_mode, false, USR);
@@ -631,18 +620,18 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
*ppdesc = NULL;
DEBUG(5, ("Getting sd for file %s. security_info=%u\n",
- fsp->fsp_name, security_info));
+ fsp_str_dbg(fsp), security_info));
if (lp_parm_bool(SNUM(fsp->conn), PARM_ONEFS_TYPE,
PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) {
- DEBUG(5, ("Ignoring SACL on %s.\n", fsp->fsp_name));
+ DEBUG(5, ("Ignoring SACL on %s.\n", fsp_str_dbg(fsp)));
security_info &= ~SACL_SECURITY_INFORMATION;
}
if (fsp->fh->fd == -1) {
if ((fsp->fh->fd = onefs_sys_create_file(handle->conn,
-1,
- fsp->fsp_name,
+ fsp->fsp_name->base_name,
0,
0,
0,
@@ -655,7 +644,7 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
0,
NULL)) == -1) {
DEBUG(0, ("Error opening file %s. errno=%d (%s)\n",
- fsp->fsp_name, errno, strerror(errno)));
+ fsp_str_dbg(fsp), errno, strerror(errno)));
status = map_nt_error_from_unix(errno);
goto out;
}
@@ -801,6 +790,7 @@ onefs_get_nt_acl(vfs_handle_struct *handle, const char* name,
{
files_struct finfo;
struct fd_handle fh;
+ NTSTATUS status;
ZERO_STRUCT(finfo);
ZERO_STRUCT(fh);
@@ -809,9 +799,16 @@ onefs_get_nt_acl(vfs_handle_struct *handle, const char* name,
finfo.conn = handle->conn;
finfo.fh = &fh;
finfo.fh->fd = -1;
- finfo.fsp_name = CONST_DISCARD(char *, name);
+ status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
+ &finfo.fsp_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
- return onefs_fget_nt_acl(handle, &finfo, security_info, ppdesc);
+ status = onefs_fget_nt_acl(handle, &finfo, security_info, ppdesc);
+
+ TALLOC_FREE(finfo.fsp_name);
+ return status;
}
/**
@@ -918,7 +915,7 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
START_PROFILE(syscall_set_sd);
- DEBUG(5,("Setting SD on file %s.\n", fsp->fsp_name ));
+ DEBUG(5,("Setting SD on file %s.\n", fsp_str_dbg(fsp)));
status = onefs_samba_sd_to_sd(sec_info_sent, psd, &sd,
SNUM(handle->conn), &sec_info_effective);
@@ -930,10 +927,10 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
fd = fsp->fh->fd;
if (fd == -1) {
- DEBUG(10,("Reopening file %s.\n", fsp->fsp_name));
+ DEBUG(10,("Reopening file %s.\n", fsp_str_dbg(fsp)));
if ((fd = onefs_sys_create_file(handle->conn,
-1,
- fsp->fsp_name,
+ fsp->fsp_name->base_name,
0,
0,
0,
@@ -946,7 +943,7 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
0,
NULL)) == -1) {
DEBUG(0, ("Error opening file %s. errno=%d (%s)\n",
- fsp->fsp_name, errno, strerror(errno)));
+ fsp_str_dbg(fsp), errno, strerror(errno)));
status = map_nt_error_from_unix(errno);
goto out;
}
diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c
index b51d516956..31f27e907a 100644
--- a/source3/modules/onefs_open.c
+++ b/source3/modules/onefs_open.c
@@ -81,7 +81,6 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
struct security_descriptor *sd,
int *granted_oplock)
{
- char *path = NULL;
struct smb_filename *smb_fname_onefs = NULL;
NTSTATUS status = NT_STATUS_OK;
int accmode = (flags & O_ACCMODE);
@@ -157,7 +156,7 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
* wildcard characters are allowed in stream names
* only test the basefilename
*/
- wild = fsp->base_fsp->fsp_name;
+ wild = fsp->base_fsp->fsp_name->base_name;
} else {
wild = smb_fname->base_name;
}
@@ -323,15 +322,13 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
fsp->aio_write_behind = True;
}
- status = get_full_smb_filename(talloc_tos(), smb_fname,
- &path);
+ status = fsp_set_smb_fname(fsp, smb_fname);
if (!NT_STATUS_IS_OK(status)) {
+ fd_close(fsp);
+ errno = map_errno_from_nt_status(status);
return status;
}
- string_set(&fsp->fsp_name, path);
- TALLOC_FREE(path);
-
fsp->wcp = NULL; /* Write cache pointer. */
DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
@@ -1592,7 +1589,12 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
fsp->is_directory = True;
fsp->posix_open = posix_open;
- string_set(&fsp->fsp_name, smb_dname->base_name);
+ status = fsp_set_smb_fname(fsp, smb_dname);
+ if (!NT_STATUS_IS_OK(status)) {
+ fd_close(fsp);
+ file_free(req, fsp);
+ return status;
+ }
mtimespec = smb_dname->st.st_ex_mtime;
diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c
index ded7dc672d..66eda57a34 100644
--- a/source3/modules/onefs_streams.c
+++ b/source3/modules/onefs_streams.c
@@ -376,7 +376,7 @@ int onefs_fstat(vfs_handle_struct *handle, struct files_struct *fsp,
}
}
- onefs_adjust_stat_time(handle->conn, fsp->fsp_name, sbuf);
+ onefs_adjust_stat_time(handle->conn, fsp->fsp_name->base_name, sbuf);
return ret;
}
@@ -600,7 +600,11 @@ static NTSTATUS walk_onefs_streams(connection_struct *conn, files_struct *fsp,
fake_fs.conn = conn;
fake_fs.fh = &fake_fh;
- fake_fs.fsp_name = SMB_STRDUP(fname);
+ status = create_synthetic_smb_fname(talloc_tos(), fname, NULL, NULL,
+ &fake_fs.fsp_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
/* Iterate over the streams in the ADS directory. */
while ((dp = SMB_VFS_READDIR(conn, dirp, NULL)) != NULL) {
@@ -667,7 +671,7 @@ out:
close(base_fd);
}
- SAFE_FREE(fake_fs.fsp_name);
+ TALLOC_FREE(fake_fs.fsp_name);
return status;
}
diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c
index 64ad3e1a78..ce84bd0e3a 100644
--- a/source3/modules/vfs_acl_tdb.c
+++ b/source3/modules/vfs_acl_tdb.c
@@ -272,27 +272,24 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
{
uint8 id_buf[16];
struct file_id id;
- SMB_STRUCT_STAT sbuf;
TDB_DATA data;
struct db_context *db;
struct db_record *rec;
int ret = -1;
DEBUG(10,("store_acl_blob_fsp: storing blob length %u on file %s\n",
- (unsigned int)pblob->length, fsp->fsp_name));
+ (unsigned int)pblob->length, fsp_str_dbg(fsp)));
SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
return NT_STATUS_INTERNAL_DB_CORRUPTION);
if (fsp->fh->fd != -1) {
- ret = SMB_VFS_FSTAT(fsp, &sbuf);
+ ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
} else {
if (fsp->posix_open) {
- ret = vfs_lstat_smb_fname(handle->conn, fsp->fsp_name,
- &sbuf);
+ ret = SMB_VFS_LSTAT(handle->conn, fsp->fsp_name);
} else {
- ret = vfs_stat_smb_fname(handle->conn, fsp->fsp_name,
- &sbuf);
+ ret = SMB_VFS_STAT(handle->conn, fsp->fsp_name);
}
}
@@ -300,7 +297,7 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
return map_nt_error_from_unix(errno);
}
- id = vfs_file_id_from_sbuf(handle->conn, &sbuf);
+ id = vfs_file_id_from_sbuf(handle->conn, &fsp->fsp_name->st);
/* For backwards compatibility only store the dev/inode. */
push_file_id_16((char *)id_buf, &id);
@@ -381,7 +378,7 @@ static NTSTATUS get_nt_acl_tdb_internal(vfs_handle_struct *handle,
NTSTATUS status;
if (fsp && name == NULL) {
- name = fsp->fsp_name;
+ name = fsp->fsp_name->base_name;
}
DEBUG(10, ("get_nt_acl_tdb_internal: name=%s\n", name));
@@ -450,7 +447,7 @@ static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx,
*********************************************************************/
static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
- const char *fname,
+ struct smb_filename *smb_fname,
files_struct *fsp,
bool container)
{
@@ -462,7 +459,7 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
size_t size;
char *parent_name;
- if (!parent_dirname(ctx, fname, &parent_name, NULL)) {
+ if (!parent_dirname(ctx, smb_fname->base_name, &parent_name, NULL)) {
return NT_STATUS_NO_MEMORY;
}
@@ -508,25 +505,22 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
}
if (!psd || psd->dacl == NULL) {
- SMB_STRUCT_STAT sbuf;
int ret;
TALLOC_FREE(psd);
if (fsp && !fsp->is_directory && fsp->fh->fd != -1) {
- ret = SMB_VFS_FSTAT(fsp, &sbuf);
+ ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
} else {
if (fsp && fsp->posix_open) {
- ret = vfs_lstat_smb_fname(handle->conn,fname,
- &sbuf);
+ ret = SMB_VFS_LSTAT(handle->conn, smb_fname);
} else {
- ret = vfs_stat_smb_fname(handle->conn,fname,
- &sbuf);
+ ret = SMB_VFS_STAT(handle->conn, smb_fname);
}
}
if (ret == -1) {
return map_nt_error_from_unix(errno);
}
- psd = default_file_sd(ctx, &sbuf);
+ psd = default_file_sd(ctx, &smb_fname->st);
if (!psd) {
return NT_STATUS_NO_MEMORY;
}
@@ -544,7 +538,8 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
if (fsp) {
return store_acl_blob_fsp(handle, fsp, &blob);
} else {
- return store_acl_blob_pathname(handle, fname, &blob);
+ return store_acl_blob_pathname(handle, smb_fname->base_name,
+ &blob);
}
}
@@ -561,19 +556,11 @@ static int open_acl_tdb(vfs_handle_struct *handle,
uint32_t access_granted = 0;
struct security_descriptor *pdesc = NULL;
bool file_existed = true;
- char *fname = NULL;
NTSTATUS status;
- status = get_full_smb_filename(talloc_tos(), smb_fname,
- &fname);
- if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- return -1;
- }
-
status = get_nt_acl_tdb_internal(handle,
NULL,
- fname,
+ smb_fname->base_name,
(OWNER_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION),
@@ -605,10 +592,13 @@ static int open_acl_tdb(vfs_handle_struct *handle,
if (!file_existed && fsp->fh->fd != -1) {
/* File was created. Inherit from parent directory. */
- string_set(&fsp->fsp_name, fname);
- inherit_new_acl(handle, fname, fsp, false);
+ status = fsp_set_smb_fname(fsp, smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
+ inherit_new_acl(handle, smb_fname, fsp, false);
}
-
return fsp->fh->fd;
}
@@ -659,13 +649,24 @@ static int unlink_acl_tdb(vfs_handle_struct *handle,
static int mkdir_acl_tdb(vfs_handle_struct *handle, const char *path, mode_t mode)
{
+ struct smb_filename *smb_fname = NULL;
int ret = SMB_VFS_NEXT_MKDIR(handle, path, mode);
+ NTSTATUS status;
if (ret == -1) {
return ret;
}
+
+ status = create_synthetic_smb_fname(talloc_tos(), path, NULL, NULL,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
+
/* New directory - inherit from parent. */
- inherit_new_acl(handle, path, NULL, true);
+ inherit_new_acl(handle, smb_fname, NULL, true);
+ TALLOC_FREE(smb_fname);
return ret;
}
@@ -713,15 +714,14 @@ static NTSTATUS fget_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp,
if (NT_STATUS_IS_OK(status)) {
if (DEBUGLEVEL >= 10) {
DEBUG(10,("fget_nt_acl_tdb: returning tdb sd for file %s\n",
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
NDR_PRINT_DEBUG(security_descriptor, *ppdesc);
}
return NT_STATUS_OK;
}
DEBUG(10,("fget_nt_acl_tdb: failed to get tdb sd for file %s, Error %s\n",
- fsp->fsp_name,
- nt_errstr(status) ));
+ fsp_str_dbg(fsp), nt_errstr(status)));
return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp,
security_info, ppdesc);
@@ -765,7 +765,7 @@ static NTSTATUS fset_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp,
if (DEBUGLEVEL >= 10) {
DEBUG(10,("fset_nt_acl_tdb: incoming sd for file %s\n",
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
NDR_PRINT_DEBUG(security_descriptor,
CONST_DISCARD(struct security_descriptor *,psd));
}
@@ -778,7 +778,6 @@ static NTSTATUS fset_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp,
/* Ensure owner and group are set. */
if (!psd->owner_sid || !psd->group_sid) {
int ret;
- SMB_STRUCT_STAT sbuf;
DOM_SID owner_sid, group_sid;
struct security_descriptor *nc_psd = dup_sec_desc(talloc_tos(), psd);
@@ -787,23 +786,19 @@ static NTSTATUS fset_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp,
}
if (fsp->is_directory || fsp->fh->fd == -1) {
if (fsp->posix_open) {
- ret = vfs_lstat_smb_fname(fsp->conn,
- fsp->fsp_name,
- &sbuf);
+ ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
} else {
- ret = vfs_stat_smb_fname(fsp->conn,
- fsp->fsp_name,
- &sbuf);
+ ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
}
} else {
- ret = SMB_VFS_FSTAT(fsp, &sbuf);
+ ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
}
if (ret == -1) {
/* Lower level acl set succeeded,
* so still return OK. */
return NT_STATUS_OK;
}
- create_file_sids(&sbuf, &owner_sid, &group_sid);
+ create_file_sids(&fsp->fsp_name->st, &owner_sid, &group_sid);
/* This is safe as nc_psd is discarded at fn exit. */
nc_psd->owner_sid = &owner_sid;
nc_psd->group_sid = &group_sid;
@@ -831,7 +826,7 @@ static NTSTATUS fset_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp,
if (DEBUGLEVEL >= 10) {
DEBUG(10,("fset_nt_acl_tdb: storing tdb sd for file %s\n",
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
NDR_PRINT_DEBUG(security_descriptor,
CONST_DISCARD(struct security_descriptor *,psd));
}
@@ -913,7 +908,6 @@ static int sys_acl_set_fd_tdb(vfs_handle_struct *handle,
files_struct *fsp,
SMB_ACL_T theacl)
{
- SMB_STRUCT_STAT sbuf;
struct db_context *db;
int ret;
@@ -921,14 +915,12 @@ static int sys_acl_set_fd_tdb(vfs_handle_struct *handle,
if (fsp->is_directory || fsp->fh->fd == -1) {
if (fsp->posix_open) {
- ret = vfs_lstat_smb_fname(fsp->conn,fsp->fsp_name,
- &sbuf);
+ ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
} else {
- ret = vfs_stat_smb_fname(fsp->conn,fsp->fsp_name,
- &sbuf);
+ ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
}
} else {
- ret = SMB_VFS_FSTAT(fsp, &sbuf);
+ ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
}
if (ret == -1) {
return -1;
@@ -941,7 +933,7 @@ static int sys_acl_set_fd_tdb(vfs_handle_struct *handle,
return -1;
}
- acl_tdb_delete(handle, db, &sbuf);
+ acl_tdb_delete(handle, db, &fsp->fsp_name->st);
return 0;
}
diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c
index 66bf21c4f7..b18bc658ff 100644
--- a/source3/modules/vfs_acl_xattr.c
+++ b/source3/modules/vfs_acl_xattr.c
@@ -27,13 +27,45 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_VFS
+static NTSTATUS create_acl_blob(const struct security_descriptor *psd,
+ DATA_BLOB *pblob,
+ uint8_t hash[16]);
+
+#define HASH_SECURITY_INFO (OWNER_SECURITY_INFORMATION | \
+ GROUP_SECURITY_INFORMATION | \
+ DACL_SECURITY_INFORMATION | \
+ SACL_SECURITY_INFORMATION)
+
+/*******************************************************************
+ Hash a security descriptor.
+*******************************************************************/
+
+static NTSTATUS hash_sd(struct security_descriptor *psd,
+ uint8_t hash[16])
+{
+ DATA_BLOB blob;
+ struct MD5Context tctx;
+ NTSTATUS status;
+
+ memset(hash, '\0', 16);
+ status = create_acl_blob(psd, &blob, hash);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ MD5Init(&tctx);
+ MD5Update(&tctx, blob.data, blob.length);
+ MD5Final(hash, &tctx);
+ return NT_STATUS_OK;
+}
+
/*******************************************************************
Parse out a struct security_descriptor from a DATA_BLOB.
*******************************************************************/
static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob,
uint32 security_info,
- struct security_descriptor **ppdesc)
+ struct security_descriptor **ppdesc,
+ uint8_t hash[16])
{
TALLOC_CTX *ctx = talloc_tos();
struct xattr_NTACL xacl;
@@ -64,6 +96,7 @@ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob,
? xacl.info.sd_hs->sd->dacl : NULL,
&sd_size);
+ memcpy(hash, xacl.info.sd_hs->hash, 16);
TALLOC_FREE(xacl.info.sd);
return (*ppdesc != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
@@ -131,7 +164,9 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
Create a DATA_BLOB from a security descriptor.
*******************************************************************/
-static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB *pblob)
+static NTSTATUS create_acl_blob(const struct security_descriptor *psd,
+ DATA_BLOB *pblob,
+ uint8_t hash[16])
{
struct xattr_NTACL xacl;
struct security_descriptor_hash sd_hs;
@@ -144,7 +179,7 @@ static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB
xacl.version = 2;
xacl.info.sd_hs = &sd_hs;
xacl.info.sd_hs->sd = CONST_DISCARD(struct security_descriptor *, psd);
- memset(&xacl.info.sd_hs->hash[0], '\0', 16);
+ memcpy(&xacl.info.sd_hs->hash[0], hash, 16);
ndr_err = ndr_push_struct_blob(
pblob, ctx, NULL, &xacl,
@@ -171,14 +206,14 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
int saved_errno = 0;
DEBUG(10,("store_acl_blob_fsp: storing blob length %u on file %s\n",
- (unsigned int)pblob->length, fsp->fsp_name));
+ (unsigned int)pblob->length, fsp_str_dbg(fsp)));
become_root();
if (fsp->fh->fd != -1) {
ret = SMB_VFS_FSETXATTR(fsp, XATTR_NTACL_NAME,
pblob->data, pblob->length, 0);
} else {
- ret = SMB_VFS_SETXATTR(fsp->conn, fsp->fsp_name,
+ ret = SMB_VFS_SETXATTR(fsp->conn, fsp->fsp_name->base_name,
XATTR_NTACL_NAME,
pblob->data, pblob->length, 0);
}
@@ -190,7 +225,7 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
errno = saved_errno;
DEBUG(5, ("store_acl_blob_fsp: setting attr failed for file %s"
"with error %s\n",
- fsp->fsp_name,
+ fsp_str_dbg(fsp),
strerror(errno) ));
return map_nt_error_from_unix(errno);
}
@@ -242,29 +277,86 @@ static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle,
uint32 security_info,
struct security_descriptor **ppdesc)
{
- TALLOC_CTX *ctx = talloc_tos();
DATA_BLOB blob;
NTSTATUS status;
+ uint8_t hash[16];
+ uint8_t hash_tmp[16];
+ struct security_descriptor *pdesc_next = NULL;
if (fsp && name == NULL) {
- name = fsp->fsp_name;
+ name = fsp->fsp_name->base_name;
}
DEBUG(10, ("get_nt_acl_xattr_internal: name=%s\n", name));
- status = get_acl_blob(ctx, handle, fsp, name, &blob);
+ status = get_acl_blob(talloc_tos(), handle, fsp, name, &blob);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("get_acl_blob returned %s\n", nt_errstr(status)));
return status;
}
- status = parse_acl_blob(&blob, security_info, ppdesc);
+ status = parse_acl_blob(&blob, security_info, ppdesc, &hash[0]);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("parse_acl_blob returned %s\n",
nt_errstr(status)));
return status;
}
+ /* If there was no stored hash, don't check. */
+ memset(&hash_tmp[0], '\0', 16);
+ if (memcmp(&hash[0], &hash_tmp[0], 16) == 0) {
+ /* No hash, goto return blob sd. */
+ goto out;
+ }
+
+ /* Get the full underlying sd, then hash. */
+ if (fsp) {
+ status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
+ fsp,
+ HASH_SECURITY_INFO,
+ &pdesc_next);
+ } else {
+ status = SMB_VFS_NEXT_GET_NT_ACL(handle,
+ name,
+ HASH_SECURITY_INFO,
+ &pdesc_next);
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+
+ status = hash_sd(pdesc_next, hash_tmp);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+
+ if (memcmp(&hash[0], &hash_tmp[0], 16) == 0) {
+ TALLOC_FREE(pdesc_next);
+ /* Hash matches, return blob sd. */
+ goto out;
+ }
+
+ /* Hash doesn't match, return underlying sd. */
+
+ if (!(security_info & OWNER_SECURITY_INFORMATION)) {
+ pdesc_next->owner_sid = NULL;
+ }
+ if (!(security_info & GROUP_SECURITY_INFORMATION)) {
+ pdesc_next->group_sid = NULL;
+ }
+ if (!(security_info & DACL_SECURITY_INFORMATION)) {
+ pdesc_next->dacl = NULL;
+ }
+ if (!(security_info & SACL_SECURITY_INFORMATION)) {
+ pdesc_next->sacl = NULL;
+ }
+
+ TALLOC_FREE(*ppdesc);
+ *ppdesc = pdesc_next;
+
+ out:
+
TALLOC_FREE(blob.data);
return status;
}
@@ -316,7 +408,7 @@ static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx,
*********************************************************************/
static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
- const char *fname,
+ struct smb_filename *smb_fname,
files_struct *fsp,
bool container)
{
@@ -324,11 +416,13 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
NTSTATUS status;
struct security_descriptor *parent_desc = NULL;
struct security_descriptor *psd = NULL;
+ struct security_descriptor *pdesc_next = NULL;
DATA_BLOB blob;
size_t size;
char *parent_name;
+ uint8_t hash[16];
- if (!parent_dirname(ctx, fname, &parent_name, NULL)) {
+ if (!parent_dirname(ctx, smb_fname->base_name, &parent_name, NULL)) {
return NT_STATUS_NO_MEMORY;
}
@@ -374,25 +468,22 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
}
if (!psd || psd->dacl == NULL) {
- SMB_STRUCT_STAT sbuf;
int ret;
TALLOC_FREE(psd);
if (fsp && !fsp->is_directory && fsp->fh->fd != -1) {
- ret = SMB_VFS_FSTAT(fsp, &sbuf);
+ ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
} else {
if (fsp && fsp->posix_open) {
- ret = vfs_lstat_smb_fname(handle->conn, fname,
- &sbuf);
+ ret = SMB_VFS_LSTAT(handle->conn, smb_fname);
} else {
- ret = vfs_stat_smb_fname(handle->conn, fname,
- &sbuf);
+ ret = SMB_VFS_STAT(handle->conn, smb_fname);
}
}
if (ret == -1) {
return map_nt_error_from_unix(errno);
}
- psd = default_file_sd(ctx, &sbuf);
+ psd = default_file_sd(ctx, &smb_fname->st);
if (!psd) {
return NT_STATUS_NO_MEMORY;
}
@@ -403,14 +494,36 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
}
}
- status = create_acl_blob(psd, &blob);
+ /* Object exists. Read the current SD to get the hash. */
+ if (fsp) {
+ status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
+ fsp,
+ HASH_SECURITY_INFO,
+ &pdesc_next);
+ } else {
+ status = SMB_VFS_NEXT_GET_NT_ACL(handle,
+ smb_fname->base_name,
+ HASH_SECURITY_INFO,
+ &pdesc_next);
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = hash_sd(pdesc_next, hash);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ status = create_acl_blob(psd, &blob, hash);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
if (fsp) {
return store_acl_blob_fsp(handle, fsp, &blob);
} else {
- return store_acl_blob_pathname(handle, fname, &blob);
+ return store_acl_blob_pathname(handle, smb_fname->base_name,
+ &blob);
}
}
@@ -430,6 +543,13 @@ static int open_acl_xattr(vfs_handle_struct *handle,
char *fname = NULL;
NTSTATUS status;
+ if (fsp->base_fsp) {
+ /* Stream open. Base filename open already did the ACL check. */
+ DEBUG(10,("open_acl_xattr: stream open on %s\n",
+ smb_fname_str_dbg(smb_fname) ));
+ return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
+ }
+
status = get_full_smb_filename(talloc_tos(), smb_fname,
&fname);
if (!NT_STATUS_IS_OK(status)) {
@@ -471,8 +591,12 @@ static int open_acl_xattr(vfs_handle_struct *handle,
if (!file_existed && fsp->fh->fd != -1) {
/* File was created. Inherit from parent directory. */
- string_set(&fsp->fsp_name, fname);
- inherit_new_acl(handle, fname, fsp, false);
+ status = fsp_set_smb_fname(fsp, smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
+ inherit_new_acl(handle, smb_fname, fsp, false);
}
return fsp->fh->fd;
@@ -480,13 +604,24 @@ static int open_acl_xattr(vfs_handle_struct *handle,
static int mkdir_acl_xattr(vfs_handle_struct *handle, const char *path, mode_t mode)
{
+ struct smb_filename *smb_fname = NULL;
int ret = SMB_VFS_NEXT_MKDIR(handle, path, mode);
+ NTSTATUS status;
if (ret == -1) {
return ret;
}
+
+ status = create_synthetic_smb_fname(talloc_tos(), path, NULL, NULL,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
+
/* New directory - inherit from parent. */
- inherit_new_acl(handle, path, NULL, true);
+ inherit_new_acl(handle, smb_fname, NULL, true);
+ TALLOC_FREE(smb_fname);
return ret;
}
@@ -497,23 +632,8 @@ static int mkdir_acl_xattr(vfs_handle_struct *handle, const char *path, mode_t m
static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
uint32 security_info, struct security_descriptor **ppdesc)
{
- NTSTATUS status = get_nt_acl_xattr_internal(handle, fsp,
+ return get_nt_acl_xattr_internal(handle, fsp,
NULL, security_info, ppdesc);
- if (NT_STATUS_IS_OK(status)) {
- if (DEBUGLEVEL >= 10) {
- DEBUG(10,("fget_nt_acl_xattr: returning xattr sd for file %s\n",
- fsp->fsp_name));
- NDR_PRINT_DEBUG(security_descriptor, *ppdesc);
- }
- return NT_STATUS_OK;
- }
-
- DEBUG(10,("fget_nt_acl_xattr: failed to get xattr sd for file %s, Error %s\n",
- fsp->fsp_name,
- nt_errstr(status) ));
-
- return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp,
- security_info, ppdesc);
}
/*********************************************************************
@@ -523,23 +643,8 @@ static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
static NTSTATUS get_nt_acl_xattr(vfs_handle_struct *handle,
const char *name, uint32 security_info, struct security_descriptor **ppdesc)
{
- NTSTATUS status = get_nt_acl_xattr_internal(handle, NULL,
+ return get_nt_acl_xattr_internal(handle, NULL,
name, security_info, ppdesc);
- if (NT_STATUS_IS_OK(status)) {
- if (DEBUGLEVEL >= 10) {
- DEBUG(10,("get_nt_acl_xattr: returning xattr sd for file %s\n",
- name));
- NDR_PRINT_DEBUG(security_descriptor, *ppdesc);
- }
- return NT_STATUS_OK;
- }
-
- DEBUG(10,("get_nt_acl_xattr: failed to get xattr sd for file %s, Error %s\n",
- name,
- nt_errstr(status) ));
-
- return SMB_VFS_NEXT_GET_NT_ACL(handle, name,
- security_info, ppdesc);
}
/*********************************************************************
@@ -551,23 +656,19 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
{
NTSTATUS status;
DATA_BLOB blob;
+ struct security_descriptor *pdesc_next = NULL;
+ uint8_t hash[16];
if (DEBUGLEVEL >= 10) {
DEBUG(10,("fset_nt_acl_xattr: incoming sd for file %s\n",
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
NDR_PRINT_DEBUG(security_descriptor,
CONST_DISCARD(struct security_descriptor *,psd));
}
- status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
/* Ensure owner and group are set. */
if (!psd->owner_sid || !psd->group_sid) {
int ret;
- SMB_STRUCT_STAT sbuf;
DOM_SID owner_sid, group_sid;
struct security_descriptor *nc_psd = dup_sec_desc(talloc_tos(), psd);
@@ -576,23 +677,19 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
}
if (fsp->is_directory || fsp->fh->fd == -1) {
if (fsp->posix_open) {
- ret = vfs_lstat_smb_fname(fsp->conn,
- fsp->fsp_name,
- &sbuf);
+ ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
} else {
- ret = vfs_stat_smb_fname(fsp->conn,
- fsp->fsp_name,
- &sbuf);
+ ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
}
} else {
- ret = SMB_VFS_FSTAT(fsp, &sbuf);
+ ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
}
if (ret == -1) {
/* Lower level acl set succeeded,
* so still return OK. */
return NT_STATUS_OK;
}
- create_file_sids(&sbuf, &owner_sid, &group_sid);
+ create_file_sids(&fsp->fsp_name->st, &owner_sid, &group_sid);
/* This is safe as nc_psd is discarded at fn exit. */
nc_psd->owner_sid = &owner_sid;
nc_psd->group_sid = &group_sid;
@@ -600,6 +697,26 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
psd = nc_psd;
}
+ status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ /* Get the full underlying sd, then hash. */
+ status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
+ fsp,
+ HASH_SECURITY_INFO,
+ &pdesc_next);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = hash_sd(pdesc_next, hash);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
#if 0
if ((security_info_sent & DACL_SECURITY_INFORMATION) &&
psd->dacl != NULL &&
@@ -620,11 +737,11 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
if (DEBUGLEVEL >= 10) {
DEBUG(10,("fset_nt_acl_xattr: storing xattr sd for file %s\n",
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
NDR_PRINT_DEBUG(security_descriptor,
CONST_DISCARD(struct security_descriptor *,psd));
}
- create_acl_blob(psd, &blob);
+ create_acl_blob(psd, &blob, hash);
store_acl_blob_fsp(handle, fsp, &blob);
return NT_STATUS_OK;
diff --git a/source3/modules/vfs_afsacl.c b/source3/modules/vfs_afsacl.c
index 55371c60f5..e6f43c9680 100644
--- a/source3/modules/vfs_afsacl.c
+++ b/source3/modules/vfs_afsacl.c
@@ -655,18 +655,17 @@ static size_t afs_to_nt_acl_common(struct afs_acl *afs_acl,
static size_t afs_to_nt_acl(struct afs_acl *afs_acl,
struct connection_struct *conn,
- const char *name,
+ struct smb_filename *smb_fname,
uint32 security_info,
struct security_descriptor **ppdesc)
{
- SMB_STRUCT_STAT sbuf;
-
/* Get the stat struct for the owner info. */
- if(vfs_stat_smb_fname(conn, name, &sbuf) != 0) {
+ if(SMB_VFS_STAT(conn, smb_fname) != 0) {
return 0;
}
- return afs_to_nt_acl_common(afs_acl, &sbuf, security_info, ppdesc);
+ return afs_to_nt_acl_common(afs_acl, &smb_fname->st, security_info,
+ ppdesc);
}
static size_t afs_fto_nt_acl(struct afs_acl *afs_acl,
@@ -905,7 +904,7 @@ static NTSTATUS afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
ZERO_STRUCT(dir_acl);
ZERO_STRUCT(file_acl);
- name = talloc_strdup(talloc_tos(), fsp->fsp_name);
+ name = talloc_strdup(talloc_tos(), fsp->fsp_name->base_name);
if (!name) {
return NT_STATUS_NO_MEMORY;
}
@@ -925,7 +924,7 @@ static NTSTATUS afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
}
if (!afs_get_afs_acl(name, &old_afs_acl)) {
- DEBUG(3, ("Could not get old ACL of %s\n", fsp->fsp_name));
+ DEBUG(3, ("Could not get old ACL of %s\n", fsp_str_dbg(fsp)));
goto done;
}
@@ -941,7 +940,8 @@ static NTSTATUS afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
}
free_afs_acl(&dir_acl);
- if (!nt_to_afs_acl(fsp->fsp_name, security_info_sent, psd,
+ if (!nt_to_afs_acl(fsp->fsp_name->base_name,
+ security_info_sent, psd,
nt_to_afs_dir_rights, &dir_acl))
goto done;
} else {
@@ -956,7 +956,8 @@ static NTSTATUS afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
}
free_afs_acl(&file_acl);
- if (!nt_to_afs_acl(fsp->fsp_name, security_info_sent, psd,
+ if (!nt_to_afs_acl(fsp->fsp_name->base_name,
+ security_info_sent, psd,
nt_to_afs_file_rights, &file_acl))
goto done;
}
@@ -997,11 +998,11 @@ static NTSTATUS afsacl_fget_nt_acl(struct vfs_handle_struct *handle,
struct afs_acl acl;
size_t sd_size;
- DEBUG(5, ("afsacl_fget_nt_acl: %s\n", fsp->fsp_name));
+ DEBUG(5, ("afsacl_fget_nt_acl: %s\n", fsp_str_dbg(fsp)));
sidpts = lp_parm_bool(SNUM(fsp->conn), "afsacl", "sidpts", False);
- if (!afs_get_afs_acl(fsp->fsp_name, &acl)) {
+ if (!afs_get_afs_acl(fsp->fsp_name->base_name, &acl)) {
return NT_STATUS_ACCESS_DENIED;
}
@@ -1018,6 +1019,8 @@ static NTSTATUS afsacl_get_nt_acl(struct vfs_handle_struct *handle,
{
struct afs_acl acl;
size_t sd_size;
+ struct smb_filename *smb_fname = NULL;
+ NTSTATUS status;
DEBUG(5, ("afsacl_get_nt_acl: %s\n", name));
@@ -1027,8 +1030,16 @@ static NTSTATUS afsacl_get_nt_acl(struct vfs_handle_struct *handle,
return NT_STATUS_ACCESS_DENIED;
}
- sd_size = afs_to_nt_acl(&acl, handle->conn, name, security_info,
+ status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ free_afs_acl(&acl);
+ return status;
+ }
+
+ sd_size = afs_to_nt_acl(&acl, handle->conn, smb_fname, security_info,
ppdesc);
+ TALLOC_FREE(smb_fname);
free_afs_acl(&acl);
diff --git a/source3/modules/vfs_aixacl2.c b/source3/modules/vfs_aixacl2.c
index 5ebc3a12f8..01de33ed0b 100644
--- a/source3/modules/vfs_aixacl2.c
+++ b/source3/modules/vfs_aixacl2.c
@@ -162,7 +162,8 @@ static NTSTATUS aixjfs2_fget_nt_acl(vfs_handle_struct *handle,
bool retryPosix = False;
*ppdesc = NULL;
- result = aixjfs2_get_nfs4_acl(fsp->fsp_name, &pacl, &retryPosix);
+ result = aixjfs2_get_nfs4_acl(fsp->fsp_name->base_name, &pacl,
+ &retryPosix);
if (retryPosix)
{
DEBUG(10, ("retrying with posix acl...\n"));
@@ -258,7 +259,7 @@ SMB_ACL_T aixjfs2_sys_acl_get_fd(vfs_handle_struct *handle,
acl_type_t aixjfs2_type;
aixjfs2_type.u64 = ACL_AIXC;
- return aixjfs2_get_posix_acl(fsp->fsp_name, aixjfs2_type);
+ return aixjfs2_get_posix_acl(fsp->fsp_name->base_name, aixjfs2_type);
}
/*
@@ -304,7 +305,7 @@ static bool aixjfs2_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl)
int rc;
acl_type_t acltype;
- DEBUG(10, ("jfs2_process_smbacl invoked on %s\n", fsp->fsp_name));
+ DEBUG(10, ("jfs2_process_smbacl invoked on %s\n", fsp_str_dbg(fsp)));
/* no need to be freed which is alloced with mem_ctx */
mem_ctx = talloc_tos();
@@ -353,7 +354,7 @@ static bool aixjfs2_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl)
/* won't set S_ISUID - the only one JFS2/NFS4 accepts */
rc = aclx_put(
- fsp->fsp_name,
+ fsp->fsp_name->base_name,
SET_ACL, /* set only the ACL, not mode bits */
acltype, /* not a pointer !!! */
jfs2acl,
@@ -444,9 +445,10 @@ int aixjfs2_sys_acl_set_fd(vfs_handle_struct *handle,
acl_type_t acl_type_info;
int rc;
- DEBUG(10, ("aixjfs2_sys_acl_set_fd invoked for %s", fsp->fsp_name));
+ DEBUG(10, ("aixjfs2_sys_acl_set_fd invoked for %s", fsp_str_dbg(fsp)));
- rc = aixjfs2_query_acl_support(fsp->fsp_name, ACL_AIXC, &acl_type_info);
+ rc = aixjfs2_query_acl_support(fsp->fsp_name->base_name, ACL_AIXC,
+ &acl_type_info);
if (rc) {
DEBUG(8, ("jfs2_set_nt_acl: AIXC support not found\n"));
return -1;
@@ -466,7 +468,7 @@ int aixjfs2_sys_acl_set_fd(vfs_handle_struct *handle,
);
if (rc) {
DEBUG(2, ("aclx_fput failed with %s for %s\n",
- strerror(errno), fsp->fsp_name));
+ strerror(errno), fsp_str_dbg(fsp)));
return -1;
}
diff --git a/source3/modules/vfs_audit.c b/source3/modules/vfs_audit.c
index cf2e27301d..dab3d78cec 100644
--- a/source3/modules/vfs_audit.c
+++ b/source3/modules/vfs_audit.c
@@ -237,7 +237,7 @@ static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mod
result = SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
syslog(audit_syslog_priority(handle), "fchmod %s mode 0x%x %s%s\n",
- fsp->fsp_name, mode,
+ fsp->fsp_name->base_name, mode,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
@@ -251,7 +251,7 @@ static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t
result = SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode);
syslog(audit_syslog_priority(handle), "fchmod_acl %s mode 0x%x %s%s\n",
- fsp->fsp_name, mode,
+ fsp->fsp_name->base_name, mode,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
diff --git a/source3/modules/vfs_cacheprime.c b/source3/modules/vfs_cacheprime.c
index 71b850505a..3997dcbcfc 100644
--- a/source3/modules/vfs_cacheprime.c
+++ b/source3/modules/vfs_cacheprime.c
@@ -72,7 +72,7 @@ static bool prime_cache(
DEBUG(module_debug,
("%s: doing readahead of %lld bytes at %lld for %s\n",
MODULE, (long long)g_readsz, (long long)*last,
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
nread = sys_pread(fsp->fh->fd, g_readbuf, g_readsz, *last);
if (nread < 0) {
diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c
index 7e363b6be7..aa77da7cd7 100644
--- a/source3/modules/vfs_cap.c
+++ b/source3/modules/vfs_cap.c
@@ -53,7 +53,9 @@ static SMB_STRUCT_DIR *cap_opendir(vfs_handle_struct *handle, const char *fname,
return SMB_VFS_NEXT_OPENDIR(handle, capname, mask, attr);
}
-static SMB_STRUCT_DIRENT *cap_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp)
+static SMB_STRUCT_DIRENT *cap_readdir(vfs_handle_struct *handle,
+ SMB_STRUCT_DIR *dirp,
+ SMB_STRUCT_STAT *sbuf)
{
SMB_STRUCT_DIRENT *result;
SMB_STRUCT_DIRENT *newdirent;
@@ -334,7 +336,8 @@ static int cap_ntimes(vfs_handle_struct *handle,
}
-static bool cap_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
+static int cap_symlink(vfs_handle_struct *handle, const char *oldpath,
+ const char *newpath)
{
char *capold = capencode(talloc_tos(), oldpath);
char *capnew = capencode(talloc_tos(), newpath);
@@ -346,7 +349,8 @@ static bool cap_symlink(vfs_handle_struct *handle, const char *oldpath, const ch
return SMB_VFS_NEXT_SYMLINK(handle, capold, capnew);
}
-static bool cap_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz)
+static int cap_readlink(vfs_handle_struct *handle, const char *path,
+ char *buf, size_t bufsiz)
{
char *cappath = capencode(talloc_tos(), path);
diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c
index 1fd101282c..3b691c0350 100644
--- a/source3/modules/vfs_catia.c
+++ b/source3/modules/vfs_catia.c
@@ -103,7 +103,8 @@ static SMB_STRUCT_DIR *catia_opendir(vfs_handle_struct *handle,
}
static SMB_STRUCT_DIRENT *catia_readdir(vfs_handle_struct *handle,
- SMB_STRUCT_DIR *dirp)
+ SMB_STRUCT_DIR *dirp,
+ SMB_STRUCT_STAT *sbuf)
{
SMB_STRUCT_DIRENT *result = NULL;
SMB_STRUCT_DIRENT *newdirent = NULL;
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index c4db8fa393..cdfd28c571 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -218,27 +218,17 @@ static int vfswrap_open(vfs_handle_struct *handle,
struct smb_filename *smb_fname,
files_struct *fsp, int flags, mode_t mode)
{
- int result;
- NTSTATUS status;
- char *fname = NULL;
+ int result = -1;
START_PROFILE(syscall_open);
- /*
- * XXX: Should an error be returned if there is a stream rather than
- * trying to open a filename with a ':'?
- */
- status = get_full_smb_filename(talloc_tos(), smb_fname,
- &fname);
- if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- return -1;
+ if (smb_fname->stream_name) {
+ errno = ENOENT;
+ goto out;
}
- result = sys_open(fname, flags, mode);
-
- TALLOC_FREE(fname);
-
+ result = sys_open(smb_fname->base_name, flags, mode);
+ out:
END_PROFILE(syscall_open);
return result;
}
@@ -562,23 +552,17 @@ static int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp)
static int vfswrap_stat(vfs_handle_struct *handle,
struct smb_filename *smb_fname)
{
- int result;
- NTSTATUS status;
- char *fname = NULL;
+ int result = -1;
START_PROFILE(syscall_stat);
- status = get_full_smb_filename(talloc_tos(), smb_fname,
- &fname);
- if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- return -1;
+ if (smb_fname->stream_name) {
+ errno = ENOENT;
+ goto out;
}
- result = sys_stat(fname, &smb_fname->st);
-
- TALLOC_FREE(fname);
-
+ result = sys_stat(smb_fname->base_name, &smb_fname->st);
+ out:
END_PROFILE(syscall_stat);
return result;
}
@@ -596,23 +580,17 @@ static int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUC
static int vfswrap_lstat(vfs_handle_struct *handle,
struct smb_filename *smb_fname)
{
- int result;
- NTSTATUS status;
- char *fname = NULL;
+ int result = -1;
START_PROFILE(syscall_lstat);
- status = get_full_smb_filename(talloc_tos(), smb_fname,
- &fname);
- if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- return -1;
+ if (smb_fname->stream_name) {
+ errno = ENOENT;
+ goto out;
}
- result = sys_lstat(fname, &smb_fname->st);
-
- TALLOC_FREE(fname);
-
+ result = sys_lstat(smb_fname->base_name, &smb_fname->st);
+ out:
END_PROFILE(syscall_lstat);
return result;
}
@@ -866,7 +844,9 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs
uint64_t space_avail;
uint64_t bsize,dfree,dsize;
- space_avail = get_dfree_info(fsp->conn,fsp->fsp_name,false,&bsize,&dfree,&dsize);
+ space_avail = get_dfree_info(fsp->conn,
+ fsp->fsp_name->base_name, false,
+ &bsize, &dfree, &dsize);
/* space_avail is 1k blocks */
if (space_avail == (uint64_t)-1 ||
((uint64_t)space_to_write/1024 > space_avail) ) {
@@ -1102,7 +1082,8 @@ static NTSTATUS vfswrap_notify_watch(vfs_handle_struct *vfs_handle,
return NT_STATUS_OK;
}
-static int vfswrap_chflags(vfs_handle_struct *handle, const char *path, int flags)
+static int vfswrap_chflags(vfs_handle_struct *handle, const char *path,
+ unsigned int flags)
{
#ifdef HAVE_CHFLAGS
return chflags(path, flags);
@@ -1113,7 +1094,7 @@ static int vfswrap_chflags(vfs_handle_struct *handle, const char *path, int flag
}
static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle,
- SMB_STRUCT_STAT *sbuf)
+ const SMB_STRUCT_STAT *sbuf)
{
struct file_id key;
diff --git a/source3/modules/vfs_dirsort.c b/source3/modules/vfs_dirsort.c
index 53d1820c11..f6fc9256d0 100644
--- a/source3/modules/vfs_dirsort.c
+++ b/source3/modules/vfs_dirsort.c
@@ -113,7 +113,8 @@ static SMB_STRUCT_DIR *dirsort_opendir(vfs_handle_struct *handle,
}
static SMB_STRUCT_DIRENT *dirsort_readdir(vfs_handle_struct *handle,
- SMB_STRUCT_DIR *dirp)
+ SMB_STRUCT_DIR *dirp,
+ SMB_STRUCT_STAT *sbuf)
{
struct dirsort_privates *data = NULL;
time_t current_mtime;
diff --git a/source3/modules/vfs_extd_audit.c b/source3/modules/vfs_extd_audit.c
index 68b85516ea..c9d1862fa4 100644
--- a/source3/modules/vfs_extd_audit.c
+++ b/source3/modules/vfs_extd_audit.c
@@ -304,12 +304,12 @@ static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mod
if (lp_syslog() > 0) {
syslog(audit_syslog_priority(handle), "fchmod %s mode 0x%x %s%s\n",
- fsp->fsp_name, mode,
+ fsp->fsp_name->base_name, mode,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
}
DEBUG(1, ("vfs_extd_audit: fchmod %s mode 0x%x %s %s",
- fsp->fsp_name, (unsigned int)mode,
+ fsp_str_dbg(fsp), (unsigned int)mode,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : ""));
@@ -324,12 +324,12 @@ static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t
if (lp_syslog() > 0) {
syslog(audit_syslog_priority(handle), "fchmod_acl %s mode 0x%x %s%s\n",
- fsp->fsp_name, mode,
+ fsp->fsp_name->base_name, mode,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
}
DEBUG(1, ("vfs_extd_audit: fchmod_acl %s mode 0x%x %s %s",
- fsp->fsp_name, (unsigned int)mode,
+ fsp_str_dbg(fsp), (unsigned int)mode,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : ""));
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index e8702aa2c8..76fbc8a8ae 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -419,6 +419,13 @@ static const char *smb_fname_str_do_log(const struct smb_filename *smb_fname)
return fname;
}
+/**
+ * Return an fsp debug string using the do_log_ctx()
+ */
+static const char *fsp_str_do_log(const struct files_struct *fsp)
+{
+ return smb_fname_str_do_log(fsp->fsp_name);
+}
/* Free function for the private data. */
@@ -561,7 +568,7 @@ static int smb_full_audit_statvfs(struct vfs_handle_struct *handle,
return result;
}
-static int smb_full_audit_fs_capabilities(struct vfs_handle_struct *handle)
+static uint32_t smb_full_audit_fs_capabilities(struct vfs_handle_struct *handle)
{
int result;
@@ -736,7 +743,8 @@ static int smb_full_audit_close(vfs_handle_struct *handle, files_struct *fsp)
result = SMB_VFS_NEXT_CLOSE(handle, fsp);
- do_log(SMB_VFS_OP_CLOSE, (result >= 0), handle, "%s", fsp->fsp_name);
+ do_log(SMB_VFS_OP_CLOSE, (result >= 0), handle, "%s",
+ fsp_str_do_log(fsp));
return result;
}
@@ -748,7 +756,8 @@ static ssize_t smb_full_audit_read(vfs_handle_struct *handle, files_struct *fsp,
result = SMB_VFS_NEXT_READ(handle, fsp, data, n);
- do_log(SMB_VFS_OP_READ, (result >= 0), handle, "%s", fsp->fsp_name);
+ do_log(SMB_VFS_OP_READ, (result >= 0), handle, "%s",
+ fsp_str_do_log(fsp));
return result;
}
@@ -760,7 +769,8 @@ static ssize_t smb_full_audit_pread(vfs_handle_struct *handle, files_struct *fsp
result = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
- do_log(SMB_VFS_OP_PREAD, (result >= 0), handle, "%s", fsp->fsp_name);
+ do_log(SMB_VFS_OP_PREAD, (result >= 0), handle, "%s",
+ fsp_str_do_log(fsp));
return result;
}
@@ -772,7 +782,8 @@ static ssize_t smb_full_audit_write(vfs_handle_struct *handle, files_struct *fsp
result = SMB_VFS_NEXT_WRITE(handle, fsp, data, n);
- do_log(SMB_VFS_OP_WRITE, (result >= 0), handle, "%s", fsp->fsp_name);
+ do_log(SMB_VFS_OP_WRITE, (result >= 0), handle, "%s",
+ fsp_str_do_log(fsp));
return result;
}
@@ -785,7 +796,8 @@ static ssize_t smb_full_audit_pwrite(vfs_handle_struct *handle, files_struct *fs
result = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
- do_log(SMB_VFS_OP_PWRITE, (result >= 0), handle, "%s", fsp->fsp_name);
+ do_log(SMB_VFS_OP_PWRITE, (result >= 0), handle, "%s",
+ fsp_str_do_log(fsp));
return result;
}
@@ -798,7 +810,7 @@ static SMB_OFF_T smb_full_audit_lseek(vfs_handle_struct *handle, files_struct *f
result = SMB_VFS_NEXT_LSEEK(handle, fsp, offset, whence);
do_log(SMB_VFS_OP_LSEEK, (result != (ssize_t)-1), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
@@ -813,7 +825,7 @@ static ssize_t smb_full_audit_sendfile(vfs_handle_struct *handle, int tofd,
result = SMB_VFS_NEXT_SENDFILE(handle, tofd, fromfsp, hdr, offset, n);
do_log(SMB_VFS_OP_SENDFILE, (result >= 0), handle,
- "%s", fromfsp->fsp_name);
+ "%s", fsp_str_do_log(fromfsp));
return result;
}
@@ -828,7 +840,7 @@ static ssize_t smb_full_audit_recvfile(vfs_handle_struct *handle, int fromfd,
result = SMB_VFS_NEXT_RECVFILE(handle, fromfd, tofsp, offset, n);
do_log(SMB_VFS_OP_RECVFILE, (result >= 0), handle,
- "%s", tofsp->fsp_name);
+ "%s", fsp_str_do_log(tofsp));
return result;
}
@@ -854,7 +866,8 @@ static int smb_full_audit_fsync(vfs_handle_struct *handle, files_struct *fsp)
result = SMB_VFS_NEXT_FSYNC(handle, fsp);
- do_log(SMB_VFS_OP_FSYNC, (result >= 0), handle, "%s", fsp->fsp_name);
+ do_log(SMB_VFS_OP_FSYNC, (result >= 0), handle, "%s",
+ fsp_str_do_log(fsp));
return result;
}
@@ -879,7 +892,8 @@ static int smb_full_audit_fstat(vfs_handle_struct *handle, files_struct *fsp,
result = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
- do_log(SMB_VFS_OP_FSTAT, (result >= 0), handle, "%s", fsp->fsp_name);
+ do_log(SMB_VFS_OP_FSTAT, (result >= 0), handle, "%s",
+ fsp_str_do_log(fsp));
return result;
}
@@ -897,7 +911,7 @@ static int smb_full_audit_lstat(vfs_handle_struct *handle,
return result;
}
-static int smb_full_audit_get_alloc_size(vfs_handle_struct *handle,
+static uint64_t smb_full_audit_get_alloc_size(vfs_handle_struct *handle,
files_struct *fsp, const SMB_STRUCT_STAT *sbuf)
{
int result;
@@ -942,7 +956,7 @@ static int smb_full_audit_fchmod(vfs_handle_struct *handle, files_struct *fsp,
result = SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
do_log(SMB_VFS_OP_FCHMOD, (result >= 0), handle,
- "%s|%o", fsp->fsp_name, mode);
+ "%s|%o", fsp_str_do_log(fsp), mode);
return result;
}
@@ -968,7 +982,7 @@ static int smb_full_audit_fchown(vfs_handle_struct *handle, files_struct *fsp,
result = SMB_VFS_NEXT_FCHOWN(handle, fsp, uid, gid);
do_log(SMB_VFS_OP_FCHOWN, (result >= 0), handle, "%s|%ld|%ld",
- fsp->fsp_name, (long int)uid, (long int)gid);
+ fsp_str_do_log(fsp), (long int)uid, (long int)gid);
return result;
}
@@ -1032,7 +1046,7 @@ static int smb_full_audit_ftruncate(vfs_handle_struct *handle, files_struct *fsp
result = SMB_VFS_NEXT_FTRUNCATE(handle, fsp, len);
do_log(SMB_VFS_OP_FTRUNCATE, (result >= 0), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
@@ -1044,7 +1058,7 @@ static bool smb_full_audit_lock(vfs_handle_struct *handle, files_struct *fsp,
result = SMB_VFS_NEXT_LOCK(handle, fsp, op, offset, count, type);
- do_log(SMB_VFS_OP_LOCK, result, handle, "%s", fsp->fsp_name);
+ do_log(SMB_VFS_OP_LOCK, result, handle, "%s", fsp_str_do_log(fsp));
return result;
}
@@ -1058,7 +1072,7 @@ static int smb_full_audit_kernel_flock(struct vfs_handle_struct *handle,
result = SMB_VFS_NEXT_KERNEL_FLOCK(handle, fsp, share_mode);
do_log(SMB_VFS_OP_KERNEL_FLOCK, (result >= 0), handle, "%s",
- fsp->fsp_name);
+ fsp_str_do_log(fsp));
return result;
}
@@ -1071,7 +1085,7 @@ static int smb_full_audit_linux_setlease(vfs_handle_struct *handle, files_struct
result = SMB_VFS_NEXT_LINUX_SETLEASE(handle, fsp, leasetype);
do_log(SMB_VFS_OP_LINUX_SETLEASE, (result >= 0), handle, "%s",
- fsp->fsp_name);
+ fsp_str_do_log(fsp));
return result;
}
@@ -1083,7 +1097,7 @@ static bool smb_full_audit_getlock(vfs_handle_struct *handle, files_struct *fsp,
result = SMB_VFS_NEXT_GETLOCK(handle, fsp, poffset, pcount, ptype, ppid);
- do_log(SMB_VFS_OP_GETLOCK, result, handle, "%s", fsp->fsp_name);
+ do_log(SMB_VFS_OP_GETLOCK, result, handle, "%s", fsp_str_do_log(fsp));
return result;
}
@@ -1256,7 +1270,7 @@ static NTSTATUS smb_full_audit_brl_lock_windows(struct vfs_handle_struct *handle
blocking_lock, blr);
do_log(SMB_VFS_OP_BRL_LOCK_WINDOWS, NT_STATUS_IS_OK(result), handle,
- "%s:%llu-%llu. type=%d. blocking=%d", br_lck->fsp->fsp_name,
+ "%s:%llu-%llu. type=%d. blocking=%d", fsp_str_do_log(br_lck->fsp),
plock->start, plock->size, plock->lock_type, blocking_lock );
return result;
@@ -1273,7 +1287,7 @@ static bool smb_full_audit_brl_unlock_windows(struct vfs_handle_struct *handle,
plock);
do_log(SMB_VFS_OP_BRL_UNLOCK_WINDOWS, (result == 0), handle,
- "%s:%llu-%llu:%d", br_lck->fsp->fsp_name, plock->start,
+ "%s:%llu-%llu:%d", fsp_str_do_log(br_lck->fsp), plock->start,
plock->size, plock->lock_type);
return result;
@@ -1289,7 +1303,7 @@ static bool smb_full_audit_brl_cancel_windows(struct vfs_handle_struct *handle,
result = SMB_VFS_NEXT_BRL_CANCEL_WINDOWS(handle, br_lck, plock, blr);
do_log(SMB_VFS_OP_BRL_CANCEL_WINDOWS, (result == 0), handle,
- "%s:%llu-%llu:%d", br_lck->fsp->fsp_name, plock->start,
+ "%s:%llu-%llu:%d", fsp_str_do_log(br_lck->fsp), plock->start,
plock->size);
return result;
@@ -1304,7 +1318,7 @@ static bool smb_full_audit_strict_lock(struct vfs_handle_struct *handle,
result = SMB_VFS_NEXT_STRICT_LOCK(handle, fsp, plock);
do_log(SMB_VFS_OP_STRICT_LOCK, result, handle,
- "%s:%llu-%llu:%d", fsp->fsp_name, plock->start,
+ "%s:%llu-%llu:%d", fsp_str_do_log(fsp), plock->start,
plock->size);
return result;
@@ -1317,7 +1331,7 @@ static void smb_full_audit_strict_unlock(struct vfs_handle_struct *handle,
SMB_VFS_NEXT_STRICT_UNLOCK(handle, fsp, plock);
do_log(SMB_VFS_OP_STRICT_UNLOCK, true, handle,
- "%s:%llu-%llu:%d", fsp->fsp_name, plock->start,
+ "%s:%llu-%llu:%d", fsp_str_do_log(fsp), plock->start,
plock->size);
return;
@@ -1332,7 +1346,7 @@ static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_stru
result = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc);
do_log(SMB_VFS_OP_FGET_NT_ACL, NT_STATUS_IS_OK(result), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
@@ -1360,7 +1374,8 @@ static NTSTATUS smb_full_audit_fset_nt_acl(vfs_handle_struct *handle, files_stru
result = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
- do_log(SMB_VFS_OP_FSET_NT_ACL, NT_STATUS_IS_OK(result), handle, "%s", fsp->fsp_name);
+ do_log(SMB_VFS_OP_FSET_NT_ACL, NT_STATUS_IS_OK(result), handle, "%s",
+ fsp_str_do_log(fsp));
return result;
}
@@ -1386,7 +1401,7 @@ static int smb_full_audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fs
result = SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode);
do_log(SMB_VFS_OP_FCHMOD_ACL, (result >= 0), handle,
- "%s|%o", fsp->fsp_name, mode);
+ "%s|%o", fsp_str_do_log(fsp), mode);
return result;
}
@@ -1475,7 +1490,7 @@ static SMB_ACL_T smb_full_audit_sys_acl_get_fd(vfs_handle_struct *handle,
result = SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp);
do_log(SMB_VFS_OP_SYS_ACL_GET_FD, (result != NULL), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
@@ -1635,7 +1650,7 @@ static int smb_full_audit_sys_acl_set_fd(vfs_handle_struct *handle, files_struct
result = SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, fsp, theacl);
do_log(SMB_VFS_OP_SYS_ACL_SET_FD, (result >= 0), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
@@ -1749,7 +1764,7 @@ static ssize_t smb_full_audit_fgetxattr(struct vfs_handle_struct *handle,
result = SMB_VFS_NEXT_FGETXATTR(handle, fsp, name, value, size);
do_log(SMB_VFS_OP_FGETXATTR, (result >= 0), handle,
- "%s|%s", fsp->fsp_name, name);
+ "%s|%s", fsp_str_do_log(fsp), name);
return result;
}
@@ -1787,7 +1802,7 @@ static ssize_t smb_full_audit_flistxattr(struct vfs_handle_struct *handle,
result = SMB_VFS_NEXT_FLISTXATTR(handle, fsp, list, size);
do_log(SMB_VFS_OP_FLISTXATTR, (result >= 0), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
@@ -1829,7 +1844,7 @@ static int smb_full_audit_fremovexattr(struct vfs_handle_struct *handle,
result = SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, name);
do_log(SMB_VFS_OP_FREMOVEXATTR, (result >= 0), handle,
- "%s|%s", fsp->fsp_name, name);
+ "%s|%s", fsp_str_do_log(fsp), name);
return result;
}
@@ -1875,7 +1890,7 @@ static int smb_full_audit_fsetxattr(struct vfs_handle_struct *handle,
result = SMB_VFS_NEXT_FSETXATTR(handle, fsp, name, value, size, flags);
do_log(SMB_VFS_OP_FSETXATTR, (result >= 0), handle,
- "%s|%s", fsp->fsp_name, name);
+ "%s|%s", fsp_str_do_log(fsp), name);
return result;
}
@@ -1886,7 +1901,7 @@ static int smb_full_audit_aio_read(struct vfs_handle_struct *handle, struct file
result = SMB_VFS_NEXT_AIO_READ(handle, fsp, aiocb);
do_log(SMB_VFS_OP_AIO_READ, (result >= 0), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
@@ -1897,7 +1912,7 @@ static int smb_full_audit_aio_write(struct vfs_handle_struct *handle, struct fil
result = SMB_VFS_NEXT_AIO_WRITE(handle, fsp, aiocb);
do_log(SMB_VFS_OP_AIO_WRITE, (result >= 0), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
@@ -1908,7 +1923,7 @@ static ssize_t smb_full_audit_aio_return(struct vfs_handle_struct *handle, struc
result = SMB_VFS_NEXT_AIO_RETURN(handle, fsp, aiocb);
do_log(SMB_VFS_OP_AIO_RETURN, (result >= 0), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
@@ -1919,7 +1934,7 @@ static int smb_full_audit_aio_cancel(struct vfs_handle_struct *handle, struct fi
result = SMB_VFS_NEXT_AIO_CANCEL(handle, fsp, aiocb);
do_log(SMB_VFS_OP_AIO_CANCEL, (result >= 0), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
@@ -1930,7 +1945,7 @@ static int smb_full_audit_aio_error(struct vfs_handle_struct *handle, struct fil
result = SMB_VFS_NEXT_AIO_ERROR(handle, fsp, aiocb);
do_log(SMB_VFS_OP_AIO_ERROR, (result >= 0), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
@@ -1941,7 +1956,7 @@ static int smb_full_audit_aio_fsync(struct vfs_handle_struct *handle, struct fil
result = SMB_VFS_NEXT_AIO_FSYNC(handle, fsp, op, aiocb);
do_log(SMB_VFS_OP_AIO_FSYNC, (result >= 0), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
@@ -1952,7 +1967,7 @@ static int smb_full_audit_aio_suspend(struct vfs_handle_struct *handle, struct f
result = SMB_VFS_NEXT_AIO_SUSPEND(handle, fsp, aiocb, n, ts);
do_log(SMB_VFS_OP_AIO_SUSPEND, (result >= 0), handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
@@ -1964,7 +1979,7 @@ static bool smb_full_audit_aio_force(struct vfs_handle_struct *handle,
result = SMB_VFS_NEXT_AIO_FORCE(handle, fsp);
do_log(SMB_VFS_OP_AIO_FORCE, result, handle,
- "%s", fsp->fsp_name);
+ "%s", fsp_str_do_log(fsp));
return result;
}
diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c
index 47858cb352..cde80f0021 100644
--- a/source3/modules/vfs_gpfs.c
+++ b/source3/modules/vfs_gpfs.c
@@ -303,7 +303,7 @@ static NTSTATUS gpfsacl_fget_nt_acl(vfs_handle_struct *handle,
int result;
*ppdesc = NULL;
- result = gpfs_get_nfs4_acl(fsp->fsp_name, &pacl);
+ result = gpfs_get_nfs4_acl(fsp->fsp_name->base_name, &pacl);
if (result == 0)
return smb_fget_nt_acl_nfs4(fsp, security_info, ppdesc, pacl);
@@ -389,7 +389,7 @@ static bool gpfsacl_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl)
"merge_writeappend", True)) {
DEBUG(2, ("vfs_gpfs.c: file [%s]: ACE contains "
"WRITE^APPEND, setting WRITE|APPEND\n",
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
gace->aceMask |= ACE4_MASK_WRITE|ACE4_MASK_APPEND;
}
@@ -423,7 +423,8 @@ static bool gpfsacl_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl)
gacl->acl_nace++;
}
- ret = smbd_gpfs_putacl(fsp->fsp_name, GPFS_PUTACL_STRUCT | GPFS_ACL_SAMBA, gacl);
+ ret = smbd_gpfs_putacl(fsp->fsp_name->base_name,
+ GPFS_PUTACL_STRUCT | GPFS_ACL_SAMBA, gacl);
if (ret != 0) {
DEBUG(8, ("gpfs_putacl failed with %s\n", strerror(errno)));
gpfs_dumpacl(8, gacl);
@@ -439,12 +440,17 @@ static NTSTATUS gpfsacl_set_nt_acl_internal(files_struct *fsp, uint32 security_i
struct gpfs_acl *acl;
NTSTATUS result = NT_STATUS_ACCESS_DENIED;
- acl = gpfs_getacl_alloc(fsp->fsp_name, 0);
+ acl = gpfs_getacl_alloc(fsp->fsp_name->base_name, 0);
if (acl == NULL)
return result;
if (acl->acl_version&GPFS_ACL_VERSION_NFS4)
{
+ if ((psd->type&SEC_DESC_DACL_PROTECTED)) {
+ DEBUG(2, ("Rejecting unsupported ACL with DACL_PROTECTED bit set\n"));
+ return NT_STATUS_NOT_SUPPORTED;
+ }
+
result = smb_set_nt_acl_nfs4(
fsp, security_info_sent, psd,
gpfsacl_process_smbacl);
@@ -589,7 +595,8 @@ static SMB_ACL_T gpfsacl_sys_acl_get_file(vfs_handle_struct *handle,
static SMB_ACL_T gpfsacl_sys_acl_get_fd(vfs_handle_struct *handle,
files_struct *fsp)
{
- return gpfsacl_get_posix_acl(fsp->fsp_name, GPFS_ACL_TYPE_ACCESS);
+ return gpfsacl_get_posix_acl(fsp->fsp_name->base_name,
+ GPFS_ACL_TYPE_ACCESS);
}
static struct gpfs_acl *smb2gpfs_acl(const SMB_ACL_T pacl,
@@ -702,7 +709,8 @@ static int gpfsacl_sys_acl_set_fd(vfs_handle_struct *handle,
files_struct *fsp,
SMB_ACL_T theacl)
{
- return gpfsacl_sys_acl_set_file(handle, fsp->fsp_name, SMB_ACL_TYPE_ACCESS, theacl);
+ return gpfsacl_sys_acl_set_file(handle, fsp->fsp_name->base_name,
+ SMB_ACL_TYPE_ACCESS, theacl);
}
static int gpfsacl_sys_acl_delete_def_file(vfs_handle_struct *handle,
@@ -759,6 +767,8 @@ static int gpfsacl_emu_chmod(const char *path, mode_t mode)
int i;
files_struct fake_fsp; /* TODO: rationalize parametrization */
SMB4ACE_T *smbace;
+ struct smb_filename *smb_fname = NULL;
+ NTSTATUS status;
DEBUG(10, ("gpfsacl_emu_chmod invoked for %s mode %o\n", path, mode));
@@ -828,11 +838,19 @@ static int gpfsacl_emu_chmod(const char *path, mode_t mode)
/* don't add complementary DENY ACEs here */
ZERO_STRUCT(fake_fsp);
- fake_fsp.fsp_name = (char *)path; /* no file_new is needed here */
-
+ status = create_synthetic_smb_fname(talloc_tos(), path, NULL, NULL,
+ &fake_fsp.fsp_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
/* put the acl */
- if (gpfsacl_process_smbacl(&fake_fsp, pacl) == False)
+ if (gpfsacl_process_smbacl(&fake_fsp, pacl) == False) {
+ TALLOC_FREE(fake_fsp.fsp_name);
return -1;
+ }
+
+ TALLOC_FREE(fake_fsp.fsp_name);
return 0; /* ok for [f]chmod */
}
@@ -870,7 +888,7 @@ static int vfs_gpfs_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t
return 0;
}
- rc = gpfsacl_emu_chmod(fsp->fsp_name, mode);
+ rc = gpfsacl_emu_chmod(fsp->fsp_name->base_name, mode);
if (rc == 1)
return SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
return rc;
diff --git a/source3/modules/vfs_hpuxacl.c b/source3/modules/vfs_hpuxacl.c
index 35341a5c3e..32e8539202 100644
--- a/source3/modules/vfs_hpuxacl.c
+++ b/source3/modules/vfs_hpuxacl.c
@@ -201,23 +201,23 @@ SMB_ACL_T hpuxacl_sys_acl_get_fd(vfs_handle_struct *handle,
DEBUG(10, ("redirecting call of hpuxacl_sys_acl_get_fd to "
"hpuxacl_sys_acl_get_file (no facl syscall on HPUX).\n"));
- return hpuxacl_sys_acl_get_file(handle, file_struct_p->fsp_name,
- SMB_ACL_TYPE_ACCESS);
+ return hpuxacl_sys_acl_get_file(handle,
+ file_struct_p->fsp_name->base_name,
+ SMB_ACL_TYPE_ACCESS);
}
int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle,
- const char *name,
+ struct smb_filename *smb_fname,
SMB_ACL_TYPE_T type,
SMB_ACL_T theacl)
{
int ret = -1;
- SMB_STRUCT_STAT s;
HPUX_ACL_T hpux_acl = NULL;
int count;
DEBUG(10, ("hpuxacl_sys_acl_set_file called for file '%s'\n",
- name));
+ smb_fname_str_dbg(smb_fname)));
if(hpux_acl_call_present() == False) {
@@ -248,11 +248,11 @@ int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle,
* that has _not_ been specified in "type" from the file first
* and concatenate it with the acl provided.
*/
- if (vfs_stat_smb_fname(handle->conn, name, &s) != 0) {
+ if (SMB_VFS_STAT(handle->conn, smb_fname) != 0) {
DEBUG(10, ("Error in stat call: %s\n", strerror(errno)));
goto done;
}
- if (S_ISDIR(s.st_ex_mode)) {
+ if (S_ISDIR(smb_fname->st.st_ex_mode)) {
HPUX_ACL_T other_acl;
int other_count;
SMB_ACL_TYPE_T other_type;
@@ -261,7 +261,8 @@ int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle,
? SMB_ACL_TYPE_DEFAULT
: SMB_ACL_TYPE_ACCESS;
DEBUGADD(10, ("getting acl from filesystem\n"));
- if (!hpux_acl_get_file(name, &other_acl, &other_count)) {
+ if (!hpux_acl_get_file(smb_fname->base_name, &other_acl,
+ &other_count)) {
DEBUG(10, ("error getting acl from directory\n"));
goto done;
}
@@ -289,7 +290,8 @@ int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle,
}
DEBUG(10, ("resulting acl is valid.\n"));
- ret = acl(CONST_DISCARD(char *, name), ACL_SET, count, hpux_acl);
+ ret = acl(CONST_DISCARD(char *, smb_fname->base_name), ACL_SET, count,
+ hpux_acl);
if (ret != 0) {
DEBUG(0, ("ERROR calling acl: %s\n", strerror(errno)));
}
diff --git a/source3/modules/vfs_hpuxacl.h b/source3/modules/vfs_hpuxacl.h
index 07b32d628c..9baed5790a 100644
--- a/source3/modules/vfs_hpuxacl.h
+++ b/source3/modules/vfs_hpuxacl.h
@@ -41,7 +41,7 @@ SMB_ACL_T hpuxacl_sys_acl_get_fd(vfs_handle_struct *handle,
files_struct *fsp);
int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle,
- const char *name,
+ struct smb_filename *smb_fname,
SMB_ACL_TYPE_T type,
SMB_ACL_T theacl);
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index 1f300a055c..7c338e7268 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -406,8 +406,8 @@ static int shadow_copy2_lstat(vfs_handle_struct *handle,
static int shadow_copy2_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf)
{
int ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
- if (ret == 0 && shadow_copy2_match_name(fsp->fsp_name)) {
- convert_sbuf(handle, fsp->fsp_name, sbuf);
+ if (ret == 0 && shadow_copy2_match_name(fsp->fsp_name->base_name)) {
+ convert_sbuf(handle, fsp->fsp_name->base_name, sbuf);
}
return ret;
}
@@ -549,7 +549,8 @@ static int shadow_copy2_rmdir(vfs_handle_struct *handle, const char *fname)
SHADOW2_NEXT(RMDIR, (handle, name), int, -1);
}
-static int shadow_copy2_chflags(vfs_handle_struct *handle, const char *fname, int flags)
+static int shadow_copy2_chflags(vfs_handle_struct *handle, const char *fname,
+ unsigned int flags)
{
SHADOW2_NEXT(CHFLAGS, (handle, name, flags), int, -1);
}
diff --git a/source3/modules/vfs_smb_traffic_analyzer.c b/source3/modules/vfs_smb_traffic_analyzer.c
index a7fbeadbbe..6f7aee0e50 100644
--- a/source3/modules/vfs_smb_traffic_analyzer.c
+++ b/source3/modules/vfs_smb_traffic_analyzer.c
@@ -336,11 +336,11 @@ static ssize_t smb_traffic_analyzer_read(vfs_handle_struct *handle, \
ssize_t result;
result = SMB_VFS_NEXT_READ(handle, fsp, data, n);
- DEBUG(10, ("smb_traffic_analyzer_read: READ: %s\n", fsp->fsp_name ));
+ DEBUG(10, ("smb_traffic_analyzer_read: READ: %s\n", fsp_str_dbg(fsp)));
smb_traffic_analyzer_send_data(handle,
result,
- fsp->fsp_name,
+ fsp->fsp_name->base_name,
false);
return result;
}
@@ -353,11 +353,12 @@ static ssize_t smb_traffic_analyzer_pread(vfs_handle_struct *handle, \
result = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
- DEBUG(10, ("smb_traffic_analyzer_pread: PREAD: %s\n", fsp->fsp_name ));
+ DEBUG(10, ("smb_traffic_analyzer_pread: PREAD: %s\n",
+ fsp_str_dbg(fsp)));
smb_traffic_analyzer_send_data(handle,
result,
- fsp->fsp_name,
+ fsp->fsp_name->base_name,
false);
return result;
@@ -370,11 +371,12 @@ static ssize_t smb_traffic_analyzer_write(vfs_handle_struct *handle, \
result = SMB_VFS_NEXT_WRITE(handle, fsp, data, n);
- DEBUG(10, ("smb_traffic_analyzer_write: WRITE: %s\n", fsp->fsp_name ));
+ DEBUG(10, ("smb_traffic_analyzer_write: WRITE: %s\n",
+ fsp_str_dbg(fsp)));
smb_traffic_analyzer_send_data(handle,
result,
- fsp->fsp_name,
+ fsp->fsp_name->base_name,
true);
return result;
}
@@ -386,11 +388,11 @@ static ssize_t smb_traffic_analyzer_pwrite(vfs_handle_struct *handle, \
result = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
- DEBUG(10, ("smb_traffic_analyzer_pwrite: PWRITE: %s\n", fsp->fsp_name ));
+ DEBUG(10, ("smb_traffic_analyzer_pwrite: PWRITE: %s\n", fsp_str_dbg(fsp)));
smb_traffic_analyzer_send_data(handle,
result,
- fsp->fsp_name,
+ fsp->fsp_name->base_name,
true);
return result;
}
diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
index eccc2379c9..c32c4f3190 100644
--- a/source3/modules/vfs_streams_xattr.c
+++ b/source3/modules/vfs_streams_xattr.c
@@ -128,27 +128,20 @@ static NTSTATUS streams_xattr_get_name(TALLOC_CTX *ctx,
static bool streams_xattr_recheck(struct stream_io *sio)
{
NTSTATUS status;
- struct smb_filename *smb_fname = NULL;
char *xattr_name = NULL;
if (sio->fsp->fsp_name == sio->fsp_name_ptr) {
return true;
}
- status = create_synthetic_smb_fname_split(talloc_tos(),
- sio->fsp->fsp_name, NULL,
- &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- return false;
- }
-
- if (smb_fname->stream_name == NULL) {
+ if (sio->fsp->fsp_name->stream_name == NULL) {
/* how can this happen */
errno = EINVAL;
return false;
}
- status = streams_xattr_get_name(talloc_tos(), smb_fname->stream_name,
+ status = streams_xattr_get_name(talloc_tos(),
+ sio->fsp->fsp_name->stream_name,
&xattr_name);
if (!NT_STATUS_IS_OK(status)) {
return false;
@@ -159,10 +152,9 @@ static bool streams_xattr_recheck(struct stream_io *sio)
sio->xattr_name = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(sio->handle, sio->fsp),
xattr_name);
sio->base = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(sio->handle, sio->fsp),
- smb_fname->base_name);
+ sio->fsp->fsp_name->base_name);
sio->fsp_name_ptr = sio->fsp->fsp_name;
- TALLOC_FREE(smb_fname);
TALLOC_FREE(xattr_name);
if ((sio->xattr_name == NULL) || (sio->base == NULL)) {
@@ -899,7 +891,8 @@ static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle,
sio->xattr_name,
ea.value.data, ea.value.length, 0);
} else {
- ret = SMB_VFS_SETXATTR(fsp->conn, fsp->base_fsp->fsp_name,
+ ret = SMB_VFS_SETXATTR(fsp->conn,
+ fsp->base_fsp->fsp_name->base_name,
sio->xattr_name,
ea.value.data, ea.value.length, 0);
}
@@ -963,8 +956,7 @@ static int streams_xattr_ftruncate(struct vfs_handle_struct *handle,
(struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
DEBUG(10, ("streams_xattr_ftruncate called for file %s offset %.0f\n",
- fsp->fsp_name,
- (double)offset ));
+ fsp_str_dbg(fsp), (double)offset));
if (sio == NULL) {
return SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset);
@@ -1004,7 +996,8 @@ static int streams_xattr_ftruncate(struct vfs_handle_struct *handle,
sio->xattr_name,
ea.value.data, ea.value.length, 0);
} else {
- ret = SMB_VFS_SETXATTR(fsp->conn, fsp->base_fsp->fsp_name,
+ ret = SMB_VFS_SETXATTR(fsp->conn,
+ fsp->base_fsp->fsp_name->base_name,
sio->xattr_name,
ea.value.data, ea.value.length, 0);
}
diff --git a/source3/modules/vfs_tsmsm.c b/source3/modules/vfs_tsmsm.c
index 57807105f6..753b2bcd26 100644
--- a/source3/modules/vfs_tsmsm.c
+++ b/source3/modules/vfs_tsmsm.c
@@ -273,7 +273,7 @@ static ssize_t tsmsm_aio_return(struct vfs_handle_struct *handle, struct files_s
if(result >= 0) {
notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES,
- fsp->fsp_name);
+ fsp->fsp_name->base_name);
}
return result;
@@ -307,7 +307,7 @@ static ssize_t tsmsm_pread(struct vfs_handle_struct *handle, struct files_struct
*/
notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES,
- fsp->fsp_name);
+ fsp->fsp_name->base_name);
}
return result;
@@ -325,7 +325,7 @@ static ssize_t tsmsm_pwrite(struct vfs_handle_struct *handle, struct files_struc
*/
notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES,
- fsp->fsp_name);
+ fsp->fsp_name->base_name);
}
return result;
diff --git a/source3/modules/vfs_zfsacl.c b/source3/modules/vfs_zfsacl.c
index a5b0490c8d..a92d5dae26 100644
--- a/source3/modules/vfs_zfsacl.c
+++ b/source3/modules/vfs_zfsacl.c
@@ -145,14 +145,14 @@ static bool zfs_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl)
SMB_ASSERT(i == naces);
/* store acl */
- if(acl(fsp->fsp_name, ACE_SETACL, naces, acebuf)) {
+ if(acl(fsp->fsp_name->base_name, ACE_SETACL, naces, acebuf)) {
if(errno == ENOSYS) {
DEBUG(9, ("acl(ACE_SETACL, %s): Operation is not "
"supported on the filesystem where the file "
- "reside", fsp->fsp_name));
+ "reside", fsp_str_dbg(fsp)));
} else {
- DEBUG(9, ("acl(ACE_SETACL, %s): %s ", fsp->fsp_name,
- strerror(errno)));
+ DEBUG(9, ("acl(ACE_SETACL, %s): %s ", fsp_str_dbg(fsp),
+ strerror(errno)));
}
return 0;
}
@@ -180,7 +180,8 @@ static NTSTATUS zfsacl_fget_nt_acl(struct vfs_handle_struct *handle,
SMB4ACL_T *pacl;
NTSTATUS status;
- status = zfs_get_nt_acl_common(fsp->fsp_name, security_info, &pacl);
+ status = zfs_get_nt_acl_common(fsp->fsp_name->base_name, security_info,
+ &pacl);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index 848baeff3d..961e930728 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -82,6 +82,8 @@ static void terminate(void)
/* If there was an async dns child - kill it. */
kill_async_dns_child();
+ gencache_stabilize();
+
pidfile_unlink();
exit(0);
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 7e4371bf0b..dbbd6e327d 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -5142,6 +5142,9 @@ static char *lp_string(const char *s)
#if 0
DEBUG(10, ("lp_string(%s)\n", s));
#endif
+ if (!s) {
+ return NULL;
+ }
ret = talloc_sub_basic(ctx,
get_current_username(),
diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c
index 4ed04e4e7a..0678181669 100644
--- a/source3/passdb/passdb.c
+++ b/source3/passdb/passdb.c
@@ -1439,7 +1439,7 @@ static bool init_samu_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 bu
}
/* Change from V1 is addition of password history field. */
- pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
+ pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
if (pwHistLen) {
uint8 *pw_hist = SMB_MALLOC_ARRAY(uint8, pwHistLen * PW_HISTORY_ENTRY_LEN);
if (!pw_hist) {
@@ -1674,7 +1674,7 @@ static bool init_samu_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 bu
}
}
- pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
+ pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
if (pwHistLen) {
uint8 *pw_hist = (uint8 *)SMB_MALLOC(pwHistLen * PW_HISTORY_ENTRY_LEN);
if (!pw_hist) {
@@ -1879,7 +1879,7 @@ static uint32 init_buffer_from_samu_v3 (uint8 **buf, struct samu *sampass, bool
nt_pw_len = 0;
}
- pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
+ pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
nt_pw_hist = pdb_get_pw_history(sampass, &nt_pw_hist_len);
if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
nt_pw_hist_len *= PW_HISTORY_ENTRY_LEN;
@@ -2085,7 +2085,7 @@ bool pdb_copy_sam_account(struct samu *dst, struct samu *src )
}
/*********************************************************************
- Update the bad password count checking the AP_RESET_COUNT_TIME
+ Update the bad password count checking the PDB_POLICY_RESET_COUNT_TIME
*********************************************************************/
bool pdb_update_bad_password_count(struct samu *sampass, bool *updated)
@@ -2102,7 +2102,7 @@ bool pdb_update_bad_password_count(struct samu *sampass, bool *updated)
}
become_root();
- res = pdb_get_account_policy(AP_RESET_COUNT_TIME, &resettime);
+ res = pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &resettime);
unbecome_root();
if (!res) {
@@ -2131,7 +2131,7 @@ bool pdb_update_bad_password_count(struct samu *sampass, bool *updated)
}
/*********************************************************************
- Update the ACB_AUTOLOCK flag checking the AP_LOCK_ACCOUNT_DURATION
+ Update the ACB_AUTOLOCK flag checking the PDB_POLICY_LOCK_ACCOUNT_DURATION
*********************************************************************/
bool pdb_update_autolock_flag(struct samu *sampass, bool *updated)
@@ -2147,7 +2147,7 @@ bool pdb_update_autolock_flag(struct samu *sampass, bool *updated)
}
become_root();
- res = pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &duration);
+ res = pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &duration);
unbecome_root();
if (!res) {
@@ -2199,7 +2199,7 @@ bool pdb_increment_bad_password_count(struct samu *sampass)
/* Retrieve the account lockout policy */
become_root();
- ret = pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout);
+ ret = pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_lockout);
unbecome_root();
if ( !ret ) {
DEBUG(0, ("pdb_increment_bad_password_count: pdb_get_account_policy failed.\n"));
diff --git a/source3/passdb/pdb_ads.c b/source3/passdb/pdb_ads.c
index eec63728ca..70d550042b 100644
--- a/source3/passdb/pdb_ads.c
+++ b/source3/passdb/pdb_ads.c
@@ -203,7 +203,7 @@ static NTSTATUS pdb_ads_init_sam_from_priv(struct pdb_methods *m,
pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
}
if (pdb_ads_pull_time(entry, "accountExpires", &tmp_time)) {
- pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
+ pdb_set_kickoff_time(sam, tmp_time, PDB_SET);
}
str = tldap_talloc_single_attribute(entry, "displayName",
@@ -250,7 +250,7 @@ static NTSTATUS pdb_ads_init_sam_from_priv(struct pdb_methods *m,
DEBUG(10, ("Could not pull userAccountControl\n"));
goto fail;
}
- pdb_set_acct_ctrl(sam, ads_uf2acb(n), PDB_SET);
+ pdb_set_acct_ctrl(sam, ds_uf2acb(n), PDB_SET);
if (tldap_get_single_valueblob(entry, "unicodePwd", &blob)) {
if (blob.length != NT_HASH_LEN) {
@@ -310,7 +310,7 @@ static bool pdb_ads_init_ads_from_sam(struct pdb_ads_state *state,
ret &= tldap_make_mod_fmt(
existing, mem_ctx, pnum_mods, pmods, "userAccountControl",
- "%d", ads_acb2uf(pdb_get_acct_ctrl(sam)));
+ "%d", ds_acb2uf(pdb_get_acct_ctrl(sam)));
ret &= tldap_make_mod_fmt(
existing, mem_ctx, pnum_mods, pmods, "homeDirectory",
@@ -1682,7 +1682,7 @@ static NTSTATUS pdb_ads_lookup_rids(struct pdb_methods *m,
DEBUG(10, ("no samAccountType"));
continue;
}
- lsa_attrs[i] = ads_atype_map(attr);
+ lsa_attrs[i] = ds_atype_map(attr);
num_mapped += 1;
}
@@ -1706,16 +1706,18 @@ static NTSTATUS pdb_ads_lookup_names(struct pdb_methods *m,
}
static NTSTATUS pdb_ads_get_account_policy(struct pdb_methods *m,
- int policy_index, uint32 *value)
+ enum pdb_policy_type type,
+ uint32_t *value)
{
- return account_policy_get(policy_index, value)
+ return account_policy_get(type, value)
? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
static NTSTATUS pdb_ads_set_account_policy(struct pdb_methods *m,
- int policy_index, uint32 value)
+ enum pdb_policy_type type,
+ uint32_t value)
{
- return account_policy_set(policy_index, value)
+ return account_policy_set(type, value)
? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
@@ -2022,7 +2024,9 @@ static NTSTATUS pdb_ads_enum_trusteddoms(struct pdb_methods *m,
uint32 *num_domains,
struct trustdom_info ***domains)
{
- return NT_STATUS_NOT_IMPLEMENTED;
+ *num_domains = 0;
+ *domains = NULL;
+ return NT_STATUS_OK;
}
static void pdb_ads_init_methods(struct pdb_methods *m)
@@ -2111,7 +2115,7 @@ static void s3_tldap_debug(void *context, enum tldap_debug_level level,
samba_level = 2;
break;
case TLDAP_DEBUG_TRACE:
- samba_level = 10;
+ samba_level = 11;
break;
};
diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c
index f55b77f675..30775e49fe 100644
--- a/source3/passdb/pdb_get_set.c
+++ b/source3/passdb/pdb_get_set.c
@@ -88,7 +88,7 @@ time_t pdb_get_pass_can_change_time(const struct samu *sampass)
pdb_get_init_flags(sampass, PDB_CANCHANGETIME) == PDB_CHANGED)
return sampass->pass_can_change_time;
- if (!pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &allow))
+ if (!pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &allow))
allow = 0;
/* in normal cases, just calculate it from policy */
@@ -112,7 +112,7 @@ time_t pdb_get_pass_must_change_time(const struct samu *sampass)
if (sampass->acct_ctrl & ACB_PWNOEXP)
return get_time_t_max();
- if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &expire)
+ if (!pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &expire)
|| expire == (uint32)-1 || expire == 0)
return get_time_t_max();
@@ -1013,7 +1013,7 @@ bool pdb_set_plaintext_passwd(struct samu *sampass, const char *plaintext)
if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL) {
uchar *pwhistory;
uint32 pwHistLen;
- pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
+ pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
if (pwHistLen != 0){
uint32 current_history_len;
/* We need to make sure we don't have a race condition here - the
diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c
index 465a6bf595..5d0b625da5 100644
--- a/source3/passdb/pdb_interface.c
+++ b/source3/passdb/pdb_interface.c
@@ -994,25 +994,25 @@ NTSTATUS pdb_lookup_names(const DOM_SID *domain_sid,
}
#endif
-bool pdb_get_account_policy(int policy_index, uint32 *value)
+bool pdb_get_account_policy(enum pdb_policy_type type, uint32_t *value)
{
struct pdb_methods *pdb = pdb_get_methods();
NTSTATUS status;
become_root();
- status = pdb->get_account_policy(pdb, policy_index, value);
+ status = pdb->get_account_policy(pdb, type, value);
unbecome_root();
return NT_STATUS_IS_OK(status);
}
-bool pdb_set_account_policy(int policy_index, uint32 value)
+bool pdb_set_account_policy(enum pdb_policy_type type, uint32_t value)
{
struct pdb_methods *pdb = pdb_get_methods();
NTSTATUS status;
become_root();
- status = pdb->set_account_policy(pdb, policy_index, value);
+ status = pdb->set_account_policy(pdb, type, value);
unbecome_root();
return NT_STATUS_IS_OK(status);
@@ -1174,14 +1174,14 @@ static NTSTATUS pdb_default_update_login_attempts (struct pdb_methods *methods,
return NT_STATUS_OK;
}
-static NTSTATUS pdb_default_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value)
+static NTSTATUS pdb_default_get_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t *value)
{
- return account_policy_get(policy_index, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+ return account_policy_get(type, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
-static NTSTATUS pdb_default_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value)
+static NTSTATUS pdb_default_set_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t value)
{
- return account_policy_set(policy_index, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
+ return account_policy_set(type, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
static NTSTATUS pdb_default_get_seq_num(struct pdb_methods *methods, time_t *seq_num)
diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c
index 3579325769..1b1e22f2c8 100644
--- a/source3/passdb/pdb_ldap.c
+++ b/source3/passdb/pdb_ldap.c
@@ -336,7 +336,7 @@ int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state,
const char **attr)
{
char *filter = NULL;
- char *escape_user = escape_ldap_string_alloc(user);
+ char *escape_user = escape_ldap_string(talloc_tos(), user);
int ret = -1;
if (!escape_user) {
@@ -350,7 +350,7 @@ int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state,
filter = talloc_asprintf(talloc_tos(), "(&%s%s)", "(uid=%u)",
get_objclass_filter(ldap_state->schema_ver));
if (!filter) {
- SAFE_FREE(escape_user);
+ TALLOC_FREE(escape_user);
return LDAP_NO_MEMORY;
}
/*
@@ -360,7 +360,7 @@ int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state,
filter = talloc_all_string_sub(talloc_tos(),
filter, "%u", escape_user);
- SAFE_FREE(escape_user);
+ TALLOC_FREE(escape_user);
if (!filter) {
return LDAP_NO_MEMORY;
}
@@ -902,7 +902,7 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
pwHistLen = 0;
- pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
+ pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
if (pwHistLen > 0){
uint8 *pwhist = NULL;
int i;
@@ -1327,7 +1327,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
if (need_update(sampass, PDB_PWHISTORY)) {
char *pwstr = NULL;
uint32 pwHistLen = 0;
- pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHistLen);
+ pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
pwstr = SMB_MALLOC_ARRAY(char, 1024);
if (!pwstr) {
@@ -1404,7 +1404,7 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
uint16 badcount = pdb_get_bad_password_count(sampass);
time_t badtime = pdb_get_bad_password_time(sampass);
uint32 pol;
- pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &pol);
+ pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &pol);
DEBUG(3, ("updating bad password fields, policy=%u, count=%u, time=%u\n",
(unsigned int)pol, (unsigned int)badcount, (unsigned int)badtime));
@@ -1701,6 +1701,7 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
char *utf8_password;
char *utf8_dn;
size_t converted_size;
+ int ret;
if (!ldap_state->is_nds_ldap) {
@@ -1732,14 +1733,31 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
}
if ((ber_printf (ber, "{") < 0) ||
- (ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, utf8_dn) < 0) ||
- (ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, utf8_password) < 0) ||
- (ber_printf (ber, "n}") < 0)) {
- DEBUG(0,("ldapsam_modify_entry: ber_printf returns a value <0\n"));
- ber_free(ber,1);
- TALLOC_FREE(utf8_dn);
- TALLOC_FREE(utf8_password);
- return NT_STATUS_UNSUCCESSFUL;
+ (ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID,
+ utf8_dn) < 0)) {
+ DEBUG(0,("ldapsam_modify_entry: ber_printf returns a "
+ "value <0\n"));
+ ber_free(ber,1);
+ TALLOC_FREE(utf8_dn);
+ TALLOC_FREE(utf8_password);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if ((utf8_password != NULL) && (*utf8_password != '\0')) {
+ ret = ber_printf(ber, "ts}",
+ LDAP_TAG_EXOP_MODIFY_PASSWD_NEW,
+ utf8_password);
+ } else {
+ ret = ber_printf(ber, "}");
+ }
+
+ if (ret < 0) {
+ DEBUG(0,("ldapsam_modify_entry: ber_printf returns a "
+ "value <0\n"));
+ ber_free(ber,1);
+ TALLOC_FREE(utf8_dn);
+ TALLOC_FREE(utf8_password);
+ return NT_STATUS_UNSUCCESSFUL;
}
if ((rc = ber_flatten (ber, &bv))<0) {
@@ -2120,18 +2138,18 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, struct s
/* does the entry already exist but without a samba attributes?
we need to return the samba attributes here */
- escape_user = escape_ldap_string_alloc( username );
+ escape_user = escape_ldap_string(talloc_tos(), username);
filter = talloc_strdup(attr_list, "(uid=%u)");
if (!filter) {
status = NT_STATUS_NO_MEMORY;
goto fn_exit;
}
filter = talloc_all_string_sub(attr_list, filter, "%u", escape_user);
+ TALLOC_FREE(escape_user);
if (!filter) {
status = NT_STATUS_NO_MEMORY;
goto fn_exit;
}
- SAFE_FREE(escape_user);
rc = smbldap_search_suffix(ldap_state->smbldap_state,
filter, attr_list, &result);
@@ -2278,7 +2296,6 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, struct s
fn_exit:
TALLOC_FREE(ctx);
- SAFE_FREE(escape_user);
if (result) {
ldap_msgfree(result);
}
@@ -2528,7 +2545,7 @@ static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
const char *name)
{
char *filter = NULL;
- char *escape_name = escape_ldap_string_alloc(name);
+ char *escape_name = escape_ldap_string(talloc_tos(), name);
NTSTATUS status;
if (!escape_name) {
@@ -2540,11 +2557,11 @@ static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
get_attr_key2string(groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), escape_name,
get_attr_key2string(groupmap_attr_list, LDAP_ATTR_CN),
escape_name) < 0) {
- SAFE_FREE(escape_name);
+ TALLOC_FREE(escape_name);
return NT_STATUS_NO_MEMORY;
}
- SAFE_FREE(escape_name);
+ TALLOC_FREE(escape_name);
status = ldapsam_getgroup(methods, filter, map);
SAFE_FREE(filter);
return status;
@@ -2665,20 +2682,19 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
for (memberuid = values; *memberuid != NULL; memberuid += 1) {
char *escape_memberuid;
- escape_memberuid = escape_ldap_string_alloc(*memberuid);
+ escape_memberuid = escape_ldap_string(talloc_tos(),
+ *memberuid);
if (escape_memberuid == NULL) {
ret = NT_STATUS_NO_MEMORY;
goto done;
}
filter = talloc_asprintf_append_buffer(filter, "(uid=%s)", escape_memberuid);
+ TALLOC_FREE(escape_memberuid);
if (filter == NULL) {
- SAFE_FREE(escape_memberuid);
ret = NT_STATUS_NO_MEMORY;
goto done;
}
-
- SAFE_FREE(escape_memberuid);
}
filter = talloc_asprintf_append_buffer(filter, "))");
@@ -2812,7 +2828,7 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
return NT_STATUS_INVALID_PARAMETER;
}
- escape_name = escape_ldap_string_alloc(pdb_get_username(user));
+ escape_name = escape_ldap_string(talloc_tos(), pdb_get_username(user));
if (escape_name == NULL)
return NT_STATUS_NO_MEMORY;
@@ -2950,7 +2966,7 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
done:
- SAFE_FREE(escape_name);
+ TALLOC_FREE(escape_name);
return ret;
}
@@ -3764,7 +3780,7 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
}
static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods,
- int policy_index,
+ enum pdb_policy_type type,
uint32 value)
{
NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
@@ -3782,7 +3798,7 @@ static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods,
return NT_STATUS_INVALID_PARAMETER;
}
- policy_attr = get_account_policy_attr(policy_index);
+ policy_attr = get_account_policy_attr(type);
if (policy_attr == NULL) {
DEBUG(0,("ldapsam_set_account_policy_in_ldap: invalid "
"policy\n"));
@@ -3802,7 +3818,7 @@ static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods,
return ntstatus;
}
- if (!cache_account_policy_set(policy_index, value)) {
+ if (!cache_account_policy_set(type, value)) {
DEBUG(0,("ldapsam_set_account_policy_in_ldap: failed to "
"update local tdb cache\n"));
return ntstatus;
@@ -3812,14 +3828,15 @@ static NTSTATUS ldapsam_set_account_policy_in_ldap(struct pdb_methods *methods,
}
static NTSTATUS ldapsam_set_account_policy(struct pdb_methods *methods,
- int policy_index, uint32 value)
+ enum pdb_policy_type type,
+ uint32_t value)
{
- return ldapsam_set_account_policy_in_ldap(methods, policy_index,
+ return ldapsam_set_account_policy_in_ldap(methods, type,
value);
}
static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods,
- int policy_index,
+ enum pdb_policy_type type,
uint32 *value)
{
NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
@@ -3841,10 +3858,10 @@ static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods
return NT_STATUS_INVALID_PARAMETER;
}
- policy_attr = get_account_policy_attr(policy_index);
+ policy_attr = get_account_policy_attr(type);
if (!policy_attr) {
DEBUG(0,("ldapsam_get_account_policy_from_ldap: invalid "
- "policy index: %d\n", policy_index));
+ "policy index: %d\n", type));
return ntstatus;
}
@@ -3898,17 +3915,18 @@ out:
Guenther
*/
static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods,
- int policy_index, uint32 *value)
+ enum pdb_policy_type type,
+ uint32_t *value)
{
NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
- if (cache_account_policy_get(policy_index, value)) {
+ if (cache_account_policy_get(type, value)) {
DEBUG(11,("ldapsam_get_account_policy: got valid value from "
"cache\n"));
return NT_STATUS_OK;
}
- ntstatus = ldapsam_get_account_policy_from_ldap(methods, policy_index,
+ ntstatus = ldapsam_get_account_policy_from_ldap(methods, type,
value);
if (NT_STATUS_IS_OK(ntstatus)) {
goto update_cache;
@@ -3919,27 +3937,27 @@ static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods,
#if 0
/* should we automagically migrate old tdb value here ? */
- if (account_policy_get(policy_index, value))
+ if (account_policy_get(type, value))
goto update_ldap;
DEBUG(10,("ldapsam_get_account_policy: no tdb for %d, trying "
- "default\n", policy_index));
+ "default\n", type));
#endif
- if (!account_policy_get_default(policy_index, value)) {
+ if (!account_policy_get_default(type, value)) {
return ntstatus;
}
/* update_ldap: */
- ntstatus = ldapsam_set_account_policy(methods, policy_index, *value);
+ ntstatus = ldapsam_set_account_policy(methods, type, *value);
if (!NT_STATUS_IS_OK(ntstatus)) {
return ntstatus;
}
update_cache:
- if (!cache_account_policy_set(policy_index, *value)) {
+ if (!cache_account_policy_set(type, *value)) {
DEBUG(0,("ldapsam_get_account_policy: failed to update local "
"tdb as a cache\n"));
return NT_STATUS_UNSUCCESSFUL;
@@ -4185,14 +4203,14 @@ static char *get_ldap_filter(TALLOC_CTX *mem_ctx, const char *username)
goto done;
}
- escaped = escape_ldap_string_alloc(username);
+ escaped = escape_ldap_string(talloc_tos(), username);
if (escaped == NULL) goto done;
result = talloc_string_sub(mem_ctx, filter, "%u", username);
done:
SAFE_FREE(filter);
- SAFE_FREE(escaped);
+ TALLOC_FREE(escaped);
return result;
}
@@ -4994,10 +5012,10 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods,
is_machine = True;
}
- username = escape_ldap_string_alloc(name);
+ username = escape_ldap_string(talloc_tos(), name);
filter = talloc_asprintf(tmp_ctx, "(&(uid=%s)(objectClass=%s))",
username, LDAP_OBJ_POSIXACCOUNT);
- SAFE_FREE(username);
+ TALLOC_FREE(username);
rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
if (rc != LDAP_SUCCESS) {
@@ -5270,10 +5288,10 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods,
gid_t gid = -1;
int rc;
- groupname = escape_ldap_string_alloc(name);
+ groupname = escape_ldap_string(talloc_tos(), name);
filter = talloc_asprintf(tmp_ctx, "(&(cn=%s)(objectClass=%s))",
groupname, LDAP_OBJ_POSIXGROUP);
- SAFE_FREE(groupname);
+ TALLOC_FREE(groupname);
rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result);
if (rc != LDAP_SUCCESS) {
@@ -5702,7 +5720,8 @@ static NTSTATUS ldapsam_set_primary_group(struct pdb_methods *my_methods,
return NT_STATUS_NO_MEMORY;
}
- escape_username = escape_ldap_string_alloc(pdb_get_username(sampass));
+ escape_username = escape_ldap_string(talloc_tos(),
+ pdb_get_username(sampass));
if (escape_username== NULL) {
return NT_STATUS_NO_MEMORY;
}
@@ -5715,7 +5734,7 @@ static NTSTATUS ldapsam_set_primary_group(struct pdb_methods *my_methods,
LDAP_OBJ_POSIXACCOUNT,
LDAP_OBJ_SAMBASAMACCOUNT);
- SAFE_FREE(escape_username);
+ TALLOC_FREE(escape_username);
if (filter == NULL) {
return NT_STATUS_NO_MEMORY;
diff --git a/source3/passdb/pdb_wbc_sam.c b/source3/passdb/pdb_wbc_sam.c
index ec54d553d1..df80411a7a 100644
--- a/source3/passdb/pdb_wbc_sam.c
+++ b/source3/passdb/pdb_wbc_sam.c
@@ -167,12 +167,12 @@ done:
return result;
}
-static NTSTATUS pdb_wbc_sam_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value)
+static NTSTATUS pdb_wbc_sam_get_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t *value)
{
return NT_STATUS_UNSUCCESSFUL;
}
-static NTSTATUS pdb_wbc_sam_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value)
+static NTSTATUS pdb_wbc_sam_set_account_policy(struct pdb_methods *methods, enum pdb_policy_type type, uint32_t value)
{
return NT_STATUS_UNSUCCESSFUL;
}
@@ -316,13 +316,12 @@ static NTSTATUS pdb_wbc_sam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map
const char *name)
{
NTSTATUS result = NT_STATUS_OK;
- char *user_name = NULL;
- char *domain = NULL;
+ const char *domain = "";
DOM_SID sid;
gid_t gid;
enum lsa_SidType name_type;
- if (!winbind_lookup_name(domain, user_name, &sid, &name_type)) {
+ if (!winbind_lookup_name(domain, name, &sid, &name_type)) {
result = NT_STATUS_NO_SUCH_GROUP;
goto done;
}
@@ -340,7 +339,7 @@ static NTSTATUS pdb_wbc_sam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map
goto done;
}
- if (!_make_group_map(methods, domain, user_name, name_type, gid, &sid, map)) {
+ if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) {
result = NT_STATUS_NO_SUCH_GROUP;
goto done;
}
diff --git a/source3/printing/printfsp.c b/source3/printing/printfsp.c
index a8e175a684..9185fc84b1 100644
--- a/source3/printing/printfsp.c
+++ b/source3/printing/printfsp.c
@@ -58,6 +58,13 @@ NTSTATUS print_fsp_open(struct smb_request *req, connection_struct *conn,
return NT_STATUS_ACCESS_DENIED; /* No errno around here */
}
+ status = create_synthetic_smb_fname(fsp,
+ print_job_fname(lp_const_servicename(SNUM(conn)), jobid), NULL,
+ NULL, &fsp->fsp_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ pjob_delete(lp_const_servicename(SNUM(conn)), jobid);
+ return status;
+ }
/* setup a full fsp */
fsp->fh->fd = print_job_fd(lp_const_servicename(SNUM(conn)),jobid);
GetTimeOfDay(&fsp->open_time);
@@ -72,7 +79,6 @@ NTSTATUS print_fsp_open(struct smb_request *req, connection_struct *conn,
fsp->oplock_type = NO_OPLOCK;
fsp->sent_oplock_break = NO_BREAK_SENT;
fsp->is_directory = False;
- string_set(&fsp->fsp_name,print_job_fname(lp_const_servicename(SNUM(conn)),jobid));
fsp->wcp = NULL;
SMB_VFS_FSTAT(fsp, psbuf);
fsp->mode = psbuf->st_ex_mode;
@@ -98,7 +104,7 @@ void print_fsp_end(files_struct *fsp, enum file_close_type close_type)
}
if (fsp->fsp_name) {
- string_free(&fsp->fsp_name);
+ TALLOC_FREE(fsp->fsp_name);
}
if (!rap_to_pjobid(fsp->rap_print_jobid, NULL, &jobid)) {
diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c
index e296d319e2..dec43ae741 100644
--- a/source3/registry/reg_backend_db.c
+++ b/source3/registry/reg_backend_db.c
@@ -2,6 +2,7 @@
* Unix SMB/CIFS implementation.
* Virtual Windows Registry Layer
* Copyright (C) Gerald Carter 2002-2005
+ * Copyright (C) Michael Adam 2007-2009
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,8 +28,16 @@
static struct db_context *regdb = NULL;
static int regdb_refcount;
-static bool regdb_key_exists(const char *key);
+static bool regdb_key_exists(struct db_context *db, const char *key);
static bool regdb_key_is_base_key(const char *key);
+static WERROR regdb_fetch_keys_internal(struct db_context *db, const char *key,
+ struct regsubkey_ctr *ctr);
+static bool regdb_store_keys_internal(struct db_context *db, const char *key,
+ struct regsubkey_ctr *ctr);
+static int regdb_fetch_values_internal(struct db_context *db, const char* key,
+ struct regval_ctr *values);
+static bool regdb_store_values_internal(struct db_context *db, const char *key,
+ struct regval_ctr *values);
/* List the deepest path into the registry. All part components will be created.*/
@@ -94,7 +103,8 @@ static struct builtin_regkey_value builtin_registry_values[] = {
* Initialize a key in the registry:
* create each component key of the specified path.
*/
-static WERROR init_registry_key_internal(const char *add_path)
+static WERROR init_registry_key_internal(struct db_context *db,
+ const char *add_path)
{
WERROR werr;
TALLOC_CTX *frame = talloc_stackframe();
@@ -173,14 +183,20 @@ static WERROR init_registry_key_internal(const char *add_path)
goto fail;
}
- regdb_fetch_keys(base, subkeys);
+ werr = regdb_fetch_keys_internal(db, base, subkeys);
+ if (!W_ERROR_IS_OK(werr) &&
+ !W_ERROR_EQUAL(werr, WERR_NOT_FOUND))
+ {
+ goto fail;
+ }
+
if (*subkeyname) {
werr = regsubkey_ctr_addkey(subkeys, subkeyname);
if (!W_ERROR_IS_OK(werr)) {
goto fail;
}
}
- if (!regdb_store_keys( base, subkeys)) {
+ if (!regdb_store_keys_internal(db, base, subkeys)) {
werr = WERR_CAN_NOT_COMPLETE;
goto fail;
}
@@ -193,6 +209,20 @@ fail:
return werr;
}
+struct init_registry_key_context {
+ const char *add_path;
+};
+
+static NTSTATUS init_registry_key_action(struct db_context *db,
+ void *private_data)
+{
+ struct init_registry_key_context *init_ctx =
+ (struct init_registry_key_context *)private_data;
+
+ return werror_to_ntstatus(init_registry_key_internal(
+ db, init_ctx->add_path));
+}
+
/**
* Initialize a key in the registry:
* create each component key of the specified path,
@@ -200,40 +230,104 @@ fail:
*/
WERROR init_registry_key(const char *add_path)
{
- WERROR werr;
+ struct init_registry_key_context init_ctx;
- if (regdb_key_exists(add_path)) {
+ if (regdb_key_exists(regdb, add_path)) {
return WERR_OK;
}
- if (regdb->transaction_start(regdb) != 0) {
- DEBUG(0, ("init_registry_key: transaction_start failed\n"));
- return WERR_REG_IO_FAILURE;
- }
+ init_ctx.add_path = add_path;
- werr = init_registry_key_internal(add_path);
- if (!W_ERROR_IS_OK(werr)) {
- goto fail;
+ return ntstatus_to_werror(dbwrap_trans_do(regdb,
+ init_registry_key_action,
+ &init_ctx));
+}
+
+/***********************************************************************
+ Open the registry data in the tdb
+ ***********************************************************************/
+
+static void regdb_ctr_add_value(struct regval_ctr *ctr,
+ struct builtin_regkey_value *value)
+{
+ UNISTR2 data;
+
+ switch(value->type) {
+ case REG_DWORD:
+ regval_ctr_addvalue(ctr, value->valuename, REG_DWORD,
+ (char*)&value->data.dw_value,
+ sizeof(uint32));
+ break;
+
+ case REG_SZ:
+ init_unistr2(&data, value->data.string, UNI_STR_TERMINATE);
+ regval_ctr_addvalue(ctr, value->valuename, REG_SZ,
+ (char*)data.buffer,
+ data.uni_str_len*sizeof(uint16));
+ break;
+
+ default:
+ DEBUG(0, ("regdb_ctr_add_value: invalid value type in "
+ "registry values [%d]\n", value->type));
}
+}
- if (regdb->transaction_commit(regdb) != 0) {
- DEBUG(0, ("init_registry_key: Could not commit transaction\n"));
- return WERR_REG_IO_FAILURE;
+static NTSTATUS init_registry_data_action(struct db_context *db,
+ void *private_data)
+{
+ NTSTATUS status;
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct regval_ctr *values;
+ int i;
+
+ /* loop over all of the predefined paths and add each component */
+
+ for (i=0; builtin_registry_paths[i] != NULL; i++) {
+ if (regdb_key_exists(db, builtin_registry_paths[i])) {
+ continue;
+ }
+ status = werror_to_ntstatus(init_registry_key_internal(db,
+ builtin_registry_paths[i]));
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
}
- return WERR_OK;
+ /* loop over all of the predefined values and add each component */
-fail:
- if (regdb->transaction_cancel(regdb) != 0) {
- smb_panic("init_registry_key: transaction_cancel failed\n");
+ for (i=0; builtin_registry_values[i].path != NULL; i++) {
+
+ values = TALLOC_ZERO_P(frame, struct regval_ctr);
+ if (values == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ regdb_fetch_values_internal(db,
+ builtin_registry_values[i].path,
+ values);
+
+ /* preserve existing values across restarts. Only add new ones */
+
+ if (!regval_ctr_key_exists(values,
+ builtin_registry_values[i].valuename))
+ {
+ regdb_ctr_add_value(values,
+ &builtin_registry_values[i]);
+ regdb_store_values_internal(db,
+ builtin_registry_values[i].path,
+ values);
+ }
+ TALLOC_FREE(values);
}
- return werr;
-}
+ status = NT_STATUS_OK;
-/***********************************************************************
- Open the registry data in the tdb
- ***********************************************************************/
+done:
+
+ TALLOC_FREE(frame);
+ return status;
+}
WERROR init_registry_data(void)
{
@@ -241,14 +335,13 @@ WERROR init_registry_data(void)
TALLOC_CTX *frame = talloc_stackframe();
struct regval_ctr *values;
int i;
- UNISTR2 data;
/*
* First, check for the existence of the needed keys and values.
* If all do already exist, we can save the writes.
*/
for (i=0; builtin_registry_paths[i] != NULL; i++) {
- if (!regdb_key_exists(builtin_registry_paths[i])) {
+ if (!regdb_key_exists(regdb, builtin_registry_paths[i])) {
goto do_init;
}
}
@@ -260,7 +353,9 @@ WERROR init_registry_data(void)
goto done;
}
- regdb_fetch_values(builtin_registry_values[i].path, values);
+ regdb_fetch_values_internal(regdb,
+ builtin_registry_values[i].path,
+ values);
if (!regval_ctr_key_exists(values,
builtin_registry_values[i].valuename))
{
@@ -284,89 +379,9 @@ do_init:
* transaction behaviour.
*/
- if (regdb->transaction_start(regdb) != 0) {
- DEBUG(0, ("init_registry_data: tdb_transaction_start "
- "failed\n"));
- werr = WERR_REG_IO_FAILURE;
- goto done;
- }
-
- /* loop over all of the predefined paths and add each component */
-
- for (i=0; builtin_registry_paths[i] != NULL; i++) {
- if (regdb_key_exists(builtin_registry_paths[i])) {
- continue;
- }
- werr = init_registry_key_internal(builtin_registry_paths[i]);
- if (!W_ERROR_IS_OK(werr)) {
- goto fail;
- }
- }
-
- /* loop over all of the predefined values and add each component */
-
- for (i=0; builtin_registry_values[i].path != NULL; i++) {
-
- values = TALLOC_ZERO_P(frame, struct regval_ctr);
- if (values == NULL) {
- werr = WERR_NOMEM;
- goto fail;
- }
-
- regdb_fetch_values(builtin_registry_values[i].path, values);
-
- /* preserve existing values across restarts. Only add new ones */
-
- if (!regval_ctr_key_exists(values,
- builtin_registry_values[i].valuename))
- {
- switch(builtin_registry_values[i].type) {
- case REG_DWORD:
- regval_ctr_addvalue(values,
- builtin_registry_values[i].valuename,
- REG_DWORD,
- (char*)&builtin_registry_values[i].data.dw_value,
- sizeof(uint32));
- break;
-
- case REG_SZ:
- init_unistr2(&data,
- builtin_registry_values[i].data.string,
- UNI_STR_TERMINATE);
- regval_ctr_addvalue(values,
- builtin_registry_values[i].valuename,
- REG_SZ,
- (char*)data.buffer,
- data.uni_str_len*sizeof(uint16));
- break;
-
- default:
- DEBUG(0, ("init_registry_data: invalid value "
- "type in builtin_registry_values "
- "[%d]\n",
- builtin_registry_values[i].type));
- }
- regdb_store_values(builtin_registry_values[i].path,
- values);
- }
- TALLOC_FREE(values);
- }
-
- if (regdb->transaction_commit(regdb) != 0) {
- DEBUG(0, ("init_registry_data: Could not commit "
- "transaction\n"));
- werr = WERR_REG_IO_FAILURE;
- } else {
- werr = WERR_OK;
- }
-
- goto done;
-
-fail:
- if (regdb->transaction_cancel(regdb) != 0) {
- smb_panic("init_registry_data: tdb_transaction_cancel "
- "failed\n");
- }
+ werr = ntstatus_to_werror(dbwrap_trans_do(regdb,
+ init_registry_data_action,
+ NULL));
done:
TALLOC_FREE(frame);
@@ -511,7 +526,8 @@ int regdb_get_seqnum(void)
}
-static WERROR regdb_delete_key_with_prefix(const char *keyname,
+static WERROR regdb_delete_key_with_prefix(struct db_context *db,
+ const char *keyname,
const char *prefix)
{
char *path;
@@ -537,7 +553,7 @@ static WERROR regdb_delete_key_with_prefix(const char *keyname,
goto done;
}
- werr = ntstatus_to_werror(dbwrap_delete_bystring(regdb, path));
+ werr = ntstatus_to_werror(dbwrap_delete_bystring(db, path));
/* treat "not" found" as ok */
if (W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) {
@@ -550,40 +566,40 @@ done:
}
-static WERROR regdb_delete_values(const char *keyname)
+static WERROR regdb_delete_values(struct db_context *db, const char *keyname)
{
- return regdb_delete_key_with_prefix(keyname, REG_VALUE_PREFIX);
+ return regdb_delete_key_with_prefix(db, keyname, REG_VALUE_PREFIX);
}
-static WERROR regdb_delete_secdesc(const char *keyname)
+static WERROR regdb_delete_secdesc(struct db_context *db, const char *keyname)
{
- return regdb_delete_key_with_prefix(keyname, REG_SECDESC_PREFIX);
+ return regdb_delete_key_with_prefix(db, keyname, REG_SECDESC_PREFIX);
}
-static WERROR regdb_delete_subkeylist(const char *keyname)
+static WERROR regdb_delete_subkeylist(struct db_context *db, const char *keyname)
{
- return regdb_delete_key_with_prefix(keyname, NULL);
+ return regdb_delete_key_with_prefix(db, keyname, NULL);
}
-static WERROR regdb_delete_key_lists(const char *keyname)
+static WERROR regdb_delete_key_lists(struct db_context *db, const char *keyname)
{
WERROR werr;
- werr = regdb_delete_values(keyname);
+ werr = regdb_delete_values(db, keyname);
if (!W_ERROR_IS_OK(werr)) {
DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n",
REG_VALUE_PREFIX, keyname, win_errstr(werr)));
goto done;
}
- werr = regdb_delete_secdesc(keyname);
+ werr = regdb_delete_secdesc(db, keyname);
if (!W_ERROR_IS_OK(werr)) {
DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n",
REG_SECDESC_PREFIX, keyname, win_errstr(werr)));
goto done;
}
- werr = regdb_delete_subkeylist(keyname);
+ werr = regdb_delete_subkeylist(db, keyname);
if (!W_ERROR_IS_OK(werr)) {
DEBUG(1, (__location__ " Deleting %s failed: %s\n",
keyname, win_errstr(werr)));
@@ -600,33 +616,42 @@ done:
fstrings
***********************************************************************/
-static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr)
+static WERROR regdb_store_keys_internal2(struct db_context *db,
+ const char *key,
+ struct regsubkey_ctr *ctr)
{
TDB_DATA dbuf;
uint8 *buffer = NULL;
int i = 0;
uint32 len, buflen;
- bool ret = true;
uint32 num_subkeys = regsubkey_ctr_numkeys(ctr);
char *keyname = NULL;
TALLOC_CTX *ctx = talloc_stackframe();
- NTSTATUS status;
+ WERROR werr;
if (!key) {
- return false;
+ werr = WERR_INVALID_PARAM;
+ goto done;
}
keyname = talloc_strdup(ctx, key);
if (!keyname) {
- return false;
+ werr = WERR_NOMEM;
+ goto done;
}
+
keyname = normalize_reg_path(ctx, keyname);
+ if (!keyname) {
+ werr = WERR_NOMEM;
+ goto done;
+ }
/* allocate some initial memory */
buffer = (uint8 *)SMB_MALLOC(1024);
if (buffer == NULL) {
- return false;
+ werr = WERR_NOMEM;
+ goto done;
}
buflen = 1024;
len = 0;
@@ -654,7 +679,7 @@ static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr
DEBUG(0, ("regdb_store_keys: Failed to realloc "
"memory of size [%u]\n",
(unsigned int)(len+thistime)*2));
- ret = false;
+ werr = WERR_NOMEM;
goto done;
}
buflen = (len+thistime)*2;
@@ -663,7 +688,7 @@ static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr
regsubkey_ctr_specific_key(ctr, i));
if (thistime2 != thistime) {
DEBUG(0, ("tdb_pack failed\n"));
- ret = false;
+ werr = WERR_CAN_NOT_COMPLETE;
goto done;
}
}
@@ -674,11 +699,9 @@ static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr
dbuf.dptr = buffer;
dbuf.dsize = len;
- status = dbwrap_store_bystring(regdb, keyname, dbuf, TDB_REPLACE);
- if (!NT_STATUS_IS_OK(status)) {
- ret = false;
- goto done;
- }
+ werr = ntstatus_to_werror(dbwrap_store_bystring(db, keyname, dbuf,
+ TDB_REPLACE));
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
/*
* Delete a sorted subkey cache for regdb_key_exists, will be
@@ -686,14 +709,22 @@ static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr
*/
keyname = talloc_asprintf(ctx, "%s/%s", REG_SORTED_SUBKEYS_PREFIX,
keyname);
- if (keyname != NULL) {
- dbwrap_delete_bystring(regdb, keyname);
+ if (keyname == NULL) {
+ werr = WERR_NOMEM;
+ goto done;
+ }
+
+ werr = ntstatus_to_werror(dbwrap_delete_bystring(db, keyname));
+
+ /* don't treat WERR_NOT_FOUND as an error here */
+ if (W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) {
+ werr = WERR_OK;
}
done:
TALLOC_FREE(ctx);
SAFE_FREE(buffer);
- return ret;
+ return werr;
}
/***********************************************************************
@@ -701,73 +732,37 @@ done:
do not currently exist
***********************************************************************/
-bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
+struct regdb_store_keys_context {
+ const char *key;
+ struct regsubkey_ctr *ctr;
+};
+
+static NTSTATUS regdb_store_keys_action(struct db_context *db,
+ void *private_data)
{
- int num_subkeys, old_num_subkeys, i;
+ struct regdb_store_keys_context *store_ctx;
+ WERROR werr;
+ int num_subkeys, i;
char *path = NULL;
struct regsubkey_ctr *subkeys = NULL, *old_subkeys = NULL;
char *oldkeyname = NULL;
- TALLOC_CTX *ctx = talloc_stackframe();
- WERROR werr;
-
- if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) {
- goto fail;
- }
-
- /*
- * fetch a list of the old subkeys so we can determine if anything has
- * changed
- */
-
- werr = regsubkey_ctr_init(ctx, &old_subkeys);
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
- return false;
- }
-
- regdb_fetch_keys(key, old_subkeys);
-
- num_subkeys = regsubkey_ctr_numkeys(ctr);
- old_num_subkeys = regsubkey_ctr_numkeys(old_subkeys);
- if ((num_subkeys && old_num_subkeys) &&
- (num_subkeys == old_num_subkeys)) {
-
- for (i = 0; i < num_subkeys; i++) {
- if (strcmp(regsubkey_ctr_specific_key(ctr, i),
- regsubkey_ctr_specific_key(old_subkeys, i))
- != 0)
- {
- break;
- }
- }
- if (i == num_subkeys) {
- /*
- * Nothing changed, no point to even start a tdb
- * transaction
- */
- TALLOC_FREE(old_subkeys);
- return true;
- }
- }
-
- TALLOC_FREE(old_subkeys);
+ TALLOC_CTX *mem_ctx = talloc_stackframe();
- if (regdb->transaction_start(regdb) != 0) {
- DEBUG(0, ("regdb_store_keys: transaction_start failed\n"));
- goto fail;
- }
+ store_ctx = (struct regdb_store_keys_context *)private_data;
/*
* Re-fetch the old keys inside the transaction
*/
- werr = regsubkey_ctr_init(ctx, &old_subkeys);
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
- goto cancel;
- }
+ werr = regsubkey_ctr_init(mem_ctx, &old_subkeys);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
- regdb_fetch_keys(key, old_subkeys);
+ werr = regdb_fetch_keys_internal(db, store_ctx->key, old_subkeys);
+ if (!W_ERROR_IS_OK(werr) &&
+ !W_ERROR_EQUAL(werr, WERR_NOT_FOUND))
+ {
+ goto done;
+ }
/*
* Make the store operation as safe as possible without transactions:
@@ -796,21 +791,22 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
for (i=0; i<num_subkeys; i++) {
oldkeyname = regsubkey_ctr_specific_key(old_subkeys, i);
- if (regsubkey_ctr_key_exists(ctr, oldkeyname)) {
+ if (regsubkey_ctr_key_exists(store_ctx->ctr, oldkeyname)) {
/*
* It's still around, don't delete
*/
-
continue;
}
- path = talloc_asprintf(ctx, "%s/%s", key, oldkeyname);
+ path = talloc_asprintf(mem_ctx, "%s/%s", store_ctx->key,
+ oldkeyname);
if (!path) {
- goto cancel;
+ werr = WERR_NOMEM;
+ goto done;
}
- werr = regdb_delete_key_lists(path);
- W_ERROR_NOT_OK_GOTO(werr, cancel);
+ werr = regdb_delete_key_lists(db, path);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
TALLOC_FREE(path);
}
@@ -819,51 +815,51 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
/* (2) store the subkey list for the parent */
- if (!regdb_store_keys_internal(key, ctr) ) {
+ werr = regdb_store_keys_internal2(db, store_ctx->key, store_ctx->ctr);
+ if (!W_ERROR_IS_OK(werr)) {
DEBUG(0,("regdb_store_keys: Failed to store new subkey list "
- "for parent [%s]\n", key));
- goto cancel;
+ "for parent [%s]: %s\n", store_ctx->key,
+ win_errstr(werr)));
+ goto done;
}
/* (3) now create records for any subkeys that don't already exist */
- num_subkeys = regsubkey_ctr_numkeys(ctr);
+ num_subkeys = regsubkey_ctr_numkeys(store_ctx->ctr);
if (num_subkeys == 0) {
- werr = regsubkey_ctr_init(ctx, &subkeys);
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
- goto cancel;
- }
+ werr = regsubkey_ctr_init(mem_ctx, &subkeys);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
- if (!regdb_store_keys_internal(key, subkeys)) {
+ werr = regdb_store_keys_internal2(db, store_ctx->key, subkeys);
+ if (!W_ERROR_IS_OK(werr)) {
DEBUG(0,("regdb_store_keys: Failed to store "
- "new record for key [%s]\n", key));
- goto cancel;
+ "new record for key [%s]: %s\n",
+ store_ctx->key, win_errstr(werr)));
+ goto done;
}
TALLOC_FREE(subkeys);
-
}
for (i=0; i<num_subkeys; i++) {
- path = talloc_asprintf(ctx, "%s/%s",
- key,
- regsubkey_ctr_specific_key(ctr, i));
+ path = talloc_asprintf(mem_ctx, "%s/%s", store_ctx->key,
+ regsubkey_ctr_specific_key(store_ctx->ctr, i));
if (!path) {
- goto cancel;
- }
- werr = regsubkey_ctr_init(ctx, &subkeys);
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
- goto cancel;
+ werr = WERR_NOMEM;
+ goto done;
}
+ werr = regsubkey_ctr_init(mem_ctx, &subkeys);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
- if (regdb_fetch_keys( path, subkeys ) == -1) {
+ werr = regdb_fetch_keys_internal(db, path, subkeys);
+ if (!W_ERROR_IS_OK(werr)) {
/* create a record with 0 subkeys */
- if (!regdb_store_keys_internal(path, subkeys)) {
+ werr = regdb_store_keys_internal2(db, path, subkeys);
+ if (!W_ERROR_IS_OK(werr)) {
DEBUG(0,("regdb_store_keys: Failed to store "
- "new record for key [%s]\n", path));
- goto cancel;
+ "new record for key [%s]: %s\n", path,
+ win_errstr(werr)));
+ goto done;
}
}
@@ -871,23 +867,129 @@ bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
TALLOC_FREE(path);
}
- if (regdb->transaction_commit(regdb) != 0) {
- DEBUG(0, ("regdb_store_keys: Could not commit transaction\n"));
- goto fail;
+ werr = WERR_OK;
+
+done:
+ talloc_free(mem_ctx);
+ return werror_to_ntstatus(werr);
+}
+
+static bool regdb_store_keys_internal(struct db_context *db, const char *key,
+ struct regsubkey_ctr *ctr)
+{
+ int num_subkeys, old_num_subkeys, i;
+ struct regsubkey_ctr *old_subkeys = NULL;
+ TALLOC_CTX *ctx = talloc_stackframe();
+ WERROR werr;
+ bool ret = false;
+ struct regdb_store_keys_context store_ctx;
+
+ if (!regdb_key_is_base_key(key) && !regdb_key_exists(db, key)) {
+ goto done;
}
- TALLOC_FREE(ctx);
- return true;
+ /*
+ * fetch a list of the old subkeys so we can determine if anything has
+ * changed
+ */
+
+ werr = regsubkey_ctr_init(ctx, &old_subkeys);
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
+ goto done;
+ }
-cancel:
- if (regdb->transaction_cancel(regdb) != 0) {
- smb_panic("regdb_store_keys: transaction_cancel failed\n");
+ werr = regdb_fetch_keys_internal(db, key, old_subkeys);
+ if (!W_ERROR_IS_OK(werr) &&
+ !W_ERROR_EQUAL(werr, WERR_NOT_FOUND))
+ {
+ goto done;
}
-fail:
+ num_subkeys = regsubkey_ctr_numkeys(ctr);
+ old_num_subkeys = regsubkey_ctr_numkeys(old_subkeys);
+ if ((num_subkeys && old_num_subkeys) &&
+ (num_subkeys == old_num_subkeys)) {
+
+ for (i = 0; i < num_subkeys; i++) {
+ if (strcmp(regsubkey_ctr_specific_key(ctr, i),
+ regsubkey_ctr_specific_key(old_subkeys, i))
+ != 0)
+ {
+ break;
+ }
+ }
+ if (i == num_subkeys) {
+ /*
+ * Nothing changed, no point to even start a tdb
+ * transaction
+ */
+
+ ret = true;
+ goto done;
+ }
+ }
+
+ TALLOC_FREE(old_subkeys);
+
+ store_ctx.key = key;
+ store_ctx.ctr = ctr;
+
+ werr = ntstatus_to_werror(dbwrap_trans_do(db,
+ regdb_store_keys_action,
+ &store_ctx));
+
+ ret = W_ERROR_IS_OK(werr);
+
+done:
TALLOC_FREE(ctx);
- return false;
+ return ret;
+}
+
+bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr)
+{
+ return regdb_store_keys_internal(regdb, key, ctr);
+}
+
+/**
+ * create a subkey of a given key
+ */
+
+struct regdb_create_subkey_context {
+ const char *key;
+ const char *subkey;
+};
+
+static NTSTATUS regdb_create_subkey_action(struct db_context *db,
+ void *private_data)
+{
+ WERROR werr;
+ struct regdb_create_subkey_context *create_ctx;
+ struct regsubkey_ctr *subkeys;
+ TALLOC_CTX *mem_ctx = talloc_stackframe();
+
+ create_ctx = (struct regdb_create_subkey_context *)private_data;
+
+ werr = regsubkey_ctr_init(mem_ctx, &subkeys);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+ werr = regdb_fetch_keys_internal(db, create_ctx->key, subkeys);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+ werr = regsubkey_ctr_addkey(subkeys, create_ctx->subkey);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+ werr = regdb_store_keys_internal2(db, create_ctx->key, subkeys);
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(0, (__location__ " failed to store new subkey list for "
+ "parent key %s: %s\n", create_ctx->key,
+ win_errstr(werr)));
+ }
+
+done:
+ talloc_free(mem_ctx);
+ return werror_to_ntstatus(werr);
}
static WERROR regdb_create_subkey(const char *key, const char *subkey)
@@ -895,8 +997,9 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey)
WERROR werr;
struct regsubkey_ctr *subkeys;
TALLOC_CTX *mem_ctx = talloc_stackframe();
+ struct regdb_create_subkey_context create_ctx;
- if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) {
+ if (!regdb_key_is_base_key(key) && !regdb_key_exists(regdb, key)) {
werr = WERR_NOT_FOUND;
goto done;
}
@@ -904,10 +1007,8 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey)
werr = regsubkey_ctr_init(mem_ctx, &subkeys);
W_ERROR_NOT_OK_GOTO_DONE(werr);
- if (regdb_fetch_keys(key, subkeys) < 0) {
- werr = WERR_REG_IO_FAILURE;
- goto done;
- }
+ werr = regdb_fetch_keys_internal(regdb, key, subkeys);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
if (regsubkey_ctr_key_exists(subkeys, subkey)) {
werr = WERR_OK;
@@ -916,55 +1017,70 @@ static WERROR regdb_create_subkey(const char *key, const char *subkey)
talloc_free(subkeys);
- werr = regdb_transaction_start();
- W_ERROR_NOT_OK_GOTO_DONE(werr);
+ create_ctx.key = key;
+ create_ctx.subkey = subkey;
- werr = regsubkey_ctr_init(mem_ctx, &subkeys);
- W_ERROR_NOT_OK_GOTO(werr, cancel);
+ werr = ntstatus_to_werror(dbwrap_trans_do(regdb,
+ regdb_create_subkey_action,
+ &create_ctx));
- if (regdb_fetch_keys(key, subkeys) < 0) {
- werr = WERR_REG_IO_FAILURE;
- goto cancel;
- }
+done:
+ talloc_free(mem_ctx);
+ return werr;
+}
- werr = regsubkey_ctr_addkey(subkeys, subkey);
- W_ERROR_NOT_OK_GOTO(werr, cancel);
+/**
+ * create a subkey of a given key
+ */
- if (!regdb_store_keys_internal(key, subkeys)) {
- DEBUG(0, (__location__ " failed to store new subkey list for "
- "parent key %s\n", key));
- werr = WERR_REG_IO_FAILURE;
- goto cancel;
- }
+struct regdb_delete_subkey_context {
+ const char *key;
+ const char *subkey;
+ const char *path;
+};
- werr = regdb_transaction_commit();
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(0, (__location__ " failed to commit transaction: %s\n",
- win_errstr(werr)));
- }
+static NTSTATUS regdb_delete_subkey_action(struct db_context *db,
+ void *private_data)
+{
+ WERROR werr;
+ struct regdb_delete_subkey_context *delete_ctx;
+ struct regsubkey_ctr *subkeys;
+ TALLOC_CTX *mem_ctx = talloc_stackframe();
- goto done;
+ delete_ctx = (struct regdb_delete_subkey_context *)private_data;
+
+ werr = regdb_delete_key_lists(db, delete_ctx->path);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+ werr = regsubkey_ctr_init(mem_ctx, &subkeys);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+ werr = regdb_fetch_keys_internal(db, delete_ctx->key, subkeys);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
-cancel:
- werr = regdb_transaction_cancel();
+ werr = regsubkey_ctr_delkey(subkeys, delete_ctx->subkey);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+ werr = regdb_store_keys_internal2(db, delete_ctx->key, subkeys);
if (!W_ERROR_IS_OK(werr)) {
- DEBUG(0, (__location__ " failed to cancel transaction: %s\n",
+ DEBUG(0, (__location__ " failed to store new subkey_list for "
+ "parent key %s: %s\n", delete_ctx->key,
win_errstr(werr)));
}
done:
talloc_free(mem_ctx);
- return werr;
+ return werror_to_ntstatus(werr);
}
static WERROR regdb_delete_subkey(const char *key, const char *subkey)
{
- WERROR werr, werr2;
- struct regsubkey_ctr *subkeys;
+ WERROR werr;
char *path;
+ struct regdb_delete_subkey_context delete_ctx;
TALLOC_CTX *mem_ctx = talloc_stackframe();
- if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) {
+ if (!regdb_key_is_base_key(key) && !regdb_key_exists(regdb, key)) {
werr = WERR_NOT_FOUND;
goto done;
}
@@ -975,56 +1091,26 @@ static WERROR regdb_delete_subkey(const char *key, const char *subkey)
goto done;
}
- if (!regdb_key_exists(path)) {
+ if (!regdb_key_exists(regdb, path)) {
werr = WERR_OK;
goto done;
}
- werr = regdb_transaction_start();
- W_ERROR_NOT_OK_GOTO_DONE(werr);
-
- werr = regdb_delete_key_lists(path);
- W_ERROR_NOT_OK_GOTO(werr, cancel);
-
- werr = regsubkey_ctr_init(mem_ctx, &subkeys);
- W_ERROR_NOT_OK_GOTO(werr, cancel);
-
- if (regdb_fetch_keys(key, subkeys) < 0) {
- werr = WERR_REG_IO_FAILURE;
- goto cancel;
- }
-
- werr = regsubkey_ctr_delkey(subkeys, subkey);
- W_ERROR_NOT_OK_GOTO(werr, cancel);
+ delete_ctx.key = key;
+ delete_ctx.subkey = subkey;
+ delete_ctx.path = path;
- if (!regdb_store_keys_internal(key, subkeys)) {
- DEBUG(0, (__location__ " failed to store new subkey_list for "
- "parent key %s\n", key));
- werr = WERR_REG_IO_FAILURE;
- goto cancel;
- }
-
- werr = regdb_transaction_commit();
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(0, (__location__ " failed to commit transaction: %s\n",
- win_errstr(werr)));
- }
-
- goto done;
-
-cancel:
- werr2 = regdb_transaction_cancel();
- if (!W_ERROR_IS_OK(werr2)) {
- DEBUG(0, (__location__ " failed to cancel transaction: %s\n",
- win_errstr(werr2)));
- }
+ werr = ntstatus_to_werror(dbwrap_trans_do(regdb,
+ regdb_delete_subkey_action,
+ &delete_ctx));
done:
talloc_free(mem_ctx);
return werr;
}
-static TDB_DATA regdb_fetch_key_internal(TALLOC_CTX *mem_ctx, const char *key)
+static TDB_DATA regdb_fetch_key_internal(struct db_context *db,
+ TALLOC_CTX *mem_ctx, const char *key)
{
char *path = NULL;
TDB_DATA data;
@@ -1034,7 +1120,7 @@ static TDB_DATA regdb_fetch_key_internal(TALLOC_CTX *mem_ctx, const char *key)
return make_tdb_data(NULL, 0);
}
- data = dbwrap_fetch_bystring(regdb, mem_ctx, path);
+ data = dbwrap_fetch_bystring(db, mem_ctx, path);
TALLOC_FREE(path);
return data;
@@ -1091,7 +1177,7 @@ done:
* parent_subkey_scanner. The code uses parse_record() to avoid a memcpy of
* the potentially large subkey record.
*
- * The sorted subkey record is deleted in regdb_store_keys_internal and
+ * The sorted subkey record is deleted in regdb_store_keys_internal2 and
* recreated on demand.
*/
@@ -1100,39 +1186,58 @@ static int cmp_keynames(const void *p1, const void *p2)
return StrCaseCmp(*((char **)p1), *((char **)p2));
}
-static bool create_sorted_subkeys(const char *key, const char *sorted_keyname)
+struct create_sorted_subkeys_context {
+ const char *key;
+ const char *sorted_keyname;
+};
+
+static NTSTATUS create_sorted_subkeys_action(struct db_context *db,
+ void *private_data)
{
char **sorted_subkeys;
struct regsubkey_ctr *ctr;
- bool result = false;
NTSTATUS status;
char *buf;
char *p;
- int i, res;
+ int i;
size_t len;
int num_subkeys;
- WERROR werr;
+ struct create_sorted_subkeys_context *sorted_ctx;
- if (regdb->transaction_start(regdb) != 0) {
- DEBUG(0, ("create_sorted_subkeys: transaction_start "
- "failed\n"));
- return false;
- }
+ sorted_ctx = (struct create_sorted_subkeys_context *)private_data;
- werr = regsubkey_ctr_init(talloc_tos(), &ctr);
- if (!W_ERROR_IS_OK(werr)) {
- goto fail;
+ /*
+ * In this function, we only treat failing of the actual write to
+ * the db as a real error. All preliminary errors, at a stage when
+ * nothing has been written to the DB yet are treated as success
+ * to be committed (as an empty transaction).
+ *
+ * The reason is that this (disposable) call might be nested in other
+ * transactions. Doing a cancel here would destroy the possibility of
+ * a transaction_commit for transactions that we might be wrapped in.
+ */
+
+ status = werror_to_ntstatus(regsubkey_ctr_init(talloc_tos(), &ctr));
+ if (!NT_STATUS_IS_OK(status)) {
+ /* don't treat this as an error */
+ status = NT_STATUS_OK;
+ goto done;
}
- res = regdb_fetch_keys(key, ctr);
- if (res == -1) {
- goto fail;
+ status = werror_to_ntstatus(regdb_fetch_keys_internal(db,
+ sorted_ctx->key,
+ ctr));
+ if (!NT_STATUS_IS_OK(status)) {
+ /* don't treat this as an error */
+ status = NT_STATUS_OK;
+ goto done;
}
num_subkeys = regsubkey_ctr_numkeys(ctr);
sorted_subkeys = talloc_array(ctr, char *, num_subkeys);
if (sorted_subkeys == NULL) {
- goto fail;
+ /* don't treat this as an error */
+ goto done;
}
len = 4 + 4*num_subkeys;
@@ -1141,7 +1246,8 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname)
sorted_subkeys[i] = talloc_strdup_upper(sorted_subkeys,
regsubkey_ctr_specific_key(ctr, i));
if (sorted_subkeys[i] == NULL) {
- goto fail;
+ /* don't treat this as an error */
+ goto done;
}
len += strlen(sorted_subkeys[i])+1;
}
@@ -1150,7 +1256,8 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname)
buf = talloc_array(ctr, char, len);
if (buf == NULL) {
- goto fail;
+ /* don't treat this as an error */
+ goto done;
}
p = buf + 4 + 4*num_subkeys;
@@ -1164,38 +1271,28 @@ static bool create_sorted_subkeys(const char *key, const char *sorted_keyname)
}
status = dbwrap_store_bystring(
- regdb, sorted_keyname, make_tdb_data((uint8_t *)buf, len),
+ db, sorted_ctx->sorted_keyname, make_tdb_data((uint8_t *)buf,
+ len),
TDB_REPLACE);
- if (!NT_STATUS_IS_OK(status)) {
- /*
- * Don't use a "goto fail;" here, this would commit the broken
- * transaction. See below for an explanation.
- */
- if (regdb->transaction_cancel(regdb) == -1) {
- DEBUG(0, ("create_sorted_subkeys: transaction_cancel "
- "failed\n"));
- }
- TALLOC_FREE(ctr);
- return false;
- }
- result = true;
- fail:
- /*
- * We only get here via the "goto fail" when we did not write anything
- * yet. Using transaction_commit even in a failure case is necessary
- * because this (disposable) call might be nested in other
- * transactions. Doing a cancel here would destroy the possibility of
- * a transaction_commit for transactions that we might be wrapped in.
- */
- if (regdb->transaction_commit(regdb) == -1) {
- DEBUG(0, ("create_sorted_subkeys: transaction_start "
- "failed\n"));
- goto fail;
- }
+done:
+ talloc_free(ctr);
+ return status;
+}
- TALLOC_FREE(ctr);
- return result;
+static bool create_sorted_subkeys(const char *key, const char *sorted_keyname)
+{
+ NTSTATUS status;
+ struct create_sorted_subkeys_context sorted_ctx;
+
+ sorted_ctx.key = key;
+ sorted_ctx.sorted_keyname = sorted_keyname;
+
+ status = dbwrap_trans_do(regdb,
+ create_sorted_subkeys_action,
+ &sorted_ctx);
+
+ return NT_STATUS_IS_OK(status);
}
struct scan_subkey_state {
@@ -1241,7 +1338,8 @@ static int parent_subkey_scanner(TDB_DATA key, TDB_DATA data,
return 0;
}
-static bool scan_parent_subkeys(const char *parent, const char *name)
+static bool scan_parent_subkeys(struct db_context *db, const char *parent,
+ const char *name)
{
char *path = NULL;
char *key = NULL;
@@ -1268,8 +1366,8 @@ static bool scan_parent_subkeys(const char *parent, const char *name)
}
state.scanned = false;
- res = regdb->parse_record(regdb, string_term_tdb_data(key),
- parent_subkey_scanner, &state);
+ res = db->parse_record(db, string_term_tdb_data(key),
+ parent_subkey_scanner, &state);
if (state.scanned) {
result = state.found;
@@ -1277,8 +1375,8 @@ static bool scan_parent_subkeys(const char *parent, const char *name)
if (!create_sorted_subkeys(path, key)) {
goto fail;
}
- res = regdb->parse_record(regdb, string_term_tdb_data(key),
- parent_subkey_scanner, &state);
+ res = db->parse_record(db, string_term_tdb_data(key),
+ parent_subkey_scanner, &state);
if ((res == 0) && (state.scanned)) {
result = state.found;
}
@@ -1298,7 +1396,7 @@ static bool scan_parent_subkeys(const char *parent, const char *name)
* The exeption of this are keys without a parent key,
* i.e. the "base" keys (HKLM, HKCU, ...).
*/
-static bool regdb_key_exists(const char *key)
+static bool regdb_key_exists(struct db_context *db, const char *key)
{
TALLOC_CTX *mem_ctx = talloc_stackframe();
TDB_DATA value;
@@ -1322,11 +1420,11 @@ static bool regdb_key_exists(const char *key)
p = strrchr(path, '/');
if (p == NULL) {
/* this is a base key */
- value = regdb_fetch_key_internal(mem_ctx, path);
+ value = regdb_fetch_key_internal(db, mem_ctx, path);
ret = (value.dptr != NULL);
} else {
*p = '\0';
- ret = scan_parent_subkeys(path, p+1);
+ ret = scan_parent_subkeys(db, path, p+1);
}
done:
@@ -1340,35 +1438,36 @@ done:
released by the caller.
***********************************************************************/
-int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr)
+static WERROR regdb_fetch_keys_internal(struct db_context *db, const char *key,
+ struct regsubkey_ctr *ctr)
{
WERROR werr;
- uint32 num_items;
+ uint32_t num_items;
uint8 *buf;
uint32 buflen, len;
int i;
fstring subkeyname;
- int ret = -1;
TALLOC_CTX *frame = talloc_stackframe();
TDB_DATA value;
DEBUG(11,("regdb_fetch_keys: Enter key => [%s]\n", key ? key : "NULL"));
- if (!regdb_key_exists(key)) {
- goto done;
- }
+ frame = talloc_stackframe();
- werr = regsubkey_ctr_set_seqnum(ctr, regdb_get_seqnum());
- if (!W_ERROR_IS_OK(werr)) {
+ if (!regdb_key_exists(db, key)) {
+ DEBUG(10, ("key [%s] not found\n", key));
+ werr = WERR_NOT_FOUND;
goto done;
}
- value = regdb_fetch_key_internal(frame, key);
+ werr = regsubkey_ctr_set_seqnum(ctr, db->get_seqnum(db));
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
+
+ value = regdb_fetch_key_internal(db, frame, key);
if (value.dptr == NULL) {
DEBUG(10, ("regdb_fetch_keys: no subkeys found for key [%s]\n",
key));
- ret = 0;
goto done;
}
@@ -1376,22 +1475,37 @@ int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr)
buflen = value.dsize;
len = tdb_unpack( buf, buflen, "d", &num_items);
+ werr = regsubkey_ctr_reinit(ctr);
+ W_ERROR_NOT_OK_GOTO_DONE(werr);
+
for (i=0; i<num_items; i++) {
len += tdb_unpack(buf+len, buflen-len, "f", subkeyname);
werr = regsubkey_ctr_addkey(ctr, subkeyname);
if (!W_ERROR_IS_OK(werr)) {
DEBUG(5, ("regdb_fetch_keys: regsubkey_ctr_addkey "
"failed: %s\n", win_errstr(werr)));
+ num_items = 0;
goto done;
}
}
DEBUG(11,("regdb_fetch_keys: Exit [%d] items\n", num_items));
- ret = num_items;
done:
TALLOC_FREE(frame);
- return ret;
+ return werr;
+}
+
+int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr)
+{
+ WERROR werr;
+
+ werr = regdb_fetch_keys_internal(regdb, key, ctr);
+ if (!W_ERROR_IS_OK(werr)) {
+ return -1;
+ }
+
+ return regsubkey_ctr_numkeys(ctr);
}
/****************************************************************************
@@ -1478,7 +1592,8 @@ static int regdb_pack_values(struct regval_ctr *values, uint8 *buf, int buflen)
released by the caller.
***********************************************************************/
-int regdb_fetch_values(const char* key, struct regval_ctr *values)
+static int regdb_fetch_values_internal(struct db_context *db, const char* key,
+ struct regval_ctr *values)
{
char *keystr = NULL;
TALLOC_CTX *ctx = talloc_stackframe();
@@ -1487,7 +1602,7 @@ int regdb_fetch_values(const char* key, struct regval_ctr *values)
DEBUG(10,("regdb_fetch_values: Looking for value of key [%s] \n", key));
- if (!regdb_key_exists(key)) {
+ if (!regdb_key_exists(db, key)) {
goto done;
}
@@ -1496,9 +1611,9 @@ int regdb_fetch_values(const char* key, struct regval_ctr *values)
goto done;
}
- values->seqnum = regdb_get_seqnum();
+ values->seqnum = db->get_seqnum(db);
- value = regdb_fetch_key_internal(ctx, keystr);
+ value = regdb_fetch_key_internal(db, ctx, keystr);
if (!value.dptr) {
/* all keys have zero values by default */
@@ -1513,7 +1628,13 @@ done:
return ret;
}
-bool regdb_store_values(const char *key, struct regval_ctr *values)
+int regdb_fetch_values(const char* key, struct regval_ctr *values)
+{
+ return regdb_fetch_values_internal(regdb, key, values);
+}
+
+static bool regdb_store_values_internal(struct db_context *db, const char *key,
+ struct regval_ctr *values)
{
TDB_DATA old_data, data;
char *keystr = NULL;
@@ -1524,7 +1645,7 @@ bool regdb_store_values(const char *key, struct regval_ctr *values)
DEBUG(10,("regdb_store_values: Looking for value of key [%s] \n", key));
- if (!regdb_key_exists(key)) {
+ if (!regdb_key_exists(db, key)) {
goto done;
}
@@ -1552,7 +1673,7 @@ bool regdb_store_values(const char *key, struct regval_ctr *values)
goto done;
}
- old_data = dbwrap_fetch_bystring(regdb, ctx, keystr);
+ old_data = dbwrap_fetch_bystring(db, ctx, keystr);
if ((old_data.dptr != NULL)
&& (old_data.dsize == data.dsize)
@@ -1562,7 +1683,7 @@ bool regdb_store_values(const char *key, struct regval_ctr *values)
goto done;
}
- status = dbwrap_trans_store_bystring(regdb, keystr, data, TDB_REPLACE);
+ status = dbwrap_trans_store_bystring(db, keystr, data, TDB_REPLACE);
result = NT_STATUS_IS_OK(status);
@@ -1571,6 +1692,11 @@ done:
return result;
}
+bool regdb_store_values(const char *key, struct regval_ctr *values)
+{
+ return regdb_store_values_internal(regdb, key, values);
+}
+
static WERROR regdb_get_secdesc(TALLOC_CTX *mem_ctx, const char *key,
struct security_descriptor **psecdesc)
{
@@ -1582,7 +1708,7 @@ static WERROR regdb_get_secdesc(TALLOC_CTX *mem_ctx, const char *key,
DEBUG(10, ("regdb_get_secdesc: Getting secdesc of key [%s]\n", key));
- if (!regdb_key_exists(key)) {
+ if (!regdb_key_exists(regdb, key)) {
err = WERR_BADFILE;
goto done;
}
@@ -1622,7 +1748,7 @@ static WERROR regdb_set_secdesc(const char *key,
WERROR err = WERR_NOMEM;
TDB_DATA tdbdata;
- if (!regdb_key_exists(key)) {
+ if (!regdb_key_exists(regdb, key)) {
err = WERR_BADFILE;
goto done;
}
diff --git a/source3/registry/reg_backend_netlogon_params.c b/source3/registry/reg_backend_netlogon_params.c
index 682c7fe9a5..6fc87efb1d 100644
--- a/source3/registry/reg_backend_netlogon_params.c
+++ b/source3/registry/reg_backend_netlogon_params.c
@@ -35,7 +35,7 @@ static int netlogon_params_fetch_values(const char *key, struct regval_ctr *regv
{
uint32 dwValue;
- if (!pdb_get_account_policy(AP_REFUSE_MACHINE_PW_CHANGE, &dwValue)) {
+ if (!pdb_get_account_policy(PDB_POLICY_REFUSE_MACHINE_PW_CHANGE, &dwValue)) {
dwValue = 0;
}
diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c
index 5ae1cd8aa7..0c0455aada 100644
--- a/source3/registry/reg_objects.c
+++ b/source3/registry/reg_objects.c
@@ -63,6 +63,29 @@ WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr)
return WERR_OK;
}
+/**
+ * re-initialize the list of subkeys (to the emtpy list)
+ * in an already allocated regsubkey_ctr
+ */
+
+WERROR regsubkey_ctr_reinit(struct regsubkey_ctr *ctr)
+{
+ if (ctr == NULL) {
+ return WERR_INVALID_PARAM;
+ }
+
+ talloc_free(ctr->subkeys_hash);
+ ctr->subkeys_hash = db_open_rbt(ctr);
+ W_ERROR_HAVE_NO_MEMORY(ctr->subkeys_hash);
+
+ TALLOC_FREE(ctr->subkeys);
+
+ ctr->num_subkeys = 0;
+ ctr->seqnum = 0;
+
+ return WERR_OK;
+}
+
WERROR regsubkey_ctr_set_seqnum(struct regsubkey_ctr *ctr, int seqnum)
{
if (ctr == NULL) {
@@ -89,7 +112,7 @@ static WERROR regsubkey_ctr_hash_keyname(struct regsubkey_ctr *ctr,
{
WERROR werr;
- werr = ntstatus_to_werror(dbwrap_store_bystring(ctr->subkeys_hash,
+ werr = ntstatus_to_werror(dbwrap_store_bystring_upper(ctr->subkeys_hash,
keyname,
make_tdb_data((uint8 *)&idx,
sizeof(idx)),
@@ -107,7 +130,7 @@ static WERROR regsubkey_ctr_unhash_keyname(struct regsubkey_ctr *ctr,
{
WERROR werr;
- werr = ntstatus_to_werror(dbwrap_delete_bystring(ctr->subkeys_hash,
+ werr = ntstatus_to_werror(dbwrap_delete_bystring_upper(ctr->subkeys_hash,
keyname));
if (!W_ERROR_IS_OK(werr)) {
DEBUG(1, ("error unhashing key '%s' in container: %s\n",
@@ -127,7 +150,7 @@ static WERROR regsubkey_ctr_index_for_keyname(struct regsubkey_ctr *ctr,
return WERR_INVALID_PARAM;
}
- data = dbwrap_fetch_bystring(ctr->subkeys_hash, ctr, keyname);
+ data = dbwrap_fetch_bystring_upper(ctr->subkeys_hash, ctr, keyname);
if (data.dptr == NULL) {
return WERR_NOT_FOUND;
}
diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c
index 0f4829dec3..621ccf4bc9 100644
--- a/source3/rpc_parse/parse_prs.c
+++ b/source3/rpc_parse/parse_prs.c
@@ -637,42 +637,6 @@ bool prs_uint8(const char *name, prs_struct *ps, int depth, uint8 *data8)
}
/*******************************************************************
- Stream a uint16* (allocate memory if unmarshalling)
- ********************************************************************/
-
-bool prs_pointer( const char *name, prs_struct *ps, int depth,
- void *dta, size_t data_size,
- bool (*prs_fn)(const char*, prs_struct*, int, void*) )
-{
- void ** data = (void **)dta;
- uint32 data_p;
-
- /* output f000baaa to stream if the pointer is non-zero. */
-
- data_p = *data ? 0xf000baaa : 0;
-
- if ( !prs_uint32("ptr", ps, depth, &data_p ))
- return False;
-
- /* we're done if there is no data */
-
- if ( !data_p )
- return True;
-
- if (UNMARSHALLING(ps)) {
- if (data_size) {
- if ( !(*data = PRS_ALLOC_MEM(ps, char, data_size)) )
- return False;
- } else {
- *data = NULL;
- }
- }
-
- return prs_fn(name, ps, depth, *data);
-}
-
-
-/*******************************************************************
Stream a uint16.
********************************************************************/
@@ -784,36 +748,6 @@ bool prs_uint64(const char *name, prs_struct *ps, int depth, uint64 *data64)
}
/*******************************************************************
- Stream a NTSTATUS
- ********************************************************************/
-
-bool prs_ntstatus(const char *name, prs_struct *ps, int depth, NTSTATUS *status)
-{
- char *q = prs_mem_get(ps, sizeof(uint32));
- if (q == NULL)
- return False;
-
- if (UNMARSHALLING(ps)) {
- if (ps->bigendian_data)
- *status = NT_STATUS(RIVAL(q,0));
- else
- *status = NT_STATUS(IVAL(q,0));
- } else {
- if (ps->bigendian_data)
- RSIVAL(q,0,NT_STATUS_V(*status));
- else
- SIVAL(q,0,NT_STATUS_V(*status));
- }
-
- DEBUGADD(5,("%s%04x %s: %s\n", tab_depth(5,depth), ps->data_offset, name,
- nt_errstr(*status)));
-
- ps->data_offset += sizeof(uint32);
-
- return True;
-}
-
-/*******************************************************************
Stream a DCE error code
********************************************************************/
@@ -843,38 +777,6 @@ bool prs_dcerpc_status(const char *name, prs_struct *ps, int depth, NTSTATUS *st
return True;
}
-
-/*******************************************************************
- Stream a WERROR
- ********************************************************************/
-
-bool prs_werror(const char *name, prs_struct *ps, int depth, WERROR *status)
-{
- char *q = prs_mem_get(ps, sizeof(uint32));
- if (q == NULL)
- return False;
-
- if (UNMARSHALLING(ps)) {
- if (ps->bigendian_data)
- *status = W_ERROR(RIVAL(q,0));
- else
- *status = W_ERROR(IVAL(q,0));
- } else {
- if (ps->bigendian_data)
- RSIVAL(q,0,W_ERROR_V(*status));
- else
- SIVAL(q,0,W_ERROR_V(*status));
- }
-
- DEBUGADD(5,("%s%04x %s: %s\n", tab_depth(5,depth), ps->data_offset, name,
- win_errstr(*status)));
-
- ps->data_offset += sizeof(uint32);
-
- return True;
-}
-
-
/******************************************************************
Stream an array of uint8s. Length is number of uint8s.
********************************************************************/
@@ -952,60 +854,6 @@ bool prs_uint16s(bool charmode, const char *name, prs_struct *ps, int depth, uin
}
/******************************************************************
- Start using a function for streaming unicode chars. If unmarshalling,
- output must be little-endian, if marshalling, input must be little-endian.
- ********************************************************************/
-
-static void dbg_rw_punival(bool charmode, const char *name, int depth, prs_struct *ps,
- char *in_buf, char *out_buf, int len)
-{
- int i;
-
- if (UNMARSHALLING(ps)) {
- if (ps->bigendian_data) {
- for (i = 0; i < len; i++)
- SSVAL(out_buf,2*i,RSVAL(in_buf, 2*i));
- } else {
- for (i = 0; i < len; i++)
- SSVAL(out_buf, 2*i, SVAL(in_buf, 2*i));
- }
- } else {
- if (ps->bigendian_data) {
- for (i = 0; i < len; i++)
- RSSVAL(in_buf, 2*i, SVAL(out_buf,2*i));
- } else {
- for (i = 0; i < len; i++)
- SSVAL(in_buf, 2*i, SVAL(out_buf,2*i));
- }
- }
-
- DEBUGADD(5,("%s%04x %s: ", tab_depth(5,depth), ps->data_offset, name));
- if (charmode)
- print_asc(5, (unsigned char*)out_buf, 2*len);
- else {
- for (i = 0; i < len; i++)
- DEBUGADD(5,("%04x ", out_buf[i]));
- }
- DEBUGADD(5,("\n"));
-}
-
-/******************************************************************
- Stream a unistr. Always little endian.
- ********************************************************************/
-
-bool prs_uint16uni(bool charmode, const char *name, prs_struct *ps, int depth, uint16 *data16s, int len)
-{
- char *q = prs_mem_get(ps, len * sizeof(uint16));
- if (q == NULL)
- return False;
-
- dbg_rw_punival(charmode, name, depth, ps, q, (char *)data16s, len);
- ps->data_offset += (len * sizeof(uint16));
-
- return True;
-}
-
-/******************************************************************
Stream an array of uint32s. Length is number of uint32s.
********************************************************************/
@@ -1216,172 +1064,6 @@ bool prs_string(const char *name, prs_struct *ps, int depth, char *str, int max_
return True;
}
-bool prs_string_alloc(const char *name, prs_struct *ps, int depth, const char **str)
-{
- size_t len;
- char *tmp_str;
-
- if (UNMARSHALLING(ps)) {
- len = strlen(&ps->data_p[ps->data_offset]);
- } else {
- len = strlen(*str);
- }
-
- tmp_str = PRS_ALLOC_MEM(ps, char, len+1);
-
- if (tmp_str == NULL) {
- return False;
- }
-
- if (MARSHALLING(ps)) {
- strncpy(tmp_str, *str, len);
- }
-
- if (!prs_string(name, ps, depth, tmp_str, len+1)) {
- return False;
- }
-
- *str = tmp_str;
- return True;
-}
-
-/*******************************************************************
- prs_uint16 wrapper. Call this and it sets up a pointer to where the
- uint16 should be stored, or gets the size if reading.
- ********************************************************************/
-
-bool prs_uint16_pre(const char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset)
-{
- *offset = ps->data_offset;
- if (UNMARSHALLING(ps)) {
- /* reading. */
- return prs_uint16(name, ps, depth, data16);
- } else {
- char *q = prs_mem_get(ps, sizeof(uint16));
- if(q ==NULL)
- return False;
- ps->data_offset += sizeof(uint16);
- }
- return True;
-}
-
-/*******************************************************************
- prs_uint16 wrapper. call this and it retrospectively stores the size.
- does nothing on reading, as that is already handled by ...._pre()
- ********************************************************************/
-
-bool prs_uint16_post(const char *name, prs_struct *ps, int depth, uint16 *data16,
- uint32 ptr_uint16, uint32 start_offset)
-{
- if (MARSHALLING(ps)) {
- /*
- * Writing - temporarily move the offset pointer.
- */
- uint16 data_size = ps->data_offset - start_offset;
- uint32 old_offset = ps->data_offset;
-
- ps->data_offset = ptr_uint16;
- if(!prs_uint16(name, ps, depth, &data_size)) {
- ps->data_offset = old_offset;
- return False;
- }
- ps->data_offset = old_offset;
- } else {
- ps->data_offset = start_offset + (uint32)(*data16);
- }
- return True;
-}
-
-/*******************************************************************
- prs_uint32 wrapper. Call this and it sets up a pointer to where the
- uint32 should be stored, or gets the size if reading.
- ********************************************************************/
-
-bool prs_uint32_pre(const char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset)
-{
- *offset = ps->data_offset;
- if (UNMARSHALLING(ps) && (data32 != NULL)) {
- /* reading. */
- return prs_uint32(name, ps, depth, data32);
- } else {
- ps->data_offset += sizeof(uint32);
- }
- return True;
-}
-
-/*******************************************************************
- prs_uint32 wrapper. call this and it retrospectively stores the size.
- does nothing on reading, as that is already handled by ...._pre()
- ********************************************************************/
-
-bool prs_uint32_post(const char *name, prs_struct *ps, int depth, uint32 *data32,
- uint32 ptr_uint32, uint32 data_size)
-{
- if (MARSHALLING(ps)) {
- /*
- * Writing - temporarily move the offset pointer.
- */
- uint32 old_offset = ps->data_offset;
- ps->data_offset = ptr_uint32;
- if(!prs_uint32(name, ps, depth, &data_size)) {
- ps->data_offset = old_offset;
- return False;
- }
- ps->data_offset = old_offset;
- }
- return True;
-}
-
-/* useful function to store a structure in rpc wire format */
-int tdb_prs_store(TDB_CONTEXT *tdb, TDB_DATA kbuf, prs_struct *ps)
-{
- TDB_DATA dbuf;
- dbuf.dptr = (uint8 *)ps->data_p;
- dbuf.dsize = prs_offset(ps);
- return tdb_trans_store(tdb, kbuf, dbuf, TDB_REPLACE);
-}
-
-/* useful function to fetch a structure into rpc wire format */
-int tdb_prs_fetch(TDB_CONTEXT *tdb, TDB_DATA kbuf, prs_struct *ps, TALLOC_CTX *mem_ctx)
-{
- TDB_DATA dbuf;
-
- prs_init_empty(ps, mem_ctx, UNMARSHALL);
-
- dbuf = tdb_fetch(tdb, kbuf);
- if (!dbuf.dptr)
- return -1;
-
- prs_give_memory(ps, (char *)dbuf.dptr, dbuf.dsize, True);
-
- return 0;
-}
-
-/*******************************************************************
- hash a stream.
- ********************************************************************/
-
-bool prs_hash1(prs_struct *ps, uint32 offset, int len)
-{
- char *q;
-
- q = ps->data_p;
- q = &q[offset];
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100, ("prs_hash1\n"));
- dump_data(100, (uint8 *)ps->sess_key, 16);
- dump_data(100, (uint8 *)q, len);
-#endif
- arcfour_crypt((uchar *) q, (const unsigned char *)ps->sess_key, len);
-
-#ifdef DEBUG_PASSWORD
- dump_data(100, (uint8 *)q, len);
-#endif
-
- return True;
-}
-
/*******************************************************************
Create a digest over the entire packet (including the data), and
MD5 it with the session key.
diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c
index 324483b3ee..ace045cfa5 100644
--- a/source3/rpc_server/srv_lsa_nt.c
+++ b/source3/rpc_server/srv_lsa_nt.c
@@ -349,7 +349,9 @@ NTSTATUS _lsa_OpenPolicy2(pipes_struct *p,
NTSTATUS status;
/* Work out max allowed. */
- map_max_allowed_access(p->server_info->ptok, &des_access);
+ map_max_allowed_access(p->server_info->ptok,
+ &p->server_info->utok,
+ &des_access);
/* map the generic bits to the lsa policy ones */
se_map_generic(&des_access, &lsa_policy_mapping);
@@ -503,6 +505,7 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p,
const char *name;
DOM_SID *sid = NULL;
union lsa_PolicyInformation *info = NULL;
+ uint32_t acc_required = 0;
if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
return NT_STATUS_INVALID_HANDLE;
@@ -511,6 +514,47 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p,
return NT_STATUS_INVALID_HANDLE;
}
+ switch (r->in.level) {
+ case LSA_POLICY_INFO_AUDIT_LOG:
+ case LSA_POLICY_INFO_AUDIT_EVENTS:
+ acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
+ break;
+ case LSA_POLICY_INFO_DOMAIN:
+ acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
+ break;
+ case LSA_POLICY_INFO_PD:
+ acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
+ break;
+ case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
+ acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
+ break;
+ case LSA_POLICY_INFO_ROLE:
+ case LSA_POLICY_INFO_REPLICA:
+ acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
+ break;
+ case LSA_POLICY_INFO_QUOTA:
+ acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
+ break;
+ case LSA_POLICY_INFO_MOD:
+ case LSA_POLICY_INFO_AUDIT_FULL_SET:
+ /* according to MS-LSAD 3.1.4.4.3 */
+ return NT_STATUS_INVALID_PARAMETER;
+ case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
+ acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
+ break;
+ case LSA_POLICY_INFO_DNS:
+ case LSA_POLICY_INFO_DNS_INT:
+ case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
+ acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
+ break;
+ default:
+ break;
+ }
+
+ if (!(handle->access & acc_required)) {
+ /* return NT_STATUS_ACCESS_DENIED; */
+ }
+
info = TALLOC_ZERO_P(p->mem_ctx, union lsa_PolicyInformation);
if (!info) {
return NT_STATUS_NO_MEMORY;
@@ -618,7 +662,8 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p,
break;
}
break;
- case LSA_POLICY_INFO_DNS: {
+ case LSA_POLICY_INFO_DNS:
+ case LSA_POLICY_INFO_DNS_INT: {
struct pdb_domain_info *dominfo;
if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
@@ -657,6 +702,28 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p,
}
/***************************************************************************
+ _lsa_QueryInfoPolicy2
+ ***************************************************************************/
+
+NTSTATUS _lsa_QueryInfoPolicy2(pipes_struct *p,
+ struct lsa_QueryInfoPolicy2 *r2)
+{
+ struct lsa_QueryInfoPolicy r;
+
+ if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
+ p->rng_fault_state = True;
+ return NT_STATUS_NOT_IMPLEMENTED;
+ }
+
+ ZERO_STRUCT(r);
+ r.in.handle = r2->in.handle;
+ r.in.level = r2->in.level;
+ r.out.info = r2->out.info;
+
+ return _lsa_QueryInfoPolicy(p, &r);
+}
+
+/***************************************************************************
_lsa_lookup_sids_internal
***************************************************************************/
@@ -1302,12 +1369,22 @@ NTSTATUS _lsa_DeleteObject(pipes_struct *p,
return NT_STATUS_ACCESS_DENIED;
}
- status = privilege_delete_account(&info->sid);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
- nt_errstr(status)));
+ switch (info->type) {
+ case LSA_HANDLE_ACCOUNT_TYPE:
+ status = privilege_delete_account(&info->sid);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
+ nt_errstr(status)));
+ return status;
+ }
+ break;
+ default:
+ return NT_STATUS_INVALID_HANDLE;
}
+ close_policy_hnd(p, r->in.handle);
+ ZERO_STRUCTP(r->out.handle);
+
return status;
}
@@ -1560,8 +1637,12 @@ NTSTATUS _lsa_GetUserName(pipes_struct *p,
NTSTATUS _lsa_CreateAccount(pipes_struct *p,
struct lsa_CreateAccount *r)
{
+ NTSTATUS status;
struct lsa_info *handle;
struct lsa_info *info;
+ uint32_t acc_granted;
+ struct security_descriptor *psd;
+ uint32_t sd_size;
/* find the connection policy handle. */
if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
@@ -1573,12 +1654,26 @@ NTSTATUS _lsa_CreateAccount(pipes_struct *p,
/* check if the user has enough rights */
- /*
- * I don't know if it's the right one. not documented.
- * but guessed with rpcclient.
- */
- if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT))
+ if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /* map the generic bits to the lsa policy ones */
+ se_map_generic(&r->in.access_mask, &lsa_account_mapping);
+
+ status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
+ &lsa_account_mapping,
+ r->in.sid, LSA_POLICY_ALL_ACCESS);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = access_check_object(psd, p->server_info->ptok,
+ NULL, 0, r->in.access_mask,
+ &acc_granted, "_lsa_CreateAccount");
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
if ( is_privileged_sid( r->in.sid ) )
return NT_STATUS_OBJECT_NAME_COLLISION;
@@ -1591,7 +1686,7 @@ NTSTATUS _lsa_CreateAccount(pipes_struct *p,
}
info->sid = *r->in.sid;
- info->access = r->in.access_mask;
+ info->access = acc_granted;
info->type = LSA_HANDLE_ACCOUNT_TYPE;
/* get a (unique) handle. open a policy on it. */
@@ -1628,7 +1723,9 @@ NTSTATUS _lsa_OpenAccount(pipes_struct *p,
* handle - so don't check against policy handle. */
/* Work out max allowed. */
- map_max_allowed_access(p->server_info->ptok, &des_access);
+ map_max_allowed_access(p->server_info->ptok,
+ &p->server_info->utok,
+ &des_access);
/* map the generic bits to the lsa account ones */
se_map_generic(&des_access, &lsa_account_mapping);
@@ -1913,6 +2010,51 @@ NTSTATUS _lsa_RemovePrivilegesFromAccount(pipes_struct *p,
}
/***************************************************************************
+ _lsa_LookupPrivName
+ ***************************************************************************/
+
+NTSTATUS _lsa_LookupPrivName(pipes_struct *p,
+ struct lsa_LookupPrivName *r)
+{
+ struct lsa_info *info = NULL;
+ const char *name;
+ struct lsa_StringLarge *lsa_name;
+
+ /* find the connection policy handle. */
+ if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (info->type != LSA_HANDLE_POLICY_TYPE) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ name = luid_to_privilege_name((LUID *)r->in.luid);
+ if (!name) {
+ return NT_STATUS_NO_SUCH_PRIVILEGE;
+ }
+
+ lsa_name = TALLOC_ZERO_P(p->mem_ctx, struct lsa_StringLarge);
+ if (!lsa_name) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ lsa_name->string = talloc_strdup(lsa_name, name);
+ if (!lsa_name->string) {
+ TALLOC_FREE(lsa_name);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ *r->out.name = lsa_name;
+
+ return NT_STATUS_OK;
+}
+
+/***************************************************************************
_lsa_QuerySecurity
***************************************************************************/
@@ -1943,19 +2085,9 @@ NTSTATUS _lsa_QuerySecurity(pipes_struct *p,
return status;
}
- switch (r->in.sec_info) {
- case 1:
- /* SD contains only the owner */
- if((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
- return NT_STATUS_NO_MEMORY;
- break;
- case 4:
- /* SD contains only the ACL */
- if((*r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
- return NT_STATUS_NO_MEMORY;
- break;
- default:
- return NT_STATUS_INVALID_LEVEL;
+ *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
+ if (!*r->out.sdbuf) {
+ return NT_STATUS_NO_MEMORY;
}
return status;
@@ -2242,18 +2374,79 @@ NTSTATUS _lsa_LookupPrivValue(pipes_struct *p,
return NT_STATUS_OK;
}
+/***************************************************************************
+ _lsa_EnumAccountsWithUserRight
+ ***************************************************************************/
+
+NTSTATUS _lsa_EnumAccountsWithUserRight(pipes_struct *p,
+ struct lsa_EnumAccountsWithUserRight *r)
+{
+ NTSTATUS status;
+ struct lsa_info *info = NULL;
+ struct dom_sid *sids = NULL;
+ int num_sids = 0;
+ uint32_t i;
+ SE_PRIV mask;
+
+ if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (info->type != LSA_HANDLE_POLICY_TYPE) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (!r->in.name || !r->in.name->string) {
+ return NT_STATUS_NO_SUCH_PRIVILEGE;
+ }
+
+ if (!se_priv_from_name(r->in.name->string, &mask)) {
+ return NT_STATUS_NO_SUCH_PRIVILEGE;
+ }
+
+ status = privilege_enum_sids(&mask, p->mem_ctx,
+ &sids, &num_sids);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ r->out.sids->num_sids = num_sids;
+ r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
+ r->out.sids->num_sids);
+
+ for (i=0; i < r->out.sids->num_sids; i++) {
+ r->out.sids->sids[i].sid = sid_dup_talloc(r->out.sids->sids,
+ &sids[i]);
+ if (!r->out.sids->sids[i].sid) {
+ TALLOC_FREE(r->out.sids->sids);
+ r->out.sids->num_sids = 0;
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
+ return NT_STATUS_OK;
+}
+
+/***************************************************************************
+ _lsa_Delete
+ ***************************************************************************/
+
+NTSTATUS _lsa_Delete(pipes_struct *p,
+ struct lsa_Delete *r)
+{
+ return NT_STATUS_NOT_SUPPORTED;
+}
+
/*
* From here on the server routines are just dummy ones to make smbd link with
* librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
* pulling the server stubs across one by one.
*/
-NTSTATUS _lsa_Delete(pipes_struct *p, struct lsa_Delete *r)
-{
- p->rng_fault_state = True;
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
NTSTATUS _lsa_SetSecObj(pipes_struct *p, struct lsa_SetSecObj *r)
{
p->rng_fault_state = True;
@@ -2308,18 +2501,6 @@ NTSTATUS _lsa_QuerySecret(pipes_struct *p, struct lsa_QuerySecret *r)
return NT_STATUS_NOT_IMPLEMENTED;
}
-NTSTATUS _lsa_LookupPrivName(pipes_struct *p, struct lsa_LookupPrivName *r)
-{
- p->rng_fault_state = True;
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS _lsa_EnumAccountsWithUserRight(pipes_struct *p, struct lsa_EnumAccountsWithUserRight *r)
-{
- p->rng_fault_state = True;
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
NTSTATUS _lsa_QueryTrustedDomainInfoBySid(pipes_struct *p, struct lsa_QueryTrustedDomainInfoBySid *r)
{
p->rng_fault_state = True;
@@ -2350,24 +2531,6 @@ NTSTATUS _lsa_RetrievePrivateData(pipes_struct *p, struct lsa_RetrievePrivateDat
return NT_STATUS_NOT_IMPLEMENTED;
}
-NTSTATUS _lsa_QueryInfoPolicy2(pipes_struct *p,
- struct lsa_QueryInfoPolicy2 *r2)
-{
- struct lsa_QueryInfoPolicy r;
-
- if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
- p->rng_fault_state = True;
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- ZERO_STRUCT(r);
- r.in.handle = r2->in.handle;
- r.in.level = r2->in.level;
- r.out.info = r2->out.info;
-
- return _lsa_QueryInfoPolicy(p, &r);
-}
-
NTSTATUS _lsa_SetInfoPolicy2(pipes_struct *p, struct lsa_SetInfoPolicy2 *r)
{
p->rng_fault_state = True;
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index 8560ee97c6..b27603f261 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -236,8 +236,9 @@ done:
Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
********************************************************************/
-void map_max_allowed_access(const NT_USER_TOKEN *token,
- uint32_t *pacc_requested)
+void map_max_allowed_access(const NT_USER_TOKEN *nt_token,
+ const struct unix_user_token *unix_token,
+ uint32_t *pacc_requested)
{
if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
return;
@@ -248,15 +249,15 @@ void map_max_allowed_access(const NT_USER_TOKEN *token,
*pacc_requested = GENERIC_READ_ACCESS|GENERIC_EXECUTE_ACCESS;
/* root gets anything. */
- if (geteuid() == sec_initial_uid()) {
+ if (unix_token->uid == sec_initial_uid()) {
*pacc_requested |= GENERIC_ALL_ACCESS;
return;
}
/* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
- if (is_sid_in_token(token, &global_sid_Builtin_Administrators) ||
- is_sid_in_token(token, &global_sid_Builtin_Account_Operators)) {
+ if (is_sid_in_token(nt_token, &global_sid_Builtin_Administrators) ||
+ is_sid_in_token(nt_token, &global_sid_Builtin_Account_Operators)) {
*pacc_requested |= GENERIC_ALL_ACCESS;
return;
}
@@ -266,7 +267,7 @@ void map_max_allowed_access(const NT_USER_TOKEN *token,
DOM_SID domadmin_sid;
sid_copy( &domadmin_sid, get_global_sam_sid() );
sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
- if (is_sid_in_token(token, &domadmin_sid)) {
+ if (is_sid_in_token(nt_token, &domadmin_sid)) {
*pacc_requested |= GENERIC_ALL_ACCESS;
return;
}
@@ -550,7 +551,9 @@ NTSTATUS _samr_OpenDomain(pipes_struct *p,
}
/*check if access can be granted as requested by client. */
- map_max_allowed_access(p->server_info->ptok, &des_access);
+ map_max_allowed_access(p->server_info->ptok,
+ &p->server_info->utok,
+ &des_access);
make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
se_map_generic( &des_access, &dom_generic_mapping );
@@ -636,9 +639,9 @@ NTSTATUS _samr_GetUserPwInfo(pipes_struct *p,
switch (sid_type) {
case SID_NAME_USER:
become_root();
- pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
+ pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
&min_password_length);
- pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
+ pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
&password_properties);
unbecome_root();
@@ -2076,19 +2079,19 @@ NTSTATUS _samr_ChangePasswordUser3(pipes_struct *p,
/* AS ROOT !!! */
- pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &tmp);
+ pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &tmp);
dominfo->min_password_length = tmp;
- pdb_get_account_policy(AP_PASSWORD_HISTORY, &tmp);
+ pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &tmp);
dominfo->password_history_length = tmp;
- pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
+ pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
&dominfo->password_properties);
- pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
+ pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
u_expire = account_policy_temp;
- pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
+ pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
u_min_age = account_policy_temp;
/* !AS ROOT */
@@ -2260,8 +2263,9 @@ NTSTATUS _samr_OpenUser(pipes_struct *p,
return NT_STATUS_NO_SUCH_USER;
/* check if access can be granted as requested by client. */
-
- map_max_allowed_access(p->server_info->ptok, &des_access);
+ map_max_allowed_access(p->server_info->ptok,
+ &p->server_info->utok,
+ &des_access);
make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
se_map_generic(&des_access, &usr_generic_mapping);
@@ -3301,19 +3305,19 @@ static NTSTATUS query_dom_info_1(TALLOC_CTX *mem_ctx,
/* AS ROOT !!! */
- pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
+ pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &account_policy_temp);
r->min_password_length = account_policy_temp;
- pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
+ pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &account_policy_temp);
r->password_history_length = account_policy_temp;
- pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
+ pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
&r->password_properties);
- pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
+ pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp);
u_expire = account_policy_temp;
- pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
+ pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp);
u_min_age = account_policy_temp;
/* !AS ROOT */
@@ -3348,7 +3352,7 @@ static NTSTATUS query_dom_info_2(TALLOC_CTX *mem_ctx,
r->num_groups = count_sam_groups(dinfo->disp_info);
r->num_aliases = count_sam_aliases(dinfo->disp_info);
- pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
+ pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &u_logout);
unix_to_nt_time_abs(&r->force_logoff_time, u_logout);
@@ -3385,7 +3389,7 @@ static NTSTATUS query_dom_info_3(TALLOC_CTX *mem_ctx,
{
uint32_t ul;
- pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
+ pdb_get_account_policy(PDB_POLICY_TIME_TO_LOGOUT, &ul);
u_logout = (time_t)ul;
}
@@ -3502,16 +3506,16 @@ static NTSTATUS query_dom_info_11(TALLOC_CTX *mem_ctx,
become_root();
- pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
+ pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
u_lock_duration = account_policy_temp;
if (u_lock_duration != -1) {
u_lock_duration *= 60;
}
- pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
+ pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
u_reset_time = account_policy_temp * 60;
- pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
+ pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
r->lockout_threshold = account_policy_temp;
/* !AS ROOT */
@@ -3537,16 +3541,16 @@ static NTSTATUS query_dom_info_12(TALLOC_CTX *mem_ctx,
/* AS ROOT !!! */
- pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
+ pdb_get_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, &account_policy_temp);
u_lock_duration = account_policy_temp;
if (u_lock_duration != -1) {
u_lock_duration *= 60;
}
- pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
+ pdb_get_account_policy(PDB_POLICY_RESET_COUNT_TIME, &account_policy_temp);
u_reset_time = account_policy_temp * 60;
- pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
+ pdb_get_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
r->lockout_threshold = account_policy_temp;
/* !AS ROOT */
@@ -3834,7 +3838,9 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p,
sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
- map_max_allowed_access(p->server_info->ptok, &des_access);
+ map_max_allowed_access(p->server_info->ptok,
+ &p->server_info->utok,
+ &des_access);
make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
&sid, SAMR_USR_RIGHTS_WRITE_PW);
@@ -3914,7 +3920,9 @@ NTSTATUS _samr_Connect(pipes_struct *p,
was observed from a win98 client trying to enumerate users (when configured
user level access control on shares) --jerry */
- map_max_allowed_access(p->server_info->ptok, &des_access);
+ map_max_allowed_access(p->server_info->ptok,
+ &p->server_info->utok,
+ &des_access);
se_map_generic( &des_access, &sam_generic_mapping );
@@ -3974,7 +3982,9 @@ NTSTATUS _samr_Connect2(pipes_struct *p,
return NT_STATUS_ACCESS_DENIED;
}
- map_max_allowed_access(p->server_info->ptok, &des_access);
+ map_max_allowed_access(p->server_info->ptok,
+ &p->server_info->utok,
+ &des_access);
make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
se_map_generic(&des_access, &sam_generic_mapping);
@@ -4187,7 +4197,9 @@ NTSTATUS _samr_OpenAlias(pipes_struct *p,
/*check if access can be granted as requested by client. */
- map_max_allowed_access(p->server_info->ptok, &des_access);
+ map_max_allowed_access(p->server_info->ptok,
+ &p->server_info->utok,
+ &des_access);
make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
se_map_generic(&des_access,&ali_generic_mapping);
@@ -6193,9 +6205,9 @@ NTSTATUS _samr_GetDomPwInfo(pipes_struct *p,
}
become_root();
- pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
+ pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
&min_password_length);
- pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
+ pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
&password_properties);
unbecome_root();
@@ -6237,7 +6249,9 @@ NTSTATUS _samr_OpenGroup(pipes_struct *p,
}
/*check if access can be granted as requested by client. */
- map_max_allowed_access(p->server_info->ptok, &des_access);
+ map_max_allowed_access(p->server_info->ptok,
+ &p->server_info->utok,
+ &des_access);
make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
se_map_generic(&des_access,&grp_generic_mapping);
@@ -6362,14 +6376,14 @@ static NTSTATUS set_dom_info_1(TALLOC_CTX *mem_ctx,
u_expire = nt_time_to_unix_abs((NTTIME *)&r->max_password_age);
u_min_age = nt_time_to_unix_abs((NTTIME *)&r->min_password_age);
- pdb_set_account_policy(AP_MIN_PASSWORD_LEN,
+ pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
(uint32_t)r->min_password_length);
- pdb_set_account_policy(AP_PASSWORD_HISTORY,
+ pdb_set_account_policy(PDB_POLICY_PASSWORD_HISTORY,
(uint32_t)r->password_history_length);
- pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
+ pdb_set_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
(uint32_t)r->password_properties);
- pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
- pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
+ pdb_set_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, (int)u_expire);
+ pdb_set_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, (int)u_min_age);
return NT_STATUS_OK;
}
@@ -6384,7 +6398,7 @@ static NTSTATUS set_dom_info_3(TALLOC_CTX *mem_ctx,
u_logout = nt_time_to_unix_abs((NTTIME *)&r->force_logoff_time);
- pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
+ pdb_set_account_policy(PDB_POLICY_TIME_TO_LOGOUT, (int)u_logout);
return NT_STATUS_OK;
}
@@ -6404,9 +6418,9 @@ static NTSTATUS set_dom_info_12(TALLOC_CTX *mem_ctx,
u_reset_time = nt_time_to_unix_abs((NTTIME *)&r->lockout_window)/60;
- pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
- pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
- pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT,
+ pdb_set_account_policy(PDB_POLICY_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
+ pdb_set_account_policy(PDB_POLICY_RESET_COUNT_TIME, (int)u_reset_time);
+ pdb_set_account_policy(PDB_POLICY_BAD_ATTEMPT_LOCKOUT,
(uint32_t)r->lockout_threshold);
return NT_STATUS_OK;
diff --git a/source3/rpc_server/srv_samr_util.c b/source3/rpc_server/srv_samr_util.c
index 69daa31e9c..1e5988af33 100644
--- a/source3/rpc_server/srv_samr_util.c
+++ b/source3/rpc_server/srv_samr_util.c
@@ -619,7 +619,7 @@ void copy_id21_to_sam_passwd(const char *log_prefix,
uint32_t pwd_max_age = 0;
time_t now = time(NULL);
- pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &pwd_max_age);
+ pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &pwd_max_age);
if (pwd_max_age == (uint32_t)-1 || pwd_max_age == 0) {
pwd_max_age = get_time_t_max();
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 9d72168202..9dc1a26e3b 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -261,7 +261,7 @@ static bool close_printer_handle(pipes_struct *p, struct policy_handle *hnd)
Delete a printer given a handle.
****************************************************************************/
-WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename )
+static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename)
{
char *cmd = lp_deleteprinter_cmd();
char *command = NULL;
@@ -309,7 +309,9 @@ WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sh
return WERR_BADFID; /* What to return here? */
/* go ahead and re-read the services immediately */
+ become_root();
reload_services(false);
+ unbecome_root();
if ( lp_servicenumber( sharename ) < 0 )
return WERR_ACCESS_DENIED;
@@ -5920,7 +5922,7 @@ static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
/****************************************************************************
****************************************************************************/
-WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri )
+static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri)
{
char *cmd = lp_addport_cmd();
char *command = NULL;
@@ -6034,7 +6036,9 @@ bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEV
}
/* reload our services immediately */
+ become_root();
reload_services(false);
+ unbecome_root();
numlines = 0;
/* Get lines and convert them back to dos-codepage */
@@ -7316,7 +7320,7 @@ static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
wrapper around the enumer ports command
****************************************************************************/
-WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines )
+static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
{
char *cmd = lp_enumports_cmd();
char **qlines = NULL;
diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c
index 44acf4d647..b9d1ed6d73 100644
--- a/source3/rpc_server/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srv_srvsvc_nt.c
@@ -540,11 +540,13 @@ static WERROR init_srv_share_info_ctr(pipes_struct *p,
if (lp_browseable(snum) && lp_snum_ok(snum) &&
is_enumeration_allowed(p, snum) &&
(all_shares || !is_hidden_share(snum)) ) {
- DEBUG(10, ("counting service %s\n", lp_servicename(snum)));
+ DEBUG(10, ("counting service %s\n",
+ lp_servicename(snum) ? lp_servicename(snum) : "(null)"));
allowed[snum] = true;
num_entries++;
} else {
- DEBUG(10, ("NOT counting service %s\n", lp_servicename(snum)));
+ DEBUG(10, ("NOT counting service %s\n",
+ lp_servicename(snum) ? lp_servicename(snum) : "(null)"));
}
}
@@ -2070,8 +2072,7 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
conn,
false,
r->in.file,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(nt_status)) {
werr = ntstatus_to_werror(nt_status);
goto error_exit;
@@ -2199,8 +2200,7 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
conn,
false,
r->in.file,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(nt_status)) {
werr = ntstatus_to_werror(nt_status);
goto error_exit;
diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c
index ef3187579a..d7f8041779 100644
--- a/source3/rpcclient/cmd_lsarpc.c
+++ b/source3/rpcclient/cmd_lsarpc.c
@@ -1356,6 +1356,366 @@ static NTSTATUS cmd_lsa_del_priv(struct rpc_pipe_client *cli,
return result;
}
+static NTSTATUS cmd_lsa_create_secret(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ const char **argv)
+{
+ NTSTATUS status;
+ struct policy_handle handle, sec_handle;
+ struct lsa_String name;
+
+ if (argc < 2) {
+ printf("Usage: %s name\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ status = rpccli_lsa_open_policy2(cli, mem_ctx,
+ true,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ init_lsa_String(&name, argv[1]);
+
+ status = rpccli_lsa_CreateSecret(cli, mem_ctx,
+ &handle,
+ name,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &sec_handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ done:
+ if (is_valid_policy_hnd(&sec_handle)) {
+ rpccli_lsa_Close(cli, mem_ctx, &sec_handle);
+ }
+ if (is_valid_policy_hnd(&handle)) {
+ rpccli_lsa_Close(cli, mem_ctx, &handle);
+ }
+
+ return status;
+}
+
+static NTSTATUS cmd_lsa_delete_secret(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ const char **argv)
+{
+ NTSTATUS status;
+ struct policy_handle handle, sec_handle;
+ struct lsa_String name;
+
+ if (argc < 2) {
+ printf("Usage: %s name\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ status = rpccli_lsa_open_policy2(cli, mem_ctx,
+ true,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ init_lsa_String(&name, argv[1]);
+
+ status = rpccli_lsa_OpenSecret(cli, mem_ctx,
+ &handle,
+ name,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &sec_handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ status = rpccli_lsa_DeleteObject(cli, mem_ctx,
+ &sec_handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ done:
+ if (is_valid_policy_hnd(&sec_handle)) {
+ rpccli_lsa_Close(cli, mem_ctx, &sec_handle);
+ }
+ if (is_valid_policy_hnd(&handle)) {
+ rpccli_lsa_Close(cli, mem_ctx, &handle);
+ }
+
+ return status;
+}
+
+static NTSTATUS cmd_lsa_query_secret(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ const char **argv)
+{
+ NTSTATUS status;
+ struct policy_handle handle, sec_handle;
+ struct lsa_String name;
+ struct lsa_DATA_BUF_PTR new_val;
+ NTTIME new_mtime = 0;
+ struct lsa_DATA_BUF_PTR old_val;
+ NTTIME old_mtime = 0;
+ DATA_BLOB session_key;
+ DATA_BLOB new_blob = data_blob_null;
+ DATA_BLOB old_blob = data_blob_null;
+ char *new_secret, *old_secret;
+
+ if (argc < 2) {
+ printf("Usage: %s name\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ status = rpccli_lsa_open_policy2(cli, mem_ctx,
+ true,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ init_lsa_String(&name, argv[1]);
+
+ status = rpccli_lsa_OpenSecret(cli, mem_ctx,
+ &handle,
+ name,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &sec_handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ ZERO_STRUCT(new_val);
+ ZERO_STRUCT(old_val);
+
+ status = rpccli_lsa_QuerySecret(cli, mem_ctx,
+ &sec_handle,
+ &new_val,
+ &new_mtime,
+ &old_val,
+ &old_mtime);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ status = cli_get_session_key(mem_ctx, cli, &session_key);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ if (new_val.buf) {
+ new_blob = data_blob_const(new_val.buf->data, new_val.buf->length);
+ }
+ if (old_val.buf) {
+ old_blob = data_blob_const(old_val.buf->data, old_val.buf->length);
+ }
+
+ new_secret = sess_decrypt_string(mem_ctx, &new_blob, &session_key);
+ old_secret = sess_decrypt_string(mem_ctx, &old_blob, &session_key);
+ if (new_secret) {
+ d_printf("new secret: %s\n", new_secret);
+ }
+ if (old_secret) {
+ d_printf("old secret: %s\n", old_secret);
+ }
+
+ done:
+ if (is_valid_policy_hnd(&sec_handle)) {
+ rpccli_lsa_Close(cli, mem_ctx, &sec_handle);
+ }
+ if (is_valid_policy_hnd(&handle)) {
+ rpccli_lsa_Close(cli, mem_ctx, &handle);
+ }
+
+ return status;
+}
+
+static NTSTATUS cmd_lsa_set_secret(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ const char **argv)
+{
+ NTSTATUS status;
+ struct policy_handle handle, sec_handle;
+ struct lsa_String name;
+ struct lsa_DATA_BUF new_val;
+ struct lsa_DATA_BUF old_val;
+ DATA_BLOB enc_key;
+ DATA_BLOB session_key;
+
+ if (argc < 3) {
+ printf("Usage: %s name secret\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ status = rpccli_lsa_open_policy2(cli, mem_ctx,
+ true,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ init_lsa_String(&name, argv[1]);
+
+ status = rpccli_lsa_OpenSecret(cli, mem_ctx,
+ &handle,
+ name,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &sec_handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ ZERO_STRUCT(new_val);
+ ZERO_STRUCT(old_val);
+
+ status = cli_get_session_key(mem_ctx, cli, &session_key);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ enc_key = sess_encrypt_string(argv[2], &session_key);
+
+ new_val.length = enc_key.length;
+ new_val.size = enc_key.length;
+ new_val.data = enc_key.data;
+
+ status = rpccli_lsa_SetSecret(cli, mem_ctx,
+ &sec_handle,
+ &new_val,
+ NULL);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ done:
+ if (is_valid_policy_hnd(&sec_handle)) {
+ rpccli_lsa_Close(cli, mem_ctx, &sec_handle);
+ }
+ if (is_valid_policy_hnd(&handle)) {
+ rpccli_lsa_Close(cli, mem_ctx, &handle);
+ }
+
+ return status;
+}
+
+static NTSTATUS cmd_lsa_retrieve_private_data(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ const char **argv)
+{
+ NTSTATUS status;
+ struct policy_handle handle;
+ struct lsa_String name;
+ struct lsa_DATA_BUF *val;
+ DATA_BLOB session_key;
+ DATA_BLOB blob;
+ char *secret;
+
+ if (argc < 2) {
+ printf("Usage: %s name\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ status = rpccli_lsa_open_policy2(cli, mem_ctx,
+ true,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ init_lsa_String(&name, argv[1]);
+
+ ZERO_STRUCT(val);
+
+ status = rpccli_lsa_RetrievePrivateData(cli, mem_ctx,
+ &handle,
+ &name,
+ &val);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ status = cli_get_session_key(mem_ctx, cli, &session_key);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ if (val) {
+ blob = data_blob_const(val->data, val->length);
+ }
+
+ secret = sess_decrypt_string(mem_ctx, &blob, &session_key);
+ if (secret) {
+ d_printf("secret: %s\n", secret);
+ }
+
+ done:
+ if (is_valid_policy_hnd(&handle)) {
+ rpccli_lsa_Close(cli, mem_ctx, &handle);
+ }
+
+ return status;
+}
+
+static NTSTATUS cmd_lsa_store_private_data(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ const char **argv)
+{
+ NTSTATUS status;
+ struct policy_handle handle;
+ struct lsa_String name;
+ struct lsa_DATA_BUF val;
+ DATA_BLOB session_key;
+ DATA_BLOB enc_key;
+
+ if (argc < 3) {
+ printf("Usage: %s name secret\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ status = rpccli_lsa_open_policy2(cli, mem_ctx,
+ true,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ init_lsa_String(&name, argv[1]);
+
+ ZERO_STRUCT(val);
+
+ status = cli_get_session_key(mem_ctx, cli, &session_key);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ enc_key = sess_encrypt_string(argv[2], &session_key);
+
+ val.length = enc_key.length;
+ val.size = enc_key.length;
+ val.data = enc_key.data;
+
+ status = rpccli_lsa_StorePrivateData(cli, mem_ctx,
+ &handle,
+ &name,
+ &val);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ done:
+ if (is_valid_policy_hnd(&handle)) {
+ rpccli_lsa_Close(cli, mem_ctx, &handle);
+ }
+
+ return status;
+}
+
/* List of commands exported by this module */
@@ -1384,6 +1744,12 @@ struct cmd_set lsarpc_commands[] = {
{ "lsaquerytrustdominfobyname",RPC_RTYPE_NTSTATUS, cmd_lsa_query_trustdominfobyname, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Query LSA trusted domains info (given a name), only works for Windows > 2k", "" },
{ "lsaquerytrustdominfobysid",RPC_RTYPE_NTSTATUS, cmd_lsa_query_trustdominfobysid, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Query LSA trusted domains info (given a SID)", "" },
{ "getusername", RPC_RTYPE_NTSTATUS, cmd_lsa_get_username, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Get username", "" },
+ { "createsecret", RPC_RTYPE_NTSTATUS, cmd_lsa_create_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Create Secret", "" },
+ { "deletesecret", RPC_RTYPE_NTSTATUS, cmd_lsa_delete_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Delete Secret", "" },
+ { "querysecret", RPC_RTYPE_NTSTATUS, cmd_lsa_query_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Query Secret", "" },
+ { "setsecret", RPC_RTYPE_NTSTATUS, cmd_lsa_set_secret, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Set Secret", "" },
+ { "retrieveprivatedata", RPC_RTYPE_NTSTATUS, cmd_lsa_retrieve_private_data, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Retrieve Private Data", "" },
+ { "storeprivatedata", RPC_RTYPE_NTSTATUS, cmd_lsa_store_private_data, NULL, &ndr_table_lsarpc.syntax_id, NULL, "Store Private Data", "" },
{ NULL }
};
diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c
index cbff69ff17..48f9df3cac 100644
--- a/source3/rpcclient/cmd_spoolss.c
+++ b/source3/rpcclient/cmd_spoolss.c
@@ -3430,6 +3430,48 @@ static WERROR cmd_spoolss_enum_monitors(struct rpc_pipe_client *cli,
return werror;
}
+static WERROR cmd_spoolss_create_printer_ic(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ const char **argv)
+{
+ WERROR result;
+ NTSTATUS status;
+ struct policy_handle handle, gdi_handle;
+ const char *printername;
+ struct spoolss_DevmodeContainer devmode_ctr;
+
+ RPCCLIENT_PRINTERNAME(printername, cli, argv[1]);
+
+ result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
+ printername,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ &handle);
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
+ }
+
+ ZERO_STRUCT(devmode_ctr);
+
+ status = rpccli_spoolss_CreatePrinterIC(cli, mem_ctx,
+ &handle,
+ &gdi_handle,
+ &devmode_ctr,
+ &result);
+ if (!W_ERROR_IS_OK(result)) {
+ goto done;
+ }
+
+ done:
+ if (is_valid_policy_hnd(&gdi_handle)) {
+ rpccli_spoolss_DeletePrinterIC(cli, mem_ctx, &gdi_handle, NULL);
+ }
+ if (is_valid_policy_hnd(&handle)) {
+ rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
+ }
+
+ return result;
+}
+
/* List of commands exported by this module */
struct cmd_set spoolss_commands[] = {
@@ -3469,6 +3511,7 @@ struct cmd_set spoolss_commands[] = {
{ "enumprocs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_procs, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processors", "" },
{ "enumprocdatatypes", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_proc_data_types, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Processor Data Types", "" },
{ "enummonitors", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_monitors, &ndr_table_spoolss.syntax_id, NULL, "Enumerate Print Monitors", "" },
+ { "createprinteric", RPC_RTYPE_WERROR, NULL, cmd_spoolss_create_printer_ic, &ndr_table_spoolss.syntax_id, NULL, "Create Printer IC", "" },
{ NULL }
};
diff --git a/source3/script/tests/test_smbtorture_s3.sh b/source3/script/tests/test_smbtorture_s3.sh
index c577ed18d4..602433bd91 100755
--- a/source3/script/tests/test_smbtorture_s3.sh
+++ b/source3/script/tests/test_smbtorture_s3.sh
@@ -21,6 +21,9 @@ incdir=`dirname $0`
. $incdir/test_functions.sh
}
+SMB_CONF_PATH="$CONFFILE"
+export SMB_CONF_PATH
+
tests="FDPASS LOCK1 LOCK2 LOCK3 LOCK4 LOCK5 LOCK6 LOCK7"
#tests="$tests UNLINK BROWSE ATTR TRANS2 MAXFID TORTURE "
tests="$tests UNLINK BROWSE ATTR TRANS2 TORTURE "
@@ -29,6 +32,7 @@ tests="$tests DIR DIR1 TCON TCONDEV RW1 RW2 RW3"
tests="$tests OPEN XCOPY RENAME DELETE PROPERTIES W2K"
tests="$tests TCON2 IOCTL CHKPATH FDSESS LOCAL-SUBSTITUTE CHAIN1"
tests="$tests GETADDRINFO POSIX UID-REGRESSION-TEST SHORTNAME-TEST"
+tests="$tests LOCAL-BASE64 LOCAL-GENCACHE"
skipped1="RANDOMIPC NEGNOWAIT NBENCH ERRMAPEXTRACT TRANS2SCAN NTTRANSSCAN"
skipped2="DENY1 DENY2 OPENATTR CASETABLE EATEST"
diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c
index c6f700f17a..ed415c5e13 100644
--- a/source3/smbd/aio.c
+++ b/source3/smbd/aio.c
@@ -188,7 +188,7 @@ bool schedule_aio_read_and_X(connection_struct *conn,
DEBUG(10,("schedule_aio_read_and_X: scheduled aio_read for file %s, "
"offset %.0f, len = %u (mid = %u)\n",
- fsp->fsp_name, (double)startpos, (unsigned int)smb_maxcnt,
+ fsp_str_dbg(fsp), (double)startpos, (unsigned int)smb_maxcnt,
(unsigned int)aio_ex->req->mid ));
outstanding_aio_calls++;
@@ -241,7 +241,7 @@ bool schedule_aio_write_and_X(connection_struct *conn,
DEBUG(10,("schedule_aio_write_and_X: failed to schedule "
"aio_write for file %s, offset %.0f, len = %u "
"(mid = %u)\n",
- fsp->fsp_name, (double)startpos,
+ fsp_str_dbg(fsp), (double)startpos,
(unsigned int)numtowrite,
(unsigned int)req->mid ));
return False;
@@ -300,14 +300,14 @@ bool schedule_aio_write_and_X(connection_struct *conn,
"failed.");
}
DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write "
- "behind for file %s\n", fsp->fsp_name ));
+ "behind for file %s\n", fsp_str_dbg(fsp)));
}
outstanding_aio_calls++;
DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write for file "
"%s, offset %.0f, len = %u (mid = %u) "
"outstanding_aio_calls = %d\n",
- fsp->fsp_name, (double)startpos, (unsigned int)numtowrite,
+ fsp_str_dbg(fsp), (double)startpos, (unsigned int)numtowrite,
(unsigned int)aio_ex->req->mid, outstanding_aio_calls ));
return True;
@@ -341,7 +341,7 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
DEBUG( 3,( "handle_aio_read_complete: file %s nread == -1. "
"Error = %s\n",
- aio_ex->fsp->fsp_name, strerror(errno) ));
+ fsp_str_dbg(aio_ex->fsp), strerror(errno)));
ret = errno;
ERROR_NT(map_nt_error_from_unix(ret));
@@ -359,7 +359,7 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
DEBUG( 3, ( "handle_aio_read_complete file %s max=%d "
"nread=%d\n",
- aio_ex->fsp->fsp_name,
+ fsp_str_dbg(aio_ex->fsp),
(int)aio_ex->acb.aio_nbytes, (int)nread ) );
}
@@ -374,7 +374,7 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
DEBUG(10,("handle_aio_read_complete: scheduled aio_read completed "
"for file %s, offset %.0f, len = %u\n",
- aio_ex->fsp->fsp_name, (double)aio_ex->acb.aio_offset,
+ fsp_str_dbg(aio_ex->fsp), (double)aio_ex->acb.aio_offset,
(unsigned int)nread ));
return ret;
@@ -399,13 +399,13 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
DEBUG(5,("handle_aio_write_complete: "
"aio_write_behind failed ! File %s "
"is corrupt ! Error %s\n",
- fsp->fsp_name, strerror(errno) ));
+ fsp_str_dbg(fsp), strerror(errno)));
ret = errno;
} else {
DEBUG(0,("handle_aio_write_complete: "
"aio_write_behind failed ! File %s "
"is corrupt ! Wanted %u bytes but "
- "only wrote %d\n", fsp->fsp_name,
+ "only wrote %d\n", fsp_str_dbg(fsp),
(unsigned int)numtowrite,
(int)nwritten ));
ret = EIO;
@@ -413,7 +413,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
} else {
DEBUG(10,("handle_aio_write_complete: "
"aio_write_behind completed for file %s\n",
- fsp->fsp_name ));
+ fsp_str_dbg(fsp)));
}
return 0;
}
@@ -424,7 +424,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
if(nwritten == -1) {
DEBUG( 3,( "handle_aio_write: file %s wanted %u bytes. "
"nwritten == %d. Error = %s\n",
- fsp->fsp_name, (unsigned int)numtowrite,
+ fsp_str_dbg(fsp), (unsigned int)numtowrite,
(int)nwritten, strerror(errno) ));
/* If errno is ECANCELED then don't return anything to the
@@ -456,7 +456,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
ERRHRD, ERRdiskfull);
srv_set_message(outbuf,0,0,true);
DEBUG(5,("handle_aio_write: sync_file for %s returned %s\n",
- fsp->fsp_name, nt_errstr(status) ));
+ fsp_str_dbg(fsp), nt_errstr(status)));
}
aio_ex->fsp->fh->pos = aio_ex->acb.aio_offset + nwritten;
@@ -472,7 +472,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
DEBUG(10,("handle_aio_write_complete: scheduled aio_write completed "
"for file %s, offset %.0f, requested %u, written = %u\n",
- fsp->fsp_name, (double)aio_ex->acb.aio_offset,
+ fsp_str_dbg(fsp), (double)aio_ex->acb.aio_offset,
(unsigned int)numtowrite, (unsigned int)nwritten ));
return ret;
@@ -496,7 +496,7 @@ static bool handle_aio_completed(struct aio_extra *aio_ex, int *perr)
if (SMB_VFS_AIO_ERROR(aio_ex->fsp, &aio_ex->acb) == EINPROGRESS) {
DEBUG(10,( "handle_aio_completed: operation mid %u still in "
"process for file %s\n",
- aio_ex->req->mid, aio_ex->fsp->fsp_name ));
+ aio_ex->req->mid, fsp_str_dbg(aio_ex->fsp)));
return False;
}
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index 4c61428692..e752194ca5 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -202,7 +202,7 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
"expiry time (%u sec. %u usec) (+%d msec) for fnum = %d, name = %s\n",
(unsigned int)blr->expire_time.tv_sec,
(unsigned int)blr->expire_time.tv_usec, lock_timeout,
- blr->fsp->fnum, blr->fsp->fsp_name ));
+ blr->fsp->fnum, fsp_str_dbg(blr->fsp)));
return True;
}
@@ -418,8 +418,9 @@ static bool process_lockingX(struct blocking_lock_record *blr)
* Success - we got all the locks.
*/
- DEBUG(3,("process_lockingX file = %s, fnum=%d type=%d num_locks=%d\n",
- fsp->fsp_name, fsp->fnum, (unsigned int)locktype, num_locks) );
+ DEBUG(3,("process_lockingX file = %s, fnum=%d type=%d "
+ "num_locks=%d\n", fsp_str_dbg(fsp), fsp->fnum,
+ (unsigned int)locktype, num_locks));
reply_lockingX_success(blr);
return True;
@@ -442,7 +443,7 @@ static bool process_lockingX(struct blocking_lock_record *blr)
DEBUG(10,("process_lockingX: only got %d locks of %d needed for file %s, fnum = %d. \
Waiting....\n",
- blr->lock_num, num_locks, fsp->fsp_name, fsp->fnum));
+ blr->lock_num, num_locks, fsp_str_dbg(fsp), fsp->fnum));
return False;
}
@@ -533,7 +534,7 @@ void cancel_pending_lock_requests_by_fid(files_struct *fsp, struct byte_range_lo
DEBUG(10, ("remove_pending_lock_requests_by_fid - removing "
"request type %d for file %s fnum = %d\n",
- blr->req->cmd, fsp->fsp_name, fsp->fnum));
+ blr->req->cmd, fsp_str_dbg(fsp), fsp->fnum));
blr_cancelled = blocking_lock_cancel(fsp,
blr->lock_pid,
@@ -583,7 +584,7 @@ void remove_pending_lock_requests_by_mid(int mid)
if (br_lck) {
DEBUG(10, ("remove_pending_lock_requests_by_mid - "
"removing request type %d for file %s fnum "
- "= %d\n", blr->req->cmd, fsp->fsp_name,
+ "= %d\n", blr->req->cmd, fsp_str_dbg(fsp),
fsp->fnum ));
brl_lock_cancel(br_lck,
@@ -703,7 +704,7 @@ void process_blocking_lock_queue(void)
DEBUG(5,("process_blocking_lock_queue: "
"pending lock fnum = %d for file %s "
"timed out.\n", blr->fsp->fnum,
- blr->fsp->fsp_name ));
+ fsp_str_dbg(blr->fsp)));
brl_lock_cancel(br_lck,
blr->lock_pid,
diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c
index 2eb09d176d..64f988f1f7 100644
--- a/source3/smbd/chgpasswd.c
+++ b/source3/smbd/chgpasswd.c
@@ -1024,7 +1024,7 @@ static bool check_passwd_history(struct samu *sampass, const char *plaintext)
int i;
uint32 pwHisLen, curr_pwHisLen;
- pdb_get_account_policy(AP_PASSWORD_HISTORY, &pwHisLen);
+ pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHisLen);
if (pwHisLen == 0) {
return False;
}
@@ -1107,7 +1107,7 @@ NTSTATUS change_oem_password(struct samu *hnd, char *old_passwd, char *new_passw
* denies machines to change the password. *
* Should we deny also SRVTRUST and/or DOMSTRUST ? .SSS. */
if (pdb_get_acct_ctrl(hnd) & ACB_WSTRUST) {
- if (pdb_get_account_policy(AP_REFUSE_MACHINE_PW_CHANGE, &refuse) && refuse) {
+ if (pdb_get_account_policy(PDB_POLICY_REFUSE_MACHINE_PW_CHANGE, &refuse) && refuse) {
DEBUG(1, ("Machine %s cannot change password now, "
"denied by Refuse Machine Password Change policy\n",
username));
@@ -1130,7 +1130,7 @@ NTSTATUS change_oem_password(struct samu *hnd, char *old_passwd, char *new_passw
return NT_STATUS_ACCOUNT_RESTRICTION;
}
- if (pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &min_len) && (str_charnum(new_passwd) < min_len)) {
+ if (pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &min_len) && (str_charnum(new_passwd) < min_len)) {
DEBUG(1, ("user %s cannot change password - password too short\n",
username));
DEBUGADD(1, (" account policy min password len = %d\n", min_len));
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index a0672f3949..788b0a7cec 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -36,90 +36,99 @@ static NTSTATUS check_magic(struct files_struct *fsp)
TALLOC_CTX *ctx = NULL;
const char *p;
struct connection_struct *conn = fsp->conn;
+ char *fname = NULL;
+ NTSTATUS status;
if (!*lp_magicscript(SNUM(conn))) {
return NT_STATUS_OK;
}
- DEBUG(5,("checking magic for %s\n",fsp->fsp_name));
+ DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp)));
+
+ ctx = talloc_stackframe();
- if (!(p = strrchr_m(fsp->fsp_name,'/'))) {
- p = fsp->fsp_name;
+ fname = fsp->fsp_name->base_name;
+
+ if (!(p = strrchr_m(fname,'/'))) {
+ p = fname;
} else {
p++;
}
if (!strequal(lp_magicscript(SNUM(conn)),p)) {
- return NT_STATUS_OK;
+ status = NT_STATUS_OK;
+ goto out;
}
- ctx = talloc_stackframe();
-
if (*lp_magicoutput(SNUM(conn))) {
magic_output = lp_magicoutput(SNUM(conn));
} else {
magic_output = talloc_asprintf(ctx,
"%s.out",
- fsp->fsp_name);
+ fname);
}
if (!magic_output) {
- TALLOC_FREE(ctx);
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
}
/* Ensure we don't depend on user's PATH. */
- p = talloc_asprintf(ctx, "./%s", fsp->fsp_name);
+ p = talloc_asprintf(ctx, "./%s", fname);
if (!p) {
- TALLOC_FREE(ctx);
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto out;
}
- if (chmod(fsp->fsp_name,0755) == -1) {
- TALLOC_FREE(ctx);
- return map_nt_error_from_unix(errno);
+ if (chmod(fname, 0755) == -1) {
+ status = map_nt_error_from_unix(errno);
+ goto out;
}
ret = smbrun(p,&tmp_fd);
DEBUG(3,("Invoking magic command %s gave %d\n",
p,ret));
- unlink(fsp->fsp_name);
+ unlink(fname);
if (ret != 0 || tmp_fd == -1) {
if (tmp_fd != -1) {
close(tmp_fd);
}
- TALLOC_FREE(ctx);
- return NT_STATUS_UNSUCCESSFUL;
+ status = NT_STATUS_UNSUCCESSFUL;
+ goto out;
}
outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
if (outfd == -1) {
int err = errno;
close(tmp_fd);
- TALLOC_FREE(ctx);
- return map_nt_error_from_unix(err);
+ status = map_nt_error_from_unix(err);
+ goto out;
}
if (sys_fstat(tmp_fd,&st) == -1) {
int err = errno;
close(tmp_fd);
close(outfd);
- TALLOC_FREE(ctx);
- return map_nt_error_from_unix(err);
+ status = map_nt_error_from_unix(err);
+ goto out;
}
if (transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_ex_size) == (SMB_OFF_T)-1) {
int err = errno;
close(tmp_fd);
close(outfd);
- TALLOC_FREE(ctx);
- return map_nt_error_from_unix(err);
+ status = map_nt_error_from_unix(err);
+ goto out;
}
close(tmp_fd);
if (close(outfd) == -1) {
- TALLOC_FREE(ctx);
- return map_nt_error_from_unix(errno);
+ status = map_nt_error_from_unix(errno);
+ goto out;
}
+
+ status = NT_STATUS_OK;
+
+ out:
TALLOC_FREE(ctx);
- return NT_STATUS_OK;
+ return status;
}
/****************************************************************************
@@ -261,18 +270,10 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
bool delete_file = false;
bool changed_user = false;
struct share_mode_lock *lck = NULL;
- struct smb_filename *smb_fname = NULL;
- char *fname = NULL;
NTSTATUS status = NT_STATUS_OK;
int ret;
struct file_id id;
- status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
- NULL, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- goto done;
- }
-
/*
* Lock the share entries, and determine if we should delete
* on close. If so delete whilst the lock is still in effect.
@@ -284,7 +285,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
if (lck == NULL) {
DEBUG(0, ("close_remove_share_mode: Could not get share mode "
- "lock for file %s\n", smb_fname_str_dbg(smb_fname)));
+ "lock for file %s\n", fsp_str_dbg(fsp)));
status = NT_STATUS_INVALID_PARAMETER;
goto done;
}
@@ -296,7 +297,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
if (!del_share_mode(lck, fsp)) {
DEBUG(0, ("close_remove_share_mode: Could not delete share "
"entry for file %s\n",
- smb_fname_str_dbg(smb_fname)));
+ fsp_str_dbg(fsp)));
}
if (fsp->initial_delete_on_close && (lck->delete_token == NULL)) {
@@ -354,7 +355,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
*/
DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
- "- deleting file.\n", smb_fname_str_dbg(smb_fname)));
+ "- deleting file.\n", fsp_str_dbg(fsp)));
/*
* Don't try to update the write time when we delete the file
@@ -366,7 +367,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
DEBUG(5,("close_remove_share_mode: file %s. "
"Change user to uid %u\n",
- smb_fname_str_dbg(smb_fname),
+ fsp_str_dbg(fsp),
(unsigned int)lck->delete_token->uid));
if (!push_sec_ctx()) {
@@ -387,30 +388,30 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
hasn't been renamed. */
if (fsp->posix_open) {
- ret = SMB_VFS_LSTAT(conn, smb_fname);
+ ret = SMB_VFS_LSTAT(conn, fsp->fsp_name);
} else {
- ret = SMB_VFS_STAT(conn, smb_fname);
+ ret = SMB_VFS_STAT(conn, fsp->fsp_name);
}
if (ret != 0) {
DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
"was set and stat failed with error %s\n",
- smb_fname_str_dbg(smb_fname), strerror(errno)));
+ fsp_str_dbg(fsp), strerror(errno)));
/*
* Don't save the errno here, we ignore this error
*/
goto done;
}
- id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
+ id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
if (!file_id_equal(&fsp->file_id, &id)) {
DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
"was set and dev and/or inode does not match\n",
- smb_fname_str_dbg(smb_fname)));
+ fsp_str_dbg(fsp)));
DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
"stat file_id %s\n",
- smb_fname_str_dbg(smb_fname),
+ fsp_str_dbg(fsp),
file_id_string_tos(&fsp->file_id),
file_id_string_tos(&id)));
/*
@@ -420,9 +421,9 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
}
if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
- && !is_ntfs_stream_smb_fname(smb_fname)) {
+ && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
- status = delete_all_streams(conn, smb_fname->base_name);
+ status = delete_all_streams(conn, fsp->fsp_name->base_name);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5, ("delete_all_streams failed: %s\n",
@@ -432,7 +433,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
}
- if (SMB_VFS_UNLINK(conn, smb_fname) != 0) {
+ if (SMB_VFS_UNLINK(conn, fsp->fsp_name) != 0) {
/*
* This call can potentially fail as another smbd may
* have had the file open with delete on close set and
@@ -443,21 +444,14 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
"was set and unlink failed with error %s\n",
- smb_fname_str_dbg(smb_fname), strerror(errno)));
+ fsp_str_dbg(fsp), strerror(errno)));
status = map_nt_error_from_unix(errno);
}
- status = get_full_smb_filename(talloc_tos(), smb_fname, &fname);
- if (!NT_STATUS_IS_OK(status)) {
- goto done;
- }
-
notify_fname(conn, NOTIFY_ACTION_REMOVED,
FILE_NOTIFY_CHANGE_FILE_NAME,
- fname);
-
- TALLOC_FREE(fname);
+ fsp->fsp_name->base_name);
/* As we now have POSIX opens which can unlink
* with other open files we may have taken
@@ -476,7 +470,6 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
}
TALLOC_FREE(lck);
- TALLOC_FREE(smb_fname);
return status;
}
@@ -499,7 +492,6 @@ void set_close_write_time(struct files_struct *fsp, struct timespec ts)
static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
{
- struct smb_filename *smb_fname = NULL;
struct smb_file_time ft;
NTSTATUS status;
int ret = -1;
@@ -514,43 +506,32 @@ static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
fsp->close_write_time = timespec_current();
}
- /* XXX: Remove when fsp->fsp_name is converted to smb_filename. */
- status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
- NULL, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- goto out;
- }
-
/* Ensure we have a valid stat struct for the source. */
if (fsp->fh->fd != -1) {
- ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
+ ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
} else {
if (fsp->posix_open) {
- ret = SMB_VFS_LSTAT(fsp->conn, smb_fname);
+ ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
} else {
- ret = SMB_VFS_STAT(fsp->conn, smb_fname);
+ ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
}
}
if (ret == -1) {
- status = map_nt_error_from_unix(errno);
- goto out;
+ return map_nt_error_from_unix(errno);
}
- if (!VALID_STAT(smb_fname->st)) {
+ if (!VALID_STAT(fsp->fsp_name->st)) {
/* if it doesn't seem to be a real file */
- status = NT_STATUS_OK;
- goto out;
+ return NT_STATUS_OK;
}
ft.mtime = fsp->close_write_time;
- status = smb_set_file_time(fsp->conn, fsp, smb_fname, &ft, true);
+ status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, true);
if (!NT_STATUS_IS_OK(status)) {
- goto out;
+ return status;
}
- out:
- TALLOC_FREE(smb_fname);
return status;
}
@@ -647,7 +628,7 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
status = ntstatus_keeperror(status, tmp);
DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
- conn->server_info->unix_name,fsp->fsp_name,
+ conn->server_info->unix_name, fsp_str_dbg(fsp),
conn->num_files_open - 1,
nt_errstr(status) ));
@@ -663,16 +644,9 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
enum file_close_type close_type)
{
struct share_mode_lock *lck = NULL;
- struct smb_filename *smb_dname = NULL;
bool delete_dir = False;
NTSTATUS status = NT_STATUS_OK;
- status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
- NULL, &smb_dname);
- if (!NT_STATUS_IS_OK(status)) {
- goto out;
- }
-
/*
* NT can set delete_on_close of the last open
* reference to a directory also.
@@ -683,14 +657,14 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
if (lck == NULL) {
DEBUG(0, ("close_directory: Could not get share mode lock for "
- "%s\n", smb_fname_str_dbg(smb_dname)));
+ "%s\n", fsp_str_dbg(fsp)));
status = NT_STATUS_INVALID_PARAMETER;
goto out;
}
if (!del_share_mode(lck, fsp)) {
DEBUG(0, ("close_directory: Could not delete share entry for "
- "%s\n", smb_fname_str_dbg(smb_dname)));
+ "%s\n", fsp_str_dbg(fsp)));
}
if (fsp->initial_delete_on_close) {
@@ -704,7 +678,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
become_user(fsp->conn, fsp->vuid);
became_user = True;
}
- send_stat_cache_delete_message(fsp->fsp_name);
+ send_stat_cache_delete_message(fsp->fsp_name->base_name);
set_delete_on_close_lck(lck, True, &current_user.ut);
if (became_user) {
unbecome_user();
@@ -747,11 +721,12 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
TALLOC_FREE(lck);
- status = rmdir_internals(talloc_tos(), fsp->conn, smb_dname);
+ status = rmdir_internals(talloc_tos(), fsp->conn,
+ fsp->fsp_name);
DEBUG(5,("close_directory: %s. Delete on close was set - "
"deleting directory returned %s.\n",
- smb_fname_str_dbg(smb_dname), nt_errstr(status)));
+ fsp_str_dbg(fsp), nt_errstr(status)));
/* unbecome user. */
pop_sec_ctx();
@@ -774,7 +749,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
- smb_fname_str_dbg(smb_dname), fsp->fh->fd, errno,
+ fsp_str_dbg(fsp), fsp->fh->fd, errno,
strerror(errno)));
}
@@ -786,7 +761,6 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
out:
TALLOC_FREE(lck);
- TALLOC_FREE(smb_dname);
return status;
}
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index ca926aa33c..bd0c7df959 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -448,8 +448,8 @@ static bool get_stat_dos_flags(connection_struct *conn,
if (S_ISDIR(smb_fname->st.st_ex_mode))
*dosmode |= aDIR;
- *dosmode |= set_sparse_flag(smb_fname->st);
- *dosmode |= set_link_read_only_flag(smb_fname->st);
+ *dosmode |= set_sparse_flag(&smb_fname->st);
+ *dosmode |= set_link_read_only_flag(&smb_fname->st);
return true;
}
@@ -845,7 +845,7 @@ bool update_write_time(struct files_struct *fsp)
}
notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
- FILE_NOTIFY_CHANGE_LAST_WRITE, fsp->fsp_name);
+ FILE_NOTIFY_CHANGE_LAST_WRITE, fsp->fsp_name->base_name);
return true;
}
diff --git a/source3/smbd/error.c b/source3/smbd/error.c
index ce22f86414..874efa2a0b 100644
--- a/source3/smbd/error.c
+++ b/source3/smbd/error.c
@@ -136,33 +136,3 @@ void reply_openerror(struct smb_request *req, NTSTATUS status)
reply_nterror(req, status);
}
}
-
-void reply_unix_error(struct smb_request *req, uint8 defclass, uint32 defcode,
- NTSTATUS defstatus, int line, const char *file)
-{
- int eclass=defclass;
- int ecode=defcode;
- NTSTATUS ntstatus = defstatus;
- int i=0;
-
- TALLOC_FREE(req->outbuf);
- reply_outbuf(req, 0, 0);
-
- if (errno != 0) {
- DEBUG(3,("unix_error_packet: error string = %s\n",
- strerror(errno)));
-
- while (unix_dos_nt_errmap[i].dos_class != 0) {
- if (unix_dos_nt_errmap[i].unix_error == errno) {
- eclass = unix_dos_nt_errmap[i].dos_class;
- ecode = unix_dos_nt_errmap[i].dos_code;
- ntstatus = unix_dos_nt_errmap[i].nt_error;
- break;
- }
- i++;
- }
- }
-
- error_packet_set((char *)req->outbuf, eclass, ecode, ntstatus,
- line, file);
-}
diff --git a/source3/smbd/fake_file.c b/source3/smbd/fake_file.c
index ef54398bc4..743d88f360 100644
--- a/source3/smbd/fake_file.c
+++ b/source3/smbd/fake_file.c
@@ -71,23 +71,32 @@ static struct fake_file_handle *init_fake_file_handle(enum FAKE_FILE_TYPE type)
Does this name match a fake filename ?
****************************************************************************/
-enum FAKE_FILE_TYPE is_fake_file(const char *fname)
+enum FAKE_FILE_TYPE is_fake_file(const struct smb_filename *smb_fname)
{
#ifdef HAVE_SYS_QUOTAS
int i;
+ char *fname = NULL;
+ NTSTATUS status;
#endif
- if (!fname) {
+ if (!smb_fname) {
return FAKE_FILE_TYPE_NONE;
}
#ifdef HAVE_SYS_QUOTAS
+ status = get_full_smb_filename(talloc_tos(), smb_fname, &fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return FAKE_FILE_TYPE_NONE;
+ }
+
for (i=0;fake_files[i].name!=NULL;i++) {
if (strncmp(fname,fake_files[i].name,strlen(fake_files[i].name))==0) {
DEBUG(5,("is_fake_file: [%s] is a fake file\n",fname));
+ TALLOC_FREE(fname);
return fake_files[i].type;
}
}
+ TALLOC_FREE(fname);
#endif
return FAKE_FILE_TYPE_NONE;
@@ -101,7 +110,7 @@ enum FAKE_FILE_TYPE is_fake_file(const char *fname)
NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn,
uint16_t current_vuid,
enum FAKE_FILE_TYPE fake_file_type,
- const char *fname,
+ const struct smb_filename *smb_fname,
uint32 access_mask,
files_struct **result)
{
@@ -112,7 +121,8 @@ NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn,
if (conn->server_info->utok.uid != 0) {
DEBUG(3, ("open_fake_file_shared: access_denied to "
"service[%s] file[%s] user[%s]\n",
- lp_servicename(SNUM(conn)), fname,
+ lp_servicename(SNUM(conn)),
+ smb_fname_str_dbg(smb_fname),
conn->server_info->unix_name));
return NT_STATUS_ACCESS_DENIED;
@@ -124,7 +134,8 @@ NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn,
}
DEBUG(5,("open_fake_file_shared: fname = %s, FID = %d, access_mask = 0x%x\n",
- fname, fsp->fnum, (unsigned int)access_mask));
+ smb_fname_str_dbg(smb_fname), fsp->fnum,
+ (unsigned int)access_mask));
fsp->conn = conn;
fsp->fh->fd = -1;
@@ -132,8 +143,12 @@ NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn,
fsp->fh->pos = -1;
fsp->can_lock = False; /* Should this be true ? - No, JRA */
fsp->access_mask = access_mask;
- string_set(&fsp->fsp_name,fname);
-
+ status = fsp_set_smb_fname(fsp, smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ file_free(req, fsp);
+ return NT_STATUS_NO_MEMORY;
+ }
+
fsp->fake_file_handle = init_fake_file_handle(fake_file_type);
if (fsp->fake_file_handle==NULL) {
diff --git a/source3/smbd/file_access.c b/source3/smbd/file_access.c
index d8fee1db06..7d0a552956 100644
--- a/source3/smbd/file_access.c
+++ b/source3/smbd/file_access.c
@@ -33,7 +33,6 @@ bool can_access_file_acl(struct connection_struct *conn,
NTSTATUS status;
uint32_t access_granted;
struct security_descriptor *secdesc = NULL;
- char *fname = NULL;
bool ret;
if (conn->server_info->utok.uid == 0 || conn->admin_user) {
@@ -41,13 +40,7 @@ bool can_access_file_acl(struct connection_struct *conn,
return true;
}
- status = get_full_smb_filename(talloc_tos(), smb_fname, &fname);
- if (!NT_STATUS_IS_OK(status)) {
- ret = false;
- goto out;
- }
-
- status = SMB_VFS_GET_NT_ACL(conn, fname,
+ status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name,
(OWNER_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION),
@@ -62,7 +55,6 @@ bool can_access_file_acl(struct connection_struct *conn,
access_mask, &access_granted);
ret = NT_STATUS_IS_OK(status);
out:
- TALLOC_FREE(fname);
TALLOC_FREE(secdesc);
return ret;
}
diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c
index 0c13b845df..bd609d3e86 100644
--- a/source3/smbd/fileio.c
+++ b/source3/smbd/fileio.c
@@ -57,6 +57,7 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n)
/* you can't read from print files */
if (fsp->print_file) {
+ errno = EBADF;
return -1;
}
@@ -102,7 +103,7 @@ tryagain:
}
DEBUG(10,("read_file (%s): pos = %.0f, size = %lu, returned %lu\n",
- fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret ));
+ fsp_str_dbg(fsp), (double)pos, (unsigned long)n, (long)ret));
fsp->fh->pos += ret;
fsp->fh->position_information = fsp->fh->pos;
@@ -135,7 +136,7 @@ static ssize_t real_write_file(struct smb_request *req,
}
DEBUG(10,("real_write_file (%s): pos = %.0f, size = %lu, returned %ld\n",
- fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret ));
+ fsp_str_dbg(fsp), (double)pos, (unsigned long)n, (long)ret));
if (ret != -1) {
fsp->fh->pos += ret;
@@ -163,8 +164,9 @@ static int wcp_file_size_change(files_struct *fsp)
wcp->file_size = wcp->offset + wcp->data_size;
ret = SMB_VFS_FTRUNCATE(fsp, wcp->file_size);
if (ret == -1) {
- DEBUG(0,("wcp_file_size_change (%s): ftruncate of size %.0f error %s\n",
- fsp->fsp_name, (double)wcp->file_size, strerror(errno) ));
+ DEBUG(0,("wcp_file_size_change (%s): ftruncate of size %.0f "
+ "error %s\n", fsp_str_dbg(fsp),
+ (double)wcp->file_size, strerror(errno)));
}
return ret;
}
@@ -178,7 +180,7 @@ static void update_write_time_handler(struct event_context *ctx,
/* Remove the timed event handler. */
TALLOC_FREE(fsp->update_write_time_event);
- DEBUG(5, ("Update write time on %s\n", fsp->fsp_name));
+ DEBUG(5, ("Update write time on %s\n", fsp_str_dbg(fsp)));
/* change the write time if not already changed by someone else */
update_write_time(fsp);
@@ -243,7 +245,8 @@ void trigger_write_time_update_immediate(struct files_struct *fsp)
}
TALLOC_FREE(fsp->update_write_time_event);
- DEBUG(5, ("Update write time immediate on %s\n", fsp->fsp_name));
+ DEBUG(5, ("Update write time immediate on %s\n",
+ fsp_str_dbg(fsp)));
fsp->update_write_time_triggered = true;
@@ -284,28 +287,17 @@ ssize_t write_file(struct smb_request *req,
}
if (!fsp->modified) {
- struct smb_filename *smb_fname = NULL;
- NTSTATUS status;
-
fsp->modified = True;
- status = create_synthetic_smb_fname_split(talloc_tos(),
- fsp->fsp_name, NULL,
- &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- return -1;
- }
-
- if (SMB_VFS_FSTAT(fsp, &smb_fname->st) == 0) {
+ if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) == 0) {
int dosmode;
trigger_write_time_update(fsp);
- dosmode = dos_mode(fsp->conn, smb_fname);
+ dosmode = dos_mode(fsp->conn, fsp->fsp_name);
if ((lp_store_dos_attributes(SNUM(fsp->conn)) ||
MAP_ARCHIVE(fsp->conn)) &&
!IS_DOS_ARCHIVE(dosmode)) {
- file_set_dosmode(fsp->conn, smb_fname,
- dosmode | aARCH, NULL, false);
+ file_set_dosmode(fsp->conn, fsp->fsp_name,
+ dosmode | aARCH, NULL, false);
}
/*
@@ -315,11 +307,10 @@ ssize_t write_file(struct smb_request *req,
if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !wcp) {
setup_write_cache(fsp,
- smb_fname->st.st_ex_size);
+ fsp->fsp_name->st.st_ex_size);
wcp = fsp->wcp;
}
}
- TALLOC_FREE(smb_fname);
}
#ifdef WITH_PROFILE
@@ -381,8 +372,10 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",
return total_written;
}
- DEBUG(9,("write_file (%s)(fd=%d pos=%.0f size=%u) wcp->offset=%.0f wcp->data_size=%u\n",
- fsp->fsp_name, fsp->fh->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size));
+ DEBUG(9,("write_file (%s)(fd=%d pos=%.0f size=%u) wcp->offset=%.0f "
+ "wcp->data_size=%u\n", fsp_str_dbg(fsp), fsp->fh->fd,
+ (double)pos, (unsigned int)n, (double)wcp->offset,
+ (unsigned int)wcp->data_size));
fsp->fh->pos = pos + n;
@@ -827,7 +820,8 @@ void delete_write_cache(files_struct *fsp)
SAFE_FREE(wcp->data);
SAFE_FREE(fsp->wcp);
- DEBUG(10,("delete_write_cache: File %s deleted write cache\n", fsp->fsp_name ));
+ DEBUG(10,("delete_write_cache: File %s deleted write cache\n",
+ fsp_str_dbg(fsp)));
}
/****************************************************************************
@@ -870,7 +864,7 @@ static bool setup_write_cache(files_struct *fsp, SMB_OFF_T file_size)
allocated_write_caches++;
DEBUG(10,("setup_write_cache: File %s allocated write cache size %lu\n",
- fsp->fsp_name, (unsigned long)wcp->alloc_size ));
+ fsp_str_dbg(fsp), (unsigned long)wcp->alloc_size));
return True;
}
@@ -887,7 +881,7 @@ void set_filelen_write_cache(files_struct *fsp, SMB_OFF_T file_size)
char *msg;
if (asprintf(&msg, "set_filelen_write_cache: size change "
"on file %s with write cache size = %lu\n",
- fsp->fsp_name,
+ fsp->fsp_name->base_name,
(unsigned long)fsp->wcp->data_size) != -1) {
smb_panic(msg);
} else {
@@ -969,7 +963,13 @@ NTSTATUS sync_file(connection_struct *conn, files_struct *fsp, bool write_throug
int fsp_stat(files_struct *fsp, SMB_STRUCT_STAT *pst)
{
if (fsp->fh->fd == -1) {
- return vfs_stat_smb_fname(fsp->conn, fsp->fsp_name, pst);
+ int ret;
+
+ ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
+ if (ret != -1) {
+ *pst = fsp->fsp_name->st;
+ }
+ return ret;
} else {
return SMB_VFS_FSTAT(fsp, pst);
}
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 29ebc37d1a..09f9a418bd 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -80,201 +80,6 @@ static NTSTATUS determine_path_error(const char *name,
}
}
-/**
- * XXX: This is temporary and there should be no callers of this outside of
- * this file once smb_filename is plumbed through all path based operations.
- * The one legitimate caller currently is smb_fname_str_dbg(), which this
- * could be made static for.
- */
-NTSTATUS get_full_smb_filename(TALLOC_CTX *ctx, const struct smb_filename *smb_fname,
- char **full_name)
-{
- if (smb_fname->stream_name) {
- *full_name = talloc_asprintf(ctx, "%s%s", smb_fname->base_name,
- smb_fname->stream_name);
- } else {
- *full_name = talloc_strdup(ctx, smb_fname->base_name);
- }
-
- if (!*full_name) {
- return NT_STATUS_NO_MEMORY;
- }
-
- return NT_STATUS_OK;
-}
-
-/**
- * There are actually legitimate callers of this such as functions that
- * enumerate streams using the SMB_VFS_STREAMINFO interface and then want to
- * operate on each stream.
- */
-NTSTATUS create_synthetic_smb_fname(TALLOC_CTX *ctx, const char *base_name,
- const char *stream_name,
- const SMB_STRUCT_STAT *psbuf,
- struct smb_filename **smb_fname_out)
-{
- struct smb_filename smb_fname_loc;
-
- ZERO_STRUCT(smb_fname_loc);
-
- /* Setup the base_name/stream_name. */
- smb_fname_loc.base_name = CONST_DISCARD(char *, base_name);
- smb_fname_loc.stream_name = CONST_DISCARD(char *, stream_name);
-
- /* Copy the psbuf if one was given. */
- if (psbuf)
- smb_fname_loc.st = *psbuf;
-
- /* Let copy_smb_filename() do the heavy lifting. */
- return copy_smb_filename(ctx, &smb_fname_loc, smb_fname_out);
-}
-
-/**
- * XXX: This is temporary and there should be no callers of this once
- * smb_filename is plumbed through all path based operations.
- */
-NTSTATUS create_synthetic_smb_fname_split(TALLOC_CTX *ctx,
- const char *fname,
- const SMB_STRUCT_STAT *psbuf,
- struct smb_filename **smb_fname_out)
-{
- NTSTATUS status;
- const char *stream_name = NULL;
- char *base_name = NULL;
-
- if (!lp_posix_pathnames()) {
- stream_name = strchr_m(fname, ':');
- }
-
- /* Setup the base_name/stream_name. */
- if (stream_name) {
- base_name = talloc_strndup(ctx, fname,
- PTR_DIFF(stream_name, fname));
- } else {
- base_name = talloc_strdup(ctx, fname);
- }
-
- if (!base_name) {
- return NT_STATUS_NO_MEMORY;
- }
-
- status = create_synthetic_smb_fname(ctx, base_name, stream_name, psbuf,
- smb_fname_out);
- TALLOC_FREE(base_name);
- return status;
-}
-
-/**
- * XXX: This is temporary and there should be no callers of this once
- * smb_filename is plumbed through all path based operations.
- */
-int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
- SMB_STRUCT_STAT *psbuf)
-{
- struct smb_filename *smb_fname = NULL;
- NTSTATUS status;
- int ret;
-
- status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
- &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- return -1;
- }
-
- ret = SMB_VFS_STAT(conn, smb_fname);
- if (ret != -1) {
- *psbuf = smb_fname->st;
- }
-
- TALLOC_FREE(smb_fname);
- return ret;
-}
-
-/**
- * XXX: This is temporary and there should be no callers of this once
- * smb_filename is plumbed through all path based operations.
- */
-int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
- SMB_STRUCT_STAT *psbuf)
-{
- struct smb_filename *smb_fname = NULL;
- NTSTATUS status;
- int ret;
-
- status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
- &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- return -1;
- }
-
- ret = SMB_VFS_LSTAT(conn, smb_fname);
- if (ret != -1) {
- *psbuf = smb_fname->st;
- }
-
- TALLOC_FREE(smb_fname);
- return ret;
-}
-
-/**
- * Return a string using the debug_ctx()
- */
-const char *smb_fname_str_dbg(const struct smb_filename *smb_fname)
-{
- char *fname = NULL;
- NTSTATUS status;
-
- if (smb_fname == NULL) {
- return "";
- }
- status = get_full_smb_filename(debug_ctx(), smb_fname, &fname);
- if (!NT_STATUS_IS_OK(status)) {
- return "";
- }
- return fname;
-}
-
-NTSTATUS copy_smb_filename(TALLOC_CTX *ctx,
- const struct smb_filename *smb_fname_in,
- struct smb_filename **smb_fname_out)
-{
-
- *smb_fname_out = talloc_zero(ctx, struct smb_filename);
- if (*smb_fname_out == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
-
- if (smb_fname_in->base_name) {
- (*smb_fname_out)->base_name =
- talloc_strdup(*smb_fname_out, smb_fname_in->base_name);
- if (!(*smb_fname_out)->base_name)
- goto no_mem_err;
- }
-
- if (smb_fname_in->stream_name) {
- (*smb_fname_out)->stream_name =
- talloc_strdup(*smb_fname_out, smb_fname_in->stream_name);
- if (!(*smb_fname_out)->stream_name)
- goto no_mem_err;
- }
-
- if (smb_fname_in->original_lcomp) {
- (*smb_fname_out)->original_lcomp =
- talloc_strdup(*smb_fname_out, smb_fname_in->original_lcomp);
- if (!(*smb_fname_out)->original_lcomp)
- goto no_mem_err;
- }
-
- (*smb_fname_out)->st = smb_fname_in->st;
- return NT_STATUS_OK;
-
- no_mem_err:
- TALLOC_FREE(*smb_fname_out);
- return NT_STATUS_NO_MEMORY;
-}
-
/****************************************************************************
This routine is called to convert names from the dos namespace to unix
namespace. It needs to handle any case conversions, mangling, format changes,
@@ -312,23 +117,21 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
struct smb_filename **smb_fname_out,
uint32_t ucf_flags)
{
- SMB_STRUCT_STAT st;
struct smb_filename *smb_fname = NULL;
char *start, *end;
char *dirpath = NULL;
- char *name = NULL;
char *stream = NULL;
bool component_was_mangled = False;
bool name_has_wildcard = False;
bool posix_pathnames = false;
bool allow_wcard_last_component = ucf_flags & UCF_ALLOW_WCARD_LCOMP;
bool save_last_component = ucf_flags & UCF_SAVE_LCOMP;
- NTSTATUS result;
+ NTSTATUS status;
int ret = -1;
*smb_fname_out = NULL;
- smb_fname = talloc_zero(talloc_tos(), struct smb_filename);
+ smb_fname = talloc_zero(ctx, struct smb_filename);
if (smb_fname == NULL) {
return NT_STATUS_NO_MEMORY;
}
@@ -338,10 +141,10 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
filename - so don't convert them */
if (!(smb_fname->base_name = talloc_strdup(smb_fname,
orig_path))) {
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
- *smb_fname_out = smb_fname;
- return NT_STATUS_OK;
+ goto done;
}
DEBUG(5, ("unix_convert called on file \"%s\"\n", orig_path));
@@ -369,15 +172,16 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
*/
if (!*orig_path) {
- if (!(name = talloc_strdup(ctx,"."))) {
- return NT_STATUS_NO_MEMORY;
+ if (!(smb_fname->base_name = talloc_strdup(smb_fname, "."))) {
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
- if (vfs_stat_smb_fname(conn,name,&st) == 0) {
- smb_fname->st = st;
- } else {
- return map_nt_error_from_unix(errno);
+ if (SMB_VFS_STAT(conn, smb_fname) != 0) {
+ status = map_nt_error_from_unix(errno);
+ goto err;
}
- DEBUG(5,("conversion finished \"\" -> %s\n",name));
+ DEBUG(5, ("conversion finished \"\" -> %s\n",
+ smb_fname->base_name));
goto done;
}
@@ -385,17 +189,19 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
orig_path[1] == '\0')) {
/* Start of pathname can't be "." only. */
if (orig_path[1] == '\0' || orig_path[2] == '\0') {
- result = NT_STATUS_OBJECT_NAME_INVALID;
+ status = NT_STATUS_OBJECT_NAME_INVALID;
} else {
- result =determine_path_error(
- &orig_path[2], allow_wcard_last_component);
+ status =determine_path_error(&orig_path[2],
+ allow_wcard_last_component);
}
- return result;
+ goto err;
}
- if (!(name = talloc_strdup(ctx, orig_path))) {
+ /* Start with the full orig_path as given by the caller. */
+ if (!(smb_fname->base_name = talloc_strdup(smb_fname, orig_path))) {
DEBUG(0, ("talloc_strdup failed\n"));
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
/*
@@ -409,7 +215,7 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
if (conn->case_sensitive && !conn->case_preserve &&
!conn->short_case_preserve) {
- strnorm(name, lp_defaultcase(SNUM(conn)));
+ strnorm(smb_fname->base_name, lp_defaultcase(SNUM(conn)));
}
/*
@@ -417,44 +223,60 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
*/
if(save_last_component) {
- end = strrchr_m(name, '/');
+ end = strrchr_m(smb_fname->base_name, '/');
if (end) {
- smb_fname->original_lcomp = talloc_strdup(ctx,
+ smb_fname->original_lcomp = talloc_strdup(smb_fname,
end + 1);
} else {
- smb_fname->original_lcomp = talloc_strdup(ctx, name);
+ smb_fname->original_lcomp =
+ talloc_strdup(smb_fname, smb_fname->base_name);
+ }
+ if (smb_fname->original_lcomp == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
}
posix_pathnames = lp_posix_pathnames();
- /* Strip off the stream. Should we use any of the other stream parsing
- * at this point? Also, should we set the is_stream bit? */
+ /*
+ * Strip off the stream, and add it back when we're done with the
+ * base_name.
+ */
if (!posix_pathnames) {
- stream = strchr_m(name, ':');
+ stream = strchr_m(smb_fname->base_name, ':');
if (stream != NULL) {
- char *tmp = talloc_strdup(ctx, stream);
+ char *tmp = talloc_strdup(smb_fname, stream);
if (tmp == NULL) {
- TALLOC_FREE(name);
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
+ /*
+ * Since this is actually pointing into
+ * smb_fname->base_name this truncates base_name.
+ */
*stream = '\0';
stream = tmp;
}
}
- start = name;
+ start = smb_fname->base_name;
- /* If we're providing case insentive semantics or
+ /*
+ * If we're providing case insentive semantics or
* the underlying filesystem is case insensitive,
* then a case-normalized hit in the stat-cache is
* authoratitive. JRA.
+ *
+ * Note: We're only checking base_name. The stream_name will be
+ * added and verified in build_stream_path().
*/
- if((!conn->case_sensitive || !(conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) &&
- stat_cache_lookup(conn, &name, &dirpath, &start, &st)) {
- smb_fname->st = st;
+ if((!conn->case_sensitive || !(conn->fs_capabilities &
+ FILE_CASE_SENSITIVE_SEARCH)) &&
+ stat_cache_lookup(conn, &smb_fname->base_name, &dirpath, &start,
+ &smb_fname->st)) {
goto done;
}
@@ -465,43 +287,46 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
if ((dirpath == NULL) && (!(dirpath = talloc_strdup(ctx,"")))) {
DEBUG(0, ("talloc_strdup failed\n"));
- TALLOC_FREE(name);
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
/*
- * stat the name - if it exists then we are all done!
+ * stat the name - if it exists then we can add the stream back (if
+ * there was one) and be done!
*/
if (posix_pathnames) {
- ret = vfs_lstat_smb_fname(conn,name,&st);
+ ret = SMB_VFS_LSTAT(conn, smb_fname);
} else {
- ret = vfs_stat_smb_fname(conn,name,&st);
+ ret = SMB_VFS_STAT(conn, smb_fname);
}
if (ret == 0) {
/* Ensure we catch all names with in "/."
this is disallowed under Windows. */
- const char *p = strstr(name, "/."); /* mb safe. */
+ const char *p = strstr(smb_fname->base_name, "/."); /*mb safe*/
if (p) {
if (p[2] == '/') {
/* Error code within a pathname. */
- result = NT_STATUS_OBJECT_PATH_NOT_FOUND;
+ status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
goto fail;
} else if (p[2] == '\0') {
/* Error code at the end of a pathname. */
- result = NT_STATUS_OBJECT_NAME_INVALID;
+ status = NT_STATUS_OBJECT_NAME_INVALID;
goto fail;
}
}
- stat_cache_add(orig_path, name, conn->case_sensitive);
- DEBUG(5,("conversion finished %s -> %s\n",orig_path, name));
- smb_fname->st = st;
+ /* Add the path (not including the stream) to the cache. */
+ stat_cache_add(orig_path, smb_fname->base_name,
+ conn->case_sensitive);
+ DEBUG(5,("conversion of base_name finished %s -> %s\n",
+ orig_path, smb_fname->base_name));
goto done;
}
DEBUG(5,("unix_convert begin: name = %s, dirpath = %s, start = %s\n",
- name, dirpath, start));
+ smb_fname->base_name, dirpath, start));
/*
* A special case - if we don't have any mangling chars and are case
@@ -509,8 +334,9 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
* won't help.
*/
- if ((conn->case_sensitive || !(conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) &&
- !mangle_is_mangled(name, conn->params)) {
+ if ((conn->case_sensitive || !(conn->fs_capabilities &
+ FILE_CASE_SENSITIVE_SEARCH)) &&
+ !mangle_is_mangled(smb_fname->base_name, conn->params)) {
goto done;
}
@@ -549,11 +375,12 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
if (save_last_component) {
TALLOC_FREE(smb_fname->original_lcomp);
- smb_fname->original_lcomp = talloc_strdup(ctx,
+ smb_fname->original_lcomp = talloc_strdup(smb_fname,
end ? end + 1 : start);
if (!smb_fname->original_lcomp) {
DEBUG(0, ("talloc failed\n"));
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
}
@@ -562,9 +389,9 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
if (ISDOT(start)) {
if (!end) {
/* Error code at the end of a pathname. */
- result = NT_STATUS_OBJECT_NAME_INVALID;
+ status = NT_STATUS_OBJECT_NAME_INVALID;
} else {
- result = determine_path_error(end+1,
+ status = determine_path_error(end+1,
allow_wcard_last_component);
}
goto fail;
@@ -577,13 +404,13 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
/* Wildcard not valid anywhere. */
if (name_has_wildcard && !allow_wcard_last_component) {
- result = NT_STATUS_OBJECT_NAME_INVALID;
+ status = NT_STATUS_OBJECT_NAME_INVALID;
goto fail;
}
/* Wildcards never valid within a pathname. */
if (name_has_wildcard && end) {
- result = NT_STATUS_OBJECT_NAME_INVALID;
+ status = NT_STATUS_OBJECT_NAME_INVALID;
goto fail;
}
@@ -592,9 +419,9 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
*/
if (posix_pathnames) {
- ret = vfs_lstat_smb_fname(conn,name, &st);
+ ret = SMB_VFS_LSTAT(conn, smb_fname);
} else {
- ret = vfs_stat_smb_fname(conn,name, &st);
+ ret = SMB_VFS_STAT(conn, smb_fname);
}
if (ret == 0) {
@@ -602,7 +429,7 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
* It exists. it must either be a directory or this must
* be the last part of the path for it to be OK.
*/
- if (end && !S_ISDIR(st.st_ex_mode)) {
+ if (end && !S_ISDIR(smb_fname->st.st_ex_mode)) {
/*
* An intermediate part of the name isn't
* a directory.
@@ -617,25 +444,15 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
* applications depend on the difference between
* these two errors.
*/
- result = NT_STATUS_OBJECT_PATH_NOT_FOUND;
+ status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
goto fail;
}
- if (!end) {
- /*
- * We just scanned for, and found the end of
- * the path. We must return the valid stat
- * struct. JRA.
- */
-
- smb_fname->st = st;
- }
-
} else {
char *found_name = NULL;
/* Stat failed - ensure we don't use it. */
- SET_STAT_INVALID(st);
+ SET_STAT_INVALID(smb_fname->st);
/*
* Reset errno so we can detect
@@ -681,11 +498,11 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
if (errno == ENOENT ||
errno == ENOTDIR ||
errno == ELOOP) {
- result =
+ status =
NT_STATUS_OBJECT_PATH_NOT_FOUND;
}
else {
- result =
+ status =
map_nt_error_from_unix(errno);
}
goto fail;
@@ -706,10 +523,10 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
*/
if (errno == ENOTDIR ||
errno == ELOOP) {
- result =
+ status =
NT_STATUS_OBJECT_PATH_NOT_FOUND;
} else {
- result =
+ status =
map_nt_error_from_unix(errno);
}
goto fail;
@@ -741,12 +558,13 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
&unmangled,
conn->params)) {
char *tmp;
- size_t start_ofs = start - name;
+ size_t start_ofs =
+ start - smb_fname->base_name;
if (*dirpath != '\0') {
- tmp = talloc_asprintf(ctx,
- "%s/%s", dirpath,
- unmangled);
+ tmp = talloc_asprintf(
+ smb_fname, "%s/%s",
+ dirpath, unmangled);
TALLOC_FREE(unmangled);
}
else {
@@ -754,11 +572,13 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
}
if (tmp == NULL) {
DEBUG(0, ("talloc failed\n"));
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
- TALLOC_FREE(name);
- name = tmp;
- start = name + start_ofs;
+ TALLOC_FREE(smb_fname->base_name);
+ smb_fname->base_name = tmp;
+ start =
+ smb_fname->base_name + start_ofs;
end = start + strlen(start);
}
@@ -773,46 +593,50 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
*/
if (end) {
char *tmp;
- size_t start_ofs = start - name;
+ size_t start_ofs =
+ start - smb_fname->base_name;
if (*dirpath != '\0') {
- tmp = talloc_asprintf(ctx,
+ tmp = talloc_asprintf(smb_fname,
"%s/%s/%s", dirpath,
found_name, end+1);
}
else {
- tmp = talloc_asprintf(ctx,
+ tmp = talloc_asprintf(smb_fname,
"%s/%s", found_name,
end+1);
}
if (tmp == NULL) {
DEBUG(0, ("talloc_asprintf failed\n"));
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
- TALLOC_FREE(name);
- name = tmp;
- start = name + start_ofs;
+ TALLOC_FREE(smb_fname->base_name);
+ smb_fname->base_name = tmp;
+ start = smb_fname->base_name + start_ofs;
end = start + strlen(found_name);
*end = '\0';
} else {
char *tmp;
- size_t start_ofs = start - name;
+ size_t start_ofs =
+ start - smb_fname->base_name;
if (*dirpath != '\0') {
- tmp = talloc_asprintf(ctx,
+ tmp = talloc_asprintf(smb_fname,
"%s/%s", dirpath,
found_name);
} else {
- tmp = talloc_strdup(ctx,
+ tmp = talloc_strdup(smb_fname,
found_name);
}
if (tmp == NULL) {
DEBUG(0, ("talloc failed\n"));
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
- TALLOC_FREE(name);
- name = tmp;
- start = name + start_ofs;
+ TALLOC_FREE(smb_fname->base_name);
+ smb_fname->base_name = tmp;
+ start = smb_fname->base_name + start_ofs;
/*
* We just scanned for, and found the end of
@@ -821,17 +645,13 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
*/
if (posix_pathnames) {
- ret = vfs_lstat_smb_fname(conn,name,
- &st);
+ ret = SMB_VFS_LSTAT(conn, smb_fname);
} else {
- ret = vfs_stat_smb_fname(conn,name,
- &st);
+ ret = SMB_VFS_STAT(conn, smb_fname);
}
- if (ret == 0) {
- smb_fname->st = st;
- } else {
- SET_STAT_INVALID(st);
+ if (ret != 0) {
+ SET_STAT_INVALID(smb_fname->st);
}
}
@@ -844,12 +664,13 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
* We should never provide different behaviors
* depending on DEVELOPER!!!
*/
- if (VALID_STAT(st)) {
+ if (VALID_STAT(smb_fname->st)) {
bool delete_pending;
- get_file_infos(vfs_file_id_from_sbuf(conn, &st),
+ get_file_infos(vfs_file_id_from_sbuf(conn,
+ &smb_fname->st),
&delete_pending, NULL);
if (delete_pending) {
- result = NT_STATUS_DELETE_PENDING;
+ status = NT_STATUS_DELETE_PENDING;
goto fail;
}
}
@@ -864,7 +685,8 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
"%s/%s", dirpath, start);
if (!tmp) {
DEBUG(0, ("talloc_asprintf failed\n"));
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
TALLOC_FREE(dirpath);
dirpath = tmp;
@@ -873,15 +695,15 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
TALLOC_FREE(dirpath);
if (!(dirpath = talloc_strdup(ctx,start))) {
DEBUG(0, ("talloc_strdup failed\n"));
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
}
/*
- * Don't cache a name with mangled or wildcard components
- * as this can change the size.
+ * Cache the dirpath thus far. Don't cache a name with mangled
+ * or wildcard components as this can change the size.
*/
-
if(!component_was_mangled && !name_has_wildcard) {
stat_cache_add(orig_path, dirpath,
conn->case_sensitive);
@@ -896,29 +718,30 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
}
/*
- * Don't cache a name with mangled or wildcard components
- * as this can change the size.
+ * Cache the full path. Don't cache a name with mangled or wildcard
+ * components as this can change the size.
*/
if(!component_was_mangled && !name_has_wildcard) {
- stat_cache_add(orig_path, name, conn->case_sensitive);
+ stat_cache_add(orig_path, smb_fname->base_name,
+ conn->case_sensitive);
}
/*
* The name has been resolved.
*/
- DEBUG(5,("conversion finished %s -> %s\n",orig_path, name));
+ DEBUG(5,("conversion finished %s -> %s\n", orig_path,
+ smb_fname->base_name));
done:
- smb_fname->base_name = name;
-
+ /* Add back the stream if one was stripped off originally. */
if (stream != NULL) {
smb_fname->stream_name = stream;
/* Check path now that the base_name has been converted. */
- result = build_stream_path(ctx, conn, orig_path, smb_fname);
- if (!NT_STATUS_IS_OK(result)) {
+ status = build_stream_path(ctx, conn, orig_path, smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
goto fail;
}
}
@@ -928,20 +751,23 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
fail:
DEBUG(10, ("dirpath = [%s] start = [%s]\n", dirpath, start));
if (*dirpath != '\0') {
- smb_fname->base_name = talloc_asprintf(ctx, "%s/%s", dirpath,
- start);
+ smb_fname->base_name = talloc_asprintf(smb_fname, "%s/%s",
+ dirpath, start);
} else {
- smb_fname->base_name = talloc_strdup(ctx, start);
+ smb_fname->base_name = talloc_strdup(smb_fname, start);
}
if (!smb_fname->base_name) {
DEBUG(0, ("talloc_asprintf failed\n"));
- return NT_STATUS_NO_MEMORY;
+ status = NT_STATUS_NO_MEMORY;
+ goto err;
}
*smb_fname_out = smb_fname;
- TALLOC_FREE(name);
TALLOC_FREE(dirpath);
- return result;
+ return status;
+ err:
+ TALLOC_FREE(smb_fname);
+ return status;
}
/****************************************************************************
@@ -1137,6 +963,7 @@ static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx,
struct stream_struct *streams = NULL;
if (SMB_VFS_STAT(conn, smb_fname) == 0) {
+ DEBUG(10, ("'%s' exists\n", smb_fname_str_dbg(smb_fname)));
return NT_STATUS_OK;
}
@@ -1183,21 +1010,16 @@ static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx,
TALLOC_FREE(smb_fname->stream_name);
- smb_fname->stream_name = talloc_strdup(mem_ctx, streams[i].name);
+ smb_fname->stream_name = talloc_strdup(smb_fname, streams[i].name);
+ if (smb_fname->stream_name == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
SET_STAT_INVALID(smb_fname->st);
if (SMB_VFS_STAT(conn, smb_fname) == 0) {
- char *result = NULL;
-
- status = get_full_smb_filename(mem_ctx, smb_fname, &result);
- if (!NT_STATUS_IS_OK(status)) {
- status = NT_STATUS_NO_MEMORY;
- goto fail;
- }
-
- stat_cache_add(orig_path, result, conn->case_sensitive);
- TALLOC_FREE(result);
+ DEBUG(10, ("'%s' exists\n", smb_fname_str_dbg(smb_fname)));
}
status = NT_STATUS_OK;
fail:
@@ -1213,8 +1035,7 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx,
connection_struct *conn,
bool dfs_path,
const char *name_in,
- struct smb_filename **pp_smb_fname,
- char **pp_name)
+ struct smb_filename **pp_smb_fname)
{
NTSTATUS status;
char *fname = NULL;
@@ -1241,22 +1062,15 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx,
return status;
}
- status = get_full_smb_filename(ctx, *pp_smb_fname, &fname);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- status = check_name(conn, fname);
+ status = check_name(conn, (*pp_smb_fname)->base_name);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3,("filename_convert: check_name failed "
"for name %s with %s\n",
- fname,
+ smb_fname_str_dbg(*pp_smb_fname),
nt_errstr(status) ));
+ TALLOC_FREE(*pp_smb_fname);
return status;
}
- if (pp_name != NULL) {
- *pp_name = fname;
- }
return status;
}
diff --git a/source3/smbd/filename_util.c b/source3/smbd/filename_util.c
new file mode 100644
index 0000000000..867709a373
--- /dev/null
+++ b/source3/smbd/filename_util.c
@@ -0,0 +1,206 @@
+/*
+ Unix SMB/CIFS implementation.
+ Filename utility functions.
+ Copyright (C) Tim Prouty 2009
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "includes.h"
+
+/**
+ * XXX: This is temporary and there should be no callers of this outside of
+ * this file once smb_filename is plumbed through all path based operations.
+ * The one legitimate caller currently is smb_fname_str_dbg(), which this
+ * could be made static for.
+ */
+NTSTATUS get_full_smb_filename(TALLOC_CTX *ctx,
+ const struct smb_filename *smb_fname,
+ char **full_name)
+{
+ if (smb_fname->stream_name) {
+ /* stream_name must always be NULL if there is no stream. */
+ SMB_ASSERT(smb_fname->stream_name[0] != '\0');
+
+ *full_name = talloc_asprintf(ctx, "%s%s", smb_fname->base_name,
+ smb_fname->stream_name);
+ } else {
+ *full_name = talloc_strdup(ctx, smb_fname->base_name);
+ }
+
+ if (!*full_name) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ return NT_STATUS_OK;
+}
+
+/**
+ * There are actually legitimate callers of this such as functions that
+ * enumerate streams using the SMB_VFS_STREAMINFO interface and then want to
+ * operate on each stream.
+ */
+NTSTATUS create_synthetic_smb_fname(TALLOC_CTX *ctx, const char *base_name,
+ const char *stream_name,
+ const SMB_STRUCT_STAT *psbuf,
+ struct smb_filename **smb_fname_out)
+{
+ struct smb_filename smb_fname_loc;
+
+ ZERO_STRUCT(smb_fname_loc);
+
+ /* Setup the base_name/stream_name. */
+ smb_fname_loc.base_name = CONST_DISCARD(char *, base_name);
+ smb_fname_loc.stream_name = CONST_DISCARD(char *, stream_name);
+
+ /* Copy the psbuf if one was given. */
+ if (psbuf)
+ smb_fname_loc.st = *psbuf;
+
+ /* Let copy_smb_filename() do the heavy lifting. */
+ return copy_smb_filename(ctx, &smb_fname_loc, smb_fname_out);
+}
+
+/**
+ * XXX: This is temporary and there should be no callers of this once
+ * smb_filename is plumbed through all path based operations.
+ */
+NTSTATUS create_synthetic_smb_fname_split(TALLOC_CTX *ctx,
+ const char *fname,
+ const SMB_STRUCT_STAT *psbuf,
+ struct smb_filename **smb_fname_out)
+{
+ NTSTATUS status;
+ const char *stream_name = NULL;
+ char *base_name = NULL;
+
+ if (!lp_posix_pathnames()) {
+ stream_name = strchr_m(fname, ':');
+ }
+
+ /* Setup the base_name/stream_name. */
+ if (stream_name) {
+ base_name = talloc_strndup(ctx, fname,
+ PTR_DIFF(stream_name, fname));
+ } else {
+ base_name = talloc_strdup(ctx, fname);
+ }
+
+ if (!base_name) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = create_synthetic_smb_fname(ctx, base_name, stream_name, psbuf,
+ smb_fname_out);
+ TALLOC_FREE(base_name);
+ return status;
+}
+
+/**
+ * Return a string using the debug_ctx()
+ */
+const char *smb_fname_str_dbg(const struct smb_filename *smb_fname)
+{
+ char *fname = NULL;
+ NTSTATUS status;
+
+ if (smb_fname == NULL) {
+ return "";
+ }
+ status = get_full_smb_filename(debug_ctx(), smb_fname, &fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return "";
+ }
+ return fname;
+}
+
+/**
+ * Return a debug string using the debug_ctx(). This can only be called from
+ * DEBUG() macros due to the debut_ctx().
+ */
+const char *fsp_str_dbg(const struct files_struct *fsp)
+{
+ return smb_fname_str_dbg(fsp->fsp_name);
+}
+
+NTSTATUS copy_smb_filename(TALLOC_CTX *ctx,
+ const struct smb_filename *smb_fname_in,
+ struct smb_filename **smb_fname_out)
+{
+ /* stream_name must always be NULL if there is no stream. */
+ if (smb_fname_in->stream_name) {
+ SMB_ASSERT(smb_fname_in->stream_name[0] != '\0');
+ }
+
+ *smb_fname_out = talloc_zero(ctx, struct smb_filename);
+ if (*smb_fname_out == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (smb_fname_in->base_name) {
+ (*smb_fname_out)->base_name =
+ talloc_strdup(*smb_fname_out, smb_fname_in->base_name);
+ if (!(*smb_fname_out)->base_name)
+ goto no_mem_err;
+ }
+
+ if (smb_fname_in->stream_name) {
+ (*smb_fname_out)->stream_name =
+ talloc_strdup(*smb_fname_out, smb_fname_in->stream_name);
+ if (!(*smb_fname_out)->stream_name)
+ goto no_mem_err;
+ }
+
+ if (smb_fname_in->original_lcomp) {
+ (*smb_fname_out)->original_lcomp =
+ talloc_strdup(*smb_fname_out, smb_fname_in->original_lcomp);
+ if (!(*smb_fname_out)->original_lcomp)
+ goto no_mem_err;
+ }
+
+ (*smb_fname_out)->st = smb_fname_in->st;
+ return NT_STATUS_OK;
+
+ no_mem_err:
+ TALLOC_FREE(*smb_fname_out);
+ return NT_STATUS_NO_MEMORY;
+}
+
+/****************************************************************************
+ Simple check to determine if the filename is a stream.
+ ***************************************************************************/
+bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname)
+{
+ /* stream_name must always be NULL if there is no stream. */
+ if (smb_fname->stream_name) {
+ SMB_ASSERT(smb_fname->stream_name[0] != '\0');
+ }
+
+ if (lp_posix_pathnames()) {
+ return false;
+ }
+
+ return smb_fname->stream_name;
+}
+
+/****************************************************************************
+ Returns true if the filename's stream == "::$DATA"
+ ***************************************************************************/
+bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname)
+{
+ if (!is_ntfs_stream_smb_fname(smb_fname)) {
+ return false;
+ }
+
+ return StrCaseCmp(smb_fname->stream_name, "::$DATA") == 0;
+}
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index 0e6dd7e457..a170f774fe 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -44,6 +44,7 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn,
{
int i;
files_struct *fsp;
+ NTSTATUS status;
/* we want to give out file handles differently on each new
connection because of a common bug in MS clients where they try to
@@ -65,21 +66,26 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn,
return NT_STATUS_TOO_MANY_OPENED_FILES;
}
- fsp = SMB_MALLOC_P(files_struct);
+ /*
+ * Make a child of the connection_struct as an fsp can't exist
+ * indepenedent of a connection.
+ */
+ fsp = talloc_zero(conn, struct files_struct);
if (!fsp) {
return NT_STATUS_NO_MEMORY;
}
- ZERO_STRUCTP(fsp);
-
- fsp->fh = SMB_MALLOC_P(struct fd_handle);
+ /*
+ * This can't be a child of fsp because the file_handle can be ref'd
+ * when doing a dos/fcb open, which will then share the file_handle
+ * across multiple fsps.
+ */
+ fsp->fh = talloc_zero(conn, struct fd_handle);
if (!fsp->fh) {
- SAFE_FREE(fsp);
+ TALLOC_FREE(fsp);
return NT_STATUS_NO_MEMORY;
}
- ZERO_STRUCTP(fsp->fh);
-
fsp->fh->ref_count = 1;
fsp->fh->fd = -1;
@@ -95,8 +101,18 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn,
fsp->fnum = i + FILE_HANDLE_OFFSET;
SMB_ASSERT(fsp->fnum < 65536);
- string_set(&fsp->fsp_name,"");
-
+ /*
+ * Create an smb_filename with "" for the base_name. There are very
+ * few NULL checks, so make sure it's initialized with something. to
+ * be safe until an audit can be done.
+ */
+ status = create_synthetic_smb_fname(fsp, "", NULL, NULL,
+ &fsp->fsp_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(fsp);
+ TALLOC_FREE(fsp->fh);
+ }
+
DLIST_ADD(Files, fsp);
DEBUG(5,("allocated file structure %d, fnum = %d (%d used)\n",
@@ -236,8 +252,9 @@ void file_dump_open_table(void)
files_struct *fsp;
for (fsp=Files;fsp;fsp=fsp->next,count++) {
- DEBUG(10,("Files[%d], fnum = %d, name %s, fd = %d, gen = %lu, fileid=%s\n",
- count, fsp->fnum, fsp->fsp_name, fsp->fh->fd, (unsigned long)fsp->fh->gen_id,
+ DEBUG(10,("Files[%d], fnum = %d, name %s, fd = %d, gen = %lu, "
+ "fileid=%s\n", count, fsp->fnum, fsp_str_dbg(fsp),
+ fsp->fh->fd, (unsigned long)fsp->fh->gen_id,
file_id_string_tos(&fsp->file_id)));
}
}
@@ -283,8 +300,10 @@ files_struct *file_find_dif(struct file_id id, unsigned long gen_id)
if ((fsp->fh->fd == -1) &&
(fsp->oplock_type != NO_OPLOCK) &&
(fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
- DEBUG(0,("file_find_dif: file %s file_id = %s, gen = %u \
-oplock_type = %u is a stat open with oplock type !\n", fsp->fsp_name,
+ DEBUG(0,("file_find_dif: file %s file_id = "
+ "%s, gen = %u oplock_type = %u is a "
+ "stat open with oplock type !\n",
+ fsp_str_dbg(fsp),
file_id_string_tos(&fsp->file_id),
(unsigned int)fsp->fh->gen_id,
(unsigned int)fsp->oplock_type ));
@@ -385,10 +404,11 @@ bool file_find_subpath(files_struct *dir_fsp)
{
files_struct *fsp;
size_t dlen;
- char *d_fullname = talloc_asprintf(talloc_tos(),
- "%s/%s",
- dir_fsp->conn->connectpath,
- dir_fsp->fsp_name);
+ char *d_fullname;
+
+ d_fullname = talloc_asprintf(talloc_tos(), "%s/%s",
+ dir_fsp->conn->connectpath,
+ dir_fsp->fsp_name->base_name);
if (!d_fullname) {
return false;
@@ -406,7 +426,7 @@ bool file_find_subpath(files_struct *dir_fsp)
d1_fullname = talloc_asprintf(talloc_tos(),
"%s/%s",
fsp->conn->connectpath,
- fsp->fsp_name);
+ fsp->fsp_name->base_name);
if (strnequal(d_fullname, d1_fullname, dlen)) {
TALLOC_FREE(d_fullname);
@@ -444,12 +464,10 @@ void file_free(struct smb_request *req, files_struct *fsp)
{
DLIST_REMOVE(Files, fsp);
- string_free(&fsp->fsp_name);
-
TALLOC_FREE(fsp->fake_file_handle);
if (fsp->fh->ref_count == 1) {
- SAFE_FREE(fsp->fh);
+ TALLOC_FREE(fsp->fh);
} else {
fsp->fh->ref_count--;
}
@@ -495,7 +513,8 @@ void file_free(struct smb_request *req, files_struct *fsp)
information */
ZERO_STRUCTP(fsp);
- SAFE_FREE(fsp);
+ /* fsp->fsp_name is a talloc child and is free'd automatically. */
+ TALLOC_FREE(fsp);
}
/****************************************************************************
@@ -541,11 +560,11 @@ files_struct *file_fsp(struct smb_request *req, uint16 fid)
Duplicate the file handle part for a DOS or FCB open.
****************************************************************************/
-void dup_file_fsp(struct smb_request *req, files_struct *from,
+NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *from,
uint32 access_mask, uint32 share_access,
uint32 create_options, files_struct *to)
{
- SAFE_FREE(to->fh);
+ TALLOC_FREE(to->fh);
to->fh = from->fh;
to->fh->ref_count++;
@@ -570,5 +589,25 @@ void dup_file_fsp(struct smb_request *req, files_struct *from,
to->modified = from->modified;
to->is_directory = from->is_directory;
to->aio_write_behind = from->aio_write_behind;
- string_set(&to->fsp_name,from->fsp_name);
+ return fsp_set_smb_fname(to, from->fsp_name);
+}
+
+/**
+ * The only way that the fsp->fsp_name field should ever be set.
+ */
+NTSTATUS fsp_set_smb_fname(struct files_struct *fsp,
+ const struct smb_filename *smb_fname_in)
+{
+ NTSTATUS status;
+ struct smb_filename *smb_fname_new;
+
+ status = copy_smb_filename(fsp, smb_fname_in, &smb_fname_new);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ TALLOC_FREE(fsp->fsp_name);
+ fsp->fsp_name = smb_fname_new;
+
+ return NT_STATUS_OK;
}
diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c
index 15550ed455..317304a86d 100644
--- a/source3/smbd/globals.c
+++ b/source3/smbd/globals.c
@@ -153,4 +153,9 @@ void smbd_init_globals(void)
ZERO_STRUCT(conn_ctx_stack);
ZERO_STRUCT(sec_ctx_stack);
+
+ smbd_server_conn = talloc_zero(smbd_event_context(), struct smbd_server_connection);
+ if (!smbd_server_conn) {
+ exit_server("failed to create smbd_server_connection");
+ }
}
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 3d195c84f0..434204b60d 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -168,6 +168,56 @@ NTSTATUS smb2_signing_check_pdu(DATA_BLOB session_key,
const struct iovec *vector,
int count);
+struct smbd_lock_element {
+ uint32_t smbpid;
+ enum brl_type brltype;
+ uint64_t offset;
+ uint64_t count;
+};
+
+NTSTATUS smbd_do_locking(struct smb_request *req,
+ files_struct *fsp,
+ uint8_t type,
+ int32_t timeout,
+ uint16_t num_ulocks,
+ struct smbd_lock_element *ulocks,
+ uint16_t num_locks,
+ struct smbd_lock_element *locks,
+ bool *async);
+
+NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
+ TALLOC_CTX *mem_ctx,
+ uint16_t info_level,
+ files_struct *fsp,
+ const struct smb_filename *smb_fname,
+ bool delete_pending,
+ struct timespec write_time_ts,
+ bool ms_dfs_link,
+ struct ea_list *ea_list,
+ int lock_data_count,
+ char *lock_data,
+ uint16_t flags2,
+ unsigned int max_data_bytes,
+ char **ppdata,
+ unsigned int *pdata_size);
+
+NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
+ struct smb_request *req,
+ TALLOC_CTX *mem_ctx,
+ uint16_t info_level,
+ files_struct *fsp,
+ struct smb_filename *smb_fname,
+ char **ppdata, int total_data,
+ int *ret_data_size);
+
+NTSTATUS smbd_do_qfsinfo(connection_struct *conn,
+ TALLOC_CTX *mem_ctx,
+ uint16_t info_level,
+ uint16_t flags2,
+ unsigned int max_data_bytes,
+ char **ppdata,
+ int *ret_data_len);
+
void smbd_server_connection_terminate_ex(struct smbd_server_connection *sconn,
const char *reason,
const char *location);
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index 1067dab074..96a411dd70 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -454,7 +454,7 @@ static void api_fd_reply(connection_struct *conn, uint16 vuid,
}
DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)\n",
- subcommand, fsp->fsp_name, pnum));
+ subcommand, fsp_str_dbg(fsp), pnum));
DEBUG(10, ("api_fd_reply: p:%p max_trans_reply: %d\n", fsp, mdrcnt));
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index d40b8a8902..2b63eb1743 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -411,7 +411,6 @@ static bool is_msdfs_link_internal(TALLOC_CTX *ctx,
char **pp_link_target,
SMB_STRUCT_STAT *sbufp)
{
- SMB_STRUCT_STAT st;
int referral_len = 0;
#if defined(HAVE_BROKEN_READLINK)
char link_target_buf[PATH_MAX];
@@ -420,6 +419,8 @@ static bool is_msdfs_link_internal(TALLOC_CTX *ctx,
#endif
size_t bufsize = 0;
char *link_target = NULL;
+ struct smb_filename *smb_fname = NULL;
+ NTSTATUS status;
if (pp_link_target) {
bufsize = 1024;
@@ -433,21 +434,28 @@ static bool is_msdfs_link_internal(TALLOC_CTX *ctx,
link_target = link_target_buf;
}
- if (sbufp == NULL) {
- sbufp = &st;
+ status = create_synthetic_smb_fname(talloc_tos(), path, NULL, NULL,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto err;
}
- if (vfs_lstat_smb_fname(conn, path, sbufp) != 0) {
+ if (SMB_VFS_LSTAT(conn, smb_fname) != 0) {
DEBUG(5,("is_msdfs_link_read_target: %s does not exist.\n",
path));
+ TALLOC_FREE(smb_fname);
goto err;
}
-
- if (!S_ISLNK(sbufp->st_ex_mode)) {
+ if (!S_ISLNK(smb_fname->st.st_ex_mode)) {
DEBUG(5,("is_msdfs_link_read_target: %s is not a link.\n",
path));
+ TALLOC_FREE(smb_fname);
goto err;
}
+ if (sbufp != NULL) {
+ *sbufp = smb_fname->st;
+ }
+ TALLOC_FREE(smb_fname);
referral_len = SMB_VFS_READLINK(conn, path, link_target, bufsize - 1);
if (referral_len == -1) {
diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
index ded888c021..8f37923865 100644
--- a/source3/smbd/notify.c
+++ b/source3/smbd/notify.c
@@ -182,7 +182,7 @@ void change_notify_reply(connection_struct *conn,
static void notify_callback(void *private_data, const struct notify_event *e)
{
files_struct *fsp = (files_struct *)private_data;
- DEBUG(10, ("notify_callback called for %s\n", fsp->fsp_name));
+ DEBUG(10, ("notify_callback called for %s\n", fsp_str_dbg(fsp)));
notify_fsp(fsp, e->action, e->path);
}
@@ -200,8 +200,9 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32 filter,
return NT_STATUS_NO_MEMORY;
}
+ /* Do notify operations on the base_name. */
if (asprintf(&fullpath, "%s/%s", fsp->conn->connectpath,
- fsp->fsp_name) == -1) {
+ fsp->fsp_name->base_name) == -1) {
DEBUG(0, ("asprintf failed\n"));
TALLOC_FREE(fsp->notify);
return NT_STATUS_NO_MEMORY;
@@ -236,7 +237,7 @@ NTSTATUS change_notify_add_request(struct smb_request *req,
struct smbd_server_connection *sconn = smbd_server_conn;
DEBUG(10, ("change_notify_add_request: Adding request for %s: "
- "max_param = %d\n", fsp->fsp_name, (int)max_param));
+ "max_param = %d\n", fsp_str_dbg(fsp), (int)max_param));
if (!(request = talloc(NULL, struct notify_change_request))
|| !(map = talloc(request, struct notify_mid_map))) {
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index b65af26eca..43212dc800 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -272,30 +272,6 @@ void send_nt_replies(connection_struct *conn,
}
/****************************************************************************
- Simple check to determine if the filename is a stream.
- ***************************************************************************/
-bool is_ntfs_stream_smb_fname(const struct smb_filename *smb_fname)
-{
- if (lp_posix_pathnames()) {
- return false;
- }
-
- return smb_fname->stream_name;
-}
-
-/****************************************************************************
- Returns true if the filename's stream == "::$DATA"
- ***************************************************************************/
-bool is_ntfs_default_stream_smb_fname(const struct smb_filename *smb_fname)
-{
- if (!is_ntfs_stream_smb_fname(smb_fname)) {
- return false;
- }
-
- return StrCaseCmp(smb_fname->stream_name, "::$DATA") == 0;
-}
-
-/****************************************************************************
Reply to an NT create and X call on a pipe
****************************************************************************/
@@ -502,8 +478,7 @@ void reply_ntcreate_and_X(struct smb_request *req)
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -794,7 +769,7 @@ static NTSTATUS set_sd(files_struct *fsp, uint8 *data, uint32 sd_len,
security_acl_map_generic(psd->sacl, &file_generic_mapping);
if (DEBUGLEVEL >= 10) {
- DEBUG(10,("set_sd for file %s\n", fsp->fsp_name ));
+ DEBUG(10,("set_sd for file %s\n", fsp_str_dbg(fsp)));
NDR_PRINT_DEBUG(security_descriptor, psd);
}
@@ -992,8 +967,7 @@ static void call_nt_transact_create(connection_struct *conn,
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -1341,8 +1315,7 @@ void reply_ntrename(struct smb_request *req)
if (req->wct < 4) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- END_PROFILE(SMBntrename);
- return;
+ goto out;
}
attrs = SVAL(req->vwv+0, 0);
@@ -1353,14 +1326,12 @@ void reply_ntrename(struct smb_request *req)
&status, &src_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBntrename);
- return;
+ goto out;
}
if (ms_has_wild(oldname)) {
reply_nterror(req, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
- END_PROFILE(SMBntrename);
- return;
+ goto out;
}
p++;
@@ -1368,55 +1339,83 @@ void reply_ntrename(struct smb_request *req)
&status, &dest_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
- END_PROFILE(SMBntrename);
- return;
+ goto out;
}
- status = filename_convert(ctx, conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
- oldname,
- &smb_fname_old,
- &oldname);
- if (!NT_STATUS_IS_OK(status)) {
- if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
- reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
- ERRSRV, ERRbadpath);
- END_PROFILE(SMBntrename);
- return;
- }
- reply_nterror(req, status);
- END_PROFILE(SMBntrename);
- return;
+ /* The newname must begin with a ':' if the oldname contains a ':'. */
+ if (strchr_m(oldname, ':') && (newname[0] != ':')) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ goto out;
}
- status = filename_convert(ctx, conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
- newname,
- &smb_fname_new,
- &newname);
- if (!NT_STATUS_IS_OK(status)) {
- if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
- reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
- ERRSRV, ERRbadpath);
- END_PROFILE(SMBntrename);
- return;
+ /* rename_internals() calls unix_convert(), so don't call it here. */
+ if (rename_type != RENAME_FLAG_RENAME) {
+ status = filename_convert(ctx, conn,
+ req->flags2 & FLAGS2_DFS_PATHNAMES,
+ oldname,
+ &smb_fname_old);
+ if (!NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_EQUAL(status,
+ NT_STATUS_PATH_NOT_COVERED)) {
+ reply_botherror(req,
+ NT_STATUS_PATH_NOT_COVERED,
+ ERRSRV, ERRbadpath);
+ goto out;
+ }
+ reply_nterror(req, status);
+ goto out;
}
- reply_nterror(req, status);
- END_PROFILE(SMBntrename);
- return;
- }
- /* The new name must begin with a ':' if the old name is a stream. */
- if (is_ntfs_stream_smb_fname(smb_fname_old) && (newname[0] != ':')) {
- reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- END_PROFILE(SMBntrename);
- return;
- }
+ status = filename_convert(ctx, conn,
+ req->flags2 & FLAGS2_DFS_PATHNAMES,
+ newname,
+ &smb_fname_new);
+ if (!NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_EQUAL(status,
+ NT_STATUS_PATH_NOT_COVERED)) {
+ reply_botherror(req,
+ NT_STATUS_PATH_NOT_COVERED,
+ ERRSRV, ERRbadpath);
+ goto out;
+ }
+ reply_nterror(req, status);
+ goto out;
+ }
- DEBUG(3,("reply_ntrename : %s -> %s\n",oldname,newname));
+ DEBUG(3,("reply_ntrename: %s -> %s\n",
+ smb_fname_str_dbg(smb_fname_old),
+ smb_fname_str_dbg(smb_fname_new)));
+ }
switch(rename_type) {
case RENAME_FLAG_RENAME:
+ status = resolve_dfspath(ctx, conn,
+ (req->flags2 &
+ FLAGS2_DFS_PATHNAMES),
+ oldname, &oldname);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10,("resolve_dfspath failed for name %s "
+ "with %s\n", oldname,
+ nt_errstr(status)));
+ reply_nterror(req, status);
+ goto out;
+ }
+
+ status = resolve_dfspath(ctx, conn,
+ (req->flags2 &
+ FLAGS2_DFS_PATHNAMES),
+ newname, &newname);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10,("resolve_dfspath failed for name %s "
+ "with %s\n", newname,
+ nt_errstr(status)));
+ reply_nterror(req, status);
+ goto out;
+ }
+
+ DEBUG(3,("reply_ntrename: %s -> %s\n", oldname,
+ newname));
+
status = rename_internals(ctx, conn, req, oldname,
newname, attrs, False, src_has_wcard,
dest_has_wcard, DELETE_ACCESS);
@@ -1454,17 +1453,15 @@ void reply_ntrename(struct smb_request *req)
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(req->mid)) {
/* We have re-scheduled this call. */
- END_PROFILE(SMBntrename);
- return;
+ goto out;
}
reply_nterror(req, status);
- END_PROFILE(SMBntrename);
- return;
+ goto out;
}
reply_outbuf(req, 0, 0);
-
+ out:
END_PROFILE(SMBntrename);
return;
}
@@ -1523,7 +1520,7 @@ static void call_nt_transact_notify_change(connection_struct *conn,
DEBUG(3,("call_nt_transact_notify_change: notify change "
"called on %s, filter = %s, recursive = %d\n",
- fsp->fsp_name, filter_string, recursive));
+ fsp_str_dbg(fsp), filter_string, recursive));
TALLOC_FREE(filter_string);
}
@@ -1626,7 +1623,7 @@ static void call_nt_transact_rename(connection_struct *conn,
send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
DEBUG(3,("nt transact rename from = %s, to = %s ignored!\n",
- fsp->fsp_name, new_name));
+ fsp_str_dbg(fsp), new_name));
return;
}
@@ -1684,8 +1681,9 @@ static void call_nt_transact_query_security_desc(connection_struct *conn,
security_info_wanted = IVAL(params,4);
- DEBUG(3,("call_nt_transact_query_security_desc: file = %s, info_wanted = 0x%x\n", fsp->fsp_name,
- (unsigned int)security_info_wanted ));
+ DEBUG(3,("call_nt_transact_query_security_desc: file = %s, "
+ "info_wanted = 0x%x\n", fsp_str_dbg(fsp),
+ (unsigned int)security_info_wanted));
params = nttrans_realloc(ppparams, 4);
if(params == NULL) {
@@ -1722,7 +1720,8 @@ static void call_nt_transact_query_security_desc(connection_struct *conn,
DEBUG(3,("call_nt_transact_query_security_desc: sd_size = %lu.\n",(unsigned long)sd_size));
if (DEBUGLEVEL >= 10) {
- DEBUG(10,("call_nt_transact_query_security_desc for file %s\n", fsp->fsp_name));
+ DEBUG(10,("call_nt_transact_query_security_desc for file %s\n",
+ fsp_str_dbg(fsp)));
NDR_PRINT_DEBUG(security_descriptor, psd);
}
@@ -1796,8 +1795,8 @@ static void call_nt_transact_set_security_desc(connection_struct *conn,
security_info_sent = IVAL(params,4);
- DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", fsp->fsp_name,
- (unsigned int)security_info_sent ));
+ DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n",
+ fsp_str_dbg(fsp), (unsigned int)security_info_sent));
if (data_count == 0) {
reply_doserror(req, ERRDOS, ERRnoaccess);
@@ -2021,7 +2020,7 @@ static void call_nt_transact_ioctl(connection_struct *conn,
cur_pdata+=12;
DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
- shadow_data->num_volumes,fsp->fsp_name));
+ shadow_data->num_volumes, fsp_str_dbg(fsp)));
if (labels && shadow_data->labels) {
for (i=0;i<shadow_data->num_volumes;i++) {
srvstr_push(pdata, req->flags2,
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index e01350f2bf..87cab1966b 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -94,6 +94,7 @@ static NTSTATUS check_open_rights(struct connection_struct *conn,
"on %s: %s\n",
smb_fname_str_dbg(smb_fname),
nt_errstr(status)));
+ TALLOC_FREE(sd);
return status;
}
@@ -218,13 +219,13 @@ void change_file_owner_to_parent(connection_struct *conn,
if (ret == -1) {
DEBUG(0,("change_file_owner_to_parent: failed to fchown "
"file %s to parent directory uid %u. Error "
- "was %s\n", fsp->fsp_name,
+ "was %s\n", fsp_str_dbg(fsp),
(unsigned int)smb_fname_parent->st.st_ex_uid,
strerror(errno) ));
}
DEBUG(10,("change_file_owner_to_parent: changed new file %s to "
- "parent directory uid %u.\n", fsp->fsp_name,
+ "parent directory uid %u.\n", fsp_str_dbg(fsp),
(unsigned int)smb_fname_parent->st.st_ex_uid));
TALLOC_FREE(smb_fname_parent);
@@ -349,7 +350,6 @@ static NTSTATUS open_file(files_struct *fsp,
uint32 access_mask, /* client requested access mask. */
uint32 open_access_mask) /* what we're actually using in the open. */
{
- char *path = NULL;
NTSTATUS status = NT_STATUS_OK;
int accmode = (flags & O_ACCMODE);
int local_flags = flags;
@@ -434,7 +434,7 @@ static NTSTATUS open_file(files_struct *fsp,
* wildcard characters are allowed in stream names
* only test the basefilename
*/
- wild = fsp->base_fsp->fsp_name;
+ wild = fsp->base_fsp->fsp_name->base_name;
} else {
wild = smb_fname->base_name;
}
@@ -614,16 +614,13 @@ static NTSTATUS open_file(files_struct *fsp,
conn->case_sensitive)) {
fsp->aio_write_behind = True;
}
-
- status = get_full_smb_filename(talloc_tos(), smb_fname,
- &path);
+ status = fsp_set_smb_fname(fsp, smb_fname);
if (!NT_STATUS_IS_OK(status)) {
+ fd_close(fsp);
+ errno = map_errno_from_nt_status(status);
return status;
}
- string_set(&fsp->fsp_name, path);
- TALLOC_FREE(path);
-
fsp->wcp = NULL; /* Write cache pointer. */
DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
@@ -795,7 +792,8 @@ static void validate_my_share_entries(int num,
str = talloc_asprintf(talloc_tos(),
"validate_my_share_entries: "
"file %s, oplock_type = 0x%x, op_type = 0x%x\n",
- fsp->fsp_name, (unsigned int)fsp->oplock_type,
+ fsp->fsp_name->base_name,
+ (unsigned int)fsp->oplock_type,
(unsigned int)share_entry->op_type );
smb_panic(str);
}
@@ -1029,7 +1027,7 @@ static bool delay_for_oplocks(struct share_mode_lock *lck,
}
DEBUG(10,("delay_for_oplocks: oplock type 0x%x on file %s\n",
- fsp->oplock_type, fsp->fsp_name));
+ fsp->oplock_type, fsp_str_dbg(fsp)));
/* No delay. */
return false;
@@ -1152,13 +1150,6 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req,
uint32 create_options)
{
files_struct *fsp;
- char *fname = NULL;
- NTSTATUS status;
-
- status = get_full_smb_filename(talloc_tos(), smb_fname, &fname);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
DEBUG(5,("fcb_or_dos_open: attempting old open semantics for "
"file %s.\n", smb_fname_str_dbg(smb_fname)));
@@ -1168,7 +1159,7 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req,
DEBUG(10,("fcb_or_dos_open: checking file %s, fd = %d, "
"vuid = %u, file_pid = %u, private_options = 0x%x "
- "access_mask = 0x%x\n", fsp->fsp_name,
+ "access_mask = 0x%x\n", fsp_str_dbg(fsp),
fsp->fh->fd, (unsigned int)fsp->vuid,
(unsigned int)fsp->file_pid,
(unsigned int)fsp->fh->private_options,
@@ -1180,7 +1171,9 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req,
(fsp->fh->private_options & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS |
NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) &&
(fsp->access_mask & FILE_WRITE_DATA) &&
- strequal(fsp->fsp_name, fname)) {
+ strequal(fsp->fsp_name->base_name, smb_fname->base_name) &&
+ strequal(fsp->fsp_name->stream_name,
+ smb_fname->stream_name)) {
DEBUG(10,("fcb_or_dos_open: file match\n"));
break;
}
@@ -1198,17 +1191,16 @@ NTSTATUS fcb_or_dos_open(struct smb_request *req,
}
/* We need to duplicate this fsp. */
- dup_file_fsp(req, fsp, access_mask, share_access,
- create_options, fsp_to_dup_into);
-
- return NT_STATUS_OK;
+ return dup_file_fsp(req, fsp, access_mask, share_access,
+ create_options, fsp_to_dup_into);
}
/****************************************************************************
Open a file with a share mode - old openX method - map into NTCreate.
****************************************************************************/
-bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func,
+bool map_open_params_to_ntcreate(const struct smb_filename *smb_fname,
+ int deny_mode, int open_func,
uint32 *paccess_mask,
uint32 *pshare_mode,
uint32 *pcreate_disposition,
@@ -1221,7 +1213,8 @@ bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func
DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
"open_func = 0x%x\n",
- fname, (unsigned int)deny_mode, (unsigned int)open_func ));
+ smb_fname_str_dbg(smb_fname), (unsigned int)deny_mode,
+ (unsigned int)open_func ));
/* Create the NT compatible access_mask. */
switch (GET_OPENX_MODE(deny_mode)) {
@@ -1295,7 +1288,7 @@ bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func
case DENY_DOS:
create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
- if (is_executable(fname)) {
+ if (is_executable(smb_fname->base_name)) {
share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
} else {
if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
@@ -1320,7 +1313,7 @@ bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func
DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
"share_mode = 0x%x, create_disposition = 0x%x, "
"create_options = 0x%x\n",
- fname,
+ smb_fname_str_dbg(smb_fname),
(unsigned int)access_mask,
(unsigned int)share_mode,
(unsigned int)create_disposition,
@@ -2611,8 +2604,10 @@ static NTSTATUS open_directory(connection_struct *conn,
fsp->sent_oplock_break = NO_BREAK_SENT;
fsp->is_directory = True;
fsp->posix_open = (file_attributes & FILE_FLAG_POSIX_SEMANTICS) ? True : False;
-
- string_set(&fsp->fsp_name, smb_dname->base_name);
+ status = fsp_set_smb_fname(fsp, smb_dname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
mtimespec = smb_dname->st.st_ex_mtime;
@@ -2730,6 +2725,11 @@ void msg_file_was_renamed(struct messaging_context *msg,
bn_len = strlen(base_name);
stream_name = sharepath + sp_len + 1 + bn_len + 1;
+ /* stream_name must always be NULL if there is no stream. */
+ if (stream_name[0] == '\0') {
+ stream_name = NULL;
+ }
+
status = create_synthetic_smb_fname(talloc_tos(), base_name,
stream_name, NULL, &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
@@ -2743,18 +2743,14 @@ void msg_file_was_renamed(struct messaging_context *msg,
for(fsp = file_find_di_first(id); fsp; fsp = file_find_di_next(fsp)) {
if (memcmp(fsp->conn->connectpath, sharepath, sp_len) == 0) {
- char *newname = NULL;
DEBUG(10,("msg_file_was_renamed: renaming file fnum %d from %s -> %s\n",
- fsp->fnum, fsp->fsp_name,
+ fsp->fnum, fsp_str_dbg(fsp),
smb_fname_str_dbg(smb_fname)));
- status = get_full_smb_filename(talloc_tos(),
- smb_fname, &newname);
+ status = fsp_set_smb_fname(fsp, smb_fname);
if (!NT_STATUS_IS_OK(status)) {
goto out;
}
- string_set(&fsp->fsp_name, newname);
- TALLOC_FREE(newname);
} else {
/* TODO. JRA. */
/* Now we have the complete path we can work out if this is
@@ -2765,7 +2761,7 @@ void msg_file_was_renamed(struct messaging_context *msg,
fsp->conn->connectpath,
sharepath,
fsp->fnum,
- fsp->fsp_name,
+ fsp_str_dbg(fsp),
smb_fname_str_dbg(smb_fname)));
}
}
@@ -2926,7 +2922,7 @@ NTSTATUS open_streams_for_delete(connection_struct *conn,
}
DEBUG(10, ("Closing stream # %d, %s\n", i,
- streams[i]->fsp_name));
+ fsp_str_dbg(streams[i])));
close_file(NULL, streams[i], NORMAL_CLOSE);
}
@@ -3326,6 +3322,11 @@ NTSTATUS get_relative_fid_filename(connection_struct *conn,
dir_fsp = file_fsp(req, root_dir_fid);
+ if (is_ntfs_stream_smb_fname(dir_fsp->fsp_name)) {
+ status = NT_STATUS_INVALID_HANDLE;
+ goto out;
+ }
+
if (dir_fsp == NULL) {
status = NT_STATUS_INVALID_HANDLE;
goto out;
@@ -3354,7 +3355,7 @@ NTSTATUS get_relative_fid_filename(connection_struct *conn,
goto out;
}
- if (ISDOT(dir_fsp->fsp_name)) {
+ if (ISDOT(dir_fsp->fsp_name->base_name)) {
/*
* We're at the toplevel dir, the final file name
* must not contain ./, as this is filtered out
@@ -3367,7 +3368,7 @@ NTSTATUS get_relative_fid_filename(connection_struct *conn,
goto out;
}
} else {
- size_t dir_name_len = strlen(dir_fsp->fsp_name);
+ size_t dir_name_len = strlen(dir_fsp->fsp_name->base_name);
/*
* Copy in the base directory name.
@@ -3379,7 +3380,7 @@ NTSTATUS get_relative_fid_filename(connection_struct *conn,
status = NT_STATUS_NO_MEMORY;
goto out;
}
- memcpy(parent_fname, dir_fsp->fsp_name,
+ memcpy(parent_fname, dir_fsp->fsp_name->base_name,
dir_name_len+1);
/*
@@ -3463,16 +3464,9 @@ NTSTATUS create_file_default(connection_struct *conn,
*/
if (is_ntfs_stream_smb_fname(smb_fname)) {
- char *fname = NULL;
enum FAKE_FILE_TYPE fake_file_type;
- status = get_full_smb_filename(talloc_tos(), smb_fname,
- &fname);
- if (!NT_STATUS_IS_OK(status)) {
- goto fail;
- }
-
- fake_file_type = is_fake_file(fname);
+ fake_file_type = is_fake_file(smb_fname);
if (fake_file_type != FAKE_FILE_TYPE_NONE) {
@@ -3488,9 +3482,8 @@ NTSTATUS create_file_default(connection_struct *conn,
* close it
*/
status = open_fake_file(req, conn, req->vuid,
- fake_file_type, fname,
+ fake_file_type, smb_fname,
access_mask, &fsp);
- TALLOC_FREE(fname);
if (!NT_STATUS_IS_OK(status)) {
goto fail;
}
@@ -3498,7 +3491,6 @@ NTSTATUS create_file_default(connection_struct *conn,
ZERO_STRUCT(smb_fname->st);
goto done;
}
- TALLOC_FREE(fname);
if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index e9b2a6cf95..dd8d5372fb 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -81,7 +81,7 @@ bool set_file_oplock(files_struct *fsp, int oplock_type)
DEBUG(5,("set_file_oplock: granted oplock on file %s, %s/%lu, "
"tv_sec = %x, tv_usec = %x\n",
- fsp->fsp_name, file_id_string_tos(&fsp->file_id),
+ fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id),
fsp->fh->gen_id, (int)fsp->open_time.tv_sec,
(int)fsp->open_time.tv_usec ));
@@ -158,14 +158,15 @@ bool remove_oplock(files_struct *fsp)
NULL);
if (lck == NULL) {
DEBUG(0,("remove_oplock: failed to lock share entry for "
- "file %s\n", fsp->fsp_name ));
+ "file %s\n", fsp_str_dbg(fsp)));
return False;
}
ret = remove_share_oplock(lck, fsp);
if (!ret) {
DEBUG(0,("remove_oplock: failed to remove share oplock for "
"file %s fnum %d, %s\n",
- fsp->fsp_name, fsp->fnum, file_id_string_tos(&fsp->file_id)));
+ fsp_str_dbg(fsp), fsp->fnum,
+ file_id_string_tos(&fsp->file_id)));
}
release_file_oplock(fsp);
TALLOC_FREE(lck);
@@ -184,14 +185,15 @@ bool downgrade_oplock(files_struct *fsp)
NULL);
if (lck == NULL) {
DEBUG(0,("downgrade_oplock: failed to lock share entry for "
- "file %s\n", fsp->fsp_name ));
+ "file %s\n", fsp_str_dbg(fsp)));
return False;
}
ret = downgrade_share_oplock(lck, fsp);
if (!ret) {
DEBUG(0,("downgrade_oplock: failed to downgrade share oplock "
"for file %s fnum %d, file_id %s\n",
- fsp->fsp_name, fsp->fnum, file_id_string_tos(&fsp->file_id)));
+ fsp_str_dbg(fsp), fsp->fnum,
+ file_id_string_tos(&fsp->file_id)));
}
downgrade_file_oplock(fsp);
@@ -294,7 +296,8 @@ static files_struct *initial_break_processing(struct file_id id, unsigned long f
if(fsp->oplock_type == NO_OPLOCK) {
if( DEBUGLVL( 3 ) ) {
- dbgtext( "initial_break_processing: file %s ", fsp->fsp_name );
+ dbgtext( "initial_break_processing: file %s ",
+ fsp_str_dbg(fsp));
dbgtext( "(file_id = %s gen_id = %lu) has no oplock.\n",
file_id_string_tos(&id), fsp->fh->gen_id );
dbgtext( "Allowing break to succeed regardless.\n" );
@@ -314,7 +317,8 @@ static void oplock_timeout_handler(struct event_context *ctx,
/* Remove the timed event handler. */
TALLOC_FREE(fsp->oplock_timeout);
- DEBUG(0, ("Oplock break failed for file %s -- replying anyway\n", fsp->fsp_name));
+ DEBUG(0, ("Oplock break failed for file %s -- replying anyway\n",
+ fsp_str_dbg(fsp)));
global_client_failed_oplock_break = True;
remove_oplock(fsp);
reply_to_oplock_break_requests(fsp);
@@ -375,7 +379,7 @@ void break_level2_to_none_async(files_struct *fsp)
DEBUG(10,("process_oplock_async_level2_break_message: sending break "
"to none message for fid %d, file %s\n", fsp->fnum,
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
/* Now send a break to none message to our client. */
break_msg = new_break_smb_message(NULL, fsp, OPLOCKLEVEL_NONE);
@@ -506,7 +510,7 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx,
!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
DEBUG(3, ("Already downgraded oplock on %s: %s\n",
file_id_string_tos(&fsp->file_id),
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
/* We just send the same message back. */
messaging_send_buf(msg_ctx, src, MSG_SMB_BREAK_RESPONSE,
(uint8 *)data->data,
@@ -740,7 +744,7 @@ static void contend_level2_oplocks_begin_default(files_struct *fsp,
NULL);
if (lck == NULL) {
DEBUG(0,("release_level_2_oplocks_on_change: failed to lock "
- "share mode entry for file %s.\n", fsp->fsp_name ));
+ "share mode entry for file %s.\n", fsp_str_dbg(fsp)));
return;
}
diff --git a/source3/smbd/oplock_irix.c b/source3/smbd/oplock_irix.c
index 89b8e0f7b5..dd32177988 100644
--- a/source3/smbd/oplock_irix.c
+++ b/source3/smbd/oplock_irix.c
@@ -212,7 +212,8 @@ static bool irix_set_kernel_oplock(struct kernel_oplocks *_ctx,
DEBUG(0,("irix_set_kernel_oplock: Unable to get "
"kernel oplock on file %s, file_id %s "
"gen_id = %ul. Error was %s\n",
- fsp->fsp_name, file_id_string_tos(&fsp->file_id),
+ fsp_str_dbg(fsp),
+ file_id_string_tos(&fsp->file_id),
fsp->fh->gen_id,
strerror(errno) ));
} else {
@@ -220,7 +221,7 @@ static bool irix_set_kernel_oplock(struct kernel_oplocks *_ctx,
"file %s, fd = %d, file_id = %s, "
"gen_id = %ul. Another process had the file "
"open.\n",
- fsp->fsp_name, fsp->fh->fd,
+ fsp_str_dbg(fsp), fsp->fh->fd,
file_id_string_tos(&fsp->file_id),
fsp->fh->gen_id ));
}
@@ -229,7 +230,7 @@ static bool irix_set_kernel_oplock(struct kernel_oplocks *_ctx,
DEBUG(10,("irix_set_kernel_oplock: got kernel oplock on file %s, file_id = %s "
"gen_id = %ul\n",
- fsp->fsp_name, file_id_string_tos(&fsp->file_id),
+ fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id),
fsp->fh->gen_id));
return True;
@@ -250,7 +251,8 @@ static void irix_release_kernel_oplock(struct kernel_oplocks *_ctx,
int state = sys_fcntl_long(fsp->fh->fd, F_OPLKACK, -1);
dbgtext("irix_release_kernel_oplock: file %s, file_id = %s"
"gen_id = %ul, has kernel oplock state "
- "of %x.\n", fsp->fsp_name, file_id_string_tos(&fsp->file_id),
+ "of %x.\n", fsp_str_dbg(fsp),
+ file_id_string_tos(&fsp->file_id),
fsp->fh->gen_id, state );
}
@@ -263,7 +265,8 @@ static void irix_release_kernel_oplock(struct kernel_oplocks *_ctx,
"removing kernel oplock on file " );
dbgtext("%s, file_id = %s gen_id = %ul. "
"Error was %s\n",
- fsp->fsp_name, file_id_string_tos(&fsp->file_id),
+ fsp_str_dbg(fsp),
+ file_id_string_tos(&fsp->file_id),
fsp->fh->gen_id,
strerror(errno) );
}
diff --git a/source3/smbd/oplock_linux.c b/source3/smbd/oplock_linux.c
index 273fbfdc01..b4a5495e4b 100644
--- a/source3/smbd/oplock_linux.c
+++ b/source3/smbd/oplock_linux.c
@@ -111,7 +111,7 @@ static bool linux_set_kernel_oplock(struct kernel_oplocks *ctx,
if ( SMB_VFS_LINUX_SETLEASE(fsp, F_WRLCK) == -1) {
DEBUG(3,("linux_set_kernel_oplock: Refused oplock on file %s, "
"fd = %d, file_id = %s. (%s)\n",
- fsp->fsp_name, fsp->fh->fd,
+ fsp_str_dbg(fsp), fsp->fh->fd,
file_id_string_tos(&fsp->file_id),
strerror(errno)));
return False;
@@ -119,7 +119,7 @@ static bool linux_set_kernel_oplock(struct kernel_oplocks *ctx,
DEBUG(3,("linux_set_kernel_oplock: got kernel oplock on file %s, "
"file_id = %s gen_id = %lu\n",
- fsp->fsp_name, file_id_string_tos(&fsp->file_id),
+ fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id),
fsp->fh->gen_id));
return True;
@@ -140,7 +140,8 @@ static void linux_release_kernel_oplock(struct kernel_oplocks *ctx,
int state = fcntl(fsp->fh->fd, F_GETLEASE, 0);
dbgtext("linux_release_kernel_oplock: file %s, file_id = %s "
"gen_id = %lu has kernel oplock state "
- "of %x.\n", fsp->fsp_name, file_id_string_tos(&fsp->file_id),
+ "of %x.\n", fsp_str_dbg(fsp),
+ file_id_string_tos(&fsp->file_id),
fsp->fh->gen_id, state );
}
@@ -152,7 +153,7 @@ static void linux_release_kernel_oplock(struct kernel_oplocks *ctx,
dbgtext("linux_release_kernel_oplock: Error when "
"removing kernel oplock on file " );
dbgtext("%s, file_id = %s, gen_id = %lu. "
- "Error was %s\n", fsp->fsp_name,
+ "Error was %s\n", fsp_str_dbg(fsp),
file_id_string_tos(&fsp->file_id),
fsp->fh->gen_id, strerror(errno) );
}
diff --git a/source3/smbd/oplock_onefs.c b/source3/smbd/oplock_onefs.c
index d359f9c6f2..a73100abdf 100644
--- a/source3/smbd/oplock_onefs.c
+++ b/source3/smbd/oplock_onefs.c
@@ -60,29 +60,30 @@ struct onefs_callback_record {
struct onefs_callback_record *callback_recs;
/**
- * Convert a onefs_callback_record to a string.
+ * Convert a onefs_callback_record to a debug string using the dbg_ctx().
*/
-static char *onefs_callback_record_str_static(const struct onefs_callback_record *r)
+const char *onefs_cb_record_str_dbg(const struct onefs_callback_record *r)
{
- static fstring result;
+ char *result;
if (r == NULL) {
- fstrcpy(result, "NULL callback record");
+ result = talloc_strdup(dbg_ctx(), "NULL callback record");
return result;
}
switch (r->state) {
case ONEFS_OPEN_FILE:
- fstr_sprintf(result, "cb record %llu for file %s",
- r->id, r->data.fsp->fsp_name);
- break;
+ result = talloc_asprintf(dbg_ctx(), "cb record %llu for file "
+ "%s", r->id,
+ fsp_str_dbg(r->data.fsp));
case ONEFS_WAITING_FOR_OPLOCK:
- fstr_sprintf(result, "cb record %llu for pending mid %d",
- r->id, (int)r->data.mid);
+ result = talloc_asprintf(dbg_ctx(), "cb record %llu for "
+ "pending mid %d", r->id,
+ (int)r->data.mid);
break;
default:
- fstr_sprintf(result, "cb record %llu unknown state %d",
- r->id, r->state);
+ result = talloc_asprintf(dbg_ctx(), "cb record %llu unknown "
+ "state %d", r->id, r->state);
break;
}
@@ -102,7 +103,7 @@ static void debug_cb_records(const char *fn)
DEBUG(10, ("cb records (%s):\n", fn));
for (rec = callback_recs; rec; rec = rec->next) {
- DEBUGADD(10, ("%s\n", onefs_callback_record_str_static(rec)));
+ DEBUGADD(10, ("%s\n", onefs_cb_record_dbg_str(rec)));
}
}
@@ -127,7 +128,7 @@ static struct onefs_callback_record *onefs_find_cb(uint64_t id,
for (rec = callback_recs; rec; rec = rec->next) {
if (rec->id == id) {
DEBUG(10, ("found %s\n",
- onefs_callback_record_str_static(rec)));
+ onefs_cb_record_dbg_str(rec)));
break;
}
}
@@ -139,7 +140,7 @@ static struct onefs_callback_record *onefs_find_cb(uint64_t id,
if (rec->state != expected_state) {
DEBUG(0, ("Expected cb type %d, got %s", expected_state,
- onefs_callback_record_str_static(rec)));
+ onefs_cb_record_dbg_str(rec)));
SMB_ASSERT(0);
return NULL;
}
@@ -299,7 +300,7 @@ static void oplock_break_to_none_handler(uint64_t id)
}
DEBUG(10, ("oplock_break_to_none_handler called for file %s\n",
- cb->data.fsp->fsp_name));
+ cb->data.fsp_str_dbg(fsp)));
init_share_mode_entry(&sme, cb, FORCE_OPLOCK_BREAK_TO_NONE);
share_mode_entry_to_message(msg, &sme);
@@ -336,7 +337,7 @@ static void oplock_break_to_level_two_handler(uint64_t id)
}
DEBUG(10, ("oplock_break_to_level_two_handler called for file %s\n",
- cb->data.fsp->fsp_name));
+ cb->data.fsp_str_dbg(fsp)));
init_share_mode_entry(&sme, cb, LEVEL_II_OPLOCK);
share_mode_entry_to_message(msg, &sme);
@@ -377,7 +378,7 @@ static void oplock_revoked_handler(uint64_t id)
SMB_ASSERT(fsp->oplock_timeout == NULL);
DEBUG(0,("Level 1 oplock break failed for file %s. Forcefully "
- "revoking oplock\n", fsp->fsp_name));
+ "revoking oplock\n", fsp_str_dbg(fsp)));
global_client_failed_oplock_break = True;
remove_oplock(fsp);
@@ -413,7 +414,7 @@ static void semlock_available_handler(uint64_t id)
char *msg;
if (asprintf(&msg, "Semlock available on an open that wasn't "
"deferred: %s\n",
- onefs_callback_record_str_static(cb)) != -1) {
+ onefs_cb_record_dbg_str(cb)) != -1) {
smb_panic(msg);
}
smb_panic("Semlock available on an open that wasn't "
@@ -457,7 +458,7 @@ static void semlock_async_failure_handler(uint64_t id)
char *msg;
if (asprintf(&msg, "Semlock failure on an open that wasn't "
"deferred: %s\n",
- onefs_callback_record_str_static(cb)) != -1) {
+ onefs_cb_record_dbg_str(cb)) != -1) {
smb_panic(msg);
}
smb_panic("Semlock failure on an open that wasn't deferred\n");
@@ -501,7 +502,7 @@ static void onefs_release_kernel_oplock(struct kernel_oplocks *_ctx,
enum oplock_type oplock = onefs_samba_oplock_to_oplock(oplock_type);
DEBUG(10, ("onefs_release_kernel_oplock: Releasing %s to type %s\n",
- fsp->fsp_name, onefs_oplock_str(oplock)));
+ fsp_str_dbg(fsp), onefs_oplock_str(oplock)));
if (fsp->fh->fd == -1) {
DEBUG(1, ("no fd\n"));
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index 928ef0169e..b1a749736d 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -428,27 +428,30 @@ bool user_in_netgroup(struct smbd_server_connection *sconn,
if (innetgr(ngname, NULL, user, sconn->smb1.sessions.my_yp_domain)) {
DEBUG(5,("user_in_netgroup: Found\n"));
return true;
- } else {
+ }
- /*
- * Ok, innetgr is case sensitive. Try once more with lowercase
- * just in case. Attempt to fix #703. JRA.
- */
+ /*
+ * Ok, innetgr is case sensitive. Try once more with lowercase
+ * just in case. Attempt to fix #703. JRA.
+ */
+ fstrcpy(lowercase_user, user);
+ strlower_m(lowercase_user);
- fstrcpy(lowercase_user, user);
- strlower_m(lowercase_user);
+ if (strcmp(user,lowercase_user) == 0) {
+ /* user name was already lower case! */
+ return false;
+ }
- DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
- lowercase_user,
- sconn->smb1.sessions.my_yp_domain?
- sconn->smb1.sessions.my_yp_domain:"(ANY)",
- ngname));
+ DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
+ lowercase_user,
+ sconn->smb1.sessions.my_yp_domain?
+ sconn->smb1.sessions.my_yp_domain:"(ANY)",
+ ngname));
- if (innetgr(ngname, NULL, lowercase_user,
- sconn->smb1.sessions.my_yp_domain)) {
- DEBUG(5,("user_in_netgroup: Found\n"));
- return true;
- }
+ if (innetgr(ngname, NULL, lowercase_user,
+ sconn->smb1.sessions.my_yp_domain)) {
+ DEBUG(5,("user_in_netgroup: Found\n"));
+ return true;
}
#endif /* HAVE_NETGROUP */
return false;
diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c
index 7ae7435646..091db09987 100644
--- a/source3/smbd/pipes.c
+++ b/source3/smbd/pipes.c
@@ -37,6 +37,7 @@ NTSTATUS open_np_file(struct smb_request *smb_req, const char *name,
{
struct connection_struct *conn = smb_req->conn;
struct files_struct *fsp;
+ struct smb_filename *smb_fname = NULL;
NTSTATUS status;
status = file_new(smb_req, conn, &fsp);
@@ -50,7 +51,19 @@ NTSTATUS open_np_file(struct smb_request *smb_req, const char *name,
fsp->vuid = smb_req->vuid;
fsp->can_lock = false;
fsp->access_mask = FILE_READ_DATA | FILE_WRITE_DATA;
- string_set(&fsp->fsp_name, name);
+
+ status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ file_free(smb_req, fsp);
+ return status;
+ }
+ status = fsp_set_smb_fname(fsp, smb_fname);
+ TALLOC_FREE(smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ file_free(smb_req, fsp);
+ return status;
+ }
status = np_open(NULL, name, conn->client_address,
conn->server_info, &fsp->fake_file_handle);
@@ -179,7 +192,7 @@ void reply_pipe_write(struct smb_request *req)
data = req->buf + 3;
DEBUG(6, ("reply_pipe_write: %x name: %s len: %d\n", (int)fsp->fnum,
- fsp->fsp_name, (int)state->numtowrite));
+ fsp_str_dbg(fsp), (int)state->numtowrite));
subreq = np_write_send(state, smbd_event_context(),
fsp->fake_file_handle, data, state->numtowrite);
@@ -203,8 +216,14 @@ static void pipe_write_done(struct tevent_req *subreq)
status = np_write_recv(subreq, &nwritten);
TALLOC_FREE(subreq);
- if ((nwritten == 0 && state->numtowrite != 0) || (nwritten < 0)) {
- reply_unixerror(req, ERRDOS, ERRnoaccess);
+ if (nwritten < 0) {
+ reply_nterror(req, status);
+ goto send;
+ }
+
+ /* Looks bogus to me now. Needs to be removed ? JRA. */
+ if ((nwritten == 0 && state->numtowrite != 0)) {
+ reply_doserror(req, ERRDOS, ERRnoaccess);
goto send;
}
@@ -269,7 +288,7 @@ void reply_pipe_write_and_X(struct smb_request *req)
== (PIPE_START_MESSAGE|PIPE_RAW_MODE));
DEBUG(6, ("reply_pipe_write_and_X: %x name: %s len: %d\n",
- (int)fsp->fnum, fsp->fsp_name, (int)state->numtowrite));
+ (int)fsp->fnum, fsp_str_dbg(fsp), (int)state->numtowrite));
data = (uint8_t *)smb_base(req->inbuf) + smb_doff;
@@ -283,7 +302,7 @@ void reply_pipe_write_and_X(struct smb_request *req)
DEBUG(0,("reply_pipe_write_and_X: start of message "
"set and not enough data sent.(%u)\n",
(unsigned int)state->numtowrite ));
- reply_unixerror(req, ERRDOS, ERRnoaccess);
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
return;
}
@@ -313,8 +332,15 @@ static void pipe_write_andx_done(struct tevent_req *subreq)
status = np_write_recv(subreq, &nwritten);
TALLOC_FREE(subreq);
- if (!NT_STATUS_IS_OK(status) || (nwritten != state->numtowrite)) {
- reply_unixerror(req, ERRDOS,ERRnoaccess);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ goto done;
+ }
+
+ /* Looks bogus to me now. Is this error message correct ? JRA. */
+ if (nwritten != state->numtowrite) {
+ reply_doserror(req, ERRDOS,ERRnoaccess);
goto done;
}
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 76eee9b56a..0a3b0dff75 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -256,15 +256,16 @@ static void store_inheritance_attributes(files_struct *fsp,
ret = SMB_VFS_FSETXATTR(fsp, SAMBA_POSIX_INHERITANCE_EA_NAME,
pai_buf, store_size, 0);
} else {
- ret = SMB_VFS_SETXATTR(fsp->conn,fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME,
- pai_buf, store_size, 0);
+ ret = SMB_VFS_SETXATTR(fsp->conn, fsp->fsp_name->base_name,
+ SAMBA_POSIX_INHERITANCE_EA_NAME,
+ pai_buf, store_size, 0);
}
SAFE_FREE(pai_buf);
DEBUG(10,("store_inheritance_attribute: type 0x%x for file %s\n",
(unsigned int)sd_type,
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
if (ret == -1 && !no_acl_syscall_error(errno)) {
DEBUG(1,("store_inheritance_attribute: Error %s\n", strerror(errno) ));
@@ -599,8 +600,10 @@ static struct pai_val *fload_inherited_info(files_struct *fsp)
ret = SMB_VFS_FGETXATTR(fsp, SAMBA_POSIX_INHERITANCE_EA_NAME,
pai_buf, pai_buf_size);
} else {
- ret = SMB_VFS_GETXATTR(fsp->conn,fsp->fsp_name,SAMBA_POSIX_INHERITANCE_EA_NAME,
- pai_buf, pai_buf_size);
+ ret = SMB_VFS_GETXATTR(fsp->conn,
+ fsp->fsp_name->base_name,
+ SAMBA_POSIX_INHERITANCE_EA_NAME,
+ pai_buf, pai_buf_size);
}
if (ret == -1) {
@@ -618,7 +621,8 @@ static struct pai_val *fload_inherited_info(files_struct *fsp)
}
} while (ret == -1);
- DEBUG(10,("load_inherited_info: ret = %lu for file %s\n", (unsigned long)ret, fsp->fsp_name));
+ DEBUG(10,("load_inherited_info: ret = %lu for file %s\n",
+ (unsigned long)ret, fsp_str_dbg(fsp)));
if (ret == -1) {
/* No attribute or not supported. */
@@ -637,8 +641,7 @@ static struct pai_val *fload_inherited_info(files_struct *fsp)
if (paiv) {
DEBUG(10,("load_inherited_info: ACL type is 0x%x for file %s\n",
- (unsigned int)paiv->sd_type,
- fsp->fsp_name));
+ (unsigned int)paiv->sd_type, fsp_str_dbg(fsp)));
}
SAFE_FREE(pai_buf);
@@ -1727,8 +1730,12 @@ static bool create_canon_ace_lists(files_struct *fsp,
got_dir_allow = True;
if ((current_ace->attr == DENY_ACE) && got_dir_allow) {
- DEBUG(0,("create_canon_ace_lists: malformed ACL in inheritable ACL ! \
-Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name ));
+ DEBUG(0,("create_canon_ace_lists: "
+ "malformed ACL in "
+ "inheritable ACL! Deny entry "
+ "after Allow entry. Failing "
+ "to set on file %s.\n",
+ fsp_str_dbg(fsp)));
free_canon_ace_list(file_ace);
free_canon_ace_list(dir_ace);
return False;
@@ -1785,8 +1792,10 @@ Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name ));
got_file_allow = True;
if ((current_ace->attr == DENY_ACE) && got_file_allow) {
- DEBUG(0,("create_canon_ace_lists: malformed ACL in file ACL ! \
-Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name ));
+ DEBUG(0,("create_canon_ace_lists: malformed "
+ "ACL in file ACL ! Deny entry after "
+ "Allow entry. Failing to set on file "
+ "%s.\n", fsp_str_dbg(fsp)));
free_canon_ace_list(file_ace);
free_canon_ace_list(dir_ace);
return False;
@@ -2169,17 +2178,8 @@ static mode_t create_default_mode(files_struct *fsp, bool interitable_mode)
mode_t mode;
if (interitable_mode) {
- struct smb_filename *smb_fname = NULL;
- NTSTATUS status;
-
- status = create_synthetic_smb_fname_split(talloc_tos(),
- fsp->fsp_name, NULL,
- &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- return 0;
- }
- mode = unix_mode(fsp->conn, FILE_ATTRIBUTE_ARCHIVE, smb_fname,
- NULL);
+ mode = unix_mode(fsp->conn, FILE_ATTRIBUTE_ARCHIVE,
+ fsp->fsp_name, NULL);
} else {
mode = S_IRUSR;
}
@@ -2602,14 +2602,9 @@ static bool set_canon_ace_list(files_struct *fsp,
SMB_ACL_TYPE_T the_acl_type = (default_ace ? SMB_ACL_TYPE_DEFAULT : SMB_ACL_TYPE_ACCESS);
bool needs_mask = False;
mode_t mask_perms = 0;
- struct smb_filename *smb_fname = NULL;
- NTSTATUS status;
- status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
- psbuf, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- goto fail;
- }
+ /* Use the psbuf that was passed in. */
+ fsp->fsp_name->st = *psbuf;
#if defined(POSIX_ACL_NEEDS_MASK)
/* HP-UX always wants to have a mask (called "class" there). */
@@ -2767,7 +2762,7 @@ static bool set_canon_ace_list(files_struct *fsp,
*/
if(default_ace || fsp->is_directory || fsp->fh->fd == -1) {
- if (SMB_VFS_SYS_ACL_SET_FILE(conn, smb_fname->base_name,
+ if (SMB_VFS_SYS_ACL_SET_FILE(conn, fsp->fsp_name->base_name,
the_acl_type, the_acl) == -1) {
/*
* Some systems allow all the above calls and only fail with no ACL support
@@ -2777,17 +2772,17 @@ static bool set_canon_ace_list(files_struct *fsp,
*pacl_set_support = False;
}
- if (acl_group_override(conn, smb_fname)) {
+ if (acl_group_override(conn, fsp->fsp_name)) {
int sret;
DEBUG(5,("set_canon_ace_list: acl group "
"control on and current user in file "
"%s primary group.\n",
- smb_fname_str_dbg(smb_fname)));
+ fsp_str_dbg(fsp)));
become_root();
sret = SMB_VFS_SYS_ACL_SET_FILE(conn,
- smb_fname->base_name, the_acl_type,
+ fsp->fsp_name->base_name, the_acl_type,
the_acl);
unbecome_root();
if (sret == 0) {
@@ -2801,8 +2796,7 @@ static bool set_canon_ace_list(files_struct *fsp,
"file %s (%s).\n",
the_acl_type == SMB_ACL_TYPE_DEFAULT ?
"directory default" : "file",
- smb_fname_str_dbg(smb_fname),
- strerror(errno)));
+ fsp_str_dbg(fsp), strerror(errno)));
goto fail;
}
}
@@ -2816,13 +2810,13 @@ static bool set_canon_ace_list(files_struct *fsp,
*pacl_set_support = False;
}
- if (acl_group_override(conn, smb_fname)) {
+ if (acl_group_override(conn, fsp->fsp_name)) {
int sret;
DEBUG(5,("set_canon_ace_list: acl group "
"control on and current user in file "
"%s primary group.\n",
- smb_fname_str_dbg(smb_fname)));
+ fsp_str_dbg(fsp)));
become_root();
sret = SMB_VFS_SYS_ACL_SET_FD(fsp, the_acl);
@@ -2836,8 +2830,7 @@ static bool set_canon_ace_list(files_struct *fsp,
DEBUG(2,("set_canon_ace_list: "
"sys_acl_set_file failed for file %s "
"(%s).\n",
- smb_fname_str_dbg(smb_fname),
- strerror(errno) ));
+ fsp_str_dbg(fsp), strerror(errno)));
goto fail;
}
}
@@ -2850,7 +2843,6 @@ static bool set_canon_ace_list(files_struct *fsp,
if (the_acl != NULL) {
SMB_VFS_SYS_ACL_FREE_ACL(conn, the_acl);
}
- TALLOC_FREE(smb_fname);
return ret;
}
@@ -2906,8 +2898,9 @@ static bool convert_canon_ace_to_posix_perms( files_struct *fsp, canon_ace *file
mode_t or_bits;
if (ace_count != 3) {
- DEBUG(3,("convert_canon_ace_to_posix_perms: Too many ACE entries for file %s to convert to \
-posix perms.\n", fsp->fsp_name ));
+ DEBUG(3,("convert_canon_ace_to_posix_perms: Too many ACE "
+ "entries for file %s to convert to posix perms.\n",
+ fsp_str_dbg(fsp)));
return False;
}
@@ -2921,8 +2914,8 @@ posix perms.\n", fsp->fsp_name ));
}
if (!owner_ace || !group_ace || !other_ace) {
- DEBUG(3,("convert_canon_ace_to_posix_perms: Can't get standard entries for file %s.\n",
- fsp->fsp_name ));
+ DEBUG(3,("convert_canon_ace_to_posix_perms: Can't get "
+ "standard entries for file %s.\n", fsp_str_dbg(fsp)));
return False;
}
@@ -2956,9 +2949,10 @@ posix perms.\n", fsp->fsp_name ));
*posix_perms = (((*posix_perms) & and_bits)|or_bits);
- DEBUG(10,("convert_canon_ace_to_posix_perms: converted u=%o,g=%o,w=%o to perm=0%o for file %s.\n",
- (int)owner_ace->perms, (int)group_ace->perms, (int)other_ace->perms, (int)*posix_perms,
- fsp->fsp_name ));
+ DEBUG(10,("convert_canon_ace_to_posix_perms: converted u=%o,g=%o,w=%o "
+ "to perm=0%o for file %s.\n", (int)owner_ace->perms,
+ (int)group_ace->perms, (int)other_ace->perms,
+ (int)*posix_perms, fsp_str_dbg(fsp)));
return True;
}
@@ -3351,11 +3345,12 @@ NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info,
*ppdesc = NULL;
- DEBUG(10,("posix_fget_nt_acl: called for file %s\n", fsp->fsp_name ));
+ DEBUG(10,("posix_fget_nt_acl: called for file %s\n",
+ fsp_str_dbg(fsp)));
/* can it happen that fsp_name == NULL ? */
if (fsp->is_directory || fsp->fh->fd == -1) {
- return posix_get_nt_acl(fsp->conn, fsp->fsp_name,
+ return posix_get_nt_acl(fsp->conn, fsp->fsp_name->base_name,
security_info, ppdesc);
}
@@ -3369,40 +3364,53 @@ NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info,
pal = fload_inherited_info(fsp);
- return posix_get_nt_acl_common(fsp->conn, fsp->fsp_name, &sbuf, pal,
- posix_acl, NULL, security_info, ppdesc);
+ return posix_get_nt_acl_common(fsp->conn, fsp->fsp_name->base_name,
+ &sbuf, pal, posix_acl, NULL,
+ security_info, ppdesc);
}
NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name,
uint32_t security_info, SEC_DESC **ppdesc)
{
- SMB_STRUCT_STAT sbuf;
SMB_ACL_T posix_acl = NULL;
SMB_ACL_T def_acl = NULL;
struct pai_val *pal;
+ struct smb_filename *smb_fname = NULL;
+ NTSTATUS status;
*ppdesc = NULL;
DEBUG(10,("posix_get_nt_acl: called for file %s\n", name ));
+ status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
/* Get the stat struct for the owner info. */
- if(vfs_stat_smb_fname(conn, name, &sbuf) != 0) {
- return map_nt_error_from_unix(errno);
+ if(SMB_VFS_STAT(conn, smb_fname) != 0) {
+ status = map_nt_error_from_unix(errno);
+ goto out;
}
/* Get the ACL from the path. */
posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, SMB_ACL_TYPE_ACCESS);
/* If it's a directory get the default POSIX ACL. */
- if(S_ISDIR(sbuf.st_ex_mode)) {
+ if(S_ISDIR(smb_fname->st.st_ex_mode)) {
def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, SMB_ACL_TYPE_DEFAULT);
def_acl = free_empty_sys_acl(conn, def_acl);
}
pal = load_inherited_info(conn, name);
- return posix_get_nt_acl_common(conn, name, &sbuf, pal, posix_acl,
- def_acl, security_info, ppdesc);
+ status = posix_get_nt_acl_common(conn, name, &smb_fname->st, pal,
+ posix_acl, def_acl, security_info,
+ ppdesc);
+ out:
+ TALLOC_FREE(smb_fname);
+ return status;
}
/****************************************************************************
@@ -3514,7 +3522,8 @@ NTSTATUS append_parent_acl(files_struct *fsp,
return NT_STATUS_NO_MEMORY;
}
- if (!parent_dirname(mem_ctx, fsp->fsp_name, &parent_name, NULL)) {
+ if (!parent_dirname(mem_ctx, fsp->fsp_name->base_name, &parent_name,
+ NULL)) {
return NT_STATUS_NO_MEMORY;
}
@@ -3596,7 +3605,7 @@ NTSTATUS append_parent_acl(files_struct *fsp,
"ignoring non container "
"inherit flags %u on ACE with sid %s "
"from parent %s\n",
- fsp->fsp_name,
+ fsp_str_dbg(fsp),
(unsigned int)se->flags,
sid_string_dbg(&se->trustee),
parent_name));
@@ -3609,7 +3618,7 @@ NTSTATUS append_parent_acl(files_struct *fsp,
"ignoring non object "
"inherit flags %u on ACE with sid %s "
"from parent %s\n",
- fsp->fsp_name,
+ fsp_str_dbg(fsp),
(unsigned int)se->flags,
sid_string_dbg(&se->trustee),
parent_name));
@@ -3633,7 +3642,7 @@ NTSTATUS append_parent_acl(files_struct *fsp,
DEBUG(10,("append_parent_acl: path %s "
"ignoring ACE with protected sid %s "
"from parent %s\n",
- fsp->fsp_name,
+ fsp_str_dbg(fsp),
sid_string_dbg(&se->trustee),
parent_name));
continue;
@@ -3671,7 +3680,7 @@ NTSTATUS append_parent_acl(files_struct *fsp,
DEBUG(10,("append_parent_acl: path %s "
"inheriting ACE with sid %s "
"from parent %s\n",
- fsp->fsp_name,
+ fsp_str_dbg(fsp),
sid_string_dbg(&se->trustee),
parent_name));
}
@@ -3707,21 +3716,13 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
bool set_acl_as_root = false;
bool acl_set_support = false;
bool ret = false;
- struct smb_filename *smb_fname = NULL;
-
- status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
- NULL, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- goto out;
- }
DEBUG(10,("set_nt_acl: called for file %s\n",
- smb_fname_str_dbg(smb_fname)));
+ fsp_str_dbg(fsp)));
if (!CAN_WRITE(conn)) {
DEBUG(10,("set acl rejected on read-only share\n"));
- status = NT_STATUS_MEDIA_WRITE_PROTECTED;
- goto out;
+ return NT_STATUS_MEDIA_WRITE_PROTECTED;
}
/*
@@ -3729,19 +3730,17 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
*/
if(fsp->is_directory || fsp->fh->fd == -1) {
- if(SMB_VFS_STAT(fsp->conn, smb_fname) != 0) {
- status = map_nt_error_from_unix(errno);
- goto out;
+ if(SMB_VFS_STAT(fsp->conn, fsp->fsp_name) != 0) {
+ return map_nt_error_from_unix(errno);
}
} else {
- if(SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
- status = map_nt_error_from_unix(errno);
- goto out;
+ if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
+ return map_nt_error_from_unix(errno);
}
}
/* Save the original element we check against. */
- orig_mode = smb_fname->st.st_ex_mode;
+ orig_mode = fsp->fsp_name->st.st_ex_mode;
/*
* Unpack the user/group/world id's.
@@ -3749,7 +3748,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
status = unpack_nt_owners( SNUM(conn), &user, &grp, security_info_sent, psd);
if (!NT_STATUS_IS_OK(status)) {
- goto out;
+ return status;
}
/*
@@ -3758,24 +3757,22 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
* Noticed by Simo.
*/
- if (((user != (uid_t)-1) && (smb_fname->st.st_ex_uid != user)) ||
- (( grp != (gid_t)-1) && (smb_fname->st.st_ex_gid != grp))) {
+ if (((user != (uid_t)-1) && (fsp->fsp_name->st.st_ex_uid != user)) ||
+ (( grp != (gid_t)-1) && (fsp->fsp_name->st.st_ex_gid != grp))) {
DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n",
- smb_fname_str_dbg(smb_fname), (unsigned int)user,
- (unsigned int)grp ));
+ fsp_str_dbg(fsp), (unsigned int)user,
+ (unsigned int)grp));
- if(try_chown(fsp->conn, smb_fname, user, grp) == -1) {
+ if(try_chown(fsp->conn, fsp->fsp_name, user, grp) == -1) {
DEBUG(3,("set_nt_acl: chown %s, %u, %u failed. Error "
- "= %s.\n", smb_fname_str_dbg(smb_fname),
+ "= %s.\n", fsp_str_dbg(fsp),
(unsigned int)user, (unsigned int)grp,
strerror(errno)));
if (errno == EPERM) {
- status = NT_STATUS_INVALID_OWNER;
- goto out;
+ return NT_STATUS_INVALID_OWNER;
}
- status = map_nt_error_from_unix(errno);
- goto out;
+ return map_nt_error_from_unix(errno);
}
/*
@@ -3784,25 +3781,24 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
*/
if(fsp->is_directory) {
- if(SMB_VFS_STAT(fsp->conn, smb_fname) != 0) {
- status = map_nt_error_from_unix(errno);
- goto out;
+ if(SMB_VFS_STAT(fsp->conn, fsp->fsp_name) != 0) {
+ return map_nt_error_from_unix(errno);
}
} else {
int sret;
if(fsp->fh->fd == -1)
- sret = SMB_VFS_STAT(fsp->conn, smb_fname);
+ sret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
else
- sret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
+ sret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
if(sret != 0)
return map_nt_error_from_unix(errno);
}
/* Save the original element we check against. */
- orig_mode = smb_fname->st.st_ex_mode;
+ orig_mode = fsp->fsp_name->st.st_ex_mode;
/* If we successfully chowned, we know we must
* be able to set the acl, so do it as root.
@@ -3810,24 +3806,22 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
set_acl_as_root = true;
}
- create_file_sids(&smb_fname->st, &file_owner_sid, &file_grp_sid);
+ create_file_sids(&fsp->fsp_name->st, &file_owner_sid, &file_grp_sid);
- acl_perms = unpack_canon_ace(fsp, &smb_fname->st, &file_owner_sid,
+ acl_perms = unpack_canon_ace(fsp, &fsp->fsp_name->st, &file_owner_sid,
&file_grp_sid, &file_ace_list,
&dir_ace_list, security_info_sent, psd);
/* Ignore W2K traverse DACL set. */
if (!file_ace_list && !dir_ace_list) {
- status = NT_STATUS_OK;
- goto out;
+ return NT_STATUS_OK;
}
if (!acl_perms) {
DEBUG(3,("set_nt_acl: cannot set permissions\n"));
free_canon_ace_list(file_ace_list);
free_canon_ace_list(dir_ace_list);
- status = NT_STATUS_ACCESS_DENIED;
- goto out;
+ return NT_STATUS_ACCESS_DENIED;
}
/*
@@ -3837,8 +3831,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
if(!(security_info_sent & DACL_SECURITY_INFORMATION) || (psd->dacl == NULL)) {
free_canon_ace_list(file_ace_list);
free_canon_ace_list(dir_ace_list);
- status = NT_STATUS_OK;
- goto out;
+ return NT_STATUS_OK;
}
/*
@@ -3851,18 +3844,17 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
become_root();
}
ret = set_canon_ace_list(fsp, file_ace_list, false,
- &smb_fname->st, &acl_set_support);
+ &fsp->fsp_name->st, &acl_set_support);
if (set_acl_as_root) {
unbecome_root();
}
if (acl_set_support && ret == false) {
DEBUG(3,("set_nt_acl: failed to set file acl on file "
- "%s (%s).\n", smb_fname_str_dbg(smb_fname),
+ "%s (%s).\n", fsp_str_dbg(fsp),
strerror(errno)));
free_canon_ace_list(file_ace_list);
free_canon_ace_list(dir_ace_list);
- status = map_nt_error_from_unix(errno);
- goto out;
+ return map_nt_error_from_unix(errno);
}
}
@@ -3872,7 +3864,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
become_root();
}
ret = set_canon_ace_list(fsp, dir_ace_list, true,
- &smb_fname->st,
+ &fsp->fsp_name->st,
&acl_set_support);
if (set_acl_as_root) {
unbecome_root();
@@ -3880,12 +3872,10 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
if (ret == false) {
DEBUG(3,("set_nt_acl: failed to set default "
"acl on directory %s (%s).\n",
- smb_fname_str_dbg(smb_fname),
- strerror(errno) ));
+ fsp_str_dbg(fsp), strerror(errno)));
free_canon_ace_list(file_ace_list);
free_canon_ace_list(dir_ace_list);
- status = map_nt_error_from_unix(errno);
- goto out;
+ return map_nt_error_from_unix(errno);
}
} else {
int sret = -1;
@@ -3898,23 +3888,23 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
become_root();
}
sret = SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn,
- smb_fname->base_name);
+ fsp->fsp_name->base_name);
if (set_acl_as_root) {
unbecome_root();
}
if (sret == -1) {
- if (acl_group_override(conn, smb_fname)) {
+ if (acl_group_override(conn, fsp->fsp_name)) {
DEBUG(5,("set_nt_acl: acl group "
"control on and current user "
"in file %s primary group. "
"Override delete_def_acl\n",
- smb_fname_str_dbg(smb_fname)));
+ fsp_str_dbg(fsp)));
become_root();
sret =
SMB_VFS_SYS_ACL_DELETE_DEF_FILE(
conn,
- smb_fname->base_name);
+ fsp->fsp_name->base_name);
unbecome_root();
}
@@ -3922,8 +3912,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
DEBUG(3,("set_nt_acl: sys_acl_delete_def_file failed (%s)\n", strerror(errno)));
free_canon_ace_list(file_ace_list);
free_canon_ace_list(dir_ace_list);
- status = map_nt_error_from_unix(errno);
- goto out;
+ return map_nt_error_from_unix(errno);
}
}
}
@@ -3954,52 +3943,48 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
free_canon_ace_list(dir_ace_list);
DEBUG(3,("set_nt_acl: failed to convert file acl to "
"posix permissions for file %s.\n",
- smb_fname_str_dbg(smb_fname)));
- status = NT_STATUS_ACCESS_DENIED;
- goto out;
+ fsp_str_dbg(fsp)));
+ return NT_STATUS_ACCESS_DENIED;
}
if (orig_mode != posix_perms) {
int sret = -1;
DEBUG(3,("set_nt_acl: chmod %s. perms = 0%o.\n",
- smb_fname_str_dbg(smb_fname),
- (unsigned int)posix_perms));
+ fsp_str_dbg(fsp), (unsigned int)posix_perms));
if (set_acl_as_root) {
become_root();
}
- sret = SMB_VFS_CHMOD(conn, smb_fname->base_name,
+ sret = SMB_VFS_CHMOD(conn, fsp->fsp_name->base_name,
posix_perms);
if (set_acl_as_root) {
unbecome_root();
}
if(sret == -1) {
- if (acl_group_override(conn, smb_fname)) {
+ if (acl_group_override(conn, fsp->fsp_name)) {
DEBUG(5,("set_nt_acl: acl group "
"control on and current user "
"in file %s primary group. "
"Override chmod\n",
- smb_fname_str_dbg(smb_fname)));
+ fsp_str_dbg(fsp)));
become_root();
- sret =
- SMB_VFS_CHMOD(conn,
- smb_fname->base_name,
- posix_perms);
+ sret = SMB_VFS_CHMOD(conn,
+ fsp->fsp_name->base_name,
+ posix_perms);
unbecome_root();
}
if (sret == -1) {
DEBUG(3,("set_nt_acl: chmod %s, 0%o "
"failed. Error = %s.\n",
- smb_fname_str_dbg(smb_fname),
+ fsp_str_dbg(fsp),
(unsigned int)posix_perms,
strerror(errno)));
free_canon_ace_list(file_ace_list);
free_canon_ace_list(dir_ace_list);
- status = map_nt_error_from_unix(errno);
- goto out;
+ return map_nt_error_from_unix(errno);
}
}
}
@@ -4008,10 +3993,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
free_canon_ace_list(file_ace_list);
free_canon_ace_list(dir_ace_list);
- status = NT_STATUS_OK;
- out:
- TALLOC_FREE(smb_fname);
- return status;
+ return NT_STATUS_OK;
}
/****************************************************************************
@@ -4614,6 +4596,7 @@ SEC_DESC *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname)
connection_struct *conn;
files_struct finfo;
struct fd_handle fh;
+ NTSTATUS status;
conn = TALLOC_ZERO_P(ctx, connection_struct);
if (conn == NULL) {
@@ -4644,16 +4627,24 @@ SEC_DESC *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname)
finfo.conn = conn;
finfo.fh = &fh;
finfo.fh->fd = -1;
- finfo.fsp_name = CONST_DISCARD(char *,fname);
+
+ status = create_synthetic_smb_fname(talloc_tos(), fname, NULL, NULL,
+ &finfo.fsp_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ conn_free_internal( conn );
+ return NULL;
+ }
if (!NT_STATUS_IS_OK(SMB_VFS_FGET_NT_ACL( &finfo, DACL_SECURITY_INFORMATION, &psd))) {
DEBUG(0,("get_nt_acl_no_snum: get_nt_acl returned zero.\n"));
+ TALLOC_FREE(finfo.fsp_name);
conn_free_internal( conn );
return NULL;
}
ret_sd = dup_sec_desc( ctx, psd );
+ TALLOC_FREE(finfo.fsp_name);
conn_free_internal( conn );
return ret_sd;
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index b26bc150db..c2065caf79 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -2015,11 +2015,6 @@ void smbd_process(void)
TALLOC_CTX *frame = talloc_stackframe();
char remaddr[INET6_ADDRSTRLEN];
- smbd_server_conn = talloc_zero(smbd_event_context(), struct smbd_server_connection);
- if (!smbd_server_conn) {
- exit_server("failed to create smbd_server_connection");
- }
-
if (lp_maxprotocol() == PROTOCOL_SMB2 &&
lp_security() != SEC_SHARE) {
smbd_server_conn->allow_smb2 = true;
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 1fd4e50ea6..76d32a2f98 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -856,6 +856,7 @@ void reply_tcon_and_X(struct smb_request *req)
END_PROFILE(SMBtconX);
+ req->tid = conn->cnum;
chain_reply(req);
return;
}
@@ -993,8 +994,7 @@ void reply_checkpath(struct smb_request *req)
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
name,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -1090,8 +1090,7 @@ void reply_getatr(struct smb_request *req)
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -1106,7 +1105,7 @@ void reply_getatr(struct smb_request *req)
DEBUG(3,("reply_getatr: stat of %s failed (%s)\n",
smb_fname_str_dbg(smb_fname),
strerror(errno)));
- reply_unixerror(req, ERRDOS,ERRbadfile);
+ reply_nterror(req, map_nt_error_from_unix(errno));
goto out;
}
@@ -1192,8 +1191,7 @@ void reply_setatr(struct smb_request *req)
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -1220,7 +1218,7 @@ void reply_setatr(struct smb_request *req)
ft.mtime = convert_time_t_to_timespec(mtime);
status = smb_set_file_time(conn, NULL, smb_fname, &ft, true);
if (!NT_STATUS_IS_OK(status)) {
- reply_unixerror(req, ERRDOS, ERRnoaccess);
+ reply_nterror(req, status);
goto out;
}
@@ -1232,7 +1230,7 @@ void reply_setatr(struct smb_request *req)
if (file_set_dosmode(conn, smb_fname, mode, NULL,
false) != 0) {
- reply_unixerror(req, ERRDOS, ERRnoaccess);
+ reply_nterror(req, map_nt_error_from_unix(errno));
goto out;
}
}
@@ -1258,7 +1256,7 @@ void reply_dskattr(struct smb_request *req)
START_PROFILE(SMBdskattr);
if (get_dfree_info(conn,".",True,&bsize,&dfree,&dsize) == (uint64_t)-1) {
- reply_unixerror(req, ERRHRD, ERRgeneral);
+ reply_nterror(req, map_nt_error_from_unix(errno));
END_PROFILE(SMBdskattr);
return;
}
@@ -1342,6 +1340,7 @@ void reply_search(struct smb_request *req)
char *path = NULL;
const char *mask = NULL;
char *directory = NULL;
+ struct smb_filename *smb_fname = NULL;
char *fname = NULL;
SMB_OFF_T size;
uint32 mode;
@@ -1366,14 +1365,12 @@ void reply_search(struct smb_request *req)
if (req->wct < 2) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
if (lp_posix_pathnames()) {
reply_unknown_new(req, req->cmd);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
/* If we were called as SMBffirst then we must expect close. */
@@ -1389,8 +1386,7 @@ void reply_search(struct smb_request *req)
&nt_status, &mask_contains_wcard);
if (!NT_STATUS_IS_OK(nt_status)) {
reply_nterror(req, nt_status);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
p++;
@@ -1400,8 +1396,6 @@ void reply_search(struct smb_request *req)
/* dirtype &= ~aDIR; */
if (status_len == 0) {
- struct smb_filename *smb_fname = NULL;
-
nt_status = resolve_dfspath_wcard(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
path,
@@ -1411,35 +1405,25 @@ void reply_search(struct smb_request *req)
if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
ERRSRV, ERRbadpath);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
reply_nterror(req, nt_status);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
nt_status = unix_convert(ctx, conn, path, &smb_fname,
UCF_ALLOW_WCARD_LCOMP);
if (!NT_STATUS_IS_OK(nt_status)) {
reply_nterror(req, nt_status);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
- nt_status = get_full_smb_filename(ctx, smb_fname, &directory);
- TALLOC_FREE(smb_fname);
- if (!NT_STATUS_IS_OK(nt_status)) {
- reply_nterror(req, nt_status);
- END_PROFILE(SMBsearch);
- return;
- }
+ directory = smb_fname->base_name;
nt_status = check_name(conn, directory);
if (!NT_STATUS_IS_OK(nt_status)) {
reply_nterror(req, nt_status);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
p = strrchr_m(directory,'/');
@@ -1454,8 +1438,7 @@ void reply_search(struct smb_request *req)
if (!directory) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
memset((char *)status,'\0',21);
@@ -1472,8 +1455,7 @@ void reply_search(struct smb_request *req)
&conn->dirptr);
if (!NT_STATUS_IS_OK(nt_status)) {
reply_nterror(req, nt_status);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
dptr_num = dptr_dnum(conn->dirptr);
} else {
@@ -1513,8 +1495,7 @@ void reply_search(struct smb_request *req)
if (!make_dir_struct(ctx,buf,"???????????",volume_label(SNUM(conn)),
0,aVOLID,0,!allow_long_path_components)) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
dptr_fill(buf+12,dptr_num);
if (dptr_zero(buf+12) && (status_len==0)) {
@@ -1526,8 +1507,7 @@ void reply_search(struct smb_request *req)
data_blob_const(buf, sizeof(buf)))
== -1) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
} else {
unsigned int i;
@@ -1566,8 +1546,7 @@ void reply_search(struct smb_request *req)
convert_timespec_to_time_t(date),
!allow_long_path_components)) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
if (!dptr_fill(buf+12,dptr_num)) {
break;
@@ -1576,8 +1555,7 @@ void reply_search(struct smb_request *req)
data_blob_const(buf, sizeof(buf)))
== -1) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
numentries++;
}
@@ -1604,8 +1582,7 @@ void reply_search(struct smb_request *req)
if ((numentries == 0) && !mask_contains_wcard) {
reply_botherror(req, STATUS_NO_MORE_FILES, ERRDOS, ERRnofiles);
- END_PROFILE(SMBsearch);
- return;
+ goto out;
}
SSVAL(req->outbuf,smb_vwv0,numentries);
@@ -1637,7 +1614,8 @@ void reply_search(struct smb_request *req)
dirtype,
numentries,
maxentries ));
-
+ out:
+ TALLOC_FREE(smb_fname);
END_PROFILE(SMBsearch);
return;
}
@@ -1746,8 +1724,7 @@ void reply_open(struct smb_request *req)
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req,
@@ -1759,10 +1736,10 @@ void reply_open(struct smb_request *req)
goto out;
}
- if (!map_open_params_to_ntcreate(
- smb_fname->base_name, deny_mode, OPENX_FILE_EXISTS_OPEN,
- &access_mask, &share_mode, &create_disposition,
- &create_options)) {
+ if (!map_open_params_to_ntcreate(smb_fname, deny_mode,
+ OPENX_FILE_EXISTS_OPEN, &access_mask,
+ &share_mode, &create_disposition,
+ &create_options)) {
reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
goto out;
}
@@ -1811,7 +1788,8 @@ void reply_open(struct smb_request *req)
mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
if (fattr & aDIR) {
- DEBUG(3,("attempt to open a directory %s\n",fsp->fsp_name));
+ DEBUG(3,("attempt to open a directory %s\n",
+ fsp_str_dbg(fsp)));
close_file(req, fsp, ERROR_CLOSE);
reply_doserror(req, ERRDOS,ERRnoaccess);
goto out;
@@ -1916,8 +1894,7 @@ void reply_open_and_X(struct smb_request *req)
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req,
@@ -1929,9 +1906,10 @@ void reply_open_and_X(struct smb_request *req)
goto out;
}
- if (!map_open_params_to_ntcreate(
- smb_fname->base_name, deny_mode, smb_ofun, &access_mask,
- &share_mode, &create_disposition, &create_options)) {
+ if (!map_open_params_to_ntcreate(smb_fname, deny_mode, smb_ofun,
+ &access_mask, &share_mode,
+ &create_disposition,
+ &create_options)) {
reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
goto out;
}
@@ -2076,6 +2054,7 @@ void reply_ulogoffX(struct smb_request *req)
DEBUG( 3, ( "ulogoffX vuid=%d\n", req->vuid ) );
END_PROFILE(SMBulogoffX);
+ req->vuid = UID_FIELD_INVALID;
chain_reply(req);
}
@@ -2124,8 +2103,7 @@ void reply_mknew(struct smb_request *req)
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req,
@@ -2257,8 +2235,7 @@ void reply_ctemp(struct smb_request *req)
status = filename_convert(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -2271,7 +2248,7 @@ void reply_ctemp(struct smb_request *req)
tmpfd = mkstemp(smb_fname->base_name);
if (tmpfd == -1) {
- reply_unixerror(req, ERRDOS, ERRnoaccess);
+ reply_nterror(req, map_nt_error_from_unix(errno));
goto out;
}
@@ -2311,9 +2288,9 @@ void reply_ctemp(struct smb_request *req)
SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
/* the returned filename is relative to the directory */
- s = strrchr_m(fsp->fsp_name, '/');
+ s = strrchr_m(fsp->fsp_name->base_name, '/');
if (!s) {
- s = fsp->fsp_name;
+ s = fsp->fsp_name->base_name;
} else {
s++;
}
@@ -2339,8 +2316,8 @@ void reply_ctemp(struct smb_request *req)
CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
}
- DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fsp->fsp_name ) );
- DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fsp->fsp_name,
+ DEBUG(2, ("reply_ctemp: created temp file %s\n", fsp_str_dbg(fsp)));
+ DEBUG(3, ("reply_ctemp %s fd=%d umode=0%o\n", fsp_str_dbg(fsp),
fsp->fh->fd, (unsigned int)smb_fname->st.st_ex_mode));
out:
TALLOC_FREE(smb_fname);
@@ -2355,22 +2332,13 @@ void reply_ctemp(struct smb_request *req)
static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp,
uint16 dirtype, SMB_STRUCT_STAT *pst)
{
- struct smb_filename *smb_fname = NULL;
- NTSTATUS status;
uint32 fmode;
if (!CAN_WRITE(conn)) {
return NT_STATUS_MEDIA_WRITE_PROTECTED;
}
- status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
- pst, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- fmode = dos_mode(conn, smb_fname);
- TALLOC_FREE(smb_fname);
+ fmode = dos_mode(conn, fsp->fsp_name);
if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) {
return NT_STATUS_NO_SUCH_FILE;
}
@@ -2646,18 +2614,23 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
while ((dname = ReadDirName(dir_hnd, &offset,
&smb_fname->st))) {
+ TALLOC_CTX *frame = talloc_stackframe();
+
if (!is_visible_file(conn, fname_dir, dname,
&smb_fname->st, true)) {
+ TALLOC_FREE(frame);
continue;
}
/* Quick check for "." and ".." */
if (ISDOT(dname) || ISDOTDOT(dname)) {
+ TALLOC_FREE(frame);
continue;
}
if(!mask_match(dname, fname_mask,
conn->case_sensitive)) {
+ TALLOC_FREE(frame);
continue;
}
@@ -2669,23 +2642,28 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
if (!smb_fname->base_name) {
TALLOC_FREE(dir_hnd);
status = NT_STATUS_NO_MEMORY;
+ TALLOC_FREE(frame);
goto out;
}
status = check_name(conn, smb_fname->base_name);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(dir_hnd);
+ TALLOC_FREE(frame);
goto out;
}
status = do_unlink(conn, req, smb_fname, dirtype);
if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(frame);
continue;
}
count++;
DEBUG(3,("unlink_internals: successful unlink [%s]\n",
smb_fname->base_name));
+
+ TALLOC_FREE(frame);
}
TALLOC_FREE(dir_hnd);
}
@@ -2854,7 +2832,7 @@ static void sendfile_short_send(files_struct *fsp,
if (nread < headersize) {
DEBUG(0,("sendfile_short_send: sendfile failed to send "
"header for file %s (%s). Terminating\n",
- fsp->fsp_name, strerror(errno) ));
+ fsp_str_dbg(fsp), strerror(errno)));
exit_server_cleanly("sendfile_short_send failed");
}
@@ -2868,7 +2846,7 @@ static void sendfile_short_send(files_struct *fsp,
}
DEBUG(0,("sendfile_short_send: filling truncated file %s "
- "with zeros !\n", fsp->fsp_name));
+ "with zeros !\n", fsp_str_dbg(fsp)));
while (nread < smb_maxcnt) {
/*
@@ -2963,15 +2941,19 @@ static void send_file_readbraw(connection_struct *conn,
DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
if (fake_sendfile(fsp, startpos, nread) == -1) {
- DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n",
- fsp->fsp_name, strerror(errno) ));
+ DEBUG(0,("send_file_readbraw: "
+ "fake_sendfile failed for "
+ "file %s (%s).\n",
+ fsp_str_dbg(fsp),
+ strerror(errno)));
exit_server_cleanly("send_file_readbraw fake_sendfile failed");
}
return;
}
- DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
- fsp->fsp_name, strerror(errno) ));
+ DEBUG(0,("send_file_readbraw: sendfile failed for "
+ "file %s (%s). Terminating\n",
+ fsp_str_dbg(fsp), strerror(errno)));
exit_server_cleanly("send_file_readbraw sendfile failed");
} else if (sendfile_read == 0) {
/*
@@ -2983,7 +2965,7 @@ static void send_file_readbraw(connection_struct *conn,
*/
DEBUG(3, ("send_file_readbraw: sendfile sent zero "
"bytes falling back to the normal read: "
- "%s\n", fsp->fsp_name));
+ "%s\n", fsp_str_dbg(fsp)));
goto normal_readbraw;
}
@@ -3269,7 +3251,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
nread = read_file(fsp,data,startpos,numtoread);
if (nread < 0) {
- reply_unixerror(req, ERRDOS, ERRnoaccess);
+ reply_nterror(req, map_nt_error_from_unix(errno));
END_PROFILE(SMBlockread);
return;
}
@@ -3363,7 +3345,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
nread = read_file(fsp,data,startpos,numtoread);
if (nread < 0) {
- reply_unixerror(req, ERRDOS,ERRnoaccess);
+ reply_nterror(req, map_nt_error_from_unix(errno));
goto strict_unlock;
}
@@ -3425,9 +3407,10 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
SMB_STRUCT_STAT sbuf;
ssize_t nread = -1;
struct lock_struct lock;
+ int saved_errno = 0;
if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
- reply_unixerror(req, ERRDOS, ERRnoaccess);
+ reply_nterror(req, map_nt_error_from_unix(errno));
return;
}
@@ -3494,8 +3477,11 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
nread = fake_sendfile(fsp, startpos,
smb_maxcnt);
if (nread == -1) {
- DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
- fsp->fsp_name, strerror(errno) ));
+ DEBUG(0,("send_file_readX: "
+ "fake_sendfile failed for "
+ "file %s (%s).\n",
+ fsp_str_dbg(fsp),
+ strerror(errno)));
exit_server_cleanly("send_file_readX: fake_sendfile failed");
}
DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n",
@@ -3504,8 +3490,9 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
goto strict_unlock;
}
- DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
- fsp->fsp_name, strerror(errno) ));
+ DEBUG(0,("send_file_readX: sendfile failed for file "
+ "%s (%s). Terminating\n", fsp_str_dbg(fsp),
+ strerror(errno)));
exit_server_cleanly("send_file_readX sendfile failed");
} else if (nread == 0) {
/*
@@ -3517,7 +3504,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
*/
DEBUG(3, ("send_file_readX: sendfile sent zero bytes "
"falling back to the normal read: %s\n",
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
goto normal_read;
}
@@ -3547,14 +3534,16 @@ normal_read:
/* Send out the header. */
if (write_data(smbd_server_fd(), (char *)headerbuf,
sizeof(headerbuf)) != sizeof(headerbuf)) {
- DEBUG(0,("send_file_readX: write_data failed for file %s (%s). Terminating\n",
- fsp->fsp_name, strerror(errno) ));
+ DEBUG(0,("send_file_readX: write_data failed for file "
+ "%s (%s). Terminating\n", fsp_str_dbg(fsp),
+ strerror(errno)));
exit_server_cleanly("send_file_readX sendfile failed");
}
nread = fake_sendfile(fsp, startpos, smb_maxcnt);
if (nread == -1) {
- DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
- fsp->fsp_name, strerror(errno) ));
+ DEBUG(0,("send_file_readX: fake_sendfile failed for "
+ "file %s (%s).\n", fsp_str_dbg(fsp),
+ strerror(errno)));
exit_server_cleanly("send_file_readX: fake_sendfile failed");
}
goto strict_unlock;
@@ -3565,11 +3554,12 @@ nosendfile_read:
reply_outbuf(req, 12, smb_maxcnt);
nread = read_file(fsp, smb_buf(req->outbuf), startpos, smb_maxcnt);
+ saved_errno = errno;
SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
if (nread < 0) {
- reply_unixerror(req, ERRDOS, ERRnoaccess);
+ reply_nterror(req, map_nt_error_from_unix(saved_errno));
return;
}
@@ -3810,7 +3800,7 @@ void reply_writebraw(struct smb_request *req)
(int)nwritten, (int)write_through));
if (nwritten < (ssize_t)numtowrite) {
- reply_unixerror(req, ERRHRD, ERRdiskfull);
+ reply_doserror(req, ERRHRD, ERRdiskfull);
error_to_writebrawerr(req);
goto strict_unlock;
}
@@ -3879,7 +3869,7 @@ void reply_writebraw(struct smb_request *req)
nwritten = write_file(req,fsp,buf+4,startpos+nwritten,numtowrite);
if (nwritten == -1) {
TALLOC_FREE(buf);
- reply_unixerror(req, ERRHRD, ERRdiskfull);
+ reply_nterror(req, map_nt_error_from_unix(errno));
error_to_writebrawerr(req);
goto strict_unlock;
}
@@ -3900,7 +3890,7 @@ void reply_writebraw(struct smb_request *req)
status = sync_file(conn, fsp, write_through);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5,("reply_writebraw: sync_file for %s returned %s\n",
- fsp->fsp_name, nt_errstr(status) ));
+ fsp_str_dbg(fsp), nt_errstr(status)));
reply_nterror(req, status);
error_to_writebrawerr(req);
goto strict_unlock;
@@ -3958,6 +3948,7 @@ void reply_writeunlock(struct smb_request *req)
NTSTATUS status = NT_STATUS_OK;
files_struct *fsp;
struct lock_struct lock;
+ int saved_errno = 0;
START_PROFILE(SMBwriteunlock);
@@ -4003,18 +3994,24 @@ void reply_writeunlock(struct smb_request *req)
nwritten = 0;
} else {
nwritten = write_file(req,fsp,data,startpos,numtowrite);
+ saved_errno = errno;
}
status = sync_file(conn, fsp, False /* write through */);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n",
- fsp->fsp_name, nt_errstr(status) ));
+ fsp_str_dbg(fsp), nt_errstr(status)));
reply_nterror(req, status);
goto strict_unlock;
}
- if(((nwritten < numtowrite) && (numtowrite != 0))||(nwritten < 0)) {
- reply_unixerror(req, ERRHRD, ERRdiskfull);
+ if(nwritten < 0) {
+ reply_nterror(req, map_nt_error_from_unix(saved_errno));
+ goto strict_unlock;
+ }
+
+ if((nwritten < numtowrite) && (numtowrite != 0)) {
+ reply_doserror(req, ERRHRD, ERRdiskfull);
goto strict_unlock;
}
@@ -4065,6 +4062,7 @@ void reply_write(struct smb_request *req)
files_struct *fsp;
struct lock_struct lock;
NTSTATUS status;
+ int saved_errno = 0;
START_PROFILE(SMBwrite);
@@ -4136,13 +4134,18 @@ void reply_write(struct smb_request *req)
status = sync_file(conn, fsp, False);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5,("reply_write: sync_file for %s returned %s\n",
- fsp->fsp_name, nt_errstr(status) ));
+ fsp_str_dbg(fsp), nt_errstr(status)));
reply_nterror(req, status);
goto strict_unlock;
}
- if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
- reply_unixerror(req, ERRHRD, ERRdiskfull);
+ if(nwritten < 0) {
+ reply_nterror(req, map_nt_error_from_unix(saved_errno));
+ goto strict_unlock;
+ }
+
+ if((nwritten == 0) && (numtowrite != 0)) {
+ reply_doserror(req, ERRHRD, ERRdiskfull);
goto strict_unlock;
}
@@ -4389,8 +4392,13 @@ void reply_write_and_X(struct smb_request *req)
nwritten = write_file(req,fsp,data,startpos,numtowrite);
}
- if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
- reply_unixerror(req, ERRHRD, ERRdiskfull);
+ if(nwritten < 0) {
+ reply_nterror(req, map_nt_error_from_unix(errno));
+ goto strict_unlock;
+ }
+
+ if((nwritten == 0) && (numtowrite != 0)) {
+ reply_doserror(req, ERRHRD, ERRdiskfull);
goto strict_unlock;
}
@@ -4409,7 +4417,7 @@ void reply_write_and_X(struct smb_request *req)
status = sync_file(conn, fsp, write_through);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5,("reply_write_and_X: sync_file for %s returned %s\n",
- fsp->fsp_name, nt_errstr(status) ));
+ fsp_str_dbg(fsp), nt_errstr(status)));
reply_nterror(req, status);
goto strict_unlock;
}
@@ -4484,8 +4492,8 @@ void reply_lseek(struct smb_request *req)
SMB_STRUCT_STAT sbuf;
if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
- reply_unixerror(req, ERRDOS,
- ERRnoaccess);
+ reply_nterror(req,
+ map_nt_error_from_unix(errno));
END_PROFILE(SMBlseek);
return;
}
@@ -4497,7 +4505,7 @@ void reply_lseek(struct smb_request *req)
}
if(res == -1) {
- reply_unixerror(req, ERRDOS, ERRnoaccess);
+ reply_nterror(req, map_nt_error_from_unix(errno));
END_PROFILE(SMBlseek);
return;
}
@@ -4545,7 +4553,7 @@ void reply_flush(struct smb_request *req)
NTSTATUS status = sync_file(conn, fsp, True);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5,("reply_flush: sync_file for %s returned %s\n",
- fsp->fsp_name, nt_errstr(status) ));
+ fsp_str_dbg(fsp), nt_errstr(status)));
reply_nterror(req, status);
END_PROFILE(SMBflush);
return;
@@ -4713,8 +4721,8 @@ void reply_writeclose(struct smb_request *req)
*/
if (numtowrite) {
- DEBUG(3,("reply_writeclose: zero length write doesn't close file %s\n",
- fsp->fsp_name ));
+ DEBUG(3,("reply_writeclose: zero length write doesn't close "
+ "file %s\n", fsp_str_dbg(fsp)));
close_status = close_file(req, fsp, NORMAL_CLOSE);
}
@@ -5197,7 +5205,7 @@ void reply_printwrite(struct smb_request *req)
data = (const char *)req->buf + 3;
if (write_file(req,fsp,data,-1,numtowrite) != numtowrite) {
- reply_unixerror(req, ERRHRD, ERRdiskfull);
+ reply_nterror(req, map_nt_error_from_unix(errno));
END_PROFILE(SMBsplwr);
return;
}
@@ -5232,8 +5240,7 @@ void reply_mkdir(struct smb_request *req)
status = filename_convert(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
directory,
- &smb_dname,
- NULL);
+ &smb_dname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -5540,8 +5547,7 @@ void reply_rmdir(struct smb_request *req)
status = filename_convert(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
directory,
- &smb_dname,
- NULL);
+ &smb_dname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -5711,7 +5717,6 @@ static void rename_open_files(connection_struct *conn,
{
files_struct *fsp;
bool did_rename = False;
- char *fname_dst = NULL;
NTSTATUS status;
for(fsp = file_find_di_first(lck->id); fsp;
@@ -5725,17 +5730,13 @@ static void rename_open_files(connection_struct *conn,
}
DEBUG(10, ("rename_open_files: renaming file fnum %d "
"(file_id %s) from %s -> %s\n", fsp->fnum,
- file_id_string_tos(&fsp->file_id), fsp->fsp_name,
+ file_id_string_tos(&fsp->file_id), fsp_str_dbg(fsp),
smb_fname_str_dbg(smb_fname_dst)));
- status = get_full_smb_filename(talloc_tos(), smb_fname_dst,
- &fname_dst);
- if (!NT_STATUS_IS_OK(status)) {
- return;
+ status = fsp_set_smb_fname(fsp, smb_fname_dst);
+ if (NT_STATUS_IS_OK(status)) {
+ did_rename = True;
}
- string_set(&fsp->fsp_name, fname_dst);
- did_rename = True;
- TALLOC_FREE(fname_dst);
}
if (!did_rename) {
@@ -5790,9 +5791,6 @@ static void notify_rename(connection_struct *conn, bool is_dir,
{
char *parent_dir_src = NULL;
char *parent_dir_dst = NULL;
- char *fname_src = NULL;
- char *fname_dst = NULL;
- NTSTATUS status;
uint32 mask;
mask = is_dir ? FILE_NOTIFY_CHANGE_DIR_NAME
@@ -5805,24 +5803,17 @@ static void notify_rename(connection_struct *conn, bool is_dir,
goto out;
}
- status = get_full_smb_filename(talloc_tos(), smb_fname_src,
- &fname_src);
- if (!NT_STATUS_IS_OK(status)) {
- goto out;
- }
- status = get_full_smb_filename(talloc_tos(), smb_fname_dst,
- &fname_dst);
- if (!NT_STATUS_IS_OK(status)) {
- goto out;
- }
-
if (strcmp(parent_dir_src, parent_dir_dst) == 0) {
- notify_fname(conn, NOTIFY_ACTION_OLD_NAME, mask, fname_src);
- notify_fname(conn, NOTIFY_ACTION_NEW_NAME, mask, fname_dst);
+ notify_fname(conn, NOTIFY_ACTION_OLD_NAME, mask,
+ smb_fname_src->base_name);
+ notify_fname(conn, NOTIFY_ACTION_NEW_NAME, mask,
+ smb_fname_dst->base_name);
}
else {
- notify_fname(conn, NOTIFY_ACTION_REMOVED, mask, fname_src);
- notify_fname(conn, NOTIFY_ACTION_ADDED, mask, fname_dst);
+ notify_fname(conn, NOTIFY_ACTION_REMOVED, mask,
+ smb_fname_src->base_name);
+ notify_fname(conn, NOTIFY_ACTION_ADDED, mask,
+ smb_fname_dst->base_name);
}
/* this is a strange one. w2k3 gives an additional event for
@@ -5832,13 +5823,11 @@ static void notify_rename(connection_struct *conn, bool is_dir,
notify_fname(conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES
|FILE_NOTIFY_CHANGE_CREATION,
- fname_dst);
+ smb_fname_dst->base_name);
}
out:
TALLOC_FREE(parent_dir_src);
TALLOC_FREE(parent_dir_dst);
- TALLOC_FREE(fname_src);
- TALLOC_FREE(fname_dst);
}
/****************************************************************************
@@ -5867,17 +5856,12 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
}
/* Make a copy of the src and dst smb_fname structs */
- status = copy_smb_filename(ctx, smb_fname_dst_in, &smb_fname_dst);
+ status = copy_smb_filename(ctx, fsp->fsp_name, &smb_fname_src);
if (!NT_STATUS_IS_OK(status)) {
goto out;
}
- /*
- * This will be replaced with copy_smb_filename() when fsp->fsp_name
- * is converted to store an smb_filename struct.
- */
- status = create_synthetic_smb_fname_split(ctx, fsp->fsp_name, NULL,
- &smb_fname_src);
+ status = copy_smb_filename(ctx, smb_fname_dst_in, &smb_fname_dst);
if (!NT_STATUS_IS_OK(status)) {
goto out;
}
@@ -6635,8 +6619,8 @@ NTSTATUS copy_file(TALLOC_CTX *ctx,
if (!target_is_directory && count) {
new_create_disposition = FILE_OPEN;
} else {
- if (!map_open_params_to_ntcreate(smb_fname_dst_tmp->base_name,
- 0, ofun, NULL, NULL,
+ if (!map_open_params_to_ntcreate(smb_fname_dst_tmp, 0, ofun,
+ NULL, NULL,
&new_create_disposition,
NULL)) {
status = NT_STATUS_INVALID_PARAMETER;
@@ -6756,7 +6740,6 @@ void reply_copy(struct smb_request *req)
const char *p;
int count=0;
int error = ERRnoaccess;
- int err = 0;
int tid2;
int ofun;
int flags;
@@ -7059,13 +7042,6 @@ void reply_copy(struct smb_request *req)
}
if (count == 0) {
- if(err) {
- /* Error on close... */
- errno = err;
- reply_unixerror(req, ERRHRD, ERRgeneral);
- goto out;
- }
-
reply_doserror(req, ERRDOS, error);
goto out;
}
@@ -7223,6 +7199,205 @@ uint64_t get_lock_offset(const uint8_t *data, int data_offset,
return offset;
}
+NTSTATUS smbd_do_locking(struct smb_request *req,
+ files_struct *fsp,
+ uint8_t type,
+ int32_t timeout,
+ uint16_t num_ulocks,
+ struct smbd_lock_element *ulocks,
+ uint16_t num_locks,
+ struct smbd_lock_element *locks,
+ bool *async)
+{
+ connection_struct *conn = req->conn;
+ int i;
+ NTSTATUS status = NT_STATUS_OK;
+
+ *async = false;
+
+ /* Data now points at the beginning of the list
+ of smb_unlkrng structs */
+ for(i = 0; i < (int)num_ulocks; i++) {
+ struct smbd_lock_element *e = &ulocks[i];
+
+ DEBUG(10,("smbd_do_locking: unlock start=%.0f, len=%.0f for "
+ "pid %u, file %s\n",
+ (double)e->offset,
+ (double)e->count,
+ (unsigned int)e->smbpid,
+ fsp_str_dbg(fsp)));
+
+ if (e->brltype != UNLOCK_LOCK) {
+ /* this can only happen with SMB2 */
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ status = do_unlock(smbd_messaging_context(),
+ fsp,
+ e->smbpid,
+ e->count,
+ e->offset,
+ WINDOWS_LOCK);
+
+ DEBUG(10, ("smbd_do_locking: unlock returned %s\n",
+ nt_errstr(status)));
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ }
+
+ /* Setup the timeout in seconds. */
+
+ if (!lp_blocking_locks(SNUM(conn))) {
+ timeout = 0;
+ }
+
+ /* Data now points at the beginning of the list
+ of smb_lkrng structs */
+
+ for(i = 0; i < (int)num_locks; i++) {
+ struct smbd_lock_element *e = &locks[i];
+
+ DEBUG(10,("smbd_do_locking: lock start=%.0f, len=%.0f for pid "
+ "%u, file %s timeout = %d\n",
+ (double)e->offset,
+ (double)e->count,
+ (unsigned int)e->smbpid,
+ fsp_str_dbg(fsp),
+ (int)timeout));
+
+ if (type & LOCKING_ANDX_CANCEL_LOCK) {
+ struct blocking_lock_record *blr = NULL;
+
+ if (lp_blocking_locks(SNUM(conn))) {
+
+ /* Schedule a message to ourselves to
+ remove the blocking lock record and
+ return the right error. */
+
+ blr = blocking_lock_cancel(fsp,
+ e->smbpid,
+ e->offset,
+ e->count,
+ WINDOWS_LOCK,
+ type,
+ NT_STATUS_FILE_LOCK_CONFLICT);
+ if (blr == NULL) {
+ return NT_STATUS_DOS(
+ ERRDOS,
+ ERRcancelviolation);
+ }
+ }
+ /* Remove a matching pending lock. */
+ status = do_lock_cancel(fsp,
+ e->smbpid,
+ e->count,
+ e->offset,
+ WINDOWS_LOCK,
+ blr);
+ } else {
+ bool blocking_lock = timeout ? true : false;
+ bool defer_lock = false;
+ struct byte_range_lock *br_lck;
+ uint32_t block_smbpid;
+
+ br_lck = do_lock(smbd_messaging_context(),
+ fsp,
+ e->smbpid,
+ e->count,
+ e->offset,
+ e->brltype,
+ WINDOWS_LOCK,
+ blocking_lock,
+ &status,
+ &block_smbpid,
+ NULL);
+
+ if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
+ /* Windows internal resolution for blocking locks seems
+ to be about 200ms... Don't wait for less than that. JRA. */
+ if (timeout != -1 && timeout < lp_lock_spin_time()) {
+ timeout = lp_lock_spin_time();
+ }
+ defer_lock = true;
+ }
+
+ /* This heuristic seems to match W2K3 very well. If a
+ lock sent with timeout of zero would fail with NT_STATUS_FILE_LOCK_CONFLICT
+ it pretends we asked for a timeout of between 150 - 300 milliseconds as
+ far as I can tell. Replacement for do_lock_spin(). JRA. */
+
+ if (br_lck && lp_blocking_locks(SNUM(conn)) && !blocking_lock &&
+ NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT)) {
+ defer_lock = true;
+ timeout = lp_lock_spin_time();
+ }
+
+ if (br_lck && defer_lock) {
+ /*
+ * A blocking lock was requested. Package up
+ * this smb into a queued request and push it
+ * onto the blocking lock queue.
+ */
+ if(push_blocking_lock_request(br_lck,
+ req,
+ fsp,
+ timeout,
+ i,
+ e->smbpid,
+ e->brltype,
+ WINDOWS_LOCK,
+ e->offset,
+ e->count,
+ block_smbpid)) {
+ TALLOC_FREE(br_lck);
+ *async = true;
+ return NT_STATUS_OK;
+ }
+ }
+
+ TALLOC_FREE(br_lck);
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ break;
+ }
+ }
+
+ /* If any of the above locks failed, then we must unlock
+ all of the previous locks (X/Open spec). */
+
+ if (num_locks != 0 && !NT_STATUS_IS_OK(status)) {
+
+ if (type & LOCKING_ANDX_CANCEL_LOCK) {
+ i = -1; /* we want to skip the for loop */
+ }
+
+ /*
+ * Ensure we don't do a remove on the lock that just failed,
+ * as under POSIX rules, if we have a lock already there, we
+ * will delete it (and we shouldn't) .....
+ */
+ for(i--; i >= 0; i--) {
+ struct smbd_lock_element *e = &locks[i];
+
+ do_unlock(smbd_messaging_context(),
+ fsp,
+ e->smbpid,
+ e->count,
+ e->offset,
+ WINDOWS_LOCK);
+ }
+ return status;
+ }
+
+ DEBUG(3, ("smbd_do_locking: fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
+ fsp->fnum, (unsigned int)type, num_locks, num_ulocks));
+
+ return NT_STATUS_OK;
+}
+
/****************************************************************************
Reply to a lockingX request.
****************************************************************************/
@@ -7235,14 +7410,15 @@ void reply_lockingX(struct smb_request *req)
unsigned char oplocklevel;
uint16 num_ulocks;
uint16 num_locks;
- uint64_t count = 0, offset = 0;
- uint32 lock_pid;
int32 lock_timeout;
int i;
const uint8_t *data;
bool large_file_format;
bool err;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
+ struct smbd_lock_element *ulocks;
+ struct smbd_lock_element *locks;
+ bool async = false;
START_PROFILE(SMBlockingX);
@@ -7304,7 +7480,8 @@ void reply_lockingX(struct smb_request *req)
DEBUG(5,("reply_lockingX: Error : oplock break from "
"client for fnum = %d (oplock=%d) and no "
"oplock granted on this file (%s).\n",
- fsp->fnum, fsp->oplock_type, fsp->fsp_name));
+ fsp->fnum, fsp->oplock_type,
+ fsp_str_dbg(fsp)));
/* if this is a pure oplock break request then don't
* send a reply */
@@ -7327,7 +7504,7 @@ void reply_lockingX(struct smb_request *req)
if (!result) {
DEBUG(0, ("reply_lockingX: error in removing "
- "oplock on file %s\n", fsp->fsp_name));
+ "oplock on file %s\n", fsp_str_dbg(fsp)));
/* Hmmm. Is this panic justified? */
smb_panic("internal tdb error");
}
@@ -7355,12 +7532,27 @@ void reply_lockingX(struct smb_request *req)
return;
}
+ ulocks = talloc_array(req, struct smbd_lock_element, num_ulocks);
+ if (ulocks == NULL) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ END_PROFILE(SMBlockingX);
+ return;
+ }
+
+ locks = talloc_array(req, struct smbd_lock_element, num_locks);
+ if (locks == NULL) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ END_PROFILE(SMBlockingX);
+ return;
+ }
+
/* Data now points at the beginning of the list
of smb_unlkrng structs */
for(i = 0; i < (int)num_ulocks; i++) {
- lock_pid = get_lock_pid( data, i, large_file_format);
- count = get_lock_count( data, i, large_file_format);
- offset = get_lock_offset( data, i, large_file_format, &err);
+ ulocks[i].smbpid = get_lock_pid(data, i, large_file_format);
+ ulocks[i].count = get_lock_count(data, i, large_file_format);
+ ulocks[i].offset = get_lock_offset(data, i, large_file_format, &err);
+ ulocks[i].brltype = UNLOCK_LOCK;
/*
* There is no error code marked "stupid client bug".... :-).
@@ -7370,32 +7562,6 @@ void reply_lockingX(struct smb_request *req)
reply_doserror(req, ERRDOS, ERRnoaccess);
return;
}
-
- DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for "
- "pid %u, file %s\n", (double)offset, (double)count,
- (unsigned int)lock_pid, fsp->fsp_name ));
-
- status = do_unlock(smbd_messaging_context(),
- fsp,
- lock_pid,
- count,
- offset,
- WINDOWS_LOCK);
-
- DEBUG(10, ("reply_lockingX: unlock returned %s\n",
- nt_errstr(status)));
-
- if (NT_STATUS_V(status)) {
- END_PROFILE(SMBlockingX);
- reply_nterror(req, status);
- return;
- }
- }
-
- /* Setup the timeout in seconds. */
-
- if (!lp_blocking_locks(SNUM(conn))) {
- lock_timeout = 0;
}
/* Now do any requested locks */
@@ -7405,11 +7571,23 @@ void reply_lockingX(struct smb_request *req)
of smb_lkrng structs */
for(i = 0; i < (int)num_locks; i++) {
- enum brl_type lock_type = ((locktype & LOCKING_ANDX_SHARED_LOCK) ?
- READ_LOCK:WRITE_LOCK);
- lock_pid = get_lock_pid( data, i, large_file_format);
- count = get_lock_count( data, i, large_file_format);
- offset = get_lock_offset( data, i, large_file_format, &err);
+ locks[i].smbpid = get_lock_pid(data, i, large_file_format);
+ locks[i].count = get_lock_count(data, i, large_file_format);
+ locks[i].offset = get_lock_offset(data, i, large_file_format, &err);
+
+ if (locktype & LOCKING_ANDX_SHARED_LOCK) {
+ if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
+ locks[i].brltype = PENDING_READ_LOCK;
+ } else {
+ locks[i].brltype = READ_LOCK;
+ }
+ } else {
+ if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
+ locks[i].brltype = PENDING_WRITE_LOCK;
+ } else {
+ locks[i].brltype = WRITE_LOCK;
+ }
+ }
/*
* There is no error code marked "stupid client bug".... :-).
@@ -7419,154 +7597,22 @@ void reply_lockingX(struct smb_request *req)
reply_doserror(req, ERRDOS, ERRnoaccess);
return;
}
-
- DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid "
- "%u, file %s timeout = %d\n", (double)offset,
- (double)count, (unsigned int)lock_pid,
- fsp->fsp_name, (int)lock_timeout ));
-
- if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
- struct blocking_lock_record *blr = NULL;
-
- if (lp_blocking_locks(SNUM(conn))) {
-
- /* Schedule a message to ourselves to
- remove the blocking lock record and
- return the right error. */
-
- blr = blocking_lock_cancel(fsp,
- lock_pid,
- offset,
- count,
- WINDOWS_LOCK,
- locktype,
- NT_STATUS_FILE_LOCK_CONFLICT);
- if (blr == NULL) {
- END_PROFILE(SMBlockingX);
- reply_nterror(
- req,
- NT_STATUS_DOS(
- ERRDOS,
- ERRcancelviolation));
- return;
- }
- }
- /* Remove a matching pending lock. */
- status = do_lock_cancel(fsp,
- lock_pid,
- count,
- offset,
- WINDOWS_LOCK,
- blr);
- } else {
- bool blocking_lock = lock_timeout ? True : False;
- bool defer_lock = False;
- struct byte_range_lock *br_lck;
- uint32 block_smbpid;
-
- br_lck = do_lock(smbd_messaging_context(),
- fsp,
- lock_pid,
- count,
- offset,
- lock_type,
- WINDOWS_LOCK,
- blocking_lock,
- &status,
- &block_smbpid,
- NULL);
-
- if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
- /* Windows internal resolution for blocking locks seems
- to be about 200ms... Don't wait for less than that. JRA. */
- if (lock_timeout != -1 && lock_timeout < lp_lock_spin_time()) {
- lock_timeout = lp_lock_spin_time();
- }
- defer_lock = True;
- }
-
- /* This heuristic seems to match W2K3 very well. If a
- lock sent with timeout of zero would fail with NT_STATUS_FILE_LOCK_CONFLICT
- it pretends we asked for a timeout of between 150 - 300 milliseconds as
- far as I can tell. Replacement for do_lock_spin(). JRA. */
-
- if (br_lck && lp_blocking_locks(SNUM(conn)) && !blocking_lock &&
- NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT)) {
- defer_lock = True;
- lock_timeout = lp_lock_spin_time();
- }
-
- if (br_lck && defer_lock) {
- /*
- * A blocking lock was requested. Package up
- * this smb into a queued request and push it
- * onto the blocking lock queue.
- */
- if(push_blocking_lock_request(br_lck,
- req,
- fsp,
- lock_timeout,
- i,
- lock_pid,
- lock_type,
- WINDOWS_LOCK,
- offset,
- count,
- block_smbpid)) {
- TALLOC_FREE(br_lck);
- END_PROFILE(SMBlockingX);
- return;
- }
- }
-
- TALLOC_FREE(br_lck);
- }
-
- if (NT_STATUS_V(status)) {
- break;
- }
}
- /* If any of the above locks failed, then we must unlock
- all of the previous locks (X/Open spec). */
- if (num_locks != 0 && !NT_STATUS_IS_OK(status)) {
-
- if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
- i = -1; /* we want to skip the for loop */
- }
-
- /*
- * Ensure we don't do a remove on the lock that just failed,
- * as under POSIX rules, if we have a lock already there, we
- * will delete it (and we shouldn't) .....
- */
- for(i--; i >= 0; i--) {
- lock_pid = get_lock_pid( data, i, large_file_format);
- count = get_lock_count( data, i, large_file_format);
- offset = get_lock_offset( data, i, large_file_format,
- &err);
-
- /*
- * There is no error code marked "stupid client
- * bug".... :-).
- */
- if(err) {
- END_PROFILE(SMBlockingX);
- reply_doserror(req, ERRDOS, ERRnoaccess);
- return;
- }
-
- do_unlock(smbd_messaging_context(),
- fsp,
- lock_pid,
- count,
- offset,
- WINDOWS_LOCK);
- }
+ status = smbd_do_locking(req, fsp,
+ locktype, lock_timeout,
+ num_ulocks, ulocks,
+ num_locks, locks,
+ &async);
+ if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBlockingX);
reply_nterror(req, status);
return;
}
+ if (async) {
+ END_PROFILE(SMBlockingX);
+ return;
+ }
reply_outbuf(req, 2, 0);
@@ -7615,7 +7661,6 @@ void reply_readbs(struct smb_request *req)
void reply_setattrE(struct smb_request *req)
{
connection_struct *conn = req->conn;
- struct smb_filename *smb_fname = NULL;
struct smb_file_time ft;
files_struct *fsp;
NTSTATUS status;
@@ -7635,14 +7680,6 @@ void reply_setattrE(struct smb_request *req)
goto out;
}
- /* XXX: Remove when fsp->fsp_name is converted to smb_filename. */
- status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
- NULL, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- goto out;
- }
-
/*
* Convert the DOS times into unix times.
*/
@@ -7663,7 +7700,7 @@ void reply_setattrE(struct smb_request *req)
/* Ensure we have a valid stat struct for the source. */
if (fsp->fh->fd != -1) {
- if (SMB_VFS_FSTAT(fsp, &smb_fname->st) == -1) {
+ if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) == -1) {
status = map_nt_error_from_unix(errno);
reply_nterror(req, status);
goto out;
@@ -7672,9 +7709,9 @@ void reply_setattrE(struct smb_request *req)
int ret = -1;
if (fsp->posix_open) {
- ret = SMB_VFS_LSTAT(conn, smb_fname);
+ ret = SMB_VFS_LSTAT(conn, fsp->fsp_name);
} else {
- ret = SMB_VFS_STAT(conn, smb_fname);
+ ret = SMB_VFS_STAT(conn, fsp->fsp_name);
}
if (ret == -1) {
status = map_nt_error_from_unix(errno);
@@ -7683,7 +7720,7 @@ void reply_setattrE(struct smb_request *req)
}
}
- status = smb_set_file_time(conn, fsp, smb_fname, &ft, true);
+ status = smb_set_file_time(conn, fsp, fsp->fsp_name, &ft, true);
if (!NT_STATUS_IS_OK(status)) {
reply_doserror(req, ERRDOS, ERRnoaccess);
goto out;
@@ -7743,8 +7780,6 @@ void reply_getattrE(struct smb_request *req)
int mode;
files_struct *fsp;
struct timespec create_ts;
- struct smb_filename *smb_fname = NULL;
- NTSTATUS status;
START_PROFILE(SMBgetattrE);
@@ -7764,21 +7799,14 @@ void reply_getattrE(struct smb_request *req)
/* Do an fstat on this file */
if(fsp_stat(fsp, &sbuf)) {
- reply_unixerror(req, ERRDOS, ERRnoaccess);
+ reply_nterror(req, map_nt_error_from_unix(errno));
END_PROFILE(SMBgetattrE);
return;
}
- status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
- &sbuf, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- END_PROFILE(SMBgetattrE);
- return;
- }
+ fsp->fsp_name->st = sbuf;
- mode = dos_mode(conn, smb_fname);
- TALLOC_FREE(smb_fname);
+ mode = dos_mode(conn, fsp->fsp_name);
/*
* Convert the times into dos times. Set create
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 6951fac171..4b1c803d75 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -94,6 +94,7 @@ static void smb_conf_updated(struct messaging_context *msg,
{
DEBUG(10,("smb_conf_updated: Got message saying smb.conf was "
"updated. Reloading.\n"));
+ change_to_root_user();
reload_services(False);
}
@@ -868,6 +869,7 @@ static void exit_server_common(enum server_exit_reason how,
if (am_parent) {
pidfile_unlink();
}
+ gencache_stabilize();
}
/* if we had any open SMB connections when we exited then we
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 0124b2b047..a043288bc9 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -182,8 +182,8 @@ bool set_current_service(connection_struct *conn, uint16 flags, bool do_chdir)
if (do_chdir &&
vfs_ChDir(conn,conn->connectpath) != 0 &&
vfs_ChDir(conn,conn->origpath) != 0) {
- DEBUG(0,("chdir (%s) failed\n",
- conn->connectpath));
+ DEBUG(((errno!=EACCES)?0:3),("chdir (%s) failed, reason: %s\n",
+ conn->connectpath, strerror(errno)));
return(False);
}
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index 3988105fa4..2d2e5141ee 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -1807,6 +1807,7 @@ void reply_sesssetup_and_X(struct smb_request *req)
SSVAL(req->outbuf,smb_uid,sess_vuid);
SSVAL(req->inbuf,smb_uid,sess_vuid);
+ req->vuid = sess_vuid;
if (!sconn->smb1.sessions.done_sesssetup) {
sconn->smb1.sessions.max_send =
diff --git a/source3/smbd/smb2_close.c b/source3/smbd/smb2_close.c
index 6724e5cc15..acb5da7751 100644
--- a/source3/smbd/smb2_close.c
+++ b/source3/smbd/smb2_close.c
@@ -107,11 +107,6 @@ static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req,
return NT_STATUS_NO_MEMORY;
}
- /* If it's an IPC, pass off the pipe handler. */
- if (IS_IPC(conn)) {
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
fsp = file_fsp(smbreq, (uint16_t)in_file_id_volatile);
if (fsp == NULL) {
return NT_STATUS_FILE_CLOSED;
@@ -126,7 +121,7 @@ static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req,
status = close_file(smbreq, fsp, NORMAL_CLOSE);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5,("smbd_smb2_close: close_file[%s]: %s\n",
- fsp->fsp_name, nt_errstr(status)));
+ fsp_str_dbg(fsp), nt_errstr(status)));
return status;
}
diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index bdff1939e5..b455f82d80 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -259,7 +259,6 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
files_struct *result;
int info;
SMB_STRUCT_STAT sbuf;
- struct smb_filename *smb_fname = NULL;
req = tevent_req_create(mem_ctx, &state,
struct smbd_smb2_create_state);
@@ -316,6 +315,8 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
}
info = FILE_WAS_CREATED;
} else {
+ struct smb_filename *smb_fname = NULL;
+
/* these are ignored for SMB2 */
in_create_options &= ~(0x10);/* NTCREATEX_OPTIONS_SYNC_ALERT */
in_create_options &= ~(0x20);/* NTCREATEX_OPTIONS_ASYNC_ALERT */
@@ -324,10 +325,10 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
smbreq->conn,
smbreq->flags2 & FLAGS2_DFS_PATHNAMES,
in_name,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
+ TALLOC_FREE(smb_fname);
goto out;
}
@@ -348,19 +349,11 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
&info);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
+ TALLOC_FREE(smb_fname);
goto out;
}
sbuf = smb_fname->st;
- }
-
- if (!smb_fname) {
- status = create_synthetic_smb_fname_split(talloc_tos(),
- result->fsp_name,
- &sbuf, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- tevent_req_nterror(req, status);
- goto out;
- }
+ TALLOC_FREE(smb_fname);
}
smb2req->compat_chain_fsp = smbreq->chain_fsp;
@@ -379,7 +372,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
state->out_allocation_size = sbuf.st_ex_blksize * sbuf.st_ex_blocks;
state->out_end_of_file = sbuf.st_ex_size;
state->out_file_attributes = dos_mode(result->conn,
- smb_fname);
+ result->fsp_name);
if (state->out_file_attributes == 0) {
state->out_file_attributes = FILE_ATTRIBUTE_NORMAL;
}
@@ -387,7 +380,6 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
tevent_req_done(req);
out:
- TALLOC_FREE(smb_fname);
return tevent_req_post(req, ev);
}
diff --git a/source3/smbd/smb2_flush.c b/source3/smbd/smb2_flush.c
index 8ce683923b..1d3ae2eb06 100644
--- a/source3/smbd/smb2_flush.c
+++ b/source3/smbd/smb2_flush.c
@@ -176,7 +176,7 @@ static struct tevent_req *smbd_smb2_flush_send(TALLOC_CTX *mem_ctx,
status = sync_file(smbreq->conn, fsp, true);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5,("smbd_smb2_flush: sync_file for %s returned %s\n",
- fsp->fsp_name, nt_errstr(status)));
+ fsp_str_dbg(fsp), nt_errstr(status)));
tevent_req_nterror(req, status);
return tevent_req_post(req, ev);
}
diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c
index ba725fdec9..5a6e3d7ecb 100644
--- a/source3/smbd/smb2_getinfo.c
+++ b/source3/smbd/smb2_getinfo.c
@@ -233,7 +233,177 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
return tevent_req_post(req, ev);
}
- tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
+ if (IS_IPC(conn)) {
+ tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
+ return tevent_req_post(req, ev);
+ }
+
+ switch (in_info_type) {
+ case 0x01:/* SMB2_GETINFO_FILE */
+ {
+ uint16_t file_info_level;
+ char *data = NULL;
+ unsigned int data_size = 0;
+ bool delete_pending = false;
+ struct timespec write_time_ts;
+ struct file_id fileid;
+ struct ea_list *ea_list = NULL;
+ int lock_data_count = 0;
+ char *lock_data = NULL;
+ bool ms_dfs_link = false;
+ NTSTATUS status;
+
+ ZERO_STRUCT(write_time_ts);
+
+ switch (in_file_info_class) {
+ case 0x0F:/* RAW_FILEINFO_SMB2_ALL_EAS */
+ file_info_level = 0xFF00 | in_file_info_class;
+ break;
+
+ case 0x12:/* RAW_FILEINFO_SMB2_ALL_INFORMATION */
+ file_info_level = 0xFF00 | in_file_info_class;
+ break;
+
+ default:
+ /* the levels directly map to the passthru levels */
+ file_info_level = in_file_info_class + 1000;
+ break;
+ }
+
+ if (fsp->fake_file_handle) {
+ /*
+ * This is actually for the QUOTA_FAKE_FILE --metze
+ */
+
+ /* We know this name is ok, it's already passed the checks. */
+
+ } else if (fsp && (fsp->is_directory || fsp->fh->fd == -1)) {
+ /*
+ * This is actually a QFILEINFO on a directory
+ * handle (returned from an NT SMB). NT5.0 seems
+ * to do this call. JRA.
+ */
+
+ if (INFO_LEVEL_IS_UNIX(file_info_level)) {
+ /* Always do lstat for UNIX calls. */
+ if (SMB_VFS_LSTAT(conn, fsp->fsp_name)) {
+ DEBUG(3,("smbd_smb2_getinfo_send: "
+ "SMB_VFS_LSTAT of %s failed "
+ "(%s)\n", fsp_str_dbg(fsp),
+ strerror(errno)));
+ status = map_nt_error_from_unix(errno);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+ } else if (SMB_VFS_STAT(conn, fsp->fsp_name)) {
+ DEBUG(3,("smbd_smb2_getinfo_send: "
+ "SMB_VFS_STAT of %s failed (%s)\n",
+ fsp_str_dbg(fsp),
+ strerror(errno)));
+ status = map_nt_error_from_unix(errno);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+
+ fileid = vfs_file_id_from_sbuf(conn,
+ &fsp->fsp_name->st);
+ get_file_infos(fileid, &delete_pending, &write_time_ts);
+ } else {
+ /*
+ * Original code - this is an open file.
+ */
+
+ if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
+ DEBUG(3, ("smbd_smb2_getinfo_send: "
+ "fstat of fnum %d failed (%s)\n",
+ fsp->fnum, strerror(errno)));
+ status = map_nt_error_from_unix(errno);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+ fileid = vfs_file_id_from_sbuf(conn,
+ &fsp->fsp_name->st);
+ get_file_infos(fileid, &delete_pending, &write_time_ts);
+ }
+
+ status = smbd_do_qfilepathinfo(conn, state,
+ file_info_level,
+ fsp,
+ fsp->fsp_name,
+ delete_pending,
+ write_time_ts,
+ ms_dfs_link,
+ ea_list,
+ lock_data_count,
+ lock_data,
+ STR_UNICODE,
+ in_output_buffer_length,
+ &data,
+ &data_size);
+ if (!NT_STATUS_IS_OK(status)) {
+ SAFE_FREE(data);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) {
+ status = NT_STATUS_INVALID_INFO_CLASS;
+ }
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+ if (data_size > 0) {
+ state->out_output_buffer = data_blob_talloc(state,
+ data,
+ data_size);
+ SAFE_FREE(data);
+ if (tevent_req_nomem(state->out_output_buffer.data, req)) {
+ return tevent_req_post(req, ev);
+ }
+ }
+ SAFE_FREE(data);
+ break;
+ }
+
+ case 0x02:/* SMB2_GETINFO_FS */
+ {
+ uint16_t file_info_level;
+ char *data = NULL;
+ int data_size = 0;
+ NTSTATUS status;
+
+ /* the levels directly map to the passthru levels */
+ file_info_level = in_file_info_class + 1000;
+
+ status = smbd_do_qfsinfo(conn, state,
+ file_info_level,
+ STR_UNICODE,
+ in_output_buffer_length,
+ &data,
+ &data_size);
+ if (!NT_STATUS_IS_OK(status)) {
+ SAFE_FREE(data);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) {
+ status = NT_STATUS_INVALID_INFO_CLASS;
+ }
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+ if (data_size > 0) {
+ state->out_output_buffer = data_blob_talloc(state,
+ data,
+ data_size);
+ SAFE_FREE(data);
+ if (tevent_req_nomem(state->out_output_buffer.data, req)) {
+ return tevent_req_post(req, ev);
+ }
+ }
+ SAFE_FREE(data);
+ break;
+ }
+
+ default:
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+
+ tevent_req_done(req);
return tevent_req_post(req, ev);
}
diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c
index 3ffe053481..121b4eb24d 100644
--- a/source3/smbd/smb2_lock.c
+++ b/source3/smbd/smb2_lock.c
@@ -31,6 +31,7 @@ struct smbd_smb2_lock_element {
static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct smbd_smb2_request *smb2req,
+ uint32_t in_smbpid,
uint64_t in_file_id_volatile,
uint16_t in_lock_count,
struct smbd_smb2_lock_element *in_locks);
@@ -41,15 +42,17 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req)
{
const uint8_t *inhdr;
const uint8_t *inbody;
- int i = req->current_idx;
+ const int i = req->current_idx;
size_t expected_body_size = 0x30;
size_t body_size;
+ uint32_t in_smbpid;
uint16_t in_lock_count;
uint64_t in_file_id_persistent;
uint64_t in_file_id_volatile;
struct smbd_smb2_lock_element *in_locks;
struct tevent_req *subreq;
const uint8_t *lock_buffer;
+ uint16_t l;
inhdr = (const uint8_t *)req->in.vector[i+0].iov_base;
if (req->in.vector[i+1].iov_len != (expected_body_size & 0xFFFFFFFE)) {
@@ -63,8 +66,10 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
}
+ in_smbpid = IVAL(inhdr, SMB2_HDR_PID);
+
in_lock_count = CVAL(inbody, 0x02);
- /* 0x04 4 bytes reserved */
+ /* 0x04 - 4 bytes reserved */
in_file_id_persistent = BVAL(inbody, 0x08);
in_file_id_volatile = BVAL(inbody, 0x10);
@@ -88,19 +93,21 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
}
- i = 0;
+ l = 0;
lock_buffer = inbody + 0x18;
- in_locks[i].offset = BVAL(lock_buffer, 0x00);
- in_locks[i].length = BVAL(lock_buffer, 0x08);
- in_locks[i].flags = BVAL(lock_buffer, 0x10);
+ in_locks[l].offset = BVAL(lock_buffer, 0x00);
+ in_locks[l].length = BVAL(lock_buffer, 0x08);
+ in_locks[l].flags = IVAL(lock_buffer, 0x10);
+ /* 0x14 - 4 reserved bytes */
lock_buffer = (const uint8_t *)req->in.vector[i+2].iov_base;
- for (i=1; i < in_lock_count; i++) {
- in_locks[i].offset = BVAL(lock_buffer, 0x00);
- in_locks[i].length = BVAL(lock_buffer, 0x08);
- in_locks[i].flags = BVAL(lock_buffer, 0x10);
+ for (l=1; l < in_lock_count; l++) {
+ in_locks[l].offset = BVAL(lock_buffer, 0x00);
+ in_locks[l].length = BVAL(lock_buffer, 0x08);
+ in_locks[l].flags = IVAL(lock_buffer, 0x10);
+ /* 0x14 - 4 reserved bytes */
lock_buffer += 0x18;
}
@@ -108,6 +115,7 @@ NTSTATUS smbd_smb2_request_process_lock(struct smbd_smb2_request *req)
subreq = smbd_smb2_lock_send(req,
req->conn->smb2.event_ctx,
req,
+ in_smbpid,
in_file_id_volatile,
in_lock_count,
in_locks);
@@ -172,6 +180,7 @@ struct smbd_smb2_lock_state {
static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct smbd_smb2_request *smb2req,
+ uint32_t in_smbpid,
uint64_t in_file_id_volatile,
uint16_t in_lock_count,
struct smbd_smb2_lock_element *in_locks)
@@ -181,6 +190,12 @@ static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx,
struct smb_request *smbreq;
connection_struct *conn = smb2req->tcon->compat_conn;
files_struct *fsp;
+ int32_t timeout = -1;
+ bool isunlock = false;
+ uint16_t i;
+ struct smbd_lock_element *locks;
+ NTSTATUS status;
+ bool async = false;
req = tevent_req_create(mem_ctx, &state,
struct smbd_smb2_lock_state);
@@ -211,7 +226,150 @@ static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx,
return tevent_req_post(req, ev);
}
- tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
+ locks = talloc_array(state, struct smbd_lock_element, in_lock_count);
+ if (locks == NULL) {
+ tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
+ return tevent_req_post(req, ev);
+ }
+
+ switch (in_locks[0].flags) {
+ case SMB2_LOCK_FLAG_SHARED:
+ case SMB2_LOCK_FLAG_EXCLUSIVE:
+ if (in_lock_count > 1) {
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+ timeout = -1;
+ break;
+
+ case SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY:
+ case SMB2_LOCK_FLAG_EXCLUSIVE|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY:
+ timeout = 0;
+ break;
+
+ case SMB2_LOCK_FLAG_UNLOCK:
+ /* only the first lock gives the UNLOCK bit - see
+ MS-SMB2 3.3.5.14 */
+ isunlock = true;
+ timeout = 0;
+ break;
+
+ default:
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+
+ for (i=0; i<in_lock_count; i++) {
+ uint64_t max_count;
+ bool invalid = false;
+
+ switch (in_locks[i].flags) {
+ case SMB2_LOCK_FLAG_SHARED:
+ case SMB2_LOCK_FLAG_EXCLUSIVE:
+ if (i > 0) {
+ tevent_req_nterror(req,
+ NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+ if (isunlock) {
+ tevent_req_nterror(req,
+ NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+ break;
+
+ case SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY:
+ case SMB2_LOCK_FLAG_EXCLUSIVE|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY:
+ if (isunlock) {
+ tevent_req_nterror(req,
+ NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+ break;
+
+ case SMB2_LOCK_FLAG_UNLOCK:
+ if (!isunlock) {
+ tevent_req_nterror(req,
+ NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+ break;
+
+ default:
+ if (isunlock) {
+ /*
+ * is the first element was a UNLOCK
+ * we need to deferr the error response
+ * to the backend, because we need to process
+ * all unlock elements before
+ */
+ invalid = true;
+ break;
+ }
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+
+ locks[i].smbpid = in_smbpid;
+ locks[i].offset = in_locks[i].offset;
+ locks[i].count = in_locks[i].length;
+
+ if (in_locks[i].flags & SMB2_LOCK_FLAG_EXCLUSIVE) {
+ locks[i].brltype = WRITE_LOCK;
+ } else if (in_locks[i].flags & SMB2_LOCK_FLAG_SHARED) {
+ locks[i].brltype = READ_LOCK;
+ } else if (invalid) {
+ /*
+ * this is an invalid UNLOCK element
+ * and the backend needs to test for
+ * brltype != UNLOCK_LOCK and return
+ * NT_STATUS_INVALID_PARAMER
+ */
+ locks[i].brltype = READ_LOCK;
+ } else {
+ locks[i].brltype = UNLOCK_LOCK;
+ }
+
+ max_count = UINT64_MAX - locks[i].offset;
+ if (locks[i].count > max_count) {
+ tevent_req_nterror(req, NT_STATUS_INVALID_LOCK_RANGE);
+ return tevent_req_post(req, ev);
+ }
+ }
+
+ if (isunlock) {
+ status = smbd_do_locking(smbreq, fsp,
+ 0,
+ timeout,
+ in_lock_count,
+ locks,
+ 0,
+ NULL,
+ &async);
+ } else {
+ status = smbd_do_locking(smbreq, fsp,
+ 0,
+ timeout,
+ 0,
+ NULL,
+ in_lock_count,
+ locks,
+ &async);
+ }
+ if (!NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
+ status = NT_STATUS_LOCK_NOT_GRANTED;
+ }
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+
+ if (async) {
+ tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+ return tevent_req_post(req, ev);
+ }
+
+ tevent_req_done(req);
return tevent_req_post(req, ev);
}
diff --git a/source3/smbd/smb2_notify.c b/source3/smbd/smb2_notify.c
index 7ab93ce574..f6d83aeeed 100644
--- a/source3/smbd/smb2_notify.c
+++ b/source3/smbd/smb2_notify.c
@@ -231,7 +231,7 @@ static struct tevent_req *smbd_smb2_notify_send(TALLOC_CTX *mem_ctx,
DEBUG(3,("smbd_smb2_notify_send: notify change "
"called on %s, filter = %s, recursive = %d\n",
- fsp->fsp_name, filter_string, recursive));
+ fsp_str_dbg(fsp), filter_string, recursive));
TALLOC_FREE(filter_string);
}
diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c
index c9f281f73e..42993511ec 100644
--- a/source3/smbd/smb2_read.c
+++ b/source3/smbd/smb2_read.c
@@ -281,13 +281,13 @@ static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
if (nread < 0) {
DEBUG(5,("smbd_smb2_read: read_file[%s] nread[%lld]\n",
- fsp->fsp_name, (long long)nread));
+ fsp_str_dbg(fsp), (long long)nread));
tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
return tevent_req_post(req, ev);
}
if (nread == 0 && in_length != 0) {
DEBUG(5,("smbd_smb2_read: read_file[%s] end of file\n",
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
tevent_req_nterror(req, NT_STATUS_END_OF_FILE);
return tevent_req_post(req, ev);
}
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 43afb1b901..204e57d860 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -1339,7 +1339,7 @@ static int smbd_smb2_request_next_vector(struct tstream_context *stream,
if (invalid) {
/* the caller should check this */
- body_size = 0;
+ body_size = 2;
}
if ((body_size % 2) != 0) {
@@ -1376,7 +1376,7 @@ static int smbd_smb2_request_next_vector(struct tstream_context *stream,
*/
memcpy(body, hdr + SMB2_HDR_BODY, 2);
vector[0].iov_base = body + 2;
- vector[0].iov_len = req->in.vector[idx].iov_len - 2;
+ vector[0].iov_len = body_size - 2;
vector[1] = req->in.vector[idx+1];
diff --git a/source3/smbd/smb2_setinfo.c b/source3/smbd/smb2_setinfo.c
index 110ce6c64a..08c4a7f5bf 100644
--- a/source3/smbd/smb2_setinfo.c
+++ b/source3/smbd/smb2_setinfo.c
@@ -200,7 +200,123 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx,
return tevent_req_post(req, ev);
}
- tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
+ if (IS_IPC(conn)) {
+ tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
+ return tevent_req_post(req, ev);
+ }
+
+ switch (in_info_type) {
+ case 0x01:/* SMB2_SETINFO_FILE */
+ {
+ uint16_t file_info_level;
+ char *data;
+ int data_size;
+ int ret_size = 0;
+ NTSTATUS status;
+
+
+ file_info_level = in_file_info_class + 1000;
+ if (file_info_level == SMB_FILE_RENAME_INFORMATION) {
+ file_info_level = 0xFF00 + in_file_info_class;
+ }
+
+ if (fsp->is_directory || fsp->fh->fd == -1) {
+ /*
+ * This is actually a SETFILEINFO on a directory
+ * handle (returned from an NT SMB). NT5.0 seems
+ * to do this call. JRA.
+ */
+ if (INFO_LEVEL_IS_UNIX(file_info_level)) {
+ /* Always do lstat for UNIX calls. */
+ if (SMB_VFS_LSTAT(conn, fsp->fsp_name)) {
+ DEBUG(3,("smbd_smb2_setinfo_send: "
+ "SMB_VFS_LSTAT of %s failed "
+ "(%s)\n", fsp_str_dbg(fsp),
+ strerror(errno)));
+ status = map_nt_error_from_unix(errno);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+ } else {
+ if (SMB_VFS_STAT(conn, fsp->fsp_name) != 0) {
+ DEBUG(3,("smbd_smb2_setinfo_send: "
+ "fileinfo of %s failed (%s)\n",
+ fsp_str_dbg(fsp),
+ strerror(errno)));
+ status = map_nt_error_from_unix(errno);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+ }
+ } else if (fsp->print_file) {
+ /*
+ * Doing a DELETE_ON_CLOSE should cancel a print job.
+ */
+ if ((file_info_level == SMB_SET_FILE_DISPOSITION_INFO)
+ && in_input_buffer.length >= 1
+ && CVAL(in_input_buffer.data,0)) {
+ fsp->fh->private_options |= FILE_DELETE_ON_CLOSE;
+
+ DEBUG(3,("smbd_smb2_setinfo_send: "
+ "Cancelling print job (%s)\n",
+ fsp_str_dbg(fsp)));
+
+ tevent_req_done(req);
+ return tevent_req_post(req, ev);
+ } else {
+ tevent_req_nterror(req,
+ NT_STATUS_OBJECT_PATH_INVALID);
+ return tevent_req_post(req, ev);
+ }
+ } else {
+ /*
+ * Original code - this is an open file.
+ */
+
+ if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
+ DEBUG(3,("smbd_smb2_setinfo_send: fstat "
+ "of fnum %d failed (%s)\n", fsp->fnum,
+ strerror(errno)));
+ status = map_nt_error_from_unix(errno);
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+ }
+
+ data = NULL;
+ data_size = in_input_buffer.length;
+ if (data_size > 0) {
+ data = (char *)SMB_MALLOC_ARRAY(char, data_size);
+ if (tevent_req_nomem(data, req)) {
+
+ }
+ memcpy(data, in_input_buffer.data, data_size);
+ }
+
+ status = smbd_do_setfilepathinfo(conn, smbreq, state,
+ file_info_level,
+ fsp,
+ fsp->fsp_name,
+ &data,
+ data_size,
+ &ret_size);
+ SAFE_FREE(data);
+ if (!NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) {
+ status = NT_STATUS_INVALID_INFO_CLASS;
+ }
+ tevent_req_nterror(req, status);
+ return tevent_req_post(req, ev);
+ }
+ break;
+ }
+
+ default:
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+
+ tevent_req_done(req);
return tevent_req_post(req, ev);
}
diff --git a/source3/smbd/smb2_write.c b/source3/smbd/smb2_write.c
index 31460a01a1..f1606be623 100644
--- a/source3/smbd/smb2_write.c
+++ b/source3/smbd/smb2_write.c
@@ -272,14 +272,14 @@ static struct tevent_req *smbd_smb2_write_send(TALLOC_CTX *mem_ctx,
if (((nwritten == 0) && (in_data.length != 0)) || (nwritten < 0)) {
DEBUG(5,("smbd_smb2_write: write_file[%s] disk full\n",
- fsp->fsp_name));
+ fsp_str_dbg(fsp)));
SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
tevent_req_nterror(req, NT_STATUS_DISK_FULL);
return tevent_req_post(req, ev);
}
DEBUG(3,("smbd_smb2_write: fnum=[%d/%s] length=%d offset=%d wrote=%d\n",
- fsp->fnum, fsp->fsp_name, (int)in_data.length,
+ fsp->fnum, fsp_str_dbg(fsp), (int)in_data.length,
(int)in_offset, (int)nwritten));
if (in_flags & 0x00000001) {
@@ -289,7 +289,7 @@ static struct tevent_req *smbd_smb2_write_send(TALLOC_CTX *mem_ctx,
status = sync_file(conn, fsp, write_through);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5,("smbd_smb2_write: sync_file for %s returned %s\n",
- fsp->fsp_name, nt_errstr(status)));
+ fsp_str_dbg(fsp), nt_errstr(status)));
SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
tevent_req_nterror(req, status);
return tevent_req_post(req, ev);
diff --git a/source3/smbd/statcache.c b/source3/smbd/statcache.c
index daed9f8225..da52cc05d4 100644
--- a/source3/smbd/statcache.c
+++ b/source3/smbd/statcache.c
@@ -175,6 +175,8 @@ bool stat_cache_lookup(connection_struct *conn,
DATA_BLOB data_val;
char *name;
TALLOC_CTX *ctx = talloc_tos();
+ struct smb_filename *smb_fname = NULL;
+ NTSTATUS status;
*pp_dirpath = NULL;
*pp_start = *pp_name;
@@ -274,14 +276,25 @@ bool stat_cache_lookup(connection_struct *conn,
"-> [%s]\n", chk_name, translated_path ));
DO_PROFILE_INC(statcache_hits);
- if (vfs_stat_smb_fname(conn, translated_path, pst) != 0) {
+ status = create_synthetic_smb_fname(talloc_tos(), translated_path,
+ NULL, NULL, &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(chk_name);
+ TALLOC_FREE(translated_path);
+ return false;
+ }
+
+ if (SMB_VFS_STAT(conn, smb_fname) != 0) {
/* Discard this entry - it doesn't exist in the filesystem. */
memcache_delete(smbd_memcache(), STAT_CACHE,
data_blob_const(chk_name, strlen(chk_name)));
TALLOC_FREE(chk_name);
TALLOC_FREE(translated_path);
+ TALLOC_FREE(smb_fname);
return False;
}
+ *pst = smb_fname->st;
+ TALLOC_FREE(smb_fname);
if (!sizechanged) {
memcpy(*pp_name, translated_path,
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 4bf27863bd..856fd9432d 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -367,6 +367,69 @@ static unsigned int fill_ea_buffer(TALLOC_CTX *mem_ctx, char *pdata, unsigned in
return ret_data_size;
}
+static NTSTATUS fill_ea_chained_buffer(TALLOC_CTX *mem_ctx,
+ char *pdata,
+ unsigned int total_data_size,
+ unsigned int *ret_data_size,
+ connection_struct *conn,
+ struct ea_list *ea_list)
+{
+ uint8_t *p = (uint8_t *)pdata;
+ uint8_t *last_start = NULL;
+
+ *ret_data_size = 0;
+
+ if (!lp_ea_support(SNUM(conn))) {
+ return NT_STATUS_NO_EAS_ON_FILE;
+ }
+
+ for (; ea_list; ea_list = ea_list->next) {
+ size_t dos_namelen;
+ fstring dos_ea_name;
+ size_t this_size;
+
+ if (last_start) {
+ SIVAL(last_start, 0, PTR_DIFF(p, last_start));
+ }
+ last_start = p;
+
+ push_ascii_fstring(dos_ea_name, ea_list->ea.name);
+ dos_namelen = strlen(dos_ea_name);
+ if (dos_namelen > 255 || dos_namelen == 0) {
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+ if (ea_list->ea.value.length > 65535) {
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+
+ this_size = 0x08 + dos_namelen + 1 + ea_list->ea.value.length;
+
+ if (ea_list->next) {
+ size_t pad = 4 - (this_size % 4);
+ this_size += pad;
+ }
+
+ if (this_size > total_data_size) {
+ return NT_STATUS_INFO_LENGTH_MISMATCH;
+ }
+
+ /* We know we have room. */
+ SIVAL(p, 0x00, 0); /* next offset */
+ SCVAL(p, 0x04, ea_list->ea.flags);
+ SCVAL(p, 0x05, dos_namelen);
+ SSVAL(p, 0x06, ea_list->ea.value.length);
+ fstrcpy((char *)(p+0x08), dos_ea_name);
+ memcpy(p + 0x08 + dos_namelen + 1, ea_list->ea.value.data, ea_list->ea.value.length);
+
+ total_data_size -= this_size;
+ p += this_size;
+ }
+
+ *ret_data_size = PTR_DIFF(p, pdata);
+ DEBUG(10,("fill_ea_chained_buffer: data_size = %u\n", *ret_data_size));
+ return NT_STATUS_OK;
+}
+
static unsigned int estimate_ea_size(connection_struct *conn, files_struct *fsp, const char *fname)
{
size_t total_ea_len = 0;
@@ -408,17 +471,13 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
const struct smb_filename *smb_fname, struct ea_list *ea_list)
{
char *fname = NULL;
- NTSTATUS status;
if (!lp_ea_support(SNUM(conn))) {
return NT_STATUS_EAS_NOT_SUPPORTED;
}
- status = get_full_smb_filename(talloc_tos(), smb_fname,
- &fname);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
+ /* For now setting EAs on streams isn't supported. */
+ fname = smb_fname->base_name;
for (;ea_list; ea_list = ea_list->next) {
int ret;
@@ -439,8 +498,9 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
if (ea_list->ea.value.length == 0) {
/* Remove the attribute. */
if (fsp && (fsp->fh->fd != -1)) {
- DEBUG(10,("set_ea: deleting ea name %s on file %s by file descriptor.\n",
- unix_ea_name, fsp->fsp_name));
+ DEBUG(10,("set_ea: deleting ea name %s on "
+ "file %s by file descriptor.\n",
+ unix_ea_name, fsp_str_dbg(fsp)));
ret = SMB_VFS_FREMOVEXATTR(fsp, unix_ea_name);
} else {
DEBUG(10,("set_ea: deleting ea name %s on file %s.\n",
@@ -457,8 +517,9 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
#endif
} else {
if (fsp && (fsp->fh->fd != -1)) {
- DEBUG(10,("set_ea: setting ea name %s on file %s by file descriptor.\n",
- unix_ea_name, fsp->fsp_name));
+ DEBUG(10,("set_ea: setting ea name %s on file "
+ "%s by file descriptor.\n",
+ unix_ea_name, fsp_str_dbg(fsp)));
ret = SMB_VFS_FSETXATTR(fsp, unix_ea_name,
ea_list->ea.value.data, ea_list->ea.value.length, 0);
} else {
@@ -963,8 +1024,7 @@ static void call_trans2open(connection_struct *conn,
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
fname,
- &smb_fname,
- NULL);
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req,
@@ -981,12 +1041,10 @@ static void call_trans2open(connection_struct *conn,
goto out;
}
- if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode,
- open_ofun,
- &access_mask,
- &share_mode,
- &create_disposition,
- &create_options)) {
+ if (!map_open_params_to_ntcreate(smb_fname, deny_mode, open_ofun,
+ &access_mask, &share_mode,
+ &create_disposition,
+ &create_options)) {
reply_doserror(req, ERRDOS, ERRbadaccess);
goto out;
}
@@ -1085,7 +1143,8 @@ static void call_trans2open(connection_struct *conn,
SIVAL(params,20,inode);
SSVAL(params,24,0); /* Padding. */
if (flags & 8) {
- uint32 ea_size = estimate_ea_size(conn, fsp, fsp->fsp_name);
+ uint32 ea_size = estimate_ea_size(conn, fsp,
+ fsp->fsp_name->base_name);
SIVAL(params, 26, ea_size);
} else {
SIVAL(params, 26, 0);
@@ -1976,7 +2035,7 @@ static void call_trans2findfirst(connection_struct *conn,
if (total_params < 13) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
+ goto out;
}
dirtype = SVAL(params,0);
@@ -2014,12 +2073,12 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
ask_sharemode = false;
if (!lp_unix_extensions()) {
reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ goto out;
}
break;
default:
reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ goto out;
}
srvstr_get_path_wcard(ctx, params, req->flags2, &directory,
@@ -2027,7 +2086,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
STR_TERMINATE, &ntstatus, &mask_contains_wcard);
if (!NT_STATUS_IS_OK(ntstatus)) {
reply_nterror(req, ntstatus);
- return;
+ goto out;
}
ntstatus = resolve_dfspath_wcard(ctx, conn,
@@ -2039,32 +2098,27 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) {
reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
ERRSRV, ERRbadpath);
- return;
+ goto out;
}
reply_nterror(req, ntstatus);
- return;
+ goto out;
}
ntstatus = unix_convert(ctx, conn, directory, &smb_dname,
(UCF_SAVE_LCOMP | UCF_ALLOW_WCARD_LCOMP));
if (!NT_STATUS_IS_OK(ntstatus)) {
reply_nterror(req, ntstatus);
- return;
+ goto out;
}
mask = smb_dname->original_lcomp;
- ntstatus = get_full_smb_filename(ctx, smb_dname, &directory);
- TALLOC_FREE(smb_dname);
- if (!NT_STATUS_IS_OK(ntstatus)) {
- reply_nterror(req, ntstatus);
- return;
- }
+ directory = smb_dname->base_name;
ntstatus = check_name(conn, directory);
if (!NT_STATUS_IS_OK(ntstatus)) {
reply_nterror(req, ntstatus);
- return;
+ goto out;
}
p = strrchr_m(directory,'/');
@@ -2074,14 +2128,14 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
mask = talloc_strdup(ctx,"*");
if (!mask) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
+ goto out;
}
mask_contains_wcard = True;
}
directory = talloc_strdup(talloc_tos(), "./");
if (!directory) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
+ goto out;
}
} else {
*p = 0;
@@ -2094,7 +2148,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
if (total_data < 4) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
+ goto out;
}
ea_size = IVAL(pdata,0);
@@ -2102,19 +2156,19 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
DEBUG(4,("call_trans2findfirst: Rejecting EA request with incorrect \
total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
+ goto out;
}
if (!lp_ea_support(SNUM(conn))) {
reply_doserror(req, ERRDOS, ERReasnotsupported);
- return;
+ goto out;
}
/* Pull out the list of names. */
ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
if (!ea_list) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
+ goto out;
}
}
@@ -2122,7 +2176,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
if(*ppdata == NULL ) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
+ goto out;
}
pdata = *ppdata;
data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1;
@@ -2131,7 +2185,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
*pparams = (char *)SMB_REALLOC(*pparams, 10);
if (*pparams == NULL) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
+ goto out;
}
params = *pparams;
@@ -2150,7 +2204,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
if (!NT_STATUS_IS_OK(ntstatus)) {
reply_nterror(req, ntstatus);
- return;
+ goto out;
}
dptr_num = dptr_dnum(conn->dirptr);
@@ -2233,11 +2287,11 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
dptr_close(&dptr_num);
if (Protocol < PROTOCOL_NT1) {
reply_doserror(req, ERRDOS, ERRnofiles);
- return;
+ goto out;
} else {
reply_botherror(req, NT_STATUS_NO_SUCH_FILE,
ERRDOS, ERRbadfile);
- return;
+ goto out;
}
}
@@ -2276,7 +2330,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
char mangled_name[13];
name_to_8_3(mask, mangled_name, True, conn->params);
}
-
+ out:
+ TALLOC_FREE(smb_dname);
return;
}
@@ -2624,67 +2679,54 @@ static void samba_extended_info_version(struct smb_extended_info *extended_info)
"%s", samba_version_string());
}
-/****************************************************************************
- Reply to a TRANS2_QFSINFO (query filesystem info).
-****************************************************************************/
-
-static void call_trans2qfsinfo(connection_struct *conn,
- struct smb_request *req,
- char **pparams, int total_params,
- char **ppdata, int total_data,
- unsigned int max_data_bytes)
+NTSTATUS smbd_do_qfsinfo(connection_struct *conn,
+ TALLOC_CTX *mem_ctx,
+ uint16_t info_level,
+ uint16_t flags2,
+ unsigned int max_data_bytes,
+ char **ppdata,
+ int *ret_data_len)
{
char *pdata, *end_data;
- char *params = *pparams;
- uint16 info_level;
- int data_len, len;
- SMB_STRUCT_STAT st;
+ int data_len = 0, len;
const char *vname = volume_label(SNUM(conn));
int snum = SNUM(conn);
char *fstype = lp_fstype(SNUM(conn));
uint32 additional_flags = 0;
-
- if (total_params < 2) {
- reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
- }
-
- info_level = SVAL(params,0);
+ struct smb_filename *smb_fname_dot = NULL;
+ SMB_STRUCT_STAT st;
+ NTSTATUS status;
if (IS_IPC(conn)) {
if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
- DEBUG(0,("call_trans2qfsinfo: not an allowed "
+ DEBUG(0,("smbd_do_qfsinfo: not an allowed "
"info level (0x%x) on IPC$.\n",
(unsigned int)info_level));
- reply_nterror(req, NT_STATUS_ACCESS_DENIED);
- return;
+ return NT_STATUS_ACCESS_DENIED;
}
}
- if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
- if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
- DEBUG(0,("call_trans2qfsinfo: encryption required "
- "and info level 0x%x sent.\n",
- (unsigned int)info_level));
- exit_server_cleanly("encryption required "
- "on connection");
- return;
- }
- }
+ DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level));
- DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
+ status = create_synthetic_smb_fname(talloc_tos(), ".", NULL, NULL,
+ &smb_fname_dot);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
- if(vfs_stat_smb_fname(conn,".",&st)!=0) {
- DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
- reply_doserror(req, ERRSRV, ERRinvdevice);
- return;
+ if(SMB_VFS_STAT(conn, smb_fname_dot) != 0) {
+ DEBUG(2,("stat of . failed (%s)\n", strerror(errno)));
+ TALLOC_FREE(smb_fname_dot);
+ return map_nt_error_from_unix(errno);
}
+ st = smb_fname_dot->st;
+ TALLOC_FREE(smb_fname_dot);
+
*ppdata = (char *)SMB_REALLOC(
*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
- if (*ppdata == NULL ) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
+ if (*ppdata == NULL) {
+ return NT_STATUS_NO_MEMORY;
}
pdata = *ppdata;
@@ -2697,8 +2739,7 @@ static void call_trans2qfsinfo(connection_struct *conn,
uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
data_len = 18;
if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
- reply_unixerror(req, ERRHRD, ERRgeneral);
- return;
+ return map_nt_error_from_unix(errno);
}
block_size = lp_block_size(snum);
@@ -2717,7 +2758,7 @@ static void call_trans2qfsinfo(connection_struct *conn,
bytes_per_sector = 512;
sectors_per_unit = bsize/bytes_per_sector;
- DEBUG(5,("call_trans2qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
+ DEBUG(5,("smbd_do_qfsinfo : SMB_INFO_ALLOCATION id=%x, bsize=%u, cSectorUnit=%u, \
cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (unsigned int)bsize, (unsigned int)sectors_per_unit,
(unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
@@ -2743,13 +2784,13 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u
* the pushed string. The change here was adding the STR_TERMINATE. JRA.
*/
len = srvstr_push(
- pdata, req->flags2,
+ pdata, flags2,
pdata+l2_vol_szVolLabel, vname,
PTR_DIFF(end_data, pdata+l2_vol_szVolLabel),
STR_NOALIGN|STR_TERMINATE);
SCVAL(pdata,l2_vol_cch,len);
data_len = l2_vol_szVolLabel + len;
- DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
+ DEBUG(5,("smbd_do_qfsinfo : time = %x, namelen = %d, name = %s\n",
(unsigned)convert_timespec_to_time_t(st.st_ex_ctime),
len, vname));
break;
@@ -2776,7 +2817,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u
SIVAL(pdata,4,255); /* Max filename component length */
/* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
and will think we can't do long filenames */
- len = srvstr_push(pdata, req->flags2, pdata+12, fstype,
+ len = srvstr_push(pdata, flags2, pdata+12, fstype,
PTR_DIFF(end_data, pdata+12),
STR_UNICODE);
SIVAL(pdata,8,len);
@@ -2785,7 +2826,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u
case SMB_QUERY_FS_LABEL_INFO:
case SMB_FS_LABEL_INFORMATION:
- len = srvstr_push(pdata, req->flags2, pdata+4, vname,
+ len = srvstr_push(pdata, flags2, pdata+4, vname,
PTR_DIFF(end_data, pdata+4), 0);
data_len = 4 + len;
SIVAL(pdata,0,len);
@@ -2802,13 +2843,13 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u
(str_checksum(get_local_machine_name())<<16));
/* Max label len is 32 characters. */
- len = srvstr_push(pdata, req->flags2, pdata+18, vname,
+ len = srvstr_push(pdata, flags2, pdata+18, vname,
PTR_DIFF(end_data, pdata+18),
STR_UNICODE);
SIVAL(pdata,12,len);
data_len = 18+len;
- DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
+ DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol=%s serv=%s\n",
(int)strlen(vname),vname, lp_servicename(snum)));
break;
@@ -2818,8 +2859,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u
uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
data_len = 24;
if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
- reply_unixerror(req, ERRHRD, ERRgeneral);
- return;
+ return map_nt_error_from_unix(errno);
}
block_size = lp_block_size(snum);
if (bsize < block_size) {
@@ -2836,7 +2876,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_ex_dev, (u
}
bytes_per_sector = 512;
sectors_per_unit = bsize/bytes_per_sector;
- DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
+ DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_SIZE_INFO bsize=%u, cSectorUnit=%u, \
cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
(unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
SBIG_UINT(pdata,0,dsize);
@@ -2851,8 +2891,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
uint64_t dfree,dsize,bsize,block_size,sectors_per_unit,bytes_per_sector;
data_len = 32;
if (get_dfree_info(conn,".",False,&bsize,&dfree,&dsize) == (uint64_t)-1) {
- reply_unixerror(req, ERRHRD, ERRgeneral);
- return;
+ return map_nt_error_from_unix(errno);
}
block_size = lp_block_size(snum);
if (bsize < block_size) {
@@ -2869,7 +2908,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
}
bytes_per_sector = 512;
sectors_per_unit = bsize/bytes_per_sector;
- DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
+ DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_FS_FULL_SIZE_INFO bsize=%u, cSectorUnit=%u, \
cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned int)sectors_per_unit,
(unsigned int)bytes_per_sector, (unsigned int)dsize, (unsigned int)dfree));
SBIG_UINT(pdata,0,dsize); /* Total Allocation units. */
@@ -2922,24 +2961,23 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
fsp.fnum = -1;
/* access check */
- if (conn->server_info->utok.uid != 0) {
+ if (conn->server_info->utok.uid != sec_initial_uid()) {
DEBUG(0,("set_user_quota: access_denied "
"service [%s] user [%s]\n",
lp_servicename(SNUM(conn)),
conn->server_info->unix_name));
- reply_doserror(req, ERRDOS, ERRnoaccess);
- return;
+ return NT_STATUS_ACCESS_DENIED;
}
if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
- reply_doserror(req, ERRSRV, ERRerror);
- return;
+ return map_nt_error_from_unix(errno);
}
data_len = 48;
- DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",lp_servicename(SNUM(conn))));
+ DEBUG(10,("SMB_FS_QUOTA_INFORMATION: for service [%s]\n",
+ lp_servicename(SNUM(conn))));
/* Unknown1 24 NULL bytes*/
SBIG_UINT(pdata,0,(uint64_t)0);
@@ -2990,8 +3028,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
int encrypt_caps = 0;
if (!lp_unix_extensions()) {
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ return NT_STATUS_INVALID_LEVEL;
}
switch (conn->encrypt_level) {
@@ -3036,8 +3073,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
vfs_statvfs_struct svfs;
if (!lp_unix_extensions()) {
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ return NT_STATUS_INVALID_LEVEL;
}
rc = SMB_VFS_STATVFS(conn, ".", &svfs);
@@ -3052,16 +3088,14 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
SBIG_UINT(pdata,32,svfs.TotalFileNodes);
SBIG_UINT(pdata,40,svfs.FreeFileNodes);
SBIG_UINT(pdata,48,svfs.FsIdentifier);
- DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
+ DEBUG(5,("smbd_do_qfsinfo : SMB_QUERY_POSIX_FS_INFO succsessful\n"));
#ifdef EOPNOTSUPP
} else if (rc == EOPNOTSUPP) {
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ return NT_STATUS_INVALID_LEVEL;
#endif /* EOPNOTSUPP */
} else {
DEBUG(0,("vfs_statvfs() failed for service [%s]\n",lp_servicename(SNUM(conn))));
- reply_doserror(req, ERRSRV, ERRerror);
- return;
+ return NT_STATUS_DOS(ERRSRV, ERRerror);
}
break;
}
@@ -3073,13 +3107,11 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
int i;
if (!lp_unix_extensions()) {
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ return NT_STATUS_INVALID_LEVEL;
}
if (max_data_bytes < 40) {
- reply_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
- return;
+ return NT_STATUS_BUFFER_TOO_SMALL;
}
/* We ARE guest if global_sid_Builtin_Guests is
@@ -3193,12 +3225,59 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
}
/* drop through */
default:
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+ return NT_STATUS_INVALID_LEVEL;
+ }
+
+ *ret_data_len = data_len;
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ Reply to a TRANS2_QFSINFO (query filesystem info).
+****************************************************************************/
+
+static void call_trans2qfsinfo(connection_struct *conn,
+ struct smb_request *req,
+ char **pparams, int total_params,
+ char **ppdata, int total_data,
+ unsigned int max_data_bytes)
+{
+ char *params = *pparams;
+ uint16_t info_level;
+ int data_len = 0;
+ NTSTATUS status;
+
+ if (total_params < 2) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
+
+ info_level = SVAL(params,0);
+
+ if (ENCRYPTION_REQUIRED(conn) && !req->encrypted) {
+ if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
+ DEBUG(0,("call_trans2qfsinfo: encryption required "
+ "and info level 0x%x sent.\n",
+ (unsigned int)info_level));
+ exit_server_cleanly("encryption required "
+ "on connection");
return;
+ }
}
+ DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
+
+ status = smbd_do_qfsinfo(conn, req,
+ info_level,
+ req->flags2,
+ max_data_bytes,
+ ppdata, &data_len);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ return;
+ }
- send_trans2_replies(conn, req, params, 0, pdata, data_len,
+ send_trans2_replies(conn, req, params, 0, *ppdata, data_len,
max_data_bytes);
DEBUG( 4, ( "%s info_level = %d\n",
@@ -3369,12 +3448,12 @@ cap_low = 0x%x, cap_high = 0x%x\n",
ZERO_STRUCT(quotas);
/* access check */
- if ((conn->server_info->utok.uid != 0)
+ if ((conn->server_info->utok.uid != sec_initial_uid())
||!CAN_WRITE(conn)) {
DEBUG(0,("set_user_quota: access_denied service [%s] user [%s]\n",
lp_servicename(SNUM(conn)),
conn->server_info->unix_name));
- reply_doserror(req, ERRSRV, ERRaccess);
+ reply_nterror(req, NT_STATUS_ACCESS_DENIED);
return;
}
@@ -3443,7 +3522,7 @@ cap_low = 0x%x, cap_high = 0x%x\n",
/* now set the quotas */
if (vfs_set_ntquota(fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
DEBUG(0,("vfs_set_ntquota() failed for service [%s]\n",lp_servicename(SNUM(conn))));
- reply_doserror(req, ERRSRV, ERRerror);
+ reply_nterror(req, map_nt_error_from_unix(errno));
return;
}
@@ -3878,296 +3957,55 @@ static void call_trans2qpipeinfo(connection_struct *conn,
return;
}
-/****************************************************************************
- Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
- file name or file id).
-****************************************************************************/
-
-static void call_trans2qfilepathinfo(connection_struct *conn,
- struct smb_request *req,
- unsigned int tran_call,
- char **pparams, int total_params,
- char **ppdata, int total_data,
- unsigned int max_data_bytes)
+NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
+ TALLOC_CTX *mem_ctx,
+ uint16_t info_level,
+ files_struct *fsp,
+ const struct smb_filename *smb_fname,
+ bool delete_pending,
+ struct timespec write_time_ts,
+ bool ms_dfs_link,
+ struct ea_list *ea_list,
+ int lock_data_count,
+ char *lock_data,
+ uint16_t flags2,
+ unsigned int max_data_bytes,
+ char **ppdata,
+ unsigned int *pdata_size)
{
- char *params = *pparams;
char *pdata = *ppdata;
char *dstart, *dend;
- uint16 info_level;
- int mode=0;
- int nlink;
- SMB_OFF_T file_size=0;
- uint64_t allocation_size=0;
- unsigned int data_size = 0;
- unsigned int param_size = 2;
+ unsigned int data_size;
+ struct timespec create_time_ts, mtime_ts, atime_ts;
+ time_t create_time, mtime, atime;
SMB_STRUCT_STAT sbuf;
- char *dos_fname = NULL;
- char *fname = NULL;
- struct smb_filename *smb_fname = NULL;
- char *fullpathname;
- char *base_name;
char *p;
- SMB_OFF_T pos = 0;
- bool delete_pending = False;
- int len;
- time_t create_time, mtime, atime;
- struct timespec create_time_ts, mtime_ts, atime_ts;
- struct timespec write_time_ts;
- files_struct *fsp = NULL;
- struct file_id fileid;
- struct ea_list *ea_list = NULL;
- char *lock_data = NULL;
- bool ms_dfs_link = false;
- TALLOC_CTX *ctx = talloc_tos();
- NTSTATUS status = NT_STATUS_OK;
-
- if (!params) {
- reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
- }
-
- ZERO_STRUCT(write_time_ts);
-
- if (tran_call == TRANSACT2_QFILEINFO) {
- if (total_params < 4) {
- reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
- }
-
- if (IS_IPC(conn)) {
- call_trans2qpipeinfo(conn, req, tran_call,
- pparams, total_params,
- ppdata, total_data,
- max_data_bytes);
- return;
- }
-
- fsp = file_fsp(req, SVAL(params,0));
- info_level = SVAL(params,2);
-
- DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
-
- if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
- }
-
- /* Initial check for valid fsp ptr. */
- if (!check_fsp_open(conn, req, fsp)) {
- return;
- }
-
- fname = talloc_strdup(talloc_tos(),fsp->fsp_name);
- if (!fname) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
- }
-
- status = create_synthetic_smb_fname_split(talloc_tos(), fname,
- NULL, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- return;
- }
-
- if(fsp->fake_file_handle) {
- /*
- * This is actually for the QUOTA_FAKE_FILE --metze
- */
-
- /* We know this name is ok, it's already passed the checks. */
-
- } else if(fsp && (fsp->is_directory || fsp->fh->fd == -1)) {
- /*
- * This is actually a QFILEINFO on a directory
- * handle (returned from an NT SMB). NT5.0 seems
- * to do this call. JRA.
- */
-
- if (INFO_LEVEL_IS_UNIX(info_level)) {
- /* Always do lstat for UNIX calls. */
- if (SMB_VFS_LSTAT(conn, smb_fname)) {
- DEBUG(3,("call_trans2qfilepathinfo: "
- "SMB_VFS_LSTAT of %s failed "
- "(%s)\n",
- smb_fname_str_dbg(smb_fname),
- strerror(errno)));
- reply_unixerror(req,ERRDOS,ERRbadpath);
- return;
- }
- } else if (SMB_VFS_STAT(conn, smb_fname)) {
- DEBUG(3,("call_trans2qfilepathinfo: "
- "SMB_VFS_STAT of %s failed (%s)\n",
- smb_fname_str_dbg(smb_fname),
- strerror(errno)));
- reply_unixerror(req, ERRDOS, ERRbadpath);
- return;
- }
-
- fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
- get_file_infos(fileid, &delete_pending, &write_time_ts);
- } else {
- /*
- * Original code - this is an open file.
- */
- if (!check_fsp(conn, req, fsp)) {
- return;
- }
-
- if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
- DEBUG(3, ("fstat of fnum %d failed (%s)\n",
- fsp->fnum, strerror(errno)));
- reply_unixerror(req, ERRDOS, ERRbadfid);
- return;
- }
- pos = fsp->fh->position_information;
- fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
- get_file_infos(fileid, &delete_pending, &write_time_ts);
- }
-
- } else {
- /* qpathinfo */
- if (total_params < 7) {
- reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
- }
-
- info_level = SVAL(params,0);
-
- DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
-
- if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
- }
-
- srvstr_get_path(ctx, params, req->flags2, &fname, &params[6],
- total_params - 6,
- STR_TERMINATE, &status);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- return;
- }
-
- status = filename_convert(ctx,
- conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
- fname,
- &smb_fname,
- &fname);
- if (!NT_STATUS_IS_OK(status)) {
- if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
- reply_botherror(req,
- NT_STATUS_PATH_NOT_COVERED,
- ERRSRV, ERRbadpath);
- return;
- }
- reply_nterror(req, status);
- return;
- }
-
- /* If this is a stream, check if there is a delete_pending. */
- if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
- && is_ntfs_stream_smb_fname(smb_fname)) {
- struct smb_filename *smb_fname_base = NULL;
-
- /* Create an smb_filename with stream_name == NULL. */
- status =
- create_synthetic_smb_fname(talloc_tos(),
- smb_fname->base_name,
- NULL, NULL,
- &smb_fname_base);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- return;
- }
-
- if (INFO_LEVEL_IS_UNIX(info_level)) {
- /* Always do lstat for UNIX calls. */
- if (SMB_VFS_LSTAT(conn, smb_fname_base) != 0) {
- DEBUG(3,("call_trans2qfilepathinfo: "
- "SMB_VFS_LSTAT of %s failed "
- "(%s)\n",
- smb_fname_str_dbg(smb_fname_base),
- strerror(errno)));
- TALLOC_FREE(smb_fname_base);
- reply_unixerror(req,ERRDOS,ERRbadpath);
- return;
- }
- } else {
- if (SMB_VFS_STAT(conn, smb_fname_base) != 0) {
- DEBUG(3,("call_trans2qfilepathinfo: "
- "fileinfo of %s failed "
- "(%s)\n",
- smb_fname_str_dbg(smb_fname_base),
- strerror(errno)));
- TALLOC_FREE(smb_fname_base);
- reply_unixerror(req,ERRDOS,ERRbadpath);
- return;
- }
- }
-
- fileid = vfs_file_id_from_sbuf(conn,
- &smb_fname_base->st);
- TALLOC_FREE(smb_fname_base);
- get_file_infos(fileid, &delete_pending, NULL);
- if (delete_pending) {
- reply_nterror(req, NT_STATUS_DELETE_PENDING);
- return;
- }
- }
-
- if (INFO_LEVEL_IS_UNIX(info_level)) {
- /* Always do lstat for UNIX calls. */
- if (SMB_VFS_LSTAT(conn, smb_fname)) {
- DEBUG(3,("call_trans2qfilepathinfo: "
- "SMB_VFS_LSTAT of %s failed (%s)\n",
- smb_fname_str_dbg(smb_fname),
- strerror(errno)));
- reply_unixerror(req, ERRDOS, ERRbadpath);
- return;
- }
-
- } else if (!VALID_STAT(smb_fname->st) &&
- SMB_VFS_STAT(conn, smb_fname) &&
- (info_level != SMB_INFO_IS_NAME_VALID)) {
- ms_dfs_link = check_msdfs_link(conn, fname,
- &smb_fname->st);
-
- if (!ms_dfs_link) {
- DEBUG(3,("call_trans2qfilepathinfo: "
- "SMB_VFS_STAT of %s failed (%s)\n",
- smb_fname_str_dbg(smb_fname),
- strerror(errno)));
- reply_unixerror(req, ERRDOS, ERRbadpath);
- return;
- }
- }
-
- fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
- get_file_infos(fileid, &delete_pending, &write_time_ts);
- if (delete_pending) {
- reply_nterror(req, NT_STATUS_DELETE_PENDING);
- return;
- }
- }
+ char *fname;
+ char *base_name;
+ char *dos_fname;
+ int mode;
+ int nlink;
+ NTSTATUS status;
+ uint64_t file_size = 0;
+ uint64_t pos = 0;
+ uint64_t allocation_size = 0;
+ uint64_t file_index = 0;
+ uint32_t access_mask = 0;
- /* Set sbuf for use below. */
sbuf = smb_fname->st;
if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ return NT_STATUS_INVALID_LEVEL;
}
- DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
- fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
+ status = get_full_smb_filename(mem_ctx, smb_fname, &fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
- p = strrchr_m(smb_fname->base_name,'/');
- if (!p)
- base_name = smb_fname->base_name;
- else
- base_name = p+1;
+ DEBUG(5,("smbd_do_qfilepathinfo: %s (fnum = %d) level=%d max_data=%u\n",
+ smb_fname_str_dbg(smb_fname), fsp ? fsp->fnum : -1,
+ info_level, max_data_bytes));
if (ms_dfs_link) {
mode = dos_mode_msdfs(conn, smb_fname);
@@ -4187,102 +4025,15 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
nlink -= 1;
}
- fullpathname = fname;
- if (!(mode & aDIR))
- file_size = get_file_size_stat(&sbuf);
-
- /* Pull out any data sent here before we realloc. */
- switch (info_level) {
- case SMB_INFO_QUERY_EAS_FROM_LIST:
- {
- /* Pull any EA list from the data portion. */
- uint32 ea_size;
-
- if (total_data < 4) {
- reply_nterror(
- req, NT_STATUS_INVALID_PARAMETER);
- return;
- }
- ea_size = IVAL(pdata,0);
-
- if (total_data > 0 && ea_size != total_data) {
- DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
-total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
- reply_nterror(
- req, NT_STATUS_INVALID_PARAMETER);
- return;
- }
-
- if (!lp_ea_support(SNUM(conn))) {
- reply_doserror(req, ERRDOS,
- ERReasnotsupported);
- return;
- }
-
- /* Pull out the list of names. */
- ea_list = read_ea_name_list(ctx, pdata + 4, ea_size - 4);
- if (!ea_list) {
- reply_nterror(
- req, NT_STATUS_INVALID_PARAMETER);
- return;
- }
- break;
- }
-
- case SMB_QUERY_POSIX_LOCK:
- {
- if (fsp == NULL || fsp->fh->fd == -1) {
- reply_nterror(req, NT_STATUS_INVALID_HANDLE);
- return;
- }
-
- if (total_data != POSIX_LOCK_DATA_SIZE) {
- reply_nterror(
- req, NT_STATUS_INVALID_PARAMETER);
- return;
- }
-
- /* Copy the lock range data. */
- lock_data = (char *)TALLOC_MEMDUP(
- ctx, pdata, total_data);
- if (!lock_data) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
- }
- }
- default:
- break;
- }
-
- *pparams = (char *)SMB_REALLOC(*pparams,2);
- if (*pparams == NULL) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
- }
- params = *pparams;
- SSVAL(params,0,0);
data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
*ppdata = (char *)SMB_REALLOC(*ppdata, data_size);
- if (*ppdata == NULL ) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
+ if (*ppdata == NULL) {
+ return NT_STATUS_NO_MEMORY;
}
pdata = *ppdata;
dstart = pdata;
dend = dstart + data_size - 1;
- allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&sbuf);
-
- if (!fsp) {
- /* Do we have this path open ? */
- files_struct *fsp1;
- fileid = vfs_file_id_from_sbuf(conn, &sbuf);
- fsp1 = file_find_di_first(fileid);
- if (fsp1 && fsp1->initial_allocation_size) {
- allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp1, &sbuf);
- }
- }
-
if (!null_timespec(write_time_ts) && !INFO_LEVEL_IS_UNIX(info_level)) {
update_stat_ex_mtime(&sbuf, write_time_ts);
}
@@ -4301,28 +4052,67 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
mtime = convert_timespec_to_time_t(mtime_ts);
atime = convert_timespec_to_time_t(atime_ts);
+ p = strrchr_m(smb_fname->base_name,'/');
+ if (!p)
+ base_name = smb_fname->base_name;
+ else
+ base_name = p+1;
+
/* NT expects the name to be in an exact form of the *full*
filename. See the trans2 torture test */
if (ISDOT(base_name)) {
- dos_fname = talloc_strdup(ctx, "\\");
+ dos_fname = talloc_strdup(mem_ctx, "\\");
if (!dos_fname) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
+ return NT_STATUS_NO_MEMORY;
}
} else {
- dos_fname = talloc_asprintf(ctx,
+ dos_fname = talloc_asprintf(mem_ctx,
"\\%s",
fname);
if (!dos_fname) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
+ return NT_STATUS_NO_MEMORY;
}
string_replace(dos_fname, '/', '\\');
}
+ allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp, &sbuf);
+
+ if (!fsp) {
+ /* Do we have this path open ? */
+ files_struct *fsp1;
+ struct file_id fileid = vfs_file_id_from_sbuf(conn, &sbuf);
+ fsp1 = file_find_di_first(fileid);
+ if (fsp1 && fsp1->initial_allocation_size) {
+ allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp1, &sbuf);
+ }
+ }
+
+ if (!(mode & aDIR)) {
+ file_size = get_file_size_stat(&sbuf);
+ }
+
+ if (fsp) {
+ pos = fsp->fh->position_information;
+ }
+
+ if (fsp) {
+ access_mask = fsp->access_mask;
+ } else {
+ /* GENERIC_EXECUTE mapping from Windows */
+ access_mask = 0x12019F;
+ }
+
+ /* This should be an index number - looks like
+ dev/ino to me :-)
+
+ I think this causes us to fail the IFSKIT
+ BasicFileInformationTest. -tpot */
+ file_index = ((sbuf.st_ex_ino) & UINT32_MAX); /* FileIndexLow */
+ file_index |= ((uint64_t)((sbuf.st_ex_dev) & UINT32_MAX)) << 32; /* FileIndexHigh */
+
switch (info_level) {
case SMB_INFO_STANDARD:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_STANDARD\n"));
data_size = 22;
srv_put_dos_date2(pdata,l1_fdateCreation,create_time);
srv_put_dos_date2(pdata,l1_fdateLastAccess,atime);
@@ -4335,7 +4125,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
case SMB_INFO_QUERY_EA_SIZE:
{
unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
- DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
data_size = 26;
srv_put_dos_date2(pdata,0,create_time);
srv_put_dos_date2(pdata,4,atime);
@@ -4348,14 +4138,13 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
}
case SMB_INFO_IS_NAME_VALID:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
- if (tran_call == TRANSACT2_QFILEINFO) {
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_IS_NAME_VALID\n"));
+ if (fsp) {
/* os/2 needs this ? really ?*/
- reply_doserror(req, ERRDOS, ERRbadfunc);
- return;
+ return NT_STATUS_DOS(ERRDOS, ERRbadfunc);
}
+ /* This is only reached for qpathinfo */
data_size = 0;
- param_size = 0;
break;
case SMB_INFO_QUERY_EAS_FROM_LIST:
@@ -4363,9 +4152,9 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
size_t total_ea_len = 0;
struct ea_list *ea_file_list = NULL;
- DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_EAS_FROM_LIST\n"));
- ea_file_list = get_ea_list_from_file(ctx, conn, fsp, fname, &total_ea_len);
+ ea_file_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
ea_list = ea_list_union(ea_list, ea_file_list, &total_ea_len);
if (!ea_list || (total_ea_len > data_size)) {
@@ -4374,7 +4163,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
break;
}
- data_size = fill_ea_buffer(ctx, pdata, data_size, conn, ea_list);
+ data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list);
break;
}
@@ -4383,16 +4172,45 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
/* We have data_size bytes to put EA's into. */
size_t total_ea_len = 0;
- DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_INFO_QUERY_ALL_EAS\n"));
- ea_list = get_ea_list_from_file(ctx, conn, fsp, fname, &total_ea_len);
+ ea_list = get_ea_list_from_file(mem_ctx, conn, fsp, fname, &total_ea_len);
if (!ea_list || (total_ea_len > data_size)) {
data_size = 4;
SIVAL(pdata,0,4); /* EA List Length must be set to 4 if no EA's. */
break;
}
- data_size = fill_ea_buffer(ctx, pdata, data_size, conn, ea_list);
+ data_size = fill_ea_buffer(mem_ctx, pdata, data_size, conn, ea_list);
+ break;
+ }
+
+ case 0xFF0F:/*SMB2_INFO_QUERY_ALL_EAS*/
+ {
+ /* We have data_size bytes to put EA's into. */
+ size_t total_ea_len = 0;
+ struct ea_list *ea_file_list = NULL;
+
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB2_INFO_QUERY_ALL_EAS\n"));
+
+ /*TODO: add filtering and index handling */
+
+ ea_file_list = get_ea_list_from_file(mem_ctx,
+ conn, fsp,
+ fname,
+ &total_ea_len);
+ if (!ea_file_list) {
+ return NT_STATUS_NO_EAS_ON_FILE;
+ }
+
+ status = fill_ea_chained_buffer(mem_ctx,
+ pdata,
+ data_size,
+ &data_size,
+ conn, ea_file_list);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
break;
}
@@ -4400,10 +4218,10 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
case SMB_QUERY_FILE_BASIC_INFO:
if (info_level == SMB_QUERY_FILE_BASIC_INFO) {
- DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_BASIC_INFO\n"));
data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
} else {
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_BASIC_INFORMATION\n"));
data_size = 40;
SIVAL(pdata,36,0);
}
@@ -4424,7 +4242,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
case SMB_FILE_STANDARD_INFORMATION:
case SMB_QUERY_FILE_STANDARD_INFO:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_STANDARD_INFORMATION\n"));
data_size = 24;
SOFF_T(pdata,0,allocation_size);
SOFF_T(pdata,8,file_size);
@@ -4438,7 +4256,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
case SMB_QUERY_FILE_EA_INFO:
{
unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_EA_INFORMATION\n"));
data_size = 4;
SIVAL(pdata,0,ea_size);
break;
@@ -4448,15 +4266,14 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
case SMB_QUERY_FILE_ALT_NAME_INFO:
case SMB_FILE_ALTERNATE_NAME_INFORMATION:
{
+ int len;
char mangled_name[13];
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALTERNATE_NAME_INFORMATION\n"));
if (!name_to_8_3(base_name,mangled_name,
True,conn->params)) {
- reply_nterror(
- req,
- NT_STATUS_NO_MEMORY);
+ return NT_STATUS_NO_MEMORY;
}
- len = srvstr_push(dstart, req->flags2,
+ len = srvstr_push(dstart, flags2,
pdata+4, mangled_name,
PTR_DIFF(dend, pdata+4),
STR_UNICODE);
@@ -4466,28 +4283,31 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
}
case SMB_QUERY_FILE_NAME_INFO:
+ {
+ int len;
/*
this must be *exactly* right for ACLs on mapped drives to work
*/
- len = srvstr_push(dstart, req->flags2,
+ len = srvstr_push(dstart, flags2,
pdata+4, dos_fname,
PTR_DIFF(dend, pdata+4),
STR_UNICODE);
- DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_NAME_INFO\n"));
data_size = 4 + len;
SIVAL(pdata,0,len);
break;
+ }
case SMB_FILE_ALLOCATION_INFORMATION:
case SMB_QUERY_FILE_ALLOCATION_INFO:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n"));
data_size = 8;
SOFF_T(pdata,0,allocation_size);
break;
case SMB_FILE_END_OF_FILE_INFORMATION:
case SMB_QUERY_FILE_END_OF_FILEINFO:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_END_OF_FILE_INFORMATION\n"));
data_size = 8;
SOFF_T(pdata,0,file_size);
break;
@@ -4495,8 +4315,9 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
case SMB_QUERY_FILE_ALL_INFO:
case SMB_FILE_ALL_INFORMATION:
{
+ int len;
unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
put_long_date_timespec(pdata,create_time_ts);
put_long_date_timespec(pdata+8,atime_ts);
put_long_date_timespec(pdata+16,mtime_ts); /* write time */
@@ -4513,7 +4334,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
pdata += 24;
SIVAL(pdata,0,ea_size);
pdata += 4; /* EA info */
- len = srvstr_push(dstart, req->flags2,
+ len = srvstr_push(dstart, flags2,
pdata+4, dos_fname,
PTR_DIFF(dend, pdata+4),
STR_UNICODE);
@@ -4522,27 +4343,52 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
data_size = PTR_DIFF(pdata,(*ppdata));
break;
}
- case SMB_FILE_INTERNAL_INFORMATION:
- /* This should be an index number - looks like
- dev/ino to me :-)
- I think this causes us to fail the IFSKIT
- BasicFileInformationTest. -tpot */
+ case 0xFF12:/*SMB2_FILE_ALL_INFORMATION*/
+ {
+ int len;
+ unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n"));
+ put_long_date_timespec(pdata+0x00,create_time_ts);
+ put_long_date_timespec(pdata+0x08,atime_ts);
+ put_long_date_timespec(pdata+0x10,mtime_ts); /* write time */
+ put_long_date_timespec(pdata+0x18,mtime_ts); /* change time */
+ SIVAL(pdata, 0x20, mode);
+ SIVAL(pdata, 0x24, 0); /* padding. */
+ SBVAL(pdata, 0x28, allocation_size);
+ SBVAL(pdata, 0x30, file_size);
+ SIVAL(pdata, 0x38, nlink);
+ SCVAL(pdata, 0x3C, delete_pending);
+ SCVAL(pdata, 0x3D, (mode&aDIR)?1:0);
+ SSVAL(pdata, 0x3E, 0); /* padding */
+ SBVAL(pdata, 0x40, file_index);
+ SIVAL(pdata, 0x48, ea_size);
+ SIVAL(pdata, 0x4C, access_mask);
+ SBVAL(pdata, 0x50, pos);
+ SIVAL(pdata, 0x58, mode); /*TODO: mode != mode fix this!!! */
+ SIVAL(pdata, 0x5C, 0); /* No alignment needed. */
+
+ pdata += 0x60;
+
+ len = srvstr_push(dstart, flags2,
+ pdata+4, dos_fname,
+ PTR_DIFF(dend, pdata+4),
+ STR_UNICODE);
+ SIVAL(pdata,0,len);
+ pdata += 4 + len;
+ data_size = PTR_DIFF(pdata,(*ppdata));
+ break;
+ }
+ case SMB_FILE_INTERNAL_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
- SIVAL(pdata,0,sbuf.st_ex_ino); /* FileIndexLow */
- SIVAL(pdata,4,sbuf.st_ex_dev); /* FileIndexHigh */
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
+ SBVAL(pdata, 0, file_index);
data_size = 8;
break;
case SMB_FILE_ACCESS_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
- if (fsp) {
- SIVAL(pdata,0,fsp->access_mask);
- } else {
- /* GENERIC_EXECUTE mapping from Windows */
- SIVAL(pdata,0,0x12019F);
- }
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
+ SIVAL(pdata, 0, access_mask);
data_size = 4;
break;
@@ -4551,32 +4397,32 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
{
size_t byte_len;
byte_len = dos_PutUniCode(pdata+4,dos_fname,(size_t)max_data_bytes,False);
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NAME_INFORMATION\n"));
SIVAL(pdata,0,byte_len);
data_size = 4 + byte_len;
break;
}
case SMB_FILE_DISPOSITION_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_DISPOSITION_INFORMATION\n"));
data_size = 1;
SCVAL(pdata,0,delete_pending);
break;
case SMB_FILE_POSITION_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_POSITION_INFORMATION\n"));
data_size = 8;
SOFF_T(pdata,0,pos);
break;
case SMB_FILE_MODE_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_MODE_INFORMATION\n"));
SIVAL(pdata,0,mode);
data_size = 4;
break;
case SMB_FILE_ALIGNMENT_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALIGNMENT_INFORMATION\n"));
SIVAL(pdata,0,0); /* No alignment needed. */
data_size = 4;
break;
@@ -4594,7 +4440,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
unsigned int num_streams;
struct stream_struct *streams;
- DEBUG(10,("call_trans2qfilepathinfo: "
+ DEBUG(10,("smbd_do_qfilepathinfo: "
"SMB_FILE_STREAM_INFORMATION\n"));
status = SMB_VFS_STREAMINFO(
@@ -4604,8 +4450,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("could not get stream info: %s\n",
nt_errstr(status)));
- reply_nterror(req, status);
- return;
+ return status;
}
status = marshall_stream_info(num_streams, streams,
@@ -4615,8 +4460,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("marshall_stream_info failed: %s\n",
nt_errstr(status)));
- reply_nterror(req, status);
- return;
+ return status;
}
TALLOC_FREE(streams);
@@ -4625,7 +4469,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
}
case SMB_QUERY_COMPRESSION_INFO:
case SMB_FILE_COMPRESSION_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_COMPRESSION_INFORMATION\n"));
SOFF_T(pdata,0,file_size);
SIVAL(pdata,8,0); /* ??? */
SIVAL(pdata,12,0); /* ??? */
@@ -4633,7 +4477,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
break;
case SMB_FILE_NETWORK_OPEN_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
put_long_date_timespec(pdata,create_time_ts);
put_long_date_timespec(pdata+8,atime_ts);
put_long_date_timespec(pdata+16,mtime_ts); /* write time */
@@ -4646,7 +4490,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
break;
case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
- DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ATTRIBUTE_TAG_INFORMATION\n"));
SIVAL(pdata,0,mode);
SIVAL(pdata,4,0);
data_size = 8;
@@ -4663,7 +4507,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
{
int i;
- DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC "));
+ DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC "));
for (i=0; i<100; i++)
DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
@@ -4679,7 +4523,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
{
int i;
- DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 "));
+ DEBUG(4,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_INFO2 "));
for (i=0; i<100; i++)
DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
@@ -4690,33 +4534,28 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
case SMB_QUERY_FILE_UNIX_LINK:
{
- char *buffer = TALLOC_ARRAY(ctx, char, PATH_MAX+1);
+ int len;
+ char *buffer = TALLOC_ARRAY(mem_ctx, char, PATH_MAX+1);
if (!buffer) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
+ return NT_STATUS_NO_MEMORY;
}
- DEBUG(10,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
+ DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
#ifdef S_ISLNK
if(!S_ISLNK(sbuf.st_ex_mode)) {
- reply_unixerror(req, ERRSRV,
- ERRbadlink);
- return;
+ return NT_STATUS_DOS(ERRSRV, ERRbadlink);
}
#else
- reply_unixerror(req, ERRDOS, ERRbadlink);
- return;
+ return NT_STATUS_DOS(ERRDOS, ERRbadlink);
#endif
- len = SMB_VFS_READLINK(conn,fullpathname,
+ len = SMB_VFS_READLINK(conn,fname,
buffer, PATH_MAX);
if (len == -1) {
- reply_unixerror(req, ERRDOS,
- ERRnoaccess);
- return;
+ return map_nt_error_from_unix(errno);
}
buffer[len] = 0;
- len = srvstr_push(dstart, req->flags2,
+ len = srvstr_push(dstart, flags2,
pdata, buffer,
PTR_DIFF(dend, pdata),
STR_TERMINATE);
@@ -4741,17 +4580,18 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
}
if (file_acl == NULL && no_acl_syscall_error(errno)) {
- DEBUG(5,("call_trans2qfilepathinfo: ACLs not implemented on filesystem containing %s\n",
+ DEBUG(5,("smbd_do_qfilepathinfo: ACLs not implemented on filesystem containing %s\n",
fname ));
- reply_nterror(
- req,
- NT_STATUS_NOT_IMPLEMENTED);
- return;
+ return NT_STATUS_NOT_IMPLEMENTED;
}
if (S_ISDIR(sbuf.st_ex_mode)) {
if (fsp && fsp->is_directory) {
- def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
+ def_acl =
+ SMB_VFS_SYS_ACL_GET_FILE(
+ conn,
+ fsp->fsp_name->base_name,
+ SMB_ACL_TYPE_DEFAULT);
} else {
def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT);
}
@@ -4762,7 +4602,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
num_def_acls = count_acl_entries(conn, def_acl);
if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) {
- DEBUG(5,("call_trans2qfilepathinfo: data_size too small (%u) need %u\n",
+ DEBUG(5,("smbd_do_qfilepathinfo: data_size too small (%u) need %u\n",
data_size,
(unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE +
SMB_POSIX_ACL_HEADER_SIZE) ));
@@ -4772,10 +4612,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
if (def_acl) {
SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
}
- reply_nterror(
- req,
- NT_STATUS_BUFFER_TOO_SMALL);
- return;
+ return NT_STATUS_BUFFER_TOO_SMALL;
}
SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
@@ -4788,9 +4625,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
if (def_acl) {
SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
}
- reply_nterror(
- req, NT_STATUS_INTERNAL_ERROR);
- return;
+ return NT_STATUS_INTERNAL_ERROR;
}
if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, def_acl)) {
if (file_acl) {
@@ -4799,10 +4634,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
if (def_acl) {
SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
}
- reply_nterror(
- req,
- NT_STATUS_INTERNAL_ERROR);
- return;
+ return NT_STATUS_INTERNAL_ERROR;
}
if (file_acl) {
@@ -4824,10 +4656,13 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
uint32 lock_pid;
enum brl_type lock_type;
- if (total_data != POSIX_LOCK_DATA_SIZE) {
- reply_nterror(
- req, NT_STATUS_INVALID_PARAMETER);
- return;
+ /* We need an open file with a real fd for this. */
+ if (!fsp || fsp->is_directory || fsp->fh->fd == -1) {
+ return NT_STATUS_INVALID_LEVEL;
+ }
+
+ if (lock_data_count != POSIX_LOCK_DATA_SIZE) {
+ return NT_STATUS_INVALID_PARAMETER;
}
switch (SVAL(pdata, POSIX_LOCK_TYPE_OFFSET)) {
@@ -4840,10 +4675,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
case POSIX_LOCK_TYPE_UNLOCK:
default:
/* There's no point in asking for an unlock... */
- reply_nterror(
- req,
- NT_STATUS_INVALID_PARAMETER);
- return;
+ return NT_STATUS_INVALID_PARAMETER;
}
lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET);
@@ -4888,15 +4720,393 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
memcpy(pdata, lock_data, POSIX_LOCK_DATA_SIZE);
SSVAL(pdata, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK);
} else {
- reply_nterror(req, status);
- return;
+ return status;
}
break;
}
default:
+ return NT_STATUS_INVALID_LEVEL;
+ }
+
+ *pdata_size = data_size;
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
+ file name or file id).
+****************************************************************************/
+
+static void call_trans2qfilepathinfo(connection_struct *conn,
+ struct smb_request *req,
+ unsigned int tran_call,
+ char **pparams, int total_params,
+ char **ppdata, int total_data,
+ unsigned int max_data_bytes)
+{
+ char *params = *pparams;
+ char *pdata = *ppdata;
+ uint16 info_level;
+ unsigned int data_size = 0;
+ unsigned int param_size = 2;
+ struct smb_filename *smb_fname = NULL;
+ bool delete_pending = False;
+ struct timespec write_time_ts;
+ files_struct *fsp = NULL;
+ struct file_id fileid;
+ struct ea_list *ea_list = NULL;
+ int lock_data_count = 0;
+ char *lock_data = NULL;
+ bool ms_dfs_link = false;
+ NTSTATUS status = NT_STATUS_OK;
+
+ if (!params) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
+
+ ZERO_STRUCT(write_time_ts);
+
+ if (tran_call == TRANSACT2_QFILEINFO) {
+ if (total_params < 4) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
+
+ if (IS_IPC(conn)) {
+ call_trans2qpipeinfo(conn, req, tran_call,
+ pparams, total_params,
+ ppdata, total_data,
+ max_data_bytes);
+ return;
+ }
+
+ fsp = file_fsp(req, SVAL(params,0));
+ info_level = SVAL(params,2);
+
+ DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
+
+ if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
reply_nterror(req, NT_STATUS_INVALID_LEVEL);
return;
+ }
+
+ /* Initial check for valid fsp ptr. */
+ if (!check_fsp_open(conn, req, fsp)) {
+ return;
+ }
+
+ status = copy_smb_filename(talloc_tos(), fsp->fsp_name,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ return;
+ }
+
+ if(fsp->fake_file_handle) {
+ /*
+ * This is actually for the QUOTA_FAKE_FILE --metze
+ */
+
+ /* We know this name is ok, it's already passed the checks. */
+
+ } else if(fsp->is_directory || fsp->fh->fd == -1) {
+ /*
+ * This is actually a QFILEINFO on a directory
+ * handle (returned from an NT SMB). NT5.0 seems
+ * to do this call. JRA.
+ */
+
+ if (INFO_LEVEL_IS_UNIX(info_level)) {
+ /* Always do lstat for UNIX calls. */
+ if (SMB_VFS_LSTAT(conn, smb_fname)) {
+ DEBUG(3,("call_trans2qfilepathinfo: "
+ "SMB_VFS_LSTAT of %s failed "
+ "(%s)\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno)));
+ reply_nterror(req,
+ map_nt_error_from_unix(errno));
+ return;
+ }
+ } else if (SMB_VFS_STAT(conn, smb_fname)) {
+ DEBUG(3,("call_trans2qfilepathinfo: "
+ "SMB_VFS_STAT of %s failed (%s)\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno)));
+ reply_nterror(req,
+ map_nt_error_from_unix(errno));
+ return;
+ }
+
+ fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
+ get_file_infos(fileid, &delete_pending, &write_time_ts);
+ } else {
+ /*
+ * Original code - this is an open file.
+ */
+ if (!check_fsp(conn, req, fsp)) {
+ return;
+ }
+
+ if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
+ DEBUG(3, ("fstat of fnum %d failed (%s)\n",
+ fsp->fnum, strerror(errno)));
+ reply_nterror(req,
+ map_nt_error_from_unix(errno));
+ return;
+ }
+ fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
+ get_file_infos(fileid, &delete_pending, &write_time_ts);
+ }
+
+ } else {
+ char *fname = NULL;
+
+ /* qpathinfo */
+ if (total_params < 7) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
+
+ info_level = SVAL(params,0);
+
+ DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
+
+ if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
+ reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+ return;
+ }
+
+ srvstr_get_path(req, params, req->flags2, &fname, &params[6],
+ total_params - 6,
+ STR_TERMINATE, &status);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ return;
+ }
+
+ status = filename_convert(req,
+ conn,
+ req->flags2 & FLAGS2_DFS_PATHNAMES,
+ fname,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
+ reply_botherror(req,
+ NT_STATUS_PATH_NOT_COVERED,
+ ERRSRV, ERRbadpath);
+ return;
+ }
+ reply_nterror(req, status);
+ return;
+ }
+
+ /* If this is a stream, check if there is a delete_pending. */
+ if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
+ && is_ntfs_stream_smb_fname(smb_fname)) {
+ struct smb_filename *smb_fname_base = NULL;
+
+ /* Create an smb_filename with stream_name == NULL. */
+ status =
+ create_synthetic_smb_fname(talloc_tos(),
+ smb_fname->base_name,
+ NULL, NULL,
+ &smb_fname_base);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ return;
+ }
+
+ if (INFO_LEVEL_IS_UNIX(info_level)) {
+ /* Always do lstat for UNIX calls. */
+ if (SMB_VFS_LSTAT(conn, smb_fname_base) != 0) {
+ DEBUG(3,("call_trans2qfilepathinfo: "
+ "SMB_VFS_LSTAT of %s failed "
+ "(%s)\n",
+ smb_fname_str_dbg(smb_fname_base),
+ strerror(errno)));
+ TALLOC_FREE(smb_fname_base);
+ reply_nterror(req,
+ map_nt_error_from_unix(errno));
+ return;
+ }
+ } else {
+ if (SMB_VFS_STAT(conn, smb_fname_base) != 0) {
+ DEBUG(3,("call_trans2qfilepathinfo: "
+ "fileinfo of %s failed "
+ "(%s)\n",
+ smb_fname_str_dbg(smb_fname_base),
+ strerror(errno)));
+ TALLOC_FREE(smb_fname_base);
+ reply_nterror(req,
+ map_nt_error_from_unix(errno));
+ return;
+ }
+ }
+
+ fileid = vfs_file_id_from_sbuf(conn,
+ &smb_fname_base->st);
+ TALLOC_FREE(smb_fname_base);
+ get_file_infos(fileid, &delete_pending, NULL);
+ if (delete_pending) {
+ reply_nterror(req, NT_STATUS_DELETE_PENDING);
+ return;
+ }
+ }
+
+ if (INFO_LEVEL_IS_UNIX(info_level)) {
+ /* Always do lstat for UNIX calls. */
+ if (SMB_VFS_LSTAT(conn, smb_fname)) {
+ DEBUG(3,("call_trans2qfilepathinfo: "
+ "SMB_VFS_LSTAT of %s failed (%s)\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno)));
+ reply_nterror(req,
+ map_nt_error_from_unix(errno));
+ return;
+ }
+
+ } else if (!VALID_STAT(smb_fname->st) &&
+ SMB_VFS_STAT(conn, smb_fname) &&
+ (info_level != SMB_INFO_IS_NAME_VALID)) {
+ ms_dfs_link = check_msdfs_link(conn,
+ smb_fname->base_name,
+ &smb_fname->st);
+
+ if (!ms_dfs_link) {
+ DEBUG(3,("call_trans2qfilepathinfo: "
+ "SMB_VFS_STAT of %s failed (%s)\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno)));
+ reply_nterror(req,
+ map_nt_error_from_unix(errno));
+ return;
+ }
+ }
+
+ fileid = vfs_file_id_from_sbuf(conn, &smb_fname->st);
+ get_file_infos(fileid, &delete_pending, &write_time_ts);
+ if (delete_pending) {
+ reply_nterror(req, NT_STATUS_DELETE_PENDING);
+ return;
+ }
+ }
+
+ DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d "
+ "total_data=%d\n", smb_fname_str_dbg(smb_fname),
+ fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
+
+ /* Pull out any data sent here before we realloc. */
+ switch (info_level) {
+ case SMB_INFO_QUERY_EAS_FROM_LIST:
+ {
+ /* Pull any EA list from the data portion. */
+ uint32 ea_size;
+
+ if (total_data < 4) {
+ reply_nterror(
+ req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
+ ea_size = IVAL(pdata,0);
+
+ if (total_data > 0 && ea_size != total_data) {
+ DEBUG(4,("call_trans2qfilepathinfo: Rejecting EA request with incorrect \
+total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pdata,0) ));
+ reply_nterror(
+ req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
+
+ if (!lp_ea_support(SNUM(conn))) {
+ reply_doserror(req, ERRDOS,
+ ERReasnotsupported);
+ return;
+ }
+
+ /* Pull out the list of names. */
+ ea_list = read_ea_name_list(req, pdata + 4, ea_size - 4);
+ if (!ea_list) {
+ reply_nterror(
+ req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
+ break;
+ }
+
+ case SMB_QUERY_POSIX_LOCK:
+ {
+ if (fsp == NULL || fsp->fh->fd == -1) {
+ reply_nterror(req, NT_STATUS_INVALID_HANDLE);
+ return;
+ }
+
+ if (total_data != POSIX_LOCK_DATA_SIZE) {
+ reply_nterror(
+ req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
+
+ /* Copy the lock range data. */
+ lock_data = (char *)TALLOC_MEMDUP(
+ req, pdata, total_data);
+ if (!lock_data) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
+ }
+ lock_data_count = total_data;
+ }
+ default:
+ break;
+ }
+
+ *pparams = (char *)SMB_REALLOC(*pparams,2);
+ if (*pparams == NULL) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
+ }
+ params = *pparams;
+ SSVAL(params,0,0);
+
+ /*
+ * draft-leach-cifs-v1-spec-02.txt
+ * 4.2.14 TRANS2_QUERY_PATH_INFORMATION: Get File Attributes given Path
+ * says:
+ *
+ * The requested information is placed in the Data portion of the
+ * transaction response. For the information levels greater than 0x100,
+ * the transaction response has 1 parameter word which should be
+ * ignored by the client.
+ *
+ * However Windows only follows this rule for the IS_NAME_VALID call.
+ */
+ switch (info_level) {
+ case SMB_INFO_IS_NAME_VALID:
+ param_size = 0;
+ break;
+ }
+
+ if ((info_level & 0xFF00) == 0xFF00) {
+ /*
+ * We use levels that start with 0xFF00
+ * internally to represent SMB2 specific levels
+ */
+ reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+ return;
+ }
+
+ status = smbd_do_qfilepathinfo(conn, req, info_level,
+ fsp, smb_fname,
+ delete_pending, write_time_ts,
+ ms_dfs_link, ea_list,
+ lock_data_count, lock_data,
+ req->flags2, max_data_bytes,
+ ppdata, &data_size);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ return;
}
send_trans2_replies(conn, req, params, param_size, *ppdata, data_size,
@@ -4915,8 +5125,6 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
const struct smb_filename *smb_fname_old,
const struct smb_filename *smb_fname_new)
{
- char *oldname = NULL;
- char *newname = NULL;
NTSTATUS status = NT_STATUS_OK;
/* source must already exist. */
@@ -4934,25 +5142,22 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
return NT_STATUS_FILE_IS_A_DIRECTORY;
}
- status = get_full_smb_filename(ctx, smb_fname_new, &newname);
- if (!NT_STATUS_IS_OK(status)) {
- goto out;
- }
- status = get_full_smb_filename(ctx, smb_fname_old, &oldname);
- if (!NT_STATUS_IS_OK(status)) {
- goto out;
+ /* Setting a hardlink to/from a stream isn't currently supported. */
+ if (is_ntfs_stream_smb_fname(smb_fname_old) ||
+ is_ntfs_stream_smb_fname(smb_fname_new)) {
+ return NT_STATUS_INVALID_PARAMETER;
}
- DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n", newname, oldname ));
+ DEBUG(10,("hardlink_internals: doing hard link %s -> %s\n",
+ smb_fname_old->base_name, smb_fname_new->base_name));
- if (SMB_VFS_LINK(conn,oldname,newname) != 0) {
+ if (SMB_VFS_LINK(conn, smb_fname_old->base_name,
+ smb_fname_new->base_name) != 0) {
status = map_nt_error_from_unix(errno);
DEBUG(3,("hardlink_internals: Error %s hard link %s -> %s\n",
- nt_errstr(status), newname, oldname));
+ nt_errstr(status), smb_fname_old->base_name,
+ smb_fname_new->base_name));
}
- out:
- TALLOC_FREE(newname);
- TALLOC_FREE(oldname);
return status;
}
@@ -5317,8 +5522,9 @@ static NTSTATUS smb_file_position_information(connection_struct *conn,
}
#endif /* LARGE_SMB_OFF_T */
- DEBUG(10,("smb_file_position_information: Set file position information for file %s to %.0f\n",
- fsp->fsp_name, (double)position_information ));
+ DEBUG(10,("smb_file_position_information: Set file position "
+ "information for file %s to %.0f\n", fsp_str_dbg(fsp),
+ (double)position_information));
fsp->fh->position_information = position_information;
return NT_STATUS_OK;
}
@@ -5351,10 +5557,10 @@ static NTSTATUS smb_set_file_unix_link(connection_struct *conn,
struct smb_request *req,
const char *pdata,
int total_data,
- const char *fname)
+ const struct smb_filename *smb_fname)
{
char *link_target = NULL;
- const char *newname = fname;
+ const char *newname = smb_fname->base_name;
NTSTATUS status = NT_STATUS_OK;
TALLOC_CTX *ctx = talloc_tos();
@@ -5454,8 +5660,7 @@ static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
oldname,
- &smb_fname_old,
- NULL);
+ &smb_fname_old);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -5529,8 +5734,8 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
/* Create an smb_fname to call rename_internals_fsp() with. */
status = create_synthetic_smb_fname(talloc_tos(),
- fsp->base_fsp->fsp_name,
- newname, NULL, &smb_fname);
+ fsp->base_fsp->fsp_name->base_name, newname, NULL,
+ &smb_fname);
if (!NT_STATUS_IS_OK(status)) {
goto out;
}
@@ -5547,7 +5752,7 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
/* Create a char * to call rename_internals() with. */
base_name = talloc_asprintf(ctx, "%s%s",
- fsp->base_fsp->fsp_name,
+ fsp->base_fsp->fsp_name->base_name,
newname);
if (!base_name) {
status = NT_STATUS_NO_MEMORY;
@@ -5604,13 +5809,15 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
}
if (fsp) {
- DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
- fsp->fnum, fsp->fsp_name, base_name ));
+ DEBUG(10,("smb_file_rename_information: "
+ "SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
+ fsp->fnum, fsp_str_dbg(fsp), base_name));
status = rename_internals_fsp(conn, fsp, smb_fname, 0,
overwrite);
} else {
- DEBUG(10,("smb_file_rename_information: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
- fname, base_name ));
+ DEBUG(10,("smb_file_rename_information: "
+ "SMB_FILE_RENAME_INFORMATION %s -> %s\n",
+ fname, base_name));
status = rename_internals(ctx, conn, req, fname, base_name, 0,
overwrite, False, dest_has_wcard,
FILE_WRITE_ATTRIBUTES);
@@ -5629,8 +5836,7 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn,
const char *pdata,
int total_data,
files_struct *fsp,
- const char *fname,
- SMB_STRUCT_STAT *psbuf)
+ const struct smb_filename *smb_fname)
{
uint16 posix_acl_version;
uint16 num_file_acls;
@@ -5665,18 +5871,20 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn,
}
DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n",
- fname ? fname : fsp->fsp_name,
+ smb_fname ? smb_fname_str_dbg(smb_fname) : fsp_str_dbg(fsp),
(unsigned int)num_file_acls,
(unsigned int)num_def_acls));
- if (valid_file_acls && !set_unix_posix_acl(conn, fsp, fname, num_file_acls,
- pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
+ if (valid_file_acls && !set_unix_posix_acl(conn, fsp,
+ smb_fname->base_name, num_file_acls,
+ pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
return map_nt_error_from_unix(errno);
}
- if (valid_def_acls && !set_unix_posix_default_acl(conn, fname, psbuf, num_def_acls,
- pdata + SMB_POSIX_ACL_HEADER_SIZE +
- (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
+ if (valid_def_acls && !set_unix_posix_default_acl(conn,
+ smb_fname->base_name, &smb_fname->st, num_def_acls,
+ pdata + SMB_POSIX_ACL_HEADER_SIZE +
+ (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
return map_nt_error_from_unix(errno);
}
return NT_STATUS_OK;
@@ -5752,7 +5960,7 @@ static NTSTATUS smb_set_posix_lock(connection_struct *conn,
DEBUG(10,("smb_set_posix_lock: file %s, lock_type = %u,"
"lock_pid = %u, count = %.0f, offset = %.0f\n",
- fsp->fsp_name,
+ fsp_str_dbg(fsp),
(unsigned int)lock_type,
(unsigned int)lock_pid,
(double)count,
@@ -6444,11 +6652,9 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn,
struct smb_request *req,
char **ppdata,
int total_data,
- const char *fname,
- SMB_STRUCT_STAT *psbuf,
+ struct smb_filename *smb_fname,
int *pdata_return_size)
{
- struct smb_filename *smb_fname;
NTSTATUS status = NT_STATUS_OK;
uint32 raw_unixmode = 0;
uint32 mod_unixmode = 0;
@@ -6465,7 +6671,8 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn,
raw_unixmode = IVAL(pdata,8);
/* Next 4 bytes are not yet defined. */
- status = unix_perms_from_wire(conn, psbuf, raw_unixmode, PERM_NEW_DIR, &unixmode);
+ status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
+ PERM_NEW_DIR, &unixmode);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -6473,13 +6680,7 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn,
mod_unixmode = (uint32)unixmode | FILE_FLAG_POSIX_SEMANTICS;
DEBUG(10,("smb_posix_mkdir: file %s, mode 0%o\n",
- fname, (unsigned int)unixmode ));
-
- status = create_synthetic_smb_fname_split(talloc_tos(), fname, psbuf,
- &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
+ smb_fname_str_dbg(smb_fname), (unsigned int)unixmode));
status = SMB_VFS_CREATE_FILE(
conn, /* conn */
@@ -6498,9 +6699,6 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn,
&fsp, /* result */
&info); /* pinfo */
- *psbuf = smb_fname->st;
- TALLOC_FREE(smb_fname);
-
if (NT_STATUS_IS_OK(status)) {
close_file(req, fsp, NORMAL_CLOSE);
}
@@ -6531,12 +6729,14 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn,
case SMB_QUERY_FILE_UNIX_BASIC:
SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
SSVAL(pdata,10,0); /* Padding. */
- store_file_unix_basic(conn, pdata + 12, fsp, psbuf);
+ store_file_unix_basic(conn, pdata + 12, fsp,
+ &smb_fname->st);
break;
case SMB_QUERY_FILE_UNIX_INFO2:
SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
SSVAL(pdata,10,0); /* Padding. */
- store_file_unix_basic_info2(conn, pdata + 12, fsp, psbuf);
+ store_file_unix_basic_info2(conn, pdata + 12, fsp,
+ &smb_fname->st);
break;
default:
SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
@@ -6555,11 +6755,9 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
struct smb_request *req,
char **ppdata,
int total_data,
- const char *fname,
- SMB_STRUCT_STAT *psbuf,
+ struct smb_filename *smb_fname,
int *pdata_return_size)
{
- struct smb_filename *smb_fname = NULL;
bool extended_oplock_granted = False;
char *pdata = *ppdata;
uint32 flags = 0;
@@ -6592,8 +6790,7 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
return smb_posix_mkdir(conn, req,
ppdata,
total_data,
- fname,
- psbuf,
+ smb_fname,
pdata_return_size);
}
@@ -6632,11 +6829,10 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
raw_unixmode = IVAL(pdata,8);
/* Next 4 bytes are not yet defined. */
- status = unix_perms_from_wire(conn,
- psbuf,
- raw_unixmode,
- VALID_STAT(*psbuf) ? PERM_EXISTING_FILE : PERM_NEW_FILE,
- &unixmode);
+ status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode,
+ (VALID_STAT(smb_fname->st) ?
+ PERM_EXISTING_FILE : PERM_NEW_FILE),
+ &unixmode);
if (!NT_STATUS_IS_OK(status)) {
return status;
@@ -6655,16 +6851,10 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
}
DEBUG(10,("smb_posix_open: file %s, smb_posix_flags = %u, mode 0%o\n",
- fname,
+ smb_fname_str_dbg(smb_fname),
(unsigned int)wire_open_mode,
(unsigned int)unixmode ));
- status = create_synthetic_smb_fname_split(talloc_tos(), fname, psbuf,
- &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
status = SMB_VFS_CREATE_FILE(
conn, /* conn */
req, /* req */
@@ -6683,9 +6873,6 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
&fsp, /* result */
&info); /* pinfo */
- *psbuf = smb_fname->st;
- TALLOC_FREE(smb_fname);
-
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -6738,12 +6925,14 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
case SMB_QUERY_FILE_UNIX_BASIC:
SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_BASIC);
SSVAL(pdata,10,0); /* padding. */
- store_file_unix_basic(conn, pdata + 12, fsp, psbuf);
+ store_file_unix_basic(conn, pdata + 12, fsp,
+ &smb_fname->st);
break;
case SMB_QUERY_FILE_UNIX_INFO2:
SSVAL(pdata,8,SMB_QUERY_FILE_UNIX_INFO2);
SSVAL(pdata,10,0); /* padding. */
- store_file_unix_basic_info2(conn, pdata + 12, fsp, psbuf);
+ store_file_unix_basic_info2(conn, pdata + 12, fsp,
+ &smb_fname->st);
break;
default:
SSVAL(pdata,8,SMB_NO_INFO_LEVEL_RETURNED);
@@ -6826,7 +7015,7 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn,
NULL);
if (lck == NULL) {
DEBUG(0, ("smb_posix_unlink: Could not get share mode "
- "lock for file %s\n", fsp->fsp_name));
+ "lock for file %s\n", fsp_str_dbg(fsp)));
close_file(req, fsp, NORMAL_CLOSE);
return NT_STATUS_INVALID_PARAMETER;
}
@@ -6867,200 +7056,42 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn,
return close_file(req, fsp, NORMAL_CLOSE);
}
-/****************************************************************************
- Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
-****************************************************************************/
-
-static void call_trans2setfilepathinfo(connection_struct *conn,
- struct smb_request *req,
- unsigned int tran_call,
- char **pparams, int total_params,
- char **ppdata, int total_data,
- unsigned int max_data_bytes)
+NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
+ struct smb_request *req,
+ TALLOC_CTX *mem_ctx,
+ uint16_t info_level,
+ files_struct *fsp,
+ struct smb_filename *smb_fname,
+ char **ppdata, int total_data,
+ int *ret_data_size)
{
- char *params = *pparams;
char *pdata = *ppdata;
- uint16 info_level;
- SMB_STRUCT_STAT sbuf;
char *fname = NULL;
- struct smb_filename *smb_fname = NULL;
- files_struct *fsp = NULL;
NTSTATUS status = NT_STATUS_OK;
int data_return_size = 0;
- TALLOC_CTX *ctx = talloc_tos();
-
- if (!params) {
- reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
- }
-
- if (tran_call == TRANSACT2_SETFILEINFO) {
- if (total_params < 4) {
- reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
- }
-
- fsp = file_fsp(req, SVAL(params,0));
- /* Basic check for non-null fsp. */
- if (!check_fsp_open(conn, req, fsp)) {
- return;
- }
- info_level = SVAL(params,2);
-
- fname = talloc_strdup(talloc_tos(),fsp->fsp_name);
- if (!fname) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
- }
-
- status = create_synthetic_smb_fname_split(talloc_tos(), fname,
- NULL, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- return;
- }
-
- if(fsp->is_directory || fsp->fh->fd == -1) {
- /*
- * This is actually a SETFILEINFO on a directory
- * handle (returned from an NT SMB). NT5.0 seems
- * to do this call. JRA.
- */
- if (INFO_LEVEL_IS_UNIX(info_level)) {
- /* Always do lstat for UNIX calls. */
- if (SMB_VFS_LSTAT(conn, smb_fname)) {
- DEBUG(3,("call_trans2setfilepathinfo: "
- "SMB_VFS_LSTAT of %s failed "
- "(%s)\n",
- smb_fname_str_dbg(smb_fname),
- strerror(errno)));
- reply_unixerror(req,ERRDOS,ERRbadpath);
- return;
- }
- } else {
- if (SMB_VFS_STAT(conn, smb_fname) != 0) {
- DEBUG(3,("call_trans2setfilepathinfo: "
- "fileinfo of %s failed (%s)\n",
- smb_fname_str_dbg(smb_fname),
- strerror(errno)));
- reply_unixerror(req,ERRDOS,ERRbadpath);
- return;
- }
- }
- } else if (fsp->print_file) {
- /*
- * Doing a DELETE_ON_CLOSE should cancel a print job.
- */
- if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
- fsp->fh->private_options |= FILE_DELETE_ON_CLOSE;
-
- DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
- SSVAL(params,0,0);
- send_trans2_replies(conn, req, params, 2,
- *ppdata, 0,
- max_data_bytes);
- return;
- } else {
- reply_unixerror(req, ERRDOS, ERRbadpath);
- return;
- }
- } else {
- /*
- * Original code - this is an open file.
- */
- if (!check_fsp(conn, req, fsp)) {
- return;
- }
-
- if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
- DEBUG(3,("call_trans2setfilepathinfo: fstat "
- "of fnum %d failed (%s)\n", fsp->fnum,
- strerror(errno)));
- reply_unixerror(req, ERRDOS, ERRbadfid);
- return;
- }
- }
- } else {
- /* set path info */
- if (total_params < 7) {
- reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
- return;
- }
-
- info_level = SVAL(params,0);
- srvstr_get_path(ctx, params, req->flags2, &fname, &params[6],
- total_params - 6, STR_TERMINATE,
- &status);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- return;
- }
-
- status = filename_convert(ctx, conn,
- req->flags2 & FLAGS2_DFS_PATHNAMES,
- fname,
- &smb_fname,
- &fname);
- if (!NT_STATUS_IS_OK(status)) {
- if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
- reply_botherror(req,
- NT_STATUS_PATH_NOT_COVERED,
- ERRSRV, ERRbadpath);
- return;
- }
- reply_nterror(req, status);
- return;
- }
-
- if (INFO_LEVEL_IS_UNIX(info_level)) {
- /*
- * For CIFS UNIX extensions the target name may not exist.
- */
-
- /* Always do lstat for UNIX calls. */
- SMB_VFS_LSTAT(conn, smb_fname);
-
- } else if (!VALID_STAT(smb_fname->st) &&
- SMB_VFS_STAT(conn, smb_fname)) {
- DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of "
- "%s failed (%s)\n",
- smb_fname_str_dbg(smb_fname),
- strerror(errno)));
- reply_unixerror(req, ERRDOS, ERRbadpath);
- return;
- }
- }
-
- /* Set sbuf for use below. */
- sbuf = smb_fname->st;
+ *ret_data_size = 0;
if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ return NT_STATUS_INVALID_LEVEL;
}
if (!CAN_WRITE(conn)) {
/* Allow POSIX opens. The open path will deny
* any non-readonly opens. */
if (info_level != SMB_POSIX_PATH_OPEN) {
- reply_doserror(req, ERRSRV, ERRaccess);
- return;
+ return NT_STATUS_DOS(ERRSRV, ERRaccess);
}
}
- DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
- tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data));
-
- /* Realloc the parameter size */
- *pparams = (char *)SMB_REALLOC(*pparams,2);
- if (*pparams == NULL) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return;
+ status = get_full_smb_filename(mem_ctx, smb_fname, &fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
- params = *pparams;
- SSVAL(params,0,0);
+ DEBUG(3,("smbd_do_setfilepathinfo: %s (fnum %d) info_level=%d "
+ "totdata=%d\n", smb_fname_str_dbg(smb_fname),
+ fsp ? fsp->fnum : -1, info_level, total_data));
switch (info_level) {
@@ -7186,22 +7217,20 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
case SMB_SET_FILE_UNIX_LINK:
{
- if (tran_call != TRANSACT2_SETPATHINFO) {
+ if (fsp) {
/* We must have a pathname for this. */
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ return NT_STATUS_INVALID_LEVEL;
}
status = smb_set_file_unix_link(conn, req, pdata,
- total_data, fname);
+ total_data, smb_fname);
break;
}
case SMB_SET_FILE_UNIX_HLINK:
{
- if (tran_call != TRANSACT2_SETPATHINFO || smb_fname == NULL) {
+ if (fsp) {
/* We must have a pathname for this. */
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ return NT_STATUS_INVALID_LEVEL;
}
status = smb_set_file_unix_hlink(conn, req,
pdata, total_data,
@@ -7224,17 +7253,15 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
pdata,
total_data,
fsp,
- fname,
- &sbuf);
+ smb_fname);
break;
}
#endif
case SMB_SET_POSIX_LOCK:
{
- if (tran_call != TRANSACT2_SETFILEINFO) {
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ if (!fsp) {
+ return NT_STATUS_INVALID_LEVEL;
}
status = smb_set_posix_lock(conn, req,
pdata, total_data, fsp);
@@ -7243,27 +7270,24 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
case SMB_POSIX_PATH_OPEN:
{
- if (tran_call != TRANSACT2_SETPATHINFO) {
+ if (fsp) {
/* We must have a pathname for this. */
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ return NT_STATUS_INVALID_LEVEL;
}
status = smb_posix_open(conn, req,
ppdata,
total_data,
- fname,
- &sbuf,
+ smb_fname,
&data_return_size);
break;
}
case SMB_POSIX_PATH_UNLINK:
{
- if (tran_call != TRANSACT2_SETPATHINFO) {
+ if (fsp) {
/* We must have a pathname for this. */
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
- return;
+ return NT_STATUS_INVALID_LEVEL;
}
status = smb_posix_unlink(conn, req,
@@ -7274,10 +7298,196 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
}
default:
- reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+ return NT_STATUS_INVALID_LEVEL;
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ *ret_data_size = data_return_size;
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ Reply to a TRANS2_SETFILEINFO (set file info by fileid or pathname).
+****************************************************************************/
+
+static void call_trans2setfilepathinfo(connection_struct *conn,
+ struct smb_request *req,
+ unsigned int tran_call,
+ char **pparams, int total_params,
+ char **ppdata, int total_data,
+ unsigned int max_data_bytes)
+{
+ char *params = *pparams;
+ char *pdata = *ppdata;
+ uint16 info_level;
+ struct smb_filename *smb_fname = NULL;
+ files_struct *fsp = NULL;
+ NTSTATUS status = NT_STATUS_OK;
+ int data_return_size = 0;
+
+ if (!params) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
+
+ if (tran_call == TRANSACT2_SETFILEINFO) {
+ if (total_params < 4) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
+
+ fsp = file_fsp(req, SVAL(params,0));
+ /* Basic check for non-null fsp. */
+ if (!check_fsp_open(conn, req, fsp)) {
+ return;
+ }
+ info_level = SVAL(params,2);
+
+ status = copy_smb_filename(talloc_tos(), fsp->fsp_name,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ return;
+ }
+
+ if(fsp->is_directory || fsp->fh->fd == -1) {
+ /*
+ * This is actually a SETFILEINFO on a directory
+ * handle (returned from an NT SMB). NT5.0 seems
+ * to do this call. JRA.
+ */
+ if (INFO_LEVEL_IS_UNIX(info_level)) {
+ /* Always do lstat for UNIX calls. */
+ if (SMB_VFS_LSTAT(conn, smb_fname)) {
+ DEBUG(3,("call_trans2setfilepathinfo: "
+ "SMB_VFS_LSTAT of %s failed "
+ "(%s)\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno)));
+ reply_nterror(req, map_nt_error_from_unix(errno));
+ return;
+ }
+ } else {
+ if (SMB_VFS_STAT(conn, smb_fname) != 0) {
+ DEBUG(3,("call_trans2setfilepathinfo: "
+ "fileinfo of %s failed (%s)\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno)));
+ reply_nterror(req, map_nt_error_from_unix(errno));
+ return;
+ }
+ }
+ } else if (fsp->print_file) {
+ /*
+ * Doing a DELETE_ON_CLOSE should cancel a print job.
+ */
+ if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
+ fsp->fh->private_options |= FILE_DELETE_ON_CLOSE;
+
+ DEBUG(3,("call_trans2setfilepathinfo: "
+ "Cancelling print job (%s)\n",
+ fsp_str_dbg(fsp)));
+
+ SSVAL(params,0,0);
+ send_trans2_replies(conn, req, params, 2,
+ *ppdata, 0,
+ max_data_bytes);
+ return;
+ } else {
+ reply_doserror(req, ERRDOS, ERRbadpath);
+ return;
+ }
+ } else {
+ /*
+ * Original code - this is an open file.
+ */
+ if (!check_fsp(conn, req, fsp)) {
+ return;
+ }
+
+ if (SMB_VFS_FSTAT(fsp, &smb_fname->st) != 0) {
+ DEBUG(3,("call_trans2setfilepathinfo: fstat "
+ "of fnum %d failed (%s)\n", fsp->fnum,
+ strerror(errno)));
+ reply_nterror(req, map_nt_error_from_unix(errno));
+ return;
+ }
+ }
+ } else {
+ char *fname = NULL;
+
+ /* set path info */
+ if (total_params < 7) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
return;
+ }
+
+ info_level = SVAL(params,0);
+ srvstr_get_path(req, params, req->flags2, &fname, &params[6],
+ total_params - 6, STR_TERMINATE,
+ &status);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ return;
+ }
+
+ status = filename_convert(req, conn,
+ req->flags2 & FLAGS2_DFS_PATHNAMES,
+ fname,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
+ reply_botherror(req,
+ NT_STATUS_PATH_NOT_COVERED,
+ ERRSRV, ERRbadpath);
+ return;
+ }
+ reply_nterror(req, status);
+ return;
+ }
+
+ if (INFO_LEVEL_IS_UNIX(info_level)) {
+ /*
+ * For CIFS UNIX extensions the target name may not exist.
+ */
+
+ /* Always do lstat for UNIX calls. */
+ SMB_VFS_LSTAT(conn, smb_fname);
+
+ } else if (!VALID_STAT(smb_fname->st) &&
+ SMB_VFS_STAT(conn, smb_fname)) {
+ DEBUG(3,("call_trans2setfilepathinfo: SMB_VFS_STAT of "
+ "%s failed (%s)\n",
+ smb_fname_str_dbg(smb_fname),
+ strerror(errno)));
+ reply_nterror(req, map_nt_error_from_unix(errno));
+ return;
+ }
+ }
+
+ DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d "
+ "totdata=%d\n", tran_call, smb_fname_str_dbg(smb_fname),
+ fsp ? fsp->fnum : -1, info_level,total_data));
+
+ /* Realloc the parameter size */
+ *pparams = (char *)SMB_REALLOC(*pparams,2);
+ if (*pparams == NULL) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
}
+ params = *pparams;
+ SSVAL(params,0,0);
+
+ status = smbd_do_setfilepathinfo(conn, req, req,
+ info_level,
+ fsp,
+ smb_fname,
+ ppdata, total_data,
+ &data_return_size);
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(req->mid)) {
/* We have re-scheduled this call. */
@@ -7301,7 +7511,6 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
return;
}
- SSVAL(params,0,0);
send_trans2_replies(conn, req, params, 2, *ppdata, data_return_size,
max_data_bytes);
@@ -7349,8 +7558,7 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
directory,
- &smb_dname,
- NULL);
+ &smb_dname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 2b4124bf7b..cd78c7962e 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -487,10 +487,12 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
* Actually try and commit the space on disk....
*/
- DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n", fsp->fsp_name, (double)len ));
+ DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
+ fsp_str_dbg(fsp), (double)len));
if (((SMB_OFF_T)len) < 0) {
- DEBUG(0,("vfs_allocate_file_space: %s negative len requested.\n", fsp->fsp_name ));
+ DEBUG(0,("vfs_allocate_file_space: %s negative len "
+ "requested.\n", fsp_str_dbg(fsp)));
errno = EINVAL;
return -1;
}
@@ -505,8 +507,9 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
if (len < (uint64_t)st.st_ex_size) {
/* Shrink - use ftruncate. */
- DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current size %.0f\n",
- fsp->fsp_name, (double)st.st_ex_size ));
+ DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
+ "size %.0f\n", fsp_str_dbg(fsp),
+ (double)st.st_ex_size));
contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
@@ -530,13 +533,16 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
len -= st.st_ex_size;
len /= 1024; /* Len is now number of 1k blocks needed. */
- space_avail = get_dfree_info(conn,fsp->fsp_name,False,&bsize,&dfree,&dsize);
+ space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false,
+ &bsize, &dfree, &dsize);
if (space_avail == (uint64_t)-1) {
return -1;
}
- DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, needed blocks = %.0f, space avail = %.0f\n",
- fsp->fsp_name, (double)st.st_ex_size, (double)len, (double)space_avail ));
+ DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
+ "needed blocks = %.0f, space avail = %.0f\n",
+ fsp_str_dbg(fsp), (double)st.st_ex_size, (double)len,
+ (double)space_avail));
if (len > space_avail) {
errno = ENOSPC;
@@ -558,14 +564,15 @@ int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len)
contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
- DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n", fsp->fsp_name, (double)len));
+ DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
+ fsp_str_dbg(fsp), (double)len));
flush_write_cache(fsp, SIZECHANGE_FLUSH);
if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
set_filelen_write_cache(fsp, len);
notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_SIZE
| FILE_NOTIFY_CHANGE_ATTRIBUTES,
- fsp->fsp_name);
+ fsp->fsp_name->base_name);
}
contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
@@ -600,8 +607,10 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len)
return 0;
}
- DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to len %.0f (%.0f bytes)\n",
- fsp->fsp_name, (double)st.st_ex_size, (double)len, (double)(len - st.st_ex_size)));
+ DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
+ "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
+ (double)st.st_ex_size, (double)len,
+ (double)(len - st.st_ex_size)));
contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
@@ -625,8 +634,9 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len)
pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
if (pwrite_ret == -1) {
- DEBUG(10,("vfs_fill_sparse: SMB_VFS_PWRITE for file %s failed with error %s\n",
- fsp->fsp_name, strerror(errno) ));
+ DEBUG(10,("vfs_fill_sparse: SMB_VFS_PWRITE for file "
+ "%s failed with error %s\n",
+ fsp_str_dbg(fsp), strerror(errno)));
ret = -1;
goto out;
}
@@ -962,15 +972,28 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
#ifdef S_ISLNK
if (!lp_symlinks(SNUM(conn))) {
- SMB_STRUCT_STAT statbuf;
- if ( (vfs_lstat_smb_fname(conn,fname,&statbuf) != -1) &&
- (S_ISLNK(statbuf.st_ex_mode)) ) {
+ struct smb_filename *smb_fname = NULL;
+ NTSTATUS status;
+
+ status = create_synthetic_smb_fname(talloc_tos(), fname, NULL,
+ NULL, &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ if (free_resolved_name) {
+ SAFE_FREE(resolved_name);
+ }
+ return status;
+ }
+
+ if ( (SMB_VFS_LSTAT(conn, smb_fname) != -1) &&
+ (S_ISLNK(smb_fname->st.st_ex_mode)) ) {
if (free_resolved_name) {
SAFE_FREE(resolved_name);
}
DEBUG(3,("reduce_name: denied: file path name %s is a symlink\n",resolved_name));
+ TALLOC_FREE(smb_fname);
return NT_STATUS_ACCESS_DENIED;
}
+ TALLOC_FREE(smb_fname);
}
#endif
@@ -980,3 +1003,58 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
}
return NT_STATUS_OK;
}
+
+/**
+ * XXX: This is temporary and there should be no callers of this once
+ * smb_filename is plumbed through all path based operations.
+ */
+int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
+ SMB_STRUCT_STAT *psbuf)
+{
+ struct smb_filename *smb_fname = NULL;
+ NTSTATUS status;
+ int ret;
+
+ status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
+
+ ret = SMB_VFS_STAT(conn, smb_fname);
+ if (ret != -1) {
+ *psbuf = smb_fname->st;
+ }
+
+ TALLOC_FREE(smb_fname);
+ return ret;
+}
+
+/**
+ * XXX: This is temporary and there should be no callers of this once
+ * smb_filename is plumbed through all path based operations.
+ */
+int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
+ SMB_STRUCT_STAT *psbuf)
+{
+ struct smb_filename *smb_fname = NULL;
+ NTSTATUS status;
+ int ret;
+
+ status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
+ &smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
+
+ ret = SMB_VFS_LSTAT(conn, smb_fname);
+ if (ret != -1) {
+ *psbuf = smb_fname->st;
+ }
+
+ TALLOC_FREE(smb_fname);
+ return ret;
+}
+
diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c
index 33ced8fa54..cd550a4f48 100644
--- a/source3/torture/cmd_vfs.c
+++ b/source3/torture/cmd_vfs.c
@@ -317,11 +317,6 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
if (fsp == NULL) {
return NT_STATUS_NO_MEMORY;
}
- fsp->fsp_name = SMB_STRDUP(argv[1]);
- if (fsp->fsp_name == NULL) {
- SAFE_FREE(fsp);
- return NT_STATUS_NO_MEMORY;
- }
fsp->fh = SMB_MALLOC_P(struct fd_handle);
if (fsp->fh == NULL) {
SAFE_FREE(fsp->fsp_name);
@@ -333,18 +328,18 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
status = create_synthetic_smb_fname_split(mem_ctx, argv[1], NULL,
&smb_fname);
if (!NT_STATUS_IS_OK(status)) {
- SAFE_FREE(fsp->fsp_name);
SAFE_FREE(fsp);
return status;
}
+ fsp->fsp_name = smb_fname;
+
fsp->fh->fd = SMB_VFS_OPEN(vfs->conn, smb_fname, fsp, flags, mode);
- TALLOC_FREE(smb_fname);
if (fsp->fh->fd == -1) {
printf("open: error=%d (%s)\n", errno, strerror(errno));
SAFE_FREE(fsp->fh);
- SAFE_FREE(fsp->fsp_name);
SAFE_FREE(fsp);
+ TALLOC_FREE(smb_fname);
return NT_STATUS_UNSUCCESSFUL;
}
@@ -415,7 +410,7 @@ static NTSTATUS cmd_close(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
else
printf("close: ok\n");
- SAFE_FREE(vfs->files[fd]->fsp_name);
+ TALLOC_FREE(vfs->files[fd]->fsp_name);
SAFE_FREE(vfs->files[fd]->fh);
SAFE_FREE(vfs->files[fd]);
vfs->files[fd] = NULL;
diff --git a/source3/torture/locktest.c b/source3/torture/locktest.c
index 30b84c073d..a90c2e2dfe 100644
--- a/source3/torture/locktest.c
+++ b/source3/torture/locktest.c
@@ -341,9 +341,9 @@ static bool test_one(struct cli_state *cli[NSERVERS][NCONNECTIONS],
case OP_UNLOCK:
/* unset a lock */
for (server=0;server<NSERVERS;server++) {
- ret[server] = cli_unlock64(cli[server][conn],
+ ret[server] = NT_STATUS_IS_OK(cli_unlock64(cli[server][conn],
fnum[server][conn][f],
- start, len);
+ start, len));
status[server] = cli_nt_error(cli[server][conn]);
}
if (showall ||
diff --git a/source3/torture/locktest2.c b/source3/torture/locktest2.c
index 93adcb51a6..5c8a2d8019 100644
--- a/source3/torture/locktest2.c
+++ b/source3/torture/locktest2.c
@@ -132,7 +132,7 @@ static bool try_unlock(struct cli_state *c, int fstype,
switch (fstype) {
case FSTYPE_SMB:
- return cli_unlock(c, fd, start, len);
+ return NT_STATUS_IS_OK(cli_unlock(c, fd, start, len));
case FSTYPE_NFS:
lock.l_type = F_UNLCK;
diff --git a/source3/torture/pdbtest.c b/source3/torture/pdbtest.c
index ab7edde85d..950177c3ca 100644
--- a/source3/torture/pdbtest.c
+++ b/source3/torture/pdbtest.c
@@ -288,7 +288,7 @@ int main(int argc, char **argv)
pdb_set_homedir(out, "\\\\torture\\home", PDB_SET);
pdb_set_logon_script(out, "torture_script.cmd", PDB_SET);
- pdb_get_account_policy(AP_PASSWORD_HISTORY, &history);
+ pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &history);
if (history * PW_HISTORY_ENTRY_LEN < NT_HASH_LEN) {
buf = (uint8 *)TALLOC(ctx, NT_HASH_LEN);
} else {
@@ -311,8 +311,8 @@ int main(int argc, char **argv)
}
pdb_set_pw_history(out, buf, history, PDB_SET);
- pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &expire);
- pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &min_age);
+ pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &expire);
+ pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &min_age);
pdb_set_pass_last_set_time(out, time(NULL), PDB_SET);
if (expire == 0 || expire == (uint32)-1) {
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index aa7e83bcc8..f9192b12b7 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -492,7 +492,7 @@ static bool rw_torture(struct cli_state *c)
correct = False;
}
- if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
+ if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
printf("unlock failed (%s)\n", cli_errstr(c));
correct = False;
}
@@ -1429,12 +1429,12 @@ static bool run_locktest2(int dummy)
printf("lock at 100 failed (%s)\n", cli_errstr(cli));
}
cli_setpid(cli, 2);
- if (cli_unlock(cli, fnum1, 100, 4)) {
+ if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
printf("unlock at 100 succeeded! This is a locking bug\n");
correct = False;
}
- if (cli_unlock(cli, fnum1, 0, 4)) {
+ if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
printf("unlock1 succeeded! This is a locking bug\n");
correct = False;
} else {
@@ -1443,7 +1443,7 @@ static bool run_locktest2(int dummy)
NT_STATUS_RANGE_NOT_LOCKED)) return False;
}
- if (cli_unlock(cli, fnum1, 0, 8)) {
+ if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
printf("unlock2 succeeded! This is a locking bug\n");
correct = False;
} else {
@@ -1565,14 +1565,14 @@ static bool run_locktest3(int dummy)
for (offset=i=0;i<torture_numops;i++) {
NEXT_OFFSET;
- if (!cli_unlock(cli1, fnum1, offset-1, 1)) {
+ if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
printf("unlock1 %d failed (%s)\n",
i,
cli_errstr(cli1));
return False;
}
- if (!cli_unlock(cli2, fnum2, offset-2, 1)) {
+ if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
printf("unlock2 %d failed (%s)\n",
i,
cli_errstr(cli1));
@@ -1703,7 +1703,7 @@ static bool run_locktest4(int dummy)
ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
- cli_unlock(cli1, fnum1, 110, 6);
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
EXPECTED(ret, False);
printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
@@ -1721,30 +1721,30 @@ static bool run_locktest4(int dummy)
ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
- cli_unlock(cli1, fnum1, 140, 4) &&
- cli_unlock(cli1, fnum1, 140, 4);
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
EXPECTED(ret, True);
printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
- cli_unlock(cli1, fnum1, 150, 4) &&
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
(cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
!(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
- cli_unlock(cli1, fnum1, 150, 4);
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
EXPECTED(ret, True);
printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
- cli_unlock(cli1, fnum1, 160, 4) &&
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
(cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
(cli_read(cli2, fnum2, buf, 160, 4) == 4);
EXPECTED(ret, True);
printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
- cli_unlock(cli1, fnum1, 170, 4) &&
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
(cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
(cli_read(cli2, fnum2, buf, 170, 4) == 4);
EXPECTED(ret, True);
@@ -1752,7 +1752,7 @@ static bool run_locktest4(int dummy)
ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
- cli_unlock(cli1, fnum1, 190, 4) &&
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
!(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
(cli_read(cli2, fnum2, buf, 190, 4) == 4);
EXPECTED(ret, True);
@@ -1861,7 +1861,7 @@ static bool run_locktest5(int dummy)
/* Unlock the first process lock, then check this was the WRITE lock that was
removed. */
- ret = cli_unlock(cli1, fnum1, 0, 4) &&
+ ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
EXPECTED(ret, True);
@@ -1872,15 +1872,15 @@ static bool run_locktest5(int dummy)
/* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
- ret = cli_unlock(cli1, fnum1, 1, 1) &&
- cli_unlock(cli1, fnum1, 0, 4) &&
- cli_unlock(cli1, fnum1, 0, 4);
+ ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
+ NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
EXPECTED(ret, True);
printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
/* Ensure the next unlock fails. */
- ret = cli_unlock(cli1, fnum1, 0, 4);
+ ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
EXPECTED(ret, False);
printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
@@ -4295,6 +4295,18 @@ static bool run_simple_posix_open_test(int dummy)
goto out;
}
+ /* Do a POSIX lock/unlock. */
+ if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
+ printf("POSIX lock failed %s\n", cli_errstr(cli1));
+ goto out;
+ }
+
+ /* Punch a hole in the locked area. */
+ if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
+ printf("POSIX unlock failed %s\n", cli_errstr(cli1));
+ goto out;
+ }
+
cli_close(cli1, fnum1);
/* Open the symlink for read - this should fail. A POSIX
@@ -5749,17 +5761,45 @@ static bool run_local_substitute(int dummy)
return ok;
}
+static bool run_local_base64(int dummy)
+{
+ int i;
+ bool ret = true;
+
+ for (i=1; i<2000; i++) {
+ DATA_BLOB blob1, blob2;
+ char *b64;
+
+ blob1.data = talloc_array(talloc_tos(), uint8_t, i);
+ blob1.length = i;
+ generate_random_buffer(blob1.data, blob1.length);
+
+ b64 = base64_encode_data_blob(talloc_tos(), blob1);
+ if (b64 == NULL) {
+ d_fprintf(stderr, "base64_encode_data_blob failed "
+ "for %d bytes\n", i);
+ ret = false;
+ }
+ blob2 = base64_decode_data_blob(b64);
+ TALLOC_FREE(b64);
+
+ if (data_blob_cmp(&blob1, &blob2)) {
+ d_fprintf(stderr, "data_blob_cmp failed for %d "
+ "bytes\n", i);
+ ret = false;
+ }
+ TALLOC_FREE(blob1.data);
+ data_blob_free(&blob2);
+ }
+ return ret;
+}
+
static bool run_local_gencache(int dummy)
{
char *val;
time_t tm;
DATA_BLOB blob;
- if (!gencache_init()) {
- d_printf("%s: gencache_init() failed\n", __location__);
- return False;
- }
-
if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
d_printf("%s: gencache_set() failed\n", __location__);
return False;
@@ -5796,15 +5836,13 @@ static bool run_local_gencache(int dummy)
}
blob = data_blob_string_const_null("bar");
- tm = time(NULL);
+ tm = time(NULL) + 60;
if (!gencache_set_data_blob("foo", &blob, tm)) {
d_printf("%s: gencache_set_data_blob() failed\n", __location__);
return False;
}
- data_blob_free(&blob);
-
if (!gencache_get_data_blob("foo", &blob, NULL)) {
d_printf("%s: gencache_get_data_blob() failed\n", __location__);
return False;
@@ -5835,17 +5873,6 @@ static bool run_local_gencache(int dummy)
return False;
}
- if (!gencache_shutdown()) {
- d_printf("%s: gencache_shutdown() failed\n", __location__);
- return False;
- }
-
- if (gencache_shutdown()) {
- d_printf("%s: second gencache_shutdown() succeeded\n",
- __location__);
- return False;
- }
-
return True;
}
@@ -6487,6 +6514,7 @@ static struct {
{ "STREAMERROR", run_streamerror },
{ "LOCAL-SUBSTITUTE", run_local_substitute, 0},
{ "LOCAL-GENCACHE", run_local_gencache, 0},
+ { "LOCAL-BASE64", run_local_base64, 0},
{ "LOCAL-RBTREE", run_local_rbtree, 0},
{ "LOCAL-MEMCACHE", run_local_memcache, 0},
{ "LOCAL-STREAM-NAME", run_local_stream_name, 0},
diff --git a/source3/utils/net.c b/source3/utils/net.c
index 0e3946f5a5..f8bfab3e99 100644
--- a/source3/utils/net.c
+++ b/source3/utils/net.c
@@ -625,6 +625,7 @@ static struct functable net_func[] = {
int main(int argc, const char **argv)
{
int opt,i;
+ char *p;
int rc = 0;
int argc_new = 0;
const char ** argv_new;
@@ -635,10 +636,12 @@ static struct functable net_func[] = {
struct poptOption long_options[] = {
{"help", 'h', POPT_ARG_NONE, 0, 'h'},
{"workgroup", 'w', POPT_ARG_STRING, &c->opt_target_workgroup},
+ {"user", 'U', POPT_ARG_STRING, &c->opt_user_name, 'U'},
{"ipaddress", 'I', POPT_ARG_STRING, 0,'I'},
{"port", 'p', POPT_ARG_INT, &c->opt_port},
{"myname", 'n', POPT_ARG_STRING, &c->opt_requester_name},
{"server", 'S', POPT_ARG_STRING, &c->opt_host},
+ {"encrypt", 'e', POPT_ARG_NONE, NULL, 'e', "Encrypt SMB transport (UNIX extended servers only)" },
{"container", 'c', POPT_ARG_STRING, &c->opt_container},
{"comment", 'C', POPT_ARG_STRING, &c->opt_comment},
{"maxusers", 'M', POPT_ARG_INT, &c->opt_maxusers},
@@ -649,13 +652,15 @@ static struct functable net_func[] = {
{"stdin", 'i', POPT_ARG_NONE, &c->opt_stdin},
{"timeout", 't', POPT_ARG_INT, &c->opt_timeout},
{"request-timeout",0,POPT_ARG_INT, &c->opt_request_timeout},
+ {"machine-pass",'P', POPT_ARG_NONE, &c->opt_machine_pass},
+ {"kerberos", 'k', POPT_ARG_NONE, &c->opt_kerberos},
{"myworkgroup", 'W', POPT_ARG_STRING, &c->opt_workgroup},
{"verbose", 'v', POPT_ARG_NONE, &c->opt_verbose},
{"test", 'T', POPT_ARG_NONE, &c->opt_testmode},
/* Options for 'net groupmap set' */
{"local", 'L', POPT_ARG_NONE, &c->opt_localgroup},
{"domain", 'D', POPT_ARG_NONE, &c->opt_domaingroup},
- {"ntname", 0, POPT_ARG_STRING, &c->opt_newntname},
+ {"ntname", 'N', POPT_ARG_STRING, &c->opt_newntname},
{"rid", 'R', POPT_ARG_INT, &c->opt_rid},
/* Options for 'net rpc share migrate' */
{"acls", 0, POPT_ARG_NONE, &c->opt_acls},
@@ -670,7 +675,6 @@ static struct functable net_func[] = {
{"clean-old-entries", 0, POPT_ARG_NONE, &c->opt_clean_old_entries},
POPT_COMMON_SAMBA
- POPT_COMMON_CREDENTIALS
{ 0, 0, 0, 0}
};
@@ -684,13 +688,6 @@ static struct functable net_func[] = {
dbf = x_stderr;
c->private_data = net_func;
- c->auth_info = user_auth_info_init(frame);
- if (c->auth_info == NULL) {
- d_fprintf(stderr, "\nOut of memory!\n");
- exit(1);
- }
- popt_common_set_auth_info(c->auth_info);
-
pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
POPT_CONTEXT_KEEP_FIRST);
@@ -698,7 +695,9 @@ static struct functable net_func[] = {
switch (opt) {
case 'h':
c->display_usage = true;
- set_cmdline_auth_info_password(c->auth_info, "");
+ break;
+ case 'e':
+ c->smb_encrypt = true;
break;
case 'I':
if (!interpret_string_addr(&c->opt_dest_ip,
@@ -708,6 +707,15 @@ static struct functable net_func[] = {
c->opt_have_ip = true;
}
break;
+ case 'U':
+ c->opt_user_specified = true;
+ c->opt_user_name = SMB_STRDUP(c->opt_user_name);
+ p = strchr(c->opt_user_name,'%');
+ if (p) {
+ *p = 0;
+ c->opt_password = p+1;
+ }
+ break;
default:
d_fprintf(stderr, "\nInvalid option %s: %s\n",
poptBadOption(pc, 0), poptStrerror(opt));
@@ -741,6 +749,10 @@ static struct functable net_func[] = {
set_global_myname(c->opt_requester_name);
}
+ if (!c->opt_user_name && getenv("LOGNAME")) {
+ c->opt_user_name = getenv("LOGNAME");
+ }
+
if (!c->opt_workgroup) {
c->opt_workgroup = smb_xstrdup(lp_workgroup());
}
@@ -758,10 +770,23 @@ static struct functable net_func[] = {
that it won't assert becouse we are not root */
sec_init();
+ if (c->opt_machine_pass) {
+ /* it is very useful to be able to make ads queries as the
+ machine account for testing purposes and for domain leave */
+
+ net_use_krb_machine_account(c);
+ }
+
+ if (!c->opt_password) {
+ c->opt_password = getenv("PASSWD");
+ }
+
rc = net_run_function(c, argc_new-1, argv_new+1, "net", net_func);
DEBUG(2,("return code = %d\n", rc));
+ gencache_stabilize();
+
libnetapi_free(c->netapi_ctx);
poptFreeContext(pc);
diff --git a/source3/utils/net.h b/source3/utils/net.h
index f604d96361..d88f962d41 100644
--- a/source3/utils/net.h
+++ b/source3/utils/net.h
@@ -28,8 +28,11 @@
struct net_context {
const char *opt_requester_name;
const char *opt_host;
- int opt_long_list_entries;
+ const char *opt_password;
+ const char *opt_user_name;
+ bool opt_user_specified;
const char *opt_workgroup;
+ int opt_long_list_entries;
int opt_reboot;
int opt_force;
int opt_stdin;
@@ -42,6 +45,7 @@ struct net_context {
int opt_timeout;
int opt_request_timeout;
const char *opt_target_workgroup;
+ int opt_machine_pass;
int opt_localgroup;
int opt_domaingroup;
int do_talloc_report;
@@ -53,14 +57,15 @@ struct net_context {
const char *opt_exclude;
const char *opt_destination;
int opt_testmode;
+ bool opt_kerberos;
int opt_force_full_repl;
int opt_single_obj_repl;
int opt_clean_old_entries;
int opt_have_ip;
struct sockaddr_storage opt_dest_ip;
+ bool smb_encrypt;
struct libnetapi_ctx *netapi_ctx;
- struct user_auth_info *auth_info;
bool display_usage;
void *private_data;
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
index d82715eb45..8f76c0eb09 100644
--- a/source3/utils/net_ads.c
+++ b/source3/utils/net_ads.c
@@ -231,23 +231,32 @@ retry_connect:
ads = ads_init(realm, c->opt_target_workgroup, c->opt_host);
+ if (!c->opt_user_name) {
+ c->opt_user_name = "administrator";
+ }
+
+ if (c->opt_user_specified) {
+ need_password = true;
+ }
+
retry:
- if (need_password) {
- set_cmdline_auth_info_getpass(c->auth_info);
+ if (!c->opt_password && need_password && !c->opt_machine_pass) {
+ c->opt_password = net_prompt_pass(c, c->opt_user_name);
+ if (!c->opt_password) {
+ ads_destroy(&ads);
+ return ADS_ERROR(LDAP_NO_MEMORY);
+ }
}
- if (get_cmdline_auth_info_got_pass(c->auth_info) ||
- !get_cmdline_auth_info_use_kerberos(c->auth_info)) {
+ if (c->opt_password) {
use_in_memory_ccache();
SAFE_FREE(ads->auth.password);
- ads->auth.password = smb_xstrdup(
- get_cmdline_auth_info_password(c->auth_info));
+ ads->auth.password = smb_xstrdup(c->opt_password);
}
ads->auth.flags |= auth_flags;
SAFE_FREE(ads->auth.user_name);
- ads->auth.user_name = smb_xstrdup(
- get_cmdline_auth_info_username(c->auth_info));
+ ads->auth.user_name = smb_xstrdup(c->opt_user_name);
/*
* If the username is of the form "name@realm",
@@ -521,7 +530,7 @@ static int ads_user_info(struct net_context *c, int argc, const char **argv)
return net_ads_user_usage(c, argc, argv);
}
- escaped_user = escape_ldap_string_alloc(argv[0]);
+ escaped_user = escape_ldap_string(talloc_tos(), argv[0]);
if (!escaped_user) {
d_fprintf(stderr, "ads_user_info: failed to escape user %s\n", argv[0]);
@@ -529,12 +538,12 @@ static int ads_user_info(struct net_context *c, int argc, const char **argv)
}
if (!ADS_ERR_OK(ads_startup(c, false, &ads))) {
- SAFE_FREE(escaped_user);
+ TALLOC_FREE(escaped_user);
return -1;
}
if (asprintf(&searchstring, "(sAMAccountName=%s)", escaped_user) == -1) {
- SAFE_FREE(escaped_user);
+ TALLOC_FREE(escaped_user);
return -1;
}
rc = ads_search(ads, &res, searchstring, attrs);
@@ -543,7 +552,7 @@ static int ads_user_info(struct net_context *c, int argc, const char **argv)
if (!ADS_ERR_OK(rc)) {
d_fprintf(stderr, "ads_search: %s\n", ads_errstr(rc));
ads_destroy(&ads);
- SAFE_FREE(escaped_user);
+ TALLOC_FREE(escaped_user);
return -1;
}
@@ -563,7 +572,7 @@ static int ads_user_info(struct net_context *c, int argc, const char **argv)
ads_msgfree(ads, res);
ads_destroy(&ads);
- SAFE_FREE(escaped_user);
+ TALLOC_FREE(escaped_user);
return 0;
}
@@ -866,7 +875,6 @@ static int net_ads_leave(struct net_context *c, int argc, const char **argv)
TALLOC_CTX *ctx;
struct libnet_UnjoinCtx *r = NULL;
WERROR werr;
- struct user_auth_info *ai = c->auth_info;
if (c->display_usage) {
d_printf("Usage:\n"
@@ -885,7 +893,7 @@ static int net_ads_leave(struct net_context *c, int argc, const char **argv)
return -1;
}
- if (!get_cmdline_auth_info_use_kerberos(ai)) {
+ if (!c->opt_kerberos) {
use_in_memory_ccache();
}
@@ -895,14 +903,12 @@ static int net_ads_leave(struct net_context *c, int argc, const char **argv)
return -1;
}
- set_cmdline_auth_info_getpass(ai);
-
r->in.debug = true;
- r->in.use_kerberos = get_cmdline_auth_info_use_kerberos(ai);
+ r->in.use_kerberos = c->opt_kerberos;
r->in.dc_name = c->opt_host;
r->in.domain_name = lp_realm();
- r->in.admin_account = get_cmdline_auth_info_username(ai);
- r->in.admin_password = get_cmdline_auth_info_password(ai);
+ r->in.admin_account = c->opt_user_name;
+ r->in.admin_password = net_prompt_pass(c, c->opt_user_name);
r->in.modify_config = lp_config_backend_is_registry();
/* Try to delete it, but if that fails, disable it. The
@@ -960,8 +966,7 @@ static NTSTATUS net_ads_join_ok(struct net_context *c)
return NT_STATUS_ACCESS_DENIED;
}
- set_cmdline_auth_info_use_machine_account(c->auth_info);
- set_cmdline_auth_info_machine_account_creds(c->auth_info);
+ net_use_krb_machine_account(c);
status = ads_startup(c, true, &ads);
if (!ADS_ERR_OK(status)) {
@@ -1192,7 +1197,6 @@ int net_ads_join(struct net_context *c, int argc, const char **argv)
const char *os_name = NULL;
const char *os_version = NULL;
bool modify_config = lp_config_backend_is_registry();
- struct user_auth_info *ai = c->auth_info;;
if (c->display_usage)
return net_ads_join_usage(c, argc, argv);
@@ -1212,7 +1216,7 @@ int net_ads_join(struct net_context *c, int argc, const char **argv)
goto fail;
}
- if (!get_cmdline_auth_info_use_kerberos(ai)) {
+ if (!c->opt_kerberos) {
use_in_memory_ccache();
}
@@ -1262,8 +1266,6 @@ int net_ads_join(struct net_context *c, int argc, const char **argv)
/* Do the domain join here */
- set_cmdline_auth_info_getpass(ai);
-
r->in.domain_name = domain;
r->in.create_upn = createupn;
r->in.upn = machineupn;
@@ -1271,10 +1273,10 @@ int net_ads_join(struct net_context *c, int argc, const char **argv)
r->in.os_name = os_name;
r->in.os_version = os_version;
r->in.dc_name = c->opt_host;
- r->in.admin_account = get_cmdline_auth_info_username(ai);
- r->in.admin_password = get_cmdline_auth_info_password(ai);
+ r->in.admin_account = c->opt_user_name;
+ r->in.admin_password = net_prompt_pass(c, c->opt_user_name);
r->in.debug = true;
- r->in.use_kerberos = get_cmdline_auth_info_use_kerberos(ai);
+ r->in.use_kerberos = c->opt_kerberos;
r->in.modify_config = modify_config;
r->in.join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE |
@@ -1585,7 +1587,6 @@ static int net_ads_printer_publish(struct net_context *c, int argc, const char *
char *prt_dn, *srv_dn, **srv_cn;
char *srv_cn_escaped = NULL, *printername_escaped = NULL;
LDAPMessage *res = NULL;
- struct user_auth_info *ai = c->auth_info;
if (argc < 1 || c->display_usage) {
d_printf("Usage:\n"
@@ -1617,9 +1618,8 @@ static int net_ads_printer_publish(struct net_context *c, int argc, const char *
nt_status = cli_full_connection(&cli, global_myname(), servername,
&server_ss, 0,
"IPC$", "IPC",
- get_cmdline_auth_info_username(ai),
- c->opt_workgroup,
- get_cmdline_auth_info_password(ai),
+ c->opt_user_name, c->opt_workgroup,
+ c->opt_password ? c->opt_password : "",
CLI_FULL_CONNECTION_USE_KERBEROS,
Undefined, NULL);
@@ -1807,8 +1807,8 @@ static int net_ads_printer(struct net_context *c, int argc, const char **argv)
static int net_ads_password(struct net_context *c, int argc, const char **argv)
{
ADS_STRUCT *ads;
- const char *auth_principal;
- const char *auth_password;
+ const char *auth_principal = c->opt_user_name;
+ const char *auth_password = c->opt_password;
char *realm = NULL;
char *new_password = NULL;
char *chr, *prompt;
@@ -1823,9 +1823,10 @@ static int net_ads_password(struct net_context *c, int argc, const char **argv)
return 0;
}
- auth_principal = get_cmdline_auth_info_username(c->auth_info);
- set_cmdline_auth_info_getpass(c->auth_info);
- auth_password = get_cmdline_auth_info_password(c->auth_info);
+ if (c->opt_user_name == NULL || c->opt_password == NULL) {
+ d_fprintf(stderr, "You must supply an administrator username/password\n");
+ return -1;
+ }
if (argc < 1) {
d_fprintf(stderr, "ERROR: You must say which username to change password for\n");
@@ -1907,7 +1908,7 @@ int net_ads_changetrustpw(struct net_context *c, int argc, const char **argv)
return -1;
}
- set_cmdline_auth_info_use_machine_account(c->auth_info);
+ net_use_krb_machine_account(c);
use_in_memory_ccache();
@@ -2289,7 +2290,6 @@ static int net_ads_kerberos_pac(struct net_context *c, int argc, const char **ar
TALLOC_CTX *mem_ctx = NULL;
NTSTATUS status;
int ret = -1;
- struct user_auth_info *ai = c->auth_info;
if (c->display_usage) {
d_printf("Usage:\n"
@@ -2303,11 +2303,11 @@ static int net_ads_kerberos_pac(struct net_context *c, int argc, const char **ar
goto out;
}
- set_cmdline_auth_info_getpass(ai);
+ c->opt_password = net_prompt_pass(c, c->opt_user_name);
status = kerberos_return_pac(mem_ctx,
- get_cmdline_auth_info_username(ai),
- get_cmdline_auth_info_password(ai),
+ c->opt_user_name,
+ c->opt_password,
0,
NULL,
NULL,
@@ -2340,7 +2340,6 @@ static int net_ads_kerberos_kinit(struct net_context *c, int argc, const char **
TALLOC_CTX *mem_ctx = NULL;
int ret = -1;
NTSTATUS status;
- struct user_auth_info *ai = c->auth_info;
if (c->display_usage) {
d_printf("Usage:\n"
@@ -2354,10 +2353,10 @@ static int net_ads_kerberos_kinit(struct net_context *c, int argc, const char **
goto out;
}
- set_cmdline_auth_info_getpass(ai);
+ c->opt_password = net_prompt_pass(c, c->opt_user_name);
- ret = kerberos_kinit_password_ext(get_cmdline_auth_info_username(ai),
- get_cmdline_auth_info_password(ai),
+ ret = kerberos_kinit_password_ext(c->opt_user_name,
+ c->opt_password,
0,
NULL,
NULL,
diff --git a/source3/utils/net_cache.c b/source3/utils/net_cache.c
index 5e7db38515..36cd12fb82 100644
--- a/source3/utils/net_cache.c
+++ b/source3/utils/net_cache.c
@@ -171,12 +171,10 @@ static int net_cache_add(struct net_context *c, int argc, const char **argv)
if (gencache_set(keystr, datastr, timeout)) {
d_printf("New cache entry stored successfully.\n");
- gencache_shutdown();
return 0;
}
d_fprintf(stderr, "Entry couldn't be added. Perhaps there's already such a key.\n");
- gencache_shutdown();
return -1;
}
@@ -275,7 +273,6 @@ static int net_cache_list(struct net_context *c, int argc, const char **argv)
return 0;
}
gencache_iterate(print_cache_entry, NULL, pattern);
- gencache_shutdown();
return 0;
}
@@ -297,10 +294,24 @@ static int net_cache_flush(struct net_context *c, int argc, const char **argv)
return 0;
}
gencache_iterate(delete_cache_entry, NULL, pattern);
- gencache_shutdown();
return 0;
}
+static int net_cache_stabilize(struct net_context *c, int argc,
+ const char **argv)
+{
+ if (c->display_usage) {
+ d_printf("Usage:\n"
+ "net cache flush\n"
+ " Delete all cache entries.\n");
+ return 0;
+ }
+
+ if (!gencache_stabilize()) {
+ return -1;
+ }
+ return 0;
+}
/**
* Entry point to 'net cache' subfunctionality
*
@@ -366,6 +377,14 @@ int net_cache(struct net_context *c, int argc, const char **argv)
"net cache flush\n"
" Delete all cache entries"
},
+ {
+ "stabilize",
+ net_cache_stabilize,
+ NET_TRANSPORT_LOCAL,
+ "Move transient cache content to stable storage",
+ "net cache stabilize\n"
+ " Move transient cache content to stable storage"
+ },
{NULL, NULL, 0, NULL, NULL}
};
diff --git a/source3/utils/net_dom.c b/source3/utils/net_dom.c
index a13f52c519..401079777f 100644
--- a/source3/utils/net_dom.c
+++ b/source3/utils/net_dom.c
@@ -368,11 +368,9 @@ int net_dom(struct net_context *c, int argc, const char **argv)
return -1;
}
- libnetapi_set_username(c->netapi_ctx,
- get_cmdline_auth_info_username(c->auth_info));
- libnetapi_set_password(c->netapi_ctx,
- get_cmdline_auth_info_password(c->auth_info));
- if (get_cmdline_auth_info_use_kerberos(c->auth_info)) {
+ libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
+ libnetapi_set_password(c->netapi_ctx, c->opt_password);
+ if (c->opt_kerberos) {
libnetapi_set_use_kerberos(c->netapi_ctx);
}
diff --git a/source3/utils/net_help.c b/source3/utils/net_help.c
index 5a170790c5..0502373aa2 100644
--- a/source3/utils/net_help.c
+++ b/source3/utils/net_help.c
@@ -65,6 +65,5 @@ int net_help(struct net_context *c, int argc, const char **argv)
}
c->display_usage = true;
- set_cmdline_auth_info_password(c->auth_info, "");
return net_run_function(c, argc, argv, "net help", func);
}
diff --git a/source3/utils/net_proto.h b/source3/utils/net_proto.h
index 8a09147aad..75ac032db9 100644
--- a/source3/utils/net_proto.h
+++ b/source3/utils/net_proto.h
@@ -459,6 +459,8 @@ NTSTATUS connect_to_ipc_krb5(struct net_context *c,
NTSTATUS connect_dst_pipe(struct net_context *c, struct cli_state **cli_dst,
struct rpc_pipe_client **pp_pipe_hnd,
const struct ndr_syntax_id *interface);
+int net_use_krb_machine_account(struct net_context *c);
+int net_use_machine_account(struct net_context *c);
bool net_find_server(struct net_context *c,
const char *domain,
unsigned flags,
@@ -473,6 +475,7 @@ NTSTATUS net_make_ipc_connection_ex(struct net_context *c ,const char *domain,
const char *server,
struct sockaddr_storage *pss,
unsigned flags, struct cli_state **pcli);
+const char *net_prompt_pass(struct net_context *c, const char *user);
int net_run_function(struct net_context *c, int argc, const char **argv,
const char *whoami, struct functable *table);
void net_display_usage_from_functable(struct functable *table);
diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c
index 0118b4818a..f6f90030fe 100644
--- a/source3/utils/net_rpc.c
+++ b/source3/utils/net_rpc.c
@@ -25,8 +25,7 @@
#include "../libcli/auth/libcli_auth.h"
static int net_mode_share;
-static bool sync_files(struct copy_clistate *cp_clistate, const char *mask,
- const struct user_auth_info *auth_info);
+static bool sync_files(struct copy_clistate *cp_clistate, const char *mask);
/**
* @file net_rpc.c
@@ -123,7 +122,6 @@ int run_rpc_command(struct net_context *c,
DOM_SID *domain_sid;
const char *domain_name;
int ret = -1;
- struct user_auth_info *ai = c->auth_info;
/* make use of cli_state handed over as an argument, if possible */
if (!cli_arg) {
@@ -173,10 +171,8 @@ int run_rpc_command(struct net_context *c,
nt_status = cli_rpc_pipe_open_ntlmssp(
cli, interface,
PIPE_AUTH_LEVEL_PRIVACY,
- lp_workgroup(),
- get_cmdline_auth_info_username(ai),
- get_cmdline_auth_info_password(ai),
- &pipe_hnd);
+ lp_workgroup(), c->opt_user_name,
+ c->opt_password, &pipe_hnd);
} else {
nt_status = cli_rpc_pipe_open_noauth(
cli, interface,
@@ -944,12 +940,9 @@ int net_rpc_user(struct net_context *c, int argc, const char **argv)
if (status != 0) {
return -1;
}
- set_cmdline_auth_info_getpass(c->auth_info);
- libnetapi_set_username(c->netapi_ctx,
- get_cmdline_auth_info_username(c->auth_info));
- libnetapi_set_password(c->netapi_ctx,
- get_cmdline_auth_info_password(c->auth_info));
- if (get_cmdline_auth_info_use_kerberos(c->auth_info)) {
+ libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
+ libnetapi_set_password(c->netapi_ctx, c->opt_password);
+ if (c->opt_kerberos) {
libnetapi_set_use_kerberos(c->netapi_ctx);
}
@@ -2763,12 +2756,9 @@ int net_rpc_group(struct net_context *c, int argc, const char **argv)
if (status != 0) {
return -1;
}
- set_cmdline_auth_info_getpass(c->auth_info);
- libnetapi_set_username(c->netapi_ctx,
- get_cmdline_auth_info_username(c->auth_info));
- libnetapi_set_password(c->netapi_ctx,
- get_cmdline_auth_info_password(c->auth_info));
- if (get_cmdline_auth_info_use_kerberos(c->auth_info)) {
+ libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
+ libnetapi_set_password(c->netapi_ctx, c->opt_password);
+ if (c->opt_kerberos) {
libnetapi_set_use_kerberos(c->netapi_ctx);
}
@@ -3255,7 +3245,7 @@ static void copy_fn(const char *mnt, file_info *f,
old_dir = local_state->cwd;
local_state->cwd = dir;
- if (!sync_files(local_state, new_mask, c->auth_info))
+ if (!sync_files(local_state, new_mask))
printf("could not handle files\n");
local_state->cwd = old_dir;
@@ -3302,18 +3292,15 @@ static void copy_fn(const char *mnt, file_info *f,
*
* @return Boolean result
**/
-static bool sync_files(struct copy_clistate *cp_clistate, const char *mask,
- const struct user_auth_info *auth_info)
+static bool sync_files(struct copy_clistate *cp_clistate, const char *mask)
{
struct cli_state *targetcli;
char *targetpath = NULL;
DEBUG(3,("calling cli_list with mask: %s\n", mask));
-
- if ( !cli_resolve_path(talloc_tos(), "", auth_info,
- cp_clistate->cli_share_src, mask, &targetcli,
- &targetpath ) ) {
+ if ( !cli_resolve_path(talloc_tos(), "", NULL, cp_clistate->cli_share_src,
+ mask, &targetcli, &targetpath ) ) {
d_fprintf(stderr, "cli_resolve_path %s failed with error: %s\n",
mask, cli_errstr(cp_clistate->cli_share_src));
return false;
@@ -3476,7 +3463,7 @@ static NTSTATUS rpc_share_migrate_files_internals(struct net_context *c,
goto done;
}
- if (!sync_files(&cp_clistate, mask, c->auth_info)) {
+ if (!sync_files(&cp_clistate, mask)) {
d_fprintf(stderr, "could not handle files for share: %s\n", info502.name);
nt_status = NT_STATUS_UNSUCCESSFUL;
goto done;
@@ -4577,12 +4564,9 @@ int net_rpc_share(struct net_context *c, int argc, const char **argv)
if (status != 0) {
return -1;
}
- set_cmdline_auth_info_getpass(c->auth_info);
- libnetapi_set_username(c->netapi_ctx,
- get_cmdline_auth_info_username(c->auth_info));
- libnetapi_set_password(c->netapi_ctx,
- get_cmdline_auth_info_password(c->auth_info));
- if (get_cmdline_auth_info_use_kerberos(c->auth_info)) {
+ libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
+ libnetapi_set_password(c->netapi_ctx, c->opt_password);
+ if (c->opt_kerberos) {
libnetapi_set_use_kerberos(c->netapi_ctx);
}
@@ -4855,12 +4839,9 @@ int net_rpc_file(struct net_context *c, int argc, const char **argv)
if (status != 0) {
return -1;
}
- set_cmdline_auth_info_getpass(c->auth_info);
- libnetapi_set_username(c->netapi_ctx,
- get_cmdline_auth_info_username(c->auth_info));
- libnetapi_set_password(c->netapi_ctx,
- get_cmdline_auth_info_password(c->auth_info));
- if (get_cmdline_auth_info_use_kerberos(c->auth_info)) {
+ libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
+ libnetapi_set_password(c->netapi_ctx, c->opt_password);
+ if (c->opt_kerberos) {
libnetapi_set_use_kerberos(c->netapi_ctx);
}
@@ -5550,7 +5531,7 @@ static int rpc_trustdom_establish(struct net_context *c, int argc,
c->opt_workgroup = smb_xstrdup(domain_name);
};
- set_cmdline_auth_info_username(c->auth_info, acct_name);
+ c->opt_user_name = acct_name;
/* find the domain controller */
if (!net_find_pdc(&server_ss, pdc_name, domain_name)) {
@@ -5647,9 +5628,7 @@ static int rpc_trustdom_establish(struct net_context *c, int argc,
* Store the password in secrets db
*/
- if (!pdb_set_trusteddom_pw(domain_name,
- get_cmdline_auth_info_password(c->auth_info),
- domain_sid)) {
+ if (!pdb_set_trusteddom_pw(domain_name, c->opt_password, domain_sid)) {
DEBUG(0, ("Storing password for trusted domain failed.\n"));
cli_shutdown(cli);
talloc_destroy(mem_ctx);
@@ -7211,12 +7190,9 @@ int net_rpc(struct net_context *c, int argc, const char **argv)
if (status != 0) {
return -1;
}
- set_cmdline_auth_info_getpass(c->auth_info);
- libnetapi_set_username(c->netapi_ctx,
- get_cmdline_auth_info_username(c->auth_info));
- libnetapi_set_password(c->netapi_ctx,
- get_cmdline_auth_info_password(c->auth_info));
- if (get_cmdline_auth_info_use_kerberos(c->auth_info)) {
+ libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
+ libnetapi_set_password(c->netapi_ctx, c->opt_password);
+ if (c->opt_kerberos) {
libnetapi_set_use_kerberos(c->netapi_ctx);
}
diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c
index cae2491aed..ed0311317d 100644
--- a/source3/utils/net_rpc_join.c
+++ b/source3/utils/net_rpc_join.c
@@ -58,8 +58,7 @@ NTSTATUS net_rpc_join_ok(struct net_context *c, const char *domain,
if (sec == SEC_ADS) {
/* Connect to IPC$ using machine account's credentials. We don't use anonymous
connection here, as it may be denied by server's local policy. */
- set_cmdline_auth_info_use_machine_account(c->auth_info);
- set_cmdline_auth_info_machine_account_creds(c->auth_info);
+ net_use_machine_account(c);
} else {
/* some servers (e.g. WinNT) don't accept machine-authenticated
diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c
index bd5047c1ff..309be171cc 100644
--- a/source3/utils/net_rpc_samsync.c
+++ b/source3/utils/net_rpc_samsync.c
@@ -379,8 +379,8 @@ NTSTATUS rpc_vampire_keytab_internals(struct net_context *c,
ctx->cli = pipe_hnd;
ctx->ops = &libnet_samsync_keytab_ops;
ctx->domain_name = domain_name;
- ctx->username = get_cmdline_auth_info_username(c->auth_info);
- ctx->password = get_cmdline_auth_info_password(c->auth_info);
+ ctx->username = c->opt_user_name;
+ ctx->password = c->opt_password;
ctx->force_full_replication = c->opt_force_full_repl ? true : false;
ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
@@ -493,17 +493,20 @@ int rpc_vampire_keytab(struct net_context *c, int argc, const char **argv)
if (!dc_info.is_ad) {
printf("DC is not running Active Directory\n");
- return -1;
- }
-
- if (dc_info.is_mixed_mode) {
ret = run_rpc_command(c, cli, &ndr_table_netlogon.syntax_id,
0,
rpc_vampire_keytab_internals, argc, argv);
+ return -1;
} else {
ret = run_rpc_command(c, cli, &ndr_table_drsuapi.syntax_id,
NET_FLAGS_SEAL,
rpc_vampire_keytab_ds_internals, argc, argv);
+ if (ret != 0 && dc_info.is_mixed_mode) {
+ printf("Fallback to NT4 vampire on Mixed-Mode AD Domain\n");
+ ret = run_rpc_command(c, cli, &ndr_table_netlogon.syntax_id,
+ 0,
+ rpc_vampire_keytab_internals, argc, argv);
+ }
}
return ret;
diff --git a/source3/utils/net_rpc_shell.c b/source3/utils/net_rpc_shell.c
index dc13e91423..3aaed1ed18 100644
--- a/source3/utils/net_rpc_shell.c
+++ b/source3/utils/net_rpc_shell.c
@@ -220,12 +220,9 @@ int net_rpc_shell(struct net_context *c, int argc, const char **argv)
if (libnetapi_init(&c->netapi_ctx) != 0) {
return -1;
}
- set_cmdline_auth_info_getpass(c->auth_info);
- libnetapi_set_username(c->netapi_ctx,
- get_cmdline_auth_info_username(c->auth_info));
- libnetapi_set_password(c->netapi_ctx,
- get_cmdline_auth_info_password(c->auth_info));
- if (get_cmdline_auth_info_use_kerberos(c->auth_info)) {
+ libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
+ libnetapi_set_password(c->netapi_ctx, c->opt_password);
+ if (c->opt_kerberos) {
libnetapi_set_use_kerberos(c->netapi_ctx);
}
diff --git a/source3/utils/net_sam.c b/source3/utils/net_sam.c
index 62abef000d..41daa4180d 100644
--- a/source3/utils/net_sam.c
+++ b/source3/utils/net_sam.c
@@ -452,7 +452,7 @@ static int net_sam_policy_set(struct net_context *c, int argc, const char **argv
const char *account_policy = NULL;
uint32 value = 0;
uint32 old_value = 0;
- int field;
+ enum pdb_policy_type field;
char *endptr;
if (argc != 2 || c->display_usage) {
@@ -462,7 +462,7 @@ static int net_sam_policy_set(struct net_context *c, int argc, const char **argv
}
account_policy = argv[0];
- field = account_policy_name_to_fieldnum(account_policy);
+ field = account_policy_name_to_typenum(account_policy);
if (strequal(argv[1], "forever") || strequal(argv[1], "never")
|| strequal(argv[1], "off")) {
@@ -519,7 +519,7 @@ static int net_sam_policy_show(struct net_context *c, int argc, const char **arg
{
const char *account_policy = NULL;
uint32 old_value;
- int field;
+ enum pdb_policy_type field;
if (argc != 1 || c->display_usage) {
d_fprintf(stderr, "usage: net sam policy show"
@@ -528,7 +528,7 @@ static int net_sam_policy_show(struct net_context *c, int argc, const char **arg
}
account_policy = argv[0];
- field = account_policy_name_to_fieldnum(account_policy);
+ field = account_policy_name_to_typenum(account_policy);
if (field == 0) {
const char **names;
diff --git a/source3/utils/net_usershare.c b/source3/utils/net_usershare.c
index 992a03d813..6eacb1386c 100644
--- a/source3/utils/net_usershare.c
+++ b/source3/utils/net_usershare.c
@@ -163,7 +163,7 @@ static int net_usershare_delete(struct net_context *c, int argc, const char **ar
d_fprintf(stderr, "net usershare delete: share name %s contains "
"invalid characters (any of %s)\n",
sharename, INVALID_SHARENAME_CHARS);
- SAFE_FREE(sharename);
+ TALLOC_FREE(sharename);
return -1;
}
@@ -172,7 +172,7 @@ static int net_usershare_delete(struct net_context *c, int argc, const char **ar
lp_usershare_path(),
sharename);
if (!us_path) {
- SAFE_FREE(sharename);
+ TALLOC_FREE(sharename);
return -1;
}
@@ -180,10 +180,10 @@ static int net_usershare_delete(struct net_context *c, int argc, const char **ar
d_fprintf(stderr, "net usershare delete: unable to remove usershare %s. "
"Error was %s\n",
us_path, strerror(errno));
- SAFE_FREE(sharename);
+ TALLOC_FREE(sharename);
return -1;
}
- SAFE_FREE(sharename);
+ TALLOC_FREE(sharename);
return 0;
}
@@ -672,7 +672,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
d_fprintf(stderr, "net usershare add: maximum number of allowed usershares (%d) reached\n",
lp_usershare_max_shares() );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
@@ -681,7 +680,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
"invalid characters (any of %s)\n",
sharename, INVALID_SHARENAME_CHARS);
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
@@ -690,7 +688,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
d_fprintf(stderr, "net usershare add: share name %s is already a valid system user name\n",
sharename );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
@@ -698,7 +695,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
full_path = get_basepath(ctx);
if (!full_path) {
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
full_path_tmp = talloc_asprintf(ctx,
@@ -706,7 +702,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
full_path);
if (!full_path_tmp) {
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
@@ -715,7 +710,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
sharename);
if (!full_path) {
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
@@ -724,7 +718,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
d_fprintf(stderr,"net usershare add: path %s is not an absolute path.\n",
us_path);
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
@@ -734,7 +727,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
"this is a directory. Error was %s\n",
us_path, strerror(errno) );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
@@ -742,7 +734,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
d_fprintf(stderr, "net usershare add: path %s is not a directory.\n",
us_path );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
@@ -756,7 +747,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
"\tto the [global] section of the smb.conf to allow this.\n",
us_path );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
@@ -786,7 +776,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
d_fprintf(stderr, "net usershare add: malformed acl %s (missing ':').\n",
pacl );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
@@ -802,7 +791,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
"(access control must be 'r', 'f', or 'd')\n",
pacl );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
@@ -810,7 +798,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
d_fprintf(stderr, "net usershare add: malformed terminating character for acl %s\n",
pacl );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
@@ -818,7 +805,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
if ((name = talloc_strndup(ctx, pacl, pcolon - pacl)) == NULL) {
d_fprintf(stderr, "talloc_strndup failed\n");
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
if (!string_to_sid(&sid, name)) {
@@ -833,7 +819,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
d_fprintf(stderr, "\n");
}
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
}
@@ -854,7 +839,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
"but the \"usershare allow guests\" parameter is not enabled "
"by this server.\n");
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
@@ -865,7 +849,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
d_fprintf(stderr, "net usershare add: cannot create tmp file %s\n",
full_path_tmp );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
@@ -874,7 +857,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
d_fprintf(stderr, "net usershare add: cannot lstat tmp file %s\n",
full_path_tmp );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
@@ -883,7 +865,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
d_fprintf(stderr, "net usershare add: cannot fstat tmp file %s\n",
full_path_tmp );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
@@ -891,7 +872,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
d_fprintf(stderr, "net usershare add: tmp file %s is not a regular file ?\n",
full_path_tmp );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
@@ -899,7 +879,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
d_fprintf(stderr, "net usershare add: failed to fchmod tmp file %s to 0644n",
full_path_tmp );
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
@@ -915,7 +894,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
(unsigned int)to_write, full_path_tmp, strerror(errno));
unlink(full_path_tmp);
TALLOC_FREE(ctx);
- SAFE_FREE(sharename);
return -1;
}
@@ -926,7 +904,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
sharename, strerror(errno));
TALLOC_FREE(ctx);
close(tmpfd);
- SAFE_FREE(sharename);
return -1;
}
@@ -939,7 +916,6 @@ static int net_usershare_add(struct net_context *c, int argc, const char **argv)
net_usershare_info(c, 1, my_argv);
}
- SAFE_FREE(sharename);
TALLOC_FREE(ctx);
return 0;
}
@@ -998,6 +974,7 @@ static int net_usershare_list(struct net_context *c, int argc,
pi.ctx = ctx;
pi.op = US_LIST_OP;
+ pi.c = c;
ret = process_share_list(info_fn, &pi);
talloc_destroy(ctx);
diff --git a/source3/utils/net_util.c b/source3/utils/net_util.c
index 50f3c1db01..8bf9aac6f2 100644
--- a/source3/utils/net_util.c
+++ b/source3/utils/net_util.c
@@ -96,22 +96,22 @@ NTSTATUS connect_to_service(struct net_context *c,
{
NTSTATUS nt_status;
int flags = 0;
- struct user_auth_info *ai = c->auth_info;
- set_cmdline_auth_info_getpass(ai);
+ c->opt_password = net_prompt_pass(c, c->opt_user_name);
- if (get_cmdline_auth_info_use_kerberos(ai)) {
- flags |= CLI_FULL_CONNECTION_USE_KERBEROS |
- CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
+ if (c->opt_kerberos) {
+ flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
+ }
+
+ if (c->opt_kerberos && c->opt_password) {
+ flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
}
nt_status = cli_full_connection(cli_ctx, NULL, server_name,
server_ss, c->opt_port,
service_name, service_type,
- get_cmdline_auth_info_username(ai),
- c->opt_workgroup,
- get_cmdline_auth_info_password(ai),
- flags, Undefined, NULL);
+ c->opt_user_name, c->opt_workgroup,
+ c->opt_password, flags, Undefined, NULL);
if (!NT_STATUS_IS_OK(nt_status)) {
d_fprintf(stderr, "Could not connect to server %s\n", server_name);
@@ -131,10 +131,10 @@ NTSTATUS connect_to_service(struct net_context *c,
return nt_status;
}
- if (get_cmdline_auth_info_smb_encrypt(ai)) {
+ if (c->smb_encrypt) {
nt_status = cli_force_encryption(*cli_ctx,
- get_cmdline_auth_info_username(ai),
- get_cmdline_auth_info_password(ai),
+ c->opt_user_name,
+ c->opt_password,
c->opt_workgroup);
if (NT_STATUS_EQUAL(nt_status,NT_STATUS_NOT_SUPPORTED)) {
@@ -234,12 +234,14 @@ NTSTATUS connect_to_ipc_krb5(struct net_context *c,
{
NTSTATUS nt_status;
char *user_and_realm = NULL;
- struct user_auth_info *ai = c->auth_info;
/* FIXME: Should get existing kerberos ticket if possible. */
- set_cmdline_auth_info_getpass(ai);
+ c->opt_password = net_prompt_pass(c, c->opt_user_name);
+ if (!c->opt_password) {
+ return NT_STATUS_NO_MEMORY;
+ }
- user_and_realm = get_user_and_realm(get_cmdline_auth_info_username(ai));
+ user_and_realm = get_user_and_realm(c->opt_user_name);
if (!user_and_realm) {
return NT_STATUS_NO_MEMORY;
}
@@ -248,7 +250,7 @@ NTSTATUS connect_to_ipc_krb5(struct net_context *c,
server_ss, c->opt_port,
"IPC$", "IPC",
user_and_realm, c->opt_workgroup,
- get_cmdline_auth_info_password(ai),
+ c->opt_password,
CLI_FULL_CONNECTION_USE_KERBEROS,
Undefined, NULL);
@@ -259,10 +261,10 @@ NTSTATUS connect_to_ipc_krb5(struct net_context *c,
return nt_status;
}
- if (get_cmdline_auth_info_smb_encrypt(ai)) {
+ if (c->smb_encrypt) {
nt_status = cli_cm_force_encryption(*cli_ctx,
user_and_realm,
- get_cmdline_auth_info_password(ai),
+ c->opt_password,
c->opt_workgroup,
"IPC$");
if (!NT_STATUS_IS_OK(nt_status)) {
@@ -326,6 +328,50 @@ NTSTATUS connect_dst_pipe(struct net_context *c, struct cli_state **cli_dst,
return nt_status;
}
+/****************************************************************************
+ Use the local machine account (krb) and password for this session.
+****************************************************************************/
+
+int net_use_krb_machine_account(struct net_context *c)
+{
+ char *user_name = NULL;
+
+ if (!secrets_init()) {
+ d_fprintf(stderr, "ERROR: Unable to open secrets database\n");
+ exit(1);
+ }
+
+ c->opt_password = secrets_fetch_machine_password(
+ c->opt_target_workgroup, NULL, NULL);
+ if (asprintf(&user_name, "%s$@%s", global_myname(), lp_realm()) == -1) {
+ return -1;
+ }
+ c->opt_user_name = user_name;
+ return 0;
+}
+
+/****************************************************************************
+ Use the machine account name and password for this session.
+****************************************************************************/
+
+int net_use_machine_account(struct net_context *c)
+{
+ char *user_name = NULL;
+
+ if (!secrets_init()) {
+ d_fprintf(stderr, "ERROR: Unable to open secrets database\n");
+ exit(1);
+ }
+
+ c->opt_password = secrets_fetch_machine_password(
+ c->opt_target_workgroup, NULL, NULL);
+ if (asprintf(&user_name, "%s$", global_myname()) == -1) {
+ return -1;
+ }
+ c->opt_user_name = user_name;
+ return 0;
+}
+
bool net_find_server(struct net_context *c,
const char *domain,
unsigned flags,
@@ -489,6 +535,33 @@ done:
/****************************************************************************
****************************************************************************/
+const char *net_prompt_pass(struct net_context *c, const char *user)
+{
+ char *prompt = NULL;
+ const char *pass = NULL;
+
+ if (c->opt_password) {
+ return c->opt_password;
+ }
+
+ if (c->opt_machine_pass) {
+ return NULL;
+ }
+
+ if (c->opt_kerberos && !c->opt_user_specified) {
+ return NULL;
+ }
+
+ if (asprintf(&prompt, "Enter %s's password:", user) == -1) {
+ return NULL;
+ }
+
+ pass = getpass(prompt);
+ SAFE_FREE(prompt);
+
+ return pass;
+}
+
int net_run_function(struct net_context *c, int argc, const char **argv,
const char *whoami, struct functable *table)
{
diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c
index a464299438..dce2f05a83 100644
--- a/source3/utils/pdbedit.c
+++ b/source3/utils/pdbedit.c
@@ -1109,7 +1109,7 @@ int main (int argc, char **argv)
/* account policy operations */
if ((checkparms & BIT_ACCPOLICY) && !(checkparms & ~(BIT_ACCPOLICY + BIT_ACCPOLVAL))) {
uint32 value;
- int field = account_policy_name_to_fieldnum(account_policy);
+ enum pdb_policy_type field = account_policy_name_to_typenum(account_policy);
if (field == 0) {
const char **names;
int count;
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index d617fe1f0b..34eaeb2d79 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -163,6 +163,8 @@ static void terminate(bool is_parent)
trustdom_cache_shutdown();
+ gencache_stabilize();
+
#if 0
if (interactive) {
TALLOC_CTX *mem_ctx = talloc_init("end_description");
diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c
index 0f40419a0e..08afb46674 100644
--- a/source3/winbindd/winbindd_ads.c
+++ b/source3/winbindd/winbindd_ads.c
@@ -210,7 +210,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
gid_t primary_gid = (gid_t)-1;
if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype) ||
- ads_atype_map(atype) != SID_NAME_USER) {
+ ds_atype_map(atype) != SID_NAME_USER) {
DEBUG(1,("Not a user account? atype=0x%x\n", atype));
continue;
}
@@ -608,7 +608,7 @@ static NTSTATUS lookup_usergroups_member(struct winbindd_domain *domain,
goto done;
}
- if (!(escaped_dn = escape_ldap_string_alloc(user_dn))) {
+ if (!(escaped_dn = escape_ldap_string(talloc_tos(), user_dn))) {
status = NT_STATUS_NO_MEMORY;
goto done;
}
@@ -620,12 +620,12 @@ static NTSTATUS lookup_usergroups_member(struct winbindd_domain *domain,
GROUP_TYPE_SECURITY_ENABLED);
if (!ldap_exp) {
DEBUG(1,("lookup_usergroups(dn=%s) asprintf failed!\n", user_dn));
- SAFE_FREE(escaped_dn);
+ TALLOC_FREE(escaped_dn);
status = NT_STATUS_NO_MEMORY;
goto done;
}
- SAFE_FREE(escaped_dn);
+ TALLOC_FREE(escaped_dn);
rc = ads_search_retry(ads, &res, ldap_exp, group_attrs);
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
index 92f0d60817..ab07c9767d 100644
--- a/source3/winbindd/winbindd_dual.c
+++ b/source3/winbindd/winbindd_dual.c
@@ -179,10 +179,6 @@ int wb_child_request_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
if (tevent_req_is_unix_error(req, err)) {
return -1;
}
- if (state->response->result != WINBINDD_OK) {
- *err = EIO; /* EIO doesn't fit, but what would be better? */
- return -1;
- }
*presponse = talloc_move(mem_ctx, &state->response);
return 0;
}
diff --git a/source3/winbindd/winbindd_passdb.c b/source3/winbindd/winbindd_passdb.c
index b18f0ff595..9a43c6d6a2 100644
--- a/source3/winbindd/winbindd_passdb.c
+++ b/source3/winbindd/winbindd_passdb.c
@@ -332,29 +332,29 @@ static NTSTATUS password_policy(struct winbindd_domain *domain,
return NT_STATUS_NO_MEMORY;
}
- if (!pdb_get_account_policy(AP_MIN_PASSWORD_LEN,
+ if (!pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN,
&account_policy_temp)) {
return NT_STATUS_ACCESS_DENIED;
}
p->min_password_length = account_policy_temp;
- if (!pdb_get_account_policy(AP_PASSWORD_HISTORY,
+ if (!pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY,
&account_policy_temp)) {
return NT_STATUS_ACCESS_DENIED;
}
p->password_history_length = account_policy_temp;
- if (!pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS,
+ if (!pdb_get_account_policy(PDB_POLICY_USER_MUST_LOGON_TO_CHG_PASS,
&p->password_properties)) {
return NT_STATUS_ACCESS_DENIED;
}
- if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp)) {
+ if (!pdb_get_account_policy(PDB_POLICY_MAX_PASSWORD_AGE, &account_policy_temp)) {
return NT_STATUS_ACCESS_DENIED;
}
u_expire = account_policy_temp;
- if (!pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp)) {
+ if (!pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_AGE, &account_policy_temp)) {
return NT_STATUS_ACCESS_DENIED;
}
u_min_age = account_policy_temp;
diff --git a/source3/winbindd/winbindd_sid.c b/source3/winbindd/winbindd_sid.c
index c091cd7f53..f8cf7db920 100644
--- a/source3/winbindd/winbindd_sid.c
+++ b/source3/winbindd/winbindd_sid.c
@@ -93,6 +93,11 @@ void winbindd_lookupname(struct winbindd_cli_state *state)
*p = 0;
name_domain = state->request->data.name.name;
name_user = p+1;
+ } else if ((p = strchr(state->request->data.name.name, '@')) != NULL) {
+ /* upn */
+ name_domain = p + 1;
+ *p = 0;
+ name_user = state->request->data.name.name;
} else {
name_domain = state->request->data.name.dom_name;
name_user = state->request->data.name.name;
diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
index 283eee09af..44ae814ae9 100644
--- a/source3/winbindd/winbindd_util.c
+++ b/source3/winbindd/winbindd_util.c
@@ -996,7 +996,8 @@ bool parse_domain_user(const char *domuser, fstring domain, fstring user)
if ( assume_domain(lp_workgroup())) {
fstrcpy(domain, lp_workgroup());
} else if ((p = strchr(domuser, '@')) != NULL) {
- fstrcpy(domain, "");
+ fstrcpy(domain, p + 1);
+ user[PTR_DIFF(p, domuser)] = 0;
} else {
return False;
}
diff --git a/source4/auth/auth.h b/source4/auth/auth.h
index 6bad017862..8a0f12efd8 100644
--- a/source4/auth/auth.h
+++ b/source4/auth/auth.h
@@ -23,6 +23,8 @@
#include "librpc/gen_ndr/ndr_krb5pac.h"
+extern const char *krbtgt_attrs[];
+extern const char *server_attrs[];
extern const char *user_attrs[];
union netr_Validation;
diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c
index 09bdec512d..f4ef36a24d 100644
--- a/source4/auth/gensec/gensec_krb5.c
+++ b/source4/auth/gensec/gensec_krb5.c
@@ -57,6 +57,7 @@ struct gensec_krb5_state {
krb5_keyblock *keyblock;
krb5_ticket *ticket;
bool gssapi;
+ krb5_flags ap_req_options;
};
static int gensec_krb5_destroy(struct gensec_krb5_state *gensec_krb5_state)
@@ -88,7 +89,7 @@ static int gensec_krb5_destroy(struct gensec_krb5_state *gensec_krb5_state)
return 0;
}
-static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security)
+static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security, bool gssapi)
{
krb5_error_code ret;
struct gensec_krb5_state *gensec_krb5_state;
@@ -114,7 +115,7 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security)
gensec_krb5_state->keyblock = NULL;
gensec_krb5_state->session_key = data_blob(NULL, 0);
gensec_krb5_state->pac = data_blob(NULL, 0);
- gensec_krb5_state->gssapi = false;
+ gensec_krb5_state->gssapi = gssapi;
talloc_set_destructor(gensec_krb5_state, gensec_krb5_destroy);
@@ -186,12 +187,12 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security)
return NT_STATUS_OK;
}
-static NTSTATUS gensec_krb5_server_start(struct gensec_security *gensec_security)
+static NTSTATUS gensec_krb5_common_server_start(struct gensec_security *gensec_security, bool gssapi)
{
NTSTATUS nt_status;
struct gensec_krb5_state *gensec_krb5_state;
- nt_status = gensec_krb5_start(gensec_security);
+ nt_status = gensec_krb5_start(gensec_security, gssapi);
if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
}
@@ -202,26 +203,23 @@ static NTSTATUS gensec_krb5_server_start(struct gensec_security *gensec_security
return NT_STATUS_OK;
}
-static NTSTATUS gensec_fake_gssapi_krb5_server_start(struct gensec_security *gensec_security)
+static NTSTATUS gensec_krb5_server_start(struct gensec_security *gensec_security)
{
- NTSTATUS nt_status = gensec_krb5_server_start(gensec_security);
+ return gensec_krb5_common_server_start(gensec_security, false);
+}
- if (NT_STATUS_IS_OK(nt_status)) {
- struct gensec_krb5_state *gensec_krb5_state;
- gensec_krb5_state = (struct gensec_krb5_state *)gensec_security->private_data;
- gensec_krb5_state->gssapi = true;
- }
- return nt_status;
+static NTSTATUS gensec_fake_gssapi_krb5_server_start(struct gensec_security *gensec_security)
+{
+ return gensec_krb5_common_server_start(gensec_security, true);
}
-static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security)
+static NTSTATUS gensec_krb5_common_client_start(struct gensec_security *gensec_security, bool gssapi)
{
struct gensec_krb5_state *gensec_krb5_state;
krb5_error_code ret;
NTSTATUS nt_status;
struct ccache_container *ccache_container;
const char *hostname;
- krb5_flags ap_req_options = AP_OPTS_USE_SUBKEY | AP_OPTS_MUTUAL_REQUIRED;
const char *principal;
krb5_data in_data;
@@ -240,13 +238,26 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security
return NT_STATUS_INVALID_PARAMETER;
}
- nt_status = gensec_krb5_start(gensec_security);
+ nt_status = gensec_krb5_start(gensec_security, gssapi);
if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
}
gensec_krb5_state = (struct gensec_krb5_state *)gensec_security->private_data;
gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_START;
+ gensec_krb5_state->ap_req_options = AP_OPTS_USE_SUBKEY;
+
+ if (gensec_krb5_state->gssapi) {
+ /* The Fake GSSAPI modal emulates Samba3, which does not do mutual authentication */
+ if (gensec_setting_bool(gensec_security->settings, "gensec_fake_gssapi_krb5", "mutual", false)) {
+ gensec_krb5_state->ap_req_options |= AP_OPTS_MUTUAL_REQUIRED;
+ }
+ } else {
+ /* The wrapping for KPASSWD (a user of the raw KRB5 API) should be mutually authenticated */
+ if (gensec_setting_bool(gensec_security->settings, "gensec_krb5", "mutual", true)) {
+ gensec_krb5_state->ap_req_options |= AP_OPTS_MUTUAL_REQUIRED;
+ }
+ }
principal = gensec_get_target_principal(gensec_security);
@@ -274,7 +285,7 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security
if (ret == 0) {
ret = krb5_mk_req_exact(gensec_krb5_state->smb_krb5_context->krb5_context,
&gensec_krb5_state->auth_context,
- ap_req_options,
+ gensec_krb5_state->ap_req_options,
target_principal,
&in_data, ccache_container->ccache,
&gensec_krb5_state->enc_ticket);
@@ -284,7 +295,7 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security
} else {
ret = krb5_mk_req(gensec_krb5_state->smb_krb5_context->krb5_context,
&gensec_krb5_state->auth_context,
- ap_req_options,
+ gensec_krb5_state->ap_req_options,
gensec_get_target_service(gensec_security),
hostname,
&in_data, ccache_container->ccache,
@@ -328,16 +339,14 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security
}
}
-static NTSTATUS gensec_fake_gssapi_krb5_client_start(struct gensec_security *gensec_security)
+static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security)
{
- NTSTATUS nt_status = gensec_krb5_client_start(gensec_security);
+ return gensec_krb5_common_client_start(gensec_security, false);
+}
- if (NT_STATUS_IS_OK(nt_status)) {
- struct gensec_krb5_state *gensec_krb5_state;
- gensec_krb5_state = (struct gensec_krb5_state *)gensec_security->private_data;
- gensec_krb5_state->gssapi = true;
- }
- return nt_status;
+static NTSTATUS gensec_fake_gssapi_krb5_client_start(struct gensec_security *gensec_security)
+{
+ return gensec_krb5_common_client_start(gensec_security, true);
}
/**
@@ -392,8 +401,13 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security,
} else {
*out = data_blob_talloc(out_mem_ctx, gensec_krb5_state->enc_ticket.data, gensec_krb5_state->enc_ticket.length);
}
- gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_MUTUAL_AUTH;
- nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED;
+ if (gensec_krb5_state->ap_req_options & AP_OPTS_MUTUAL_REQUIRED) {
+ gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_MUTUAL_AUTH;
+ nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED;
+ } else {
+ gensec_krb5_state->state_position = GENSEC_KRB5_DONE;
+ nt_status = NT_STATUS_OK;
+ }
return nt_status;
}
diff --git a/source4/auth/sam.c b/source4/auth/sam.c
index c396662c12..635d94242f 100644
--- a/source4/auth/sam.c
+++ b/source4/auth/sam.c
@@ -32,25 +32,37 @@
#include "param/param.h"
#include "auth/auth_sam.h"
-const char *user_attrs[] = {
- /* required for the krb5 kdc */
- "objectClass",
- "sAMAccountName",
- "userPrincipalName",
- "servicePrincipalName",
- "msDS-KeyVersionNumber",
- "supplementalCredentials",
+#define KRBTGT_ATTRS \
+ /* required for the krb5 kdc */ \
+ "objectClass", \
+ "sAMAccountName", \
+ "userPrincipalName", \
+ "servicePrincipalName", \
+ "msDS-KeyVersionNumber", \
+ "supplementalCredentials", \
+ \
+ /* passwords */ \
+ "dBCSPwd", \
+ "unicodePwd", \
+ \
+ "userAccountControl", \
+ "objectSid", \
+ \
+ "pwdLastSet", \
+ "accountExpires"
+
+const char *krbtgt_attrs[] = {
+ KRBTGT_ATTRS
+};
- /* passwords */
- "dBCSPwd",
- "unicodePwd",
+const char *server_attrs[] = {
+ KRBTGT_ATTRS
+};
- "userAccountControl",
+const char *user_attrs[] = {
+ KRBTGT_ATTRS,
- "pwdLastSet",
- "accountExpires",
"logonHours",
- "objectSid",
/* check 'allowed workstations' */
"userWorkstations",
diff --git a/source4/cldap_server/netlogon.c b/source4/cldap_server/netlogon.c
index 8a21ea55c9..b1a46c3c31 100644
--- a/source4/cldap_server/netlogon.c
+++ b/source4/cldap_server/netlogon.c
@@ -189,7 +189,7 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
"(!(userAccountControl:" LDB_OID_COMPARATOR_AND ":=%u))"
"(userAccountControl:" LDB_OID_COMPARATOR_OR ":=%u))",
ldb_binary_encode_string(mem_ctx, user),
- UF_ACCOUNTDISABLE, samdb_acb2uf(acct_control));
+ UF_ACCOUNTDISABLE, ds_acb2uf(acct_control));
if (ret != LDB_SUCCESS) {
DEBUG(2,("Unable to find referece to user '%s' with ACB 0x%8x under %s: %s\n",
user, acct_control, ldb_dn_get_linearized(dom_res->msgs[0]->dn),
diff --git a/source4/configure.ac b/source4/configure.ac
index 1930f4b6c7..7c5f310aa9 100644
--- a/source4/configure.ac
+++ b/source4/configure.ac
@@ -37,6 +37,7 @@ m4_include(client/config.m4)
AC_CONFIG_FILES(lib/registry/registry.pc)
AC_CONFIG_FILES(librpc/dcerpc.pc)
AC_CONFIG_FILES(../librpc/ndr.pc)
+AC_CONFIG_FILES(../librpc/ndr_standard.pc)
AC_CONFIG_FILES(../lib/torture/torture.pc)
AC_CONFIG_FILES(auth/gensec/gensec.pc)
AC_CONFIG_FILES(param/samba-hostconfig.pc)
diff --git a/source4/dsdb/common/sidmap.c b/source4/dsdb/common/sidmap.c
index 5c20149384..3111a78e51 100644
--- a/source4/dsdb/common/sidmap.c
+++ b/source4/dsdb/common/sidmap.c
@@ -21,7 +21,7 @@
#include "includes.h"
#include "system/passwd.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#include "dsdb/samdb/samdb.h"
#include "auth/auth.h"
#include "libcli/ldap/ldap_ndr.h"
@@ -583,7 +583,7 @@ NTSTATUS sidmap_allocated_sid_lookup(struct sidmap_context *sidmap,
struct passwd *pwd;
uid_t uid = rid - SIDMAP_LOCAL_USER_BASE;
atype = ATYPE_NORMAL_ACCOUNT;
- *rtype = samdb_atype_map(atype);
+ *rtype = ds_atype_map(atype);
pwd = getpwuid(uid);
if (pwd == NULL) {
@@ -595,7 +595,7 @@ NTSTATUS sidmap_allocated_sid_lookup(struct sidmap_context *sidmap,
struct group *grp;
gid_t gid = rid - SIDMAP_LOCAL_GROUP_BASE;
atype = ATYPE_LOCAL_GROUP;
- *rtype = samdb_atype_map(atype);
+ *rtype = ds_atype_map(atype);
grp = getgrgid(gid);
if (grp == NULL) {
*name = talloc_asprintf(mem_ctx, "gid%u", gid);
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index cbae2ec24c..247aec7035 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -31,7 +31,7 @@
#include "libcli/security/security.h"
#include "librpc/gen_ndr/ndr_security.h"
#include "librpc/gen_ndr/ndr_misc.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#include "dsdb/common/proto.h"
#include "libcli/ldap/ldap_ndr.h"
#include "param/param.h"
@@ -640,7 +640,7 @@ uint32_t samdb_result_acct_flags(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ct
struct ldb_message *msg, struct ldb_dn *domain_dn)
{
uint32_t userAccountControl = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0);
- uint32_t acct_flags = samdb_uf2acb(userAccountControl);
+ uint32_t acct_flags = ds_uf2acb(userAccountControl);
NTTIME must_change_time;
NTTIME now;
@@ -902,7 +902,7 @@ int samdb_msg_add_hashes(TALLOC_CTX *mem_ctx, struct ldb_message *msg,
int samdb_msg_add_acct_flags(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
const char *attr_name, uint32_t v)
{
- return samdb_msg_add_uint(sam_ldb, mem_ctx, msg, attr_name, samdb_acb2uf(v));
+ return samdb_msg_add_uint(sam_ldb, mem_ctx, msg, attr_name, ds_acb2uf(v));
}
/*
diff --git a/source4/dsdb/config.mk b/source4/dsdb/config.mk
index 0438647698..2a9f70fdb5 100644
--- a/source4/dsdb/config.mk
+++ b/source4/dsdb/config.mk
@@ -26,8 +26,8 @@ PRIVATE_DEPENDENCIES = LIBLDB
SAMDB_COMMON_OBJ_FILES = $(addprefix $(dsdbsrcdir)/common/, \
sidmap.o \
- flag_mapping.o \
- util.o)
+ util.o) \
+ ../libds/common/flag_mapping.o
$(eval $(call proto_header_template,$(dsdbsrcdir)/common/proto.h,$(SAMDB_COMMON_OBJ_FILES:.o=.c)))
[SUBSYSTEM::SAMDB_SCHEMA]
diff --git a/source4/dsdb/samdb/ldb_modules/instancetype.c b/source4/dsdb/samdb/ldb_modules/instancetype.c
index 8d648d6d82..f0d56ac627 100644
--- a/source4/dsdb/samdb/ldb_modules/instancetype.c
+++ b/source4/dsdb/samdb/ldb_modules/instancetype.c
@@ -38,7 +38,7 @@
#include "ldb_module.h"
#include "librpc/gen_ndr/ndr_misc.h"
#include "dsdb/samdb/samdb.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
struct it_context {
struct ldb_module *module;
diff --git a/source4/dsdb/samdb/ldb_modules/linked_attributes.c b/source4/dsdb/samdb/ldb_modules/linked_attributes.c
index 4e28c8a149..9ed06a9130 100644
--- a/source4/dsdb/samdb/ldb_modules/linked_attributes.c
+++ b/source4/dsdb/samdb/ldb_modules/linked_attributes.c
@@ -741,15 +741,15 @@ static int la_op_search_callback(struct ldb_request *req,
if (ret != LDB_SUCCESS) {
return ldb_module_done(ac->req, NULL, NULL, ret);
}
- break;
- case LDB_RENAME:
-
+ return ret;
+
+ case LDB_RENAME:
+ /* start the mod requests chain */
ret = la_do_mod_request(ac);
if (ret != LDB_SUCCESS) {
return ldb_module_done(ac->req, NULL, NULL,
ret);
- }
-
+ }
return ret;
default:
@@ -759,7 +759,6 @@ static int la_op_search_callback(struct ldb_request *req,
return ldb_module_done(ac->req, NULL, NULL,
LDB_ERR_OPERATIONS_ERROR);
}
- return LDB_SUCCESS;
}
talloc_free(ares);
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
index 44b7ef91e9..c7fa636aa8 100644
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
@@ -42,7 +42,7 @@
#include "auth/kerberos/kerberos.h"
#include "system/time.h"
#include "dsdb/samdb/samdb.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#include "dsdb/samdb/ldb_modules/password_modules.h"
#include "librpc/ndr/libndr.h"
#include "librpc/gen_ndr/ndr_drsblobs.h"
@@ -1026,6 +1026,7 @@ static int setup_supplemental_field(struct setup_password_fields_io *io)
uint8_t zero16[16];
bool do_newer_keys = false;
bool do_cleartext = false;
+ int *domainFunctionality;
ZERO_STRUCT(zero16);
ZERO_STRUCT(names);
@@ -1064,10 +1065,10 @@ static int setup_supplemental_field(struct setup_password_fields_io *io)
_old_scb.sub.signature, SUPPLEMENTAL_CREDENTIALS_SIGNATURE);
}
}
+ /* Per MS-SAMR 3.1.1.8.11.6 we create AES keys if our domain functionality level is 2008 or higher */
+ domainFunctionality = talloc_get_type(ldb_get_opaque(ldb, "domainFunctionality"), int);
- /* TODO: do the correct check for this, it maybe depends on the functional level? */
- do_newer_keys = lp_parm_bool(ldb_get_opaque(ldb, "loadparm"),
- NULL, "password_hash", "create_aes_key", false);
+ do_newer_keys = *domainFunctionality && (*domainFunctionality >= DS_BEHAVIOR_WIN2008);
if (io->domain->store_cleartext &&
(io->u.user_account_control & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED)) {
@@ -1399,33 +1400,33 @@ static int setup_password_fields(struct setup_password_fields_io *io)
}
ret = setup_kerberos_keys(io);
- if (ret != 0) {
+ if (ret != LDB_SUCCESS) {
return ret;
}
}
ret = setup_nt_fields(io);
- if (ret != 0) {
+ if (ret != LDB_SUCCESS) {
return ret;
}
ret = setup_lm_fields(io);
- if (ret != 0) {
+ if (ret != LDB_SUCCESS) {
return ret;
}
ret = setup_supplemental_field(io);
- if (ret != 0) {
+ if (ret != LDB_SUCCESS) {
return ret;
}
ret = setup_last_set_field(io);
- if (ret != 0) {
+ if (ret != LDB_SUCCESS) {
return ret;
}
ret = setup_kvno_field(io);
- if (ret != 0) {
+ if (ret != LDB_SUCCESS) {
return ret;
}
@@ -1648,6 +1649,7 @@ static int get_domain_data_callback(struct ldb_request *req,
if (ret != LDB_SUCCESS) {
return ldb_module_done(ac->req, NULL, NULL, ret);
}
+ break;
case LDB_REPLY_REFERRAL:
/* ignore */
diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
index 41f4e8e7d5..53d6d0749c 100644
--- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
+++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
@@ -41,7 +41,7 @@
#include "includes.h"
#include "ldb_module.h"
#include "dsdb/samdb/samdb.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#include "librpc/gen_ndr/ndr_misc.h"
#include "librpc/gen_ndr/ndr_drsuapi.h"
#include "librpc/gen_ndr/ndr_drsblobs.h"
diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c
index 7080fb632f..59ea51dbce 100644
--- a/source4/dsdb/samdb/ldb_modules/rootdse.c
+++ b/source4/dsdb/samdb/ldb_modules/rootdse.c
@@ -59,6 +59,7 @@ static int rootdse_add_dynamic(struct ldb_module *module, struct ldb_message *ms
struct private_data *priv = talloc_get_type(ldb_module_get_private(module), struct private_data);
char **server_sasl;
const struct dsdb_schema *schema;
+ int *val;
ldb = ldb_module_get_ctx(module);
schema = dsdb_get_schema(ldb);
@@ -77,7 +78,7 @@ static int rootdse_add_dynamic(struct ldb_module *module, struct ldb_message *ms
}
}
- if (do_attribute(attrs, "supportedControl")) {
+ if (priv && do_attribute(attrs, "supportedControl")) {
int i;
for (i = 0; i < priv->num_controls; i++) {
char *control = talloc_strdup(msg, priv->controls[i]);
@@ -91,7 +92,7 @@ static int rootdse_add_dynamic(struct ldb_module *module, struct ldb_message *ms
}
}
- if (do_attribute(attrs, "namingContexts")) {
+ if (priv && do_attribute(attrs, "namingContexts")) {
int i;
for (i = 0; i < priv->num_partitions; i++) {
struct ldb_dn *dn = priv->partitions[i];
@@ -201,13 +202,37 @@ static int rootdse_add_dynamic(struct ldb_module *module, struct ldb_message *ms
}
}
- if (schema && do_attribute_explicit(attrs, "vendorVersion")) {
+ if (do_attribute_explicit(attrs, "vendorVersion")) {
if (ldb_msg_add_fmt(msg, "vendorVersion",
"%s", SAMBA_VERSION_STRING) != 0) {
goto failed;
}
}
+ if (priv && do_attribute(attrs, "domainFunctionality")
+ && (val = talloc_get_type(ldb_get_opaque(ldb, "domainFunctionality"), int))) {
+ if (ldb_msg_add_fmt(msg, "domainFunctionality",
+ "%d", *val) != 0) {
+ goto failed;
+ }
+ }
+
+ if (priv && do_attribute(attrs, "forestFunctionality")
+ && (val = talloc_get_type(ldb_get_opaque(ldb, "forestFunctionality"), int))) {
+ if (ldb_msg_add_fmt(msg, "forestFunctionality",
+ "%d", *val) != 0) {
+ goto failed;
+ }
+ }
+
+ if (priv && do_attribute(attrs, "domainControllerFunctionality")
+ && (val = talloc_get_type(ldb_get_opaque(ldb, "domainControllerFunctionality"), int))) {
+ if (ldb_msg_add_fmt(msg, "domainControllerFunctionality",
+ "%d", *val) != 0) {
+ goto failed;
+ }
+ }
+
/* TODO: lots more dynamic attributes should be added here */
return LDB_SUCCESS;
@@ -394,12 +419,17 @@ static int rootdse_request(struct ldb_module *module, struct ldb_request *req)
static int rootdse_init(struct ldb_module *module)
{
+ int ret;
struct ldb_context *ldb;
+ struct ldb_result *res;
struct private_data *data;
+ const char *attrs[] = { "msDS-Behavior-Version", NULL };
+ const char *ds_attrs[] = { "dsServiceName", NULL };
+ TALLOC_CTX *mem_ctx;
ldb = ldb_module_get_ctx(module);
- data = talloc(module, struct private_data);
+ data = talloc_zero(module, struct private_data);
if (data == NULL) {
return -1;
}
@@ -412,7 +442,107 @@ static int rootdse_init(struct ldb_module *module)
ldb_set_default_dns(ldb);
- return ldb_next_init(module);
+ ret = ldb_next_init(module);
+
+ if (ret) {
+ return ret;
+ }
+
+ mem_ctx = talloc_new(data);
+ if (!mem_ctx) {
+ ldb_oom(ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ /* Now that the partitions are set up, do a search for:
+ - domainControllerFunctionality
+ - domainFunctionality
+ - forestFunctionality
+
+ Then stuff these values into an opaque
+ */
+ ret = ldb_search(ldb, mem_ctx, &res,
+ ldb_get_default_basedn(ldb),
+ LDB_SCOPE_BASE, attrs, NULL);
+ if (ret == LDB_SUCCESS && res->count == 1) {
+ int domain_behaviour_version
+ = ldb_msg_find_attr_as_int(res->msgs[0],
+ "msDS-Behavior-Version", -1);
+ if (domain_behaviour_version != -1) {
+ int *val = talloc(ldb, int);
+ if (!val) {
+ ldb_oom(ldb);
+ talloc_free(mem_ctx);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ *val = domain_behaviour_version;
+ ret = ldb_set_opaque(ldb, "domainFunctionality", val);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(mem_ctx);
+ return ret;
+ }
+ }
+ }
+
+ ret = ldb_search(ldb, mem_ctx, &res,
+ samdb_partitions_dn(ldb, mem_ctx),
+ LDB_SCOPE_BASE, attrs, NULL);
+ if (ret == LDB_SUCCESS && res->count == 1) {
+ int forest_behaviour_version
+ = ldb_msg_find_attr_as_int(res->msgs[0],
+ "msDS-Behavior-Version", -1);
+ if (forest_behaviour_version != -1) {
+ int *val = talloc(ldb, int);
+ if (!val) {
+ ldb_oom(ldb);
+ talloc_free(mem_ctx);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ *val = forest_behaviour_version;
+ ret = ldb_set_opaque(ldb, "forestFunctionality", val);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(mem_ctx);
+ return ret;
+ }
+ }
+ }
+
+ ret = ldb_search(ldb, mem_ctx, &res,
+ ldb_dn_new(mem_ctx, ldb, ""),
+ LDB_SCOPE_BASE, ds_attrs, NULL);
+ if (ret == LDB_SUCCESS && res->count == 1) {
+ struct ldb_dn *ds_dn
+ = ldb_msg_find_attr_as_dn(ldb, mem_ctx, res->msgs[0],
+ "dsServiceName");
+ if (ds_dn) {
+ ret = ldb_search(ldb, mem_ctx, &res, ds_dn,
+ LDB_SCOPE_BASE, attrs, NULL);
+ if (ret == LDB_SUCCESS && res->count == 1) {
+ int domain_controller_behaviour_version
+ = ldb_msg_find_attr_as_int(res->msgs[0],
+ "msDS-Behavior-Version", -1);
+ if (domain_controller_behaviour_version != -1) {
+ int *val = talloc(ldb, int);
+ if (!val) {
+ ldb_oom(ldb);
+ talloc_free(mem_ctx);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ *val = domain_controller_behaviour_version;
+ ret = ldb_set_opaque(ldb,
+ "domainControllerFunctionality", val);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(mem_ctx);
+ return ret;
+ }
+ }
+ }
+ }
+ }
+
+ talloc_free(mem_ctx);
+
+ return LDB_SUCCESS;
}
static int rootdse_modify(struct ldb_module *module, struct ldb_request *req)
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index 8e21e38139..544249cbe3 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -572,7 +572,7 @@ static int samldb_check_samAccountType(struct samldb_ctx *ac)
"userAccountControl invalid");
return LDB_ERR_UNWILLING_TO_PERFORM;
} else {
- account_type = samdb_uf2atype(uac);
+ account_type = ds_uf2atype(uac);
ret = samdb_msg_add_uint(ldb,
ac->msg, ac->msg,
"sAMAccountType",
@@ -590,7 +590,7 @@ static int samldb_check_samAccountType(struct samldb_ctx *ac)
"groupType invalid");
return LDB_ERR_UNWILLING_TO_PERFORM;
} else {
- account_type = samdb_gtype2atype(group_type);
+ account_type = ds_gtype2atype(group_type);
ret = samdb_msg_add_uint(ldb,
ac->msg, ac->msg,
"sAMAccountType",
@@ -1280,7 +1280,7 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
req->op.mod.message = msg = ldb_msg_copy_shallow(req, req->op.mod.message);
group_type = strtoul((const char *)el->values[0].data, NULL, 0);
- account_type = samdb_gtype2atype(group_type);
+ account_type = ds_gtype2atype(group_type);
ret = samdb_msg_add_uint(ldb, msg, msg,
"sAMAccountType",
account_type);
@@ -1296,7 +1296,7 @@ static int samldb_modify(struct ldb_module *module, struct ldb_request *req)
req->op.mod.message = msg = ldb_msg_copy_shallow(req, req->op.mod.message);
user_account_control = strtoul((const char *)el->values[0].data, NULL, 0);
- account_type = samdb_uf2atype(user_account_control);
+ account_type = ds_uf2atype(user_account_control);
ret = samdb_msg_add_uint(ldb, msg, msg,
"sAMAccountType",
account_type);
diff --git a/source4/dsdb/samdb/samdb.c b/source4/dsdb/samdb/samdb.c
index 851187380b..08e6e0d985 100644
--- a/source4/dsdb/samdb/samdb.c
+++ b/source4/dsdb/samdb/samdb.c
@@ -36,7 +36,7 @@
#include "ldb_wrap.h"
#include "../lib/util/util_ldb.h"
#include "dsdb/samdb/samdb.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#include "param/param.h"
#include "lib/events/events.h"
#include "auth/credentials/credentials.h"
diff --git a/source4/dsdb/samdb/samdb.h b/source4/dsdb/samdb/samdb.h
index 49dc14d74c..1493345b9d 100644
--- a/source4/dsdb/samdb/samdb.h
+++ b/source4/dsdb/samdb/samdb.h
@@ -38,7 +38,7 @@ struct tevent_context;
#include "dsdb/schema/schema.h"
#include "dsdb/samdb/samdb_proto.h"
#include "dsdb/common/proto.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#define DSDB_CONTROL_CURRENT_PARTITION_OID "1.3.6.1.4.1.7165.4.3.2"
struct dsdb_control_current_partition {
diff --git a/source4/heimdal/kdc/kaserver.c b/source4/heimdal/kdc/kaserver.c
index 3702ab9281..69b5bb1d6e 100644
--- a/source4/heimdal/kdc/kaserver.c
+++ b/source4/heimdal/kdc/kaserver.c
@@ -493,10 +493,10 @@ do_authenticate (krb5_context context,
goto out;
}
- ret = _kdc_check_flags (context, config,
- client_entry, client_name,
- server_entry, server_name,
- TRUE);
+ ret = kdc_check_flags (context, config,
+ client_entry, client_name,
+ server_entry, server_name,
+ TRUE);
if (ret) {
make_error_reply (hdr, KAPWEXPIRED, reply);
goto out;
@@ -790,10 +790,10 @@ do_getticket (krb5_context context,
goto out;
}
- ret = _kdc_check_flags (context, config,
- client_entry, client_name,
- server_entry, server_name,
- FALSE);
+ ret = kdc_check_flags (context, config,
+ client_entry, client_name,
+ server_entry, server_name,
+ FALSE);
if (ret) {
make_error_reply (hdr, KAPWEXPIRED, reply);
goto out;
diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c
index e364dcc1d1..43d54bf702 100644
--- a/source4/heimdal/kdc/kerberos5.c
+++ b/source4/heimdal/kdc/kerberos5.c
@@ -678,6 +678,12 @@ kdc_check_flags(krb5_context context,
hdb_entry *client = &client_ex->entry;
/* check client */
+ if (client->flags.locked_out) {
+ kdc_log(context, config, 0,
+ "Client (%s) is locked out", client_name);
+ return KRB5KDC_ERR_POLICY;
+ }
+
if (client->flags.invalid) {
kdc_log(context, config, 0,
"Client (%s) has invalid bit set", client_name);
@@ -727,6 +733,11 @@ kdc_check_flags(krb5_context context,
if (server_ex != NULL) {
hdb_entry *server = &server_ex->entry;
+ if (server->flags.locked_out) {
+ kdc_log(context, config, 0,
+ "Client server locked out -- %s", server_name);
+ return KRB5KDC_ERR_POLICY;
+ }
if (server->flags.invalid) {
kdc_log(context, config, 0,
"Server has invalid flag set -- %s", server_name);
@@ -883,6 +894,7 @@ _kdc_as_rep(krb5_context context,
AS_REP rep;
KDCOptions f = b->kdc_options;
hdb_entry_ex *client = NULL, *server = NULL;
+ HDB *clientdb;
krb5_enctype cetype, setype, sessionetype;
krb5_data e_data;
EncTicketPart et;
@@ -966,7 +978,7 @@ _kdc_as_rep(krb5_context context,
*/
ret = _kdc_db_fetch(context, config, client_princ,
- HDB_F_GET_CLIENT | flags, NULL, &client);
+ HDB_F_GET_CLIENT | flags, &clientdb, &client);
if(ret){
kdc_log(context, config, 0, "UNKNOWN -- %s: %s", client_name,
krb5_get_err_text(context, ret));
@@ -1114,8 +1126,8 @@ _kdc_as_rep(krb5_context context,
"No client key matching pa-data (%s) -- %s",
estr, client_name);
free(estr);
-
free_EncryptedData(&enc_data);
+
continue;
}
@@ -1159,6 +1171,10 @@ _kdc_as_rep(krb5_context context,
e_text = "Failed to decrypt PA-DATA";
free_EncryptedData(&enc_data);
+
+ if (clientdb->hdb_auth_status)
+ (clientdb->hdb_auth_status)(context, clientdb, client, HDB_AUTH_WRONG_PASSWORD);
+
ret = KRB5KDC_ERR_PREAUTH_FAILED;
continue;
}
@@ -1323,6 +1339,10 @@ _kdc_as_rep(krb5_context context,
goto out;
}
+ if (clientdb->hdb_auth_status)
+ (clientdb->hdb_auth_status)(context, clientdb, client,
+ HDB_AUTH_SUCCESS);
+
/*
* Verify flags after the user been required to prove its identity
* with in a preauth mech.
diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c
index 59104da3d6..635eb27e75 100644
--- a/source4/heimdal/kdc/krb5tgs.c
+++ b/source4/heimdal/kdc/krb5tgs.c
@@ -492,6 +492,7 @@ check_tgs_flags(krb5_context context,
static krb5_error_code
check_constrained_delegation(krb5_context context,
krb5_kdc_configuration *config,
+ HDB *clientdb,
hdb_entry_ex *client,
krb5_const_principal server)
{
@@ -499,21 +500,32 @@ check_constrained_delegation(krb5_context context,
krb5_error_code ret;
int i;
- ret = hdb_entry_get_ConstrainedDelegACL(&client->entry, &acl);
- if (ret) {
- krb5_clear_error_message(context);
- return ret;
- }
+ /* if client delegates to itself, that ok */
+ if (krb5_principal_compare(context, client->entry.principal, server) == TRUE)
+ return 0;
- if (acl) {
- for (i = 0; i < acl->len; i++) {
- if (krb5_principal_compare(context, server, &acl->val[i]) == TRUE)
- return 0;
+ if (clientdb->hdb_check_constrained_delegation) {
+ ret = clientdb->hdb_check_constrained_delegation(context, clientdb, client, server);
+ if (ret == 0)
+ return 0;
+ } else {
+ ret = hdb_entry_get_ConstrainedDelegACL(&client->entry, &acl);
+ if (ret) {
+ krb5_clear_error_message(context);
+ return ret;
+ }
+
+ if (acl) {
+ for (i = 0; i < acl->len; i++) {
+ if (krb5_principal_compare(context, server, &acl->val[i]) == TRUE)
+ return 0;
+ }
}
+ ret = KRB5KDC_ERR_BADOPTION;
}
kdc_log(context, config, 0,
"Bad request for constrained delegation");
- return KRB5KDC_ERR_BADOPTION;
+ return ret;
}
/*
@@ -793,17 +805,34 @@ tgs_make_reply(krb5_context context,
et.flags.hw_authent = tgt->flags.hw_authent;
et.flags.anonymous = tgt->flags.anonymous;
et.flags.ok_as_delegate = server->entry.flags.ok_as_delegate;
+
+ if(rspac->length) {
+ /*
+ * No not need to filter out the any PAC from the
+ * auth_data since it's signed by the KDC.
+ */
+ ret = _kdc_tkt_add_if_relevant_ad(context, &et,
+ KRB5_AUTHDATA_WIN2K_PAC, rspac);
+ if (ret)
+ goto out;
+ }
if (auth_data) {
- /* XXX Check enc-authorization-data */
- et.authorization_data = calloc(1, sizeof(*et.authorization_data));
+ unsigned int i = 0;
+
+ /* XXX check authdata */
if (et.authorization_data == NULL) {
ret = ENOMEM;
+ krb5_set_error_message(context, ret, "malloc: out of memory");
goto out;
}
- ret = copy_AuthorizationData(auth_data, et.authorization_data);
- if (ret)
- goto out;
+ for(i = 0; i < auth_data->len ; i++) {
+ ret = add_AuthorizationData(et.authorization_data, &auth_data->val[i]);
+ if (ret) {
+ krb5_set_error_message(context, ret, "malloc: out of memory");
+ goto out;
+ }
+ }
/* Filter out type KRB5SignedPath */
ret = find_KRB5SignedPath(context, et.authorization_data, NULL);
@@ -820,18 +849,6 @@ tgs_make_reply(krb5_context context,
}
}
- if(rspac->length) {
- /*
- * No not need to filter out the any PAC from the
- * auth_data since it's signed by the KDC.
- */
- ret = _kdc_tkt_add_if_relevant_ad(context, &et,
- KRB5_AUTHDATA_WIN2K_PAC,
- rspac);
- if (ret)
- goto out;
- }
-
ret = krb5_copy_keyblock_contents(context, sessionkey, &et.key);
if (ret)
goto out;
@@ -1369,6 +1386,7 @@ tgs_build_reply(krb5_context context,
krb5_principal client_principal = NULL;
char *spn = NULL, *cpn = NULL;
hdb_entry_ex *server = NULL, *client = NULL;
+ HDB *clientdb;
krb5_realm ref_realm = NULL;
EncTicketPart *tgt = &ticket->ticket;
krb5_principals spp = NULL;
@@ -1531,7 +1549,7 @@ server_lookup:
}
ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT | HDB_F_CANON,
- NULL, &client);
+ &clientdb, &client);
if(ret) {
const char *krbtgt_realm;
@@ -1792,7 +1810,7 @@ server_lookup:
if (ret) {
kdc_log(context, config, 0,
"failed to decrypt ticket for "
- "constrained delegation from %s to %s ", spn, cpn);
+ "constrained delegation from %s to %s ", cpn, spn);
goto out;
}
@@ -1800,16 +1818,17 @@ server_lookup:
if (adtkt.flags.forwardable == 0) {
kdc_log(context, config, 0,
"Missing forwardable flag on ticket for "
- "constrained delegation from %s to %s ", spn, cpn);
+ "constrained delegation from %s to %s ", cpn, spn);
ret = KRB5KDC_ERR_BADOPTION;
goto out;
}
- ret = check_constrained_delegation(context, config, client, sp);
+ ret = check_constrained_delegation(context, config, clientdb,
+ client, sp);
if (ret) {
kdc_log(context, config, 0,
"constrained delegation from %s to %s not allowed",
- spn, cpn);
+ cpn, spn);
goto out;
}
diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi.h b/source4/heimdal/lib/gssapi/gssapi/gssapi.h
index 9fe2bb8b46..91141808f5 100644
--- a/source4/heimdal/lib/gssapi/gssapi/gssapi.h
+++ b/source4/heimdal/lib/gssapi/gssapi/gssapi.h
@@ -54,7 +54,13 @@
#endif
#ifndef GSSAPI_DEPRECATED
+#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1 )))
#define GSSAPI_DEPRECATED __attribute__((deprecated))
+#elif defined(_MSC_VER)
+#define GSSAPI_DEPRECATED __declspec(deprecated)
+#else
+#define GSSAPI_DEPRECATED
+#endif
#endif
/*
@@ -768,42 +774,6 @@ gss_pseudo_random
gss_buffer_t prf_out
);
-/*
- * AEAD support
- */
-
-OM_uint32 GSSAPI_LIB_FUNCTION
-gss_wrap_iov(OM_uint32 * /* minor_status */,
- gss_ctx_id_t /* context_handle */,
- int /* conf_req_flag */,
- gss_qop_t /* qop_req */,
- int * /* conf_state */,
- gss_iov_buffer_desc * /*iov */,
- int /* iov_count */);
-
-OM_uint32 GSSAPI_LIB_FUNCTION
-gss_unwrap_iov(OM_uint32 * /* minor_status */,
- gss_ctx_id_t /* context_handle */,
- int * /* conf_state */,
- gss_qop_t * /* qop_state */,
- gss_iov_buffer_desc * /* iov */,
- int /* iov_count */);
-
-OM_uint32 GSSAPI_LIB_FUNCTION
-gss_wrap_iov_length(OM_uint32 * /* minor_status */,
- gss_ctx_id_t /* context_handle */,
- int /* conf_req_flag */,
- gss_qop_t /* qop_req */,
- int * /* conf_state */,
- gss_iov_buffer_desc * /* iov */,
- int /* iov_count */);
-
-OM_uint32 GSSAPI_LIB_FUNCTION
-gss_release_iov_buffer(OM_uint32 * /* minor_status */,
- gss_iov_buffer_desc * /* iov */,
- int /* iov_count */);
-
-
OM_uint32
gss_store_cred(OM_uint32 * /* minor_status */,
gss_cred_id_t /* input_cred_handle */,
@@ -899,6 +869,31 @@ gss_decapsulate_token(gss_buffer_t /* input_token */,
+/*
+ * AEAD support
+ */
+
+/*
+ * GSS_IOV
+ */
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_wrap_iov(OM_uint32 *, gss_ctx_id_t, int, gss_qop_t, int *,
+ gss_iov_buffer_desc *, int);
+
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_unwrap_iov(OM_uint32 *, gss_ctx_id_t, int *, gss_qop_t *,
+ gss_iov_buffer_desc *, int);
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_wrap_iov_length(OM_uint32 *, gss_ctx_id_t, int, gss_qop_t, int *,
+ gss_iov_buffer_desc *, int);
+
+OM_uint32 GSSAPI_LIB_FUNCTION
+gss_release_iov_buffer(OM_uint32 *, gss_iov_buffer_desc *, int);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/source4/heimdal/lib/gssapi/krb5/8003.c b/source4/heimdal/lib/gssapi/krb5/8003.c
index f5181cc311..a6f0165e72 100644
--- a/source4/heimdal/lib/gssapi/krb5/8003.c
+++ b/source4/heimdal/lib/gssapi/krb5/8003.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
krb5_error_code
_gsskrb5_encode_om_uint32(OM_uint32 n, u_char *p)
{
diff --git a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c
index e0944852a7..8d998ed098 100644
--- a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c
+++ b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
HEIMDAL_MUTEX gssapi_keytab_mutex = HEIMDAL_MUTEX_INITIALIZER;
krb5_keytab _gsskrb5_keytab;
@@ -519,10 +517,12 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
}
/*
- * Samba style get some flags (but not DCE-STYLE)
+ * Samba style get some flags (but not DCE-STYLE), use
+ * ap_options to guess the mutual flag.
*/
- ctx->flags =
- GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG;
+ ctx->flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG;
+ if (ap_options & AP_OPTS_MUTUAL_REQUIRED)
+ ctx->flags |= GSS_C_MUTUAL_FLAG;
}
}
diff --git a/source4/heimdal/lib/gssapi/krb5/acquire_cred.c b/source4/heimdal/lib/gssapi/krb5/acquire_cred.c
index bfab5667be..4f6f38e674 100644
--- a/source4/heimdal/lib/gssapi/krb5/acquire_cred.c
+++ b/source4/heimdal/lib/gssapi/krb5/acquire_cred.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32
__gsskrb5_ccache_lifetime(OM_uint32 *minor_status,
krb5_context context,
diff --git a/source4/heimdal/lib/gssapi/krb5/add_cred.c b/source4/heimdal/lib/gssapi/krb5/add_cred.c
index aa96a45e45..adc8a09fa4 100644
--- a/source4/heimdal/lib/gssapi/krb5/add_cred.c
+++ b/source4/heimdal/lib/gssapi/krb5/add_cred.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_add_cred (
OM_uint32 *minor_status,
const gss_cred_id_t input_cred_handle,
diff --git a/source4/heimdal/lib/gssapi/krb5/aeap.c b/source4/heimdal/lib/gssapi/krb5/aeap.c
index 7dab7877d7..38a5ac2dbe 100644
--- a/source4/heimdal/lib/gssapi/krb5/aeap.c
+++ b/source4/heimdal/lib/gssapi/krb5/aeap.c
@@ -35,66 +35,6 @@
#include <roken.h>
-static OM_uint32
-iov_allocate(OM_uint32 *minor_status, gss_iov_buffer_desc *iov, int iov_count)
-{
- unsigned int i;
-
- for (i = 0; i < iov_count; i++) {
- if (GSS_IOV_BUFFER_FLAGS(iov[i].type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE){
- void *ptr = malloc(iov[i].buffer.length);
- if (ptr == NULL)
- abort();
- if (iov[i].buffer.value)
- memcpy(ptr, iov[i].buffer.value, iov[i].buffer.length);
- iov[i].buffer.value = ptr;
- iov[i].type |= GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED;
- }
- }
- return GSS_S_COMPLETE;
-}
-
-static OM_uint32
-iov_map(OM_uint32 *minor_status,
- const gss_iov_buffer_desc *iov,
- int iov_count,
- krb5_crypto_iov *data)
-{
- unsigned int i;
-
- for (i = 0; i < iov_count; i++) {
- switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) {
- case GSS_IOV_BUFFER_TYPE_EMPTY:
- data[i].flags = KRB5_CRYPTO_TYPE_EMPTY;
- break;
- case GSS_IOV_BUFFER_TYPE_DATA:
- data[i].flags = KRB5_CRYPTO_TYPE_DATA;
- break;
- case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
- data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
- break;
- case GSS_IOV_BUFFER_TYPE_HEADER:
- data[i].flags = KRB5_CRYPTO_TYPE_HEADER;
- break;
- case GSS_IOV_BUFFER_TYPE_TRAILER:
- data[i].flags = KRB5_CRYPTO_TYPE_TRAILER;
- break;
- case GSS_IOV_BUFFER_TYPE_PADDING:
- data[i].flags = KRB5_CRYPTO_TYPE_PADDING;
- break;
- case GSS_IOV_BUFFER_TYPE_STREAM:
- abort();
- break;
- default:
- *minor_status = EINVAL;
- return GSS_S_FAILURE;
- }
- data[i].data.data = iov[i].buffer.value;
- data[i].data.length = iov[i].buffer.length;
- }
- return GSS_S_COMPLETE;
-}
-
OM_uint32 GSSAPI_LIB_FUNCTION
_gk_wrap_iov(OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
@@ -104,50 +44,17 @@ _gk_wrap_iov(OM_uint32 * minor_status,
gss_iov_buffer_desc *iov,
int iov_count)
{
- gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle;
- krb5_context context;
- OM_uint32 major_status, junk;
- krb5_crypto_iov *data;
- krb5_error_code ret;
- unsigned usage;
-
- GSSAPI_KRB5_INIT (&context);
-
- major_status = iov_allocate(minor_status, iov, iov_count);
- if (major_status != GSS_S_COMPLETE)
- return major_status;
-
- data = calloc(iov_count, sizeof(data[0]));
- if (data == NULL) {
- gss_release_iov_buffer(&junk, iov, iov_count);
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
-
- major_status = iov_map(minor_status, iov, iov_count, data);
- if (major_status != GSS_S_COMPLETE) {
- gss_release_iov_buffer(&junk, iov, iov_count);
- free(data);
- return major_status;
- }
+ const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
+ krb5_context context;
- if (ctx->more_flags & LOCAL) {
- usage = KRB5_KU_USAGE_ACCEPTOR_SIGN;
- } else {
- usage = KRB5_KU_USAGE_INITIATOR_SIGN;
- }
+ GSSAPI_KRB5_INIT (&context);
- ret = krb5_encrypt_iov_ivec(context, ctx->crypto, usage,
- data, iov_count, NULL);
- free(data);
- if (ret) {
- gss_release_iov_buffer(&junk, iov, iov_count);
- *minor_status = ret;
- return GSS_S_FAILURE;
- }
+ if (ctx->more_flags & IS_CFX)
+ return _gssapi_wrap_cfx_iov(minor_status, ctx, context,
+ conf_req_flag, conf_state,
+ iov, iov_count);
- *minor_status = 0;
- return GSS_S_COMPLETE;
+ return GSS_S_FAILURE;
}
OM_uint32 GSSAPI_LIB_FUNCTION
@@ -158,50 +65,16 @@ _gk_unwrap_iov(OM_uint32 *minor_status,
gss_iov_buffer_desc *iov,
int iov_count)
{
- gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle;
+ const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
krb5_context context;
- krb5_error_code ret;
- OM_uint32 major_status, junk;
- krb5_crypto_iov *data;
- unsigned usage;
GSSAPI_KRB5_INIT (&context);
-
- major_status = iov_allocate(minor_status, iov, iov_count);
- if (major_status != GSS_S_COMPLETE)
- return major_status;
-
- data = calloc(iov_count, sizeof(data[0]));
- if (data == NULL) {
- gss_release_iov_buffer(&junk, iov, iov_count);
- *minor_status = ENOMEM;
- return GSS_S_FAILURE;
- }
-
- major_status = iov_map(minor_status, iov, iov_count, data);
- if (major_status != GSS_S_COMPLETE) {
- gss_release_iov_buffer(&junk, iov, iov_count);
- free(data);
- return major_status;
- }
-
- if (ctx->more_flags & LOCAL) {
- usage = KRB5_KU_USAGE_INITIATOR_SIGN;
- } else {
- usage = KRB5_KU_USAGE_ACCEPTOR_SIGN;
- }
-
- ret = krb5_decrypt_iov_ivec(context, ctx->crypto, usage,
- data, iov_count, NULL);
- free(data);
- if (ret) {
- *minor_status = ret;
- gss_release_iov_buffer(&junk, iov, iov_count);
- return GSS_S_FAILURE;
- }
-
- *minor_status = 0;
- return GSS_S_COMPLETE;
+
+ if (ctx->more_flags & IS_CFX)
+ return _gssapi_unwrap_cfx_iov(minor_status, ctx, context,
+ conf_state, qop_state, iov, iov_count);
+
+ return GSS_S_FAILURE;
}
OM_uint32 GSSAPI_LIB_FUNCTION
@@ -213,59 +86,15 @@ _gk_wrap_iov_length(OM_uint32 * minor_status,
gss_iov_buffer_desc *iov,
int iov_count)
{
- gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle;
+ const gsskrb5_ctx ctx = (const gsskrb5_ctx) context_handle;
krb5_context context;
- unsigned int i;
- size_t size;
- size_t *padding = NULL;
-
+
GSSAPI_KRB5_INIT (&context);
- *minor_status = 0;
-
- for (size = 0, i = 0; i < iov_count; i++) {
- switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) {
- case GSS_IOV_BUFFER_TYPE_EMPTY:
- break;
- case GSS_IOV_BUFFER_TYPE_DATA:
- size += iov[i].buffer.length;
- break;
- case GSS_IOV_BUFFER_TYPE_HEADER:
- iov[i].buffer.length =
- krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER);
- size += iov[i].buffer.length;
- break;
- case GSS_IOV_BUFFER_TYPE_TRAILER:
- iov[i].buffer.length =
- krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER);
- size += iov[i].buffer.length;
- break;
- case GSS_IOV_BUFFER_TYPE_PADDING:
- if (padding != NULL) {
- *minor_status = 0;
- return GSS_S_FAILURE;
- }
- padding = &iov[i].buffer.length;
- break;
- case GSS_IOV_BUFFER_TYPE_STREAM:
- size += iov[i].buffer.length;
- break;
- case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
- break;
- default:
- *minor_status = EINVAL;
- return GSS_S_FAILURE;
- }
- }
- if (padding) {
- size_t pad = krb5_crypto_length(context, ctx->crypto,
- KRB5_CRYPTO_TYPE_PADDING);
- if (pad > 1) {
- *padding = pad - (size % pad);
- if (*padding == pad)
- *padding = 0;
- } else
- *padding = 0;
- }
-
- return GSS_S_COMPLETE;
+
+ if (ctx->more_flags & IS_CFX)
+ return _gssapi_wrap_iov_length_cfx(minor_status, ctx, context,
+ conf_req_flag, qop_req, conf_state,
+ iov, iov_count);
+
+ return GSS_S_FAILURE;
}
diff --git a/source4/heimdal/lib/gssapi/krb5/arcfour.c b/source4/heimdal/lib/gssapi/krb5/arcfour.c
index b48cfebcf1..e7331b0119 100644
--- a/source4/heimdal/lib/gssapi/krb5/arcfour.c
+++ b/source4/heimdal/lib/gssapi/krb5/arcfour.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
/*
* Implements draft-brezak-win2k-krb-rc4-hmac-04.txt
*
diff --git a/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c b/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c
index 3a206b1be1..7e0c3fe727 100644
--- a/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c
+++ b/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_canonicalize_name (
OM_uint32 * minor_status,
const gss_name_t input_name,
diff --git a/source4/heimdal/lib/gssapi/krb5/cfx.c b/source4/heimdal/lib/gssapi/krb5/cfx.c
index 7ae26e2e7a..35e5a9e45a 100755
--- a/source4/heimdal/lib/gssapi/krb5/cfx.c
+++ b/source4/heimdal/lib/gssapi/krb5/cfx.c
@@ -32,10 +32,8 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
/*
- * Implementation of draft-ietf-krb-wg-gssapi-cfx-06.txt
+ * Implementation of RFC 4121
*/
#define CFXSentByAcceptor (1 << 0)
@@ -101,13 +99,14 @@ _gsskrb5cfx_wrap_length_cfx(const gsskrb5_ctx context_handle,
return 0;
}
-OM_uint32 _gssapi_wrap_size_cfx(OM_uint32 *minor_status,
- const gsskrb5_ctx ctx,
- krb5_context context,
- int conf_req_flag,
- gss_qop_t qop_req,
- OM_uint32 req_output_size,
- OM_uint32 *max_input_size)
+OM_uint32
+_gssapi_wrap_size_cfx(OM_uint32 *minor_status,
+ const gsskrb5_ctx ctx,
+ krb5_context context,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ OM_uint32 req_output_size,
+ OM_uint32 *max_input_size)
{
krb5_error_code ret;
@@ -203,11 +202,763 @@ rrc_rotate(void *data, size_t len, uint16_t rrc, krb5_boolean unrotate)
return 0;
}
+gss_iov_buffer_desc *
+_gk_find_buffer(gss_iov_buffer_desc *iov, int iov_count, OM_uint32 type)
+{
+ int i;
+
+ for (i = 0; i < iov_count; i++)
+ if (type == GSS_IOV_BUFFER_TYPE(iov[i].type))
+ return &iov[i];
+ return NULL;
+}
+
+static OM_uint32
+allocate_buffer(OM_uint32 *minor_status, gss_iov_buffer_desc *buffer, size_t size)
+{
+ if (buffer->type & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED) {
+ if (buffer->buffer.length == size)
+ return GSS_S_COMPLETE;
+ free(buffer->buffer.value);
+ }
+
+ buffer->buffer.value = malloc(size);
+ buffer->buffer.length = size;
+ if (buffer->buffer.value == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ buffer->type |= GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED;
+
+ return GSS_S_COMPLETE;
+}
+
+
+
+OM_uint32
+_gssapi_wrap_cfx_iov(OM_uint32 *minor_status,
+ gsskrb5_ctx ctx,
+ krb5_context context,
+ int conf_req_flag,
+ int *conf_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+ OM_uint32 major_status, junk;
+ gss_iov_buffer_desc *header, *trailer, *padding;
+ size_t gsshsize, k5hsize;
+ size_t gsstsize, k5tsize;
+ size_t i, padlength, rrc = 0, ec = 0;
+ gss_cfx_wrap_token token;
+ krb5_error_code ret;
+ int32_t seq_number;
+ unsigned usage;
+ krb5_crypto_iov *data = NULL;
+ int paddingoffset = 0;
+
+ header = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER);
+ if (header == NULL) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_PADDING, &padlength);
+
+ padding = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_PADDING);
+ if (padlength != 0 && padding == NULL) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);
+
+ if (conf_req_flag) {
+ ec = padlength;
+
+ krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER, &k5tsize);
+ krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER, &k5hsize);
+
+ gsshsize = k5hsize + sizeof(*token);
+ gsstsize = k5tsize + sizeof(*token); /* encrypted token stored in trailer */
+
+ } else {
+
+ krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_CHECKSUM, &k5tsize);
+
+ gsshsize = sizeof(*token);
+ gsstsize = k5tsize;
+ }
+
+ /*
+ *
+ */
+
+ if (trailer == NULL) {
+ /* conf_req_flag=0 doesn't support DCE_STYLE */
+ if (conf_req_flag == 0) {
+ *minor_status = EINVAL;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+ rrc = gsstsize;
+ if (IS_DCE_STYLE(ctx))
+ rrc -= ec;
+ gsshsize += gsstsize;
+ gsstsize = 0;
+ } else if (GSS_IOV_BUFFER_FLAGS(trailer->type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE) {
+ major_status = allocate_buffer(minor_status, trailer, gsstsize);
+ if (major_status)
+ goto failure;
+ } else if (trailer->buffer.length < gsstsize) {
+ *minor_status = KRB5_BAD_MSIZE;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ } else
+ trailer->buffer.length = gsstsize;
+
+ /*
+ *
+ */
+
+ if (GSS_IOV_BUFFER_FLAGS(header->type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE) {
+ major_status = allocate_buffer(minor_status, header, gsshsize);
+ if (major_status != GSS_S_COMPLETE)
+ goto failure;
+ } else if (header->buffer.length < gsshsize) {
+ *minor_status = KRB5_BAD_MSIZE;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ } else
+ header->buffer.length = gsshsize;
+
+ token = (gss_cfx_wrap_token)header->buffer.value;
+
+ token->TOK_ID[0] = 0x05;
+ token->TOK_ID[1] = 0x04;
+ token->Flags = 0;
+ token->Filler = 0xFF;
+
+ if (ctx->more_flags & ACCEPTOR_SUBKEY)
+ token->Flags |= CFXAcceptorSubkey;
+
+ if (ctx->more_flags & LOCAL)
+ usage = KRB5_KU_USAGE_INITIATOR_SEAL;
+ else
+ usage = KRB5_KU_USAGE_ACCEPTOR_SEAL;
+
+ if (conf_req_flag) {
+ /*
+ * In Wrap tokens with confidentiality, the EC field is
+ * used to encode the size (in bytes) of the random filler.
+ */
+ token->Flags |= CFXSealed;
+ token->EC[0] = (padlength >> 8) & 0xFF;
+ token->EC[1] = (padlength >> 0) & 0xFF;
+
+ } else {
+ /*
+ * In Wrap tokens without confidentiality, the EC field is
+ * used to encode the size (in bytes) of the trailing
+ * checksum.
+ *
+ * This is not used in the checksum calcuation itself,
+ * because the checksum length could potentially vary
+ * depending on the data length.
+ */
+ token->EC[0] = 0;
+ token->EC[1] = 0;
+ }
+
+ /*
+ * In Wrap tokens that provide for confidentiality, the RRC
+ * field in the header contains the hex value 00 00 before
+ * encryption.
+ *
+ * In Wrap tokens that do not provide for confidentiality,
+ * both the EC and RRC fields in the appended checksum
+ * contain the hex value 00 00 for the purpose of calculating
+ * the checksum.
+ */
+ token->RRC[0] = 0;
+ token->RRC[1] = 0;
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ krb5_auth_con_getlocalseqnumber(context,
+ ctx->auth_context,
+ &seq_number);
+ _gsskrb5_encode_be_om_uint32(0, &token->SND_SEQ[0]);
+ _gsskrb5_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]);
+ krb5_auth_con_setlocalseqnumber(context,
+ ctx->auth_context,
+ ++seq_number);
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ data = calloc(iov_count + 3, sizeof(data[0]));
+ if (data == NULL) {
+ *minor_status = ENOMEM;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ if (conf_req_flag) {
+ /*
+ plain packet:
+
+ {"header" | encrypt(plaintext-data | padding | E"header")}
+
+ Expanded, this is with with RRC = 0:
+
+ {"header" | krb5-header | plaintext-data | padding | E"header" | krb5-trailer }
+
+ In DCE-RPC mode == no trailer: RRC = gss "trailer" == length(padding | E"header" | krb5-trailer)
+
+ {"header" | padding | E"header" | krb5-trailer | krb5-header | plaintext-data }
+ */
+
+ i = 0;
+ data[i].flags = KRB5_CRYPTO_TYPE_HEADER;
+ data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize;
+ data[i].data.length = k5hsize;
+
+ for (i = 1; i < iov_count + 1; i++) {
+ switch (GSS_IOV_BUFFER_TYPE(iov[i - 1].type)) {
+ case GSS_IOV_BUFFER_TYPE_DATA:
+ data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+ break;
+ case GSS_IOV_BUFFER_TYPE_PADDING:
+ data[i].flags = KRB5_CRYPTO_TYPE_PADDING;
+ paddingoffset = i;
+ break;
+ case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+ data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
+ break;
+ default:
+ data[i].flags = KRB5_CRYPTO_TYPE_EMPTY;
+ break;
+ }
+ data[i].data.length = iov[i - 1].buffer.length;
+ data[i].data.data = iov[i - 1].buffer.value;
+ }
+
+ /*
+ * Any necessary padding is added here to ensure that the
+ * encrypted token header is always at the end of the
+ * ciphertext.
+ */
+
+ /* XXX KRB5_CRYPTO_TYPE_PADDING */
+
+ /* encrypted CFX header in trailer (or after the header if in
+ DCE mode). Copy in header into E"header"
+ */
+ data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+ if (trailer)
+ data[i].data.data = trailer->buffer.value;
+ else
+ data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize - k5tsize - sizeof(*token);
+
+ data[i].data.length = sizeof(*token);
+ memcpy(data[i].data.data, token, sizeof(*token));
+ i++;
+
+ /* Kerberos trailer comes after the gss trailer */
+ data[i].flags = KRB5_CRYPTO_TYPE_TRAILER;
+ data[i].data.data = ((uint8_t *)data[i-1].data.data) + sizeof(*token);
+ data[i].data.length = k5tsize;
+ i++;
+
+ ret = krb5_encrypt_iov_ivec(context, ctx->crypto, usage, data, i, NULL);
+ if (ret != 0) {
+ *minor_status = ret;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ if (rrc) {
+ token->RRC[0] = (rrc >> 8) & 0xFF;
+ token->RRC[1] = (rrc >> 0) & 0xFF;
+ }
+
+ if (paddingoffset)
+ padding->buffer.length = data[paddingoffset].data.length;
+
+ } else {
+ /*
+ plain packet:
+
+ {data | "header" | gss-trailer (krb5 checksum)
+
+ don't do RRC != 0
+
+ */
+
+ for (i = 0; i < iov_count; i++) {
+ switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
+ case GSS_IOV_BUFFER_TYPE_DATA:
+ case GSS_IOV_BUFFER_TYPE_PADDING:
+ data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+ break;
+ case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+ data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
+ break;
+ default:
+ data[i].flags = KRB5_CRYPTO_TYPE_EMPTY;
+ break;
+ }
+ data[i].data.length = iov[i].buffer.length;
+ data[i].data.data = iov[i].buffer.value;
+ }
+
+ data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+ data[i].data.data = header->buffer.value;
+ data[i].data.length = header->buffer.length;
+ i++;
+
+ data[i].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
+ data[i].data.data = trailer->buffer.value;
+ data[i].data.length = trailer->buffer.length;
+ i++;
+
+ ret = krb5_create_checksum_iov(context, ctx->crypto, usage, data, i, NULL);
+ if (ret) {
+ *minor_status = ret;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ token->EC[0] = (trailer->buffer.length >> 8) & 0xFF;
+ token->EC[1] = (trailer->buffer.length >> 0) & 0xFF;
+ }
+
+ if (conf_state != NULL)
+ *conf_state = conf_req_flag;
+
+ free(data);
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+
+ failure:
+ if (data)
+ free(data);
+
+ gss_release_iov_buffer(&junk, iov, iov_count);
+
+ return major_status;
+}
+
+/* This is slowpath */
+static OM_uint32
+unrotate_iov(OM_uint32 *minor_status, size_t rrc, gss_iov_buffer_desc *iov, int iov_count)
+{
+ uint8_t *p, *q;
+ size_t len = 0, skip;
+ int i;
+
+ for (i = 0; i < iov_count; i++)
+ if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA ||
+ GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING ||
+ GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER)
+ len += iov[i].buffer.length;
+
+ p = malloc(len);
+ if (p == NULL) {
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+ q = p;
+
+ /* copy up */
+
+ for (i = 0; i < iov_count; i++) {
+ if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA ||
+ GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING ||
+ GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER)
+ {
+ memcpy(q, iov[i].buffer.value, iov[i].buffer.length);
+ q += iov[i].buffer.length;
+ }
+ }
+ assert((q - p) == len);
+
+ /* unrotate first part */
+ q = p + rrc;
+ skip = rrc;
+ for (i = 0; i < iov_count; i++) {
+ if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA ||
+ GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING ||
+ GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER)
+ {
+ if (iov[i].buffer.length <= skip) {
+ skip -= iov[i].buffer.length;
+ } else {
+ memcpy(((uint8_t *)iov[i].buffer.value) + skip, q, iov[i].buffer.length - skip);
+ q += iov[i].buffer.length - skip;
+ skip = 0;
+ }
+ }
+ }
+ /* copy trailer */
+ q = p;
+ skip = rrc;
+ for (i = 0; i < iov_count; i++) {
+ if (GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_DATA ||
+ GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_PADDING ||
+ GSS_IOV_BUFFER_TYPE(iov[i].type) == GSS_IOV_BUFFER_TYPE_TRAILER)
+ {
+ memcpy(q, iov[i].buffer.value, MIN(iov[i].buffer.length, skip));
+ if (iov[i].buffer.length > skip)
+ break;
+ skip -= iov[i].buffer.length;
+ q += iov[i].buffer.length;
+ }
+ }
+ return GSS_S_COMPLETE;
+}
+
+
+OM_uint32
+_gssapi_unwrap_cfx_iov(OM_uint32 *minor_status,
+ gsskrb5_ctx ctx,
+ krb5_context context,
+ int *conf_state,
+ gss_qop_t *qop_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+ OM_uint32 seq_number_lo, seq_number_hi, major_status, junk;
+ gss_iov_buffer_desc *header, *trailer;
+ gss_cfx_wrap_token token, ttoken;
+ u_char token_flags;
+ krb5_error_code ret;
+ unsigned usage;
+ uint16_t ec, rrc;
+ krb5_crypto_iov *data = NULL;
+ int i, j;
+
+ *minor_status = 0;
+
+ header = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_HEADER);
+ if (header == NULL) {
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ if (header->buffer.length < sizeof(*token)) /* we check exact below */
+ return GSS_S_DEFECTIVE_TOKEN;
+
+ trailer = _gk_find_buffer(iov, iov_count, GSS_IOV_BUFFER_TYPE_TRAILER);
+
+ token = (gss_cfx_wrap_token)header->buffer.value;
+
+ if (token->TOK_ID[0] != 0x05 || token->TOK_ID[1] != 0x04)
+ return GSS_S_DEFECTIVE_TOKEN;
+
+ /* Ignore unknown flags */
+ token_flags = token->Flags &
+ (CFXSentByAcceptor | CFXSealed | CFXAcceptorSubkey);
+
+ if (token_flags & CFXSentByAcceptor) {
+ if ((ctx->more_flags & LOCAL) == 0)
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+
+ if (ctx->more_flags & ACCEPTOR_SUBKEY) {
+ if ((token_flags & CFXAcceptorSubkey) == 0)
+ return GSS_S_DEFECTIVE_TOKEN;
+ } else {
+ if (token_flags & CFXAcceptorSubkey)
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+
+ if (token->Filler != 0xFF)
+ return GSS_S_DEFECTIVE_TOKEN;
+
+ if (conf_state != NULL)
+ *conf_state = (token_flags & CFXSealed) ? 1 : 0;
+
+ ec = (token->EC[0] << 8) | token->EC[1];
+ rrc = (token->RRC[0] << 8) | token->RRC[1];
+
+ /*
+ * Check sequence number
+ */
+ _gsskrb5_decode_be_om_uint32(&token->SND_SEQ[0], &seq_number_hi);
+ _gsskrb5_decode_be_om_uint32(&token->SND_SEQ[4], &seq_number_lo);
+ if (seq_number_hi) {
+ /* no support for 64-bit sequence numbers */
+ *minor_status = ERANGE;
+ return GSS_S_UNSEQ_TOKEN;
+ }
+
+ HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
+ ret = _gssapi_msg_order_check(ctx->order, seq_number_lo);
+ if (ret != 0) {
+ *minor_status = 0;
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+ return ret;
+ }
+ HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+
+ /*
+ * Decrypt and/or verify checksum
+ */
+
+ if (ctx->more_flags & LOCAL) {
+ usage = KRB5_KU_USAGE_ACCEPTOR_SEAL;
+ } else {
+ usage = KRB5_KU_USAGE_INITIATOR_SEAL;
+ }
+
+ data = calloc(iov_count + 3, sizeof(data[0]));
+ if (data == NULL) {
+ *minor_status = ENOMEM;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ if (token_flags & CFXSealed) {
+ size_t k5tsize, k5hsize;
+
+ krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER, &k5hsize);
+ krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER, &k5tsize);
+
+ /* Rotate by RRC; bogus to do this in-place XXX */
+ /* Check RRC */
+
+ if (trailer == NULL) {
+ size_t gsstsize = k5tsize + sizeof(*token);
+ size_t gsshsize = k5hsize + sizeof(*token);
+
+ if (IS_DCE_STYLE(ctx))
+ gsstsize += ec;
+ gsshsize += gsstsize;
+
+ if (rrc != gsstsize) {
+ major_status = GSS_S_DEFECTIVE_TOKEN;
+ goto failure;
+ }
+ if (header->buffer.length != gsshsize) {
+ major_status = GSS_S_DEFECTIVE_TOKEN;
+ goto failure;
+ }
+ } else if (trailer->buffer.length != sizeof(*token) + k5tsize) {
+ major_status = GSS_S_DEFECTIVE_TOKEN;
+ goto failure;
+ } else if (header->buffer.length != sizeof(*token) + k5hsize) {
+ major_status = GSS_S_DEFECTIVE_TOKEN;
+ goto failure;
+ } else if (rrc != 0) {
+ /* go though slowpath */
+ major_status = unrotate_iov(minor_status, rrc, iov, iov_count);
+ if (major_status)
+ goto failure;
+ }
+
+ i = 0;
+ data[i].flags = KRB5_CRYPTO_TYPE_HEADER;
+ data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize;
+ data[i].data.length = k5hsize;
+ i++;
+
+ for (j = 0; j < iov_count; i++, j++) {
+ switch (GSS_IOV_BUFFER_TYPE(iov[j].type)) {
+ case GSS_IOV_BUFFER_TYPE_DATA:
+ case GSS_IOV_BUFFER_TYPE_PADDING:
+ data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+ break;
+ case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+ data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
+ break;
+ default:
+ data[i].flags = KRB5_CRYPTO_TYPE_EMPTY;
+ break;
+ }
+ data[i].data.length = iov[j].buffer.length;
+ data[i].data.data = iov[j].buffer.value;
+ }
+
+ /* encrypted CFX header in trailer (or after the header if in
+ DCE mode). Copy in header into E"header"
+ */
+ data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+ if (trailer)
+ data[i].data.data = trailer->buffer.value;
+ else
+ data[i].data.data = ((uint8_t *)header->buffer.value) + header->buffer.length - k5hsize - k5tsize - sizeof(*token);
+ data[i].data.length = sizeof(*token);
+ ttoken = (gss_cfx_wrap_token)data[i].data.data;
+ i++;
+
+ /* Kerberos trailer comes after the gss trailer */
+ data[i].flags = KRB5_CRYPTO_TYPE_TRAILER;
+ data[i].data.data = ((uint8_t *)data[i-1].data.data) + sizeof(*token);
+ data[i].data.length = k5tsize;
+ i++;
+
+ ret = krb5_decrypt_iov_ivec(context, ctx->crypto, usage, data, i, NULL);
+ if (ret != 0) {
+ *minor_status = ret;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ ttoken->RRC[0] = token->RRC[0];
+ ttoken->RRC[1] = token->RRC[1];
+
+ /* Check the integrity of the header */
+ if (memcmp(ttoken, token, sizeof(*token)) != 0) {
+ major_status = GSS_S_BAD_MIC;
+ goto failure;
+ }
+ } else {
+ /* Check RRC */
+ if (rrc != 0) {
+ *minor_status = EINVAL;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ if (trailer == NULL) {
+ *minor_status = EINVAL;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ if (trailer->buffer.length != ec) {
+ *minor_status = EINVAL;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+
+ for (i = 0; i < iov_count; i++) {
+ switch (GSS_IOV_BUFFER_TYPE(iov[i].type)) {
+ case GSS_IOV_BUFFER_TYPE_DATA:
+ case GSS_IOV_BUFFER_TYPE_PADDING:
+ data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+ break;
+ case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+ data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
+ break;
+ default:
+ data[i].flags = KRB5_CRYPTO_TYPE_EMPTY;
+ break;
+ }
+ data[i].data.length = iov[i].buffer.length;
+ data[i].data.data = iov[i].buffer.value;
+ }
+
+ data[i].flags = KRB5_CRYPTO_TYPE_DATA;
+ data[i].data.data = header->buffer.value;
+ data[i].data.length = header->buffer.length;
+ i++;
+
+ data[i].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
+ data[i].data.data = trailer->buffer.value;
+ data[i].data.length = trailer->buffer.length;
+ i++;
+
+ token = (gss_cfx_wrap_token)header->buffer.value;
+ token->EC[0] = 0;
+ token->EC[1] = 0;
+ token->RRC[0] = 0;
+ token->RRC[1] = 0;
+
+ ret = krb5_verify_checksum_iov(context, ctx->crypto, usage, data, i, NULL);
+ if (ret) {
+ *minor_status = ret;
+ major_status = GSS_S_FAILURE;
+ goto failure;
+ }
+ }
+
+ if (qop_state != NULL) {
+ *qop_state = GSS_C_QOP_DEFAULT;
+ }
+
+ free(data);
+
+ *minor_status = 0;
+ return GSS_S_COMPLETE;
+
+ failure:
+ if (data)
+ free(data);
+
+ gss_release_iov_buffer(&junk, iov, iov_count);
+
+ return major_status;
+}
+
+OM_uint32
+_gssapi_wrap_iov_length_cfx(OM_uint32 *minor_status,
+ gsskrb5_ctx ctx,
+ krb5_context context,
+ int conf_req_flag,
+ gss_qop_t qop_req,
+ int *conf_state,
+ gss_iov_buffer_desc *iov,
+ int iov_count)
+{
+ size_t size;
+ int i;
+ size_t *padding = NULL;
+
+ GSSAPI_KRB5_INIT (&context);
+ *minor_status = 0;
+
+ for (size = 0, i = 0; i < iov_count; i++) {
+ switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) {
+ case GSS_IOV_BUFFER_TYPE_EMPTY:
+ break;
+ case GSS_IOV_BUFFER_TYPE_DATA:
+ size += iov[i].buffer.length;
+ break;
+ case GSS_IOV_BUFFER_TYPE_HEADER:
+ *minor_status = krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER, &iov[i].buffer.length);
+ if (*minor_status)
+ return GSS_S_FAILURE;
+ break;
+ case GSS_IOV_BUFFER_TYPE_TRAILER:
+ *minor_status = krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER, &iov[i].buffer.length);
+ if (*minor_status)
+ return GSS_S_FAILURE;
+ break;
+ case GSS_IOV_BUFFER_TYPE_PADDING:
+ if (padding != NULL) {
+ *minor_status = 0;
+ return GSS_S_FAILURE;
+ }
+ padding = &iov[i].buffer.length;
+ break;
+ case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
+ break;
+ default:
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ }
+ if (padding) {
+ size_t pad;
+ krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_PADDING, &pad);
+ if (pad > 1) {
+ *padding = pad - (size % pad);
+ if (*padding == pad)
+ *padding = 0;
+ } else
+ *padding = 0;
+ }
+
+ return GSS_S_COMPLETE;
+}
+
+
+
+
OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
const gsskrb5_ctx ctx,
krb5_context context,
int conf_req_flag,
- gss_qop_t qop_req,
const gss_buffer_t input_message_buffer,
int *conf_state,
gss_buffer_t output_message_buffer)
diff --git a/source4/heimdal/lib/gssapi/krb5/compare_name.c b/source4/heimdal/lib/gssapi/krb5/compare_name.c
index fbb0f0218e..f45e4df3e2 100644
--- a/source4/heimdal/lib/gssapi/krb5/compare_name.c
+++ b/source4/heimdal/lib/gssapi/krb5/compare_name.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_compare_name
(OM_uint32 * minor_status,
const gss_name_t name1,
diff --git a/source4/heimdal/lib/gssapi/krb5/compat.c b/source4/heimdal/lib/gssapi/krb5/compat.c
index 012602c074..221d219c69 100644
--- a/source4/heimdal/lib/gssapi/krb5/compat.c
+++ b/source4/heimdal/lib/gssapi/krb5/compat.c
@@ -33,9 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
-
static krb5_error_code
check_compat(OM_uint32 *minor_status,
krb5_context context, krb5_const_principal name,
diff --git a/source4/heimdal/lib/gssapi/krb5/context_time.c b/source4/heimdal/lib/gssapi/krb5/context_time.c
index 3230389938..987ceea4aa 100644
--- a/source4/heimdal/lib/gssapi/krb5/context_time.c
+++ b/source4/heimdal/lib/gssapi/krb5/context_time.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32
_gsskrb5_lifetime_left(OM_uint32 *minor_status,
krb5_context context,
diff --git a/source4/heimdal/lib/gssapi/krb5/copy_ccache.c b/source4/heimdal/lib/gssapi/krb5/copy_ccache.c
index 40a8fab1b7..a4b28f91ed 100644
--- a/source4/heimdal/lib/gssapi/krb5/copy_ccache.c
+++ b/source4/heimdal/lib/gssapi/krb5/copy_ccache.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
#if 0
OM_uint32
gss_krb5_copy_ccache(OM_uint32 *minor_status,
diff --git a/source4/heimdal/lib/gssapi/krb5/decapsulate.c b/source4/heimdal/lib/gssapi/krb5/decapsulate.c
index a2a5de9fe7..7ccf0b0f79 100644
--- a/source4/heimdal/lib/gssapi/krb5/decapsulate.c
+++ b/source4/heimdal/lib/gssapi/krb5/decapsulate.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
/*
* return the length of the mechanism in token or -1
* (which implies that the token was bad - GSS_S_DEFECTIVE_TOKEN
diff --git a/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c b/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c
index ea0831815a..b3d436ea01 100644
--- a/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c
+++ b/source4/heimdal/lib/gssapi/krb5/delete_sec_context.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32
_gsskrb5_delete_sec_context(OM_uint32 * minor_status,
gss_ctx_id_t * context_handle,
diff --git a/source4/heimdal/lib/gssapi/krb5/display_name.c b/source4/heimdal/lib/gssapi/krb5/display_name.c
index 0b37731510..6487d84880 100644
--- a/source4/heimdal/lib/gssapi/krb5/display_name.c
+++ b/source4/heimdal/lib/gssapi/krb5/display_name.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_display_name
(OM_uint32 * minor_status,
const gss_name_t input_name,
diff --git a/source4/heimdal/lib/gssapi/krb5/display_status.c b/source4/heimdal/lib/gssapi/krb5/display_status.c
index 4136c25e53..f9d84fc762 100644
--- a/source4/heimdal/lib/gssapi/krb5/display_status.c
+++ b/source4/heimdal/lib/gssapi/krb5/display_status.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
static const char *
calling_error(OM_uint32 v)
{
diff --git a/source4/heimdal/lib/gssapi/krb5/duplicate_name.c b/source4/heimdal/lib/gssapi/krb5/duplicate_name.c
index 2b5e5c0ef4..b0188acd51 100644
--- a/source4/heimdal/lib/gssapi/krb5/duplicate_name.c
+++ b/source4/heimdal/lib/gssapi/krb5/duplicate_name.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_duplicate_name (
OM_uint32 * minor_status,
const gss_name_t src_name,
diff --git a/source4/heimdal/lib/gssapi/krb5/encapsulate.c b/source4/heimdal/lib/gssapi/krb5/encapsulate.c
index 838a34d7db..79cd9232e1 100644
--- a/source4/heimdal/lib/gssapi/krb5/encapsulate.c
+++ b/source4/heimdal/lib/gssapi/krb5/encapsulate.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
void
_gssapi_encap_length (size_t data_len,
size_t *len,
diff --git a/source4/heimdal/lib/gssapi/krb5/export_name.c b/source4/heimdal/lib/gssapi/krb5/export_name.c
index bad73611dc..705bb70d91 100644
--- a/source4/heimdal/lib/gssapi/krb5/export_name.c
+++ b/source4/heimdal/lib/gssapi/krb5/export_name.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_export_name
(OM_uint32 * minor_status,
const gss_name_t input_name,
diff --git a/source4/heimdal/lib/gssapi/krb5/export_sec_context.c b/source4/heimdal/lib/gssapi/krb5/export_sec_context.c
index 305d5c334e..3d3870a6b4 100644
--- a/source4/heimdal/lib/gssapi/krb5/export_sec_context.c
+++ b/source4/heimdal/lib/gssapi/krb5/export_sec_context.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32
_gsskrb5_export_sec_context (
OM_uint32 * minor_status,
diff --git a/source4/heimdal/lib/gssapi/krb5/external.c b/source4/heimdal/lib/gssapi/krb5/external.c
index 1c28f7c141..df23776a63 100644
--- a/source4/heimdal/lib/gssapi/krb5/external.c
+++ b/source4/heimdal/lib/gssapi/krb5/external.c
@@ -34,8 +34,6 @@
#include "gsskrb5_locl.h"
#include <gssapi_mech.h>
-RCSID("$Id$");
-
/*
* The implementation must reserve static storage for a
* gss_OID_desc object containing the value
diff --git a/source4/heimdal/lib/gssapi/krb5/get_mic.c b/source4/heimdal/lib/gssapi/krb5/get_mic.c
index 66aaba44d6..ad3009c73e 100644
--- a/source4/heimdal/lib/gssapi/krb5/get_mic.c
+++ b/source4/heimdal/lib/gssapi/krb5/get_mic.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
static OM_uint32
mic_des
(OM_uint32 * minor_status,
diff --git a/source4/heimdal/lib/gssapi/krb5/import_name.c b/source4/heimdal/lib/gssapi/krb5/import_name.c
index 8f5387fe2b..d488ce754b 100644
--- a/source4/heimdal/lib/gssapi/krb5/import_name.c
+++ b/source4/heimdal/lib/gssapi/krb5/import_name.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
static OM_uint32
parse_krb5_name (OM_uint32 *minor_status,
krb5_context context,
diff --git a/source4/heimdal/lib/gssapi/krb5/import_sec_context.c b/source4/heimdal/lib/gssapi/krb5/import_sec_context.c
index ba1a977d2d..2af942338f 100644
--- a/source4/heimdal/lib/gssapi/krb5/import_sec_context.c
+++ b/source4/heimdal/lib/gssapi/krb5/import_sec_context.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32
_gsskrb5_import_sec_context (
OM_uint32 * minor_status,
diff --git a/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c b/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c
index 3702106e79..b1d18bd244 100644
--- a/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c
+++ b/source4/heimdal/lib/gssapi/krb5/indicate_mechs.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_indicate_mechs
(OM_uint32 * minor_status,
gss_OID_set * mech_set
diff --git a/source4/heimdal/lib/gssapi/krb5/init.c b/source4/heimdal/lib/gssapi/krb5/init.c
index b28e6a4c12..3a22c33ed6 100644
--- a/source4/heimdal/lib/gssapi/krb5/init.c
+++ b/source4/heimdal/lib/gssapi/krb5/init.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
static HEIMDAL_MUTEX context_mutex = HEIMDAL_MUTEX_INITIALIZER;
static int created_key;
static HEIMDAL_thread_key context_key;
diff --git a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
index 4b632bd95a..35ab9dd88d 100644
--- a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
+++ b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
/*
* copy the addresses from `input_chan_bindings' (if any) to
* the auth context `ac'
@@ -697,7 +695,7 @@ repl_mutual
if (actual_mech_type)
*actual_mech_type = GSS_KRB5_MECHANISM;
- if (ctx->flags & GSS_C_DCE_STYLE) {
+ if (IS_DCE_STYLE(ctx)) {
/* There is no OID wrapping. */
indata.length = input_token->length;
indata.data = input_token->value;
diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_context.c b/source4/heimdal/lib/gssapi/krb5/inquire_context.c
index 188a6135a4..381ffc9e6f 100644
--- a/source4/heimdal/lib/gssapi/krb5/inquire_context.c
+++ b/source4/heimdal/lib/gssapi/krb5/inquire_context.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_inquire_context (
OM_uint32 * minor_status,
const gss_ctx_id_t context_handle,
diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_cred.c b/source4/heimdal/lib/gssapi/krb5/inquire_cred.c
index 27e3014923..518736d78e 100644
--- a/source4/heimdal/lib/gssapi/krb5/inquire_cred.c
+++ b/source4/heimdal/lib/gssapi/krb5/inquire_cred.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_inquire_cred
(OM_uint32 * minor_status,
const gss_cred_id_t cred_handle,
diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c
index 1fd9733940..9da1ac43f1 100644
--- a/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c
+++ b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_mech.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_inquire_cred_by_mech (
OM_uint32 * minor_status,
const gss_cred_id_t cred_handle,
diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c
index 5a35202a6a..f32342f1d8 100644
--- a/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c
+++ b/source4/heimdal/lib/gssapi/krb5/inquire_cred_by_oid.c
@@ -32,8 +32,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_inquire_cred_by_oid
(OM_uint32 * minor_status,
const gss_cred_id_t cred_handle,
diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c b/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c
index 5d54bd6508..5fa3c302a2 100644
--- a/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c
+++ b/source4/heimdal/lib/gssapi/krb5/inquire_mechs_for_name.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_inquire_mechs_for_name (
OM_uint32 * minor_status,
const gss_name_t input_name,
diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c b/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c
index 9eba7b7f4d..591343307e 100644
--- a/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c
+++ b/source4/heimdal/lib/gssapi/krb5/inquire_names_for_mech.c
@@ -33,9 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
-
static gss_OID *name_list[] = {
&GSS_C_NT_HOSTBASED_SERVICE,
&GSS_C_NT_USER_NAME,
diff --git a/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c b/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c
index f8ef2a3aa4..ce01e666fa 100644
--- a/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c
+++ b/source4/heimdal/lib/gssapi/krb5/inquire_sec_context_by_oid.c
@@ -32,8 +32,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
static int
oid_prefix_equal(gss_OID oid_enc, gss_OID prefix_enc, unsigned *suffix)
{
diff --git a/source4/heimdal/lib/gssapi/krb5/prf.c b/source4/heimdal/lib/gssapi/krb5/prf.c
index 9fd13f51bd..76ae3b78ed 100644
--- a/source4/heimdal/lib/gssapi/krb5/prf.c
+++ b/source4/heimdal/lib/gssapi/krb5/prf.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32
_gsskrb5_pseudo_random(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
diff --git a/source4/heimdal/lib/gssapi/krb5/process_context_token.c b/source4/heimdal/lib/gssapi/krb5/process_context_token.c
index 3229b36292..1c9d44588f 100644
--- a/source4/heimdal/lib/gssapi/krb5/process_context_token.c
+++ b/source4/heimdal/lib/gssapi/krb5/process_context_token.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_process_context_token (
OM_uint32 *minor_status,
const gss_ctx_id_t context_handle,
diff --git a/source4/heimdal/lib/gssapi/krb5/release_buffer.c b/source4/heimdal/lib/gssapi/krb5/release_buffer.c
index 18e0279939..b704e001eb 100644
--- a/source4/heimdal/lib/gssapi/krb5/release_buffer.c
+++ b/source4/heimdal/lib/gssapi/krb5/release_buffer.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_release_buffer
(OM_uint32 * minor_status,
gss_buffer_t buffer
diff --git a/source4/heimdal/lib/gssapi/krb5/release_cred.c b/source4/heimdal/lib/gssapi/krb5/release_cred.c
index 62674a1d53..5eec3c48cb 100644
--- a/source4/heimdal/lib/gssapi/krb5/release_cred.c
+++ b/source4/heimdal/lib/gssapi/krb5/release_cred.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_release_cred
(OM_uint32 * minor_status,
gss_cred_id_t * cred_handle
diff --git a/source4/heimdal/lib/gssapi/krb5/release_name.c b/source4/heimdal/lib/gssapi/krb5/release_name.c
index 5491052c59..0fafc275d0 100644
--- a/source4/heimdal/lib/gssapi/krb5/release_name.c
+++ b/source4/heimdal/lib/gssapi/krb5/release_name.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
OM_uint32 _gsskrb5_release_name
(OM_uint32 * minor_status,
gss_name_t * input_name
diff --git a/source4/heimdal/lib/gssapi/krb5/sequence.c b/source4/heimdal/lib/gssapi/krb5/sequence.c
index 6391d44429..fbbc5b6c70 100644
--- a/source4/heimdal/lib/gssapi/krb5/sequence.c
+++ b/source4/heimdal/lib/gssapi/krb5/sequence.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
#define DEFAULT_JITTER_WINDOW 20
struct gss_msg_order {
diff --git a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c
index 2a2390f8d1..15d7632e4c 100644
--- a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c
+++ b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c
@@ -32,8 +32,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
/* 1.2.752.43.13.17 */
static gss_OID_desc gss_krb5_cred_no_ci_flags_x_oid_desc =
{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x11")};
diff --git a/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c b/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c
index 460cfe942a..096e835045 100644
--- a/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c
+++ b/source4/heimdal/lib/gssapi/krb5/set_sec_context_option.c
@@ -36,8 +36,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
static OM_uint32
get_bool(OM_uint32 *minor_status,
const gss_buffer_t value,
diff --git a/source4/heimdal/lib/gssapi/krb5/unwrap.c b/source4/heimdal/lib/gssapi/krb5/unwrap.c
index 0e87cb88b7..20cf952b4e 100644
--- a/source4/heimdal/lib/gssapi/krb5/unwrap.c
+++ b/source4/heimdal/lib/gssapi/krb5/unwrap.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
static OM_uint32
unwrap_des
(OM_uint32 * minor_status,
diff --git a/source4/heimdal/lib/gssapi/krb5/verify_mic.c b/source4/heimdal/lib/gssapi/krb5/verify_mic.c
index 6eb7ae4b08..c7e16e81f7 100644
--- a/source4/heimdal/lib/gssapi/krb5/verify_mic.c
+++ b/source4/heimdal/lib/gssapi/krb5/verify_mic.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
static OM_uint32
verify_mic_des
(OM_uint32 * minor_status,
diff --git a/source4/heimdal/lib/gssapi/krb5/wrap.c b/source4/heimdal/lib/gssapi/krb5/wrap.c
index b9f4c237c7..3de13f908f 100644
--- a/source4/heimdal/lib/gssapi/krb5/wrap.c
+++ b/source4/heimdal/lib/gssapi/krb5/wrap.c
@@ -33,8 +33,6 @@
#include "gsskrb5_locl.h"
-RCSID("$Id$");
-
/*
* Return initiator subkey, or if that doesn't exists, the subkey.
*/
@@ -540,7 +538,7 @@ OM_uint32 _gsskrb5_wrap
if (ctx->more_flags & IS_CFX)
return _gssapi_wrap_cfx (minor_status, ctx, context, conf_req_flag,
- qop_req, input_message_buffer, conf_state,
+ input_message_buffer, conf_state,
output_message_buffer);
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
diff --git a/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c b/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c
index a8ebe644ab..b1bc7dd981 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_acquire_cred.c
@@ -50,7 +50,7 @@ gss_acquire_cred(OM_uint32 *minor_status,
int i;
*minor_status = 0;
- if (output_cred_handle)
+ if (output_cred_handle == NULL)
return GSS_S_CALL_INACCESSIBLE_READ;
if (actual_mechs)
*actual_mechs = GSS_C_NO_OID_SET;
diff --git a/source4/heimdal/lib/gssapi/mech/gss_aeap.c b/source4/heimdal/lib/gssapi/mech/gss_aeap.c
index cbe0cd1460..9c784f42de 100644
--- a/source4/heimdal/lib/gssapi/mech/gss_aeap.c
+++ b/source4/heimdal/lib/gssapi/mech/gss_aeap.c
@@ -3,27 +3,39 @@
*/
#include "mech_locl.h"
-RCSID("$Id$");
/**
* Encrypts or sign the data.
*
+ * This is a more complicated version of gss_wrap(), it allows the
+ * caller to use AEAD data (signed header/trailer) and allow greater
+ * controll over where the encrypted data is placed.
+ *
* The maximum packet size is gss_context_stream_sizes.max_msg_size.
*
- * The caller needs provide the folloing buffers:
+ * The caller needs provide the folloing buffers when using in conf_req_flag=1 mode:
*
* - HEADER (of size gss_context_stream_sizes.header)
- * SIGN_ONLY (optional, zero or more)
- * DATA
- * SIGN_ONLY (optional, zero or more)
- * PADDING (of size gss_context_stream_sizes.blocksize)
+ * { DATA or SIGN_ONLY } (optional, zero or more)
+ * PADDING (of size gss_context_stream_sizes.blocksize, if zero padding is zero, can be omitted)
* TRAILER (of size gss_context_stream_sizes.trailer)
*
* - on DCE-RPC mode, the caller can skip PADDING and TRAILER if the
- * DATA elements is padded to a block bountry.
+ * DATA elements is padded to a block bountry and header is of at
+ * least size gss_context_stream_sizes.header + gss_context_stream_sizes.trailer.
+ *
+ * HEADER, PADDING, TRAILER will be shrunken to the size required to transmit any of them too large.
*
* To generate gss_wrap() compatible packets, use: HEADER | DATA | PADDING | TRAILER
*
+ * When used in conf_req_flag=0,
+ *
+ * - HEADER (of size gss_context_stream_sizes.header)
+ * { DATA or SIGN_ONLY } (optional, zero or more)
+ * PADDING (of size gss_context_stream_sizes.blocksize, if zero padding is zero, can be omitted)
+ * TRAILER (of size gss_context_stream_sizes.trailer)
+ *
+ *
* The input sizes of HEADER, PADDING and TRAILER can be fetched using gss_wrap_iov_length() or
* gss_context_query_attributes().
*
@@ -65,6 +77,13 @@ gss_wrap_iov(OM_uint32 * minor_status,
iov, iov_count);
}
+/**
+ * Decrypt or verifies the signature on the data.
+ *
+ *
+ * @ingroup gssapi
+ */
+
OM_uint32 GSSAPI_LIB_FUNCTION
gss_unwrap_iov(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
@@ -99,7 +118,18 @@ gss_unwrap_iov(OM_uint32 *minor_status,
iov, iov_count);
}
-OM_uint32 GSSAPI_LIB_FUNCTION
+/**
+ * Update the length fields in iov buffer for the types:
+ * - GSS_IOV_BUFFER_TYPE_HEADER
+ * - GSS_IOV_BUFFER_TYPE_PADDING
+ * - GSS_IOV_BUFFER_TYPE_TRAILER
+ *
+ * Consider using gss_context_query_attributes() to fetch the data instead.
+ *
+ * @ingroup gssapi
+ */
+
+OM_uint32 GSSAPI_LIB_FUNCTION
gss_wrap_iov_length(OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
int conf_req_flag,
@@ -132,6 +162,13 @@ gss_wrap_iov_length(OM_uint32 * minor_status,
iov, iov_count);
}
+/**
+ * Free all buffer allocated by gss_wrap_iov() or gss_unwrap_iov() by
+ * looking at the GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED flag.
+ *
+ * @ingroup gssapi
+ */
+
OM_uint32 GSSAPI_LIB_FUNCTION
gss_release_iov_buffer(OM_uint32 *minor_status,
gss_iov_buffer_desc *iov,
@@ -146,9 +183,10 @@ gss_release_iov_buffer(OM_uint32 *minor_status,
return GSS_S_CALL_INACCESSIBLE_READ;
for (i = 0; i < iov_count; i++) {
- if (iov[i].type & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED)
+ if ((iov[i].type & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED) == 0)
continue;
gss_release_buffer(&junk, &iov[i].buffer);
+ iov[i].type &= ~GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED;
}
return GSS_S_COMPLETE;
}
@@ -159,6 +197,8 @@ gss_release_iov_buffer(OM_uint32 *minor_status,
* SSPI equivalent if this function is QueryContextAttributes.
*
* - GSS_C_ATTR_STREAM_SIZES data is a gss_context_stream_sizes.
+ *
+ * @ingroup gssapi
*/
static gss_OID_desc gss_c_attr_stream_sizes_desc =
diff --git a/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c b/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c
index 158126d99f..2bdfc28ebf 100644
--- a/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c
+++ b/source4/heimdal/lib/gssapi/spnego/accept_sec_context.c
@@ -92,12 +92,6 @@ send_supported_mechs (OM_uint32 *minor_status,
gss_buffer_t output_token)
{
NegotiationTokenWin nt;
- char hostname[MAXHOSTNAMELEN + 1], *p;
- gss_buffer_desc name_buf;
- gss_OID name_type;
- gss_name_t target_princ;
- gss_name_t canon_princ;
- OM_uint32 minor;
size_t buf_len;
gss_buffer_desc data;
OM_uint32 ret;
@@ -116,62 +110,9 @@ send_supported_mechs (OM_uint32 *minor_status,
return ret;
}
- memset(&target_princ, 0, sizeof(target_princ));
- if (gethostname(hostname, sizeof(hostname) - 2) != 0) {
- *minor_status = errno;
- free_NegotiationTokenWin(&nt);
- return GSS_S_FAILURE;
- }
- hostname[sizeof(hostname) - 1] = '\0';
-
- /* Send the constructed SAM name for this host */
- for (p = hostname; *p != '\0' && *p != '.'; p++) {
- *p = toupper((unsigned char)*p);
- }
- *p++ = '$';
- *p = '\0';
-
- name_buf.length = strlen(hostname);
- name_buf.value = hostname;
-
- ret = gss_import_name(minor_status, &name_buf,
- GSS_C_NO_OID,
- &target_princ);
- if (ret != GSS_S_COMPLETE) {
- free_NegotiationTokenWin(&nt);
- return ret;
- }
-
- name_buf.length = 0;
- name_buf.value = NULL;
-
- /* Canonicalize the name using the preferred mechanism */
- ret = gss_canonicalize_name(minor_status,
- target_princ,
- GSS_C_NO_OID,
- &canon_princ);
- if (ret != GSS_S_COMPLETE) {
- free_NegotiationTokenWin(&nt);
- gss_release_name(&minor, &target_princ);
- return ret;
- }
-
- ret = gss_display_name(minor_status, canon_princ,
- &name_buf, &name_type);
- if (ret != GSS_S_COMPLETE) {
- free_NegotiationTokenWin(&nt);
- gss_release_name(&minor, &canon_princ);
- gss_release_name(&minor, &target_princ);
- return ret;
- }
-
- gss_release_name(&minor, &canon_princ);
- gss_release_name(&minor, &target_princ);
-
ALLOC(nt.u.negTokenInit.negHints, 1);
if (nt.u.negTokenInit.negHints == NULL) {
*minor_status = ENOMEM;
- gss_release_buffer(&minor, &name_buf);
free_NegotiationTokenWin(&nt);
return GSS_S_FAILURE;
}
@@ -179,20 +120,19 @@ send_supported_mechs (OM_uint32 *minor_status,
ALLOC(nt.u.negTokenInit.negHints->hintName, 1);
if (nt.u.negTokenInit.negHints->hintName == NULL) {
*minor_status = ENOMEM;
- gss_release_buffer(&minor, &name_buf);
free_NegotiationTokenWin(&nt);
return GSS_S_FAILURE;
}
- *(nt.u.negTokenInit.negHints->hintName) = name_buf.value;
- name_buf.value = NULL;
+ *nt.u.negTokenInit.negHints->hintName = strdup("not_defined_in_RFC4178@please_ignore");
nt.u.negTokenInit.negHints->hintAddress = NULL;
ASN1_MALLOC_ENCODE(NegotiationTokenWin,
data.value, data.length, &nt, &buf_len, ret);
free_NegotiationTokenWin(&nt);
if (ret) {
- return ret;
+ *minor_status = ret;
+ return GSS_S_FAILURE;
}
if (data.length != buf_len)
abort();
diff --git a/source4/heimdal/lib/hcrypto/des.h b/source4/heimdal/lib/hcrypto/des.h
index 14402d4b1c..99eb76c818 100644
--- a/source4/heimdal/lib/hcrypto/des.h
+++ b/source4/heimdal/lib/hcrypto/des.h
@@ -84,12 +84,14 @@ typedef struct DES_key_schedule
*
*/
-#if !defined(__GNUC__) && !defined(__attribute__)
-#define __attribute__(x)
-#endif
-
#ifndef HC_DEPRECATED
+#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1 )))
#define HC_DEPRECATED __attribute__((deprecated))
+#elif defined(_MSC_VER) && (_MSC_VER>1200)
+#define HC_DEPRECATED __declspec(deprecated)
+#else
+#define HC_DEPRECATED
+#endif
#endif
#ifdef __cplusplus
diff --git a/source4/heimdal/lib/hcrypto/evp.h b/source4/heimdal/lib/hcrypto/evp.h
index a7c8fac900..0086a06960 100644
--- a/source4/heimdal/lib/hcrypto/evp.h
+++ b/source4/heimdal/lib/hcrypto/evp.h
@@ -190,10 +190,17 @@ struct hc_evp_md {
#endif
#ifndef HC_DEPRECATED
+#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1 )))
#define HC_DEPRECATED __attribute__((deprecated))
+#elif defined(_MSC_VER) && (_MSC_VER>1200)
+#define HC_DEPRECATED __declspec(deprecated)
+#else
+#define HC_DEPRECATED
#endif
+#endif
+
#ifndef HC_DEPRECATED_CRYPTO
-#define HC_DEPRECATED_CRYPTO __attribute__((deprecated))
+#define HC_DEPRECATED_CRYPTO HC_DEPRECATED
#endif
diff --git a/source4/heimdal/lib/hdb/db.c b/source4/heimdal/lib/hdb/db.c
index 556833d1c4..9de0a04a1f 100644
--- a/source4/heimdal/lib/hdb/db.c
+++ b/source4/heimdal/lib/hdb/db.c
@@ -33,8 +33,6 @@
#include "hdb_locl.h"
-RCSID("$Id$");
-
#if HAVE_DB1
#if defined(HAVE_DB_185_H)
@@ -317,6 +315,7 @@ hdb_db_create(krb5_context context, HDB **db,
}
(*db)->hdb_master_key_set = 0;
(*db)->hdb_openp = 0;
+ (*db)->hdb_capability_flags = HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL;
(*db)->hdb_open = DB_open;
(*db)->hdb_close = DB_close;
(*db)->hdb_fetch = _hdb_fetch;
diff --git a/source4/heimdal/lib/hdb/dbinfo.c b/source4/heimdal/lib/hdb/dbinfo.c
index 7e2961c614..a399ab0a5c 100644
--- a/source4/heimdal/lib/hdb/dbinfo.c
+++ b/source4/heimdal/lib/hdb/dbinfo.c
@@ -33,8 +33,6 @@
#include "hdb_locl.h"
-RCSID("$Id$");
-
struct hdb_dbinfo {
char *label;
char *realm;
diff --git a/source4/heimdal/lib/hdb/ext.c b/source4/heimdal/lib/hdb/ext.c
index 9053fd6633..faf0b6bdf2 100644
--- a/source4/heimdal/lib/hdb/ext.c
+++ b/source4/heimdal/lib/hdb/ext.c
@@ -34,8 +34,6 @@
#include "hdb_locl.h"
#include <der.h>
-RCSID("$Id$");
-
krb5_error_code
hdb_entry_check_mandatory(krb5_context context, const hdb_entry *ent)
{
diff --git a/source4/heimdal/lib/hdb/hdb.asn1 b/source4/heimdal/lib/hdb/hdb.asn1
index c2abd4af73..a72851c9f2 100644
--- a/source4/heimdal/lib/hdb/hdb.asn1
+++ b/source4/heimdal/lib/hdb/hdb.asn1
@@ -45,7 +45,9 @@ HDBFlags ::= BIT STRING {
immutable(13), -- may not be deleted
trusted-for-delegation(14), -- Trusted to print forwardabled tickets
allow-kerberos4(15), -- Allow Kerberos 4 requests
- allow-digest(16) -- Allow digest requests
+ allow-digest(16), -- Allow digest requests
+ locked-out(17) -- Account is locked out,
+ -- authentication will be denied
}
GENERATION ::= SEQUENCE {
diff --git a/source4/heimdal/lib/hdb/hdb.c b/source4/heimdal/lib/hdb/hdb.c
index e55b0bed03..9795f8b255 100644
--- a/source4/heimdal/lib/hdb/hdb.c
+++ b/source4/heimdal/lib/hdb/hdb.c
@@ -33,7 +33,6 @@
#include "krb5_locl.h"
#include "hdb_locl.h"
-RCSID("$Id$");
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
diff --git a/source4/heimdal/lib/hdb/hdb.h b/source4/heimdal/lib/hdb/hdb.h
index a5e6514e6c..f490dbf2f0 100644
--- a/source4/heimdal/lib/hdb/hdb.h
+++ b/source4/heimdal/lib/hdb/hdb.h
@@ -54,7 +54,15 @@ enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK };
#define HDB_F_GET_ANY 28 /* fetch any of client,server,krbtgt */
#define HDB_F_CANON 32 /* want canonicalition */
+/* hdb_capability_flags */
#define HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL 1
+#define HDB_CAP_F_HANDLE_PASSWORDS 2
+#define HDB_CAP_F_PASSWORD_UPDATE_KEYS 4
+
+/* auth status values */
+#define HDB_AUTH_SUCCESS 0
+#define HDB_AUTH_WRONG_PASSWORD 1
+#define HDB_AUTH_INVALID_SIGNATURE 2
/* key usage for master key */
#define HDB_KU_MKEY 0x484442
@@ -184,6 +192,34 @@ typedef struct HDB{
* point for the module.
*/
krb5_error_code (*hdb_destroy)(krb5_context, struct HDB*);
+ /**
+ * Change password.
+ *
+ * Will update keys for the entry when given password. The new
+ * keys must be written into the entry and and will then later be
+ * ->hdb_store() into the database. The backend will still perform
+ * all other operations, increasing the kvno, and update
+ * modification timestamp.
+ *
+ * The backen need to call _kadm5_set_keys() and perform password
+ * quality checks.
+ */
+ krb5_error_code (*hdb_password)(krb5_context, struct HDB*, hdb_entry_ex*, const char *, int);
+
+ /**
+ * Auth feedback
+ *
+ * This is a feedback call that allows backends that provides
+ * lockout functionality to register failure and/or successes.
+ *
+ * In case the entry is locked out, the backend should set the
+ * hdb_entry.flags.locked-out flag.
+ */
+ krb5_error_code (*hdb_auth_status)(krb5_context, struct HDB *, hdb_entry_ex *, int);
+ /**
+ * Check is delegation is allowed.
+ */
+ krb5_error_code (*hdb_check_constrained_delegation)(krb5_context, struct HDB *, hdb_entry_ex *, krb5_const_principal);
}HDB;
#define HDB_INTERFACE_VERSION 5
diff --git a/source4/heimdal/lib/hdb/keys.c b/source4/heimdal/lib/hdb/keys.c
index 50fe7d7fda..63f254d002 100644
--- a/source4/heimdal/lib/hdb/keys.c
+++ b/source4/heimdal/lib/hdb/keys.c
@@ -34,8 +34,6 @@
#include "hdb_locl.h"
-RCSID("$Id$");
-
/*
* free all the memory used by (len, keys)
*/
diff --git a/source4/heimdal/lib/hdb/keytab.c b/source4/heimdal/lib/hdb/keytab.c
index 97989a9764..9b36a268cf 100644
--- a/source4/heimdal/lib/hdb/keytab.c
+++ b/source4/heimdal/lib/hdb/keytab.c
@@ -35,8 +35,6 @@
/* keytab backend for HDB databases */
-RCSID("$Id$");
-
struct hdb_data {
char *dbname;
char *mkey;
@@ -123,61 +121,43 @@ hdb_get_name(krb5_context context,
return 0;
}
-static void
-set_config (krb5_context context,
- const krb5_config_binding *binding,
- const char **dbname,
- const char **mkey)
-{
- *dbname = krb5_config_get_string(context, binding, "dbname", NULL);
- *mkey = krb5_config_get_string(context, binding, "mkey_file", NULL);
-}
-
/*
* try to figure out the database (`dbname') and master-key (`mkey')
* that should be used for `principal'.
*/
-static void
+static krb5_error_code
find_db (krb5_context context,
- const char **dbname,
- const char **mkey,
+ char **dbname,
+ char **mkey,
krb5_const_principal principal)
{
- const krb5_config_binding *top_bind = NULL;
- const krb5_config_binding *default_binding = NULL;
- const krb5_config_binding *db;
krb5_const_realm realm = krb5_principal_get_realm(context, principal);
+ krb5_error_code ret;
+ struct hdb_dbinfo *head, *dbinfo = NULL;
*dbname = *mkey = NULL;
- while ((db =
- krb5_config_get_next(context,
- NULL,
- &top_bind,
- krb5_config_list,
- "kdc",
- "database",
- NULL)) != NULL) {
- const char *p;
-
- p = krb5_config_get_string (context, db, "realm", NULL);
- if (p == NULL) {
- if(default_binding) {
- krb5_warnx(context, "WARNING: more than one realm-less "
- "database specification");
- krb5_warnx(context, "WARNING: using the first encountered");
- } else
- default_binding = db;
- } else if (strcmp (realm, p) == 0) {
- set_config (context, db, dbname, mkey);
+ ret = hdb_get_dbinfo(context, &head);
+ if (ret)
+ return ret;
+
+ while ((dbinfo = hdb_dbinfo_get_next(head, dbinfo)) != NULL) {
+ const char *p = hdb_dbinfo_get_realm(context, dbinfo);
+ if (p && strcmp (realm, p) == 0) {
+ p = hdb_dbinfo_get_dbname(context, dbinfo);
+ if (p)
+ *dbname = strdup(p);
+ p = hdb_dbinfo_get_mkey_file(context, dbinfo);
+ if (p)
+ *mkey = strdup(p);
break;
}
}
- if (*dbname == NULL && default_binding != NULL)
- set_config (context, default_binding, dbname, mkey);
+ hdb_free_dbinfo(context, &head);
if (*dbname == NULL)
- *dbname = HDB_DEFAULT_DB;
+ *dbname = strdup(HDB_DEFAULT_DB);
+ return 0;
}
/*
@@ -196,29 +176,35 @@ hdb_get_entry(krb5_context context,
hdb_entry_ex ent;
krb5_error_code ret;
struct hdb_data *d = id->data;
- int i;
- HDB *db;
const char *dbname = d->dbname;
const char *mkey = d->mkey;
+ char *fdbname = NULL, *fmkey = NULL;
+ HDB *db;
+ int i;
memset(&ent, 0, sizeof(ent));
- if (dbname == NULL)
- find_db (context, &dbname, &mkey, principal);
+ if (dbname == NULL) {
+ ret = find_db(context, &fdbname, &fmkey, principal);
+ if (ret)
+ return ret;
+ dbname = fdbname;
+ mkey = fmkey;
+ }
ret = hdb_create (context, &db, dbname);
if (ret)
- return ret;
+ goto out2;
ret = hdb_set_master_keyfile (context, db, mkey);
if (ret) {
(*db->hdb_destroy)(context, db);
- return ret;
+ goto out2;
}
ret = (*db->hdb_open)(context, db, O_RDONLY, 0);
if (ret) {
(*db->hdb_destroy)(context, db);
- return ret;
+ goto out2;
}
ret = (*db->hdb_fetch)(context, db, principal,
HDB_F_DECRYPT|
@@ -252,9 +238,12 @@ hdb_get_entry(krb5_context context,
}
}
hdb_free_entry(context, &ent);
-out:
+ out:
(*db->hdb_close)(context, db);
(*db->hdb_destroy)(context, db);
+ out2:
+ free(fdbname);
+ free(fmkey);
return ret;
}
diff --git a/source4/heimdal/lib/hdb/mkey.c b/source4/heimdal/lib/hdb/mkey.c
index 1520c4f7e9..35323cf100 100644
--- a/source4/heimdal/lib/hdb/mkey.c
+++ b/source4/heimdal/lib/hdb/mkey.c
@@ -36,8 +36,6 @@
#define O_BINARY 0
#endif
-RCSID("$Id$");
-
struct hdb_master_key_data {
krb5_keytab_entry keytab;
krb5_crypto crypto;
diff --git a/source4/heimdal/lib/hdb/ndbm.c b/source4/heimdal/lib/hdb/ndbm.c
index 1e9df81652..d97a98ed6b 100644
--- a/source4/heimdal/lib/hdb/ndbm.c
+++ b/source4/heimdal/lib/hdb/ndbm.c
@@ -33,8 +33,6 @@
#include "hdb_locl.h"
-RCSID("$Id$");
-
#if HAVE_NDBM
#if defined(HAVE_GDBM_NDBM_H)
@@ -348,6 +346,7 @@ hdb_ndbm_create(krb5_context context, HDB **db,
}
(*db)->hdb_master_key_set = 0;
(*db)->hdb_openp = 0;
+ (*db)->hdb_capability_flags = HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL;
(*db)->hdb_open = NDBM_open;
(*db)->hdb_close = NDBM_close;
(*db)->hdb_fetch = _hdb_fetch;
diff --git a/source4/heimdal/lib/hx509/crypto.c b/source4/heimdal/lib/hx509/crypto.c
index 8063100717..f4667c6e31 100644
--- a/source4/heimdal/lib/hx509/crypto.c
+++ b/source4/heimdal/lib/hx509/crypto.c
@@ -37,10 +37,6 @@ struct hx509_crypto;
struct signature_alg;
-enum crypto_op_type {
- COT_SIGN
-};
-
struct hx509_generate_private_context {
const heim_oid *key_oid;
int isCA;
diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c
index 9fd2117345..a30780d1ed 100644
--- a/source4/heimdal/lib/krb5/crypto.c
+++ b/source4/heimdal/lib/krb5/crypto.c
@@ -3182,7 +3182,7 @@ krb5_encrypt_iov_ivec(krb5_context context,
krb5_error_code ret;
struct key_data *dkey;
const struct encryption_type *et = crypto->et;
- krb5_crypto_iov *tiv, *piv, *hiv, *div;
+ krb5_crypto_iov *tiv, *piv, *hiv;
if (num_data < 0) {
krb5_clear_error_message(context);
@@ -3197,11 +3197,11 @@ krb5_encrypt_iov_ivec(krb5_context context,
headersz = et->confoundersize;
trailersz = CHECKSUMSIZE(et->keyed_checksum);
- div = find_iv(data, num_data, KRB5_CRYPTO_TYPE_DATA);
- if (div == NULL)
- return KRB5_CRYPTO_INTERNAL;
-
- len = div->data.length;
+ for (len = 0, i = 0; i < num_data; i++) {
+ if (data[i].flags != KRB5_CRYPTO_TYPE_DATA)
+ continue;
+ len += data[i].data.length;
+ }
sz = headersz + len;
block_sz = (sz + et->padsize - 1) &~ (et->padsize - 1); /* pad */
@@ -3217,7 +3217,6 @@ krb5_encrypt_iov_ivec(krb5_context context,
krb5_generate_random_block(hiv->data.data, hiv->data.length);
/* padding */
-
piv = find_iv(data, num_data, KRB5_CRYPTO_TYPE_PADDING);
/* its ok to have no TYPE_PADDING if there is no padding */
if (piv == NULL && pad_sz != 0)
@@ -3226,26 +3225,26 @@ krb5_encrypt_iov_ivec(krb5_context context,
if (piv->data.length < pad_sz)
return KRB5_BAD_MSIZE;
piv->data.length = pad_sz;
+ if (pad_sz)
+ memset(piv->data.data, pad_sz, pad_sz);
+ else
+ piv = NULL;
}
-
/* trailer */
-
tiv = find_iv(data, num_data, KRB5_CRYPTO_TYPE_TRAILER);
if (tiv == NULL || tiv->data.length != trailersz)
return KRB5_BAD_MSIZE;
-
/*
* XXX replace with EVP_Sign? at least make create_checksum an iov
* function.
* XXX CTS EVP is broken, can't handle multi buffers :(
*/
- len = hiv->data.length;
+ len = block_sz;
for (i = 0; i < num_data; i++) {
- if (data[i].flags != KRB5_CRYPTO_TYPE_DATA &&
- data[i].flags != KRB5_CRYPTO_TYPE_SIGN_ONLY)
+ if (data[i].flags != KRB5_CRYPTO_TYPE_SIGN_ONLY)
continue;
len += data[i].data.length;
}
@@ -3261,6 +3260,10 @@ krb5_encrypt_iov_ivec(krb5_context context,
memcpy(q, data[i].data.data, data[i].data.length);
q += data[i].data.length;
}
+ if (piv) {
+ memset(q, 0, piv->data.length);
+ q += piv->data.length;
+ }
ret = create_checksum(context,
et->keyed_checksum,
@@ -3282,30 +3285,24 @@ krb5_encrypt_iov_ivec(krb5_context context,
memcpy(tiv->data.data, cksum.checksum.data, cksum.checksum.length);
free_Checksum (&cksum);
- /* now encrypt data */
-
- ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey);
- if(ret)
- return ret;
- ret = _key_schedule(context, dkey);
- if(ret)
- return ret;
-
/* XXX replace with EVP_Cipher */
-
- len = hiv->data.length + div->data.length;
- if (piv)
- len += piv->data.length;
-
- p = q = malloc(len);
+ p = q = malloc(block_sz);
if(p == NULL)
return ENOMEM;
memcpy(q, hiv->data.data, hiv->data.length);
q += hiv->data.length;
- memcpy(q, div->data.data, div->data.length);
- q += div->data.length;
- memset(q, 0, pad_sz);
+
+ for (i = 0; i < num_data; i++) {
+ if (data[i].flags != KRB5_CRYPTO_TYPE_DATA)
+ continue;
+ memcpy(q, data[i].data.data, data[i].data.length);
+ q += data[i].data.length;
+ }
+ if (piv) {
+ memset(q, 0, piv->data.length);
+ q += piv->data.length;
+ }
ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey);
if(ret) {
@@ -3318,7 +3315,7 @@ krb5_encrypt_iov_ivec(krb5_context context,
return ret;
}
- ret = (*et->encrypt)(context, dkey, p, len, 1, usage, ivec);
+ ret = (*et->encrypt)(context, dkey, p, block_sz, 1, usage, ivec);
if (ret) {
free(p);
return ret;
@@ -3330,11 +3327,17 @@ krb5_encrypt_iov_ivec(krb5_context context,
memcpy(hiv->data.data, q, hiv->data.length);
q += hiv->data.length;
- memcpy(div->data.data, q, div->data.length);
- q += div->data.length;
-
- if (piv)
+ for (i = 0; i < num_data; i++) {
+ if (data[i].flags != KRB5_CRYPTO_TYPE_DATA)
+ continue;
+ memcpy(data[i].data.data, q, data[i].data.length);
+ q += data[i].data.length;
+ }
+ if (piv) {
memcpy(piv->data.data, q, pad_sz);
+ q += pad_sz;
+ }
+
free(p);
return ret;
@@ -3371,13 +3374,12 @@ krb5_decrypt_iov_ivec(krb5_context context,
{
unsigned int i;
size_t headersz, trailersz, len;
- size_t sz, block_sz, pad_sz;
Checksum cksum;
unsigned char *p, *q;
krb5_error_code ret;
struct key_data *dkey;
struct encryption_type *et = crypto->et;
- krb5_crypto_iov *tiv, *hiv, *div;
+ krb5_crypto_iov *tiv, *hiv;
if (num_data < 0) {
krb5_clear_error_message(context);
@@ -3390,56 +3392,47 @@ krb5_decrypt_iov_ivec(krb5_context context,
}
headersz = et->confoundersize;
- trailersz = CHECKSUMSIZE(et->keyed_checksum);
-
- for (len = 0, i = 0; i < num_data; i++) {
- if (data[i].flags == KRB5_CRYPTO_TYPE_DATA) {
- if (len != 0)
- return KRB5_CRYPTO_INTERNAL;
- len += data[i].data.length;
- }
- }
-
- sz = headersz + len;
- block_sz = (sz + et->padsize - 1) &~ (et->padsize - 1); /* pad */
-
- pad_sz = block_sz - sz;
- trailersz += pad_sz;
-
- /* header */
hiv = find_iv(data, num_data, KRB5_CRYPTO_TYPE_HEADER);
- if (hiv == NULL || hiv->data.length < headersz)
+ if (hiv == NULL || hiv->data.length != headersz)
return KRB5_BAD_MSIZE;
- hiv->data.length = headersz;
/* trailer */
+ trailersz = CHECKSUMSIZE(et->keyed_checksum);
tiv = find_iv(data, num_data, KRB5_CRYPTO_TYPE_TRAILER);
- if (tiv == NULL || tiv->data.length < trailersz)
+ if (tiv->data.length != trailersz)
return KRB5_BAD_MSIZE;
- tiv->data.length = trailersz;
-
- div = find_iv(data, num_data, KRB5_CRYPTO_TYPE_DATA);
- if (div == NULL)
- return KRB5_CRYPTO_INTERNAL;
- /* XXX replace with EVP_Cipher */
+ /* Find length of data we will decrypt */
- for (len = 0, i = 0; i < num_data; i++) {
- if (data[i].flags != KRB5_CRYPTO_TYPE_HEADER &&
- data[i].flags != KRB5_CRYPTO_TYPE_DATA)
+ len = headersz;
+ for (i = 0; i < num_data; i++) {
+ if (data[i].flags != KRB5_CRYPTO_TYPE_DATA)
continue;
len += data[i].data.length;
}
+ if ((len % et->padsize) != 0) {
+ krb5_clear_error_message(context);
+ return KRB5_BAD_MSIZE;
+ }
+
+ /* XXX replace with EVP_Cipher */
+
p = q = malloc(len);
if (p == NULL)
return ENOMEM;
memcpy(q, hiv->data.data, hiv->data.length);
q += hiv->data.length;
- memcpy(q, div->data.data, div->data.length);
+
+ for (i = 0; i < num_data; i++) {
+ if (data[i].flags != KRB5_CRYPTO_TYPE_DATA)
+ continue;
+ memcpy(q, data[i].data.data, data[i].data.length);
+ q += data[i].data.length;
+ }
ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey);
if(ret) {
@@ -3460,20 +3453,26 @@ krb5_decrypt_iov_ivec(krb5_context context,
/* copy data back to buffers */
memcpy(hiv->data.data, p, hiv->data.length);
- memcpy(div->data.data, p + hiv->data.length, len - hiv->data.length);
+ q = p + hiv->data.length;
+ for (i = 0; i < num_data; i++) {
+ if (data[i].flags != KRB5_CRYPTO_TYPE_DATA)
+ continue;
+ memcpy(data[i].data.data, q, data[i].data.length);
+ q += data[i].data.length;
+ }
+
free(p);
/* check signature */
-
- len = hiv->data.length;
for (i = 0; i < num_data; i++) {
- if (data[i].flags != KRB5_CRYPTO_TYPE_DATA &&
- data[i].flags != KRB5_CRYPTO_TYPE_SIGN_ONLY)
+ if (data[i].flags != KRB5_CRYPTO_TYPE_SIGN_ONLY)
continue;
len += data[i].data.length;
}
p = q = malloc(len);
+ if (p == NULL)
+ return ENOMEM;
memcpy(q, hiv->data.data, hiv->data.length);
q += hiv->data.length;
@@ -3582,33 +3581,145 @@ krb5_create_checksum_iov(krb5_context context,
return 0;
}
+/**
+ * Verify a Kerberos message checksum.
+ *
+ * @param context Kerberos context
+ * @param crypto Kerberos crypto context
+ * @param usage Key usage for this buffer
+ * @param data array of buffers to process
+ * @param num_data length of array
+ *
+ * @return Return an error code or 0.
+ * @ingroup krb5_crypto
+ */
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_verify_checksum_iov(krb5_context context,
+ krb5_crypto crypto,
+ unsigned usage,
+ krb5_crypto_iov *data,
+ unsigned int num_data,
+ krb5_cksumtype *type)
+{
+ struct encryption_type *et = crypto->et;
+ Checksum cksum;
+ krb5_crypto_iov *civ;
+ krb5_error_code ret;
+ int i;
+ size_t len;
+ char *p, *q;
+
+ if (num_data < 0) {
+ krb5_clear_error_message(context);
+ return KRB5_CRYPTO_INTERNAL;
+ }
+
+ if(!derived_crypto(context, crypto)) {
+ krb5_clear_error_message(context);
+ return KRB5_CRYPTO_INTERNAL;
+ }
+
+ civ = find_iv(data, num_data, KRB5_CRYPTO_TYPE_CHECKSUM);
+ if (civ == NULL)
+ return KRB5_BAD_MSIZE;
+
+ len = 0;
+ for (i = 0; i < num_data; i++) {
+ if (data[i].flags != KRB5_CRYPTO_TYPE_DATA &&
+ data[i].flags != KRB5_CRYPTO_TYPE_SIGN_ONLY)
+ continue;
+ len += data[i].data.length;
+ }
+
+ p = q = malloc(len);
+
+ for (i = 0; i < num_data; i++) {
+ if (data[i].flags != KRB5_CRYPTO_TYPE_DATA &&
+ data[i].flags != KRB5_CRYPTO_TYPE_SIGN_ONLY)
+ continue;
+ memcpy(q, data[i].data.data, data[i].data.length);
+ q += data[i].data.length;
+ }
+
+ cksum.cksumtype = CHECKSUMTYPE(et->keyed_checksum);
+ cksum.checksum.length = civ->data.length;
+ cksum.checksum.data = civ->data.data;
+
+ ret = krb5_verify_checksum(context, crypto, usage, p, len, &cksum);
+ free(p);
+
+ if (ret == 0 && type)
+ *type = cksum.cksumtype;
+
+ return ret;
+}
+
-size_t KRB5_LIB_FUNCTION
+krb5_error_code KRB5_LIB_FUNCTION
krb5_crypto_length(krb5_context context,
krb5_crypto crypto,
- int type)
+ int type,
+ size_t *len)
{
- if (!derived_crypto(context, crypto))
- return (size_t)-1;
+ if (!derived_crypto(context, crypto)) {
+ krb5_set_error_message(context, EINVAL, "not a derived crypto");
+ return EINVAL;
+ }
+
switch(type) {
case KRB5_CRYPTO_TYPE_EMPTY:
+ *len = 0;
return 0;
case KRB5_CRYPTO_TYPE_HEADER:
- return crypto->et->blocksize;
+ *len = crypto->et->blocksize;
+ return 0;
+ case KRB5_CRYPTO_TYPE_DATA:
+ case KRB5_CRYPTO_TYPE_SIGN_ONLY:
+ /* len must already been filled in */
+ return 0;
case KRB5_CRYPTO_TYPE_PADDING:
if (crypto->et->padsize > 1)
- return crypto->et->padsize;
+ *len = crypto->et->padsize;
+ else
+ *len = 0;
return 0;
case KRB5_CRYPTO_TYPE_TRAILER:
- return CHECKSUMSIZE(crypto->et->keyed_checksum);
+ *len = CHECKSUMSIZE(crypto->et->keyed_checksum);
+ return 0;
case KRB5_CRYPTO_TYPE_CHECKSUM:
if (crypto->et->keyed_checksum)
- return CHECKSUMSIZE(crypto->et->keyed_checksum);
- return CHECKSUMSIZE(crypto->et->checksum);
+ *len = CHECKSUMSIZE(crypto->et->keyed_checksum);
+ else
+ *len = CHECKSUMSIZE(crypto->et->checksum);
+ return 0;
+ }
+ krb5_set_error_message(context, EINVAL,
+ "%d not a supported type", type);
+ return EINVAL;
+}
+
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb5_crypto_length_iov(krb5_context context,
+ krb5_crypto crypto,
+ krb5_crypto_iov *data,
+ unsigned int num_data)
+{
+ krb5_error_code ret;
+ int i;
+
+ for (i = 0; i < num_data; i++) {
+ ret = krb5_crypto_length(context, crypto,
+ data[i].flags,
+ &data[i].data.length);
+ if (ret)
+ return ret;
}
- return (size_t)-1;
+ return 0;
}
+
krb5_error_code KRB5_LIB_FUNCTION
krb5_encrypt_ivec(krb5_context context,
krb5_crypto crypto,
diff --git a/source4/heimdal/lib/krb5/get_addrs.c b/source4/heimdal/lib/krb5/get_addrs.c
index 96571af531..8f366fa148 100644
--- a/source4/heimdal/lib/krb5/get_addrs.c
+++ b/source4/heimdal/lib/krb5/get_addrs.c
@@ -41,9 +41,7 @@ struct mbuf;
#ifdef HAVE_NET_IF_H
#include <net/if.h>
#endif
-#ifdef HAVE_IFADDR_H
#include <ifaddrs.h>
-#endif
static krb5_error_code
gethostname_fallback (krb5_context context, krb5_addresses *res)
diff --git a/source4/heimdal/lib/krb5/init_creds_pw.c b/source4/heimdal/lib/krb5/init_creds_pw.c
index 0435ab5d3b..ff89a90d55 100644
--- a/source4/heimdal/lib/krb5/init_creds_pw.c
+++ b/source4/heimdal/lib/krb5/init_creds_pw.c
@@ -1601,7 +1601,7 @@ krb5_init_creds_step(krb5_context context,
ret = 0;
} else if (ret == KRB5_KDC_ERR_WRONG_REALM && ctx->flags.canonicalize) {
/* client referal to a new realm */
- if (ctx->error.crealm) {
+ if (ctx->error.crealm == NULL) {
krb5_set_error_message(context, ret,
N_("Got a client referral, not but no realm", ""));
goto out;
diff --git a/source4/heimdal/lib/krb5/krb5.h b/source4/heimdal/lib/krb5/krb5.h
index 13dafacf21..1f2e769728 100644
--- a/source4/heimdal/lib/krb5/krb5.h
+++ b/source4/heimdal/lib/krb5/krb5.h
@@ -52,7 +52,13 @@
#endif
#ifndef KRB5_DEPRECATED
+#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1 )))
#define KRB5_DEPRECATED __attribute__((deprecated))
+#elif defined(_MSC_VER) && (_MSC_VER>1200)
+#define KRB5_DEPRECATED __declspec(deprecated)
+#else
+#define KRB5_DEPRECATED
+#endif
#endif
/* simple constants */
diff --git a/source4/heimdal/lib/krb5/log.c b/source4/heimdal/lib/krb5/log.c
index 31d267320f..ee5c1159b1 100644
--- a/source4/heimdal/lib/krb5/log.c
+++ b/source4/heimdal/lib/krb5/log.c
@@ -32,6 +32,7 @@
*/
#include "krb5_locl.h"
+#include <vis.h>
struct facility {
int min;
@@ -218,11 +219,21 @@ log_file(const char *timestr,
void *data)
{
struct file_data *f = data;
+ char *msgclean;
+ size_t len = strlen(msg) + 1;
if(f->keep_open == 0)
f->fd = fopen(f->filename, f->mode);
if(f->fd == NULL)
return;
- fprintf(f->fd, "%s %s\n", timestr, msg);
+ /* make sure the log doesn't contain special chars */
+ len *= 4;
+ msgclean = malloc(len);
+ if (msgclean == NULL)
+ goto out;
+ strvisx(rk_UNCONST(msg), msgclean, len, VIS_OCTAL);
+ fprintf(f->fd, "%s %s\n", timestr, msgclean);
+ free(msgclean);
+ out:
if(f->keep_open == 0) {
fclose(f->fd);
f->fd = NULL;
diff --git a/source4/heimdal/lib/krb5/store_emem.c b/source4/heimdal/lib/krb5/store_emem.c
index 4be89b6564..acf984280e 100644
--- a/source4/heimdal/lib/krb5/store_emem.c
+++ b/source4/heimdal/lib/krb5/store_emem.c
@@ -110,7 +110,12 @@ emem_trunc(krb5_storage *sp, off_t offset)
* If offset is larget then current size, or current size is
* shrunk more then half of the current size, adjust buffer.
*/
- if (offset > s->size || (s->size / 2) > offset) {
+ if (offset == 0) {
+ free(s->base);
+ s->size = 0;
+ s->base = NULL;
+ s->ptr = NULL;
+ } else if (offset > s->size || (s->size / 2) > offset) {
void *base;
size_t off;
off = s->ptr - s->base;
diff --git a/source4/heimdal_build/ifaddrs.hin b/source4/heimdal_build/ifaddrs.hin
new file mode 100644
index 0000000000..a50b03335b
--- /dev/null
+++ b/source4/heimdal_build/ifaddrs.hin
@@ -0,0 +1 @@
+#include "system/network.h"
diff --git a/source4/heimdal_build/internal.m4 b/source4/heimdal_build/internal.m4
index 5c8d78e56d..e7e7ae1842 100644
--- a/source4/heimdal_build/internal.m4
+++ b/source4/heimdal_build/internal.m4
@@ -46,6 +46,15 @@ dnl declarations will be correct). Phew!
AC_CHECK_HEADERS([err.h], [],
[ cp heimdal/lib/roken/err.hin heimdal_build/err.h ])
+dnl Not all systems have ifaddrs.h, so we provide a replacement. Heimdal
+dnl unconditionally #includes <ifaddrs.h>, so we need to create an ifaddrs.h,
+dnl but we can't just have a static one because we don't want to use
+dnl it on systems that have a real ifaddrs.h. If the system has a real
+dnl ifaddrs.h. We don't use heimdal's lib/roken/ifaddrs.hin because
+dnl our libreplace would conflict with it.
+AC_CHECK_HEADERS([ifaddrs.h], [],
+ [ cp heimdal_build/ifaddrs.hin heimdal_build/ifaddrs.h ])
+
AC_CHECK_HEADERS([ \
crypt.h \
curses.h \
diff --git a/source4/heimdal_build/replace.c b/source4/heimdal_build/replace.c
index ba43dd9495..8c3def7dca 100644
--- a/source4/heimdal_build/replace.c
+++ b/source4/heimdal_build/replace.c
@@ -21,11 +21,9 @@
*/
#include "config.h"
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
#include "err.h"
#include "roken.h"
+#include "system/filesys.h"
#ifndef HAVE_ERR
void err(int eval, const char *format, ...)
@@ -63,6 +61,7 @@
#ifndef HAVE_FLOCK
int flock(int fd, int op)
{
+#undef flock
struct flock lock;
lock.l_whence = 0;
lock.l_start = 0;
diff --git a/source4/heimdal_build/roken.h b/source4/heimdal_build/roken.h
index 4eabbe2af4..87060cff17 100644
--- a/source4/heimdal_build/roken.h
+++ b/source4/heimdal_build/roken.h
@@ -37,6 +37,10 @@
#define HAVE_SETEUID 1
#endif
+#ifndef HAVE_STRNLEN
+#define HAVE_STRNLEN
+#endif
+
#ifndef HAVE_STRNDUP
#define HAVE_STRNDUP
#endif
@@ -53,6 +57,14 @@
#define HAVE_STRCASECMP
#endif
+#ifndef HAVE_ASPRINTF
+#define HAVE_ASPRINTF
+#endif
+
+#ifndef HAVE_VASPRINTF
+#define HAVE_VASPRINTF
+#endif
+
#ifndef HAVE_MKSTEMP
#define HAVE_MKSTEMP
#endif
@@ -85,6 +97,10 @@
#define HAVE_INNETGR
#endif
+#ifndef HAVE_INET_ATON
+#define HAVE_INET_ATON
+#endif
+
/* we lie about having pidfile() so that NetBSD5 can compile. Nothing
in the parts of heimdal we use actually uses pidfile(), and we
don't use it in Samba, so this works, although its ugly */
diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c
index 7d731ab13d..cadbe33af6 100644
--- a/source4/kdc/hdb-samba4.c
+++ b/source4/kdc/hdb-samba4.c
@@ -34,7 +34,7 @@
#include "includes.h"
#include "system/time.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#include "lib/ldb/include/ldb.h"
#include "lib/ldb/include/ldb_errors.h"
#include "librpc/gen_ndr/netlogon.h"
@@ -154,7 +154,7 @@ static HDBFlags uf2HDBFlags(krb5_context context, int userAccountControl, enum h
flags.invalid = 1;
}
-/* UF_DONT_EXPIRE_PASSWD and UF_USE_DES_KEY_ONLY handled in LDB_message2entry() */
+/* UF_DONT_EXPIRE_PASSWD and UF_USE_DES_KEY_ONLY handled in hdb_samba4_message2entry() */
/*
if (userAccountControl & UF_MNS_LOGON_ACCOUNT) {
@@ -193,7 +193,7 @@ static void hdb_ldb_free_entry(krb5_context context, hdb_entry_ex *entry_ex)
talloc_free(entry_ex->ctx);
}
-static krb5_error_code LDB_message2entry_keys(krb5_context context,
+static krb5_error_code hdb_samba4_message2entry_keys(krb5_context context,
struct smb_iconv_convenience *iconv_convenience,
TALLOC_CTX *mem_ctx,
struct ldb_message *msg,
@@ -283,22 +283,22 @@ static krb5_error_code LDB_message2entry_keys(krb5_context context,
(ndr_pull_flags_fn_t)ndr_pull_package_PrimaryKerberosBlob);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
ret = EINVAL;
- krb5_set_error_message(context, ret, "LDB_message2entry_keys: could not parse package_PrimaryKerberosBlob");
- krb5_warnx(context, "LDB_message2entry_keys: could not parse package_PrimaryKerberosBlob");
+ krb5_set_error_message(context, ret, "hdb_samba4_message2entry_keys: could not parse package_PrimaryKerberosBlob");
+ krb5_warnx(context, "hdb_samba4_message2entry_keys: could not parse package_PrimaryKerberosBlob");
goto out;
}
if (newer_keys && _pkb.version != 4) {
ret = EINVAL;
- krb5_set_error_message(context, ret, "LDB_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4");
- krb5_warnx(context, "LDB_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4");
+ krb5_set_error_message(context, ret, "hdb_samba4_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4");
+ krb5_warnx(context, "hdb_samba4_message2entry_keys: Primary:Kerberos-Newer-Keys not version 4");
goto out;
}
if (!newer_keys && _pkb.version != 3) {
ret = EINVAL;
- krb5_set_error_message(context, ret, "LDB_message2entry_keys: could not parse Primary:Kerberos not version 3");
- krb5_warnx(context, "LDB_message2entry_keys: could not parse Primary:Kerberos not version 3");
+ krb5_set_error_message(context, ret, "hdb_samba4_message2entry_keys: could not parse Primary:Kerberos not version 3");
+ krb5_warnx(context, "hdb_samba4_message2entry_keys: could not parse Primary:Kerberos not version 3");
goto out;
}
@@ -484,7 +484,7 @@ out:
/*
* Construct an hdb_entry from a directory entry.
*/
-static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
+static krb5_error_code hdb_samba4_message2entry(krb5_context context, HDB *db,
struct loadparm_context *lp_ctx,
TALLOC_CTX *mem_ctx, krb5_const_principal principal,
enum hdb_ldb_ent_type ent_type,
@@ -511,7 +511,7 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
if (!samAccountName) {
ret = ENOENT;
- krb5_set_error_message(context, ret, "LDB_message2entry: no samAccountName present");
+ krb5_set_error_message(context, ret, "hdb_samba4_message2entry: no samAccountName present");
goto out;
}
@@ -690,7 +690,7 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
entry_ex->entry.generation = NULL;
/* Get keys from the db */
- ret = LDB_message2entry_keys(context, p->iconv_convenience, p, msg, userAccountControl, entry_ex);
+ ret = hdb_samba4_message2entry_keys(context, p->iconv_convenience, p, msg, userAccountControl, entry_ex);
if (ret) {
/* Could be bougus data in the entry, or out of memory */
goto out;
@@ -731,7 +731,7 @@ out:
/*
* Construct an hdb_entry from a directory entry.
*/
-static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db,
+static krb5_error_code hdb_samba4_trust_message2entry(krb5_context context, HDB *db,
struct loadparm_context *lp_ctx,
TALLOC_CTX *mem_ctx, krb5_const_principal principal,
enum trust_direction direction,
@@ -909,7 +909,7 @@ out:
}
-static krb5_error_code LDB_lookup_trust(krb5_context context, struct ldb_context *ldb_ctx,
+static krb5_error_code hdb_samba4_lookup_trust(krb5_context context, struct ldb_context *ldb_ctx,
TALLOC_CTX *mem_ctx,
const char *realm,
struct ldb_dn *realm_dn,
@@ -946,39 +946,39 @@ static krb5_error_code LDB_lookup_trust(krb5_context context, struct ldb_context
return 0;
}
-static krb5_error_code LDB_open(krb5_context context, HDB *db, int flags, mode_t mode)
+static krb5_error_code hdb_samba4_open(krb5_context context, HDB *db, int flags, mode_t mode)
{
if (db->hdb_master_key_set) {
krb5_error_code ret = HDB_ERR_NOENTRY;
- krb5_warnx(context, "LDB_open: use of a master key incompatible with LDB\n");
- krb5_set_error_message(context, ret, "LDB_open: use of a master key incompatible with LDB\n");
+ krb5_warnx(context, "hdb_samba4_open: use of a master key incompatible with LDB\n");
+ krb5_set_error_message(context, ret, "hdb_samba4_open: use of a master key incompatible with LDB\n");
return ret;
}
return 0;
}
-static krb5_error_code LDB_close(krb5_context context, HDB *db)
+static krb5_error_code hdb_samba4_close(krb5_context context, HDB *db)
{
return 0;
}
-static krb5_error_code LDB_lock(krb5_context context, HDB *db, int operation)
+static krb5_error_code hdb_samba4_lock(krb5_context context, HDB *db, int operation)
{
return 0;
}
-static krb5_error_code LDB_unlock(krb5_context context, HDB *db)
+static krb5_error_code hdb_samba4_unlock(krb5_context context, HDB *db)
{
return 0;
}
-static krb5_error_code LDB_rename(krb5_context context, HDB *db, const char *new_name)
+static krb5_error_code hdb_samba4_rename(krb5_context context, HDB *db, const char *new_name)
{
return HDB_ERR_DB_INUSE;
}
-static krb5_error_code LDB_fetch_client(krb5_context context, HDB *db,
+static krb5_error_code hdb_samba4_fetch_client(krb5_context context, HDB *db,
struct loadparm_context *lp_ctx,
TALLOC_CTX *mem_ctx,
krb5_const_principal principal,
@@ -1008,13 +1008,13 @@ static krb5_error_code LDB_fetch_client(krb5_context context, HDB *db,
return EINVAL;
}
- ret = LDB_message2entry(context, db, lp_ctx, mem_ctx,
+ ret = hdb_samba4_message2entry(context, db, lp_ctx, mem_ctx,
principal, HDB_SAMBA4_ENT_TYPE_CLIENT,
realm_dn, msg, entry_ex);
return ret;
}
-static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
+static krb5_error_code hdb_samba4_fetch_krbtgt(krb5_context context, HDB *db,
struct loadparm_context *lp_ctx,
TALLOC_CTX *mem_ctx,
krb5_const_principal principal,
@@ -1044,19 +1044,18 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
int lret;
char *realm_fixed;
- const char * const *princ_attrs = user_attrs;
lret = gendb_search_single_extended_dn(db->hdb_db, mem_ctx,
realm_dn, LDB_SCOPE_SUBTREE,
- &msg, princ_attrs,
+ &msg, krbtgt_attrs,
"(&(objectClass=user)(samAccountName=krbtgt))");
if (lret == LDB_ERR_NO_SUCH_OBJECT) {
- krb5_warnx(context, "LDB_fetch: could not find own KRBTGT in DB!");
- krb5_set_error_message(context, HDB_ERR_NOENTRY, "LDB_fetch: could not find own KRBTGT in DB!");
+ krb5_warnx(context, "hdb_samba4_fetch: could not find own KRBTGT in DB!");
+ krb5_set_error_message(context, HDB_ERR_NOENTRY, "hdb_samba4_fetch: could not find own KRBTGT in DB!");
return HDB_ERR_NOENTRY;
} else if (lret != LDB_SUCCESS) {
- krb5_warnx(context, "LDB_fetch: could not find own KRBTGT in DB: %s", ldb_errstring(db->hdb_db));
- krb5_set_error_message(context, HDB_ERR_NOENTRY, "LDB_fetch: could not find own KRBTGT in DB: %s", ldb_errstring(db->hdb_db));
+ krb5_warnx(context, "hdb_samba4_fetch: could not find own KRBTGT in DB: %s", ldb_errstring(db->hdb_db));
+ krb5_set_error_message(context, HDB_ERR_NOENTRY, "hdb_samba4_fetch: could not find own KRBTGT in DB: %s", ldb_errstring(db->hdb_db));
return HDB_ERR_NOENTRY;
}
@@ -1077,16 +1076,16 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
talloc_free(realm_fixed);
if (!alloc_principal->name.name_string.val[1]) {
ret = ENOMEM;
- krb5_set_error_message(context, ret, "LDB_fetch: strdup() failed!");
+ krb5_set_error_message(context, ret, "hdb_samba4_fetch: strdup() failed!");
return ret;
}
principal = alloc_principal;
- ret = LDB_message2entry(context, db, lp_ctx, mem_ctx,
+ ret = hdb_samba4_message2entry(context, db, lp_ctx, mem_ctx,
principal, HDB_SAMBA4_ENT_TYPE_KRBTGT,
realm_dn, msg, entry_ex);
if (ret != 0) {
- krb5_warnx(context, "LDB_fetch: self krbtgt message2entry failed");
+ krb5_warnx(context, "hdb_samba4_fetch: self krbtgt message2entry failed");
}
return ret;
@@ -1109,21 +1108,21 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
/* Trusted domains are under CN=system */
- ret = LDB_lookup_trust(context, (struct ldb_context *)db->hdb_db,
+ ret = hdb_samba4_lookup_trust(context, (struct ldb_context *)db->hdb_db,
mem_ctx,
realm, realm_dn, &msg);
if (ret != 0) {
- krb5_warnx(context, "LDB_fetch: could not find principal in DB");
- krb5_set_error_message(context, ret, "LDB_fetch: could not find principal in DB");
+ krb5_warnx(context, "hdb_samba4_fetch: could not find principal in DB");
+ krb5_set_error_message(context, ret, "hdb_samba4_fetch: could not find principal in DB");
return ret;
}
- ret = LDB_trust_message2entry(context, db, lp_ctx, mem_ctx,
+ ret = hdb_samba4_trust_message2entry(context, db, lp_ctx, mem_ctx,
principal, direction,
realm_dn, msg, entry_ex);
if (ret != 0) {
- krb5_warnx(context, "LDB_fetch: trust_message2entry failed");
+ krb5_warnx(context, "hdb_samba4_fetch: trust_message2entry failed");
}
return ret;
@@ -1134,17 +1133,16 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
}
-static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
- struct loadparm_context *lp_ctx,
- TALLOC_CTX *mem_ctx,
- krb5_const_principal principal,
- unsigned flags,
- hdb_entry_ex *entry_ex)
+static krb5_error_code hdb_samba4_lookup_server(krb5_context context, HDB *db,
+ struct loadparm_context *lp_ctx,
+ TALLOC_CTX *mem_ctx,
+ krb5_const_principal principal,
+ const char **attrs,
+ struct ldb_dn **realm_dn,
+ struct ldb_message **msg)
{
krb5_error_code ret;
const char *realm;
- struct ldb_message *msg = NULL;
- struct ldb_dn *realm_dn;
if (principal->name.name_string.len >= 2) {
/* 'normal server' case */
int ldb_ret;
@@ -1164,7 +1162,7 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
* referral instead */
nt_status = crack_service_principal_name((struct ldb_context *)db->hdb_db,
mem_ctx, principal_string,
- &user_dn, &realm_dn);
+ &user_dn, realm_dn);
free(principal_string);
if (!NT_STATUS_IS_OK(nt_status)) {
@@ -1174,7 +1172,7 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
ldb_ret = gendb_search_single_extended_dn((struct ldb_context *)db->hdb_db,
mem_ctx,
user_dn, LDB_SCOPE_BASE,
- &msg, user_attrs,
+ msg, attrs,
"(objectClass=*)");
if (ldb_ret != LDB_SUCCESS) {
return HDB_ERR_NOENTRY;
@@ -1183,10 +1181,9 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
} else {
int lret;
char *filter = NULL;
- const char * const *princ_attrs = user_attrs;
char *short_princ;
/* server as client principal case, but we must not lookup userPrincipalNames */
- realm_dn = ldb_get_default_basedn(db->hdb_db);
+ *realm_dn = ldb_get_default_basedn(db->hdb_db);
realm = krb5_principal_get_realm(context, principal);
/* TODO: Check if it is our realm, otherwise give referall */
@@ -1194,14 +1191,14 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
ret = krb5_unparse_name_flags(context, principal, KRB5_PRINCIPAL_UNPARSE_NO_REALM, &short_princ);
if (ret != 0) {
- krb5_set_error_message(context, ret, "LDB_lookup_principal: could not parse principal");
- krb5_warnx(context, "LDB_lookup_principal: could not parse principal");
+ krb5_set_error_message(context, ret, "hdb_samba4_lookup_principal: could not parse principal");
+ krb5_warnx(context, "hdb_samba4_lookup_principal: could not parse principal");
return ret;
}
lret = gendb_search_single_extended_dn(db->hdb_db, mem_ctx,
- realm_dn, LDB_SCOPE_SUBTREE,
- &msg, princ_attrs, "(&(objectClass=user)(samAccountName=%s))",
+ *realm_dn, LDB_SCOPE_SUBTREE,
+ msg, attrs, "(&(objectClass=user)(samAccountName=%s))",
ldb_binary_encode_string(mem_ctx, short_princ));
free(short_princ);
if (lret == LDB_ERR_NO_SUCH_OBJECT) {
@@ -1215,46 +1212,66 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
}
}
- ret = LDB_message2entry(context, db, lp_ctx, mem_ctx,
+ return 0;
+}
+
+static krb5_error_code hdb_samba4_fetch_server(krb5_context context, HDB *db,
+ struct loadparm_context *lp_ctx,
+ TALLOC_CTX *mem_ctx,
+ krb5_const_principal principal,
+ unsigned flags,
+ hdb_entry_ex *entry_ex)
+{
+ krb5_error_code ret;
+ struct ldb_dn *realm_dn;
+ struct ldb_message *msg;
+
+ ret = hdb_samba4_lookup_server(context, db, lp_ctx, mem_ctx, principal,
+ server_attrs, &realm_dn, &msg);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = hdb_samba4_message2entry(context, db, lp_ctx, mem_ctx,
principal, HDB_SAMBA4_ENT_TYPE_SERVER,
realm_dn, msg, entry_ex);
if (ret != 0) {
- krb5_warnx(context, "LDB_fetch: message2entry failed");
+ krb5_warnx(context, "hdb_samba4_fetch: message2entry failed");
}
return ret;
}
-static krb5_error_code LDB_fetch(krb5_context context, HDB *db,
+static krb5_error_code hdb_samba4_fetch(krb5_context context, HDB *db,
krb5_const_principal principal,
unsigned flags,
hdb_entry_ex *entry_ex)
{
krb5_error_code ret = HDB_ERR_NOENTRY;
- TALLOC_CTX *mem_ctx = talloc_named(db, 0, "LDB_fetch context");
+ TALLOC_CTX *mem_ctx = talloc_named(db, 0, "hdb_samba4_fetch context");
struct loadparm_context *lp_ctx = talloc_get_type(ldb_get_opaque(db->hdb_db, "loadparm"), struct loadparm_context);
if (!mem_ctx) {
ret = ENOMEM;
- krb5_set_error_message(context, ret, "LDB_fetch: talloc_named() failed!");
+ krb5_set_error_message(context, ret, "hdb_samba4_fetch: talloc_named() failed!");
return ret;
}
if (flags & HDB_F_GET_CLIENT) {
- ret = LDB_fetch_client(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex);
+ ret = hdb_samba4_fetch_client(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex);
if (ret != HDB_ERR_NOENTRY) goto done;
}
if (flags & HDB_F_GET_SERVER) {
/* krbtgt fits into this situation for trusted realms, and for resolving different versions of our own realm name */
- ret = LDB_fetch_krbtgt(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex);
+ ret = hdb_samba4_fetch_krbtgt(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex);
if (ret != HDB_ERR_NOENTRY) goto done;
/* We return 'no entry' if it does not start with krbtgt/, so move to the common case quickly */
- ret = LDB_fetch_server(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex);
+ ret = hdb_samba4_fetch_server(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex);
if (ret != HDB_ERR_NOENTRY) goto done;
}
if (flags & HDB_F_GET_KRBTGT) {
- ret = LDB_fetch_krbtgt(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex);
+ ret = hdb_samba4_fetch_krbtgt(context, db, lp_ctx, mem_ctx, principal, flags, entry_ex);
if (ret != HDB_ERR_NOENTRY) goto done;
}
@@ -1263,12 +1280,12 @@ done:
return ret;
}
-static krb5_error_code LDB_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry)
+static krb5_error_code hdb_samba4_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry)
{
return HDB_ERR_DB_INUSE;
}
-static krb5_error_code LDB_remove(krb5_context context, HDB *db, krb5_const_principal principal)
+static krb5_error_code hdb_samba4_remove(krb5_context context, HDB *db, krb5_const_principal principal)
{
return HDB_ERR_DB_INUSE;
}
@@ -1282,7 +1299,7 @@ struct hdb_ldb_seq {
struct ldb_dn *realm_dn;
};
-static krb5_error_code LDB_seq(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry)
+static krb5_error_code hdb_samba4_seq(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry)
{
krb5_error_code ret;
struct hdb_ldb_seq *priv = (struct hdb_ldb_seq *)db->hdb_dbc;
@@ -1294,16 +1311,16 @@ static krb5_error_code LDB_seq(krb5_context context, HDB *db, unsigned flags, hd
return HDB_ERR_NOENTRY;
}
- mem_ctx = talloc_named(priv, 0, "LDB_seq context");
+ mem_ctx = talloc_named(priv, 0, "hdb_samba4_seq context");
if (!mem_ctx) {
ret = ENOMEM;
- krb5_set_error_message(context, ret, "LDB_seq: talloc_named() failed!");
+ krb5_set_error_message(context, ret, "hdb_samba4_seq: talloc_named() failed!");
return ret;
}
if (priv->index < priv->count) {
- ret = LDB_message2entry(context, db, priv->lp_ctx,
+ ret = hdb_samba4_message2entry(context, db, priv->lp_ctx,
mem_ctx,
NULL, HDB_SAMBA4_ENT_TYPE_ANY,
priv->realm_dn, priv->msgs[priv->index++], entry);
@@ -1321,7 +1338,7 @@ static krb5_error_code LDB_seq(krb5_context context, HDB *db, unsigned flags, hd
return ret;
}
-static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flags,
+static krb5_error_code hdb_samba4_firstkey(krb5_context context, HDB *db, unsigned flags,
hdb_entry_ex *entry)
{
struct ldb_context *ldb_ctx = (struct ldb_context *)db->hdb_db;
@@ -1353,11 +1370,11 @@ static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flag
priv->realm_dn = ldb_get_default_basedn(ldb_ctx);
priv->count = 0;
- mem_ctx = talloc_named(priv, 0, "LDB_firstkey context");
+ mem_ctx = talloc_named(priv, 0, "hdb_samba4_firstkey context");
if (!mem_ctx) {
ret = ENOMEM;
- krb5_set_error_message(context, ret, "LDB_firstkey: talloc_named() failed!");
+ krb5_set_error_message(context, ret, "hdb_samba4_firstkey: talloc_named() failed!");
return ret;
}
@@ -1382,7 +1399,7 @@ static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flag
db->hdb_dbc = priv;
- ret = LDB_seq(context, db, flags, entry);
+ ret = hdb_samba4_seq(context, db, flags, entry);
if (ret != 0) {
talloc_free(priv);
@@ -1393,18 +1410,87 @@ static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flag
return ret;
}
-static krb5_error_code LDB_nextkey(krb5_context context, HDB *db, unsigned flags,
+static krb5_error_code hdb_samba4_nextkey(krb5_context context, HDB *db, unsigned flags,
hdb_entry_ex *entry)
{
- return LDB_seq(context, db, flags, entry);
+ return hdb_samba4_seq(context, db, flags, entry);
}
-static krb5_error_code LDB_destroy(krb5_context context, HDB *db)
+static krb5_error_code hdb_samba4_destroy(krb5_context context, HDB *db)
{
talloc_free(db);
return 0;
}
+krb5_error_code hdb_samba4_check_constrained_delegation(krb5_context context, HDB *db,
+ hdb_entry_ex *entry,
+ krb5_const_principal target_principal)
+{
+ struct ldb_context *ldb_ctx = (struct ldb_context *)db->hdb_db;
+ struct loadparm_context *lp_ctx = talloc_get_type(ldb_get_opaque(ldb_ctx, "loadparm"),
+ struct loadparm_context);
+ krb5_error_code ret;
+ krb5_principal enterprise_prinicpal = NULL;
+ struct ldb_dn *realm_dn;
+ struct ldb_message *msg;
+ struct dom_sid *orig_sid;
+ struct dom_sid *target_sid;
+ struct hdb_ldb_private *p = talloc_get_type(entry->ctx, struct hdb_ldb_private);
+ const char *delegation_check_attrs[] = {
+ "objectSid", NULL
+ };
+
+ TALLOC_CTX *mem_ctx = talloc_named(db, 0, "hdb_samba4_check_constrained_delegation");
+
+ if (!mem_ctx) {
+ ret = ENOMEM;
+ krb5_set_error_message(context, ret, "hdb_samba4_fetch: talloc_named() failed!");
+ return ret;
+ }
+
+ if (target_principal->name.name_type == KRB5_NT_ENTERPRISE_PRINCIPAL) {
+ /* Need to reparse the enterprise principal to find the real target */
+ if (target_principal->name.name_string.len != 1) {
+ ret = KRB5_PARSE_MALFORMED;
+ krb5_set_error_message(context, ret, "hdb_samba4_check_constrained_delegation: request for delegation to enterprise principal with wrong (%d) number of components",
+ target_principal->name.name_string.len);
+ talloc_free(mem_ctx);
+ return ret;
+ }
+ ret = krb5_parse_name(context, target_principal->name.name_string.val[0],
+ &enterprise_prinicpal);
+ if (ret) {
+ talloc_free(mem_ctx);
+ return ret;
+ }
+ target_principal = enterprise_prinicpal;
+ }
+
+ ret = hdb_samba4_lookup_server(context, db, lp_ctx, mem_ctx, target_principal,
+ delegation_check_attrs, &realm_dn, &msg);
+
+ krb5_free_principal(context, enterprise_prinicpal);
+
+ if (ret != 0) {
+ talloc_free(mem_ctx);
+ return ret;
+ }
+
+ orig_sid = samdb_result_dom_sid(mem_ctx, p->msg, "objectSid");
+ target_sid = samdb_result_dom_sid(mem_ctx, msg, "objectSid");
+
+ /* Allow delegation to the same principal, even if by a different
+ * name. The easy and safe way to prove this is by SID
+ * comparison */
+ if (!(orig_sid && target_sid && dom_sid_equal(orig_sid, target_sid))) {
+ talloc_free(mem_ctx);
+ return KRB5KDC_ERR_BADOPTION;
+ }
+
+ talloc_free(mem_ctx);
+ return ret;
+}
+
/* This interface is to be called by the KDC, which is expecting Samba
* calling conventions. It is also called by a wrapper
* (hdb_ldb_create) from the kpasswdd -> krb5 -> keytab_hdb -> hdb
@@ -1451,22 +1537,25 @@ NTSTATUS kdc_hdb_samba4_create(TALLOC_CTX *mem_ctx,
}
(*db)->hdb_dbc = NULL;
- (*db)->hdb_open = LDB_open;
- (*db)->hdb_close = LDB_close;
- (*db)->hdb_fetch = LDB_fetch;
- (*db)->hdb_store = LDB_store;
- (*db)->hdb_remove = LDB_remove;
- (*db)->hdb_firstkey = LDB_firstkey;
- (*db)->hdb_nextkey = LDB_nextkey;
- (*db)->hdb_lock = LDB_lock;
- (*db)->hdb_unlock = LDB_unlock;
- (*db)->hdb_rename = LDB_rename;
+ (*db)->hdb_open = hdb_samba4_open;
+ (*db)->hdb_close = hdb_samba4_close;
+ (*db)->hdb_fetch = hdb_samba4_fetch;
+ (*db)->hdb_store = hdb_samba4_store;
+ (*db)->hdb_remove = hdb_samba4_remove;
+ (*db)->hdb_firstkey = hdb_samba4_firstkey;
+ (*db)->hdb_nextkey = hdb_samba4_nextkey;
+ (*db)->hdb_lock = hdb_samba4_lock;
+ (*db)->hdb_unlock = hdb_samba4_unlock;
+ (*db)->hdb_rename = hdb_samba4_rename;
/* we don't implement these, as we are not a lockable database */
(*db)->hdb__get = NULL;
(*db)->hdb__put = NULL;
/* kadmin should not be used for deletes - use other tools instead */
(*db)->hdb__del = NULL;
- (*db)->hdb_destroy = LDB_destroy;
+ (*db)->hdb_destroy = hdb_samba4_destroy;
+
+ (*db)->hdb_auth_status = NULL;
+ (*db)->hdb_check_constrained_delegation = hdb_samba4_check_constrained_delegation;
return NT_STATUS_OK;
}
diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c
index 5bd4cb10c7..21ae7091a6 100644
--- a/source4/kdc/pac-glue.c
+++ b/source4/kdc/pac-glue.c
@@ -21,7 +21,7 @@
*/
#include "includes.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#include "lib/ldb/include/ldb.h"
#include "librpc/gen_ndr/ndr_krb5pac.h"
#include "librpc/gen_ndr/krb5pac.h"
diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c
index 64ad6832db..164e5a95a0 100644
--- a/source4/lib/ldb/common/ldb.c
+++ b/source4/lib/ldb/common/ldb.c
@@ -240,7 +240,7 @@ int ldb_connect(struct ldb_context *ldb, const char *url,
if (ldb_load_modules(ldb, options) != LDB_SUCCESS) {
ldb_debug(ldb, LDB_DEBUG_FATAL,
- "Unable to load modules for %s: %s\n",
+ "Unable to load modules for %s: %s",
url, ldb_errstring(ldb));
return LDB_ERR_OTHER;
}
diff --git a/source4/lib/ldb/common/ldb_debug.c b/source4/lib/ldb/common/ldb_debug.c
index f8009eb8a3..7680862c2c 100644
--- a/source4/lib/ldb/common/ldb_debug.c
+++ b/source4/lib/ldb/common/ldb_debug.c
@@ -56,6 +56,7 @@ static void ldb_debug_stderr(void *context, enum ldb_debug_level level,
{
if (level <= LDB_DEBUG_WARNING) {
vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
}
}
diff --git a/source4/lib/ldb/common/ldb_ldif.c b/source4/lib/ldb/common/ldb_ldif.c
index d64a9f1c3a..d890ff8300 100644
--- a/source4/lib/ldb/common/ldb_ldif.c
+++ b/source4/lib/ldb/common/ldb_ldif.c
@@ -296,7 +296,7 @@ int ldb_ldif_write(struct ldb_context *ldb,
}
}
if (!ldb_changetypes[i].name) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Invalid ldif changetype %d\n",
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Invalid ldif changetype %d",
ldif->changetype);
talloc_free(mem_ctx);
return -1;
@@ -561,7 +561,7 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
/* first line must be a dn */
if (ldb_attr_cmp(attr, "dn") != 0) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: First line of ldif must be a dn not '%s'\n",
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: First line of ldif must be a dn not '%s'",
attr);
goto failed;
}
@@ -569,7 +569,7 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
msg->dn = ldb_dn_from_ldb_val(msg, ldb, &value);
if ( ! ldb_dn_validate(msg->dn)) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Unable to parse dn '%s'\n",
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Unable to parse dn '%s'",
(char *)value.data);
goto failed;
}
@@ -588,8 +588,8 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
}
}
if (!ldb_changetypes[i].name) {
- ldb_debug(ldb, LDB_DEBUG_ERROR,
- "Error: Bad ldif changetype '%s'\n",(char *)value.data);
+ ldb_debug(ldb, LDB_DEBUG_ERROR,
+ "Error: Bad ldif changetype '%s'",(char *)value.data);
}
flags = 0;
continue;
@@ -638,7 +638,7 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
}
if (value.length == 0) {
ldb_debug(ldb, LDB_DEBUG_ERROR,
- "Error: Attribute value cannot be empty for attribute '%s'\n", el->name);
+ "Error: Attribute value cannot be empty for attribute '%s'", el->name);
goto failed;
}
if (value.data != el->values[el->num_values].data) {
diff --git a/source4/lib/ldb/common/ldb_match.c b/source4/lib/ldb/common/ldb_match.c
index c622701d30..e6ee0de027 100644
--- a/source4/lib/ldb/common/ldb_match.c
+++ b/source4/lib/ldb/common/ldb_match.c
@@ -335,7 +335,7 @@ static int ldb_match_extended(struct ldb_context *ldb,
}
}
if (comp == NULL) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: unknown extended rule_id %s\n",
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: unknown extended rule_id %s",
tree->u.extended.rule_id);
return -1;
}
diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c
index ae97ef4cce..05dffd005a 100644
--- a/source4/lib/ldb/common/ldb_modules.c
+++ b/source4/lib/ldb/common/ldb_modules.c
@@ -84,13 +84,13 @@ const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *m
/* spaces not admitted */
modstr = ldb_modules_strdup_no_spaces(mem_ctx, string);
if ( ! modstr) {
- ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_strdup_no_spaces()\n");
+ ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_strdup_no_spaces()");
return NULL;
}
modules = talloc_realloc(mem_ctx, modules, char *, 2);
if ( ! modules ) {
- ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()\n");
+ ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()");
talloc_free(modstr);
return NULL;
}
@@ -106,7 +106,7 @@ const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *m
i++;
modules = talloc_realloc(mem_ctx, modules, char *, i + 2);
if ( ! modules ) {
- ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()\n");
+ ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()");
return NULL;
}
@@ -239,7 +239,7 @@ int ldb_connect_backend(struct ldb_context *ldb,
if (fn == NULL) {
ldb_debug(ldb, LDB_DEBUG_FATAL,
- "Unable to find backend for '%s'\n", url);
+ "Unable to find backend for '%s'", url);
return LDB_ERR_OTHER;
}
@@ -247,7 +247,7 @@ int ldb_connect_backend(struct ldb_context *ldb,
if (ret != LDB_SUCCESS) {
ldb_debug(ldb, LDB_DEBUG_ERROR,
- "Failed to connect to '%s'\n", url);
+ "Failed to connect to '%s'", url);
return ret;
}
return ret;
@@ -304,18 +304,18 @@ static void *ldb_dso_load_symbol(struct ldb_context *ldb, const char *name,
path = talloc_asprintf(ldb, "%s/%s.%s", ldb->modules_dir, name,
SHLIBEXT);
- ldb_debug(ldb, LDB_DEBUG_TRACE, "trying to load %s from %s\n", name, path);
+ ldb_debug(ldb, LDB_DEBUG_TRACE, "trying to load %s from %s", name, path);
handle = dlopen(path, RTLD_NOW);
if (handle == NULL) {
- ldb_debug(ldb, LDB_DEBUG_WARNING, "unable to load %s from %s: %s\n", name, path, dlerror());
+ ldb_debug(ldb, LDB_DEBUG_WARNING, "unable to load %s from %s: %s", name, path, dlerror());
return NULL;
}
sym = (int (*)(void))dlsym(handle, symbol);
if (sym == NULL) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "no symbol `%s' found in %s: %s\n", symbol, path, dlerror());
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "no symbol `%s' found in %s: %s", symbol, path, dlerror());
return NULL;
}
@@ -351,7 +351,7 @@ int ldb_load_modules_list(struct ldb_context *ldb, const char **module_list, str
}
if (ops == NULL) {
- ldb_debug(ldb, LDB_DEBUG_WARNING, "WARNING: Module [%s] not found\n",
+ ldb_debug(ldb, LDB_DEBUG_WARNING, "WARNING: Module [%s] not found",
module_list[i]);
continue;
}
@@ -382,7 +382,7 @@ int ldb_init_module_chain(struct ldb_context *ldb, struct ldb_module *module)
if (module) {
int ret = module->ops->init_context(module);
if (ret != LDB_SUCCESS) {
- ldb_debug(ldb, LDB_DEBUG_FATAL, "module %s initialization failed\n", module->ops->name);
+ ldb_debug(ldb, LDB_DEBUG_FATAL, "module %s initialization failed", module->ops->name);
return ret;
}
}
@@ -428,7 +428,7 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[])
if (ret == LDB_ERR_NO_SUCH_OBJECT) {
ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db");
} else if (ret != LDB_SUCCESS) {
- ldb_debug(ldb, LDB_DEBUG_FATAL, "ldb error (%s) occurred searching for modules, bailing out\n", ldb_errstring(ldb));
+ ldb_debug(ldb, LDB_DEBUG_FATAL, "ldb error (%s) occurred searching for modules, bailing out", ldb_errstring(ldb));
talloc_free(mem_ctx);
return ret;
} else {
@@ -436,7 +436,7 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[])
if (res->count == 0) {
ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db");
} else if (res->count > 1) {
- ldb_debug(ldb, LDB_DEBUG_FATAL, "Too many records found (%d), bailing out\n", res->count);
+ ldb_debug(ldb, LDB_DEBUG_FATAL, "Too many records found (%d), bailing out", res->count);
talloc_free(mem_ctx);
return -1;
} else {
diff --git a/source4/lib/ldb/ldb.mk b/source4/lib/ldb/ldb.mk
index a9a6dad46d..4234fcc311 100644
--- a/source4/lib/ldb/ldb.mk
+++ b/source4/lib/ldb/ldb.mk
@@ -67,11 +67,8 @@ build-python:: ldb.$(SHLIBEXT)
pyldb.o: $(ldbdir)/pyldb.c
$(CC) $(PICFLAG) -c $(ldbdir)/pyldb.c $(CFLAGS) `$(PYTHON_CONFIG) --cflags`
-pyldb_util.o: $(ldbdir)/pyldb_util.c
- $(CC) $(PICFLAG) -c $(ldbdir)/pyldb_util.c $(CFLAGS) `$(PYTHON_CONFIG) --cflags`
-
-ldb.$(SHLIBEXT): pyldb.o pyldb_util.o
- $(SHLD) $(SHLD_FLAGS) -o ldb.$(SHLIBEXT) pyldb.o pyldb_util.o $(LIB_FLAGS) `$(PYTHON_CONFIG) --ldflags`
+ldb.$(SHLIBEXT): pyldb.o
+ $(SHLD) $(SHLD_FLAGS) -o ldb.$(SHLIBEXT) pyldb.o $(LIB_FLAGS) `$(PYTHON_CONFIG) --ldflags`
install-python:: build-python
mkdir -p $(DESTDIR)`$(PYTHON) -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1, prefix='$(prefix)')"`
diff --git a/source4/lib/ldb/ldb.pc.in b/source4/lib/ldb/ldb.pc.in
index b7e4c85844..01482f6bfb 100644
--- a/source4/lib/ldb/ldb.pc.in
+++ b/source4/lib/ldb/ldb.pc.in
@@ -2,7 +2,7 @@ prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
-modulesdir=@modulesdir@
+modulesdir=@LDB_MODULESDIR@
Name: ldb
Description: An LDAP-like embedded database
diff --git a/source4/lib/ldb/ldb_ildap/ldb_ildap.c b/source4/lib/ldb/ldb_ildap/ldb_ildap.c
index 4447d0e09a..ffde048223 100644
--- a/source4/lib/ldb/ldb_ildap/ldb_ildap.c
+++ b/source4/lib/ldb/ldb_ildap/ldb_ildap.c
@@ -790,7 +790,7 @@ static int ildb_connect(struct ldb_context *ldb, const char *url,
status = ldap_connect(ildb->ldap, url);
if (!NT_STATUS_IS_OK(status)) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to ldap URL '%s' - %s\n",
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to ldap URL '%s' - %s",
url, ldap_errstr(ildb->ldap, module, status));
goto failed;
}
@@ -810,14 +810,14 @@ static int ildb_connect(struct ldb_context *ldb, const char *url,
const char *password = cli_credentials_get_password(creds);
status = ldap_bind_simple(ildb->ldap, bind_dn, password);
if (!NT_STATUS_IS_OK(status)) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s\n",
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s",
ldap_errstr(ildb->ldap, module, status));
goto failed;
}
} else {
status = ldap_bind_sasl(ildb->ldap, creds, lp_ctx);
if (!NT_STATUS_IS_OK(status)) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s\n",
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s",
ldap_errstr(ildb->ldap, module, status));
goto failed;
}
diff --git a/source4/lib/ldb/ldb_ldap/ldb_ldap.c b/source4/lib/ldb/ldb_ldap/ldb_ldap.c
index 43a01f75a7..52c16101bb 100644
--- a/source4/lib/ldb/ldb_ldap/ldb_ldap.c
+++ b/source4/lib/ldb/ldb_ldap/ldb_ldap.c
@@ -219,7 +219,7 @@ static int lldb_search(struct lldb_context *lldb_ac)
}
if (req->controls != NULL) {
- ldb_debug(ldb, LDB_DEBUG_WARNING, "Controls are not yet supported by ldb_ldap backend!\n");
+ ldb_debug(ldb, LDB_DEBUG_WARNING, "Controls are not yet supported by ldb_ldap backend!");
}
ldb_request_set_state(req, LDB_ASYNC_PENDING);
@@ -871,7 +871,7 @@ static int lldb_connect(struct ldb_context *ldb,
ret = ldap_initialize(&lldb->ldap, url);
if (ret != LDAP_SUCCESS) {
- ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_initialize failed for URL '%s' - %s\n",
+ ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_initialize failed for URL '%s' - %s",
url, ldap_err2string(ret));
goto failed;
}
@@ -880,7 +880,7 @@ static int lldb_connect(struct ldb_context *ldb,
ret = ldap_set_option(lldb->ldap, LDAP_OPT_PROTOCOL_VERSION, &version);
if (ret != LDAP_SUCCESS) {
- ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_set_option failed - %s\n",
+ ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_set_option failed - %s",
ldap_err2string(ret));
goto failed;
}
diff --git a/source4/lib/ldb/ldb_map/ldb_map.c b/source4/lib/ldb/ldb_map/ldb_map.c
index 5b4ea7910a..68e9d3f392 100644
--- a/source4/lib/ldb/ldb_map/ldb_map.c
+++ b/source4/lib/ldb/ldb_map/ldb_map.c
@@ -242,7 +242,7 @@ int ldb_next_remote_request(struct ldb_module *module, struct ldb_request *reque
default:
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
- "Invalid remote request!\n");
+ "Invalid remote request!");
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -503,14 +503,14 @@ struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, struct
case MAP_GENERATE:
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
"MAP_IGNORE/MAP_GENERATE attribute '%s' "
- "used in DN!\n", ldb_dn_get_component_name(dn, i));
+ "used in DN!", ldb_dn_get_component_name(dn, i));
goto failed;
case MAP_CONVERT:
if (map->u.convert.convert_local == NULL) {
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
"'convert_local' not set for attribute '%s' "
- "used in DN!\n", ldb_dn_get_component_name(dn, i));
+ "used in DN!", ldb_dn_get_component_name(dn, i));
goto failed;
}
/* fall through */
@@ -578,14 +578,14 @@ struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, struc
case MAP_GENERATE:
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
"MAP_IGNORE/MAP_GENERATE attribute '%s' "
- "used in DN!\n", ldb_dn_get_component_name(dn, i));
+ "used in DN!", ldb_dn_get_component_name(dn, i));
goto failed;
case MAP_CONVERT:
if (map->u.convert.convert_remote == NULL) {
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
"'convert_remote' not set for attribute '%s' "
- "used in DN!\n", ldb_dn_get_component_name(dn, i));
+ "used in DN!", ldb_dn_get_component_name(dn, i));
goto failed;
}
/* fall through */
@@ -1007,7 +1007,7 @@ static int map_init_dns(struct ldb_module *module, struct ldb_map_context *data,
dn = ldb_dn_new_fmt(data, ldb, "%s=%s", MAP_DN_NAME, name);
if ( ! ldb_dn_validate(dn)) {
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
- "Failed to construct '%s' DN!\n", MAP_DN_NAME);
+ "Failed to construct '%s' DN!", MAP_DN_NAME);
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -1018,13 +1018,13 @@ static int map_init_dns(struct ldb_module *module, struct ldb_map_context *data,
}
if (res->count == 0) {
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
- "No results for '%s=%s'!\n", MAP_DN_NAME, name);
+ "No results for '%s=%s'!", MAP_DN_NAME, name);
talloc_free(res);
return LDB_ERR_CONSTRAINT_VIOLATION;
}
if (res->count > 1) {
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
- "Too many results for '%s=%s'!\n", MAP_DN_NAME, name);
+ "Too many results for '%s=%s'!", MAP_DN_NAME, name);
talloc_free(res);
return LDB_ERR_CONSTRAINT_VIOLATION;
}
diff --git a/source4/lib/ldb/ldb_map/ldb_map_inbound.c b/source4/lib/ldb/ldb_map/ldb_map_inbound.c
index 455740ce59..89037419fb 100644
--- a/source4/lib/ldb/ldb_map/ldb_map_inbound.c
+++ b/source4/lib/ldb/ldb_map/ldb_map_inbound.c
@@ -73,7 +73,7 @@ static int ldb_msg_el_partition(struct ldb_module *module, struct ldb_message *l
/* Unknown attribute: ignore */
if (map == NULL) {
ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: "
- "Not mapping attribute '%s': no mapping found\n",
+ "Not mapping attribute '%s': no mapping found",
old->name);
goto local;
}
@@ -86,7 +86,7 @@ static int ldb_msg_el_partition(struct ldb_module *module, struct ldb_message *l
if (map->u.convert.convert_local == NULL) {
ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: "
"Not mapping attribute '%s': "
- "'convert_local' not set\n",
+ "'convert_local' not set",
map->local_name);
goto local;
}
@@ -100,7 +100,7 @@ static int ldb_msg_el_partition(struct ldb_module *module, struct ldb_message *l
if (map->u.generate.generate_remote == NULL) {
ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: "
"Not mapping attribute '%s': "
- "'generate_remote' not set\n",
+ "'generate_remote' not set",
map->local_name);
goto local;
}
@@ -167,7 +167,7 @@ static int ldb_msg_partition(struct ldb_module *module, struct ldb_message *loca
/* Skip 'IS_MAPPED' */
if (ldb_attr_cmp(msg->elements[i].name, IS_MAPPED) == 0) {
ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: "
- "Skipping attribute '%s'\n",
+ "Skipping attribute '%s'",
msg->elements[i].name);
continue;
}
diff --git a/source4/lib/ldb/ldb_map/ldb_map_outbound.c b/source4/lib/ldb/ldb_map/ldb_map_outbound.c
index ffcefad6be..4487d7e763 100644
--- a/source4/lib/ldb/ldb_map/ldb_map_outbound.c
+++ b/source4/lib/ldb/ldb_map/ldb_map_outbound.c
@@ -304,7 +304,7 @@ static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local
if (map->u.convert.convert_remote == NULL) {
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
"Skipping attribute '%s': "
- "'convert_remote' not set\n",
+ "'convert_remote' not set",
attr_name);
return LDB_SUCCESS;
}
@@ -323,7 +323,7 @@ static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local
if (map->u.generate.generate_local == NULL) {
ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: "
"Skipping attribute '%s': "
- "'generate_local' not set\n",
+ "'generate_local' not set",
attr_name);
return LDB_SUCCESS;
}
@@ -900,7 +900,7 @@ static int map_subtree_collect_remote(struct ldb_module *module, void *mem_ctx,
if (map->type == MAP_GENERATE) {
ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: "
"Skipping attribute '%s': "
- "'convert_operator' not set\n",
+ "'convert_operator' not set",
tree->u.equality.attr);
*new = NULL;
return 0;
@@ -1062,7 +1062,7 @@ int map_return_entry(struct map_context *ac, struct ldb_reply *ares)
ac->req->op.search.scope)) {
ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_map: "
"Skipping record '%s': "
- "doesn't match original search\n",
+ "doesn't match original search",
ldb_dn_get_linearized(ares->message->dn));
return LDB_SUCCESS;
}
diff --git a/source4/lib/ldb/ldb_tdb/ldb_cache.c b/source4/lib/ldb/ldb_tdb/ldb_cache.c
index 042c1c9282..2c399686ea 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_cache.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_cache.c
@@ -141,7 +141,7 @@ static int ltdb_attributes_load(struct ldb_module *module)
const struct ldb_schema_syntax *s;
if (ltdb_attributes_flags(&msg->elements[i], &flags) != 0) {
- ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid @ATTRIBUTES element for '%s'\n", msg->elements[i].name);
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid @ATTRIBUTES element for '%s'", msg->elements[i].name);
goto failed;
}
switch (flags & ~LTDB_FLAG_HIDDEN) {
@@ -156,7 +156,7 @@ static int ltdb_attributes_load(struct ldb_module *module)
break;
default:
ldb_debug(ldb, LDB_DEBUG_ERROR,
- "Invalid flag combination 0x%x for '%s' in @ATTRIBUTES\n",
+ "Invalid flag combination 0x%x for '%s' in @ATTRIBUTES",
flags, msg->elements[i].name);
goto failed;
}
@@ -164,7 +164,7 @@ static int ltdb_attributes_load(struct ldb_module *module)
s = ldb_standard_syntax_by_name(ldb, syntax);
if (s == NULL) {
ldb_debug(ldb, LDB_DEBUG_ERROR,
- "Invalid attribute syntax '%s' for '%s' in @ATTRIBUTES\n",
+ "Invalid attribute syntax '%s' for '%s' in @ATTRIBUTES",
syntax, msg->elements[i].name);
goto failed;
}
diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c
index fab60cb125..1daa4500f8 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_index.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_index.c
@@ -1409,7 +1409,7 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn,
struct ldb_ldif ldif;
ldb_debug(ldb, LDB_DEBUG_ERROR,
- "ERROR: dn %s not found in %s\n", dn,
+ "ERROR: dn %s not found in %s", dn,
ldb_dn_get_linearized(dn_key));
ldif.changetype = LDB_CHANGETYPE_NONE;
ldif.msg = msg;
@@ -1587,7 +1587,7 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *
key2 = ltdb_key(module, msg->dn);
if (key2.dptr == NULL) {
/* probably a corrupt record ... darn */
- ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid DN in re_index: %s\n",
+ ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid DN in re_index: %s",
ldb_dn_get_linearized(msg->dn));
talloc_free(msg);
return 0;
@@ -1609,7 +1609,7 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *
ret = ltdb_index_add0(module, dn, msg->elements, msg->num_elements);
} else {
ldb_debug(ldb, LDB_DEBUG_ERROR,
- "Adding special ONE LEVEL index failed (%s)!\n",
+ "Adding special ONE LEVEL index failed (%s)!",
ldb_dn_get_linearized(msg->dn));
}
diff --git a/source4/lib/ldb/ldb_tdb/ldb_pack.c b/source4/lib/ldb/ldb_tdb/ldb_pack.c
index 1995606f88..5640e7053c 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_pack.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_pack.c
@@ -280,7 +280,7 @@ int ltdb_unpack_data(struct ldb_module *module,
if (remaining != 0) {
ldb_debug(ldb, LDB_DEBUG_ERROR,
- "Error: %d bytes unread in ltdb_unpack_data\n", remaining);
+ "Error: %d bytes unread in ltdb_unpack_data", remaining);
}
return 0;
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
index 4a452761b8..d4f7b452cb 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
@@ -1276,7 +1276,7 @@ static int ltdb_connect(struct ldb_context *ldb, const char *url,
ldb_get_create_perms(ldb), ldb);
if (!ltdb->tdb) {
ldb_debug(ldb, LDB_DEBUG_ERROR,
- "Unable to open tdb '%s'\n", path);
+ "Unable to open tdb '%s'", path);
talloc_free(ltdb);
return -1;
}
diff --git a/source4/lib/ldb/modules/asq.c b/source4/lib/ldb/modules/asq.c
index dd5afd868c..271cf52625 100644
--- a/source4/lib/ldb/modules/asq.c
+++ b/source4/lib/ldb/modules/asq.c
@@ -393,7 +393,7 @@ static int asq_init(struct ldb_module *module)
ret = ldb_mod_register_control(module, LDB_CONTROL_ASQ_OID);
if (ret != LDB_SUCCESS) {
- ldb_debug(ldb, LDB_DEBUG_WARNING, "asq: Unable to register control with rootdse!\n");
+ ldb_debug(ldb, LDB_DEBUG_WARNING, "asq: Unable to register control with rootdse!");
}
return ldb_next_init(module);
diff --git a/source4/lib/ldb/modules/operational.c b/source4/lib/ldb/modules/operational.c
index 43b223b52e..77b0014afa 100644
--- a/source4/lib/ldb/modules/operational.c
+++ b/source4/lib/ldb/modules/operational.c
@@ -169,8 +169,8 @@ static int operational_search_post_process(struct ldb_module *module,
return 0;
failed:
- ldb_debug_set(ldb, LDB_DEBUG_WARNING,
- "operational_search_post_process failed for attribute '%s'\n",
+ ldb_debug_set(ldb, LDB_DEBUG_WARNING,
+ "operational_search_post_process failed for attribute '%s'",
attrs[a]);
return -1;
}
diff --git a/source4/lib/ldb/modules/paged_results.c b/source4/lib/ldb/modules/paged_results.c
index f2692305d5..b712f84872 100644
--- a/source4/lib/ldb/modules/paged_results.c
+++ b/source4/lib/ldb/modules/paged_results.c
@@ -409,7 +409,7 @@ static int paged_request_init(struct ldb_module *module)
if (ret != LDB_SUCCESS) {
ldb_debug(ldb, LDB_DEBUG_WARNING,
"paged_results:"
- "Unable to register control with rootdse!\n");
+ "Unable to register control with rootdse!");
}
return ldb_next_init(module);
diff --git a/source4/lib/ldb/modules/rdn_name.c b/source4/lib/ldb/modules/rdn_name.c
index 880678d89d..e9f873f073 100644
--- a/source4/lib/ldb/modules/rdn_name.c
+++ b/source4/lib/ldb/modules/rdn_name.c
@@ -98,7 +98,7 @@ static int rdn_name_add(struct ldb_module *module, struct ldb_request *req)
int i, ret;
ldb = ldb_module_get_ctx(module);
- ldb_debug(ldb, LDB_DEBUG_TRACE, "rdn_name_add_record\n");
+ ldb_debug(ldb, LDB_DEBUG_TRACE, "rdn_name_add_record");
/* do not manipulate our control entries */
if (ldb_dn_is_special(req->op.add.message->dn)) {
@@ -288,7 +288,7 @@ static int rdn_name_rename(struct ldb_module *module, struct ldb_request *req)
int ret;
ldb = ldb_module_get_ctx(module);
- ldb_debug(ldb, LDB_DEBUG_TRACE, "rdn_name_rename\n");
+ ldb_debug(ldb, LDB_DEBUG_TRACE, "rdn_name_rename");
/* do not manipulate our control entries */
if (ldb_dn_is_special(req->op.rename.newdn)) {
diff --git a/source4/lib/ldb/modules/sort.c b/source4/lib/ldb/modules/sort.c
index a95a86140c..b4ea017b32 100644
--- a/source4/lib/ldb/modules/sort.c
+++ b/source4/lib/ldb/modules/sort.c
@@ -339,7 +339,7 @@ static int server_sort_init(struct ldb_module *module)
if (ret != LDB_SUCCESS) {
ldb_debug(ldb, LDB_DEBUG_WARNING,
"server_sort:"
- "Unable to register control with rootdse!\n");
+ "Unable to register control with rootdse!");
}
return ldb_next_init(module);
diff --git a/source4/lib/ldb/pyldb.c b/source4/lib/ldb/pyldb.c
index 2e0f4fdf36..bcca70eb82 100644
--- a/source4/lib/ldb/pyldb.c
+++ b/source4/lib/ldb/pyldb.c
@@ -41,6 +41,16 @@ typedef intargfunc ssizeargfunc;
#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
#endif
+static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
+{
+ if (ret == LDB_ERR_PYTHON_EXCEPTION)
+ return; /* Python exception should already be set, just keep that */
+
+ PyErr_SetObject(error,
+ Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
+ ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
+}
+
static PyObject *PyExc_LdbError;
PyAPI_DATA(PyTypeObject) PyLdbMessage;
diff --git a/source4/lib/ldb/pyldb.h b/source4/lib/ldb/pyldb.h
index e0e0d2af69..a0954158bd 100644
--- a/source4/lib/ldb/pyldb.h
+++ b/source4/lib/ldb/pyldb.h
@@ -85,7 +85,6 @@ typedef struct {
PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *);
#define PyLdbTree_AsTree(pyobj) ((PyLdbTreeObject *)pyobj)->tree
-void PyErr_SetLdbError(PyObject *exctype, int ret, struct ldb_context *ldb_ctx);
#define PyErr_LDB_ERROR_IS_ERR_RAISE(err,ret,ldb) \
if (ret != LDB_SUCCESS) { \
PyErr_SetLdbError(err, ret, ldb); \
diff --git a/source4/lib/ldb/pyldb_util.c b/source4/lib/ldb/pyldb_util.c
deleted file mode 100644
index 84183e89de..0000000000
--- a/source4/lib/ldb/pyldb_util.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- interface to ldb.
-
- Copyright (C) 2009 Jelmer Vernooij <jelmer@samba.org>
-
- ** NOTE! The following LGPL license applies to the ldb
- ** library. This does NOT imply that all of Samba is released
- ** under the LGPL
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "replace.h"
-#include <Python.h>
-#include "pyldb.h"
-#include <ldb.h>
-
-void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
-{
- if (ret == LDB_ERR_PYTHON_EXCEPTION)
- return; /* Python exception should already be set, just keep that */
-
- PyErr_SetObject(error,
- Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
- ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
-}
diff --git a/source4/lib/ldb/python.mk b/source4/lib/ldb/python.mk
index e08c150aaf..dbc2eb27eb 100644
--- a/source4/lib/ldb/python.mk
+++ b/source4/lib/ldb/python.mk
@@ -1,14 +1,6 @@
[PYTHON::pyldb]
LIBRARY_REALNAME = ldb.$(SHLIBEXT)
PUBLIC_DEPENDENCIES = LIBLDB PYTALLOC
-PRIVATE_DEPENDENCIES = pyldb_util
pyldb_OBJ_FILES = $(ldbsrcdir)/pyldb.o
$(pyldb_OBJ_FILES): CFLAGS+=-I$(ldbsrcdir)/include
-
-[SUBSYSTEM::pyldb_util]
-PUBLIC_DEPENDENCIES = LIBPYTHON
-PRIVATE_DEPENDENCIES = LIBLDB
-
-pyldb_util_OBJ_FILES = $(ldbsrcdir)/pyldb_util.o
-$(pyldb_OBJ_FILES): CFLAGS+=-I$(ldbsrcdir)/include
diff --git a/source4/lib/ldb/rules.mk b/source4/lib/ldb/rules.mk
index 639271b76d..0598f8039b 100644
--- a/source4/lib/ldb/rules.mk
+++ b/source4/lib/ldb/rules.mk
@@ -19,6 +19,7 @@ ctags:
showflags::
@echo 'ldb will be compiled with flags:'
@echo ' CFLAGS = $(CFLAGS)'
+ @echo ' SHLD_FLAGS = $(SHLD_FLAGS)'
@echo ' LIBS = $(LIBS)'
distclean::
diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c
index 925806985e..24d86abf48 100644
--- a/source4/lib/registry/patchfile.c
+++ b/source4/lib/registry/patchfile.c
@@ -316,6 +316,7 @@ _PUBLIC_ WERROR reg_diff_load(const char *filename,
if (read(fd, &hdr, 4) != 4) {
DEBUG(0, ("Error reading registry patch file `%s'\n",
filename));
+ close(fd);
return WERR_GENERAL_FAILURE;
}
diff --git a/source4/lib/samba3/README b/source4/lib/samba3/README
index 83520f673d..3f6553f7e8 100644
--- a/source4/lib/samba3/README
+++ b/source4/lib/samba3/README
@@ -3,6 +3,3 @@ Samba3 import, migration and compatibility.
For example, the first file in this directory (smbpasswd.c) handles
portions of the smbpasswd file format.
-
-The other files in this directory support reading the various
-TDB databases from Samba3.
diff --git a/source4/lib/samba3/STATUS b/source4/lib/samba3/STATUS
deleted file mode 100644
index e4644526df..0000000000
--- a/source4/lib/samba3/STATUS
+++ /dev/null
@@ -1,68 +0,0 @@
---- Samba3 -> Samba4 Upgrade ---
-(C) 2005 Jelmer Vernooij <jelmer@samba.org>
-Published under the GNU GPL
-
-Sponsored by the Google Summer of Code program (http://code.google.com/summerofcode.html)
-Mentored by Andrew Bartlett <abartlet@samba.org>
-Thanks!
-
-Done:
- - Reading wins.dat
- - Reading registry.tdb
- - Reading passdb.tdb
- - Reading account_policy.tdb
- - Reading group_mappings.tdb
- - Reading winbindd_idmap.tdb
- - Reading share_info.tdb
- - Reading secrets.tdb
- - Reading smbpasswd
- - Reading + writing (generic) smb.conf files
- - Testsuite for read support mentioned above
- - Console utility for dumping Samba information
- - Import user accounts in Samba4
- - Import groups in Samba4
- - Import secrets in Samba4
- - Import WINS data in Samba4
- - Dump idmap data to LDB
- - Import registry keys/values in Samba4
- - Import account policies in Samba4
- - Testsuite for upgrade
- - Console utility from upgrading from Samba3 -> Samba4
- - SWAT (Web interface) support for upgrading from Samba3 -> Samba4
- - LDB generic mapping module
- - (Experimental) Samba4 LDB <-> Samba3 LDAP mapping module based on LDB generic mapping module
- - Testsuite for Samba4 LDB <-> Samba3 LDAP mapping module
-
-Source files:
-source/lib/ldb/modules/ldb_map.c
-source/lib/ldb/modules/ldb_map.h
-source/lib/samba3/group.c
-source/lib/samba3/idmap.c
-source/lib/samba3/policy.c
-source/lib/samba3/registry.c
-source/lib/samba3/samba3.c
-source/lib/samba3/secrets.c
-source/lib/samba3/share_info.c
-source/lib/samba3/smbpasswd.c
-source/lib/samba3/tdbsam.c
-source/lib/samba3/winsdb.c
-source/lib/samba3/samba3.h
-source/scripting/libjs/upgrade.js
-source/scripting/ejs/smbcalls_param.c
-source/scripting/ejs/smbcalls_samba3.c
-source/param/generic.c
-source/param/generic.h
-testdata/samba3/verify
-testprogs/ejs/samba3sam
-source/setup/upgrade
-source/scripting/bin/samba3dump
-source/dsdb/samdb/ldb_modules/samba3sam.c
-source/script/tests/test_s3upgrade.sh
-swat/install/samba3.esp
-
-Known remaining issues:
- - [upgrade] Conversion from the smbpasswd/TDB passwords to ntPwdHash / lmPwdHash is broken. Couldn't find out why.
- - [ldb_map] Conversion of attribute names in DN's is still a bit dodgy
- - [ldb_map] mapped objectClass names may be mentioned multiple times in returned records
- - [ldb_map] add/modify support not tested very well with LDAP yet (only LDB+TDB)
- - [ldb_map] group membership is not yet mapped (only primaryGroupID / sambaPrimaryGroupSID)
diff --git a/source4/lib/samba3/samba3.h b/source4/lib/samba3/samba3.h
index 1a0ce04143..87de13f8f8 100644
--- a/source4/lib/samba3/samba3.h
+++ b/source4/lib/samba3/samba3.h
@@ -22,7 +22,6 @@
#include "librpc/gen_ndr/security.h"
#include "librpc/gen_ndr/samr.h"
-#include "param/param.h"
struct samr_Password *smbpasswd_gethexpwd(TALLOC_CTX *mem_ctx, const char *p);
char *smbpasswd_sethexpwd(TALLOC_CTX *mem_ctx, struct samr_Password *pwd, uint16_t acb_info);
diff --git a/source4/libcli/security/security_token.c b/source4/libcli/security/security_token.c
index e1349e06f8..0764dfeb8f 100644
--- a/source4/libcli/security/security_token.c
+++ b/source4/libcli/security/security_token.c
@@ -1,7 +1,7 @@
/*
Unix SMB/CIFS implementation.
- security descriptror utility functions
+ security descriptor utility functions
Copyright (C) Andrew Tridgell 2004
Copyright (C) Stefan Metzmacher 2005
diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c
index f3684ed280..5d09a5083a 100644
--- a/source4/libcli/smb2/request.c
+++ b/source4/libcli/smb2/request.c
@@ -78,9 +78,11 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_
req = talloc(transport, struct smb2_request);
if (req == NULL) return NULL;
- seqnum = transport->seqnum++;
- if (seqnum == UINT64_MAX) {
- seqnum = transport->seqnum++;
+ seqnum = transport->seqnum;
+ if (transport->credits.charge > 0) {
+ transport->seqnum += transport->credits.charge;
+ } else {
+ transport->seqnum += 1;
}
req->state = SMB2_REQUEST_INIT;
@@ -131,7 +133,7 @@ struct smb2_request *smb2_request_init(struct smb2_transport *transport, uint16_
SIVAL(req->out.hdr, 0, SMB2_MAGIC);
SSVAL(req->out.hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
- SSVAL(req->out.hdr, SMB2_HDR_EPOCH, 0);
+ SSVAL(req->out.hdr, SMB2_HDR_EPOCH, transport->credits.charge);
SIVAL(req->out.hdr, SMB2_HDR_STATUS, 0);
SSVAL(req->out.hdr, SMB2_HDR_OPCODE, opcode);
SSVAL(req->out.hdr, SMB2_HDR_CREDIT, transport->credits.ask_num);
diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h
index eb231984df..6372cd805b 100644
--- a/source4/libcli/smb2/smb2.h
+++ b/source4/libcli/smb2/smb2.h
@@ -87,6 +87,7 @@ struct smb2_transport {
} compound;
struct {
+ uint16_t charge;
uint16_t ask_num;
} credits;
diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c
index 60522370b7..dffd1acd2b 100644
--- a/source4/libcli/smb2/transport.c
+++ b/source4/libcli/smb2/transport.c
@@ -84,6 +84,7 @@ struct smb2_transport *smb2_transport_init(struct smbcli_socket *sock,
transport->socket = talloc_steal(transport, sock);
transport->options = *options;
+ transport->credits.charge = 0;
transport->credits.ask_num = 1;
/* setup the stream -> packet parser */
@@ -552,6 +553,12 @@ void smb2_transport_credits_ask_num(struct smb2_transport *transport,
transport->credits.ask_num = ask_num;
}
+void smb2_transport_credits_set_charge(struct smb2_transport *transport,
+ uint16_t charge)
+{
+ transport->credits.charge = charge;
+}
+
static void idle_handler(struct tevent_context *ev,
struct tevent_timer *te, struct timeval t, void *private_data)
{
diff --git a/source4/libnet/libnet_become_dc.c b/source4/libnet/libnet_become_dc.c
index dbbabd6a6d..b89e238a1c 100644
--- a/source4/libnet/libnet_become_dc.c
+++ b/source4/libnet/libnet_become_dc.c
@@ -25,7 +25,7 @@
#include "lib/ldb/include/ldb_errors.h"
#include "lib/ldb_wrap.h"
#include "dsdb/samdb/samdb.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#include "librpc/gen_ndr/ndr_drsuapi_c.h"
#include "libcli/security/security.h"
#include "librpc/gen_ndr/ndr_misc.h"
diff --git a/source4/libnet/libnet_group.c b/source4/libnet/libnet_group.c
index b0669640f3..9e7abe81b1 100644
--- a/source4/libnet/libnet_group.c
+++ b/source4/libnet/libnet_group.c
@@ -484,7 +484,7 @@ struct composite_context *libnet_GroupList_send(struct libnet_context *ctx,
/* store the arguments in the state structure */
s->ctx = ctx;
s->page_size = io->in.page_size;
- s->resume_index = (uint32_t)io->in.resume_index;
+ s->resume_index = io->in.resume_index;
s->domain_name = talloc_strdup(c, io->in.domain_name);
s->monitor_fn = monitor;
diff --git a/source4/libnet/libnet_group.h b/source4/libnet/libnet_group.h
index b80d3449c8..8ac47437fd 100644
--- a/source4/libnet/libnet_group.h
+++ b/source4/libnet/libnet_group.h
@@ -58,11 +58,11 @@ struct libnet_GroupList {
struct {
const char *domain_name;
int page_size;
- uint resume_index;
+ uint32_t resume_index;
} in;
struct {
int count;
- uint resume_index;
+ uint32_t resume_index;
struct grouplist {
const char *sid;
diff --git a/source4/libnet/libnet_samdump.c b/source4/libnet/libnet_samdump.c
index 08a2295169..8092260515 100644
--- a/source4/libnet/libnet_samdump.c
+++ b/source4/libnet/libnet_samdump.c
@@ -25,6 +25,7 @@
#include "../lib/util/dlinklist.h"
#include "samba3/samba3.h"
#include "libcli/security/security.h"
+#include "param/param.h"
struct samdump_secret {
diff --git a/source4/libnet/libnet_unbecome_dc.c b/source4/libnet/libnet_unbecome_dc.c
index e0e5e42115..3bd7a4e287 100644
--- a/source4/libnet/libnet_unbecome_dc.c
+++ b/source4/libnet/libnet_unbecome_dc.c
@@ -25,7 +25,7 @@
#include "lib/ldb/include/ldb_errors.h"
#include "lib/ldb_wrap.h"
#include "dsdb/samdb/samdb.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#include "librpc/gen_ndr/ndr_drsuapi_c.h"
#include "param/param.h"
diff --git a/source4/libnet/libnet_user.c b/source4/libnet/libnet_user.c
index 8606d0856e..dd4d501c17 100644
--- a/source4/libnet/libnet_user.c
+++ b/source4/libnet/libnet_user.c
@@ -945,7 +945,7 @@ struct composite_context* libnet_UserList_send(struct libnet_context *ctx,
/* store the arguments in the state structure */
s->ctx = ctx;
s->page_size = r->in.page_size;
- s->resume_index = (uint32_t)r->in.resume_index;
+ s->resume_index = r->in.resume_index;
s->domain_name = talloc_strdup(c, r->in.domain_name);
s->monitor_fn = monitor;
diff --git a/source4/libnet/libnet_user.h b/source4/libnet/libnet_user.h
index 4aad654b3b..8203d14c33 100644
--- a/source4/libnet/libnet_user.h
+++ b/source4/libnet/libnet_user.h
@@ -140,11 +140,11 @@ struct libnet_UserList {
struct {
const char *domain_name;
int page_size;
- uint resume_index;
+ uint32_t resume_index;
} in;
struct {
int count;
- uint resume_index;
+ uint32_t resume_index;
struct userlist {
const char *sid;
diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk
index 52c7f3e2d1..9cb2d7faf6 100644
--- a/source4/librpc/config.mk
+++ b/source4/librpc/config.mk
@@ -79,11 +79,6 @@ PUBLIC_DEPENDENCIES = LIBNDR
NDR_WINSTATION_OBJ_FILES = $(gen_ndrsrcdir)/ndr_winstation.o
-[SUBSYSTEM::NDR_ECHO]
-PUBLIC_DEPENDENCIES = LIBNDR
-
-NDR_ECHO_OBJ_FILES = ../librpc/gen_ndr/ndr_echo.o
-
[SUBSYSTEM::NDR_IRPC]
PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY NDR_NBT
@@ -114,30 +109,23 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_ORPC
NDR_ROT_OBJ_FILES = ../librpc/gen_ndr/ndr_rot.o
-[SUBSYSTEM::NDR_LSA]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY
-
-NDR_LSA_OBJ_FILES = ../librpc/gen_ndr/ndr_lsa.o
-
-PUBLIC_HEADERS += ../librpc/gen_ndr/lsa.h
-
-[SUBSYSTEM::NDR_DFS]
-PUBLIC_DEPENDENCIES = LIBNDR
-
-NDR_DFS_OBJ_FILES = ../librpc/gen_ndr/ndr_dfs.o
-
[SUBSYSTEM::NDR_FRSRPC]
PUBLIC_DEPENDENCIES = LIBNDR
-NDR_FRSRPC_OBJ_FILES = ../librpc/gen_ndr/ndr_frsrpc.o
+NDR_FRSRPC_OBJ_FILES = ../librpc/gen_ndr/ndr_frsrpc.o ../librpc/ndr/ndr_frsrpc.o
[SUBSYSTEM::NDR_FRSAPI]
PUBLIC_DEPENDENCIES = LIBNDR
NDR_FRSAPI_OBJ_FILES = ../librpc/gen_ndr/ndr_frsapi.o
+[SUBSYSTEM::NDR_FRSTRANS]
+PUBLIC_DEPENDENCIES = LIBNDR
+
+NDR_FRSTRANS_OBJ_FILES = ../librpc/gen_ndr/ndr_frstrans.o
+
[SUBSYSTEM::NDR_DRSUAPI]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_COMPRESSION NDR_SECURITY NDR_SAMR ASN1_UTIL
+PUBLIC_DEPENDENCIES = LIBNDR NDR_COMPRESSION NDR_SECURITY NDR_STANDARD ASN1_UTIL
NDR_DRSUAPI_OBJ_FILES = ../librpc/gen_ndr/ndr_drsuapi.o ../librpc/ndr/ndr_drsuapi.o
@@ -161,13 +149,6 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY
NDR_UNIXINFO_OBJ_FILES = ../librpc/gen_ndr/ndr_unixinfo.o
-[SUBSYSTEM::NDR_SAMR]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_LSA NDR_SECURITY
-
-NDR_SAMR_OBJ_FILES = ../librpc/gen_ndr/ndr_samr.o
-
-PUBLIC_HEADERS += $(addprefix ../librpc/gen_ndr/, samr.h ndr_samr.h ndr_samr_c.h)
-
[SUBSYSTEM::NDR_NFS4ACL]
PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY
@@ -182,35 +163,6 @@ NDR_SPOOLSS_OBJ_FILES = ../librpc/gen_ndr/ndr_spoolss.o
NDR_SPOOLSS_BUF_OBJ_FILES = ../librpc/ndr/ndr_spoolss_buf.o
-[SUBSYSTEM::NDR_WKSSVC]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_SRVSVC NDR_SECURITY
-
-NDR_WKSSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_wkssvc.o
-
-[SUBSYSTEM::NDR_SRVSVC]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_SVCCTL NDR_SECURITY
-
-NDR_SRVSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_srvsvc.o
-
-[SUBSYSTEM::NDR_SVCCTL]
-PUBLIC_DEPENDENCIES = LIBNDR
-
-NDR_SVCCTL_OBJ_FILES = ../librpc/gen_ndr/ndr_svcctl.o ../librpc/ndr/ndr_svcctl.o
-
-PUBLIC_HEADERS += $(addprefix ../librpc/gen_ndr/, ndr_svcctl.h svcctl.h)
-
-[SUBSYSTEM::NDR_ATSVC]
-PUBLIC_DEPENDENCIES = LIBNDR
-
-NDR_ATSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_atsvc.o
-
-PUBLIC_HEADERS += $(addprefix ../librpc/gen_ndr/, atsvc.h ndr_atsvc.h)
-
-[SUBSYSTEM::NDR_EVENTLOG]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_LSA
-
-NDR_EVENTLOG_OBJ_FILES = ../librpc/gen_ndr/ndr_eventlog.o
-
[SUBSYSTEM::NDR_EPMAPPER]
PUBLIC_DEPENDENCIES = LIBNDR
@@ -236,16 +188,6 @@ PUBLIC_DEPENDENCIES = LIBNDR
NDR_WINS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_wins.o
-[SUBSYSTEM::NDR_WINREG]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_INITSHUTDOWN NDR_SECURITY
-
-NDR_WINREG_OBJ_FILES = ../librpc/gen_ndr/ndr_winreg.o
-
-[SUBSYSTEM::NDR_INITSHUTDOWN]
-PUBLIC_DEPENDENCIES = LIBNDR
-
-NDR_INITSHUTDOWN_OBJ_FILES = ../librpc/gen_ndr/ndr_initshutdown.o
-
[SUBSYSTEM::NDR_MGMT]
PUBLIC_DEPENDENCIES = LIBNDR
@@ -291,18 +233,6 @@ PUBLIC_DEPENDENCIES = LIBNDR
NDR_SCERPC_OBJ_FILES = ../librpc/gen_ndr/ndr_scerpc.o
-[SUBSYSTEM::NDR_NTSVCS]
-PUBLIC_DEPENDENCIES = LIBNDR
-
-NDR_NTSVCS_OBJ_FILES = ../librpc/gen_ndr/ndr_ntsvcs.o
-
-[SUBSYSTEM::NDR_NETLOGON]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_SAMR NDR_LSA NDR_SECURITY
-
-NDR_NETLOGON_OBJ_FILES = ../librpc/gen_ndr/ndr_netlogon.o ../librpc/ndr/ndr_netlogon.o
-
-PUBLIC_HEADERS += ../librpc/gen_ndr/netlogon.h
-
[SUBSYSTEM::NDR_TRKWKS]
PUBLIC_DEPENDENCIES = LIBNDR
@@ -314,7 +244,7 @@ PUBLIC_DEPENDENCIES = LIBNDR
NDR_KEYSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_keysvc.o
[SUBSYSTEM::NDR_KRB5PAC]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_NETLOGON NDR_SECURITY
+PUBLIC_DEPENDENCIES = LIBNDR NDR_STANDARD NDR_SECURITY
NDR_KRB5PAC_OBJ_FILES = ../librpc/gen_ndr/ndr_krb5pac.o ../librpc/ndr/ndr_krb5pac.o
@@ -339,7 +269,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT
NDR_SCHANNEL_OBJ_FILES = $(gen_ndrsrcdir)/ndr_schannel.o
[SUBSYSTEM::NDR_NBT]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT_BUF NDR_SVCCTL NDR_SECURITY NDR_SAMR LIBCLI_NDR_NETLOGON
+PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT_BUF NDR_SECURITY NDR_STANDARD LIBCLI_NDR_NETLOGON
NDR_NBT_OBJ_FILES = ../librpc/gen_ndr/ndr_nbt.o
@@ -356,7 +286,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT
NDR_WINSREPL_OBJ_FILES = $(gen_ndrsrcdir)/ndr_winsrepl.o
[SUBSYSTEM::NDR_WINBIND]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_NETLOGON
+PUBLIC_DEPENDENCIES = LIBNDR NDR_STANDARD
NDR_WINBIND_OBJ_FILES = $(gen_ndrsrcdir)/ndr_winbind.o
#PUBLIC_HEADERS += $(gen_ndrsrcdir)/winbind.h
@@ -374,18 +304,48 @@ $(gen_ndrsrcdir)/tables.c: $(IDL_NDR_PARSE_H_FILES)
@$(PERL) ../librpc/tables.pl --output=$@ $^ > $(gen_ndrsrcdir)/tables.x
@mv $(gen_ndrsrcdir)/tables.x $@
+[LIBRARY::NDR_STANDARD]
+PUBLIC_DEPENDENCIES = LIBNDR
+PRIVATE_DEPENDENCIES = NDR_SECURITY
+
+NDR_STANDARD_OBJ_FILES = ../librpc/gen_ndr/ndr_echo.o \
+ ../librpc/gen_ndr/ndr_lsa.o \
+ ../librpc/gen_ndr/ndr_samr.o \
+ ../librpc/gen_ndr/ndr_netlogon.o \
+ ../librpc/ndr/ndr_netlogon.o \
+ ../librpc/gen_ndr/ndr_dfs.o \
+ ../librpc/gen_ndr/ndr_atsvc.o \
+ ../librpc/gen_ndr/ndr_wkssvc.o \
+ ../librpc/gen_ndr/ndr_srvsvc.o \
+ ../librpc/gen_ndr/ndr_svcctl.o \
+ ../librpc/ndr/ndr_svcctl.o \
+ ../librpc/gen_ndr/ndr_winreg.o \
+ ../librpc/gen_ndr/ndr_initshutdown.o \
+ ../librpc/gen_ndr/ndr_eventlog.o \
+ ../librpc/gen_ndr/ndr_ntsvcs.o
+
+PC_FILES += $(librpcsrcdir)/ndr_standard.pc
+
+PUBLIC_HEADERS += $(addprefix ../librpc/gen_ndr/, samr.h ndr_samr.h lsa.h netlogon.h atsvc.h ndr_atsvc.h ndr_svcctl.h svcctl.h)
+
+NDR_STANDARD_VERSION = 0.0.1
+NDR_STANDARD_SOVERSION = 0
+
[SUBSYSTEM::NDR_TABLE]
PUBLIC_DEPENDENCIES = \
- NDR_AUDIOSRV NDR_ECHO NDR_DCERPC \
- NDR_DSBACKUP NDR_EFS NDR_LSA NDR_DFS NDR_DRSUAPI \
- NDR_POLICYAGENT NDR_UNIXINFO NDR_SAMR NDR_SPOOLSS NDR_WKSSVC NDR_SRVSVC NDR_ATSVC \
- NDR_EVENTLOG NDR_EPMAPPER NDR_DBGIDL NDR_DSSETUP NDR_MSGSVC NDR_WINS \
- NDR_WINREG NDR_MGMT NDR_PROTECTED_STORAGE NDR_OXIDRESOLVER \
- NDR_REMACT NDR_WZCSVC NDR_BROWSER NDR_W32TIME NDR_SCERPC NDR_NTSVCS \
- NDR_NETLOGON NDR_TRKWKS NDR_KEYSVC NDR_KRB5PAC NDR_XATTR NDR_SCHANNEL \
- NDR_ROT NDR_DRSBLOBS NDR_SVCCTL NDR_NBT NDR_WINSREPL NDR_SECURITY \
- NDR_INITSHUTDOWN NDR_DNSSERVER NDR_WINSTATION NDR_IRPC NDR_OPENDB \
- NDR_SASL_HELPERS NDR_NOTIFY NDR_WINBIND NDR_FRSRPC NDR_FRSAPI NDR_NFS4ACL NDR_NTP_SIGND \
+ NDR_STANDARD \
+ NDR_AUDIOSRV \
+ NDR_DSBACKUP NDR_EFS NDR_DRSUAPI \
+ NDR_POLICYAGENT NDR_UNIXINFO NDR_SPOOLSS \
+ NDR_EPMAPPER NDR_DBGIDL NDR_DSSETUP NDR_MSGSVC NDR_WINS \
+ NDR_MGMT NDR_PROTECTED_STORAGE NDR_OXIDRESOLVER \
+ NDR_REMACT NDR_WZCSVC NDR_BROWSER NDR_W32TIME NDR_SCERPC \
+ NDR_TRKWKS NDR_KEYSVC NDR_KRB5PAC NDR_XATTR NDR_SCHANNEL \
+ NDR_ROT NDR_DRSBLOBS NDR_NBT NDR_WINSREPL NDR_SECURITY \
+ NDR_DNSSERVER NDR_WINSTATION NDR_IRPC NDR_OPENDB \
+ NDR_SASL_HELPERS NDR_NOTIFY NDR_WINBIND \
+ NDR_FRSRPC NDR_FRSAPI NDR_FRSTRANS \
+ NDR_NFS4ACL NDR_NTP_SIGND \
NDR_DCOM NDR_WMI NDR_NAMED_PIPE_AUTH
NDR_TABLE_OBJ_FILES = ../librpc/ndr/ndr_table.o $(gen_ndrsrcdir)/tables.o
@@ -401,7 +361,7 @@ PUBLIC_DEPENDENCIES = NDR_AUDIOSRV dcerpc
RPC_NDR_AUDIOSRV_OBJ_FILES = ../librpc/gen_ndr/ndr_audiosrv_c.o
[SUBSYSTEM::RPC_NDR_ECHO]
-PUBLIC_DEPENDENCIES = dcerpc NDR_ECHO
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
RPC_NDR_ECHO_OBJ_FILES = ../librpc/gen_ndr/ndr_echo_c.o
@@ -416,12 +376,12 @@ PUBLIC_DEPENDENCIES = dcerpc NDR_EFS
RPC_NDR_EFS_OBJ_FILES = ../librpc/gen_ndr/ndr_efs_c.o
[SUBSYSTEM::RPC_NDR_LSA]
-PUBLIC_DEPENDENCIES = dcerpc NDR_LSA
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
RPC_NDR_LSA_OBJ_FILES = ../librpc/gen_ndr/ndr_lsa_c.o
[SUBSYSTEM::RPC_NDR_DFS]
-PUBLIC_DEPENDENCIES = dcerpc NDR_DFS
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
RPC_NDR_DFS_OBJ_FILES = ../librpc/gen_ndr/ndr_dfs_c.o
@@ -456,7 +416,7 @@ PUBLIC_DEPENDENCIES = dcerpc NDR_IRPC
RPC_NDR_IRPC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_irpc_c.o
[LIBRARY::dcerpc_samr]
-PUBLIC_DEPENDENCIES = dcerpc NDR_SAMR
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
PC_FILES += $(librpcsrcdir)/dcerpc_samr.pc
@@ -464,13 +424,15 @@ dcerpc_samr_VERSION = 0.0.1
dcerpc_samr_SOVERSION = 0
dcerpc_samr_OBJ_FILES = ../librpc/gen_ndr/ndr_samr_c.o
+PUBLIC_HEADERS += ../librpc/gen_ndr/ndr_samr_c.h
+
[SUBSYSTEM::RPC_NDR_SPOOLSS]
PUBLIC_DEPENDENCIES = dcerpc NDR_SPOOLSS
RPC_NDR_SPOOLSS_OBJ_FILES = ../librpc/gen_ndr/ndr_spoolss_c.o
[SUBSYSTEM::RPC_NDR_WKSSVC]
-PUBLIC_DEPENDENCIES = dcerpc NDR_WKSSVC
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
RPC_NDR_WKSSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_wkssvc_c.o
@@ -480,14 +442,14 @@ PUBLIC_DEPENDENCIES = dcerpc NDR_SRVSVC
RPC_NDR_SRVSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_srvsvc_c.o
[SUBSYSTEM::RPC_NDR_SVCCTL]
-PUBLIC_DEPENDENCIES = dcerpc NDR_SVCCTL
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
RPC_NDR_SVCCTL_OBJ_FILES = ../librpc/gen_ndr/ndr_svcctl_c.o
PUBLIC_HEADERS += ../librpc/gen_ndr/ndr_svcctl_c.h
[LIBRARY::dcerpc_atsvc]
-PUBLIC_DEPENDENCIES = dcerpc NDR_ATSVC
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
dcerpc_atsvc_VERSION = 0.0.1
dcerpc_atsvc_SOVERSION = 0
@@ -498,7 +460,7 @@ PC_FILES += $(librpcsrcdir)/dcerpc_atsvc.pc
PUBLIC_HEADERS += ../librpc/gen_ndr/ndr_atsvc_c.h
[SUBSYSTEM::RPC_NDR_EVENTLOG]
-PUBLIC_DEPENDENCIES = dcerpc NDR_EVENTLOG
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
RPC_NDR_EVENTLOG_OBJ_FILES = ../librpc/gen_ndr/ndr_eventlog_c.o
@@ -528,12 +490,12 @@ PUBLIC_DEPENDENCIES = dcerpc NDR_WINS
RPC_NDR_WINS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_wins_c.o
[SUBSYSTEM::RPC_NDR_WINREG]
-PUBLIC_DEPENDENCIES = dcerpc NDR_WINREG
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
RPC_NDR_WINREG_OBJ_FILES = ../librpc/gen_ndr/ndr_winreg_c.o
[SUBSYSTEM::RPC_NDR_INITSHUTDOWN]
-PUBLIC_DEPENDENCIES = dcerpc NDR_INITSHUTDOWN
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
RPC_NDR_INITSHUTDOWN_OBJ_FILES = ../librpc/gen_ndr/ndr_initshutdown_c.o
@@ -573,12 +535,12 @@ PUBLIC_DEPENDENCIES = dcerpc NDR_SCERPC
RPC_NDR_SCERPC_OBJ_FILES = ../librpc/gen_ndr/ndr_scerpc_c.o
[SUBSYSTEM::RPC_NDR_NTSVCS]
-PUBLIC_DEPENDENCIES = dcerpc NDR_NTSVCS
+PUBLIC_DEPENDENCIES = dcerpc NDR_STANDARD
RPC_NDR_NTSVCS_OBJ_FILES = ../librpc/gen_ndr/ndr_ntsvcs_c.o
[SUBSYSTEM::RPC_NDR_NETLOGON]
-PUBLIC_DEPENDENCIES = NDR_NETLOGON
+PUBLIC_DEPENDENCIES = NDR_STANDARD
RPC_NDR_NETLOGON_OBJ_FILES = ../librpc/gen_ndr/ndr_netlogon_c.o
diff --git a/source4/ntptr/simple_ldb/ntptr_simple_ldb.c b/source4/ntptr/simple_ldb/ntptr_simple_ldb.c
index 4ebbaaeffc..601f7902df 100644
--- a/source4/ntptr/simple_ldb/ntptr_simple_ldb.c
+++ b/source4/ntptr/simple_ldb/ntptr_simple_ldb.c
@@ -192,9 +192,12 @@ static WERROR sptr_GetPrintServerData(struct ntptr_GenericHandle *server, TALLOC
os_ex.major = server_info->version_major;
os_ex.minor = server_info->version_minor;
os_ex.build = server_info->version_build;
- os_ex.extra_string = "";
- os_ex.unknown2 = 0;
- os_ex.unknown3 = 0;
+ os_ex.extra_string = "";
+ os_ex.service_pack_major= 0;
+ os_ex.service_pack_minor= 0;
+ os_ex.suite_mask = 0;
+ os_ex.product_type = 0;
+ os_ex.reserved = 0;
ndr_err = ndr_push_struct_blob(&blob, mem_ctx, lp_iconv_convenience(server->ntptr->lp_ctx), &os_ex, (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersionEx);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c
index 20b00f24e3..95ad1c51fb 100644
--- a/source4/ntvfs/ipc/vfs_ipc.c
+++ b/source4/ntvfs/ipc/vfs_ipc.c
@@ -258,7 +258,8 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs,
one of the interfaces attached to this pipe endpoint.
*/
ep_description->transport = NCACN_NP;
- ep_description->endpoint = talloc_reference(ep_description, p->pipe_name);
+ ep_description->endpoint = talloc_strdup(ep_description, p->pipe_name);
+ NT_STATUS_HAVE_NO_MEMORY(ep_description->endpoint);
/* The session info is refcount-increased in the
* dcesrv_endpoint_search_connect() function
diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c
index c33323350e..8e8da72e1f 100644
--- a/source4/ntvfs/posix/pvfs_resolve.c
+++ b/source4/ntvfs/posix/pvfs_resolve.c
@@ -796,7 +796,10 @@ NTSTATUS pvfs_resolve_parent(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx,
(*name)->has_wildcard = false;
/* we can't get the correct 'original_name', but for the purposes
of this call this is close enough */
- (*name)->original_name = talloc_reference(*name, child->original_name);
+ (*name)->original_name = talloc_strdup(*name, child->original_name);
+ if ((*name)->original_name == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
(*name)->stream_name = NULL;
(*name)->stream_id = 0;
diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c
index 3ef341d61a..97c306f7c3 100644
--- a/source4/ntvfs/unixuid/vfs_unixuid.c
+++ b/source4/ntvfs/unixuid/vfs_unixuid.c
@@ -310,9 +310,9 @@ static NTSTATUS unixuid_connect(struct ntvfs_module_context *ntvfs,
return NT_STATUS_INTERNAL_ERROR;
}
- ntvfs->private_data = priv;
priv->last_sec_ctx = NULL;
priv->last_token = NULL;
+ ntvfs->private_data = priv;
tevent_loop_set_nesting_hook(ntvfs->ctx->event_ctx,
unixuid_event_nesting_hook,
diff --git a/source4/rpc_server/config.mk b/source4/rpc_server/config.mk
index f3dc074125..32669db37a 100644
--- a/source4/rpc_server/config.mk
+++ b/source4/rpc_server/config.mk
@@ -19,7 +19,7 @@ PUBLIC_HEADERS += $(rpc_serversrcdir)/common/common.h
[MODULE::dcerpc_rpcecho]
INIT_FUNCTION = dcerpc_server_rpcecho_init
SUBSYSTEM = dcerpc_server
-PRIVATE_DEPENDENCIES = NDR_ECHO LIBEVENTS
+PRIVATE_DEPENDENCIES = NDR_STANDARD LIBEVENTS
# End MODULE dcerpc_rpcecho
################################################
@@ -69,7 +69,7 @@ $(eval $(call proto_header_template,$(rpc_serversrcdir)/srvsvc/proto.h,$(dcerpc_
INIT_FUNCTION = dcerpc_server_wkssvc_init
SUBSYSTEM = dcerpc_server
PRIVATE_DEPENDENCIES = \
- DCERPC_COMMON NDR_WKSSVC
+ DCERPC_COMMON NDR_STANDARD
# End MODULE dcerpc_wkssvc
################################################
@@ -99,7 +99,7 @@ SUBSYSTEM = dcerpc_server
PRIVATE_DEPENDENCIES = \
SAMDB \
DCERPC_COMMON \
- NDR_SAMR
+ NDR_STANDARD
# End MODULE dcesrv_samr
################################################
@@ -114,7 +114,7 @@ INIT_FUNCTION = dcerpc_server_winreg_init
SUBSYSTEM = dcerpc_server
OUTPUT_TYPE = MERGED_OBJ
PRIVATE_DEPENDENCIES = \
- registry NDR_WINREG
+ registry NDR_STANDARD
# End MODULE dcerpc_winreg
################################################
@@ -128,7 +128,7 @@ SUBSYSTEM = dcerpc_server
PRIVATE_DEPENDENCIES = \
DCERPC_COMMON \
SCHANNELDB \
- NDR_NETLOGON \
+ NDR_STANDARD \
auth_sam \
LIBSAMBA-HOSTCONFIG
# End MODULE dcerpc_netlogon
@@ -144,7 +144,7 @@ SUBSYSTEM = dcerpc_server
PRIVATE_DEPENDENCIES = \
SAMDB \
DCERPC_COMMON \
- NDR_LSA \
+ NDR_STANDARD \
LIBCLI_AUTH \
NDR_DSSETUP
# End MODULE dcerpc_lsa
diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c
index cbadf654fb..2b4a891556 100644
--- a/source4/rpc_server/lsa/dcesrv_lsa.c
+++ b/source4/rpc_server/lsa/dcesrv_lsa.c
@@ -1378,7 +1378,7 @@ static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_
= samdb_result_uint(msg, "posixOffset", 0);
return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
- case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES:
+ case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
info->enc_types.enc_types
= samdb_result_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
break;
diff --git a/source4/rpc_server/lsa/lsa_lookup.c b/source4/rpc_server/lsa/lsa_lookup.c
index dc47d3783a..005c7d4f06 100644
--- a/source4/rpc_server/lsa/lsa_lookup.c
+++ b/source4/rpc_server/lsa/lsa_lookup.c
@@ -394,7 +394,7 @@ static NTSTATUS dcesrv_lsa_lookup_name(struct tevent_context *ev_ctx,
atype = samdb_result_uint(res[i], "sAMAccountType", 0);
- *rtype = samdb_atype_map(atype);
+ *rtype = ds_atype_map(atype);
if (*rtype == SID_NAME_UNKNOWN) {
return STATUS_SOME_UNMAPPED;
}
@@ -503,7 +503,7 @@ static NTSTATUS dcesrv_lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX
atype = samdb_result_uint(res[0], "sAMAccountType", 0);
- *rtype = samdb_atype_map(atype);
+ *rtype = ds_atype_map(atype);
return NT_STATUS_OK;
}
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index dc2d078d6b..2095bf6fa5 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -27,7 +27,7 @@
#include "auth/auth.h"
#include "auth/auth_sam_reply.h"
#include "dsdb/samdb/samdb.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#include "rpc_server/samr/proto.h"
#include "../lib/util/util_ldb.h"
#include "libcli/auth/libcli_auth.h"
@@ -151,8 +151,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca
}
/* pull the user attributes */
- num_records = gendb_search((struct ldb_context *)sam_ctx,
- mem_ctx, NULL, &msgs,
+ num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs,
trust_dom_attrs,
"(&(trustPartner=%s)(objectclass=trustedDomain))",
encoded_account);
@@ -184,8 +183,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca
}
/* pull the user attributes */
- num_records = gendb_search((struct ldb_context *)sam_ctx, mem_ctx,
- NULL, &msgs, attrs,
+ num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
"(&(sAMAccountName=%s)(objectclass=user))",
ldb_binary_encode_string(mem_ctx, account_name));
@@ -852,7 +850,7 @@ static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_C
struct netr_GetDcName *r)
{
const char * const attrs[] = { NULL };
- void *sam_ctx;
+ struct ldb_context *sam_ctx;
struct ldb_message **res;
struct ldb_dn *domain_dn;
int ret;
@@ -865,13 +863,13 @@ static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_C
return WERR_DS_SERVICE_UNAVAILABLE;
}
- domain_dn = samdb_domain_to_dn((struct ldb_context *)sam_ctx, mem_ctx,
+ domain_dn = samdb_domain_to_dn(sam_ctx, mem_ctx,
r->in.domainname);
if (domain_dn == NULL) {
return WERR_DS_SERVICE_UNAVAILABLE;
}
- ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx,
+ ret = gendb_search_dn(sam_ctx, mem_ctx,
domain_dn, &res, attrs);
if (ret != 1) {
return WERR_NO_SUCH_DOMAIN;
@@ -1401,7 +1399,7 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce
struct netr_DsrEnumerateDomainTrusts *r)
{
struct netr_DomainTrustList *trusts;
- void *sam_ctx;
+ struct ldb_context *sam_ctx;
int ret;
struct ldb_message **dom_res;
const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
@@ -1413,7 +1411,7 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce
return WERR_GENERAL_FAILURE;
}
- ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx, NULL,
+ ret = gendb_search_dn(sam_ctx, mem_ctx, NULL,
&dom_res, dom_attrs);
if (ret == -1) {
return WERR_GENERAL_FAILURE;
diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c
index 03acf97cab..c755601230 100644
--- a/source4/rpc_server/samr/dcesrv_samr.c
+++ b/source4/rpc_server/samr/dcesrv_samr.c
@@ -29,7 +29,7 @@
#include "system/time.h"
#include "lib/ldb/include/ldb.h"
#include "lib/ldb/include/ldb_errors.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#include "dsdb/samdb/samdb.h"
#include "libcli/ldap/ldap_ndr.h"
#include "libcli/security/security.h"
@@ -1360,7 +1360,7 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL
UF_INTERDOMAIN_TRUST_ACCOUNT |
UF_WORKSTATION_TRUST_ACCOUNT |
UF_SERVER_TRUST_ACCOUNT));
- user_account_control |= samdb_acb2uf(r->in.acct_flags);
+ user_account_control |= ds_acb2uf(r->in.acct_flags);
talloc_free(msg);
msg = ldb_msg_new(mem_ctx);
@@ -1876,7 +1876,7 @@ static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALL
continue;
}
- rtype = samdb_atype_map(atype);
+ rtype = ds_atype_map(atype);
if (rtype == SID_NAME_UNKNOWN) {
status = STATUS_SOME_UNMAPPED;
@@ -1962,7 +1962,7 @@ static NTSTATUS dcesrv_samr_LookupRids(struct dcesrv_call_state *dce_call, TALLO
continue;
}
- ids[i] = samdb_atype_map(atype);
+ ids[i] = ds_atype_map(atype);
if (ids[i] == SID_NAME_UNKNOWN) {
status = STATUS_SOME_UNMAPPED;
diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c
index ec83cbfdc9..6f12d2f119 100644
--- a/source4/rpc_server/samr/samr_password.c
+++ b/source4/rpc_server/samr/samr_password.c
@@ -26,7 +26,7 @@
#include "rpc_server/samr/dcesrv_samr.h"
#include "system/time.h"
#include "../lib/crypto/crypto.h"
-#include "dsdb/common/flags.h"
+#include "../libds/common/flags.h"
#include "libcli/ldap/ldap.h"
#include "dsdb/samdb/samdb.h"
#include "auth/auth.h"
diff --git a/source4/script/installmisc.sh b/source4/script/installmisc.sh
index 2bd34b119f..0666ae1ade 100755
--- a/source4/script/installmisc.sh
+++ b/source4/script/installmisc.sh
@@ -8,11 +8,15 @@ cd $SRCDIR || exit 1
echo "Installing setup templates"
mkdir -p $SETUPDIR || exit 1
+mkdir -p $SETUPDIR/ad-schema || exit 1
+cp setup/ad-schema/*.txt $SETUPDIR/ad-schema || exit 1
+for p in enableaccount newuser provision provision-backend setexpiry setpassword
+do
+ chmod 0555 setup/$p
+ cp setup/$p $SETUPDIR || exit 1
+done
cp setup/schema-map-* $SETUPDIR || exit 1
cp setup/DB_CONFIG $SETUPDIR || exit 1
-cp setup/provision-backend $SETUPDIR || exit 1
-cp setup/provision $SETUPDIR || exit 1
-cp setup/newuser $SETUPDIR || exit 1
cp setup/*.inf $SETUPDIR || exit 1
cp setup/*.ldif $SETUPDIR || exit 1
cp setup/*.reg $SETUPDIR || exit 1
diff --git a/source4/scripting/python/pyglue.c b/source4/scripting/python/pyglue.c
index 5816d9637d..0869d2feac 100644
--- a/source4/scripting/python/pyglue.c
+++ b/source4/scripting/python/pyglue.c
@@ -46,6 +46,15 @@
} */\
ldb = PyLdb_AsLdbContext(py_ldb);
+static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
+{
+ if (ret == LDB_ERR_PYTHON_EXCEPTION)
+ return; /* Python exception should already be set, just keep that */
+
+ PyErr_SetObject(error,
+ Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
+ ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
+}
static PyObject *py_ldb_get_exception(void)
{
@@ -204,6 +213,63 @@ static PyObject *py_dsdb_set_ntds_invocation_id(PyObject *self, PyObject *args)
Py_RETURN_NONE;
}
+static PyObject *py_dsdb_set_opaque_integer(PyObject *self, PyObject *args)
+{
+ PyObject *py_ldb;
+ int value;
+ int *old_val, *new_val;
+ char *py_opaque_name, *opaque_name_talloc;
+ struct ldb_context *ldb;
+ TALLOC_CTX *tmp_ctx;
+
+ if (!PyArg_ParseTuple(args, "Osi", &py_ldb, &py_opaque_name, &value))
+ return NULL;
+
+ PyErr_LDB_OR_RAISE(py_ldb, ldb);
+
+ /* see if we have a cached copy */
+ old_val = (int *)ldb_get_opaque(ldb,
+ py_opaque_name);
+
+ if (old_val) {
+ *old_val = value;
+ Py_RETURN_NONE;
+ }
+
+ tmp_ctx = talloc_new(ldb);
+ if (tmp_ctx == NULL) {
+ goto failed;
+ }
+
+ new_val = talloc(tmp_ctx, int);
+ if (!new_val) {
+ goto failed;
+ }
+
+ opaque_name_talloc = talloc_strdup(tmp_ctx, py_opaque_name);
+ if (!opaque_name_talloc) {
+ goto failed;
+ }
+
+ *new_val = value;
+
+ /* cache the domain_sid in the ldb */
+ if (ldb_set_opaque(ldb, opaque_name_talloc, new_val) != LDB_SUCCESS) {
+ goto failed;
+ }
+
+ talloc_steal(ldb, new_val);
+ talloc_steal(ldb, opaque_name_talloc);
+ talloc_free(tmp_ctx);
+
+ Py_RETURN_NONE;
+
+failed:
+ talloc_free(tmp_ctx);
+ PyErr_SetString(PyExc_RuntimeError, "Failed to set opaque integer into the ldb!\n");
+ return NULL;
+}
+
static PyObject *py_dsdb_set_global_schema(PyObject *self, PyObject *args)
{
PyObject *py_ldb;
@@ -284,6 +350,8 @@ static PyMethodDef py_misc_methods[] = {
"Register Samba-specific LDB modules and schemas." },
{ "dsdb_set_ntds_invocation_id", (PyCFunction)py_dsdb_set_ntds_invocation_id, METH_VARARGS,
NULL },
+ { "dsdb_set_opaque_integer", (PyCFunction)py_dsdb_set_opaque_integer, METH_VARARGS,
+ NULL },
{ "dsdb_set_global_schema", (PyCFunction)py_dsdb_set_global_schema, METH_VARARGS,
NULL },
{ "dsdb_attach_schema_from_ldif", (PyCFunction)py_dsdb_attach_schema_from_ldif, METH_VARARGS,
@@ -303,5 +371,11 @@ void initglue(void)
return;
PyModule_AddObject(m, "version", PyString_FromString(SAMBA_VERSION_STRING));
+
+ PyModule_AddObject(m, "DS_BEHAVIOR_WIN2000", PyInt_FromLong(DS_BEHAVIOR_WIN2000));
+ PyModule_AddObject(m, "DS_BEHAVIOR_WIN2003_INTERIM", PyInt_FromLong(DS_BEHAVIOR_WIN2003_INTERIM));
+ PyModule_AddObject(m, "DS_BEHAVIOR_WIN2003", PyInt_FromLong(DS_BEHAVIOR_WIN2003));
+ PyModule_AddObject(m, "DS_BEHAVIOR_WIN2008", PyInt_FromLong(DS_BEHAVIOR_WIN2008));
+
}
diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py
index 60a7919136..164803bb65 100644
--- a/source4/scripting/python/samba/__init__.py
+++ b/source4/scripting/python/samba/__init__.py
@@ -42,7 +42,6 @@ else:
import ldb
-import credentials
import glue
class Ldb(ldb.Ldb):
@@ -73,6 +72,8 @@ class Ldb(ldb.Ldb):
self.set_modules_dir(modules_dir)
elif default_ldb_modules_dir is not None:
self.set_modules_dir(default_ldb_modules_dir)
+ elif lp is not None:
+ self.set_modules_dir(os.path.join(lp.get("modules dir"), "ldb"))
if credentials is not None:
self.set_credentials(credentials)
@@ -242,3 +243,8 @@ def valid_netbios_name(name):
return True
version = glue.version
+
+DS_BEHAVIOR_WIN2000 = glue.DS_BEHAVIOR_WIN2000
+DS_BEHAVIOR_WIN2003_INTERIM = glue.DS_BEHAVIOR_WIN2003_INTERIM
+DS_BEHAVIOR_WIN2003 = glue.DS_BEHAVIOR_WIN2003
+DS_BEHAVIOR_WIN2008 = glue.DS_BEHAVIOR_WIN2008
diff --git a/source4/scripting/python/samba/getopt.py b/source4/scripting/python/samba/getopt.py
index c12245f6c5..8b756b2d6f 100644
--- a/source4/scripting/python/samba/getopt.py
+++ b/source4/scripting/python/samba/getopt.py
@@ -20,7 +20,7 @@
"""Support for parsing Samba-related command-line options."""
import optparse
-from credentials import Credentials, AUTO_USE_KERBEROS, DONT_USE_KERBEROS, MUST_USE_KERBEROS
+from credentials import Credentials, DONT_USE_KERBEROS, MUST_USE_KERBEROS
from hostconfig import Hostconfig
__docformat__ = "restructuredText"
diff --git a/source4/scripting/python/samba/idmap.py b/source4/scripting/python/samba/idmap.py
index f8eeb18925..ee79be1af9 100644
--- a/source4/scripting/python/samba/idmap.py
+++ b/source4/scripting/python/samba/idmap.py
@@ -23,8 +23,6 @@
__docformat__ = "restructuredText"
import samba
-import glue
-import ldb
class IDmapDB(samba.Ldb):
"""The IDmap database."""
diff --git a/source4/scripting/python/samba/ms_schema.py b/source4/scripting/python/samba/ms_schema.py
index 2e8050e503..a0abc337ce 100644
--- a/source4/scripting/python/samba/ms_schema.py
+++ b/source4/scripting/python/samba/ms_schema.py
@@ -226,6 +226,7 @@ def __transform_entry(entry, objectClass):
assert(cn)
entry.insert(0, ["dn", "CN=%s,${SCHEMADN}" % cn])
entry.insert(1, ["objectClass", ["top", objectClass]])
+ entry.insert(2, ["cn", cn])
for l in entry:
key = l[0].lower()
diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py
index 189c93a1fc..8a7ed6a86e 100644
--- a/source4/scripting/python/samba/provision.py
+++ b/source4/scripting/python/samba/provision.py
@@ -37,13 +37,13 @@ import param
import registry
import samba
from auth import system_session
-from samba import Ldb, substitute_var, valid_netbios_name, check_all_substituted
+from samba import version, Ldb, substitute_var, valid_netbios_name, check_all_substituted, \
+ DS_BEHAVIOR_WIN2008
from samba.samdb import SamDB
from samba.idmap import IDmapDB
from samba.dcerpc import security
import urllib
-from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \
- timestring, CHANGETYPE_MODIFY, CHANGETYPE_NONE
+from ldb import SCOPE_SUBTREE, LdbError, timestring
from ms_schema import read_ms_schema
__docformat__ = "restructuredText"
@@ -729,7 +729,7 @@ def setup_samdb_rootdse(samdb, setup_path, names):
def setup_self_join(samdb, names,
machinepass, dnspass,
domainsid, invocationid, setup_path,
- policyguid):
+ policyguid, domainControllerFunctionality):
"""Join a host to its own domain."""
assert isinstance(invocationid, str)
setup_add_ldif(samdb, setup_path("provision_self_join.ldif"), {
@@ -745,7 +745,9 @@ def setup_self_join(samdb, names,
"DNSPASS_B64": b64encode(dnspass),
"REALM": names.realm,
"DOMAIN": names.domain,
- "DNSDOMAIN": names.dnsdomain})
+ "DNSDOMAIN": names.dnsdomain,
+ "SAMBA_VERSION_STRING": version,
+ "DOMAIN_CONTROLLER_FUNCTIONALITY": str(domainControllerFunctionality)})
setup_add_ldif(samdb, setup_path("provision_group_policy.ldif"), {
"POLICYGUID": policyguid,
"DNSDOMAIN": names.dnsdomain,
@@ -765,6 +767,10 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
:note: This will wipe the main SAM database file!
"""
+ domainFunctionality = DS_BEHAVIOR_WIN2008
+ forestFunctionality = DS_BEHAVIOR_WIN2008
+ domainControllerFunctionality = DS_BEHAVIOR_WIN2008
+
erase = (fill != FILL_DRS)
# Also wipes the database
@@ -780,6 +786,11 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
return samdb
message("Pre-loading the Samba 4 and AD schema")
+
+ samdb.set_opaque_integer("domainFunctionality", domainFunctionality)
+ samdb.set_opaque_integer("forestFunctionality", forestFunctionality)
+ samdb.set_opaque_integer("domainControllerFunctionality", domainControllerFunctionality)
+
samdb.set_domain_sid(str(domainsid))
if serverrole == "domain controller":
samdb.set_invocation_id(invocationid)
@@ -818,6 +829,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
"POLICYGUID": policyguid,
"DOMAINDN": names.domaindn,
"DOMAINGUID_MOD": domainguid_mod,
+ "DOMAIN_FUNCTIONALITY": str(domainFunctionality)
})
message("Adding configuration container (permitted to fail)")
@@ -864,7 +876,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
"DOMAIN": names.domain,
"SCHEMADN": names.schemadn,
"DOMAINDN": names.domaindn,
- "SERVERDN": names.serverdn
+ "SERVERDN": names.serverdn,
+ "FOREST_FUNCTIONALALITY": str(forestFunctionality)
})
message("Setting up display specifiers")
@@ -908,7 +921,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
dnspass=dnspass,
machinepass=machinepass,
domainsid=domainsid, policyguid=policyguid,
- setup_path=setup_path)
+ setup_path=setup_path, domainControllerFunctionality=domainControllerFunctionality)
except:
samdb.transaction_cancel()
diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py
index c8ddbc8864..179efa2700 100644
--- a/source4/scripting/python/samba/samba3.py
+++ b/source4/scripting/python/samba/samba3.py
@@ -502,7 +502,7 @@ TDBSAM_USER_PREFIX = "USER_"
class LdapSam(object):
"""Samba 3 LDAP passdb backend reader."""
def __init__(self, url):
- self.ldap_url = ldap_url
+ self.ldap_url = url
class TdbSam(TdbDatabase):
@@ -692,7 +692,7 @@ class ParamFile(object):
(k, v) = l.split("=", 1)
self._sections[section][self._sanitize_name(k)] = v
else:
- raise Error("Unable to parser line %d: %r" % (i+1,l))
+ raise Exception("Unable to parser line %d: %r" % (i+1,l))
def get(self, param, section=None):
"""Return the value of a parameter.
diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py
index bc76cd3c5f..6cb2469846 100644
--- a/source4/scripting/python/samba/samdb.py
+++ b/source4/scripting/python/samba/samdb.py
@@ -231,6 +231,14 @@ userPassword:: %s
"""
glue.dsdb_set_ntds_invocation_id(self, invocation_id)
+ def set_opaque_integer(self, name, value):
+ """Set an integer as an opaque (a flag or other value) value on the database
+
+ :param name: The name for the opaque value
+ :param value: The integer value
+ """
+ glue.dsdb_set_opaque_integer(self, name, value)
+
def setexpiry(self, user, expiry_seconds, noexpiry):
"""Set the account expiry for a user
diff --git a/source4/scripting/python/samba/tests/shares.py b/source4/scripting/python/samba/tests/shares.py
new file mode 100644
index 0000000000..9130c36780
--- /dev/null
+++ b/source4/scripting/python/samba/tests/shares.py
@@ -0,0 +1,74 @@
+#!/usr/bin/python
+
+# Unix SMB/CIFS implementation. Tests for shares
+# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2009
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+from samba.shares import SharesContainer
+from unittest import TestCase
+
+
+class MockService(object):
+
+ def __init__(self, data):
+ self.data = data
+
+ def __getitem__(self, name):
+ return self.data[name]
+
+
+class MockLoadParm(object):
+
+ def __init__(self, data):
+ self.data = data
+
+ def __getitem__(self, name):
+ return MockService(self.data[name])
+
+ def __contains__(self, name):
+ return name in self.data
+
+ def __len__(self):
+ return len(self.data)
+
+ def services(self):
+ return self.data.keys()
+
+
+class ShareTests(TestCase):
+
+ def _get_shares(self, conf):
+ return SharesContainer(MockLoadParm(conf))
+
+ def test_len_no_global(self):
+ shares = self._get_shares({})
+ self.assertEquals(0, len(shares))
+
+ def test_iter(self):
+ self.assertEquals([], list(self._get_shares({})))
+ self.assertEquals([], list(self._get_shares({"global":{}})))
+ self.assertEquals(["bla"], list(self._get_shares({"global":{}, "bla":{}})))
+
+ def test_len(self):
+ shares = self._get_shares({"global": {}})
+ self.assertEquals(0, len(shares))
+
+ def test_getitem_nonexistant(self):
+ shares = self._get_shares({"global": {}})
+ self.assertRaises(KeyError, shares.__getitem__, "bla")
+
+ def test_getitem_global(self):
+ shares = self._get_shares({"global": {}})
+ self.assertRaises(KeyError, shares.__getitem__, "global")
diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py
index 0c83604e82..81945525e6 100644
--- a/source4/scripting/python/samba/upgrade.py
+++ b/source4/scripting/python/samba/upgrade.py
@@ -9,17 +9,16 @@
__docformat__ = "restructuredText"
-from provision import findnss, provision, FILL_DRS
+from provision import provision, FILL_DRS
import grp
import ldb
import time
import pwd
-import uuid
import registry
from samba import Ldb
-from samba.samdb import SamDB
+from samba.param import LoadParm
-def import_sam_policy(samldb, samba3_policy, domaindn):
+def import_sam_policy(samldb, policy, dn):
"""Import a Samba 3 policy database."""
samldb.modify_ldif("""
dn: %s
@@ -394,7 +393,7 @@ def upgrade_smbconf(oldconf,mark):
kept in the new configuration as "samba3:<name>"
"""
data = oldconf.data()
- newconf = param_init()
+ newconf = LoadParm()
for s in data:
for p in data[s]:
diff --git a/source4/selftest/knownfail b/source4/selftest/knownfail
index 91180418b8..68d406ab9b 100644
--- a/source4/selftest/knownfail
+++ b/source4/selftest/knownfail
@@ -40,6 +40,7 @@ rpc.netlogon.*.DatabaseRedo
rpc.netlogon.*.ServerGetTrustInfo
samba4.rpc.samr.passwords.pwdlastset # Not provided by Samba 4 yet
samba4.rpc.samr.users.privileges
+samba4.rpc.spoolss.printer # Not provided by Samba 4 yet
base.charset.*.Testing partial surrogate
.*net.api.delshare.* # DelShare isn't implemented yet
rap.*netservergetinfo
diff --git a/source4/setup/provision b/source4/setup/provision
index 5cb851ceb7..d7fa6aa54f 100755
--- a/source4/setup/provision
+++ b/source4/setup/provision
@@ -22,9 +22,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-import getopt
import optparse
-import os
import sys
# Find right directory when running from source tree
@@ -34,7 +32,6 @@ import samba
from samba.credentials import DONT_USE_KERBEROS
from samba.auth import system_session
import samba.getopt as options
-from samba import param
from samba.provision import provision, FILL_FULL, FILL_NT4SYNC, FILL_DRS, find_setup_dir
# how do we make this case insensitive??
@@ -121,7 +118,6 @@ if not opts.interactive and (opts.realm is None or opts.domain is None):
if opts.interactive:
from getpass import getpass
- import readline
import socket
def ask(prompt, default=None):
if default is not None:
diff --git a/source4/setup/provision.ldif b/source4/setup/provision.ldif
index e5b20d03e1..9f50b45dff 100644
--- a/source4/setup/provision.ldif
+++ b/source4/setup/provision.ldif
@@ -1,7 +1,28 @@
+dn: CN=Builtin,${DOMAINDN}
+objectClass: top
+objectClass: builtinDomain
+forceLogoff: -9223372036854775808
+lockoutDuration: -18000000000
+lockOutObservationWindow: -18000000000
+lockoutThreshold: 0
+maxPwdAge: -37108517437440
+minPwdAge: 0
+minPwdLength: 0
+modifiedCountAtLastProm: 0
+nextRid: 1000
+pwdProperties: 0
+pwdHistoryLength: 0
+objectSid: S-1-5-32
+serverState: 1
+uASCompat: 1
+modifiedCount: 1
+systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+showInAdvancedViewOnly: FALSE
+
dn: OU=Domain Controllers,${DOMAINDN}
objectClass: top
objectClass: organizationalUnit
-cn: Domain Controllers
description: Default container for domain controllers
systemFlags: -1946157056
isCriticalSystemObject: TRUE
@@ -10,82 +31,171 @@ showInAdvancedViewOnly: FALSE
dn: CN=ForeignSecurityPrincipals,${DOMAINDN}
objectClass: top
objectClass: container
-cn: ForeignSecurityPrincipals
description: Default container for security identifiers (SIDs) associated with objects from external, trusted domains
systemFlags: -1946157056
isCriticalSystemObject: TRUE
showInAdvancedViewOnly: FALSE
+dn: CN=Infrastructure,${DOMAINDN}
+objectClass: top
+objectClass: infrastructureUpdate
+systemFlags: -1946157056
+fSMORoleOwner: CN=NTDS Settings,${SERVERDN}
+isCriticalSystemObject: TRUE
+
+dn: CN=LostAndFound,${DOMAINDN}
+objectClass: top
+objectClass: lostAndFound
+description: Default container for orphaned objects
+systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+
+dn: CN=NTDS Quotas,${DOMAINDN}
+objectClass: top
+objectClass: msDS-QuotaContainer
+description: Quota specifications container
+msDS-TombstoneQuotaFactor: 100
+systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+
+dn: CN=Program Data,${DOMAINDN}
+objectClass: top
+objectClass: container
+description: Default location for storage of application data.
+
+dn: CN=Microsoft,CN=Program Data,${DOMAINDN}
+objectClass: top
+objectClass: container
+description: Default location for storage of Microsoft application data.
+
dn: CN=System,${DOMAINDN}
objectClass: top
objectClass: container
-cn: System
description: Builtin system settings
systemFlags: -1946157056
isCriticalSystemObject: TRUE
-dn: CN=RID Manager$,CN=System,${DOMAINDN}
-objectclass: top
-objectclass: rIDManager
-cn: RID Manager$
+dn: CN=AdminSDHolder,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: container
systemFlags: -1946157056
isCriticalSystemObject: TRUE
-fSMORoleOwner: CN=NTDS Settings,${SERVERDN}
-rIDAvailablePool: 4611686014132423217
+
+dn: CN=ComPartitions,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: container
+systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+
+dn: CN=ComPartitionSets,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: container
+systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+
+dn: CN=Default Domain Policy,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: leaf
+objectClass: domainPolicy
+isCriticalSystemObject: TRUE
+
+dn: CN=AppCategories,CN=Default Domain Policy,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: classStore
+isCriticalSystemObject: TRUE
+
+dn: CN=Dfs-Configuration,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: dfsConfiguration
+isCriticalSystemObject: TRUE
+showInAdvancedViewOnly: FALSE
dn: CN=DomainUpdates,CN=System,${DOMAINDN}
objectClass: top
objectClass: container
-cn: DomainUpdates
+
+dn: CN=Operations,CN=DomainUpdates,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: container
dn: CN=Windows2003Update,CN=DomainUpdates,CN=System,${DOMAINDN}
objectClass: top
objectClass: container
-cn: Windows2003Update
revision: 8
-dn: CN=Infrastructure,${DOMAINDN}
-objectclass: top
-objectclass: infrastructureUpdate
-cn: Infrastructure
+dn: CN=File Replication Service,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: applicationSettings
+objectClass: nTFRSSettings
systemFlags: -1946157056
isCriticalSystemObject: TRUE
-fSMORoleOwner: CN=NTDS Settings,${SERVERDN}
-dn: CN=Builtin,${DOMAINDN}
+dn: CN=FileLinks,CN=System,${DOMAINDN}
objectClass: top
-objectClass: builtinDomain
-cn: Builtin
-forceLogoff: -9223372036854775808
-lockoutDuration: -18000000000
-lockOutObservationWindow: -18000000000
-lockoutThreshold: 0
-maxPwdAge: -37108517437440
-minPwdAge: 0
-minPwdLength: 0
-modifiedCountAtLastProm: 0
-nextRid: 1000
-pwdProperties: 0
-pwdHistoryLength: 0
-objectSid: S-1-5-32
-serverState: 1
-uASCompat: 1
-modifiedCount: 1
+objectClass: fileLinkTracking
+systemFlags: -1946157056
isCriticalSystemObject: TRUE
-showInAdvancedViewOnly: FALSE
+
+dn: CN=ObjectMoveTable,CN=FileLinks,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: fileLinkTracking
+objectClass: linkTrackObjectMoveTable
+systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+
+dn: CN=VolumeTable,CN=FileLinks,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: fileLinkTracking
+objectClass: linkTrackVolumeTable
systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+
+dn: CN=IP Security,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: container
+isCriticalSystemObject: TRUE
+
+dn: CN=Meetings,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: container
+isCriticalSystemObject: TRUE
dn: CN=Policies,CN=System,${DOMAINDN}
objectClass: top
objectClass: container
systemFlags: -1946157056
+isCriticalSystemObject: TRUE
-dn: CN=IP Security,CN=System,${DOMAINDN}
+dn: CN=RAS and IAS Servers Access Check,CN=System,${DOMAINDN}
objectClass: top
objectClass: container
+systemFlags: -1946157056
+isCriticalSystemObject: TRUE
-dn: CN=ComPartitionSets,CN=System,${DOMAINDN}
+dn: CN=RID Manager$,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: rIDManager
+systemFlags: -1946157056
+fSMORoleOwner: CN=NTDS Settings,${SERVERDN}
+rIDAvailablePool: 4611686014132423217
+isCriticalSystemObject: TRUE
+
+dn: CN=RpcServices,CN=System,${DOMAINDN}
objectClass: top
objectClass: container
+objectClass: rpcContainer
systemFlags: -1946157056
+isCriticalSystemObject: TRUE
+
+dn: CN=Server,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: securityObject
+objectClass: samServer
+systemFlags: -1946157056
+revision: 65543
+isCriticalSystemObject: TRUE
+dn: CN=WinsockServices,CN=System,${DOMAINDN}
+objectClass: top
+objectClass: container
+isCriticalSystemObject: TRUE
diff --git a/source4/setup/provision_basedn_modify.ldif b/source4/setup/provision_basedn_modify.ldif
index a7f3ce985c..29ba75be98 100644
--- a/source4/setup/provision_basedn_modify.ldif
+++ b/source4/setup/provision_basedn_modify.ldif
@@ -47,10 +47,10 @@ replace: serverState
serverState: 1
-
replace: nTMixedDomain
-nTMixedDomain: 1
+nTMixedDomain: 0
-
replace: msDS-Behavior-Version
-msDS-Behavior-Version: 0
+msDS-Behavior-Version: ${DOMAIN_FUNCTIONALITY}
-
replace: ridManagerReference
ridManagerReference: CN=RID Manager$,CN=System,${DOMAINDN}
@@ -67,9 +67,6 @@ fSMORoleOwner: CN=NTDS Settings,${SERVERDN}
replace: systemFlags
systemFlags: -1946157056
-
-replace: isCriticalSystemObject
-isCriticalSystemObject: TRUE
--
replace: subRefs
subRefs: ${CONFIGDN}
-
@@ -84,4 +81,7 @@ wellKnownObjects: B:32:a361b2ffffd211d1aa4b00c04fd7d83a:OU=Domain Controllers,${
wellKnownObjects: B:32:aa312825768811d1aded00c04fd8d5cd:CN=Computers,${DOMAINDN}
wellKnownObjects: B:32:a9d1ca15768811d1aded00c04fd8d5cd:CN=Users,${DOMAINDN}
-
+replace: isCriticalSystemObject
+isCriticalSystemObject: TRUE
+-
${DOMAINGUID_MOD}
diff --git a/source4/setup/provision_computers_modify.ldif b/source4/setup/provision_computers_modify.ldif
index 110c44c356..b3d9dc1fa8 100644
--- a/source4/setup/provision_computers_modify.ldif
+++ b/source4/setup/provision_computers_modify.ldif
@@ -3,11 +3,11 @@ changetype: modify
replace: description
description: Default container for upgraded computer accounts
-
-replace: showInAdvancedViewOnly
-showInAdvancedViewOnly: FALSE
--
replace: systemFlags
systemFlags: -1946157056
-
replace: isCriticalSystemObject
isCriticalSystemObject: TRUE
+-
+replace: showInAdvancedViewOnly
+showInAdvancedViewOnly: FALSE
diff --git a/source4/setup/provision_configuration.ldif b/source4/setup/provision_configuration.ldif
index e84ac8517e..4109c2236c 100644
--- a/source4/setup/provision_configuration.ldif
+++ b/source4/setup/provision_configuration.ldif
@@ -6,8 +6,9 @@ objectClass: top
objectClass: crossRefContainer
cn: Partitions
systemFlags: -2147483648
-msDS-Behavior-Version: 0
+msDS-Behavior-Version: ${FOREST_FUNCTIONALALITY}
fSMORoleOwner: CN=NTDS Settings,${SERVERDN}
+showInAdvancedViewOnly: TRUE
dn: CN=Enterprise Configuration,CN=Partitions,${CONFIGDN}
objectClass: top
diff --git a/source4/setup/provision_group_policy.ldif b/source4/setup/provision_group_policy.ldif
index d6a4659250..65ab1eaf5f 100644
--- a/source4/setup/provision_group_policy.ldif
+++ b/source4/setup/provision_group_policy.ldif
@@ -1,14 +1,3 @@
-dn: CN=Default Domain Policy,CN=System,${DOMAINDN}
-objectClass: top
-objectClass: leaf
-objectClass: domainPolicy
-isCriticalSystemObject: TRUE
-
-dn: CN=AppCategories,CN=Default Domain Policy,CN=System,${DOMAINDN}
-objectClass: top
-objectClass: classStore
-isCriticalSystemObject: TRUE
-
dn: CN={${POLICYGUID}},CN=Policies,CN=System,${DOMAINDN}
objectClass: top
objectClass: container
diff --git a/source4/setup/provision_rootdse_add.ldif b/source4/setup/provision_rootdse_add.ldif
index e4e4309a90..f9ee4e5904 100644
--- a/source4/setup/provision_rootdse_add.ldif
+++ b/source4/setup/provision_rootdse_add.ldif
@@ -11,9 +11,6 @@ supportedLDAPVersion: 2
dnsHostName: ${DNSNAME}
ldapServiceName: ${DNSDOMAIN}:${NETBIOSNAME}$@${REALM}
serverName: ${SERVERDN}
-domainFunctionality: 0
-forestFunctionality: 0
-domainControllerFunctionality: 2
isSynchronized: FALSE
vendorName: Samba Team (http://samba.org)
supportedCapabilities: 1.2.840.113556.1.4.800
diff --git a/source4/setup/provision_self_join.ldif b/source4/setup/provision_self_join.ldif
index b7ca872319..da8c5b9e1d 100644
--- a/source4/setup/provision_self_join.ldif
+++ b/source4/setup/provision_self_join.ldif
@@ -13,9 +13,8 @@ primaryGroupID: 516
accountExpires: 9223372036854775807
sAMAccountName: ${NETBIOSNAME}$
operatingSystem: Samba
-operatingSystemVersion: 4.0
+operatingSystemVersion: ${SAMBA_VERSION_STRING}
dNSHostName: ${DNSNAME}
-isCriticalSystemObject: TRUE
userPassword:: ${MACHINEPASS_B64}
servicePrincipalName: HOST/${DNSNAME}
servicePrincipalName: HOST/${NETBIOSNAME}
@@ -23,6 +22,7 @@ servicePrincipalName: HOST/${DNSNAME}/${REALM}
servicePrincipalName: HOST/${NETBIOSNAME}/${REALM}
servicePrincipalName: HOST/${DNSNAME}/${DOMAIN}
servicePrincipalName: HOST/${NETBIOSNAME}/${DOMAIN}
+isCriticalSystemObject: TRUE
#Provide a account for DNS keytab export
dn: CN=dns,CN=Users,${DOMAINDN}
@@ -36,9 +36,8 @@ userAccountControl: 514
accountExpires: 9223372036854775807
sAMAccountName: dns
servicePrincipalName: DNS/${DNSDOMAIN}
-isCriticalSystemObject: TRUE
userPassword:: ${DNSPASS_B64}
-showInAdvancedViewOnly: TRUE
+isCriticalSystemObject: TRUE
dn: ${SERVERDN}
objectClass: top
@@ -57,7 +56,7 @@ options: 1
systemFlags: 33554432
dMDLocation: ${SCHEMADN}
invocationId: ${INVOCATIONID}
-msDS-Behavior-Version: 2
+msDS-Behavior-Version: ${DOMAIN_CONTROLLER_FUNCTIONALITY}
msDS-hasMasterNCs: ${CONFIGDN}
msDS-hasMasterNCs: ${SCHEMADN}
msDS-hasMasterNCs: ${DOMAINDN}
diff --git a/source4/setup/provision_users.ldif b/source4/setup/provision_users.ldif
index 88146d8cac..47240a9d07 100644
--- a/source4/setup/provision_users.ldif
+++ b/source4/setup/provision_users.ldif
@@ -7,8 +7,8 @@ objectSid: ${DOMAINSID}-500
adminCount: 1
accountExpires: 9223372036854775807
sAMAccountName: Administrator
-isCriticalSystemObject: TRUE
userPassword:: ${ADMINPASS_B64}
+isCriticalSystemObject: TRUE
dn: CN=Guest,CN=Users,${DOMAINDN}
objectClass: user
@@ -45,8 +45,8 @@ adminCount: 1
accountExpires: 9223372036854775807
sAMAccountName: krbtgt
servicePrincipalName: kadmin/changepw
-isCriticalSystemObject: TRUE
userPassword:: ${KRBTGTPASS_B64}
+isCriticalSystemObject: TRUE
dn: CN=Domain Computers,CN=Users,${DOMAINDN}
objectClass: top
@@ -187,16 +187,6 @@ sAMAccountName: Event Log Readers
groupType: -2147483644
isCriticalSystemObject: TRUE
-dn: CN=IIS_IUSRS,CN=Users,${DOMAINDN}
-objectClass: top
-objectClass: group
-cn: IIS_IUSRS
-description: IIS_IUSRS
-objectSid: ${DOMAINSID}-568
-sAMAccountName: IIS_IUSRS
-groupType: -2147483644
-isCriticalSystemObject: TRUE
-
dn: CN=Administrators,CN=Builtin,${DOMAINDN}
objectClass: top
objectClass: group
@@ -210,7 +200,6 @@ adminCount: 1
sAMAccountName: Administrators
systemFlags: -1946157056
groupType: -2147483643
-isCriticalSystemObject: TRUE
privilege: SeSecurityPrivilege
privilege: SeBackupPrivilege
privilege: SeRestorePrivilege
@@ -235,6 +224,7 @@ privilege: SeEnableDelegationPrivilege
privilege: SeInteractiveLogonRight
privilege: SeNetworkLogonRight
privilege: SeRemoteInteractiveLogonRight
+isCriticalSystemObject: TRUE
dn: CN=Users,CN=Builtin,${DOMAINDN}
objectClass: top
@@ -271,10 +261,10 @@ adminCount: 1
sAMAccountName: Print Operators
systemFlags: -1946157056
groupType: -2147483643
-isCriticalSystemObject: TRUE
privilege: SeLoadDriverPrivilege
privilege: SeShutdownPrivilege
privilege: SeInteractiveLogonRight
+isCriticalSystemObject: TRUE
dn: CN=Backup Operators,CN=Builtin,${DOMAINDN}
objectClass: top
@@ -286,11 +276,11 @@ adminCount: 1
sAMAccountName: Backup Operators
systemFlags: -1946157056
groupType: -2147483643
-isCriticalSystemObject: TRUE
privilege: SeBackupPrivilege
privilege: SeRestorePrivilege
privilege: SeShutdownPrivilege
privilege: SeInteractiveLogonRight
+isCriticalSystemObject: TRUE
dn: CN=Replicator,CN=Builtin,${DOMAINDN}
objectClass: top
@@ -358,13 +348,13 @@ adminCount: 1
sAMAccountName: Server Operators
systemFlags: -1946157056
groupType: -2147483643
-isCriticalSystemObject: TRUE
privilege: SeBackupPrivilege
privilege: SeSystemtimePrivilege
privilege: SeRemoteShutdownPrivilege
privilege: SeRestorePrivilege
privilege: SeShutdownPrivilege
privilege: SeInteractiveLogonRight
+isCriticalSystemObject: TRUE
dn: CN=Account Operators,CN=Builtin,${DOMAINDN}
objectClass: top
@@ -376,8 +366,8 @@ adminCount: 1
sAMAccountName: Account Operators
systemFlags: -1946157056
groupType: -2147483643
-isCriticalSystemObject: TRUE
privilege: SeInteractiveLogonRight
+isCriticalSystemObject: TRUE
dn: CN=Pre-Windows 2000 Compatible Access,CN=Builtin,${DOMAINDN}
objectClass: top
@@ -388,9 +378,9 @@ objectSid: S-1-5-32-554
sAMAccountName: Pre-Windows 2000 Compatible Access
systemFlags: -1946157056
groupType: -2147483643
-isCriticalSystemObject: TRUE
privilege: SeRemoteInteractiveLogonRight
privilege: SeChangeNotifyPrivilege
+isCriticalSystemObject: TRUE
dn: CN=Incoming Forest Trust Builders,CN=Builtin,${DOMAINDN}
objectClass: top
diff --git a/source4/setup/provision_users_modify.ldif b/source4/setup/provision_users_modify.ldif
index a7e8a4336a..6a2e180b15 100644
--- a/source4/setup/provision_users_modify.ldif
+++ b/source4/setup/provision_users_modify.ldif
@@ -3,11 +3,11 @@ changetype: modify
replace: description
description: Default container for upgraded user accounts
-
-replace: showInAdvancedViewOnly
-showInAdvancedViewOnly: FALSE
--
replace: systemFlags
systemFlags: -1946157056
-
replace: isCriticalSystemObject
isCriticalSystemObject: TRUE
+-
+replace: showInAdvancedViewOnly
+showInAdvancedViewOnly: FALSE
diff --git a/source4/setup/schema_samba4.ldif b/source4/setup/schema_samba4.ldif
index c11e65e465..591aefbb75 100644
--- a/source4/setup/schema_samba4.ldif
+++ b/source4/setup/schema_samba4.ldif
@@ -220,7 +220,6 @@ objectClass: classSchema
subClassOf: top
governsID: 1.3.6.1.4.1.7165.4.2.2
rDNAttID: cn
-showInAdvancedViewOnly: TRUE
adminDisplayName: Samba4-Local-Domain
adminDescription: Samba4-Local-Domain
systemMayContain: msDS-Behavior-Version
@@ -243,7 +242,6 @@ subClassOf: top
governsID: 1.3.6.1.4.1.7165.4.2.1
mayContain: msDS-ObjectReferenceBL
rDNAttID: cn
-showInAdvancedViewOnly: TRUE
adminDisplayName: Samba4TopTop
adminDescription: Attributes used in top in Samba4 that OpenLDAP does not
objectClassCategory: 3
@@ -344,7 +342,6 @@ objectClass: classSchema
subClassOf: top
governsID: 1.3.6.1.4.1.7165.4.2.3
rDNAttID: cn
-showInAdvancedViewOnly: TRUE
adminDisplayName: Samba4TopExtra
adminDescription: Attributes used in top in Samba4 that OpenLDAP does not
objectClassCategory: 2
diff --git a/source4/torture/auth/pac.c b/source4/torture/auth/pac.c
index fd54863686..076120bfee 100644
--- a/source4/torture/auth/pac.c
+++ b/source4/torture/auth/pac.c
@@ -29,6 +29,7 @@
#include "libcli/security/security.h"
#include "torture/torture.h"
#include "auth/auth_sam_reply.h"
+#include "param/param.h"
static bool torture_pac_self_check(struct torture_context *tctx)
{
diff --git a/source4/torture/rpc/frsapi.c b/source4/torture/rpc/frsapi.c
index c8e421a674..e9a19bcf96 100644
--- a/source4/torture/rpc/frsapi.c
+++ b/source4/torture/rpc/frsapi.c
@@ -114,15 +114,15 @@ static bool test_IsPathReplicated_err(struct torture_context *tctx,
{
struct frsapi_IsPathReplicated r;
struct GUID guid;
- uint32_t unknown1, unknown2, unknown3 = 0;
+ uint32_t replicated, primary, root;
ZERO_STRUCT(r);
r.in.path = path;
r.in.replica_set_type = type;
- r.out.unknown1 = &unknown1;
- r.out.unknown2 = &unknown2;
- r.out.unknown3 = &unknown3;
+ r.out.replicated = &replicated;
+ r.out.primary = &primary;
+ r.out.root = &root;
r.out.replica_set_guid = &guid;
torture_assert_ntstatus_ok(tctx,
@@ -191,11 +191,11 @@ static bool test_ForceReplication(struct torture_context *tctx,
ZERO_STRUCT(r);
- r.in.guid1 = NULL;
- r.in.guid2 = NULL;
- r.in.replica_set = talloc_asprintf(tctx, "%s",
- lp_realm(tctx->lp_ctx));
- r.in.partner_name = dcerpc_server_name(p);
+ r.in.replica_set_guid = NULL;
+ r.in.connection_guid = NULL;
+ r.in.replica_set_name = talloc_asprintf(tctx, "%s",
+ lp_realm(tctx->lp_ctx));
+ r.in.partner_dns_name = dcerpc_server_name(p);
torture_assert_ntstatus_ok(tctx,
dcerpc_frsapi_ForceReplication(p, tctx, &r),
diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c
index 7d03e7ef9e..b45b565452 100644
--- a/source4/torture/rpc/lsa.c
+++ b/source4/torture/rpc/lsa.c
@@ -47,7 +47,7 @@ static bool test_OpenPolicy(struct dcerpc_pipe *p,
NTSTATUS status;
uint16_t system_name = '\\';
- printf("\nTesting OpenPolicy\n");
+ torture_comment(tctx, "\nTesting OpenPolicy\n");
qos.len = 0;
qos.impersonation_level = 2;
@@ -70,10 +70,10 @@ static bool test_OpenPolicy(struct dcerpc_pipe *p,
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
- printf("not considering %s to be an error\n", nt_errstr(status));
+ torture_comment(tctx, "not considering %s to be an error\n", nt_errstr(status));
return true;
}
- printf("OpenPolicy failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "OpenPolicy failed - %s\n", nt_errstr(status));
return false;
}
@@ -90,7 +90,7 @@ bool test_lsa_OpenPolicy2(struct dcerpc_pipe *p,
struct lsa_OpenPolicy2 r;
NTSTATUS status;
- printf("\nTesting OpenPolicy2\n");
+ torture_comment(tctx, "\nTesting OpenPolicy2\n");
*handle = talloc(tctx, struct policy_handle);
if (!*handle) {
@@ -118,12 +118,12 @@ bool test_lsa_OpenPolicy2(struct dcerpc_pipe *p,
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
- printf("not considering %s to be an error\n", nt_errstr(status));
+ torture_comment(tctx, "not considering %s to be an error\n", nt_errstr(status));
talloc_free(*handle);
*handle = NULL;
return true;
}
- printf("OpenPolicy2 failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "OpenPolicy2 failed - %s\n", nt_errstr(status));
return false;
}
@@ -161,7 +161,7 @@ static bool test_LookupNames(struct dcerpc_pipe *p,
NTSTATUS status;
int i;
- printf("\nTesting LookupNames with %d names\n", tnames->count);
+ torture_comment(tctx, "\nTesting LookupNames with %d names\n", tnames->count);
sids.count = 0;
sids.sids = NULL;
@@ -187,30 +187,30 @@ static bool test_LookupNames(struct dcerpc_pipe *p,
NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
for (i=0;i< tnames->count;i++) {
if (i < count && sids.sids[i].sid_type == SID_NAME_UNKNOWN) {
- printf("LookupName of %s was unmapped\n",
+ torture_comment(tctx, "LookupName of %s was unmapped\n",
tnames->names[i].name.string);
} else if (i >=count) {
- printf("LookupName of %s failed to return a result\n",
+ torture_comment(tctx, "LookupName of %s failed to return a result\n",
tnames->names[i].name.string);
}
}
- printf("LookupNames failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "LookupNames failed - %s\n", nt_errstr(status));
return false;
} else if (!NT_STATUS_IS_OK(status)) {
- printf("LookupNames failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "LookupNames failed - %s\n", nt_errstr(status));
return false;
}
for (i=0;i< tnames->count;i++) {
if (i < count && sids.sids[i].sid_type != tnames->names[i].sid_type) {
- printf("LookupName of %s got unexpected name type: %s\n",
+ torture_comment(tctx, "LookupName of %s got unexpected name type: %s\n",
tnames->names[i].name.string, sid_type_lookup(sids.sids[i].sid_type));
} else if (i >=count) {
- printf("LookupName of %s failed to return a result\n",
+ torture_comment(tctx, "LookupName of %s failed to return a result\n",
tnames->names[i].name.string);
}
}
- printf("\n");
+ torture_comment(tctx, "\n");
return true;
}
@@ -235,7 +235,7 @@ static bool test_LookupNames_bogus(struct dcerpc_pipe *p,
name[0].name.string = "NT AUTHORITY\\BOGUS";
name[1].name.string = NULL;
- printf("\nTesting LookupNames with bogus names\n");
+ torture_comment(tctx, "\nTesting LookupNames with bogus names\n");
sids.count = 0;
sids.sids = NULL;
@@ -257,11 +257,11 @@ static bool test_LookupNames_bogus(struct dcerpc_pipe *p,
status = dcerpc_lsa_LookupNames(p, tctx, &r);
if (!NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
- printf("LookupNames failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "LookupNames failed - %s\n", nt_errstr(status));
return false;
}
- printf("\n");
+ torture_comment(tctx, "\n");
return true;
}
@@ -274,7 +274,7 @@ static bool test_LookupNames_wellknown(struct dcerpc_pipe *p,
struct lsa_TransNameArray tnames;
bool ret = true;
- printf("Testing LookupNames with well known names\n");
+ torture_comment(tctx, "Testing LookupNames with well known names\n");
tnames.names = &name;
tnames.count = 1;
@@ -330,7 +330,7 @@ static bool test_LookupNames2(struct dcerpc_pipe *p,
NTSTATUS status;
int i;
- printf("\nTesting LookupNames2 with %d names\n", tnames->count);
+ torture_comment(tctx, "\nTesting LookupNames2 with %d names\n", tnames->count);
sids.count = 0;
sids.sids = NULL;
@@ -354,7 +354,7 @@ static bool test_LookupNames2(struct dcerpc_pipe *p,
status = dcerpc_lsa_LookupNames2(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("LookupNames2 failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "LookupNames2 failed - %s\n", nt_errstr(status));
return false;
}
@@ -366,7 +366,7 @@ static bool test_LookupNames2(struct dcerpc_pipe *p,
}
}
- printf("\n");
+ torture_comment(tctx, "\n");
return true;
}
@@ -386,7 +386,7 @@ static bool test_LookupNames3(struct dcerpc_pipe *p,
NTSTATUS status;
int i;
- printf("\nTesting LookupNames3 with %d names\n", tnames->count);
+ torture_comment(tctx, "\nTesting LookupNames3 with %d names\n", tnames->count);
sids.count = 0;
sids.sids = NULL;
@@ -410,7 +410,7 @@ static bool test_LookupNames3(struct dcerpc_pipe *p,
status = dcerpc_lsa_LookupNames3(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("LookupNames3 failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "LookupNames3 failed - %s\n", nt_errstr(status));
return false;
}
@@ -422,7 +422,7 @@ static bool test_LookupNames3(struct dcerpc_pipe *p,
}
}
- printf("\n");
+ torture_comment(tctx, "\n");
return true;
}
@@ -440,7 +440,7 @@ static bool test_LookupNames4(struct dcerpc_pipe *p,
NTSTATUS status;
int i;
- printf("\nTesting LookupNames4 with %d names\n", tnames->count);
+ torture_comment(tctx, "\nTesting LookupNames4 with %d names\n", tnames->count);
sids.count = 0;
sids.sids = NULL;
@@ -463,7 +463,7 @@ static bool test_LookupNames4(struct dcerpc_pipe *p,
status = dcerpc_lsa_LookupNames4(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("LookupNames4 failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "LookupNames4 failed - %s\n", nt_errstr(status));
return false;
}
@@ -475,7 +475,7 @@ static bool test_LookupNames4(struct dcerpc_pipe *p,
}
}
- printf("\n");
+ torture_comment(tctx, "\n");
return true;
}
@@ -492,7 +492,7 @@ static bool test_LookupSids(struct dcerpc_pipe *p,
uint32_t count = sids->num_sids;
NTSTATUS status;
- printf("\nTesting LookupSids\n");
+ torture_comment(tctx, "\nTesting LookupSids\n");
names.count = 0;
names.names = NULL;
@@ -508,11 +508,11 @@ static bool test_LookupSids(struct dcerpc_pipe *p,
status = dcerpc_lsa_LookupSids(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("LookupSids failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "LookupSids failed - %s\n", nt_errstr(status));
return false;
}
- printf("\n");
+ torture_comment(tctx, "\n");
if (!test_LookupNames(p, tctx, handle, &names)) {
return false;
@@ -533,7 +533,7 @@ static bool test_LookupSids2(struct dcerpc_pipe *p,
uint32_t count = sids->num_sids;
NTSTATUS status;
- printf("\nTesting LookupSids2\n");
+ torture_comment(tctx, "\nTesting LookupSids2\n");
names.count = 0;
names.names = NULL;
@@ -551,11 +551,11 @@ static bool test_LookupSids2(struct dcerpc_pipe *p,
status = dcerpc_lsa_LookupSids2(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("LookupSids2 failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "LookupSids2 failed - %s\n", nt_errstr(status));
return false;
}
- printf("\n");
+ torture_comment(tctx, "\n");
if (!test_LookupNames2(p, tctx, handle, &names, false)) {
return false;
@@ -578,7 +578,7 @@ static bool test_LookupSids3(struct dcerpc_pipe *p,
uint32_t count = sids->num_sids;
NTSTATUS status;
- printf("\nTesting LookupSids3\n");
+ torture_comment(tctx, "\nTesting LookupSids3\n");
names.count = 0;
names.names = NULL;
@@ -597,15 +597,15 @@ static bool test_LookupSids3(struct dcerpc_pipe *p,
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
- printf("not considering %s to be an error\n", nt_errstr(status));
+ torture_comment(tctx, "not considering %s to be an error\n", nt_errstr(status));
return true;
}
- printf("LookupSids3 failed - %s - not considered an error\n",
+ torture_comment(tctx, "LookupSids3 failed - %s - not considered an error\n",
nt_errstr(status));
return false;
}
- printf("\n");
+ torture_comment(tctx, "\n");
if (!test_LookupNames4(p, tctx, &names, false)) {
return false;
@@ -623,7 +623,7 @@ bool test_many_LookupSids(struct dcerpc_pipe *p,
struct lsa_SidArray sids;
int i;
- printf("\nTesting LookupSids with lots of SIDs\n");
+ torture_comment(tctx, "\nTesting LookupSids with lots of SIDs\n");
sids.num_sids = 100;
@@ -654,11 +654,11 @@ bool test_many_LookupSids(struct dcerpc_pipe *p,
status = dcerpc_lsa_LookupSids(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("LookupSids failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "LookupSids failed - %s\n", nt_errstr(status));
return false;
}
- printf("\n");
+ torture_comment(tctx, "\n");
if (!test_LookupNames(p, tctx, handle, &names)) {
return false;
@@ -672,7 +672,7 @@ bool test_many_LookupSids(struct dcerpc_pipe *p,
names.count = 0;
names.names = NULL;
- printf("\nTesting LookupSids3\n");
+ torture_comment(tctx, "\nTesting LookupSids3\n");
r.in.sids = &sids;
r.in.names = &names;
@@ -688,10 +688,10 @@ bool test_many_LookupSids(struct dcerpc_pipe *p,
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED)) {
- printf("not considering %s to be an error\n", nt_errstr(status));
+ torture_comment(tctx, "not considering %s to be an error\n", nt_errstr(status));
return true;
}
- printf("LookupSids3 failed - %s\n",
+ torture_comment(tctx, "LookupSids3 failed - %s\n",
nt_errstr(status));
return false;
}
@@ -700,7 +700,7 @@ bool test_many_LookupSids(struct dcerpc_pipe *p,
}
}
- printf("\n");
+ torture_comment(tctx, "\n");
@@ -742,7 +742,7 @@ static bool test_LookupSids_async(struct dcerpc_pipe *p,
names = talloc_array(tctx, struct lsa_TransNameArray, num_async_requests);
r = talloc_array(tctx, struct lsa_LookupSids, num_async_requests);
- printf("\nTesting %d async lookupsids request\n", num_async_requests);
+ torture_comment(tctx, "\nTesting %d async lookupsids request\n", num_async_requests);
req = talloc_array(tctx, struct rpc_request *, num_async_requests);
@@ -804,7 +804,7 @@ static bool test_LookupPrivValue(struct dcerpc_pipe *p,
status = dcerpc_lsa_LookupPrivValue(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("\nLookupPrivValue failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "\nLookupPrivValue failed - %s\n", nt_errstr(status));
return false;
}
@@ -826,7 +826,7 @@ static bool test_LookupPrivName(struct dcerpc_pipe *p,
status = dcerpc_lsa_LookupPrivName(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("\nLookupPrivName failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "\nLookupPrivName failed - %s\n", nt_errstr(status));
return false;
}
@@ -844,7 +844,7 @@ static bool test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p,
struct lsa_PrivilegeSet privs;
bool ret = true;
- printf("\nTesting RemovePrivilegesFromAccount\n");
+ torture_comment(tctx, "\nTesting RemovePrivilegesFromAccount\n");
r.in.handle = acct_handle;
r.in.remove_all = 0;
@@ -868,7 +868,7 @@ static bool test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p,
status = dcerpc_lsa_LookupPrivName(p, tctx, &r_name);
if (!NT_STATUS_IS_OK(status)) {
- printf("\nLookupPrivName failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "\nLookupPrivName failed - %s\n", nt_errstr(status));
return false;
}
/* Windows 2008 does not allow this to be removed */
@@ -876,7 +876,7 @@ static bool test_RemovePrivilegesFromAccount(struct dcerpc_pipe *p,
return ret;
}
- printf("RemovePrivilegesFromAccount failed to remove %s - %s\n",
+ torture_comment(tctx, "RemovePrivilegesFromAccount failed to remove %s - %s\n",
name->string,
nt_errstr(status));
return false;
@@ -895,7 +895,7 @@ static bool test_AddPrivilegesToAccount(struct dcerpc_pipe *p,
struct lsa_PrivilegeSet privs;
bool ret = true;
- printf("\nTesting AddPrivilegesToAccount\n");
+ torture_comment(tctx, "\nTesting AddPrivilegesToAccount\n");
r.in.handle = acct_handle;
r.in.privs = &privs;
@@ -908,7 +908,7 @@ static bool test_AddPrivilegesToAccount(struct dcerpc_pipe *p,
status = dcerpc_lsa_AddPrivilegesToAccount(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("AddPrivilegesToAccount failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "AddPrivilegesToAccount failed - %s\n", nt_errstr(status));
return false;
}
@@ -925,14 +925,14 @@ static bool test_EnumPrivsAccount(struct dcerpc_pipe *p,
struct lsa_PrivilegeSet *privs = NULL;
bool ret = true;
- printf("\nTesting EnumPrivsAccount\n");
+ torture_comment(tctx, "\nTesting EnumPrivsAccount\n");
r.in.handle = acct_handle;
r.out.privs = &privs;
status = dcerpc_lsa_EnumPrivsAccount(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("EnumPrivsAccount failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "EnumPrivsAccount failed - %s\n", nt_errstr(status));
return false;
}
@@ -961,46 +961,46 @@ static bool test_GetSystemAccessAccount(struct dcerpc_pipe *p,
uint32_t access_mask;
struct lsa_GetSystemAccessAccount r;
- printf("\nTesting GetSystemAccessAccount\n");
+ torture_comment(tctx, "\nTesting GetSystemAccessAccount\n");
r.in.handle = acct_handle;
r.out.access_mask = &access_mask;
status = dcerpc_lsa_GetSystemAccessAccount(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("GetSystemAccessAccount failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "GetSystemAccessAccount failed - %s\n", nt_errstr(status));
return false;
}
if (r.out.access_mask != NULL) {
- printf("Rights:");
+ torture_comment(tctx, "Rights:");
if (*(r.out.access_mask) & LSA_POLICY_MODE_INTERACTIVE)
- printf(" LSA_POLICY_MODE_INTERACTIVE");
+ torture_comment(tctx, " LSA_POLICY_MODE_INTERACTIVE");
if (*(r.out.access_mask) & LSA_POLICY_MODE_NETWORK)
- printf(" LSA_POLICY_MODE_NETWORK");
+ torture_comment(tctx, " LSA_POLICY_MODE_NETWORK");
if (*(r.out.access_mask) & LSA_POLICY_MODE_BATCH)
- printf(" LSA_POLICY_MODE_BATCH");
+ torture_comment(tctx, " LSA_POLICY_MODE_BATCH");
if (*(r.out.access_mask) & LSA_POLICY_MODE_SERVICE)
- printf(" LSA_POLICY_MODE_SERVICE");
+ torture_comment(tctx, " LSA_POLICY_MODE_SERVICE");
if (*(r.out.access_mask) & LSA_POLICY_MODE_PROXY)
- printf(" LSA_POLICY_MODE_PROXY");
+ torture_comment(tctx, " LSA_POLICY_MODE_PROXY");
if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_INTERACTIVE)
- printf(" LSA_POLICY_MODE_DENY_INTERACTIVE");
+ torture_comment(tctx, " LSA_POLICY_MODE_DENY_INTERACTIVE");
if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_NETWORK)
- printf(" LSA_POLICY_MODE_DENY_NETWORK");
+ torture_comment(tctx, " LSA_POLICY_MODE_DENY_NETWORK");
if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_BATCH)
- printf(" LSA_POLICY_MODE_DENY_BATCH");
+ torture_comment(tctx, " LSA_POLICY_MODE_DENY_BATCH");
if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_SERVICE)
- printf(" LSA_POLICY_MODE_DENY_SERVICE");
+ torture_comment(tctx, " LSA_POLICY_MODE_DENY_SERVICE");
if (*(r.out.access_mask) & LSA_POLICY_MODE_REMOTE_INTERACTIVE)
- printf(" LSA_POLICY_MODE_REMOTE_INTERACTIVE");
+ torture_comment(tctx, " LSA_POLICY_MODE_REMOTE_INTERACTIVE");
if (*(r.out.access_mask) & LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE)
- printf(" LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE");
+ torture_comment(tctx, " LSA_POLICY_MODE_DENY_REMOTE_INTERACTIVE");
if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL)
- printf(" LSA_POLICY_MODE_ALL");
+ torture_comment(tctx, " LSA_POLICY_MODE_ALL");
if (*(r.out.access_mask) & LSA_POLICY_MODE_ALL_NT4)
- printf(" LSA_POLICY_MODE_ALL_NT4");
- printf("\n");
+ torture_comment(tctx, " LSA_POLICY_MODE_ALL_NT4");
+ torture_comment(tctx, "\n");
}
return true;
@@ -1013,12 +1013,12 @@ static bool test_Delete(struct dcerpc_pipe *p,
NTSTATUS status;
struct lsa_Delete r;
- printf("\nTesting Delete\n");
+ torture_comment(tctx, "\nTesting Delete\n");
r.in.handle = handle;
status = dcerpc_lsa_Delete(p, tctx, &r);
if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
- printf("Delete should have failed NT_STATUS_NOT_SUPPORTED - %s\n", nt_errstr(status));
+ torture_comment(tctx, "Delete should have failed NT_STATUS_NOT_SUPPORTED - %s\n", nt_errstr(status));
return false;
}
@@ -1032,13 +1032,13 @@ static bool test_DeleteObject(struct dcerpc_pipe *p,
NTSTATUS status;
struct lsa_DeleteObject r;
- printf("\nTesting DeleteObject\n");
+ torture_comment(tctx, "\nTesting DeleteObject\n");
r.in.handle = handle;
r.out.handle = handle;
status = dcerpc_lsa_DeleteObject(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("DeleteObject failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "DeleteObject failed - %s\n", nt_errstr(status));
return false;
}
@@ -1057,7 +1057,7 @@ static bool test_CreateAccount(struct dcerpc_pipe *p,
newsid = dom_sid_parse_talloc(tctx, "S-1-5-12349876-4321-2854");
- printf("\nTesting CreateAccount\n");
+ torture_comment(tctx, "\nTesting CreateAccount\n");
r.in.handle = handle;
r.in.sid = newsid;
@@ -1074,11 +1074,11 @@ static bool test_CreateAccount(struct dcerpc_pipe *p,
status = dcerpc_lsa_OpenAccount(p, tctx, &r_o);
if (!NT_STATUS_IS_OK(status)) {
- printf("OpenAccount failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "OpenAccount failed - %s\n", nt_errstr(status));
return false;
}
} else if (!NT_STATUS_IS_OK(status)) {
- printf("CreateAccount failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "CreateAccount failed - %s\n", nt_errstr(status));
return false;
}
@@ -1109,7 +1109,7 @@ static bool test_DeleteTrustedDomain(struct dcerpc_pipe *p,
status = dcerpc_lsa_OpenTrustedDomainByName(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
return false;
}
@@ -1137,7 +1137,7 @@ static bool test_DeleteTrustedDomainBySid(struct dcerpc_pipe *p,
status = dcerpc_lsa_DeleteTrustedDomain(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("DeleteTrustedDomain failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "DeleteTrustedDomain failed - %s\n", nt_errstr(status));
return false;
}
@@ -1183,7 +1183,7 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
secname[GLOBAL] = talloc_asprintf(tctx, "G$torturesecret-%u", (uint_t)random());
for (i=0; i< 2; i++) {
- printf("\nTesting CreateSecret of %s\n", secname[i]);
+ torture_comment(tctx, "\nTesting CreateSecret of %s\n", secname[i]);
init_lsa_String(&r.in.name, secname[i]);
@@ -1193,7 +1193,7 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
status = dcerpc_lsa_CreateSecret(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("CreateSecret failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "CreateSecret failed - %s\n", nt_errstr(status));
return false;
}
@@ -1203,7 +1203,7 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
status = dcerpc_lsa_CreateSecret(p, tctx, &r);
if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
- printf("CreateSecret should have failed OBJECT_NAME_COLLISION - %s\n", nt_errstr(status));
+ torture_comment(tctx, "CreateSecret should have failed OBJECT_NAME_COLLISION - %s\n", nt_errstr(status));
return false;
}
@@ -1212,17 +1212,17 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
r2.in.name = r.in.name;
r2.out.sec_handle = &sec_handle2;
- printf("Testing OpenSecret\n");
+ torture_comment(tctx, "Testing OpenSecret\n");
status = dcerpc_lsa_OpenSecret(p, tctx, &r2);
if (!NT_STATUS_IS_OK(status)) {
- printf("OpenSecret failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "OpenSecret failed - %s\n", nt_errstr(status));
return false;
}
status = dcerpc_fetch_session_key(p, &session_key);
if (!NT_STATUS_IS_OK(status)) {
- printf("dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
return false;
}
@@ -1235,11 +1235,11 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
r3.in.new_val->length = enc_key.length;
r3.in.new_val->size = enc_key.length;
- printf("Testing SetSecret\n");
+ torture_comment(tctx, "Testing SetSecret\n");
status = dcerpc_lsa_SetSecret(p, tctx, &r3);
if (!NT_STATUS_IS_OK(status)) {
- printf("SetSecret failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(status));
return false;
}
@@ -1253,11 +1253,11 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
/* break the encrypted data */
enc_key.data[0]++;
- printf("Testing SetSecret with broken key\n");
+ torture_comment(tctx, "Testing SetSecret with broken key\n");
status = dcerpc_lsa_SetSecret(p, tctx, &r3);
if (!NT_STATUS_EQUAL(status, NT_STATUS_UNKNOWN_REVISION)) {
- printf("SetSecret should have failed UNKNOWN_REVISION - %s\n", nt_errstr(status));
+ torture_comment(tctx, "SetSecret should have failed UNKNOWN_REVISION - %s\n", nt_errstr(status));
ret = false;
}
@@ -1275,14 +1275,14 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
bufp1.buf = NULL;
- printf("Testing QuerySecret\n");
+ torture_comment(tctx, "Testing QuerySecret\n");
status = dcerpc_lsa_QuerySecret(p, tctx, &r4);
if (!NT_STATUS_IS_OK(status)) {
- printf("QuerySecret failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(status));
ret = false;
} else {
if (r4.out.new_val == NULL || r4.out.new_val->buf == NULL) {
- printf("No secret buffer returned\n");
+ torture_comment(tctx, "No secret buffer returned\n");
ret = false;
} else {
blob1.data = r4.out.new_val->buf->data;
@@ -1294,7 +1294,7 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
&blob1, &session_key);
if (strcmp(secret1, secret2) != 0) {
- printf("Returned secret (r4) '%s' doesn't match '%s'\n",
+ torture_comment(tctx, "Returned secret (r4) '%s' doesn't match '%s'\n",
secret2, secret1);
ret = false;
}
@@ -1312,11 +1312,11 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
msleep(200);
- printf("Testing SetSecret (existing value should move to old)\n");
+ torture_comment(tctx, "Testing SetSecret (existing value should move to old)\n");
status = dcerpc_lsa_SetSecret(p, tctx, &r5);
if (!NT_STATUS_IS_OK(status)) {
- printf("SetSecret failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(status));
ret = false;
}
@@ -1337,14 +1337,14 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
status = dcerpc_lsa_QuerySecret(p, tctx, &r6);
if (!NT_STATUS_IS_OK(status)) {
- printf("QuerySecret failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(status));
ret = false;
secret4 = NULL;
} else {
if (r6.out.new_val->buf == NULL || r6.out.old_val->buf == NULL
|| r6.out.new_mtime == NULL || r6.out.old_mtime == NULL) {
- printf("Both secret buffers and both times not returned\n");
+ torture_comment(tctx, "Both secret buffers and both times not returned\n");
ret = false;
secret4 = NULL;
} else {
@@ -1357,7 +1357,7 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
&blob1, &session_key);
if (strcmp(secret3, secret4) != 0) {
- printf("Returned NEW secret %s doesn't match %s\n", secret4, secret3);
+ torture_comment(tctx, "Returned NEW secret %s doesn't match %s\n", secret4, secret3);
ret = false;
}
@@ -1370,12 +1370,12 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
&blob1, &session_key);
if (strcmp(secret1, secret2) != 0) {
- printf("Returned OLD secret %s doesn't match %s\n", secret2, secret1);
+ torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret2, secret1);
ret = false;
}
if (*r6.out.new_mtime == *r6.out.old_mtime) {
- printf("Returned secret (r6-%d) %s must not have same mtime for both secrets: %s != %s\n",
+ torture_comment(tctx, "Returned secret (r6-%d) %s must not have same mtime for both secrets: %s != %s\n",
i,
secname[i],
nt_time_string(tctx, *r6.out.old_mtime),
@@ -1394,11 +1394,11 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
r7.in.old_val->size = enc_key.length;
r7.in.new_val = NULL;
- printf("Testing SetSecret of old Secret only\n");
+ torture_comment(tctx, "Testing SetSecret of old Secret only\n");
status = dcerpc_lsa_SetSecret(p, tctx, &r7);
if (!NT_STATUS_IS_OK(status)) {
- printf("SetSecret failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "SetSecret failed - %s\n", nt_errstr(status));
ret = false;
}
@@ -1416,20 +1416,20 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
status = dcerpc_lsa_QuerySecret(p, tctx, &r8);
if (!NT_STATUS_IS_OK(status)) {
- printf("QuerySecret failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QuerySecret failed - %s\n", nt_errstr(status));
ret = false;
} else {
if (!r8.out.new_val || !r8.out.old_val) {
- printf("in/out pointers not returned, despite being set on in for QuerySecret\n");
+ torture_comment(tctx, "in/out pointers not returned, despite being set on in for QuerySecret\n");
ret = false;
} else if (r8.out.new_val->buf != NULL) {
- printf("NEW secret buffer must not be returned after OLD set\n");
+ torture_comment(tctx, "NEW secret buffer must not be returned after OLD set\n");
ret = false;
} else if (r8.out.old_val->buf == NULL) {
- printf("OLD secret buffer was not returned after OLD set\n");
+ torture_comment(tctx, "OLD secret buffer was not returned after OLD set\n");
ret = false;
} else if (r8.out.new_mtime == NULL || r8.out.old_mtime == NULL) {
- printf("Both times not returned after OLD set\n");
+ torture_comment(tctx, "Both times not returned after OLD set\n");
ret = false;
} else {
blob1.data = r8.out.old_val->buf->data;
@@ -1441,12 +1441,12 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
&blob1, &session_key);
if (strcmp(secret5, secret6) != 0) {
- printf("Returned OLD secret %s doesn't match %s\n", secret5, secret6);
+ torture_comment(tctx, "Returned OLD secret %s doesn't match %s\n", secret5, secret6);
ret = false;
}
if (*r8.out.new_mtime != *r8.out.old_mtime) {
- printf("Returned secret (r8) %s did not had same mtime for both secrets: %s != %s\n",
+ torture_comment(tctx, "Returned secret (r8) %s did not had same mtime for both secrets: %s != %s\n",
secname[i],
nt_time_string(tctx, *r8.out.old_mtime),
nt_time_string(tctx, *r8.out.new_mtime));
@@ -1467,15 +1467,15 @@ static bool test_CreateSecret(struct dcerpc_pipe *p,
d_o.out.handle = &sec_handle2;
status = dcerpc_lsa_DeleteObject(p, tctx, &d_o);
if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) {
- printf("Second delete expected INVALID_HANDLE - %s\n", nt_errstr(status));
+ torture_comment(tctx, "Second delete expected INVALID_HANDLE - %s\n", nt_errstr(status));
ret = false;
} else {
- printf("Testing OpenSecret of just-deleted secret\n");
+ torture_comment(tctx, "Testing OpenSecret of just-deleted secret\n");
status = dcerpc_lsa_OpenSecret(p, tctx, &r2);
if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
- printf("OpenSecret expected OBJECT_NAME_NOT_FOUND - %s\n", nt_errstr(status));
+ torture_comment(tctx, "OpenSecret expected OBJECT_NAME_NOT_FOUND - %s\n", nt_errstr(status));
ret = false;
}
}
@@ -1495,7 +1495,7 @@ static bool test_EnumAccountRights(struct dcerpc_pipe *p,
struct lsa_EnumAccountRights r;
struct lsa_RightSet rights;
- printf("\nTesting EnumAccountRights\n");
+ torture_comment(tctx, "\nTesting EnumAccountRights\n");
r.in.handle = acct_handle;
r.in.sid = sid;
@@ -1503,7 +1503,7 @@ static bool test_EnumAccountRights(struct dcerpc_pipe *p,
status = dcerpc_lsa_EnumAccountRights(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("EnumAccountRights of %s failed - %s\n",
+ torture_comment(tctx, "EnumAccountRights of %s failed - %s\n",
dom_sid_string(tctx, sid), nt_errstr(status));
return false;
}
@@ -1522,19 +1522,21 @@ static bool test_QuerySecurity(struct dcerpc_pipe *p,
struct sec_desc_buf *sdbuf = NULL;
if (torture_setting_bool(tctx, "samba4", false)) {
- printf("\nskipping QuerySecurity test against Samba4\n");
+ torture_comment(tctx, "\nskipping QuerySecurity test against Samba4\n");
return true;
}
- printf("\nTesting QuerySecurity\n");
+ torture_comment(tctx, "\nTesting QuerySecurity\n");
r.in.handle = acct_handle;
- r.in.sec_info = 7;
+ r.in.sec_info = SECINFO_OWNER |
+ SECINFO_GROUP |
+ SECINFO_DACL;
r.out.sdbuf = &sdbuf;
status = dcerpc_lsa_QuerySecurity(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("QuerySecurity failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QuerySecurity failed - %s\n", nt_errstr(status));
return false;
}
@@ -1550,7 +1552,7 @@ static bool test_OpenAccount(struct dcerpc_pipe *p,
struct lsa_OpenAccount r;
struct policy_handle acct_handle;
- printf("\nTesting OpenAccount\n");
+ torture_comment(tctx, "\nTesting OpenAccount\n");
r.in.handle = handle;
r.in.sid = sid;
@@ -1559,7 +1561,7 @@ static bool test_OpenAccount(struct dcerpc_pipe *p,
status = dcerpc_lsa_OpenAccount(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("OpenAccount failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "OpenAccount failed - %s\n", nt_errstr(status));
return false;
}
@@ -1589,7 +1591,7 @@ static bool test_EnumAccounts(struct dcerpc_pipe *p,
int i;
bool ret = true;
- printf("\nTesting EnumAccounts\n");
+ torture_comment(tctx, "\nTesting EnumAccounts\n");
r.in.handle = handle;
r.in.resume_handle = &resume_handle;
@@ -1604,7 +1606,7 @@ static bool test_EnumAccounts(struct dcerpc_pipe *p,
break;
}
if (!NT_STATUS_IS_OK(status)) {
- printf("EnumAccounts failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "EnumAccounts failed - %s\n", nt_errstr(status));
return false;
}
@@ -1620,31 +1622,31 @@ static bool test_EnumAccounts(struct dcerpc_pipe *p,
* be on schannel, or we would not be able to do the
* rest */
- printf("Testing all accounts\n");
+ torture_comment(tctx, "Testing all accounts\n");
for (i=0;i<sids1.num_sids;i++) {
ret &= test_OpenAccount(p, tctx, handle, sids1.sids[i].sid);
ret &= test_EnumAccountRights(p, tctx, handle, sids1.sids[i].sid);
}
- printf("\n");
+ torture_comment(tctx, "\n");
}
if (sids1.num_sids < 3) {
return ret;
}
- printf("Trying EnumAccounts partial listing (asking for 1 at 2)\n");
+ torture_comment(tctx, "Trying EnumAccounts partial listing (asking for 1 at 2)\n");
resume_handle = 2;
r.in.num_entries = 1;
r.out.sids = &sids2;
status = dcerpc_lsa_EnumAccounts(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("EnumAccounts failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "EnumAccounts failed - %s\n", nt_errstr(status));
return false;
}
if (sids2.num_sids != 1) {
- printf("Returned wrong number of entries (%d)\n", sids2.num_sids);
+ torture_comment(tctx, "Returned wrong number of entries (%d)\n", sids2.num_sids);
return false;
}
@@ -1664,7 +1666,7 @@ static bool test_LookupPrivDisplayName(struct dcerpc_pipe *p,
uint16_t returned_language_id = 0;
struct lsa_StringLarge *disp_name = NULL;
- printf("\nTesting LookupPrivDisplayName(%s)\n", priv_name->string);
+ torture_comment(tctx, "\nTesting LookupPrivDisplayName(%s)\n", priv_name->string);
r.in.handle = handle;
r.in.name = priv_name;
@@ -1675,10 +1677,10 @@ static bool test_LookupPrivDisplayName(struct dcerpc_pipe *p,
status = dcerpc_lsa_LookupPrivDisplayName(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("LookupPrivDisplayName failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "LookupPrivDisplayName failed - %s\n", nt_errstr(status));
return false;
}
- printf("%s -> \"%s\" (language 0x%x/0x%x)\n",
+ torture_comment(tctx, "%s -> \"%s\" (language 0x%x/0x%x)\n",
priv_name->string, disp_name->string,
r.in.language_id, *r.out.returned_language_id);
@@ -1696,7 +1698,7 @@ static bool test_EnumAccountsWithUserRight(struct dcerpc_pipe *p,
ZERO_STRUCT(sids);
- printf("\nTesting EnumAccountsWithUserRight(%s)\n", priv_name->string);
+ torture_comment(tctx, "\nTesting EnumAccountsWithUserRight(%s)\n", priv_name->string);
r.in.handle = handle;
r.in.name = priv_name;
@@ -1710,7 +1712,7 @@ static bool test_EnumAccountsWithUserRight(struct dcerpc_pipe *p,
}
if (!NT_STATUS_IS_OK(status)) {
- printf("EnumAccountsWithUserRight failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "EnumAccountsWithUserRight failed - %s\n", nt_errstr(status));
return false;
}
@@ -1729,7 +1731,7 @@ static bool test_EnumPrivs(struct dcerpc_pipe *p,
int i;
bool ret = true;
- printf("\nTesting EnumPrivs\n");
+ torture_comment(tctx, "\nTesting EnumPrivs\n");
r.in.handle = handle;
r.in.resume_handle = &resume_handle;
@@ -1740,7 +1742,7 @@ static bool test_EnumPrivs(struct dcerpc_pipe *p,
resume_handle = 0;
status = dcerpc_lsa_EnumPrivs(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("EnumPrivs failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "EnumPrivs failed - %s\n", nt_errstr(status));
return false;
}
@@ -1766,10 +1768,10 @@ static bool test_QueryForestTrustInformation(struct dcerpc_pipe *p,
struct lsa_String string;
struct lsa_ForestTrustInformation info, *info_ptr;
- printf("\nTesting lsaRQueryForestTrustInformation\n");
+ torture_comment(tctx, "\nTesting lsaRQueryForestTrustInformation\n");
if (torture_setting_bool(tctx, "samba4", false)) {
- printf("skipping QueryForestTrustInformation against Samba4\n");
+ torture_comment(tctx, "skipping QueryForestTrustInformation against Samba4\n");
return true;
}
@@ -1789,7 +1791,7 @@ static bool test_QueryForestTrustInformation(struct dcerpc_pipe *p,
status = dcerpc_lsa_lsaRQueryForestTrustInformation(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("lsaRQueryForestTrustInformation of %s failed - %s\n", trusted_domain_name, nt_errstr(status));
+ torture_comment(tctx, "lsaRQueryForestTrustInformation of %s failed - %s\n", trusted_domain_name, nt_errstr(status));
ret = false;
}
@@ -1824,7 +1826,7 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p,
int i,j;
bool ret = true;
- printf("\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n");
+ torture_comment(tctx, "\nTesting OpenTrustedDomain, OpenTrustedDomainByName and QueryInfoTrustedDomain\n");
for (i=0; i< domains->count; i++) {
struct lsa_OpenTrustedDomain trust;
struct lsa_OpenTrustedDomainByName trust_by_name;
@@ -1844,7 +1846,7 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p,
status = dcerpc_lsa_OpenTrustedDomain(p, tctx, &trust);
if (!NT_STATUS_IS_OK(status)) {
- printf("OpenTrustedDomain failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "OpenTrustedDomain failed - %s\n", nt_errstr(status));
return false;
}
@@ -1862,11 +1864,11 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p,
q.out.info = &info;
status = dcerpc_lsa_QueryTrustedDomainInfo(p, tctx, &q);
if (!NT_STATUS_IS_OK(status) && ok[j]) {
- printf("QueryTrustedDomainInfo level %d failed - %s\n",
+ torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n",
levels[j], nt_errstr(status));
ret = false;
} else if (NT_STATUS_IS_OK(status) && !ok[j]) {
- printf("QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
+ torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
levels[j], nt_errstr(status));
ret = false;
}
@@ -1874,7 +1876,7 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p,
status = dcerpc_lsa_CloseTrustedDomainEx(p, tctx, &c_trust);
if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
- printf("Expected CloseTrustedDomainEx to return NT_STATUS_NOT_IMPLEMENTED, instead - %s\n", nt_errstr(status));
+ torture_comment(tctx, "Expected CloseTrustedDomainEx to return NT_STATUS_NOT_IMPLEMENTED, instead - %s\n", nt_errstr(status));
return false;
}
@@ -1883,7 +1885,7 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p,
status = dcerpc_lsa_Close(p, tctx, &c);
if (!NT_STATUS_IS_OK(status)) {
- printf("Close of trusted domain failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(status));
return false;
}
@@ -1902,11 +1904,11 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p,
status = dcerpc_lsa_QueryTrustedDomainInfoBySid(p, tctx, &q);
if (!NT_STATUS_IS_OK(status) && ok[j]) {
- printf("QueryTrustedDomainInfoBySid level %d failed - %s\n",
+ torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d failed - %s\n",
levels[j], nt_errstr(status));
ret = false;
} else if (NT_STATUS_IS_OK(status) && !ok[j]) {
- printf("QueryTrustedDomainInfoBySid level %d unexpectedly succeeded - %s\n",
+ torture_comment(tctx, "QueryTrustedDomainInfoBySid level %d unexpectedly succeeded - %s\n",
levels[j], nt_errstr(status));
ret = false;
}
@@ -1921,7 +1923,7 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p,
status = dcerpc_lsa_OpenTrustedDomainByName(p, tctx, &trust_by_name);
if (!NT_STATUS_IS_OK(status)) {
- printf("OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "OpenTrustedDomainByName failed - %s\n", nt_errstr(status));
return false;
}
@@ -1933,11 +1935,11 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p,
q.out.info = &info;
status = dcerpc_lsa_QueryTrustedDomainInfo(p, tctx, &q);
if (!NT_STATUS_IS_OK(status) && ok[j]) {
- printf("QueryTrustedDomainInfo level %d failed - %s\n",
+ torture_comment(tctx, "QueryTrustedDomainInfo level %d failed - %s\n",
levels[j], nt_errstr(status));
ret = false;
} else if (NT_STATUS_IS_OK(status) && !ok[j]) {
- printf("QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
+ torture_comment(tctx, "QueryTrustedDomainInfo level %d unexpectedly succeeded - %s\n",
levels[j], nt_errstr(status));
ret = false;
}
@@ -1948,7 +1950,7 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p,
status = dcerpc_lsa_Close(p, tctx, &c);
if (!NT_STATUS_IS_OK(status)) {
- printf("Close of trusted domain failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "Close of trusted domain failed - %s\n", nt_errstr(status));
return false;
}
@@ -1965,11 +1967,11 @@ static bool test_query_each_TrustDom(struct dcerpc_pipe *p,
q.out.info = &info;
status = dcerpc_lsa_QueryTrustedDomainInfoByName(p, tctx, &q);
if (!NT_STATUS_IS_OK(status) && ok[j]) {
- printf("QueryTrustedDomainInfoByName level %d failed - %s\n",
+ torture_comment(tctx, "QueryTrustedDomainInfoByName level %d failed - %s\n",
levels[j], nt_errstr(status));
ret = false;
} else if (NT_STATUS_IS_OK(status) && !ok[j]) {
- printf("QueryTrustedDomainInfoByName level %d unexpectedly succeeded - %s\n",
+ torture_comment(tctx, "QueryTrustedDomainInfoByName level %d unexpectedly succeeded - %s\n",
levels[j], nt_errstr(status));
ret = false;
}
@@ -1990,7 +1992,7 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p,
struct lsa_DomainListEx domains_ex;
bool ret = true;
- printf("\nTesting EnumTrustDom\n");
+ torture_comment(tctx, "\nTesting EnumTrustDom\n");
r.in.handle = handle;
r.in.resume_handle = &resume_handle;
@@ -2002,11 +2004,11 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p,
if (NT_STATUS_IS_OK(enum_status)) {
if (domains.count == 0) {
- printf("EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
+ torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
return false;
}
} else if (!(NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES))) {
- printf("EnumTrustDom of zero size failed - %s\n", nt_errstr(enum_status));
+ torture_comment(tctx, "EnumTrustDom of zero size failed - %s\n", nt_errstr(enum_status));
return false;
}
@@ -2027,24 +2029,24 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p,
if (domains.count == 0) {
return true;
}
- printf("EnumTrustDom failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
+ torture_comment(tctx, "EnumTrustDom failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
return false;
} else if (NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)) {
/* Windows 2003 gets this off by one on the first run */
if (r.out.domains->count < 3 || r.out.domains->count > 4) {
- printf("EnumTrustDom didn't fill the buffer we "
+ torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
"asked it to (got %d, expected %d / %d == %d entries)\n",
r.out.domains->count, LSA_ENUM_TRUST_DOMAIN_MULTIPLIER * 3,
LSA_ENUM_TRUST_DOMAIN_MULTIPLIER, r.in.max_size);
ret = false;
}
} else if (!NT_STATUS_IS_OK(enum_status)) {
- printf("EnumTrustDom failed - %s\n", nt_errstr(enum_status));
+ torture_comment(tctx, "EnumTrustDom failed - %s\n", nt_errstr(enum_status));
return false;
}
if (domains.count == 0) {
- printf("EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
+ torture_comment(tctx, "EnumTrustDom failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
return false;
}
@@ -2052,7 +2054,7 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p,
} while ((NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)));
- printf("\nTesting EnumTrustedDomainsEx\n");
+ torture_comment(tctx, "\nTesting EnumTrustedDomainsEx\n");
r_ex.in.handle = handle;
r_ex.in.resume_handle = &resume_handle;
@@ -2063,7 +2065,7 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p,
enum_status = dcerpc_lsa_EnumTrustedDomainsEx(p, tctx, &r_ex);
if (!(NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES) || NT_STATUS_EQUAL(enum_status, NT_STATUS_NO_MORE_ENTRIES))) {
- printf("EnumTrustedDomainEx of zero size failed - %s\n", nt_errstr(enum_status));
+ torture_comment(tctx, "EnumTrustedDomainEx of zero size failed - %s\n", nt_errstr(enum_status));
return false;
}
@@ -2082,12 +2084,12 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p,
if (domains_ex.count == 0) {
return true;
}
- printf("EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
+ torture_comment(tctx, "EnumTrustDomainsEx failed - should have returned 0 trusted domains with 'NT_STATUS_NO_MORE_ENTRIES'\n");
return false;
} else if (NT_STATUS_EQUAL(enum_status, STATUS_MORE_ENTRIES)) {
/* Windows 2003 gets this off by one on the first run */
if (r_ex.out.domains->count < 3 || r_ex.out.domains->count > 4) {
- printf("EnumTrustDom didn't fill the buffer we "
+ torture_comment(tctx, "EnumTrustDom didn't fill the buffer we "
"asked it to (got %d, expected %d / %d == %d entries)\n",
r_ex.out.domains->count,
r_ex.in.max_size,
@@ -2095,12 +2097,12 @@ static bool test_EnumTrustDom(struct dcerpc_pipe *p,
r_ex.in.max_size / LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER);
}
} else if (!NT_STATUS_IS_OK(enum_status)) {
- printf("EnumTrustedDomainEx failed - %s\n", nt_errstr(enum_status));
+ torture_comment(tctx, "EnumTrustedDomainEx failed - %s\n", nt_errstr(enum_status));
return false;
}
if (domains_ex.count == 0) {
- printf("EnumTrustDomainEx failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
+ torture_comment(tctx, "EnumTrustDomainEx failed - should have returned 'NT_STATUS_NO_MORE_ENTRIES' for 0 trusted domains\n");
return false;
}
@@ -2125,7 +2127,7 @@ static bool test_CreateTrustedDomain(struct dcerpc_pipe *p,
union lsa_TrustedDomainInfo *info = NULL;
int i;
- printf("\nTesting CreateTrustedDomain for 12 domains\n");
+ torture_comment(tctx, "\nTesting CreateTrustedDomain for 12 domains\n");
if (!test_EnumTrustDom(p, tctx, handle)) {
ret = false;
@@ -2151,7 +2153,7 @@ static bool test_CreateTrustedDomain(struct dcerpc_pipe *p,
status = dcerpc_lsa_CreateTrustedDomain(p, tctx, &r);
}
if (!NT_STATUS_IS_OK(status)) {
- printf("CreateTrustedDomain failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "CreateTrustedDomain failed - %s\n", nt_errstr(status));
ret = false;
} else {
@@ -2160,28 +2162,28 @@ static bool test_CreateTrustedDomain(struct dcerpc_pipe *p,
q.out.info = &info;
status = dcerpc_lsa_QueryTrustedDomainInfo(p, tctx, &q);
if (!NT_STATUS_IS_OK(status)) {
- printf("QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status));
ret = false;
} else if (!q.out.info) {
ret = false;
} else {
if (strcmp(info->info_ex.netbios_name.string, trustinfo.name.string) != 0) {
- printf("QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n",
+ torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n",
info->info_ex.netbios_name.string, trustinfo.name.string);
ret = false;
}
if (info->info_ex.trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
- printf("QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
+ torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
trust_name, info->info_ex.trust_type, LSA_TRUST_TYPE_DOWNLEVEL);
ret = false;
}
if (info->info_ex.trust_attributes != 0) {
- printf("QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
+ torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
trust_name, info->info_ex.trust_attributes, 0);
ret = false;
}
if (info->info_ex.trust_direction != LSA_TRUST_DIRECTION_OUTBOUND) {
- printf("QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
+ torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
trust_name, info->info_ex.trust_direction, LSA_TRUST_DIRECTION_OUTBOUND);
ret = false;
}
@@ -2222,11 +2224,11 @@ static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p,
enum ndr_err_code ndr_err;
int i;
- printf("\nTesting CreateTrustedDomainEx2 for 12 domains\n");
+ torture_comment(tctx, "\nTesting CreateTrustedDomainEx2 for 12 domains\n");
status = dcerpc_fetch_session_key(p, &session_key);
if (!NT_STATUS_IS_OK(status)) {
- printf("dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "dcerpc_fetch_session_key failed - %s\n", nt_errstr(status));
return false;
}
@@ -2263,7 +2265,7 @@ static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p,
ndr_err = ndr_push_struct_blob(&auth_blob, tctx, lp_iconv_convenience(tctx->lp_ctx), &auth_struct,
(ndr_push_flags_fn_t)ndr_push_trustDomainPasswords);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- printf("ndr_push_struct_blob of trustDomainPasswords structure failed");
+ torture_comment(tctx, "ndr_push_struct_blob of trustDomainPasswords structure failed");
ret = false;
}
@@ -2284,7 +2286,7 @@ static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p,
status = dcerpc_lsa_CreateTrustedDomainEx2(p, tctx, &r);
}
if (!NT_STATUS_IS_OK(status)) {
- printf("CreateTrustedDomainEx failed2 - %s\n", nt_errstr(status));
+ torture_comment(tctx, "CreateTrustedDomainEx failed2 - %s\n", nt_errstr(status));
ret = false;
} else {
@@ -2293,29 +2295,29 @@ static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p,
q.out.info = &info;
status = dcerpc_lsa_QueryTrustedDomainInfo(p, tctx, &q);
if (!NT_STATUS_IS_OK(status)) {
- printf("QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed - %s\n", nt_errstr(status));
ret = false;
} else if (!q.out.info) {
- printf("QueryTrustedDomainInfo level 1 failed to return an info pointer\n");
+ torture_comment(tctx, "QueryTrustedDomainInfo level 1 failed to return an info pointer\n");
ret = false;
} else {
if (strcmp(info->info_ex.netbios_name.string, trustinfo.netbios_name.string) != 0) {
- printf("QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n",
+ torture_comment(tctx, "QueryTrustedDomainInfo returned inconsistant short name: %s != %s\n",
info->info_ex.netbios_name.string, trustinfo.netbios_name.string);
ret = false;
}
if (info->info_ex.trust_type != trustinfo.trust_type) {
- printf("QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
+ torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust type %d != %d\n",
trust_name, info->info_ex.trust_type, trustinfo.trust_type);
ret = false;
}
if (info->info_ex.trust_attributes != LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION) {
- printf("QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
+ torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust attributes %d != %d\n",
trust_name, info->info_ex.trust_attributes, LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION);
ret = false;
}
if (info->info_ex.trust_direction != trustinfo.trust_direction) {
- printf("QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
+ torture_comment(tctx, "QueryTrustedDomainInfo of %s returned incorrect trust direction %d != %d\n",
trust_name, info->info_ex.trust_direction, trustinfo.trust_direction);
ret = false;
}
@@ -2325,13 +2327,13 @@ static bool test_CreateTrustedDomainEx2(struct dcerpc_pipe *p,
/* now that we have some domains to look over, we can test the enum calls */
if (!test_EnumTrustDom(p, tctx, handle)) {
- printf("test_EnumTrustDom failed\n");
+ torture_comment(tctx, "test_EnumTrustDom failed\n");
ret = false;
}
for (i=0; i<12; i++) {
if (!test_DeleteTrustedDomainBySid(p, tctx, handle, domsid[i])) {
- printf("test_DeleteTrustedDomainBySid failed\n");
+ torture_comment(tctx, "test_DeleteTrustedDomainBySid failed\n");
ret = false;
}
}
@@ -2349,14 +2351,14 @@ static bool test_QueryDomainInfoPolicy(struct dcerpc_pipe *p,
int i;
bool ret = true;
- printf("\nTesting QueryDomainInformationPolicy\n");
+ torture_comment(tctx, "\nTesting QueryDomainInformationPolicy\n");
for (i=2;i<4;i++) {
r.in.handle = handle;
r.in.level = i;
r.out.info = &info;
- printf("\nTrying QueryDomainInformationPolicy level %d\n", i);
+ torture_comment(tctx, "\nTrying QueryDomainInformationPolicy level %d\n", i);
status = dcerpc_lsa_QueryDomainInformationPolicy(p, tctx, &r);
@@ -2364,7 +2366,7 @@ static bool test_QueryDomainInfoPolicy(struct dcerpc_pipe *p,
if (i == LSA_DOMAIN_INFO_POLICY_EFS && NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
continue;
} else if (!NT_STATUS_IS_OK(status)) {
- printf("QueryDomainInformationPolicy failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QueryDomainInformationPolicy failed - %s\n", nt_errstr(status));
ret = false;
continue;
}
@@ -2386,9 +2388,9 @@ static bool test_QueryInfoPolicyCalls( bool version2,
bool ret = true;
if (version2)
- printf("\nTesting QueryInfoPolicy2\n");
+ torture_comment(tctx, "\nTesting QueryInfoPolicy2\n");
else
- printf("\nTesting QueryInfoPolicy\n");
+ torture_comment(tctx, "\nTesting QueryInfoPolicy\n");
for (i=1;i<=14;i++) {
r.in.handle = handle;
@@ -2396,9 +2398,9 @@ static bool test_QueryInfoPolicyCalls( bool version2,
r.out.info = &info;
if (version2)
- printf("\nTrying QueryInfoPolicy2 level %d\n", i);
+ torture_comment(tctx, "\nTrying QueryInfoPolicy2 level %d\n", i);
else
- printf("\nTrying QueryInfoPolicy level %d\n", i);
+ torture_comment(tctx, "\nTrying QueryInfoPolicy level %d\n", i);
if (version2)
/* We can perform the cast, because both types are
@@ -2413,7 +2415,7 @@ static bool test_QueryInfoPolicyCalls( bool version2,
case LSA_POLICY_INFO_AUDIT_FULL_SET:
case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
- printf("Server should have failed level %u: %s\n", i, nt_errstr(status));
+ torture_comment(tctx, "Server should have failed level %u: %s\n", i, nt_errstr(status));
ret = false;
}
break;
@@ -2430,9 +2432,9 @@ static bool test_QueryInfoPolicyCalls( bool version2,
case LSA_POLICY_INFO_PD:
if (!NT_STATUS_IS_OK(status)) {
if (version2)
- printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
else
- printf("QueryInfoPolicy failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QueryInfoPolicy failed - %s\n", nt_errstr(status));
ret = false;
}
break;
@@ -2441,16 +2443,16 @@ static bool test_QueryInfoPolicyCalls( bool version2,
/* Other levels not implemented yet */
if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
if (version2)
- printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
else
- printf("QueryInfoPolicy failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QueryInfoPolicy failed - %s\n", nt_errstr(status));
ret = false;
}
} else if (!NT_STATUS_IS_OK(status)) {
if (version2)
- printf("QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QueryInfoPolicy2 failed - %s\n", nt_errstr(status));
else
- printf("QueryInfoPolicy failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "QueryInfoPolicy failed - %s\n", nt_errstr(status));
ret = false;
}
break;
@@ -2522,7 +2524,7 @@ static bool test_GetUserName(struct dcerpc_pipe *p,
struct lsa_String *authority_name_p = NULL;
struct lsa_String *account_name_p = NULL;
- printf("\nTesting GetUserName\n");
+ torture_comment(tctx, "\nTesting GetUserName\n");
r.in.system_name = "\\";
r.in.account_name = &account_name_p;
@@ -2532,7 +2534,7 @@ static bool test_GetUserName(struct dcerpc_pipe *p,
status = dcerpc_lsa_GetUserName(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("GetUserName failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(status));
ret = false;
}
@@ -2544,7 +2546,7 @@ static bool test_GetUserName(struct dcerpc_pipe *p,
status = dcerpc_lsa_GetUserName(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("GetUserName failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "GetUserName failed - %s\n", nt_errstr(status));
ret = false;
}
@@ -2559,25 +2561,25 @@ bool test_lsa_Close(struct dcerpc_pipe *p,
struct lsa_Close r;
struct policy_handle handle2;
- printf("\nTesting Close\n");
+ torture_comment(tctx, "\nTesting Close\n");
r.in.handle = handle;
r.out.handle = &handle2;
status = dcerpc_lsa_Close(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("Close failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "Close failed - %s\n", nt_errstr(status));
return false;
}
status = dcerpc_lsa_Close(p, tctx, &r);
/* its really a fault - we need a status code for rpc fault */
if (!NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- printf("Close failed - %s\n", nt_errstr(status));
+ torture_comment(tctx, "Close failed - %s\n", nt_errstr(status));
return false;
}
- printf("\n");
+ torture_comment(tctx, "\n");
return true;
}
@@ -2625,28 +2627,9 @@ bool torture_rpc_lsa(struct torture_context *tctx)
ret = false;
}
- if (!test_CreateAccount(p, tctx, handle)) {
- ret = false;
- }
-
if (!test_CreateSecret(p, tctx, handle)) {
ret = false;
}
- if (!test_CreateTrustedDomain(p, tctx, handle)) {
- ret = false;
- }
-
- if (!test_CreateTrustedDomainEx2(p, tctx, handle)) {
- ret = false;
- }
-
- if (!test_EnumAccounts(p, tctx, handle)) {
- ret = false;
- }
-
- if (!test_EnumPrivs(p, tctx, handle)) {
- ret = false;
- }
if (!test_QueryInfoPolicy(p, tctx, handle)) {
ret = false;
@@ -2766,3 +2749,104 @@ struct torture_suite *torture_rpc_lsa_lookup_names(TALLOC_CTX *mem_ctx)
return suite;
}
+
+static bool testcase_TrustedDomains(struct torture_context *tctx,
+ struct dcerpc_pipe *p)
+{
+ bool ret = true;
+ struct policy_handle *handle;
+
+ if (!test_OpenPolicy(p, tctx)) {
+ ret = false;
+ }
+
+ if (!test_lsa_OpenPolicy2(p, tctx, &handle)) {
+ ret = false;
+ }
+
+ if (!handle) {
+ ret = false;
+ }
+
+ if (!test_CreateTrustedDomain(p, tctx, handle)) {
+ ret = false;
+ }
+
+ if (!test_CreateTrustedDomainEx2(p, tctx, handle)) {
+ ret = false;
+ }
+
+ if (!test_lsa_Close(p, tctx, handle)) {
+ ret = false;
+ }
+
+ return ret;
+}
+
+struct torture_suite *torture_rpc_lsa_trusted_domains(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite;
+ struct torture_rpc_tcase *tcase;
+
+ suite = torture_suite_create(mem_ctx, "LSA-TRUSTED-DOMAINS");
+
+ tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
+ &ndr_table_lsarpc);
+ torture_rpc_tcase_add_test(tcase, "TrustedDomains",
+ testcase_TrustedDomains);
+
+ return suite;
+}
+
+static bool testcase_Privileges(struct torture_context *tctx,
+ struct dcerpc_pipe *p)
+{
+ bool ret = true;
+ struct policy_handle *handle;
+
+ if (!test_OpenPolicy(p, tctx)) {
+ ret = false;
+ }
+
+ if (!test_lsa_OpenPolicy2(p, tctx, &handle)) {
+ ret = false;
+ }
+
+ if (!handle) {
+ ret = false;
+ }
+
+ if (!test_CreateAccount(p, tctx, handle)) {
+ ret = false;
+ }
+
+ if (!test_EnumAccounts(p, tctx, handle)) {
+ ret = false;
+ }
+
+ if (!test_EnumPrivs(p, tctx, handle)) {
+ ret = false;
+ }
+
+ if (!test_lsa_Close(p, tctx, handle)) {
+ ret = false;
+ }
+
+ return ret;
+}
+
+
+struct torture_suite *torture_rpc_lsa_privileges(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite;
+ struct torture_rpc_tcase *tcase;
+
+ suite = torture_suite_create(mem_ctx, "LSA-PRIVILEGES");
+
+ tcase = torture_suite_add_rpc_iface_tcase(suite, "lsa",
+ &ndr_table_lsarpc);
+ torture_rpc_tcase_add_test(tcase, "Privileges",
+ testcase_Privileges);
+
+ return suite;
+}
diff --git a/source4/torture/rpc/object_uuid.c b/source4/torture/rpc/object_uuid.c
index a70266697e..53d03a3ce9 100644
--- a/source4/torture/rpc/object_uuid.c
+++ b/source4/torture/rpc/object_uuid.c
@@ -35,7 +35,6 @@ static bool test_random_uuid(struct torture_context *torture)
{
NTSTATUS status;
struct dcerpc_pipe *p1, *p2;
- struct rpc_request *req;
struct GUID uuid;
struct dssetup_DsRoleGetPrimaryDomainInformation r1;
struct lsa_GetUserName r2;
diff --git a/source4/torture/rpc/rpc.c b/source4/torture/rpc/rpc.c
index 4043562ab5..ffdd748470 100644
--- a/source4/torture/rpc/rpc.c
+++ b/source4/torture/rpc/rpc.c
@@ -431,6 +431,8 @@ NTSTATUS torture_rpc_init(void)
torture_suite_add_suite(suite, torture_rpc_lsa_lookup_sids(suite));
torture_suite_add_suite(suite, torture_rpc_lsa_lookup_names(suite));
torture_suite_add_suite(suite, torture_rpc_lsa_secrets(suite));
+ torture_suite_add_suite(suite, torture_rpc_lsa_trusted_domains(suite));
+ torture_suite_add_suite(suite, torture_rpc_lsa_privileges(suite));
torture_suite_add_suite(suite, torture_rpc_echo(suite));
torture_suite_add_simple_test(suite, "DFS", torture_rpc_dfs);
torture_suite_add_suite(suite, torture_rpc_frsapi(suite));
@@ -444,6 +446,7 @@ NTSTATUS torture_rpc_init(void)
torture_suite_add_simple_test(suite, "SPOOLSS", torture_rpc_spoolss);
torture_suite_add_suite(suite, torture_rpc_spoolss_notify(suite));
torture_suite_add_suite(suite, torture_rpc_spoolss_win(suite));
+ torture_suite_add_suite(suite, torture_rpc_spoolss_printer(suite));
torture_suite_add_simple_test(suite, "SAMR", torture_rpc_samr);
torture_suite_add_simple_test(suite, "SAMR-USERS", torture_rpc_samr_users);
torture_suite_add_simple_test(suite, "SAMR-PASSWORDS", torture_rpc_samr_passwords);
diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c
index 10e18e1531..ddc14f33a2 100644
--- a/source4/torture/rpc/spoolss.c
+++ b/source4/torture/rpc/spoolss.c
@@ -26,6 +26,11 @@
#include "torture/rpc/rpc.h"
#include "librpc/gen_ndr/ndr_spoolss_c.h"
+#define TORTURE_WELLKNOWN_PRINTER "torture_wkn_printer"
+#define TORTURE_PRINTER "torture_printer"
+#define TORTURE_WELLKNOWN_PRINTER_EX "torture_wkn_printer_ex"
+#define TORTURE_PRINTER_EX "torture_printer_ex"
+
struct test_spoolss_context {
/* print server handle */
struct policy_handle server_handle;
@@ -75,20 +80,22 @@ struct test_spoolss_context {
#define COMPARE_STRING_ARRAY(tctx, c,r,e)
-static bool test_OpenPrinter_server(struct torture_context *tctx, struct dcerpc_pipe *p, struct test_spoolss_context *ctx)
+static bool test_OpenPrinter_server(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *server_handle)
{
NTSTATUS status;
struct spoolss_OpenPrinter op;
- op.in.printername = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(p));
+ op.in.printername = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
op.in.datatype = NULL;
op.in.devmode_ctr.devmode= NULL;
op.in.access_mask = 0;
- op.out.handle = &ctx->server_handle;
+ op.out.handle = server_handle;
torture_comment(tctx, "Testing OpenPrinter(%s)\n", op.in.printername);
- status = dcerpc_spoolss_OpenPrinter(p, ctx, &op);
+ status = dcerpc_spoolss_OpenPrinter(p, tctx, &op);
torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_OpenPrinter failed");
torture_assert_werr_ok(tctx, op.out.result, "dcerpc_spoolss_OpenPrinter failed");
@@ -810,6 +817,564 @@ static bool test_GetPrinter(struct torture_context *tctx,
return true;
}
+static bool test_SetPrinter_errors(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *handle)
+{
+ struct spoolss_SetPrinter r;
+ uint16_t levels[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ int i;
+
+ struct spoolss_SetPrinterInfoCtr info_ctr;
+ struct spoolss_DevmodeContainer devmode_ctr;
+ struct sec_desc_buf secdesc_ctr;
+
+ info_ctr.level = 0;
+ info_ctr.info.info0 = NULL;
+
+ ZERO_STRUCT(devmode_ctr);
+ ZERO_STRUCT(secdesc_ctr);
+
+ r.in.handle = handle;
+ r.in.info_ctr = &info_ctr;
+ r.in.devmode_ctr = &devmode_ctr;
+ r.in.secdesc_ctr = &secdesc_ctr;
+ r.in.command = 0;
+
+ torture_comment(tctx, "Testing SetPrinter all zero\n");
+
+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_SetPrinter(p, tctx, &r),
+ "failed to call SetPrinter");
+ torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
+ "failed to call SetPrinter");
+
+ again:
+ for (i=0; i < ARRAY_SIZE(levels); i++) {
+
+ struct spoolss_SetPrinterInfo0 info0;
+ struct spoolss_SetPrinterInfo1 info1;
+ struct spoolss_SetPrinterInfo2 info2;
+ struct spoolss_SetPrinterInfo3 info3;
+ struct spoolss_SetPrinterInfo4 info4;
+ struct spoolss_SetPrinterInfo5 info5;
+ struct spoolss_SetPrinterInfo6 info6;
+ struct spoolss_SetPrinterInfo7 info7;
+ struct spoolss_DeviceModeInfo info8;
+ struct spoolss_DeviceModeInfo info9;
+
+
+ info_ctr.level = levels[i];
+ switch (levels[i]) {
+ case 0:
+ ZERO_STRUCT(info0);
+ info_ctr.info.info0 = &info0;
+ break;
+ case 1:
+ ZERO_STRUCT(info1);
+ info_ctr.info.info1 = &info1;
+ break;
+ case 2:
+ ZERO_STRUCT(info2);
+ info_ctr.info.info2 = &info2;
+ break;
+ case 3:
+ ZERO_STRUCT(info3);
+ info_ctr.info.info3 = &info3;
+ break;
+ case 4:
+ ZERO_STRUCT(info4);
+ info_ctr.info.info4 = &info4;
+ break;
+ case 5:
+ ZERO_STRUCT(info5);
+ info_ctr.info.info5 = &info5;
+ break;
+ case 6:
+ ZERO_STRUCT(info6);
+ info_ctr.info.info6 = &info6;
+ break;
+ case 7:
+ ZERO_STRUCT(info7);
+ info_ctr.info.info7 = &info7;
+ break;
+ case 8:
+ ZERO_STRUCT(info8);
+ info_ctr.info.info8 = &info8;
+ break;
+ case 9:
+ ZERO_STRUCT(info9);
+ info_ctr.info.info9 = &info9;
+ break;
+ }
+
+ torture_comment(tctx, "Testing SetPrinter level %d, command %d\n",
+ info_ctr.level, r.in.command);
+
+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_SetPrinter(p, tctx, &r),
+ "failed to call SetPrinter");
+
+ switch (r.in.command) {
+ case SPOOLSS_PRINTER_CONTROL_UNPAUSE: /* 0 */
+ /* is ignored for all levels other then 0 */
+ if (info_ctr.level > 0) {
+ /* ignored then */
+ break;
+ }
+ case SPOOLSS_PRINTER_CONTROL_PAUSE: /* 1 */
+ case SPOOLSS_PRINTER_CONTROL_RESUME: /* 2 */
+ case SPOOLSS_PRINTER_CONTROL_PURGE: /* 3 */
+ if (info_ctr.level > 0) {
+ /* is invalid for all levels other then 0 */
+ torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PRINTER_COMMAND,
+ "unexpected error code returned");
+ continue;
+ } else {
+ torture_assert_werr_ok(tctx, r.out.result,
+ "failed to call SetPrinter with non 0 command");
+ continue;
+ }
+ break;
+
+ case SPOOLSS_PRINTER_CONTROL_SET_STATUS: /* 4 */
+ /* FIXME: gd needs further investigation */
+ default:
+ torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PRINTER_COMMAND,
+ "unexpected error code returned");
+ continue;
+ }
+
+ switch (info_ctr.level) {
+ case 1:
+ torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL,
+ "unexpected error code returned");
+ break;
+ case 2:
+ torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_PRINTER_DRIVER,
+ "unexpected error code returned");
+ break;
+ case 3:
+ case 4:
+ case 5:
+ case 7:
+ torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM,
+ "unexpected error code returned");
+ break;
+ case 9:
+ torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
+ "unexpected error code returned");
+ break;
+ default:
+ torture_assert_werr_ok(tctx, r.out.result,
+ "failed to call SetPrinter");
+ break;
+ }
+ }
+
+ if (r.in.command < 5) {
+ r.in.command++;
+ goto again;
+ }
+
+ return true;
+}
+
+static void clear_info2(struct spoolss_SetPrinterInfoCtr *r)
+{
+ if ((r->level == 2) && (r->info.info2)) {
+ r->info.info2->secdesc = NULL;
+ r->info.info2->devmode = NULL;
+ }
+}
+
+static bool test_PrinterInfo(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *handle)
+{
+ NTSTATUS status;
+ struct spoolss_SetPrinter s;
+ struct spoolss_GetPrinter q;
+ struct spoolss_GetPrinter q0;
+ struct spoolss_SetPrinterInfoCtr info_ctr;
+ union spoolss_PrinterInfo info;
+ struct spoolss_DevmodeContainer devmode_ctr;
+ struct sec_desc_buf secdesc_ctr;
+ uint32_t needed;
+ bool ret = true;
+ int i;
+
+ uint32_t status_list[] = {
+ /* these do not stick
+ PRINTER_STATUS_PAUSED,
+ PRINTER_STATUS_ERROR,
+ PRINTER_STATUS_PENDING_DELETION, */
+ PRINTER_STATUS_PAPER_JAM,
+ PRINTER_STATUS_PAPER_OUT,
+ PRINTER_STATUS_MANUAL_FEED,
+ PRINTER_STATUS_PAPER_PROBLEM,
+ PRINTER_STATUS_OFFLINE,
+ PRINTER_STATUS_IO_ACTIVE,
+ PRINTER_STATUS_BUSY,
+ PRINTER_STATUS_PRINTING,
+ PRINTER_STATUS_OUTPUT_BIN_FULL,
+ PRINTER_STATUS_NOT_AVAILABLE,
+ PRINTER_STATUS_WAITING,
+ PRINTER_STATUS_PROCESSING,
+ PRINTER_STATUS_INITIALIZING,
+ PRINTER_STATUS_WARMING_UP,
+ PRINTER_STATUS_TONER_LOW,
+ PRINTER_STATUS_NO_TONER,
+ PRINTER_STATUS_PAGE_PUNT,
+ PRINTER_STATUS_USER_INTERVENTION,
+ PRINTER_STATUS_OUT_OF_MEMORY,
+ PRINTER_STATUS_DOOR_OPEN,
+ PRINTER_STATUS_SERVER_UNKNOWN,
+ PRINTER_STATUS_POWER_SAVE,
+ /* these do not stick
+ 0x02000000,
+ 0x04000000,
+ 0x08000000,
+ 0x10000000,
+ 0x20000000,
+ 0x40000000,
+ 0x80000000 */
+ };
+ uint32_t default_attribute = PRINTER_ATTRIBUTE_LOCAL;
+ uint32_t attribute_list[] = {
+ PRINTER_ATTRIBUTE_QUEUED,
+ /* fails with WERR_INVALID_DATATYPE:
+ PRINTER_ATTRIBUTE_DIRECT, */
+ /* does not stick
+ PRINTER_ATTRIBUTE_DEFAULT, */
+ PRINTER_ATTRIBUTE_SHARED,
+ /* does not stick
+ PRINTER_ATTRIBUTE_NETWORK, */
+ PRINTER_ATTRIBUTE_HIDDEN,
+ PRINTER_ATTRIBUTE_LOCAL,
+ PRINTER_ATTRIBUTE_ENABLE_DEVQ,
+ PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS,
+ PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST,
+ PRINTER_ATTRIBUTE_WORK_OFFLINE,
+ /* does not stick
+ PRINTER_ATTRIBUTE_ENABLE_BIDI, */
+ /* fails with WERR_INVALID_DATATYPE:
+ PRINTER_ATTRIBUTE_RAW_ONLY, */
+ /* these do not stick
+ PRINTER_ATTRIBUTE_PUBLISHED,
+ PRINTER_ATTRIBUTE_FAX,
+ PRINTER_ATTRIBUTE_TS,
+ 0x00010000,
+ 0x00020000,
+ 0x00040000,
+ 0x00080000,
+ 0x00100000,
+ 0x00200000,
+ 0x00400000,
+ 0x00800000,
+ 0x01000000,
+ 0x02000000,
+ 0x04000000,
+ 0x08000000,
+ 0x10000000,
+ 0x20000000,
+ 0x40000000,
+ 0x80000000 */
+ };
+
+ ZERO_STRUCT(devmode_ctr);
+ ZERO_STRUCT(secdesc_ctr);
+
+ s.in.handle = handle;
+ s.in.command = 0;
+ s.in.info_ctr = &info_ctr;
+ s.in.devmode_ctr = &devmode_ctr;
+ s.in.secdesc_ctr = &secdesc_ctr;
+
+ q.in.handle = handle;
+ q.out.info = &info;
+ q0 = q;
+
+#define TESTGETCALL(call, r) \
+ r.in.buffer = NULL; \
+ r.in.offered = 0;\
+ r.out.needed = &needed; \
+ status = dcerpc_spoolss_ ##call(p, tctx, &r); \
+ if (!NT_STATUS_IS_OK(status)) { \
+ torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
+ r.in.level, nt_errstr(status), __location__); \
+ ret = false; \
+ break; \
+ }\
+ if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {\
+ DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed); \
+ data_blob_clear(&blob); \
+ r.in.buffer = &blob; \
+ r.in.offered = needed; \
+ }\
+ status = dcerpc_spoolss_ ##call(p, tctx, &r); \
+ if (!NT_STATUS_IS_OK(status)) { \
+ torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
+ r.in.level, nt_errstr(status), __location__); \
+ ret = false; \
+ break; \
+ } \
+ if (!W_ERROR_IS_OK(r.out.result)) { \
+ torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
+ r.in.level, win_errstr(r.out.result), __location__); \
+ ret = false; \
+ break; \
+ }
+
+
+#define TESTSETCALL_EXP(call, r, err) \
+ clear_info2(&info_ctr);\
+ status = dcerpc_spoolss_ ##call(p, tctx, &r); \
+ if (!NT_STATUS_IS_OK(status)) { \
+ torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
+ r.in.info_ctr->level, nt_errstr(status), __location__); \
+ ret = false; \
+ break; \
+ } \
+ if (!W_ERROR_IS_OK(err)) { \
+ if (!W_ERROR_EQUAL(err, r.out.result)) { \
+ torture_comment(tctx, #call " level %u failed - %s, expected %s (%s)\n", \
+ r.in.info_ctr->level, win_errstr(r.out.result), win_errstr(err), __location__); \
+ ret = false; \
+ } \
+ break; \
+ } \
+ if (!W_ERROR_IS_OK(r.out.result)) { \
+ torture_comment(tctx, #call " level %u failed - %s (%s)\n", \
+ r.in.info_ctr->level, win_errstr(r.out.result), __location__); \
+ ret = false; \
+ break; \
+ }
+
+#define TESTSETCALL(call, r) \
+ TESTSETCALL_EXP(call, r, WERR_OK)
+
+#define STRING_EQUAL(s1, s2, field) \
+ if ((s1 && !s2) || (s2 && !s1) || strcmp(s1, s2)) { \
+ torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
+ #field, s2, __location__); \
+ ret = false; \
+ break; \
+ }
+
+#define MEM_EQUAL(s1, s2, length, field) \
+ if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
+ torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
+ #field, (const char *)s2, __location__); \
+ ret = false; \
+ break; \
+ }
+
+#define INT_EQUAL(i1, i2, field) \
+ if (i1 != i2) { \
+ torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
+ #field, (unsigned long long)i2, (unsigned long long)i1, __location__); \
+ ret = false; \
+ break; \
+ }
+
+#define TEST_PRINTERINFO_STRING_EXP_ERR(lvl1, field1, lvl2, field2, value, err) do { \
+ torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
+ q.in.level = lvl1; \
+ TESTGETCALL(GetPrinter, q) \
+ info_ctr.level = lvl1; \
+ info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)&q.out.info->info ## lvl1; \
+ info_ctr.info.info ## lvl1->field1 = value;\
+ TESTSETCALL_EXP(SetPrinter, s, err) \
+ info_ctr.info.info ## lvl1->field1 = ""; \
+ TESTGETCALL(GetPrinter, q) \
+ info_ctr.info.info ## lvl1->field1 = value; \
+ STRING_EQUAL(info_ctr.info.info ## lvl1->field1, value, field1); \
+ q.in.level = lvl2; \
+ TESTGETCALL(GetPrinter, q) \
+ info_ctr.info.info ## lvl2 = (struct spoolss_SetPrinterInfo ## lvl2 *)&q.out.info->info ## lvl2; \
+ STRING_EQUAL(info_ctr.info.info ## lvl2->field2, value, field2); \
+ } while (0)
+
+#define TEST_PRINTERINFO_STRING(lvl1, field1, lvl2, field2, value) do { \
+ TEST_PRINTERINFO_STRING_EXP_ERR(lvl1, field1, lvl2, field2, value, WERR_OK); \
+ } while (0);
+
+#define TEST_PRINTERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value) do { \
+ torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
+ q.in.level = lvl1; \
+ TESTGETCALL(GetPrinter, q) \
+ info_ctr.level = lvl1; \
+ info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)&q.out.info->info ## lvl1; \
+ info_ctr.info.info ## lvl1->field1 = value; \
+ TESTSETCALL(SetPrinter, s) \
+ info_ctr.info.info ## lvl1->field1 = 0; \
+ TESTGETCALL(GetPrinter, q) \
+ info_ctr.info.info ## lvl1 = (struct spoolss_SetPrinterInfo ## lvl1 *)&q.out.info->info ## lvl1; \
+ INT_EQUAL(info_ctr.info.info ## lvl1->field1, exp_value, field1); \
+ q.in.level = lvl2; \
+ TESTGETCALL(GetPrinter, q) \
+ info_ctr.info.info ## lvl2 = (struct spoolss_SetPrinterInfo ## lvl2 *)&q.out.info->info ## lvl2; \
+ INT_EQUAL(info_ctr.info.info ## lvl2->field2, exp_value, field1); \
+ } while (0)
+
+#define TEST_PRINTERINFO_INT(lvl1, field1, lvl2, field2, value) do { \
+ TEST_PRINTERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, value); \
+ } while (0)
+
+ q0.in.level = 0;
+ do { TESTGETCALL(GetPrinter, q0) } while (0);
+
+ TEST_PRINTERINFO_STRING(2, comment, 1, comment, "xx2-1 comment");
+ TEST_PRINTERINFO_STRING(2, comment, 2, comment, "xx2-2 comment");
+
+ /* level 0 printername does not stick */
+/* TEST_PRINTERINFO_STRING(2, printername, 0, printername, "xx2-0 printer"); */
+ TEST_PRINTERINFO_STRING(2, printername, 1, name, "xx2-1 printer");
+ TEST_PRINTERINFO_STRING(2, printername, 2, printername, "xx2-2 printer");
+ TEST_PRINTERINFO_STRING(2, printername, 4, printername, "xx2-4 printer");
+ TEST_PRINTERINFO_STRING(2, printername, 5, printername, "xx2-5 printer");
+/* TEST_PRINTERINFO_STRING(4, printername, 0, printername, "xx4-0 printer"); */
+ TEST_PRINTERINFO_STRING(4, printername, 1, name, "xx4-1 printer");
+ TEST_PRINTERINFO_STRING(4, printername, 2, printername, "xx4-2 printer");
+ TEST_PRINTERINFO_STRING(4, printername, 4, printername, "xx4-4 printer");
+ TEST_PRINTERINFO_STRING(4, printername, 5, printername, "xx4-5 printer");
+/* TEST_PRINTERINFO_STRING(5, printername, 0, printername, "xx5-0 printer"); */
+ TEST_PRINTERINFO_STRING(5, printername, 1, name, "xx5-1 printer");
+ TEST_PRINTERINFO_STRING(5, printername, 2, printername, "xx5-2 printer");
+ TEST_PRINTERINFO_STRING(5, printername, 4, printername, "xx5-4 printer");
+ TEST_PRINTERINFO_STRING(5, printername, 5, printername, "xx5-5 printer");
+
+ /* servername can be set but does not stick
+ TEST_PRINTERINFO_STRING(2, servername, 0, servername, "xx2-0 servername");
+ TEST_PRINTERINFO_STRING(2, servername, 2, servername, "xx2-2 servername");
+ TEST_PRINTERINFO_STRING(2, servername, 4, servername, "xx2-4 servername");
+ */
+
+ /* passing an invalid port will result in WERR_UNKNOWN_PORT */
+ TEST_PRINTERINFO_STRING_EXP_ERR(2, portname, 2, portname, "xx2-2 portname", WERR_UNKNOWN_PORT);
+ TEST_PRINTERINFO_STRING_EXP_ERR(2, portname, 5, portname, "xx2-5 portname", WERR_UNKNOWN_PORT);
+ TEST_PRINTERINFO_STRING_EXP_ERR(5, portname, 2, portname, "xx5-2 portname", WERR_UNKNOWN_PORT);
+ TEST_PRINTERINFO_STRING_EXP_ERR(5, portname, 5, portname, "xx5-5 portname", WERR_UNKNOWN_PORT);
+
+ TEST_PRINTERINFO_STRING(2, sharename, 2, sharename, "xx2-2 sharename");
+ /* passing an invalid driver will result in WERR_UNKNOWN_PRINTER_DRIVER */
+ TEST_PRINTERINFO_STRING_EXP_ERR(2, drivername, 2, drivername, "xx2-2 drivername", WERR_UNKNOWN_PRINTER_DRIVER);
+ TEST_PRINTERINFO_STRING(2, location, 2, location, "xx2-2 location");
+ /* passing an invalid sepfile will result in WERR_INVALID_SEPARATOR_FILE */
+ TEST_PRINTERINFO_STRING_EXP_ERR(2, sepfile, 2, sepfile, "xx2-2 sepfile", WERR_INVALID_SEPARATOR_FILE);
+ /* passing an invalid printprocessor will result in WERR_UNKNOWN_PRINTPROCESSOR */
+ TEST_PRINTERINFO_STRING_EXP_ERR(2, printprocessor, 2, printprocessor, "xx2-2 printprocessor", WERR_UNKNOWN_PRINTPROCESSOR);
+ TEST_PRINTERINFO_STRING(2, datatype, 2, datatype, "xx2-2 datatype");
+ TEST_PRINTERINFO_STRING(2, parameters, 2, parameters, "xx2-2 parameters");
+
+ for (i=0; i < ARRAY_SIZE(attribute_list); i++) {
+/* TEST_PRINTERINFO_INT_EXP(2, attributes, 1, flags,
+ attribute_list[i],
+ (attribute_list[i] | default_attribute)
+ ); */
+ TEST_PRINTERINFO_INT_EXP(2, attributes, 2, attributes,
+ attribute_list[i],
+ (attribute_list[i] | default_attribute)
+ );
+ TEST_PRINTERINFO_INT_EXP(2, attributes, 4, attributes,
+ attribute_list[i],
+ (attribute_list[i] | default_attribute)
+ );
+ TEST_PRINTERINFO_INT_EXP(2, attributes, 5, attributes,
+ attribute_list[i],
+ (attribute_list[i] | default_attribute)
+ );
+/* TEST_PRINTERINFO_INT_EXP(4, attributes, 1, flags,
+ attribute_list[i],
+ (attribute_list[i] | default_attribute)
+ ); */
+ TEST_PRINTERINFO_INT_EXP(4, attributes, 2, attributes,
+ attribute_list[i],
+ (attribute_list[i] | default_attribute)
+ );
+ TEST_PRINTERINFO_INT_EXP(4, attributes, 4, attributes,
+ attribute_list[i],
+ (attribute_list[i] | default_attribute)
+ );
+ TEST_PRINTERINFO_INT_EXP(4, attributes, 5, attributes,
+ attribute_list[i],
+ (attribute_list[i] | default_attribute)
+ );
+/* TEST_PRINTERINFO_INT_EXP(5, attributes, 1, flags,
+ attribute_list[i],
+ (attribute_list[i] | default_attribute)
+ ); */
+ TEST_PRINTERINFO_INT_EXP(5, attributes, 2, attributes,
+ attribute_list[i],
+ (attribute_list[i] | default_attribute)
+ );
+ TEST_PRINTERINFO_INT_EXP(5, attributes, 4, attributes,
+ attribute_list[i],
+ (attribute_list[i] | default_attribute)
+ );
+ TEST_PRINTERINFO_INT_EXP(5, attributes, 5, attributes,
+ attribute_list[i],
+ (attribute_list[i] | default_attribute)
+ );
+ }
+
+ for (i=0; i < ARRAY_SIZE(status_list); i++) {
+ /* level 2 sets do not stick
+ TEST_PRINTERINFO_INT(2, status, 0, status, status_list[i]);
+ TEST_PRINTERINFO_INT(2, status, 2, status, status_list[i]);
+ TEST_PRINTERINFO_INT(2, status, 6, status, status_list[i]); */
+ TEST_PRINTERINFO_INT(6, status, 0, status, status_list[i]);
+ TEST_PRINTERINFO_INT(6, status, 2, status, status_list[i]);
+ TEST_PRINTERINFO_INT(6, status, 6, status, status_list[i]);
+ }
+
+ /* priorities need to be between 0 and 99
+ passing an invalid priority will result in WERR_INVALID_PRIORITY */
+ TEST_PRINTERINFO_INT(2, priority, 2, priority, 0);
+ TEST_PRINTERINFO_INT(2, priority, 2, priority, 1);
+ TEST_PRINTERINFO_INT(2, priority, 2, priority, 99);
+ /* TEST_PRINTERINFO_INT(2, priority, 2, priority, 100); */
+ TEST_PRINTERINFO_INT(2, defaultpriority,2, defaultpriority, 0);
+ TEST_PRINTERINFO_INT(2, defaultpriority,2, defaultpriority, 1);
+ TEST_PRINTERINFO_INT(2, defaultpriority,2, defaultpriority, 99);
+ /* TEST_PRINTERINFO_INT(2, defaultpriority,2, defaultpriority, 100); */
+
+ TEST_PRINTERINFO_INT(2, starttime, 2, starttime, __LINE__);
+ TEST_PRINTERINFO_INT(2, untiltime, 2, untiltime, __LINE__);
+
+ /* does not stick
+ TEST_PRINTERINFO_INT(2, cjobs, 2, cjobs, __LINE__);
+ TEST_PRINTERINFO_INT(2, averageppm, 2, averageppm, __LINE__); */
+
+ /* does not stick
+ TEST_PRINTERINFO_INT(5, device_not_selected_timeout, 5, device_not_selected_timeout, __LINE__);
+ TEST_PRINTERINFO_INT(5, transmission_retry_timeout, 5, transmission_retry_timeout, __LINE__); */
+
+ /* FIXME: gd also test devmode and secdesc behavior */
+
+ {
+ /* verify composition of level 1 description field */
+ const char *description;
+ const char *tmp;
+
+ q0.in.level = 1;
+ do { TESTGETCALL(GetPrinter, q0) } while (0);
+
+ description = talloc_strdup(tctx, q0.out.info->info1.description);
+
+ q0.in.level = 2;
+ do { TESTGETCALL(GetPrinter, q0) } while (0);
+
+ tmp = talloc_asprintf(tctx, "%s,%s,%s",
+ q0.out.info->info2.printername,
+ q0.out.info->info2.drivername,
+ q0.out.info->info2.location);
+
+ do { STRING_EQUAL(description, tmp, "description")} while (0);
+ }
+
+ return ret;
+}
+
static bool test_ClosePrinter(struct torture_context *tctx,
struct dcerpc_pipe *p,
@@ -1972,12 +2537,45 @@ static bool test_EnumPrinters_old(struct torture_context *tctx, struct dcerpc_pi
return ret;
}
-#if 0
-static bool test_GetPrinterDriver2(struct dcerpc_pipe *p,
+static bool test_GetPrinterDriver(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *handle,
+ const char *driver_name)
+{
+ struct spoolss_GetPrinterDriver r;
+ uint32_t needed;
+
+ r.in.handle = handle;
+ r.in.architecture = "W32X86";
+ r.in.level = 1;
+ r.in.buffer = NULL;
+ r.in.offered = 0;
+ r.out.needed = &needed;
+
+ torture_comment(tctx, "Testing GetPrinterDriver level %d\n", r.in.level);
+
+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinterDriver(p, tctx, &r),
+ "failed to call GetPrinterDriver");
+ if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+ DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
+ data_blob_clear(&blob);
+ r.in.buffer = &blob;
+ r.in.offered = needed;
+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinterDriver(p, tctx, &r),
+ "failed to call GetPrinterDriver");
+ }
+
+ torture_assert_werr_ok(tctx, r.out.result,
+ "failed to call GetPrinterDriver");
+
+ return true;
+}
+
+static bool test_GetPrinterDriver2(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
struct policy_handle *handle,
const char *driver_name)
{
- NTSTATUS status;
struct spoolss_GetPrinterDriver2 r;
uint32_t needed;
uint32_t server_major_version;
@@ -1994,34 +2592,24 @@ static bool test_GetPrinterDriver2(struct dcerpc_pipe *p,
r.out.server_major_version = &server_major_version;
r.out.server_minor_version = &server_minor_version;
- printf("Testing GetPrinterDriver2\n");
-
- status = dcerpc_spoolss_GetPrinterDriver2(p, tctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
- printf("GetPrinterDriver2 failed - %s\n", nt_errstr(status));
- return false;
- }
+ torture_comment(tctx, "Testing GetPrinterDriver2 level %d\n", r.in.level);
+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinterDriver2(p, tctx, &r),
+ "failed to call GetPrinterDriver2");
if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+ DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
+ data_blob_clear(&blob);
+ r.in.buffer = &blob;
r.in.offered = needed;
- status = dcerpc_spoolss_GetPrinterDriver2(p, tctx, &r);
- }
-
- if (!NT_STATUS_IS_OK(status)) {
- printf("GetPrinterDriver2 failed - %s\n",
- nt_errstr(status));
- return false;
+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinterDriver2(p, tctx, &r),
+ "failed to call GetPrinterDriver2");
}
- if (!W_ERROR_IS_OK(r.out.result)) {
- printf("GetPrinterDriver2 failed - %s\n",
- win_errstr(r.out.result));
- return false;
- }
+ torture_assert_werr_ok(tctx, r.out.result,
+ "failed to call GetPrinterDriver2");
return true;
}
-#endif
static bool test_EnumPrinterDrivers_old(struct torture_context *tctx,
struct dcerpc_pipe *p)
@@ -2073,6 +2661,432 @@ static bool test_EnumPrinterDrivers_old(struct torture_context *tctx,
return true;
}
+static bool test_DeletePrinter(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *handle)
+{
+ struct spoolss_DeletePrinter r;
+
+ torture_comment(tctx, "Testing DeletePrinter\n");
+
+ r.in.handle = handle;
+
+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_DeletePrinter(p, tctx, &r),
+ "failed to delete printer");
+ torture_assert_werr_ok(tctx, r.out.result,
+ "failed to delete printer");
+
+ return true;
+}
+
+static bool test_EnumPrinters_findname(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ uint32_t flags,
+ uint32_t level,
+ const char *name,
+ bool *found)
+{
+ struct spoolss_EnumPrinters e;
+ uint32_t count;
+ union spoolss_PrinterInfo *info;
+ uint32_t needed;
+ int i;
+
+ *found = false;
+
+ e.in.flags = flags;
+ e.in.server = NULL;
+ e.in.level = level;
+ e.in.buffer = NULL;
+ e.in.offered = 0;
+ e.out.count = &count;
+ e.out.info = &info;
+ e.out.needed = &needed;
+
+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinters(p, tctx, &e),
+ "failed to enum printers");
+
+ if (W_ERROR_EQUAL(e.out.result, WERR_INSUFFICIENT_BUFFER)) {
+ DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
+ data_blob_clear(&blob);
+ e.in.buffer = &blob;
+ e.in.offered = needed;
+
+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinters(p, tctx, &e),
+ "failed to enum printers");
+ }
+
+ torture_assert_werr_ok(tctx, e.out.result,
+ "failed to enum printers");
+
+ for (i=0; i < count; i++) {
+
+ const char *current = NULL;
+
+ switch (level) {
+ case 1:
+ current = info[i].info1.name;
+ break;
+ }
+
+ if (strequal(current, name)) {
+ *found = true;
+ break;
+ }
+ }
+
+ return true;
+}
+
+static bool test_AddPrinter_wellknown(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ const char *printername,
+ bool ex)
+{
+ WERROR result;
+ struct spoolss_AddPrinter r;
+ struct spoolss_AddPrinterEx rex;
+ struct spoolss_SetPrinterInfoCtr info_ctr;
+ struct spoolss_SetPrinterInfo1 info1;
+ struct spoolss_DevmodeContainer devmode_ctr;
+ struct sec_desc_buf secdesc_ctr;
+ struct spoolss_UserLevelCtr userlevel_ctr;
+ struct policy_handle handle;
+ bool found = false;
+
+ ZERO_STRUCT(devmode_ctr);
+ ZERO_STRUCT(secdesc_ctr);
+ ZERO_STRUCT(userlevel_ctr);
+ ZERO_STRUCT(info1);
+
+ torture_comment(tctx, "Testing AddPrinter%s level 1\n", ex ? "Ex":"");
+
+ /* try to add printer to wellknown printer list (level 1) */
+
+ userlevel_ctr.level = 1;
+
+ info_ctr.info.info1 = &info1;
+ info_ctr.level = 1;
+
+ rex.in.server = NULL;
+ rex.in.info_ctr = &info_ctr;
+ rex.in.devmode_ctr = &devmode_ctr;
+ rex.in.secdesc_ctr = &secdesc_ctr;
+ rex.in.userlevel_ctr = &userlevel_ctr;
+ rex.out.handle = &handle;
+
+ r.in.server = NULL;
+ r.in.info_ctr = &info_ctr;
+ r.in.devmode_ctr = &devmode_ctr;
+ r.in.secdesc_ctr = &secdesc_ctr;
+ r.out.handle = &handle;
+
+ torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+ dcerpc_spoolss_AddPrinter(p, tctx, &r),
+ "failed to add printer");
+ result = ex ? rex.out.result : r.out.result;
+ torture_assert_werr_equal(tctx, result, WERR_INVALID_PRINTER_NAME,
+ "unexpected result code");
+
+ info1.name = printername;
+ info1.flags = PRINTER_ATTRIBUTE_SHARED;
+
+ torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+ dcerpc_spoolss_AddPrinter(p, tctx, &r),
+ "failed to add printer");
+ result = ex ? rex.out.result : r.out.result;
+ torture_assert_werr_equal(tctx, result, WERR_PRINTER_ALREADY_EXISTS,
+ "unexpected result code");
+
+ /* bizarre protocol, WERR_PRINTER_ALREADY_EXISTS means success here,
+ better do a real check to see the printer is really there */
+
+ torture_assert(tctx, test_EnumPrinters_findname(tctx, p,
+ PRINTER_ENUM_NETWORK, 1,
+ printername,
+ &found),
+ "failed to enum printers");
+
+ torture_assert(tctx, found, "failed to find newly added printer");
+
+ info1.flags = 0;
+
+ torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+ dcerpc_spoolss_AddPrinter(p, tctx, &r),
+ "failed to add printer");
+ result = ex ? rex.out.result : r.out.result;
+ torture_assert_werr_equal(tctx, result, WERR_PRINTER_ALREADY_EXISTS,
+ "unexpected result code");
+
+ /* bizarre protocol, WERR_PRINTER_ALREADY_EXISTS means success here,
+ better do a real check to see the printer has really been removed
+ from the well known printer list */
+
+ found = false;
+
+ torture_assert(tctx, test_EnumPrinters_findname(tctx, p,
+ PRINTER_ENUM_NETWORK, 1,
+ printername,
+ &found),
+ "failed to enum printers");
+#if 0
+ torture_assert(tctx, !found, "printer still in well known printer list");
+#endif
+ return true;
+}
+
+static bool test_AddPrinter_normal(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *handle_p,
+ const char *printername,
+ const char *drivername,
+ const char *portname,
+ bool ex)
+{
+ WERROR result;
+ struct spoolss_AddPrinter r;
+ struct spoolss_AddPrinterEx rex;
+ struct spoolss_SetPrinterInfoCtr info_ctr;
+ struct spoolss_SetPrinterInfo2 info2;
+ struct spoolss_DevmodeContainer devmode_ctr;
+ struct sec_desc_buf secdesc_ctr;
+ struct spoolss_UserLevelCtr userlevel_ctr;
+ struct policy_handle handle;
+ bool found = false;
+
+ ZERO_STRUCT(devmode_ctr);
+ ZERO_STRUCT(secdesc_ctr);
+ ZERO_STRUCT(userlevel_ctr);
+
+ torture_comment(tctx, "Testing AddPrinter%s level 2\n", ex ? "Ex":"");
+
+ userlevel_ctr.level = 1;
+
+ rex.in.server = NULL;
+ rex.in.info_ctr = &info_ctr;
+ rex.in.devmode_ctr = &devmode_ctr;
+ rex.in.secdesc_ctr = &secdesc_ctr;
+ rex.in.userlevel_ctr = &userlevel_ctr;
+ rex.out.handle = &handle;
+
+ r.in.server = NULL;
+ r.in.info_ctr = &info_ctr;
+ r.in.devmode_ctr = &devmode_ctr;
+ r.in.secdesc_ctr = &secdesc_ctr;
+ r.out.handle = &handle;
+
+ again:
+
+ /* try to add printer to printer list (level 2) */
+
+ ZERO_STRUCT(info2);
+
+ info_ctr.info.info2 = &info2;
+ info_ctr.level = 2;
+
+ torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+ dcerpc_spoolss_AddPrinter(p, tctx, &r),
+ "failed to add printer");
+ result = ex ? rex.out.result : r.out.result;
+ torture_assert_werr_equal(tctx, result, WERR_INVALID_PRINTER_NAME,
+ "unexpected result code");
+
+ info2.printername = printername;
+
+ torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+ dcerpc_spoolss_AddPrinter(p, tctx, &r),
+ "failed to add printer");
+ result = ex ? rex.out.result : r.out.result;
+
+ if (W_ERROR_EQUAL(result, WERR_PRINTER_ALREADY_EXISTS)) {
+ struct policy_handle printer_handle;
+
+ torture_assert(tctx, call_OpenPrinterEx(tctx, p, printername, &printer_handle),
+ "failed to open printer handle");
+
+ torture_assert(tctx, test_DeletePrinter(tctx, p, &printer_handle),
+ "failed to delete printer");
+
+ torture_assert(tctx, test_ClosePrinter(tctx, p, &printer_handle),
+ "failed to close server handle");
+
+ goto again;
+ }
+
+ torture_assert_werr_equal(tctx, result, WERR_UNKNOWN_PORT,
+ "unexpected result code");
+
+ info2.portname = portname;
+
+ torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+ dcerpc_spoolss_AddPrinter(p, tctx, &r),
+ "failed to add printer");
+ result = ex ? rex.out.result : r.out.result;
+ torture_assert_werr_equal(tctx, result, WERR_UNKNOWN_PRINTER_DRIVER,
+ "unexpected result code");
+
+ info2.drivername = drivername;
+
+ torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+ dcerpc_spoolss_AddPrinter(p, tctx, &r),
+ "failed to add printer");
+ result = ex ? rex.out.result : r.out.result;
+ torture_assert_werr_equal(tctx, result, WERR_UNKNOWN_PRINTPROCESSOR,
+ "unexpected result code");
+
+ info2.printprocessor = "winprint";
+
+ torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+ dcerpc_spoolss_AddPrinter(p, tctx, &r),
+ "failed to add printer");
+ result = ex ? rex.out.result : r.out.result;
+ torture_assert_werr_ok(tctx, result,
+ "failed to add printer");
+
+ *handle_p = handle;
+
+ /* we are paranoid, really check if the printer is there now */
+
+ torture_assert(tctx, test_EnumPrinters_findname(tctx, p,
+ PRINTER_ENUM_LOCAL, 1,
+ printername,
+ &found),
+ "failed to enum printers");
+ torture_assert(tctx, found, "failed to find newly added printer");
+
+ torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, tctx, &rex) :
+ dcerpc_spoolss_AddPrinter(p, tctx, &r),
+ "failed to add printer");
+ result = ex ? rex.out.result : r.out.result;
+ torture_assert_werr_equal(tctx, result, WERR_PRINTER_ALREADY_EXISTS,
+ "unexpected result code");
+
+ return true;
+}
+
+static bool test_AddPrinterEx(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *handle_p,
+ const char *printername,
+ const char *drivername,
+ const char *portname)
+{
+ bool ret = true;
+
+ if (!torture_setting_bool(tctx, "samba3", false)) {
+ if (!test_AddPrinter_wellknown(tctx, p, TORTURE_WELLKNOWN_PRINTER_EX, true)) {
+ torture_comment(tctx, "failed to add printer to well known list\n");
+ ret = false;
+ }
+ }
+
+ if (!test_AddPrinter_normal(tctx, p, handle_p,
+ printername, drivername, portname,
+ true)) {
+ torture_comment(tctx, "failed to add printer to printer list\n");
+ ret = false;
+ }
+
+ return ret;
+}
+
+static bool test_AddPrinter(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *handle_p,
+ const char *printername,
+ const char *drivername,
+ const char *portname)
+{
+ bool ret = true;
+
+ if (!torture_setting_bool(tctx, "samba3", false)) {
+ if (!test_AddPrinter_wellknown(tctx, p, TORTURE_WELLKNOWN_PRINTER, false)) {
+ torture_comment(tctx, "failed to add printer to well known list\n");
+ ret = false;
+ }
+ }
+
+ if (!test_AddPrinter_normal(tctx, p, handle_p,
+ printername, drivername, portname,
+ false)) {
+ torture_comment(tctx, "failed to add printer to printer list\n");
+ ret = false;
+ }
+
+ return ret;
+}
+
+static bool test_printer_info(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *handle)
+{
+ bool ret = true;
+
+ if (!test_PrinterInfo(tctx, p, handle)) {
+ ret = false;
+ }
+
+ if (!test_SetPrinter_errors(tctx, p, handle)) {
+ ret = false;
+ }
+
+ return ret;
+}
+
+static bool test_printer(struct torture_context *tctx,
+ struct dcerpc_pipe *p)
+{
+ bool ret = true;
+ struct policy_handle handle[2];
+ bool found = false;
+ const char *drivername = "Microsoft XPS Document Writer";
+ const char *portname = "LPT1:";
+
+ /* test printer created via AddPrinter */
+
+ if (!test_AddPrinter(tctx, p, &handle[0], TORTURE_PRINTER, drivername, portname)) {
+ return false;
+ }
+
+ if (!test_printer_info(tctx, p, &handle[0])) {
+ ret = false;
+ }
+
+ if (!test_DeletePrinter(tctx, p, &handle[0])) {
+ ret = false;
+ }
+
+ if (!test_EnumPrinters_findname(tctx, p, PRINTER_ENUM_LOCAL, 1,
+ TORTURE_PRINTER, &found)) {
+ ret = false;
+ }
+
+ torture_assert(tctx, !found, "deleted printer still there");
+
+ /* test printer created via AddPrinterEx */
+
+ if (!test_AddPrinterEx(tctx, p, &handle[1], TORTURE_PRINTER_EX, drivername, portname)) {
+ return false;
+ }
+
+ if (!test_printer_info(tctx, p, &handle[1])) {
+ ret = false;
+ }
+
+ if (!test_DeletePrinter(tctx, p, &handle[1])) {
+ ret = false;
+ }
+
+ if (!test_EnumPrinters_findname(tctx, p, PRINTER_ENUM_LOCAL, 1,
+ TORTURE_PRINTER_EX, &found)) {
+ ret = false;
+ }
+
+ torture_assert(tctx, !found, "deleted printer still there");
+
+ return ret;
+}
+
bool torture_rpc_spoolss(struct torture_context *torture)
{
NTSTATUS status;
@@ -2087,7 +3101,7 @@ bool torture_rpc_spoolss(struct torture_context *torture)
ctx = talloc_zero(torture, struct test_spoolss_context);
- ret &= test_OpenPrinter_server(torture, p, ctx);
+ ret &= test_OpenPrinter_server(torture, p, &ctx->server_handle);
ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "W3SvcInstalled");
ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "BeepEnabled");
@@ -2129,3 +3143,15 @@ bool torture_rpc_spoolss(struct torture_context *torture)
return ret;
}
+
+struct torture_suite *torture_rpc_spoolss_printer(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "SPOOLSS-PRINTER");
+
+ struct torture_rpc_tcase *tcase = torture_suite_add_rpc_iface_tcase(suite,
+ "printer", &ndr_table_spoolss);
+
+ torture_rpc_tcase_add_test(tcase, "printer", test_printer);
+
+ return suite;
+}
diff --git a/source4/torture/smb2/config.mk b/source4/torture/smb2/config.mk
index bc4fc15e07..b321b41bdd 100644
--- a/source4/torture/smb2/config.mk
+++ b/source4/torture/smb2/config.mk
@@ -22,6 +22,7 @@ TORTURE_SMB2_OBJ_FILES = $(addprefix $(torturesrcdir)/smb2/, \
smb2.o \
durable_open.o \
oplocks.o \
+ dir.o \
lease.o \
create.o \
read.o \
diff --git a/source4/torture/smb2/connect.c b/source4/torture/smb2/connect.c
index bd1abce827..fd32b52111 100644
--- a/source4/torture/smb2/connect.c
+++ b/source4/torture/smb2/connect.c
@@ -200,6 +200,8 @@ bool torture_smb2_connect(struct torture_context *torture)
return false;
}
+ smb2_util_unlink(tree, "test9.dat");
+
h1 = torture_smb2_createfile(tree, "test9.dat");
h2 = torture_smb2_createfile(tree, "test9.dat");
status = torture_smb2_write(torture, tree, h1);
diff --git a/source4/torture/smb2/dir.c b/source4/torture/smb2/dir.c
index 58cf2229bc..4b44a50bbd 100644
--- a/source4/torture/smb2/dir.c
+++ b/source4/torture/smb2/dir.c
@@ -1,20 +1,22 @@
-/*
+/*
Unix SMB/CIFS implementation.
SMB2 dir list test suite
Copyright (C) Andrew Tridgell 2005
-
+ Copyright (C) Zachary Loafman 2009
+ Copyright (C) Aravind Srinivasan 2009
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -22,72 +24,1307 @@
#include "includes.h"
#include "libcli/smb2/smb2.h"
#include "libcli/smb2/smb2_calls.h"
+#include "libcli/smb_composite/smb_composite.h"
+#include "libcli/raw/libcliraw.h"
+#include "libcli/raw/raw_proto.h"
+#include "libcli/libcli.h"
#include "torture/torture.h"
#include "torture/smb2/proto.h"
+#include "torture/util.h"
+
+#include "system/filesys.h"
+
+#define CHECK_STATUS(status, correct) do { \
+ if (!NT_STATUS_EQUAL(status, correct)) { \
+ torture_result(tctx, TORTURE_FAIL, __location__": \
+ Incorrect status %s - should be %s", \
+ nt_errstr(status), nt_errstr(correct)); \
+ ret = false; \
+ goto done; \
+ }} while (0)
+
+#define CHECK_VALUE(v, correct) torture_assert_int_equal(tctx, (v), \
+ (correct), "incorrect value");
+
+#define DNAME "smb2_dir"
+#define NFILES 100
+
+struct file_elem {
+ char *name;
+ bool found;
+};
+
+static NTSTATUS populate_tree(struct torture_context *tctx,
+ TALLOC_CTX *mem_ctx,
+ struct smb2_tree *tree,
+ struct file_elem *files,
+ int nfiles,
+ struct smb2_handle *h_out)
+{
+ struct smb2_create create;
+ NTSTATUS status;
+ bool ret;
+ int i;
+
+ smb2_deltree(tree, DNAME);
+
+ ZERO_STRUCT(create);
+ create.in.desired_access = SEC_RIGHTS_DIR_ALL;
+ create.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
+ create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
+ create.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
+ NTCREATEX_SHARE_ACCESS_WRITE |
+ NTCREATEX_SHARE_ACCESS_DELETE;
+ create.in.create_disposition = NTCREATEX_DISP_CREATE;
+ create.in.fname = DNAME;
+
+ status = smb2_create(tree, mem_ctx, &create);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ *h_out = create.out.file.handle;
+
+ ZERO_STRUCT(create);
+ create.in.desired_access = SEC_RIGHTS_FILE_ALL;
+ create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+ create.in.create_disposition = NTCREATEX_DISP_CREATE;
+
+ for (i = 0; i < nfiles; i++) {
+ files[i].name = generate_random_str(tctx, 8);
+ create.in.fname = talloc_asprintf(mem_ctx, "%s\\%s",
+ DNAME, files[i].name);
+ status = smb2_create(tree, mem_ctx, &create);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ smb2_util_close(tree, create.out.file.handle);
+ }
+ done:
+ return status;
+}
/*
test find continue
*/
-static bool torture_smb2_find_dir(struct smb2_tree *tree)
+
+static bool test_find(struct torture_context *tctx,
+ struct smb2_tree *tree)
{
- struct smb2_handle handle;
- NTSTATUS status;
- int i;
+ TALLOC_CTX *mem_ctx = talloc_new(tctx);
+ struct smb2_handle h;
struct smb2_find f;
- bool ret = true;
union smb_search_data *d;
+ struct file_elem files[NFILES] = {};
+ NTSTATUS status;
+ bool ret = true;
uint_t count;
+ int i, j, file_count = 0;
- status = smb2_util_roothandle(tree, &handle);
- if (!NT_STATUS_IS_OK(status)) {
- return false;
+ status = populate_tree(tctx, mem_ctx, tree, files, NFILES, &h);
+
+ ZERO_STRUCT(f);
+ f.in.file.handle = h;
+ f.in.pattern = "*";
+ f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE;
+ f.in.max_response_size = 0x100;
+ f.in.level = SMB2_FIND_BOTH_DIRECTORY_INFO;
+
+ do {
+ status = smb2_find_level(tree, tree, &f, &count, &d);
+ if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
+ break;
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ for (i = 0; i < count; i++) {
+ bool expected;
+ const char *found = d[i].both_directory_info.name.s;
+
+ if (!strcmp(found, ".") || !strcmp(found, ".."))
+ continue;
+
+ expected = false;
+ for (j = 0; j < NFILES; j++) {
+ if (!strcmp(files[j].name, found)) {
+ files[j].found = true;
+ expected = true;
+ break;
+ }
+ }
+
+ if (expected)
+ continue;
+
+ torture_result(tctx, TORTURE_FAIL,
+ "(%s): didn't expect %s\n",
+ __location__, found);
+ ret = false;
+ goto done;
+ }
+
+ file_count = file_count + i;
+ f.in.continue_flags = 0;
+ f.in.max_response_size = 4096;
+ } while (count != 0);
+
+ CHECK_VALUE(file_count, NFILES + 2);
+
+ for (i = 0; i < NFILES; i++) {
+ if (files[j].found)
+ continue;
+
+ torture_result(tctx, TORTURE_FAIL,
+ "(%s): expected to find %s, but didn't\n",
+ __location__, files[j].name);
+ ret = false;
+ goto done;
}
+ done:
+ smb2_deltree(tree, DNAME);
+ talloc_free(mem_ctx);
+
+ return ret;
+}
+
+/*
+ test fixed enumeration
+*/
+
+static bool test_fixed(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(tctx);
+ struct smb2_create create;
+ struct smb2_handle h, h2;
+ struct smb2_find f;
+ union smb_search_data *d;
+ struct file_elem files[NFILES] = {};
+ NTSTATUS status;
+ bool ret = true;
+ uint_t count;
+ int i;
+
+ status = populate_tree(tctx, mem_ctx, tree, files, NFILES, &h);
+
+ ZERO_STRUCT(create);
+ create.in.desired_access = SEC_RIGHTS_DIR_ALL;
+ create.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
+ create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
+ create.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
+ NTCREATEX_SHARE_ACCESS_WRITE |
+ NTCREATEX_SHARE_ACCESS_DELETE;
+ create.in.create_disposition = NTCREATEX_DISP_OPEN;
+ create.in.fname = DNAME;
+
+ status = smb2_create(tree, mem_ctx, &create);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ h2 = create.out.file.handle;
+
ZERO_STRUCT(f);
- f.in.file.handle = handle;
+ f.in.file.handle = h;
f.in.pattern = "*";
f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE;
f.in.max_response_size = 0x100;
f.in.level = SMB2_FIND_BOTH_DIRECTORY_INFO;
+ /* Start enumeration on h, then delete all from h2 */
+ status = smb2_find_level(tree, tree, &f, &count, &d);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ f.in.file.handle = h2;
+
do {
status = smb2_find_level(tree, tree, &f, &count, &d);
- if (!NT_STATUS_IS_OK(status)) {
- printf("SMB2_FIND_ID_BOTH_DIRECTORY_INFO failed - %s\n", nt_errstr(status));
+ if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
break;
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ for (i = 0; i < count; i++) {
+ const char *found = d[i].both_directory_info.name.s;
+ char *path = talloc_asprintf(mem_ctx, "%s\\%s",
+ DNAME, found);
+
+ if (!strcmp(found, ".") || !strcmp(found, ".."))
+ continue;
+
+ status = smb2_util_unlink(tree, path);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ talloc_free(path);
}
- printf("Got %d files\n", count);
- for (i=0;i<count;i++) {
- printf("\t'%s'\n",
- d[i].both_directory_info.name.s);
+ f.in.continue_flags = 0;
+ f.in.max_response_size = 4096;
+ } while (count != 0);
+
+ /* Now finish h enumeration. */
+ f.in.file.handle = h;
+
+ do {
+ status = smb2_find_level(tree, tree, &f, &count, &d);
+ if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
+ break;
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ for (i = 0; i < count; i++) {
+ const char *found = d[i].both_directory_info.name.s;
+
+ if (!strcmp(found, ".") || !strcmp(found, ".."))
+ continue;
+
+ torture_result(tctx, TORTURE_FAIL,
+ "(%s): didn't expect %s\n",
+ __location__, found);
+ ret = false;
+ goto done;
}
+
f.in.continue_flags = 0;
f.in.max_response_size = 4096;
} while (count != 0);
+ done:
+ smb2_util_close(tree, h);
+ smb2_util_close(tree, h2);
+ smb2_deltree(tree, DNAME);
+ talloc_free(mem_ctx);
return ret;
}
+static struct {
+ const char *name;
+ uint8_t level;
+ enum smb_search_data_level data_level;
+ int name_offset;
+ int resume_key_offset;
+ uint32_t capability_mask;
+ NTSTATUS status;
+ union smb_search_data data;
+} levels[] = {
+ {"SMB2_FIND_DIRECTORY_INFO",
+ SMB2_FIND_DIRECTORY_INFO, RAW_SEARCH_DATA_DIRECTORY_INFO,
+ offsetof(union smb_search_data, directory_info.name.s),
+ offsetof(union smb_search_data, directory_info.file_index),
+ },
+ {"SMB2_FIND_FULL_DIRECTORY_INFO",
+ SMB2_FIND_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO,
+ offsetof(union smb_search_data, full_directory_info.name.s),
+ offsetof(union smb_search_data, full_directory_info.file_index),
+ },
+ {"SMB2_FIND_NAME_INFO",
+ SMB2_FIND_NAME_INFO, RAW_SEARCH_DATA_NAME_INFO,
+ offsetof(union smb_search_data, name_info.name.s),
+ offsetof(union smb_search_data, name_info.file_index),
+ },
+ {"SMB2_FIND_BOTH_DIRECTORY_INFO",
+ SMB2_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO,
+ offsetof(union smb_search_data, both_directory_info.name.s),
+ offsetof(union smb_search_data, both_directory_info.file_index),
+ },
+ {"SMB2_FIND_ID_FULL_DIRECTORY_INFO",
+ SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO,
+ offsetof(union smb_search_data, id_full_directory_info.name.s),
+ offsetof(union smb_search_data, id_full_directory_info.file_index),
+ },
+ {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO",
+ SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO,
+ offsetof(union smb_search_data, id_both_directory_info.name.s),
+ offsetof(union smb_search_data, id_both_directory_info.file_index),
+ }
+};
+
+/*
+ extract the name from a smb_data structure and level
+*/
+static const char *extract_name(union smb_search_data *data,
+ uint8_t level,
+ enum smb_search_data_level data_level)
+{
+ int i;
+ for (i=0;i<ARRAY_SIZE(levels);i++) {
+ if (level == levels[i].level &&
+ data_level == levels[i].data_level) {
+ return *(const char **)(levels[i].name_offset + (char *)data);
+ }
+ }
+ return NULL;
+}
+
+/* find a level in the table by name */
+static union smb_search_data *find(const char *name)
+{
+ int i;
+ for (i=0;i<ARRAY_SIZE(levels);i++) {
+ if (NT_STATUS_IS_OK(levels[i].status) &&
+ strcmp(levels[i].name, name) == 0) {
+ return &levels[i].data;
+ }
+ }
+ return NULL;
+}
+
+static bool fill_level_data(TALLOC_CTX *mem_ctx,
+ union smb_search_data *data,
+ union smb_search_data *d,
+ uint_t count,
+ uint8_t level,
+ enum smb_search_data_level data_level)
+{
+ int i;
+ const char *sname = NULL;
+ for (i=0; i < count ; i++) {
+ sname = extract_name(&d[i], level, data_level);
+ if (sname == NULL)
+ return false;
+ if (!strcmp(sname, ".") || !strcmp(sname, ".."))
+ continue;
+ *data = d[i];
+ }
+ return true;
+}
+
+
+NTSTATUS torture_single_file_search(struct smb2_tree *tree,
+ TALLOC_CTX *mem_ctx,
+ const char *pattern,
+ uint8_t level,
+ enum smb_search_data_level data_level,
+ int index,
+ union smb_search_data *d,
+ uint_t *count,
+ struct smb2_handle *h)
+{
+ struct smb2_find f;
+ NTSTATUS status;
+
+ ZERO_STRUCT(f);
+ f.in.file.handle = *h;
+ f.in.pattern = pattern;
+ f.in.continue_flags = SMB2_CONTINUE_FLAG_RESTART;
+ f.in.max_response_size = 0x100;
+ f.in.level = level;
+
+ status = smb2_find_level(tree, tree, &f, count, &d);
+ if (NT_STATUS_IS_OK(status))
+ fill_level_data(mem_ctx, &levels[index].data, d, *count, level,
+ data_level);
+ return status;
+}
+
+/*
+ basic testing of all File Information Classes using a single file
+*/
+static bool test_one_file(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(tctx);
+ bool ret = true;
+ const char *fname = "torture_search.txt";
+ NTSTATUS status;
+ int i;
+ uint_t count;
+ union smb_fileinfo all_info2, alt_info, internal_info;
+ union smb_search_data *s;
+ union smb_search_data d;
+ struct smb2_handle h, h2;
+
+ status = torture_smb2_testdir(tree, DNAME, &h);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ status = smb2_create_complex_file(tree, DNAME "\\torture_search.txt",
+ &h2);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ /* call all the File Information Classes */
+ for (i=0;i<ARRAY_SIZE(levels);i++) {
+ torture_comment(tctx, "testing %s %d\n", levels[i].name,
+ levels[i].level);
+
+ levels[i].status = torture_single_file_search(tree, mem_ctx,
+ fname, levels[i].level, levels[i].data_level,
+ i, &d, &count, &h);
+ CHECK_STATUS(levels[i].status, NT_STATUS_OK);
+ }
+
+ /* get the all_info file into to check against */
+ all_info2.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
+ all_info2.generic.in.file.handle = h2;
+ status = smb2_getinfo_file(tree, tctx, &all_info2);
+ torture_assert_ntstatus_ok(tctx, status,
+ "RAW_FILEINFO_ALL_INFO failed");
+
+ alt_info.generic.level = RAW_FILEINFO_ALT_NAME_INFORMATION;
+ alt_info.generic.in.file.handle = h2;
+ status = smb2_getinfo_file(tree, tctx, &alt_info);
+ torture_assert_ntstatus_ok(tctx, status,
+ "RAW_FILEINFO_ALT_NAME_INFO failed");
+
+ internal_info.generic.level = RAW_FILEINFO_INTERNAL_INFORMATION;
+ internal_info.generic.in.file.handle = h2;
+ status = smb2_getinfo_file(tree, tctx, &internal_info);
+ torture_assert_ntstatus_ok(tctx, status,
+ "RAW_FILEINFO_INTERNAL_INFORMATION failed");
+
+#define CHECK_VAL(name, sname1, field1, v, sname2, field2) do { \
+ s = find(name); \
+ if (s) { \
+ if ((s->sname1.field1) != (v.sname2.out.field2)) { \
+ printf("(%s) %s/%s [0x%x] != %s/%s [0x%x]\n", \
+ __location__, \
+ #sname1, #field1, (int)s->sname1.field1, \
+ #sname2, #field2, (int)v.sname2.out.field2); \
+ ret = false; \
+ } \
+ }} while (0)
+
+#define CHECK_TIME(name, sname1, field1, v, sname2, field2) do { \
+ s = find(name); \
+ if (s) { \
+ if (s->sname1.field1 != \
+ (~1 & nt_time_to_unix(v.sname2.out.field2))) { \
+ printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \
+ __location__, \
+ #sname1, #field1, \
+ timestring(tctx, s->sname1.field1), \
+ #sname2, #field2, \
+ nt_time_string(tctx, v.sname2.out.field2)); \
+ ret = false; \
+ } \
+ }} while (0)
+
+#define CHECK_NTTIME(name, sname1, field1, v, sname2, field2) do { \
+ s = find(name); \
+ if (s) { \
+ if (s->sname1.field1 != v.sname2.out.field2) { \
+ printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \
+ __location__, \
+ #sname1, #field1, \
+ nt_time_string(tctx, s->sname1.field1), \
+ #sname2, #field2, \
+ nt_time_string(tctx, v.sname2.out.field2)); \
+ ret = false; \
+ } \
+ }} while (0)
+
+#define CHECK_STR(name, sname1, field1, v, sname2, field2) do { \
+ s = find(name); \
+ if (s) { \
+ if (!s->sname1.field1 || \
+ strcmp(s->sname1.field1, v.sname2.out.field2.s)) { \
+ printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \
+ __location__, \
+ #sname1, #field1, s->sname1.field1, \
+ #sname2, #field2, v.sname2.out.field2.s); \
+ ret = false; \
+ } \
+ }} while (0)
+
+#define CHECK_WSTR(name, sname1, field1, v, sname2, field2, flags) do { \
+ s = find(name); \
+ if (s) { \
+ if (!s->sname1.field1.s || \
+ strcmp(s->sname1.field1.s, v.sname2.out.field2.s)) { \
+ printf("(%s) %s/%s [%s] != %s/%s [%s]\n", \
+ __location__, \
+ #sname1, #field1, s->sname1.field1.s, \
+ #sname2, #field2, v.sname2.out.field2.s); \
+ ret = false; \
+ } \
+ }} while (0)
+
+#define CHECK_NAME(name, sname1, field1, fname, flags) do { \
+ s = find(name); \
+ if (s) { \
+ if (!s->sname1.field1.s || \
+ strcmp(s->sname1.field1.s, fname)) { \
+ printf("(%s) %s/%s [%s] != %s\n", \
+ __location__, \
+ #sname1, #field1, s->sname1.field1.s, \
+ fname); \
+ ret = false; \
+ } \
+ }} while (0)
+
+#define CHECK_UNIX_NAME(name, sname1, field1, fname, flags) do { \
+ s = find(name); \
+ if (s) { \
+ if (!s->sname1.field1 || \
+ strcmp(s->sname1.field1, fname)) { \
+ printf("(%s) %s/%s [%s] != %s\n", \
+ __location__, \
+ #sname1, #field1, s->sname1.field1, \
+ fname); \
+ ret = false; \
+ } \
+ }} while (0)
+
+ /* check that all the results are as expected */
+ CHECK_VAL("SMB2_FIND_DIRECTORY_INFO", directory_info, attrib, all_info2, all_info2, attrib);
+ CHECK_VAL("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, attrib, all_info2, all_info2, attrib);
+ CHECK_VAL("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, attrib, all_info2, all_info2, attrib);
+ CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, attrib, all_info2, all_info2, attrib);
+ CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, attrib, all_info2, all_info2, attrib);
+
+ CHECK_NTTIME("SMB2_FIND_DIRECTORY_INFO", directory_info, write_time, all_info2, all_info2, write_time);
+ CHECK_NTTIME("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, write_time, all_info2, all_info2, write_time);
+ CHECK_NTTIME("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, write_time, all_info2, all_info2, write_time);
+ CHECK_NTTIME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, write_time, all_info2, all_info2, write_time);
+ CHECK_NTTIME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, write_time, all_info2, all_info2, write_time);
+
+ CHECK_NTTIME("SMB2_FIND_DIRECTORY_INFO", directory_info, create_time, all_info2, all_info2, create_time);
+ CHECK_NTTIME("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, create_time, all_info2, all_info2, create_time);
+ CHECK_NTTIME("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, create_time, all_info2, all_info2, create_time);
+ CHECK_NTTIME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, create_time, all_info2, all_info2, create_time);
+ CHECK_NTTIME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, create_time, all_info2, all_info2, create_time);
+ CHECK_NTTIME("SMB2_FIND_DIRECTORY_INFO", directory_info, access_time, all_info2, all_info2, access_time);
+ CHECK_NTTIME("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, access_time, all_info2, all_info2, access_time);
+ CHECK_NTTIME("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, access_time, all_info2, all_info2, access_time);
+ CHECK_NTTIME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, access_time, all_info2, all_info2, access_time);
+ CHECK_NTTIME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, access_time, all_info2, all_info2, access_time);
+
+ CHECK_NTTIME("SMB2_FIND_DIRECTORY_INFO", directory_info, change_time, all_info2, all_info2, change_time);
+ CHECK_NTTIME("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, change_time, all_info2, all_info2, change_time);
+ CHECK_NTTIME("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, change_time, all_info2, all_info2, change_time);
+ CHECK_NTTIME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, change_time, all_info2, all_info2, change_time);
+ CHECK_NTTIME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, change_time, all_info2, all_info2, change_time);
+
+ CHECK_VAL("SMB2_FIND_DIRECTORY_INFO", directory_info, size, all_info2, all_info2, size);
+ CHECK_VAL("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, size, all_info2, all_info2, size);
+ CHECK_VAL("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, size, all_info2, all_info2, size);
+ CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, size, all_info2, all_info2, size);
+ CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, size, all_info2, all_info2, size);
+
+ CHECK_VAL("SMB2_FIND_DIRECTORY_INFO", directory_info, alloc_size, all_info2, all_info2, alloc_size);
+ CHECK_VAL("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, alloc_size, all_info2, all_info2, alloc_size);
+ CHECK_VAL("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, alloc_size, all_info2, all_info2, alloc_size);
+ CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, alloc_size, all_info2, all_info2, alloc_size);
+ CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, alloc_size, all_info2, all_info2, alloc_size);
+
+ CHECK_VAL("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, ea_size, all_info2, all_info2, ea_size);
+ CHECK_VAL("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, ea_size, all_info2, all_info2, ea_size);
+ CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, ea_size, all_info2, all_info2, ea_size);
+ CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, ea_size, all_info2, all_info2, ea_size);
+
+ CHECK_WSTR("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, short_name, alt_info, alt_name_info, fname, STR_UNICODE);
+
+ CHECK_NAME("SMB2_FIND_DIRECTORY_INFO", directory_info, name, fname, STR_TERMINATE_ASCII);
+ CHECK_NAME("SMB2_FIND_FULL_DIRECTORY_INFO", full_directory_info, name, fname, STR_TERMINATE_ASCII);
+ CHECK_NAME("SMB2_FIND_NAME_INFO", name_info, name, fname, STR_TERMINATE_ASCII);
+ CHECK_NAME("SMB2_FIND_BOTH_DIRECTORY_INFO", both_directory_info, name, fname, STR_TERMINATE_ASCII);
+ CHECK_NAME("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, name, fname, STR_TERMINATE_ASCII);
+ CHECK_NAME("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, name, fname, STR_TERMINATE_ASCII);
+ CHECK_VAL("SMB2_FIND_ID_FULL_DIRECTORY_INFO", id_full_directory_info, file_id, internal_info, internal_information, file_id);
+
+ CHECK_VAL("SMB2_FIND_ID_BOTH_DIRECTORY_INFO", id_both_directory_info, file_id, internal_info, internal_information, file_id);
+
+done:
+ smb2_util_close(tree, h);
+ smb2_util_unlink(tree, fname);
+ talloc_free(mem_ctx);
+
+ return ret;
+}
+
+
+struct multiple_result {
+ TALLOC_CTX *tctx;
+ int count;
+ union smb_search_data *list;
+};
+
+bool fill_result(void *private_data,
+ union smb_search_data *file,
+ int count,
+ uint8_t level,
+ enum smb_search_data_level data_level)
+{
+ int i;
+ const char *sname;
+ struct multiple_result *data = (struct multiple_result *)private_data;
+
+ for (i=0; i<count; i++) {
+ sname = extract_name(&file[i], level, data_level);
+ if (!strcmp(sname, ".") || !(strcmp(sname, "..")))
+ continue;
+ data->count++;
+ data->list = talloc_realloc(data->tctx,
+ data->list,
+ union smb_search_data,
+ data->count);
+ data->list[data->count-1] = file[i];
+ }
+ return true;
+}
+
+enum continue_type {CONT_SINGLE, CONT_INDEX, CONT_RESTART};
+
+static NTSTATUS multiple_smb2_search(struct smb2_tree *tree,
+ TALLOC_CTX *tctx,
+ const char *pattern,
+ uint8_t level,
+ enum smb_search_data_level data_level,
+ enum continue_type cont_type,
+ void *data,
+ struct smb2_handle *h)
+{
+ struct smb2_find f;
+ bool ret = true;
+ uint_t count = 0;
+ union smb_search_data *d;
+ NTSTATUS status;
+ struct multiple_result *result = (struct multiple_result *)data;
+
+ ZERO_STRUCT(f);
+ f.in.file.handle = *h;
+ f.in.pattern = pattern;
+ f.in.max_response_size = 0x1000;
+ f.in.level = level;
+
+ /* The search should start from the beginning everytime */
+ f.in.continue_flags = SMB2_CONTINUE_FLAG_RESTART;
+
+ do {
+ status = smb2_find_level(tree, tree, &f, &count, &d);
+ if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
+ break;
+ CHECK_STATUS(status, NT_STATUS_OK);
+ if (!fill_result(result, d, count, level, data_level)) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /*
+ * After the first iteration is complete set the CONTINUE
+ * FLAGS appropriately
+ */
+ switch (cont_type) {
+ case CONT_INDEX:
+ f.in.continue_flags = SMB2_CONTINUE_FLAG_INDEX;
+ break;
+ case CONT_SINGLE:
+ f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE;
+ break;
+ case CONT_RESTART:
+ default:
+ /* we should prevent staying in the loop forever */
+ f.in.continue_flags = 0;
+ break;
+ }
+ } while (count != 0);
+done:
+ return status;
+}
+
+
+static enum smb_search_data_level compare_data_level;
+uint8_t level_sort;
-/*
- basic testing of directory listing with continue
+static int search_compare(union smb_search_data *d1,
+ union smb_search_data *d2)
+{
+ const char *s1, *s2;
+
+ s1 = extract_name(d1, level_sort, compare_data_level);
+ s2 = extract_name(d2, level_sort, compare_data_level);
+ return strcmp_safe(s1, s2);
+}
+
+/*
+ basic testing of search calls using many files
*/
-bool torture_smb2_dir(struct torture_context *torture)
+static bool test_many_files(struct torture_context *tctx,
+ struct smb2_tree *tree)
{
- TALLOC_CTX *mem_ctx = talloc_new(NULL);
- struct smb2_tree *tree;
+ TALLOC_CTX *mem_ctx = talloc_new(tctx);
+ const int num_files = 700;
+ int i, t;
+ char *fname;
bool ret = true;
+ NTSTATUS status;
+ struct multiple_result result;
+ struct smb2_create create;
+ struct smb2_handle h;
+ struct {
+ const char *name;
+ const char *cont_name;
+ uint8_t level;
+ enum smb_search_data_level data_level;
+ enum continue_type cont_type;
+ } search_types[] = {
+ {"SMB2_FIND_BOTH_DIRECTORY_INFO", "SINGLE", SMB2_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO, CONT_SINGLE},
+ {"SMB2_FIND_BOTH_DIRECTORY_INFO", "INDEX", SMB2_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO, CONT_INDEX},
+ {"SMB2_FIND_BOTH_DIRECTORY_INFO", "RESTART", SMB2_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO, CONT_RESTART},
+ {"SMB2_FIND_DIRECTORY_INFO", "SINGLE", SMB2_FIND_DIRECTORY_INFO, RAW_SEARCH_DATA_DIRECTORY_INFO, CONT_SINGLE},
+ {"SMB2_FIND_DIRECTORY_INFO", "INDEX", SMB2_FIND_DIRECTORY_INFO, RAW_SEARCH_DATA_DIRECTORY_INFO, CONT_INDEX},
+ {"SMB2_FIND_DIRECTORY_INFO", "RESTART", SMB2_FIND_DIRECTORY_INFO, RAW_SEARCH_DATA_DIRECTORY_INFO, CONT_RESTART},
+ {"SMB2_FIND_FULL_DIRECTORY_INFO", "SINGLE", SMB2_FIND_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO, CONT_SINGLE},
+ {"SMB2_FIND_FULL_DIRECTORY_INFO", "INDEX", SMB2_FIND_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO, CONT_INDEX},
+ {"SMB2_FIND_FULL_DIRECTORY_INFO", "RESTART", SMB2_FIND_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO, CONT_RESTART},
+ {"SMB2_FIND_ID_FULL_DIRECTORY_INFO", "SINGLE", SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, CONT_SINGLE},
+ {"SMB2_FIND_ID_FULL_DIRECTORY_INFO", "INDEX", SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, CONT_INDEX},
+ {"SMB2_FIND_ID_FULL_DIRECTORY_INFO", "RESTART", SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, CONT_RESTART},
+ {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "SINGLE", SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_SINGLE},
+ {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "INDEX", SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_INDEX},
+ {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "RESTART", SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_RESTART}
+ };
- if (!torture_smb2_connection(torture, &tree)) {
+ smb2_deltree(tree, DNAME);
+ status = torture_smb2_testdir(tree, DNAME, &h);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ torture_comment(tctx, "Testing with %d files\n", num_files);
+ ZERO_STRUCT(create);
+ create.in.desired_access = SEC_RIGHTS_FILE_ALL;
+ create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+ create.in.create_disposition = NTCREATEX_DISP_CREATE;
+
+ for (i=num_files-1;i>=0;i--) {
+ fname = talloc_asprintf(mem_ctx, DNAME "\\t%03d-%d.txt", i, i);
+ create.in.fname = talloc_asprintf(mem_ctx, "%s", fname);
+ status = smb2_create(tree, mem_ctx, &create);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ smb2_util_close(tree, create.out.file.handle);
+ talloc_free(fname);
+ }
+
+ for (t=0;t<ARRAY_SIZE(search_types);t++) {
+ ZERO_STRUCT(result);
+ result.tctx = talloc_new(tctx);
+
+ torture_comment(tctx,
+ "Continue %s via %s\n", search_types[t].name,
+ search_types[t].cont_name);
+ status = multiple_smb2_search(tree, tctx, "*",
+ search_types[t].level,
+ search_types[t].data_level,
+ search_types[t].cont_type,
+ &result, &h);
+
+ CHECK_VALUE(result.count, num_files);
+
+ compare_data_level = search_types[t].data_level;
+ level_sort = search_types[t].level;
+
+ qsort(result.list, result.count, sizeof(result.list[0]),
+ QSORT_CAST search_compare);
+
+ for (i=0;i<result.count;i++) {
+ const char *s;
+ enum smb_search_level level;
+ level = RAW_SEARCH_SMB2;
+ s = extract_name(&result.list[i],
+ search_types[t].level,
+ compare_data_level);
+ fname = talloc_asprintf(mem_ctx, "t%03d-%d.txt", i, i);
+ torture_assert_str_equal(tctx, fname, s,
+ "Incorrect name");
+ talloc_free(fname);
+ }
+ talloc_free(result.tctx);
+ }
+
+done:
+ smb2_util_close(tree, h);
+ smb2_deltree(tree, DNAME);
+ talloc_free(mem_ctx);
+
+ return ret;
+}
+
+/*
+ check a individual file result
+*/
+static bool check_result(struct multiple_result *result,
+ const char *name,
+ bool exist,
+ uint32_t attrib)
+{
+ int i;
+ for (i=0;i<result->count;i++) {
+ if (strcmp(name,
+ result->list[i].both_directory_info.name.s) == 0) {
+ break;
+ }
+ }
+ if (i == result->count) {
+ if (exist) {
+ printf("failed: '%s' should exist with attribute %s\n",
+ name, attrib_string(result->list, attrib));
+ return false;
+ }
+ return true;
+ }
+
+ if (!exist) {
+ printf("failed: '%s' should NOT exist (has attribute %s)\n",
+ name, attrib_string(result->list,
+ result->list[i].both_directory_info.attrib));
return false;
}
- ret &= torture_smb2_find_dir(tree);
+ if ((result->list[i].both_directory_info.attrib&0xFFF) != attrib) {
+ printf("failed: '%s' should have attribute 0x%x (has 0x%x)\n",
+ name,
+ attrib, result->list[i].both_directory_info.attrib);
+ return false;
+ }
+ return true;
+}
+
+/*
+ test what happens when the directory is modified during a search
+*/
+static bool test_modify_search(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ int num_files = 700;
+ struct multiple_result result;
+ union smb_setfileinfo sfinfo;
+ TALLOC_CTX *mem_ctx = talloc_new(tctx);
+ struct smb2_create create;
+ struct smb2_handle h;
+ struct smb2_find f;
+ union smb_search_data *d;
+ struct file_elem files[700] = {};
+ NTSTATUS status;
+ bool ret = true;
+ int i;
+ uint_t count;
+
+ smb2_deltree(tree, DNAME);
+
+ status = torture_smb2_testdir(tree, DNAME, &h);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ printf("Creating %d files\n", num_files);
+
+ ZERO_STRUCT(create);
+ create.in.desired_access = SEC_RIGHTS_FILE_ALL;
+ create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+ create.in.create_disposition = NTCREATEX_DISP_CREATE;
+
+ for (i = num_files-1; i >= 0; i--) {
+ files[i].name = talloc_asprintf(mem_ctx, "t%03d-%d.txt", i, i);
+ create.in.fname = talloc_asprintf(mem_ctx, "%s\\%s",
+ DNAME, files[i].name);
+ status = smb2_create(tree, mem_ctx, &create);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ smb2_util_close(tree, create.out.file.handle);
+ }
+
+ printf("pulling the first two files\n");
+ ZERO_STRUCT(result);
+ result.tctx = talloc_new(tctx);
+
+ ZERO_STRUCT(f);
+ f.in.file.handle = h;
+ f.in.pattern = "*";
+ f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE;
+ f.in.max_response_size = 0x100;
+ f.in.level = SMB2_FIND_BOTH_DIRECTORY_INFO;
+
+ do {
+ status = smb2_find_level(tree, tree, &f, &count, &d);
+ if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
+ break;
+ CHECK_STATUS(status, NT_STATUS_OK);
+ if (!fill_result(&result, d, count, f.in.level,
+ RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO)) {
+ ret = false;
+ goto done;
+ }
+ }while(result.count < 2);
+
+ printf("Changing attributes and deleting\n");
+ ZERO_STRUCT(create);
+ create.in.desired_access = SEC_RIGHTS_FILE_ALL;
+ create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+ create.in.create_disposition = NTCREATEX_DISP_CREATE;
+
+ files[num_files].name = talloc_asprintf(mem_ctx, "T003-03.txt.2");
+ create.in.fname = talloc_asprintf(mem_ctx, "%s\\%s", DNAME,
+ files[num_files].name);
+ status = smb2_create(tree, mem_ctx, &create);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ smb2_util_close(tree, create.out.file.handle);
+
+ ZERO_STRUCT(create);
+ create.in.desired_access = SEC_RIGHTS_FILE_ALL;
+ create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+ create.in.create_disposition = NTCREATEX_DISP_CREATE;
+
+ files[num_files + 1].name = talloc_asprintf(mem_ctx, "T013-13.txt.2");
+ create.in.fname = talloc_asprintf(mem_ctx, "%s\\%s", DNAME,
+ files[num_files + 1].name);
+ status = smb2_create(tree, mem_ctx, &create);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ smb2_util_close(tree, create.out.file.handle);
+
+ files[num_files + 2].name = talloc_asprintf(mem_ctx, "T013-13.txt.3");
+ status = smb2_create_complex_file(tree, DNAME "\\T013-13.txt.3", &h);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ smb2_util_unlink(tree, DNAME "\\T014-14.txt");
+ smb2_util_setatr(tree, DNAME "\\T015-15.txt", FILE_ATTRIBUTE_HIDDEN);
+ smb2_util_setatr(tree, DNAME "\\T016-16.txt", FILE_ATTRIBUTE_NORMAL);
+ smb2_util_setatr(tree, DNAME "\\T017-17.txt", FILE_ATTRIBUTE_SYSTEM);
+ smb2_util_setatr(tree, DNAME "\\T018-18.txt", 0);
+ smb2_util_setatr(tree, DNAME "\\T039-39.txt", FILE_ATTRIBUTE_HIDDEN);
+ smb2_util_setatr(tree, DNAME "\\T000-0.txt", FILE_ATTRIBUTE_HIDDEN);
+ sfinfo.generic.level = RAW_SFILEINFO_DISPOSITION_INFORMATION;
+ sfinfo.generic.in.file.path = DNAME "\\T013-13.txt.3";
+ sfinfo.disposition_info.in.delete_on_close = 1;
+ status = smb2_composite_setpathinfo(tree, &sfinfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ /* Reset the numfiles to include the new files and start the
+ * search from the beginning */
+ num_files = num_files + 2;
+ f.in.pattern = "*";
+ f.in.continue_flags = SMB2_CONTINUE_FLAG_RESTART;
+ result.count = 0;
+
+ do {
+ status = smb2_find_level(tree, tree, &f, &count, &d);
+ if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
+ break;
+ CHECK_STATUS(status, NT_STATUS_OK);
+ if (!fill_result(&result, d, count, f.in.level,
+ RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO)) {
+ ret = false;
+ goto done;
+ }
+ f.in.continue_flags = 0;
+ f.in.max_response_size = 4096;
+ } while (count != 0);
+
+
+ ret &= check_result(&result, "t039-39.txt", true, FILE_ATTRIBUTE_HIDDEN);
+ ret &= check_result(&result, "t000-0.txt", true, FILE_ATTRIBUTE_HIDDEN);
+ ret &= check_result(&result, "t014-14.txt", false, 0);
+ ret &= check_result(&result, "t015-15.txt", true, FILE_ATTRIBUTE_HIDDEN);
+ ret &= check_result(&result, "t016-16.txt", true, FILE_ATTRIBUTE_NORMAL);
+ ret &= check_result(&result, "t017-17.txt", true, FILE_ATTRIBUTE_SYSTEM);
+ ret &= check_result(&result, "t018-18.txt", true, FILE_ATTRIBUTE_ARCHIVE);
+ ret &= check_result(&result, "t019-19.txt", true, FILE_ATTRIBUTE_ARCHIVE);
+ ret &= check_result(&result, "T013-13.txt.2", true, FILE_ATTRIBUTE_ARCHIVE);
+ ret &= check_result(&result, "T003-3.txt.2", false, 0);
+ ret &= check_result(&result, "T013-13.txt.3", true, FILE_ATTRIBUTE_NORMAL);
+
+ if (!ret) {
+ for (i=0;i<result.count;i++) {
+ printf("%s %s (0x%x)\n",
+ result.list[i].both_directory_info.name.s,
+ attrib_string(tctx,
+ result.list[i].both_directory_info.attrib),
+ result.list[i].both_directory_info.attrib);
+ }
+ }
+ done:
+ smb2_util_close(tree, h);
+ smb2_deltree(tree, DNAME);
talloc_free(mem_ctx);
return ret;
}
+
+/*
+ testing if directories always come back sorted
+*/
+static bool test_sorted(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(tctx);
+ const int num_files = 700;
+ int i;
+ struct file_elem files[700] = {};
+ bool ret = true;
+ NTSTATUS status;
+ struct multiple_result result;
+ struct smb2_handle h;
+
+ printf("Testing if directories always come back sorted\n");
+ status = populate_tree(tctx, mem_ctx, tree, files, num_files, &h);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ ZERO_STRUCT(result);
+ result.tctx = tctx;
+
+ status = multiple_smb2_search(tree, tctx, "*",
+ SMB2_FIND_BOTH_DIRECTORY_INFO,
+ RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO,
+ SMB2_CONTINUE_FLAG_SINGLE,
+ &result, &h);
+
+ CHECK_VALUE(result.count, num_files);
+
+ for (i=0;i<num_files-1;i++) {
+ const char *name1, *name2;
+ name1 = result.list[i].both_directory_info.name.s;
+ name2 = result.list[i+1].both_directory_info.name.s;
+ if (strcasecmp_m(name1, name2) > 0) {
+ printf("non-alphabetical order at entry %d '%s' '%s'"
+ "\n", i, name1, name2);
+ torture_comment(tctx,
+ "Server does not produce sorted directory listings"
+ "(not an error)\n");
+ goto done;
+ }
+ }
+ talloc_free(result.list);
+done:
+ smb2_util_close(tree, h);
+ smb2_deltree(tree, DNAME);
+ talloc_free(mem_ctx);
+
+ return ret;
+}
+
+/* test the behavior of file_index field in the SMB2_FIND struct */
+
+static bool test_file_index(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(tctx);
+ const int num_files = 100;
+ int resume_index = 4;
+ int i;
+ char *fname;
+ bool ret = true;
+ NTSTATUS status;
+ struct multiple_result result;
+ struct smb2_create create;
+ struct smb2_find f;
+ struct smb2_handle h;
+ union smb_search_data *d;
+ int count;
+
+ smb2_deltree(tree, DNAME);
+
+ status = torture_smb2_testdir(tree, DNAME, &h);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ printf("Testing the behavior of file_index flag\n");
+
+ ZERO_STRUCT(create);
+ create.in.desired_access = SEC_RIGHTS_FILE_ALL;
+ create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+ create.in.create_disposition = NTCREATEX_DISP_CREATE;
+ for (i = num_files-1; i >= 0; i--) {
+ fname = talloc_asprintf(mem_ctx, DNAME "\\file%u.txt", i);
+ create.in.fname = fname;
+ status = smb2_create(tree, mem_ctx, &create);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ talloc_free(fname);
+ smb2_util_close(tree, create.out.file.handle);
+ }
+
+ ZERO_STRUCT(result);
+ result.tctx = tctx;
+
+ ZERO_STRUCT(f);
+ f.in.file.handle = h;
+ f.in.pattern = "*";
+ f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE;
+ f.in.max_response_size = 0x1000;
+ f.in.level = SMB2_FIND_FULL_DIRECTORY_INFO;
+
+ do {
+ status = smb2_find_level(tree, tree, &f, &count, &d);
+ if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
+ break;
+ CHECK_STATUS(status, NT_STATUS_OK);
+ if (!fill_result(&result, d, count, f.in.level,
+ RAW_SEARCH_DATA_FULL_DIRECTORY_INFO)) {
+ ret = false;
+ goto done;
+ }
+ } while(result.count < 10);
+
+ if (result.list[0].full_directory_info.file_index == 0) {
+ torture_comment(tctx,
+ "Talking to a server that doesn't provide a "
+ "file index.\nWindows servers using NTFS do "
+ "not provide a file_index. Skipping test\n");
+ goto done;
+ } else {
+ /* We are not talking to a Windows based server. Windows
+ * servers using NTFS do not provide a file_index. Windows
+ * server using FAT do provide a file index, however in both
+ * cases they do not honor a file index on a resume request.
+ * See MS-FSCC <62> and MS-SMB2 <54> for more information. */
+
+ /* Set the file_index flag to point to the fifth file from the
+ * previous enumeration and try to start the subsequent
+ * searches from that point */
+ f.in.file_index =
+ result.list[resume_index].full_directory_info.file_index;
+ f.in.continue_flags = SMB2_CONTINUE_FLAG_INDEX;
+
+ /* get the name of the next expected file */
+ fname = talloc_asprintf(mem_ctx, DNAME "\\%s",
+ result.list[resume_index].full_directory_info.name.s);
+
+ ZERO_STRUCT(result);
+ result.tctx = tctx;
+ status = smb2_find_level(tree, tree, &f, &count, &d);
+ if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
+ goto done;
+ CHECK_STATUS(status, NT_STATUS_OK);
+ if (!fill_result(&result, d, count, f.in.level,
+ RAW_SEARCH_DATA_FULL_DIRECTORY_INFO)) {
+ ret = false;
+ goto done;
+ }
+ if (strcmp(fname,
+ result.list[0].full_directory_info.name.s)) {
+ printf("next expected file: %s but the server "
+ "returned %s\n", fname,
+ result.list[0].full_directory_info.name.s);
+ torture_comment(tctx,
+ "Not an error. Resuming using a file "
+ "index is an optional feature of the "
+ "protocol.\n");
+ goto done;
+ }
+ }
+done:
+ smb2_util_close(tree, h);
+ smb2_deltree(tree, DNAME);
+ talloc_free(mem_ctx);
+
+ return ret;
+}
+
+/*
+ * Tests directory enumeration in a directory containing >1000 files with
+ * names of varying lengths.
+ */
+static bool test_large_files(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(tctx);
+ const int num_files = 2000;
+ int i, j = 1, retry_count = 0;
+ struct file_elem files[2000] = {};
+ bool ret = true;
+ NTSTATUS status;
+ struct smb2_create create;
+ struct smb2_find f;
+ struct smb2_handle h;
+ union smb_search_data *d;
+ int count, file_count = 0;
+
+ torture_comment(tctx,
+ "Testing directory enumeration in a directory with >1000 files\n");
+
+ smb2_deltree(tree, DNAME);
+
+ ZERO_STRUCT(create);
+ create.in.desired_access = SEC_RIGHTS_DIR_ALL;
+ create.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
+ create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
+ create.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
+ NTCREATEX_SHARE_ACCESS_WRITE |
+ NTCREATEX_SHARE_ACCESS_DELETE;
+ create.in.create_disposition = NTCREATEX_DISP_CREATE;
+ create.in.fname = DNAME;
+
+ status = smb2_create(tree, mem_ctx, &create);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ h = create.out.file.handle;
+
+ ZERO_STRUCT(create);
+ create.in.desired_access = SEC_RIGHTS_FILE_ALL;
+ create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+ create.in.create_disposition = NTCREATEX_DISP_CREATE;
+
+ for (i = 0; i < num_files; i++) {
+ files[i].name = generate_random_str(tctx, j);
+ create.in.fname = talloc_asprintf(mem_ctx, "%s\\%s",
+ DNAME, files[i].name);
+ status = smb2_create(tree, mem_ctx, &create);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ smb2_util_close(tree, create.out.file.handle);
+ retry_count = 0;
+ if (i%9 == 0)
+ j = j + 1;
+ }
+
+ ZERO_STRUCT(f);
+ f.in.file.handle = h;
+ f.in.pattern = "*";
+ f.in.max_response_size = 0x100;
+ f.in.level = SMB2_FIND_BOTH_DIRECTORY_INFO;
+
+ do {
+ status = smb2_find_level(tree, tree, &f, &count, &d);
+ if (NT_STATUS_EQUAL(status, STATUS_NO_MORE_FILES))
+ break;
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ for (i = 0; i < count; i++) {
+ bool expected;
+ const char *found = d[i].both_directory_info.name.s;
+
+ if (!strcmp(found, ".") || !strcmp(found, ".."))
+ continue;
+
+ expected = false;
+ for (j = 0; j < 2000; j++) {
+ if (!strcmp(files[j].name, found)) {
+ files[j].found = true;
+ expected = true;
+ break;
+ }
+ }
+
+ if (expected)
+ continue;
+
+ torture_result(tctx, TORTURE_FAIL,
+ "(%s): didn't expect %s\n",
+ __location__, found);
+ ret = false;
+ goto done;
+ }
+ file_count = file_count + i;
+ f.in.continue_flags = 0;
+ f.in.max_response_size = 4096;
+ } while (count != 0);
+
+ CHECK_VALUE(file_count, num_files + 2);
+
+ for (i = 0; i < num_files; i++) {
+ if (files[j].found)
+ continue;
+
+ torture_result(tctx, TORTURE_FAIL,
+ "(%s): expected to find %s, but didn't\n",
+ __location__, files[j].name);
+ ret = false;
+ goto done;
+ }
+done:
+ smb2_util_close(tree, h);
+ smb2_deltree(tree, DNAME);
+ talloc_free(mem_ctx);
+
+ return ret;
+}
+
+struct torture_suite *torture_smb2_dir_init(void)
+{
+ struct torture_suite *suite =
+ torture_suite_create(talloc_autofree_context(), "DIR");
+
+ torture_suite_add_1smb2_test(suite, "FIND", test_find);
+ torture_suite_add_1smb2_test(suite, "FIXED", test_fixed);
+ torture_suite_add_1smb2_test(suite, "ONE", test_one_file);
+ torture_suite_add_1smb2_test(suite, "MANY", test_many_files);
+ torture_suite_add_1smb2_test(suite, "MODIFY", test_modify_search);
+ torture_suite_add_1smb2_test(suite, "SORTED", test_sorted);
+ torture_suite_add_1smb2_test(suite, "FILE-INDEX", test_file_index);
+ torture_suite_add_1smb2_test(suite, "LARGE-FILES", test_large_files);
+ suite->description = talloc_strdup(suite, "SMB2-DIR tests");
+
+ return suite;
+}
diff --git a/source4/torture/smb2/getinfo.c b/source4/torture/smb2/getinfo.c
index c4ab31f4cf..166c3f694f 100644
--- a/source4/torture/smb2/getinfo.c
+++ b/source4/torture/smb2/getinfo.c
@@ -49,9 +49,9 @@ static struct {
{ LEVEL(RAW_FILEINFO_COMPRESSION_INFORMATION) },
{ LEVEL(RAW_FILEINFO_NETWORK_OPEN_INFORMATION) },
{ LEVEL(RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION) },
-/*
+
{ LEVEL(RAW_FILEINFO_SMB2_ALL_EAS) },
-*/
+
{ LEVEL(RAW_FILEINFO_SMB2_ALL_INFORMATION) },
{ LEVEL(RAW_FILEINFO_SEC_DESC) }
};
diff --git a/source4/torture/smb2/smb2.c b/source4/torture/smb2/smb2.c
index a5730a7eb3..9766620867 100644
--- a/source4/torture/smb2/smb2.c
+++ b/source4/torture/smb2/smb2.c
@@ -141,6 +141,7 @@ NTSTATUS torture_smb2_init(void)
torture_suite_add_simple_test(suite, "NOTIFY", torture_smb2_notify);
torture_suite_add_suite(suite, torture_smb2_durable_open_init());
torture_suite_add_1smb2_test(suite, "OPLOCK-BATCH1", torture_smb2_oplock_batch1);
+ torture_suite_add_suite(suite, torture_smb2_dir_init());
torture_suite_add_suite(suite, torture_smb2_lease_init());
torture_suite_add_suite(suite, torture_smb2_compound_init());
diff --git a/source4/winbind/wb_cmd_list_users.c b/source4/winbind/wb_cmd_list_users.c
index f67f133488..755d45786b 100644
--- a/source4/winbind/wb_cmd_list_users.c
+++ b/source4/winbind/wb_cmd_list_users.c
@@ -33,7 +33,7 @@ struct cmd_list_users_state {
struct wbsrv_domain *domain;
char *domain_name;
- uint resume_index;
+ uint32_t resume_index;
char *result;
};