summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs-xml/manpages-3/net.8.xml2
-rw-r--r--docs-xml/manpages-3/wbinfo.1.xml27
-rw-r--r--docs-xml/smbdotconf/security/writeable.xml2
-rw-r--r--lib/README1
-rw-r--r--lib/replace/autoconf-2.60.m42
-rw-r--r--lib/torture/config.mk (renamed from source4/lib/torture/config.mk)1
-rw-r--r--lib/torture/subunit.c (renamed from source4/lib/torture/subunit.c)6
-rw-r--r--lib/torture/torture.c (renamed from source4/lib/torture/torture.c)8
-rw-r--r--lib/torture/torture.h (renamed from source4/lib/torture/torture.h)17
-rw-r--r--lib/torture/torture.pc.in (renamed from source4/lib/torture/torture.pc.in)0
-rw-r--r--lib/util/fault.m414
-rw-r--r--lib/util/util.c4
-rw-r--r--lib/util/util.h5
-rw-r--r--libcli/nbt/libnbt.h6
-rw-r--r--libcli/util/doserr.c1
-rw-r--r--libcli/util/ntstatus.h1
-rw-r--r--libcli/util/werror.h2
-rw-r--r--librpc/idl/eventlog.idl8
-rw-r--r--librpc/idl/misc.idl16
-rw-r--r--librpc/idl/named_pipe_auth.idl44
-rw-r--r--librpc/idl/netlogon.idl36
-rw-r--r--librpc/idl/ntsvcs.idl29
-rw-r--r--librpc/idl/samr.idl (renamed from source3/librpc/idl/samr.idl)46
-rw-r--r--librpc/idl/security.cnf (renamed from source4/librpc/idl/security.cnf)0
-rw-r--r--librpc/idl/security.idl29
-rw-r--r--librpc/idl/svcctl.idl44
-rw-r--r--librpc/idl/xattr.idl10
-rw-r--r--librpc/ndr/libndr.h2
-rw-r--r--librpc/ndr/ndr_netlogon.c65
-rw-r--r--librpc/ndr/ndr_netlogon.h28
-rw-r--r--librpc/ndr/ndr_sec_helper.c118
-rw-r--r--librpc/ndr/uuid.c82
-rw-r--r--librpc/rpc/binding.c4
-rw-r--r--pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm5
-rw-r--r--pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm14
-rw-r--r--pidl/lib/Parse/Pidl/Samba4/Python.pm3
-rwxr-xr-xrelease-scripts/build-docs2
-rwxr-xr-xrelease-scripts/create-tarball8
-rw-r--r--source3/Makefile.in79
-rw-r--r--source3/auth/auth.c16
-rw-r--r--source3/auth/token_util.c8
-rw-r--r--source3/client/mount.cifs.c97
-rw-r--r--source3/client/mount.h38
-rw-r--r--source3/client/mtab.c219
-rw-r--r--source3/client/umount.cifs.c22
-rw-r--r--source3/configure.in64
-rw-r--r--source3/include/eventlog.h41
-rw-r--r--source3/include/includes.h1
-rw-r--r--source3/include/localedir.h6
-rw-r--r--source3/include/nss_info.h10
-rw-r--r--source3/include/ntdomain.h40
-rw-r--r--source3/include/ntlmssp.h6
-rw-r--r--source3/include/passdb.h10
-rw-r--r--source3/include/proto.h126
-rw-r--r--source3/include/rpc_eventlog.h23
-rw-r--r--source3/include/rpc_ntsvcs.h19
-rw-r--r--source3/include/rpc_svcctl.h8
-rw-r--r--source3/include/smb_macros.h4
-rw-r--r--source3/include/vfs_macros.h6
-rw-r--r--source3/lib/debug.c2
-rw-r--r--source3/lib/memcache.c39
-rw-r--r--source3/lib/secdesc.c16
-rw-r--r--source3/lib/util.c25
-rw-r--r--source3/lib/util_pw.c28
-rw-r--r--source3/lib/util_str.c16
-rw-r--r--source3/libads/kerberos_keytab.c7
-rw-r--r--source3/libads/ldap.c86
-rw-r--r--source3/libgpo/gpo_ldap.c6
-rw-r--r--source3/libnet/libnet_dssync_keytab.c111
-rw-r--r--source3/libnet/libnet_join.c114
-rw-r--r--source3/libnet/libnet_keytab.c33
-rw-r--r--source3/libnet/libnet_proto.h7
-rw-r--r--source3/libnet/libnet_samsync.c200
-rw-r--r--source3/libnet/libnet_samsync.h65
-rw-r--r--source3/libnet/libnet_samsync_display.c17
-rw-r--r--source3/libnet/libnet_samsync_keytab.c221
-rw-r--r--source3/libnet/libnet_samsync_ldif.c119
-rw-r--r--source3/libnet/libnet_samsync_passdb.c20
-rw-r--r--source3/librpc/gen_ndr/cli_eventlog.c8
-rw-r--r--source3/librpc/gen_ndr/cli_eventlog.h4
-rw-r--r--source3/librpc/gen_ndr/cli_netlogon.c4
-rw-r--r--source3/librpc/gen_ndr/cli_netlogon.h4
-rw-r--r--source3/librpc/gen_ndr/cli_ntsvcs.c40
-rw-r--r--source3/librpc/gen_ndr/cli_ntsvcs.h18
-rw-r--r--source3/librpc/gen_ndr/cli_samr.c2
-rw-r--r--source3/librpc/gen_ndr/cli_samr.h2
-rw-r--r--source3/librpc/gen_ndr/cli_svcctl.c36
-rw-r--r--source3/librpc/gen_ndr/cli_svcctl.h34
-rw-r--r--source3/librpc/gen_ndr/dom_sid.h15
-rw-r--r--source3/librpc/gen_ndr/eventlog.h4
-rw-r--r--source3/librpc/gen_ndr/misc.h32
-rw-r--r--source3/librpc/gen_ndr/named_pipe_auth.h32
-rw-r--r--source3/librpc/gen_ndr/ndr_dom_sid.h10
-rw-r--r--source3/librpc/gen_ndr/ndr_eventlog.c43
-rw-r--r--source3/librpc/gen_ndr/ndr_eventlog.h1
-rw-r--r--source3/librpc/gen_ndr/ndr_misc.c53
-rw-r--r--source3/librpc/gen_ndr/ndr_misc.h6
-rw-r--r--source3/librpc/gen_ndr/ndr_named_pipe_auth.c302
-rw-r--r--source3/librpc/gen_ndr/ndr_named_pipe_auth.h20
-rw-r--r--source3/librpc/gen_ndr/ndr_netlogon.c260
-rw-r--r--source3/librpc/gen_ndr/ndr_netlogon.h7
-rw-r--r--source3/librpc/gen_ndr/ndr_ntsvcs.c196
-rw-r--r--source3/librpc/gen_ndr/ndr_samr.c129
-rw-r--r--source3/librpc/gen_ndr/ndr_samr.h7
-rw-r--r--source3/librpc/gen_ndr/ndr_security.c32
-rw-r--r--source3/librpc/gen_ndr/ndr_security.h7
-rw-r--r--source3/librpc/gen_ndr/ndr_svcctl.c216
-rw-r--r--source3/librpc/gen_ndr/ndr_svcctl.h1
-rw-r--r--source3/librpc/gen_ndr/ndr_xattr.c48
-rw-r--r--source3/librpc/gen_ndr/ndr_xattr.h6
-rw-r--r--source3/librpc/gen_ndr/netlogon.h34
-rw-r--r--source3/librpc/gen_ndr/ntsvcs.h31
-rw-r--r--source3/librpc/gen_ndr/samr.h57
-rw-r--r--source3/librpc/gen_ndr/security.h8
-rw-r--r--source3/librpc/gen_ndr/srv_lsa.c28
-rw-r--r--source3/librpc/gen_ndr/srv_netlogon.c10
-rw-r--r--source3/librpc/gen_ndr/srv_ntsvcs.c10
-rw-r--r--source3/librpc/gen_ndr/srv_samr.c2
-rw-r--r--source3/librpc/gen_ndr/srv_srvsvc.c20
-rw-r--r--source3/librpc/gen_ndr/srv_svcctl.c22
-rw-r--r--source3/librpc/gen_ndr/srv_winreg.c2
-rw-r--r--source3/librpc/gen_ndr/srv_wkssvc.c6
-rw-r--r--source3/librpc/gen_ndr/svcctl.h48
-rw-r--r--source3/librpc/gen_ndr/xattr.h6
-rw-r--r--source3/librpc/idl/dom_sid.idl29
-rw-r--r--source3/librpc/ndr/ndr_sec.h35
-rw-r--r--source3/librpc/ndr/ndr_sec_helper.c117
-rw-r--r--source3/librpc/ndr/sid.c53
-rw-r--r--source3/libsmb/cliconnect.c46
-rw-r--r--source3/libsmb/clifile.c2
-rw-r--r--source3/libsmb/clitrans.c21
-rw-r--r--source3/libsmb/dsgetdcname.c2
-rw-r--r--source3/libsmb/nterr.c1
-rw-r--r--source3/libsmb/ntlmssp.c137
-rw-r--r--source3/locale/pam_winbind/de.po181
-rwxr-xr-xsource3/locale/pam_winbind/genmsg25
-rw-r--r--source3/localedir.c3
-rw-r--r--source3/m4/check_path.m435
-rw-r--r--source3/modules/gpfs.c92
-rw-r--r--source3/modules/nfs4_acls.h2
-rw-r--r--source3/modules/onefs.h52
-rw-r--r--source3/modules/onefs_acl.c807
-rw-r--r--source3/modules/vfs_acl_tdb.c891
-rw-r--r--source3/modules/vfs_acl_xattr.c228
-rw-r--r--source3/modules/vfs_onefs.c48
-rw-r--r--source3/modules/vfs_readonly.c13
-rw-r--r--source3/modules/vfs_streams_depot.c123
-rw-r--r--source3/modules/vfs_streams_xattr.c339
-rw-r--r--source3/modules/vfs_tsmsm.c2
-rw-r--r--source3/modules/vfs_zfsacl.c83
-rw-r--r--source3/nsswitch/libwbclient/wbc_idmap.c154
-rw-r--r--source3/nsswitch/libwbclient/wbc_pam.c15
-rw-r--r--source3/nsswitch/libwbclient/wbc_pwd.c216
-rw-r--r--source3/nsswitch/libwbclient/wbclient.c2
-rw-r--r--source3/nsswitch/libwbclient/wbclient.h55
-rw-r--r--source3/nsswitch/pam_winbind.c187
-rw-r--r--source3/nsswitch/pam_winbind.h15
-rw-r--r--source3/nsswitch/wb_common.c2
-rw-r--r--source3/nsswitch/wbinfo.c181
-rw-r--r--source3/nsswitch/winbind_struct_protocol.h12
-rw-r--r--source3/nsswitch/wins.c63
-rw-r--r--source3/param/loadparm.c10
-rw-r--r--source3/passdb/passdb.c2
-rw-r--r--source3/passdb/pdb_interface.c22
-rw-r--r--source3/passdb/util_unixsids.c2
-rw-r--r--source3/printing/nt_printing.c213
-rw-r--r--source3/printing/printfsp.c15
-rw-r--r--source3/rpc_client/cli_reg.c17
-rw-r--r--source3/rpc_client/init_netlogon.c18
-rw-r--r--source3/rpc_client/init_samr.c154
-rw-r--r--source3/rpc_parse/parse_misc.c54
-rw-r--r--source3/rpc_parse/parse_ntsvcs.c68
-rw-r--r--source3/rpc_parse/parse_prs.c33
-rw-r--r--source3/rpc_server/srv_dfs_nt.c4
-rw-r--r--source3/rpc_server/srv_eventlog_lib.c42
-rw-r--r--source3/rpc_server/srv_eventlog_nt.c132
-rw-r--r--source3/rpc_server/srv_lsa_nt.c42
-rw-r--r--source3/rpc_server/srv_netlog_nt.c2
-rw-r--r--source3/rpc_server/srv_ntsvcs.c18
-rw-r--r--source3/rpc_server/srv_ntsvcs_nt.c46
-rw-r--r--source3/rpc_server/srv_pipe.c50
-rw-r--r--source3/rpc_server/srv_pipe_hnd.c124
-rw-r--r--source3/rpc_server/srv_samr_nt.c627
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c62
-rw-r--r--source3/rpc_server/srv_srvsvc_nt.c58
-rw-r--r--source3/rpc_server/srv_svcctl_nt.c28
-rw-r--r--source3/rpc_server/srv_winreg_nt.c10
-rw-r--r--source3/rpc_server/srv_wkssvc_nt.c4
-rw-r--r--source3/rpcclient/cmd_netlogon.c67
-rw-r--r--source3/rpcclient/cmd_ntsvcs.c163
-rw-r--r--source3/rpcclient/cmd_samr.c4
-rw-r--r--source3/samba4.m43
-rw-r--r--source3/samba4.mk2
-rw-r--r--source3/script/installmo.sh87
-rwxr-xr-xsource3/script/tests/selftest.sh30
-rw-r--r--source3/script/uninstallmo.sh1
-rw-r--r--source3/smbd/aio.c2
-rw-r--r--source3/smbd/blocking.c85
-rw-r--r--source3/smbd/close.c8
-rw-r--r--source3/smbd/dosmode.c160
-rw-r--r--source3/smbd/fake_file.c1
-rw-r--r--source3/smbd/filename.c42
-rw-r--r--source3/smbd/files.c74
-rw-r--r--source3/smbd/ipc.c191
-rw-r--r--source3/smbd/map_username.c2
-rw-r--r--source3/smbd/msdfs.c31
-rw-r--r--source3/smbd/notify.c86
-rw-r--r--source3/smbd/nttrans.c147
-rw-r--r--source3/smbd/open.c230
-rw-r--r--source3/smbd/password.c2
-rw-r--r--source3/smbd/pipes.c2
-rw-r--r--source3/smbd/posix_acls.c14
-rw-r--r--source3/smbd/process.c4
-rw-r--r--source3/smbd/reply.c74
-rw-r--r--source3/smbd/server.c6
-rw-r--r--source3/smbd/service.c32
-rw-r--r--source3/smbd/sesssetup.c4
-rw-r--r--source3/smbd/share_access.c6
-rw-r--r--source3/smbd/trans2.c197
-rw-r--r--source3/smbd/uid.c11
-rw-r--r--source3/torture/torture.c33
-rw-r--r--source3/utils/net.h10
-rw-r--r--source3/utils/net_proto.h5
-rw-r--r--source3/utils/net_rap.c9
-rw-r--r--source3/utils/net_registry.c4
-rw-r--r--source3/utils/net_rpc.c10
-rw-r--r--source3/utils/net_rpc_join.c3
-rw-r--r--source3/utils/net_rpc_samsync.c180
-rw-r--r--source3/utils/net_sam.c2
-rw-r--r--source3/utils/net_util.c38
-rw-r--r--source3/utils/ntlm_auth.c25
-rw-r--r--source3/utils/pdbedit.c4
-rw-r--r--source3/utils/smbpasswd.c4
-rw-r--r--source3/utils/smbtree.c16
-rw-r--r--source3/web/cgi.c4
-rw-r--r--source3/web/neg_lang.c2
-rw-r--r--source3/winbindd/idmap.c27
-rw-r--r--source3/winbindd/idmap_ad.c414
-rw-r--r--source3/winbindd/idmap_adex/idmap_adex.c16
-rw-r--r--source3/winbindd/idmap_hash/idmap_hash.c6
-rw-r--r--source3/winbindd/idmap_tdb.c63
-rw-r--r--source3/winbindd/idmap_util.c12
-rw-r--r--source3/winbindd/nss_info.c151
-rw-r--r--source3/winbindd/nss_info_template.c4
-rw-r--r--source3/winbindd/winbindd.c3
-rw-r--r--source3/winbindd/winbindd_ads.c229
-rw-r--r--source3/winbindd/winbindd_cache.c7
-rw-r--r--source3/winbindd/winbindd_dual.c1
-rw-r--r--source3/winbindd/winbindd_group.c4
-rw-r--r--source3/winbindd/winbindd_idmap.c63
-rw-r--r--source3/winbindd/winbindd_pam.c31
-rw-r--r--source3/winbindd/winbindd_passdb.c5
-rw-r--r--source3/winbindd/winbindd_proto.h40
-rw-r--r--source3/winbindd/winbindd_rpc.c65
-rw-r--r--source3/winbindd/winbindd_sid.c45
-rw-r--r--source4/Makefile4
-rw-r--r--source4/auth/config.m46
-rw-r--r--source4/build/m4/check_python.m415
-rw-r--r--source4/build/m4/public.m413
-rw-r--r--source4/build/make/python.mk2
-rw-r--r--source4/configure.ac2
-rw-r--r--source4/dsdb/common/util.c33
-rw-r--r--source4/dsdb/config.mk2
-rw-r--r--source4/dsdb/samdb/ldb_modules/config.mk8
-rw-r--r--source4/dsdb/samdb/ldb_modules/linked_attributes.c41
-rw-r--r--source4/dsdb/samdb/ldb_modules/objectclass.c4
-rw-r--r--source4/dsdb/samdb/ldb_modules/schema_fsmo.c56
-rw-r--r--source4/dsdb/samdb/ldb_modules/tests/samba3sam.py6
-rw-r--r--source4/dsdb/schema/schema.h4
-rw-r--r--source4/dsdb/schema/schema_description.c142
-rw-r--r--source4/dsdb/schema/schema_init.c43
-rw-r--r--source4/dsdb/schema/schema_syntax.c9
-rw-r--r--source4/headermap.txt3
-rw-r--r--source4/ldap_server/ldap_backend.c22
-rw-r--r--source4/lib/ldb-samba/config.mk2
-rw-r--r--source4/lib/ldb/common/ldb_ldif.c6
-rw-r--r--source4/lib/ldb/ldb.i3
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.c9
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.h1
-rw-r--r--source4/lib/ldb/ldb_wrap.c1
-rw-r--r--source4/lib/registry/config.mk2
-rw-r--r--source4/lib/wmi/config.mk2
-rw-r--r--source4/libcli/clideltree.c3
-rw-r--r--source4/libcli/ldap/ldap_bind.c2
-rw-r--r--source4/libcli/resolve/host.c22
-rw-r--r--source4/libcli/security/config.mk2
-rw-r--r--source4/libcli/util/nterr.c1
-rw-r--r--source4/libnet/groupinfo.c18
-rw-r--r--source4/libnet/groupman.c10
-rw-r--r--source4/libnet/libnet_domain.c21
-rw-r--r--source4/libnet/libnet_group.c16
-rw-r--r--source4/libnet/libnet_join.c25
-rw-r--r--source4/libnet/libnet_passwd.c22
-rw-r--r--source4/libnet/libnet_samsync_ldb.c6
-rw-r--r--source4/libnet/libnet_user.c16
-rw-r--r--source4/libnet/userinfo.c16
-rw-r--r--source4/libnet/userman.c33
-rw-r--r--source4/librpc/config.mk69
-rw-r--r--source4/librpc/idl/dom_sid.idl42
-rw-r--r--source4/librpc/idl/samr.idl1424
-rw-r--r--source4/librpc/idl/security.idl410
-rw-r--r--source4/librpc/ndr/ndr_dom_sid.c (renamed from source4/librpc/ndr/ndr_sec_helper.c)63
-rw-r--r--source4/main.mk2
-rw-r--r--source4/ntvfs/posix/pvfs_resolve.c65
-rw-r--r--source4/rpc_server/dcerpc_server.c4
-rw-r--r--source4/rpc_server/samr/dcesrv_samr.c363
-rw-r--r--source4/rpc_server/samr/samr_password.c11
-rw-r--r--source4/rpc_server/service_rpc.c41
-rw-r--r--source4/selftest/knownfail1
-rw-r--r--source4/selftest/skip2
-rw-r--r--source4/setup/schema-map-fedora-ds-1.04
-rw-r--r--source4/setup/schema-map-openldap-2.34
-rw-r--r--source4/smbd/config.mk3
-rw-r--r--source4/smbd/service_named_pipe.c366
-rw-r--r--source4/torture/config.mk11
-rw-r--r--source4/torture/libnet/libnet_domain.c6
-rw-r--r--source4/torture/libnet/libnet_group.c9
-rw-r--r--source4/torture/libnet/libnet_user.c9
-rw-r--r--source4/torture/libnet/utils.c18
-rw-r--r--source4/torture/raw/acls.c16
-rw-r--r--source4/torture/raw/chkpath.c81
-rw-r--r--source4/torture/raw/streams.c429
-rw-r--r--source4/torture/rpc/eventlog.c8
-rw-r--r--source4/torture/rpc/netlogon.c535
-rw-r--r--source4/torture/rpc/ntsvcs.c169
-rw-r--r--source4/torture/rpc/rpc.c2
-rw-r--r--source4/torture/rpc/rpc.h3
-rw-r--r--source4/torture/rpc/samba3rpc.c61
-rw-r--r--source4/torture/rpc/samr.c1214
-rw-r--r--source4/torture/rpc/samr_accessmask.c29
-rw-r--r--source4/torture/rpc/samsync.c149
-rw-r--r--source4/torture/rpc/schannel.c2
-rw-r--r--source4/torture/rpc/svcctl.c178
-rw-r--r--source4/torture/rpc/testjoin.c19
-rw-r--r--source4/torture/smb2/config.mk2
-rw-r--r--source4/torture/smbtorture.h2
-rw-r--r--source4/torture/util.h2
-rw-r--r--source4/torture/winbind/config.mk2
-rw-r--r--source4/utils/ad2oLschema.c17
-rw-r--r--source4/utils/net/config.mk1
-rw-r--r--source4/utils/net/net.c2
-rw-r--r--source4/utils/net/net_machinepw.c91
-rw-r--r--source4/winbind/wb_async_helpers.c7
343 files changed, 14013 insertions, 6548 deletions
diff --git a/docs-xml/manpages-3/net.8.xml b/docs-xml/manpages-3/net.8.xml
index 31fe69d8d3..75f85e1c55 100644
--- a/docs-xml/manpages-3/net.8.xml
+++ b/docs-xml/manpages-3/net.8.xml
@@ -395,7 +395,7 @@ current network.</para>
<title>RAP PRINTQ</title>
<refsect3>
-<title>RAP PRINTQ LIST <replaceable>QUEUE_NAME</replaceable></title>
+<title>RAP PRINTQ INFO <replaceable>QUEUE_NAME</replaceable></title>
<para>Lists the specified print queue and print jobs on the server.
If the <replaceable>QUEUE_NAME</replaceable> is omitted, all
diff --git a/docs-xml/manpages-3/wbinfo.1.xml b/docs-xml/manpages-3/wbinfo.1.xml
index 72a2380dde..abb1c7f53f 100644
--- a/docs-xml/manpages-3/wbinfo.1.xml
+++ b/docs-xml/manpages-3/wbinfo.1.xml
@@ -39,10 +39,14 @@
<arg choice="opt">--own-domain</arg>
<arg choice="opt">-p</arg>
<arg choice="opt">-r user</arg>
+ <arg choice="opt">--remove-uid-mapping uid,sid</arg>
+ <arg choice="opt">--remove-gid-mapping gid,sid</arg>
<arg choice="opt">-s sid</arg>
<arg choice="opt">--separator</arg>
<arg choice="opt">--sequence</arg>
<arg choice="opt">--set-auth-user user%password</arg>
+ <arg choice="opt">--set-uid-mapping uid,sid</arg>
+ <arg choice="opt">--set-gid-mapping gid,sid</arg>
<arg choice="opt">-S sid</arg>
<arg choice="opt">-t</arg>
<arg choice="opt">-u</arg>
@@ -333,6 +337,29 @@
the operation will fail. </para></listitem>
</varlistentry>
+ <varlistentry>
+ <term>--remove-uid-mapping uid,sid</term>
+ <listitem><para>Remove an existing uid to sid mapping
+ entry from the IDmap backend.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>--remove-gid-mapping gid,sid</term>
+ <listitem><para>Remove an existing gid to sid
+ mapping entry from the IDmap backend.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>--set-uid-mapping uid,sid</term>
+ <listitem><para>Create a new or modify an existing uid to sid
+ mapping in the IDmap backend.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>--set-gid-mapping gid,sid</term>
+ <listitem><para>Create a new or modify an existing gid to sid
+ mapping in the IDmap backend.</para></listitem>
+ </varlistentry>
&stdarg.version;
&stdarg.help;
diff --git a/docs-xml/smbdotconf/security/writeable.xml b/docs-xml/smbdotconf/security/writeable.xml
index f811c47e5c..99678a9fce 100644
--- a/docs-xml/smbdotconf/security/writeable.xml
+++ b/docs-xml/smbdotconf/security/writeable.xml
@@ -6,4 +6,6 @@
<description>
<para>Inverted synonym for <smbconfoption name="read only"/>.</para>
</description>
+
+<value type="default">no</value>
</samba:parameter>
diff --git a/lib/README b/lib/README
index b994447f4b..acae62c378 100644
--- a/lib/README
+++ b/lib/README
@@ -8,3 +8,4 @@ socket_wrapper - Wrapper library allowing TCP/IP traffic to be redirected
over Unix domain sockets.
talloc - Hierarchical pool based memory allocator
tdb - Simple but fast key/value database library, supporting multiple writers
+torture - Simple unit testing helper library
diff --git a/lib/replace/autoconf-2.60.m4 b/lib/replace/autoconf-2.60.m4
index acdcd38efe..2d5dbc1661 100644
--- a/lib/replace/autoconf-2.60.m4
+++ b/lib/replace/autoconf-2.60.m4
@@ -179,6 +179,7 @@ AC_DEFUN([AC_PROG_CC_C99],
# ------------------------
# Enable extensions on systems that normally disable them,
# typically due to standards-conformance issues.
+m4_ifndef([AC_USE_SYSTEM_EXTENSIONS],[
AC_DEFUN([AC_USE_SYSTEM_EXTENSIONS],
[
AC_BEFORE([$0], [AC_COMPILE_IFELSE])
@@ -208,3 +209,4 @@ AC_DEFUN([AC_USE_SYSTEM_EXTENSIONS],
AC_DEFINE([__EXTENSIONS__])
AC_DEFINE([_POSIX_PTHREAD_SEMANTICS])
])
+])
diff --git a/source4/lib/torture/config.mk b/lib/torture/config.mk
index 8a7f2a3b6b..abd89260f6 100644
--- a/source4/lib/torture/config.mk
+++ b/lib/torture/config.mk
@@ -4,6 +4,7 @@ PUBLIC_DEPENDENCIES = \
LIBSAMBA-HOSTCONFIG \
LIBSAMBA-UTIL \
LIBTALLOC
+CFLAGS = -I$(libtorturesrcdir) -I$(libtorturesrcdir)/../
torture_VERSION = 0.0.1
torture_SOVERSION = 0
diff --git a/source4/lib/torture/subunit.c b/lib/torture/subunit.c
index d5ee344596..832f11fafc 100644
--- a/source4/lib/torture/subunit.c
+++ b/lib/torture/subunit.c
@@ -20,11 +20,6 @@
#include "includes.h"
#include "lib/torture/torture.h"
-static void subunit_init(struct torture_results *results)
-{
- /* FIXME: register segv and bus handler */
-}
-
static void subunit_suite_start(struct torture_context *ctx,
struct torture_suite *suite)
{
@@ -87,7 +82,6 @@ static void subunit_warning(struct torture_context *test,
}
const struct torture_ui_ops torture_subunit_ui_ops = {
- .init = subunit_init,
.comment = subunit_comment,
.warning = subunit_warning,
.test_start = subunit_test_start,
diff --git a/source4/lib/torture/torture.c b/lib/torture/torture.c
index e465529f6b..9ad29ba9d0 100644
--- a/source4/lib/torture/torture.c
+++ b/lib/torture/torture.c
@@ -2,7 +2,7 @@
Unix SMB/CIFS implementation.
SMB torture UI functions
- Copyright (C) Jelmer Vernooij 2006
+ Copyright (C) Jelmer Vernooij 2006-2008
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
@@ -18,8 +18,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "includes.h"
-#include "torture/torture.h"
+#include "source4/include/includes.h"
+#include "../torture/torture.h"
#include "../lib/util/dlinklist.h"
#include "param/param.h"
#include "system/filesys.h"
@@ -310,7 +310,7 @@ static bool internal_torture_run_test(struct torture_context *context,
bool already_setup)
{
bool success;
- char *old_testname;
+ char *old_testname = NULL;
if (tcase == NULL || strcmp(test->name, tcase->name) != 0) {
old_testname = context->active_testname;
diff --git a/source4/lib/torture/torture.h b/lib/torture/torture.h
index f06ffe012b..73ea1eb643 100644
--- a/source4/lib/torture/torture.h
+++ b/lib/torture/torture.h
@@ -105,8 +105,6 @@ struct torture_results
bool quiet;
bool returncode;
-
-
};
/*
@@ -286,6 +284,21 @@ void torture_result(struct torture_context *test,
} \
} while(0)
+#define torture_assert_data_blob_equal(torture_ctx,got,expected,cmt)\
+ do { const DATA_BLOB __got = (got), __expected = (expected); \
+ if (__got.length != __expected.length) { \
+ torture_result(torture_ctx, TORTURE_FAIL, \
+ __location__": "#got".len %d did not match "#expected" len %d: %s", \
+ (int)__got.length, (int)__expected.length, cmt); \
+ return false; \
+ } \
+ if (memcmp(__got.data, __expected.data, __got.length) != 0) { \
+ torture_result(torture_ctx, TORTURE_FAIL, \
+ __location__": "#got" of len %d did not match"#expected": %s", (int)__got.length, cmt); \
+ return false; \
+ } \
+ } while(0)
+
#define torture_assert_file_contains_text(torture_ctx,filename,expected,cmt)\
do { \
char *__got; \
diff --git a/source4/lib/torture/torture.pc.in b/lib/torture/torture.pc.in
index 6582816cb5..6582816cb5 100644
--- a/source4/lib/torture/torture.pc.in
+++ b/lib/torture/torture.pc.in
diff --git a/lib/util/fault.m4 b/lib/util/fault.m4
index b24e63641c..da077af31d 100644
--- a/lib/util/fault.m4
+++ b/lib/util/fault.m4
@@ -1,5 +1,15 @@
AC_CHECK_HEADERS(execinfo.h)
AC_SEARCH_LIBS_EXT(backtrace, [execinfo], EXECINFO_LIBS)
AC_CHECK_FUNC_EXT(backtrace, $EXECINFO_LIBS)
-SMB_EXT_LIB(EXECINFO,[${EXECINFO_LIBS}])
-SMB_ENABLE(EXECINFO)
+
+
+if test x"$ac_cv_header_execinfo_h" = x"yes" -a x"$ac_cv_func_ext_backtrace" = x"yes";then
+ SMB_ENABLE(EXECINFO, YES)
+ EXECINFO_CFLAGS="$CFLAGS"
+ EXECINFO_CPPFLAGS="$CPPFLAGS"
+ EXECINFO_LDFLAGS="$LDFLAGS"
+else
+ SMB_ENABLE(EXECINFO,NO)
+fi
+
+SMB_EXT_LIB(EXECINFO, [${EXECINFO_LIBS}], [${EXECINFO_CFLAGS}], [${EXECINFO_CPPFLAGS}], [${EXECINFO_LDFLAGS}])
diff --git a/lib/util/util.c b/lib/util/util.c
index 4e2a5aab09..7548d30b7e 100644
--- a/lib/util/util.c
+++ b/lib/util/util.c
@@ -701,10 +701,14 @@ _PUBLIC_ char *hex_encode_talloc(TALLOC_CTX *mem_ctx, const unsigned char *buff_
char *hex_buffer;
hex_buffer = talloc_array(mem_ctx, char, (len*2)+1);
+ if (!hex_buffer) {
+ return NULL;
+ }
for (i = 0; i < len; i++)
slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
+ talloc_set_name_const(hex_buffer, hex_buffer);
return hex_buffer;
}
diff --git a/lib/util/util.h b/lib/util/util.h
index ec1cfef110..dced557acb 100644
--- a/lib/util/util.h
+++ b/lib/util/util.h
@@ -21,6 +21,8 @@
#ifndef _SAMBA_UTIL_H_
#define _SAMBA_UTIL_H_
+#include <netinet/in.h>
+
#if _SAMBA_BUILD_ == 4
#include "../lib/util/charset/charset.h"
#endif
@@ -124,9 +126,6 @@ void CatchChildLeaveStatus(void);
/* The following definitions come from lib/util/system.c */
-
-struct in_addr;
-
/**************************************************************************
A wrapper for gethostbyname() that tries avoids looking up hostnames
in the root domain, which can cause dial-on-demand links to come up for no
diff --git a/libcli/nbt/libnbt.h b/libcli/nbt/libnbt.h
index e03352d7cf..7d8ca49e9a 100644
--- a/libcli/nbt/libnbt.h
+++ b/libcli/nbt/libnbt.h
@@ -331,9 +331,9 @@ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock,
struct nbt_name_packet *request);
-NDR_SCALAR_PROTO(wrepl_nbt_name, const struct nbt_name *);
-NDR_SCALAR_PROTO(nbt_string, const char *);
-NDR_BUFFER_PROTO(nbt_name, struct nbt_name);
+NDR_SCALAR_PROTO(wrepl_nbt_name, const struct nbt_name *)
+NDR_SCALAR_PROTO(nbt_string, const char *)
+NDR_BUFFER_PROTO(nbt_name, struct nbt_name)
NTSTATUS nbt_rcode_to_ntstatus(uint8_t rcode);
struct composite_context;
diff --git a/libcli/util/doserr.c b/libcli/util/doserr.c
index 2ab39125df..160e7bc3e0 100644
--- a/libcli/util/doserr.c
+++ b/libcli/util/doserr.c
@@ -135,6 +135,7 @@ static const struct werror_code_struct dos_errs[] =
{ "WERR_INVALID_FLAGS", WERR_INVALID_FLAGS },
{ "WERR_NOT_FOUND", WERR_NOT_FOUND },
{ "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE },
+ { "WERR_NO_TRUST_SAM_ACCOUNT", WERR_NO_TRUST_SAM_ACCOUNT },
{ "WERR_CLASS_NOT_REGISTERED", WERR_CLASS_NOT_REGISTERED },
{ "WERR_NO_SHUTDOWN_IN_PROGRESS", WERR_NO_SHUTDOWN_IN_PROGRESS },
{ "WERR_SHUTDOWN_ALREADY_IN_PROGRESS", WERR_SHUTDOWN_ALREADY_IN_PROGRESS },
diff --git a/libcli/util/ntstatus.h b/libcli/util/ntstatus.h
index fa4553df1e..139562d8c2 100644
--- a/libcli/util/ntstatus.h
+++ b/libcli/util/ntstatus.h
@@ -592,6 +592,7 @@ typedef uint32_t NTSTATUS;
#define NT_STATUS_TOO_MANY_LINKS NT_STATUS(0xC0000000 | 0x0265)
#define NT_STATUS_QUOTA_LIST_INCONSISTENT NT_STATUS(0xC0000000 | 0x0266)
#define NT_STATUS_FILE_IS_OFFLINE NT_STATUS(0xC0000000 | 0x0267)
+#define NT_STATUS_DS_BUSY NT_STATUS(0xC0000000 | 0x02a5)
#define NT_STATUS_DS_NO_MORE_RIDS NT_STATUS(0xC0000000 | 0x02a8)
#define NT_STATUS_NOT_A_REPARSE_POINT NT_STATUS(0xC0000000 | 0x0275)
#define NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED NT_STATUS(0xC0000000 | 0x02E9)
diff --git a/libcli/util/werror.h b/libcli/util/werror.h
index fe819fce5e..d22516ae5c 100644
--- a/libcli/util/werror.h
+++ b/libcli/util/werror.h
@@ -136,6 +136,7 @@ typedef uint32_t WERROR;
#define WERR_TIME_SKEW W_ERROR(1398)
#define WERR_EVENTLOG_FILE_CORRUPT W_ERROR(1500)
#define WERR_SERVER_UNAVAILABLE W_ERROR(1722)
+#define WERR_NO_TRUST_SAM_ACCOUNT W_ERROR(1787)
#define WERR_INVALID_FORM_NAME W_ERROR(1902)
#define WERR_INVALID_FORM_SIZE W_ERROR(1903)
#define WERR_PASSWORD_MUST_CHANGE W_ERROR(1907)
@@ -180,6 +181,7 @@ typedef uint32_t WERROR;
/* Configuration Manager Errors */
/* Basically Win32 errors meanings are specific to the \ntsvcs pipe */
+#define WERR_CM_BUFFER_SMALL W_ERROR(26)
#define WERR_CM_NO_MORE_HW_PROFILES W_ERROR(35)
#define WERR_CM_NO_SUCH_VALUE W_ERROR(37)
diff --git a/librpc/idl/eventlog.idl b/librpc/idl/eventlog.idl
index ce25dd65ff..bab4cb90c7 100644
--- a/librpc/idl/eventlog.idl
+++ b/librpc/idl/eventlog.idl
@@ -11,7 +11,7 @@ import "lsa.idl", "security.idl";
helpstring("Event Logger")
] interface eventlog
{
- typedef bitmap {
+ typedef [bitmap32bit] bitmap {
EVENTLOG_SEQUENTIAL_READ = 0x0001,
EVENTLOG_SEEK_READ = 0x0002,
EVENTLOG_FORWARDS_READ = 0x0004,
@@ -100,8 +100,8 @@ import "lsa.idl", "security.idl";
[in,unique] eventlog_OpenUnknown0 *unknown0,
[in,ref] lsa_String *logname,
[in,ref] lsa_String *servername,
- [in] uint32 unknown2,
- [in] uint32 unknown3,
+ [in] uint32 major_version,
+ [in] uint32 minor_version,
[out] policy_handle *handle
);
@@ -117,7 +117,7 @@ import "lsa.idl", "security.idl";
/* Function: 0x0a */
NTSTATUS eventlog_ReadEventLogW(
[in] policy_handle *handle,
- [in] uint32 flags,
+ [in] eventlogReadFlags flags,
[in] uint32 offset,
[in] [range(0,0x7FFFF)] uint32 number_of_bytes,
[out,ref,size_is(number_of_bytes)] uint8 *data,
diff --git a/librpc/idl/misc.idl b/librpc/idl/misc.idl
index ff548fe804..1907195252 100644
--- a/librpc/idl/misc.idl
+++ b/librpc/idl/misc.idl
@@ -2,7 +2,6 @@
miscellaneous IDL structures
*/
-
[
pointer_default(unique)
]
@@ -36,19 +35,4 @@ interface misc
SEC_CHAN_DOMAIN = 4,
SEC_CHAN_BDC = 6
} netr_SchannelType;
-
- /* SAM database types */
- typedef [public,v1_enum] enum {
- SAM_DATABASE_DOMAIN = 0, /* Domain users and groups */
- SAM_DATABASE_BUILTIN = 1, /* BUILTIN users and groups */
- SAM_DATABASE_PRIVS = 2 /* Privileges */
- } netr_SamDatabaseID;
-
- typedef [public,v1_enum] enum {
- SAMR_REJECT_OTHER = 0,
- SAMR_REJECT_TOO_SHORT = 1,
- SAMR_REJECT_IN_HISTORY = 2,
- SAMR_REJECT_COMPLEXITY = 5
- } samr_RejectReason;
-
}
diff --git a/librpc/idl/named_pipe_auth.idl b/librpc/idl/named_pipe_auth.idl
new file mode 100644
index 0000000000..7d85eba9eb
--- /dev/null
+++ b/librpc/idl/named_pipe_auth.idl
@@ -0,0 +1,44 @@
+#include "idl_types.h"
+/*
+ miscellaneous IDL structures
+*/
+
+import "netlogon.idl";
+
+[
+ pointer_default(unique)
+]
+interface named_pipe_auth
+{
+ const char *NAMED_PIPE_AUTH_MAGIC = "NPAM";
+
+ typedef [switch_type(uint32)] union {
+ [case(0)] ;/* anonymous */
+ [case(1)] netr_SamInfo3 info1;
+ } named_pipe_auth_req_info;
+
+ typedef [public,gensize] struct {
+ [flag(NDR_BIG_ENDIAN),
+ value(ndr_size_named_pipe_auth_req(r,ndr->flags)-4)]
+ uint32 length;
+ [charset(DOS),value(NAMED_PIPE_AUTH_MAGIC)] uint8 magic[4];
+ uint32 level;
+ [switch_is(level)] named_pipe_auth_req_info info;
+ } named_pipe_auth_req;
+
+ typedef [switch_type(uint32)] union {
+ [case(0)] ;
+ [case(1)] ;
+ } named_pipe_auth_rep_info;
+
+ typedef [public,gensize] struct {
+ [flag(NDR_BIG_ENDIAN),
+ value(ndr_size_named_pipe_auth_rep(r,ndr->flags)-4)]
+ uint32 length;
+ [charset(DOS),value(NAMED_PIPE_AUTH_MAGIC)] uint8 magic[4];
+ uint32 level;
+ [switch_is(level)] named_pipe_auth_rep_info info;
+ NTSTATUS status;
+ } named_pipe_auth_rep;
+}
+
diff --git a/librpc/idl/netlogon.idl b/librpc/idl/netlogon.idl
index 0561f5becd..cf4da7adfa 100644
--- a/librpc/idl/netlogon.idl
+++ b/librpc/idl/netlogon.idl
@@ -8,10 +8,14 @@ import "misc.idl", "lsa.idl", "samr.idl", "security.idl", "nbt.idl";
#include "idl_types.h"
+cpp_quote("#define netr_DeltaEnum8Bit netr_DeltaEnum")
+cpp_quote("#define netr_SamDatabaseID8Bit netr_SamDatabaseID")
+
[
uuid("12345678-1234-abcd-ef00-01234567cffb"),
version(1.0),
endpoint("ncacn_np:[\\pipe\\netlogon]","ncacn_ip_tcp:","ncalrpc:"),
+ helper("../librpc/ndr/ndr_netlogon.h"),
pointer_default(unique)
]
@@ -19,6 +23,8 @@ interface netlogon
{
typedef bitmap samr_AcctFlags samr_AcctFlags;
typedef bitmap samr_GroupAttrs samr_GroupAttrs;
+ typedef enum netr_DeltaEnum8Bit netr_DeltaEnum8Bit;
+ typedef enum netr_SamDatabaseID8Bit netr_SamDatabaseID8Bit;
/*****************/
/* Function 0x00 */
@@ -432,7 +438,7 @@ interface netlogon
boolean8 lm_password_present;
boolean8 password_expired;
lsa_String comment;
- lsa_String parameters;
+ lsa_BinaryString parameters;
uint16 country_code;
uint16 code_page;
netr_USER_PRIVATE_INFO user_private_info;
@@ -958,13 +964,37 @@ interface netlogon
/* i'm not at all sure how this call works */
+ typedef [bitmap16bit] bitmap {
+ NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED = 0x0001,
+ NETR_CHANGELOG_CHANGED_PASSWORD = 0x0002,
+ NETR_CHANGELOG_SID_INCLUDED = 0x0004,
+ NETR_CHANGELOG_NAME_INCLUDED = 0x0008,
+ NETR_CHANGELOG_FIRST_PROMOTION_OBJ = 0x0010
+ } netr_ChangeLogFlags;
+
+ typedef [nodiscriminant] union {
+ [case(NETR_CHANGELOG_SID_INCLUDED)] dom_sid object_sid;
+ [case(NETR_CHANGELOG_NAME_INCLUDED)] nstring object_name;
+ [default];
+ } netr_ChangeLogObject;
+
+ typedef [public,gensize] struct {
+ uint32 serial_number1;
+ uint32 serial_number2;
+ uint32 object_rid;
+ netr_ChangeLogFlags flags;
+ netr_SamDatabaseID8Bit db_index;
+ netr_DeltaEnum8Bit delta_type;
+ [switch_is(flags & (NETR_CHANGELOG_SID_INCLUDED|NETR_CHANGELOG_NAME_INCLUDED))] netr_ChangeLogObject object;
+ } netr_ChangeLogEntry;
+
NTSTATUS netr_DatabaseRedo(
[in] [string,charset(UTF16)] uint16 logon_server[],
[in] [string,charset(UTF16)] uint16 computername[],
[in] netr_Authenticator *credential,
[in,out,ref] netr_Authenticator *return_authenticator,
- [in,ref][size_is(change_log_entry_size)] uint8 *change_log_entry,
- [in] uint32 change_log_entry_size,
+ [in] [subcontext(4),subcontext_size(change_log_entry_size)] netr_ChangeLogEntry change_log_entry,
+ [in] [value(ndr_size_netr_ChangeLogEntry(&change_log_entry, ndr->flags))] uint32 change_log_entry_size,
[out,ref] netr_DELTA_ENUM_ARRAY **delta_enum_array
);
diff --git a/librpc/idl/ntsvcs.idl b/librpc/idl/ntsvcs.idl
index 809ead90c3..be7fcdff13 100644
--- a/librpc/idl/ntsvcs.idl
+++ b/librpc/idl/ntsvcs.idl
@@ -2,9 +2,12 @@
plug and play services
*/
+import "winreg.idl";
+
[
uuid("8d9f4e40-a03d-11ce-8f69-08003e30051b"),
version(1.0),
+ endpoint("ncacn_np:[\\pipe\\ntsvcs]","ncacn_np:[\\pipe\\plugplay]"),
helpstring("Plug and Play services")
]
interface ntsvcs
@@ -67,7 +70,7 @@ interface ntsvcs
/******************/
/* Function: 0x0a */
- [todo] WERROR PNP_GetDeviceList(
+ WERROR PNP_GetDeviceList(
[in,unique] [string,charset(UTF16)] uint16 *filter,
[out,ref] [size_is(*length),length_is(*length)] uint16 *buffer,
[in,out,ref] uint32 *length,
@@ -96,7 +99,7 @@ interface ntsvcs
WERROR PNP_GetDeviceRegProp(
[in,ref] [string,charset(UTF16)] uint16 *devicepath,
[in] uint32 property,
- [in,out,ref] uint32 *reg_data_type,
+ [in,out,ref] winreg_Type *reg_data_type,
[out,ref] [size_is(*buffer_size)] [length_is(*buffer_size)] uint8 *buffer,
[in,out,ref] uint32 *buffer_size,
[in,out,ref] uint32 *needed,
@@ -237,31 +240,31 @@ interface ntsvcs
/* Function: 0x28 */
WERROR PNP_HwProfFlags(
- [in] uint32 unknown1,
+ [in] uint32 action,
[in,ref] [string,charset(UTF16)] uint16 *devicepath,
- [in] uint32 unknown2,
- [in,out,ref] uint32 *unknown3,
- [in,out,unique] uint16 *unknown4,
+ [in] uint32 config,
+ [in,out,ref] uint32 *profile_flags,
+ [in,out,unique] uint16 *veto_type,
[in,unique] [string,charset(UTF16)] uint16 *unknown5,
[out,unique] [string,charset(UTF16)] uint16 **unknown5a,
- [in] uint32 unknown6,
- [in] uint32 unknown7
+ [in] uint32 name_length,
+ [in] uint32 flags
);
/******************/
/* Function: 0x29 */
typedef struct {
- uint32 unknown1;
- uint16 unknown2[160];
- uint32 unknown3;
+ uint32 profile_handle;
+ uint16 friendly_name[80];
+ uint32 flags;
} PNP_HwProfInfo;
WERROR PNP_GetHwProfInfo(
[in] uint32 idx,
[in,out,ref] PNP_HwProfInfo *info,
- [in] uint32 unknown1,
- [in] uint32 unknown2
+ [in] uint32 size,
+ [in] uint32 flags
);
/******************/
diff --git a/source3/librpc/idl/samr.idl b/librpc/idl/samr.idl
index f47e0994dc..46478ee9e8 100644
--- a/source3/librpc/idl/samr.idl
+++ b/librpc/idl/samr.idl
@@ -17,6 +17,22 @@ import "misc.idl", "lsa.idl", "security.idl";
{
typedef bitmap security_secinfo security_secinfo;
+ /* SAM database types */
+ typedef [public,v1_enum] enum {
+ SAM_DATABASE_DOMAIN = 0, /* Domain users and groups */
+ SAM_DATABASE_BUILTIN = 1, /* BUILTIN users and groups */
+ SAM_DATABASE_PRIVS = 2 /* Privileges */
+ } netr_SamDatabaseID;
+
+ typedef [public,v1_enum] enum {
+ SAMR_REJECT_OTHER = 0,
+ SAMR_REJECT_TOO_SHORT = 1,
+ SAMR_REJECT_IN_HISTORY = 2,
+ SAMR_REJECT_COMPLEXITY = 5
+ } samr_RejectReason;
+
+
+
/* account control (acct_flags) bits */
typedef [public,bitmap32bit] bitmap {
ACB_DISABLED = 0x00000001, /* 1 = User account disabled */
@@ -321,6 +337,11 @@ import "misc.idl", "lsa.idl", "security.idl";
DOMAIN_REFUSE_PASSWORD_CHANGE = 0x00000020
} samr_PasswordProperties;
+ typedef [v1_enum] enum {
+ DOMAIN_SERVER_ENABLED = 1,
+ DOMAIN_SERVER_DISABLED = 2
+ } samr_DomainServerState;
+
typedef struct {
uint16 min_password_length;
uint16 password_history_length;
@@ -336,7 +357,7 @@ import "misc.idl", "lsa.idl", "security.idl";
lsa_String domain_name;
lsa_String primary; /* PDC name if this is a BDC */
udlong sequence_num;
- uint32 unknown2;
+ samr_DomainServerState domain_server_state;
samr_Role role;
uint32 unknown3;
uint32 num_users;
@@ -370,7 +391,7 @@ import "misc.idl", "lsa.idl", "security.idl";
} samr_DomInfo8;
typedef struct {
- uint32 unknown; /* w2k3 returns 1 */
+ samr_DomainServerState domain_server_state;
} samr_DomInfo9;
typedef struct {
@@ -417,7 +438,7 @@ import "misc.idl", "lsa.idl", "security.idl";
/************************/
/* Function 0x09 */
/*
- only levels 1, 3, 4, 6, 7, 9, 12 are valid for this
+ only levels 1, 3, 4, 6, 7, 9, 12 are valid for this
call in w2k3
*/
NTSTATUS samr_SetDomainInfo(
@@ -436,14 +457,10 @@ import "misc.idl", "lsa.idl", "security.idl";
[out,ref] policy_handle *group_handle,
[out,ref] uint32 *rid
);
-
+
/************************/
/* Function 0x0b */
-
- const int MAX_SAM_ENTRIES_W2K = 0x400; /* 1024 */
- const int MAX_SAM_ENTRIES_W95 = 50;
-
NTSTATUS samr_EnumDomainGroups(
[in] policy_handle *domain_handle,
[in,out,ref] uint32 *resume_handle,
@@ -853,7 +870,7 @@ import "misc.idl", "lsa.idl", "security.idl";
typedef struct {
samr_AcctFlags acct_flags;
} samr_UserInfo16;
-
+
typedef struct {
NTTIME acct_expiry;
} samr_UserInfo17;
@@ -959,7 +976,7 @@ import "misc.idl", "lsa.idl", "security.idl";
typedef struct {
samr_CryptPassword password;
- uint8 pw_len;
+ uint8 password_expired;
} samr_UserInfo24;
typedef [flag(NDR_PAHEX)] struct {
@@ -973,7 +990,7 @@ import "misc.idl", "lsa.idl", "security.idl";
typedef struct {
samr_CryptPasswordEx password;
- uint8 pw_len;
+ uint8 password_expired;
} samr_UserInfo26;
typedef [switch_type(uint16)] union {
@@ -1135,7 +1152,7 @@ import "misc.idl", "lsa.idl", "security.idl";
this seems to be an alphabetic search function. The returned index
is the index for samr_QueryDisplayInfo needed to get names occurring
after the specified name. The supplied name does not need to exist
- in the database (for example you can supply just a first letter for
+ in the database (for example you can supply just a first letter for
searching starting at that letter)
The level corresponds to the samr_QueryDisplayInfo level
@@ -1330,7 +1347,7 @@ import "misc.idl", "lsa.idl", "security.idl";
/************************/
/* Function 0x3a */
/*
- seems to be an exact alias for samr_SetUserInfo()
+ seems to be an exact alias for samr_SetUserInfo()
*/
[public] NTSTATUS samr_SetUserInfo2(
[in,ref] policy_handle *user_handle,
@@ -1434,10 +1451,9 @@ import "misc.idl", "lsa.idl", "security.idl";
NTSTATUS samr_RidToSid(
[in,ref] policy_handle *domain_handle,
[in] uint32 rid,
- [out,ref] dom_sid2 *sid
+ [out,ref] dom_sid2 **sid
);
-
/************************/
/* Function 0x42 */
diff --git a/source4/librpc/idl/security.cnf b/librpc/idl/security.cnf
index 37da8c7423..37da8c7423 100644
--- a/source4/librpc/idl/security.cnf
+++ b/librpc/idl/security.cnf
diff --git a/librpc/idl/security.idl b/librpc/idl/security.idl
index 690f406081..3f70e2c36e 100644
--- a/librpc/idl/security.idl
+++ b/librpc/idl/security.idl
@@ -5,27 +5,10 @@
*/
import "misc.idl";
-
-/*
- use the same structure for dom_sid2 as dom_sid. A dom_sid2 is really
- just a dom sid, but with the sub_auths represented as a conformant
- array. As with all in-structure conformant arrays, the array length
- is placed before the start of the structure. That's what gives rise
- to the extra num_auths elemenent. We don't want the Samba code to
- have to bother with such esoteric NDR details, so its easier to just
- define it as a dom_sid and use pidl magic to make it all work. It
- just means you need to mark a sid as a "dom_sid2" in the IDL when you
- know it is of the conformant array variety
-*/
-cpp_quote("#define dom_sid2 dom_sid")
-
-/* same struct as dom_sid but inside a 28 bytes fixed buffer in NDR */
-cpp_quote("#define dom_sid28 dom_sid")
-
-/* same struct as dom_sid but in a variable byte buffer, which is maybe empty in NDR */
-cpp_quote("#define dom_sid0 dom_sid")
+import "dom_sid.idl";
[
+ helper("librpc/gen_ndr/ndr_dom_sid.h"),
pointer_default(unique)
]
interface security
@@ -257,7 +240,7 @@ interface security
} sec_privilege;
- typedef [bitmap8bit] bitmap {
+ typedef [public,bitmap8bit] bitmap {
SEC_ACE_FLAG_OBJECT_INHERIT = 0x01,
SEC_ACE_FLAG_CONTAINER_INHERIT = 0x02,
SEC_ACE_FLAG_NO_PROPAGATE_INHERIT = 0x04,
@@ -268,7 +251,7 @@ interface security
SEC_ACE_FLAG_FAILED_ACCESS = 0x80
} security_ace_flags;
- typedef [enum8bit] enum {
+ typedef [public,enum8bit] enum {
SEC_ACE_TYPE_ACCESS_ALLOWED = 0,
SEC_ACE_TYPE_ACCESS_DENIED = 1,
SEC_ACE_TYPE_SYSTEM_AUDIT = 2,
@@ -305,7 +288,7 @@ interface security
[switch_is(flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT)] security_ace_object_inherited_type inherited_type;
} security_ace_object;
- typedef [nodiscriminant] union {
+ typedef [public,nodiscriminant] union {
[case(SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT)] security_ace_object object;
[case(SEC_ACE_TYPE_ACCESS_DENIED_OBJECT)] security_ace_object object;
[case(SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT)] security_ace_object object;
@@ -313,7 +296,7 @@ interface security
[default];
} security_ace_object_ctr;
- typedef [public,gensize,nosize] struct {
+ typedef [public,nopull,gensize,nosize] struct {
security_ace_type type; /* SEC_ACE_TYPE_* */
security_ace_flags flags; /* SEC_ACE_FLAG_* */
[value(ndr_size_security_ace(r,ndr->flags))] uint16 size;
diff --git a/librpc/idl/svcctl.idl b/librpc/idl/svcctl.idl
index fa8e10988c..4b88f5e5f4 100644
--- a/librpc/idl/svcctl.idl
+++ b/librpc/idl/svcctl.idl
@@ -89,13 +89,19 @@ import "misc.idl", "security.idl";
/*****************/
/* Function 0x01 */
- typedef enum {
- FIXME=1
+ /* Service Controls */
+
+ typedef [v1_enum] enum {
+ SVCCTL_CONTROL_STOP = 0x00000001,
+ SVCCTL_CONTROL_PAUSE = 0x00000002,
+ SVCCTL_CONTROL_CONTINUE = 0x00000003,
+ SVCCTL_CONTROL_INTERROGATE = 0x00000004,
+ SVCCTL_CONTROL_SHUTDOWN = 0x00000005
} SERVICE_CONTROL;
WERROR svcctl_ControlService(
[in,ref] policy_handle *handle,
- [in] uint32 control,
+ [in] SERVICE_CONTROL control,
[out,ref] SERVICE_STATUS *service_status
);
@@ -218,10 +224,10 @@ import "misc.idl", "security.idl";
[in,ref] policy_handle *handle,
[in] uint32 type,
[in] uint32 state,
- [in] uint32 buf_size,
- [out,size_is(buf_size)] uint8 service[*],
- [out,ref] uint32 *bytes_needed,
- [out,ref] uint32 *services_returned,
+ [out,ref,size_is(buf_size)] uint8 *service,
+ [in] [range(0,262144)] uint32 buf_size,
+ [out,ref] [range(0,262144)] uint32 *bytes_needed,
+ [out,ref] [range(0,262144)] uint32 *services_returned,
[in,out,unique] uint32 *resume_handle
);
@@ -535,9 +541,9 @@ import "misc.idl", "security.idl";
WERROR svcctl_QueryServiceConfig2W(
[in,ref] policy_handle *handle,
[in] uint32 info_level,
- [out] uint8 buffer[buf_size],
- [in] uint32 buf_size,
- [out,ref] uint32 *bytes_needed
+ [out,ref,size_is(buf_size)] uint8 *buffer,
+ [in] [range(0,8192)] uint32 buf_size,
+ [out,ref] [range(0,8192)] uint32 *bytes_needed
);
/*****************/
@@ -545,9 +551,9 @@ import "misc.idl", "security.idl";
WERROR svcctl_QueryServiceStatusEx(
[in,ref] policy_handle *handle,
[in] uint32 info_level,
- [out] uint8 buffer[buf_size],
- [in] uint32 buf_size,
- [out,ref] uint32 *bytes_needed
+ [out,ref,size_is(buf_size)] uint8 *buffer,
+ [in] [range(0,8192)] uint32 buf_size,
+ [out,ref] [range(0,8192)] uint32 *bytes_needed
);
/*****************/
@@ -572,12 +578,12 @@ import "misc.idl", "security.idl";
[in] uint32 info_level,
[in] uint32 type,
[in] uint32 state,
- [out] uint8 services[buf_size],
- [in] uint32 buf_size,
- [out,ref] uint32 *bytes_needed,
- [out,ref] uint32 *service_returned,
- [in,out,unique] uint32 *resume_handle,
- [out,ref] [string,charset(UTF16)] uint16 **group_name
+ [out,ref,size_is(buf_size)] uint8 *services,
+ [in] [range(0,262144)] uint32 buf_size,
+ [out,ref] [range(0,262144)] uint32 *bytes_needed,
+ [out,ref] [range(0,262144)] uint32 *service_returned,
+ [in,out,unique] [range(0,262144)] uint32 *resume_handle,
+ [in,unique] [string,charset(UTF16)] uint16 *group_name
);
/*****************/
diff --git a/librpc/idl/xattr.idl b/librpc/idl/xattr.idl
index c1af4791ae..4191ea67ce 100644
--- a/librpc/idl/xattr.idl
+++ b/librpc/idl/xattr.idl
@@ -117,20 +117,20 @@ interface xattr
stored in "security.NTACL"
Version 1. raw SD stored as Samba4 does it.
- Version 2. raw SD + last changed timestamp so we
- can discard if this doesn't match the POSIX st_ctime.
+ Version 2. raw SD + last changed hash so we
+ can discard if this doesn't match the underlying ACL hash.
*/
const char *XATTR_NTACL_NAME = "security.NTACL";
typedef [public] struct {
security_descriptor *sd;
- NTTIME last_changed;
- } security_descriptor_timestamp;
+ uint8 hash[16];
+ } security_descriptor_hash;
typedef [switch_type(uint16)] union {
[case(1)] security_descriptor *sd;
- [case(2)] security_descriptor_timestamp *sd_ts;
+ [case(2)] security_descriptor_hash *sd_hs;
} xattr_NTACL_Info;
typedef [public] struct {
diff --git a/librpc/ndr/libndr.h b/librpc/ndr/libndr.h
index 127f6734e3..eafaf688af 100644
--- a/librpc/ndr/libndr.h
+++ b/librpc/ndr/libndr.h
@@ -511,6 +511,7 @@ enum ndr_err_code ndr_push_charset(struct ndr_push *ndr, int ndr_flags, const ch
/* GUIDs */
bool GUID_equal(const struct GUID *u1, const struct GUID *u2);
+NTSTATUS GUID_from_data_blob(const DATA_BLOB *s, struct GUID *guid);
NTSTATUS GUID_from_string(const char *s, struct GUID *guid);
NTSTATUS NS_GUID_from_string(const char *s, struct GUID *guid);
struct GUID GUID_zero(void);
@@ -518,6 +519,7 @@ bool GUID_all_zero(const struct GUID *u);
int GUID_compare(const struct GUID *u1, const struct GUID *u2);
char *GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid);
char *GUID_string2(TALLOC_CTX *mem_ctx, const struct GUID *guid);
+char *GUID_hexstring(TALLOC_CTX *mem_ctx, const struct GUID *guid);
char *NS_GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid);
struct GUID GUID_random(void);
diff --git a/librpc/ndr/ndr_netlogon.c b/librpc/ndr/ndr_netlogon.c
new file mode 100644
index 0000000000..411f3b9ba0
--- /dev/null
+++ b/librpc/ndr/ndr_netlogon.c
@@ -0,0 +1,65 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ routines for marshalling/unmarshalling special netlogon types
+
+ Copyright (C) Guenther Deschner 2008
+
+ 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_netlogon.h"
+#include "librpc/gen_ndr/ndr_misc.h"
+#include "librpc/gen_ndr/ndr_samr.h"
+
+_PUBLIC_ enum ndr_err_code ndr_push_netr_SamDatabaseID8Bit(struct ndr_push *ndr, int ndr_flags, enum netr_SamDatabaseID8Bit r)
+{
+ if (r > 0xff) return NDR_ERR_BUFSIZE;
+ NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r));
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_pull_netr_SamDatabaseID8Bit(struct ndr_pull *ndr, int ndr_flags, enum netr_SamDatabaseID8Bit *r)
+{
+ uint8_t v;
+ NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &v));
+ *r = v;
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_netr_SamDatabaseID8Bit(struct ndr_print *ndr, const char *name, enum netr_SamDatabaseID8Bit r)
+{
+ ndr_print_netr_SamDatabaseID(ndr, name, r);
+}
+
+_PUBLIC_ enum ndr_err_code ndr_push_netr_DeltaEnum8Bit(struct ndr_push *ndr, int ndr_flags, enum netr_DeltaEnum8Bit r)
+{
+ if (r > 0xff) return NDR_ERR_BUFSIZE;
+ NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r));
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_pull_netr_DeltaEnum8Bit(struct ndr_pull *ndr, int ndr_flags, enum netr_DeltaEnum8Bit *r)
+{
+ uint8_t v;
+ NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &v));
+ *r = v;
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_netr_DeltaEnum8Bit(struct ndr_print *ndr, const char *name, enum netr_DeltaEnum8Bit r)
+{
+ ndr_print_netr_DeltaEnum(ndr, name, r);
+}
diff --git a/librpc/ndr/ndr_netlogon.h b/librpc/ndr/ndr_netlogon.h
new file mode 100644
index 0000000000..0e6bd6a410
--- /dev/null
+++ b/librpc/ndr/ndr_netlogon.h
@@ -0,0 +1,28 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ routines for marshalling/unmarshalling special netlogon types
+
+ Copyright (C) Guenther Deschner 2008
+
+ 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/>.
+*/
+
+_PUBLIC_ enum ndr_err_code ndr_push_netr_SamDatabaseID8Bit(struct ndr_push *ndr, int ndr_flags, enum netr_SamDatabaseID8Bit r);
+_PUBLIC_ enum ndr_err_code ndr_pull_netr_SamDatabaseID8Bit(struct ndr_pull *ndr, int ndr_flags, enum netr_SamDatabaseID8Bit *r);
+_PUBLIC_ void ndr_print_netr_SamDatabaseID8Bit(struct ndr_print *ndr, const char *name, enum netr_SamDatabaseID8Bit r);
+
+_PUBLIC_ enum ndr_err_code ndr_push_netr_DeltaEnum8Bit(struct ndr_push *ndr, int ndr_flags, enum netr_DeltaEnum8Bit r);
+_PUBLIC_ enum ndr_err_code ndr_pull_netr_DeltaEnum8Bit(struct ndr_pull *ndr, int ndr_flags, enum netr_DeltaEnum8Bit *r);
+_PUBLIC_ void ndr_print_netr_DeltaEnum8Bit(struct ndr_print *ndr, const char *name, enum netr_DeltaEnum8Bit r);
diff --git a/librpc/ndr/ndr_sec_helper.c b/librpc/ndr/ndr_sec_helper.c
new file mode 100644
index 0000000000..4b135505d8
--- /dev/null
+++ b/librpc/ndr/ndr_sec_helper.c
@@ -0,0 +1,118 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ fast routines for getting the wire size of security objects
+
+ Copyright (C) Andrew Tridgell 2003
+ Copyright (C) Stefan Metzmacher 2006-2008
+
+ 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_security.h"
+
+/*
+ return the wire size of a security_ace
+*/
+size_t ndr_size_security_ace(const struct security_ace *ace, int flags)
+{
+ size_t ret;
+
+ if (!ace) return 0;
+
+ ret = 8 + ndr_size_dom_sid(&ace->trustee, flags);
+
+ switch (ace->type) {
+ case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
+ case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
+ case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT:
+ case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT:
+ ret += 4; /* uint32 bitmap ace->object.object.flags */
+ if (ace->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT) {
+ ret += 16; /* GUID ace->object.object.type.type */
+ }
+ if (ace->object.object.flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) {
+ ret += 16; /* GUID ace->object.object.inherited_typeinherited_type */
+ }
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+enum ndr_err_code ndr_pull_security_ace(struct ndr_pull *ndr, int ndr_flags, struct security_ace *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ uint32_t start_ofs = ndr->offset;
+ uint32_t size = 0;
+ uint32_t pad = 0;
+ NDR_CHECK(ndr_pull_align(ndr, 4));
+ NDR_CHECK(ndr_pull_security_ace_type(ndr, NDR_SCALARS, &r->type));
+ NDR_CHECK(ndr_pull_security_ace_flags(ndr, NDR_SCALARS, &r->flags));
+ NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->size));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->access_mask));
+ NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->object, r->type));
+ NDR_CHECK(ndr_pull_security_ace_object_ctr(ndr, NDR_SCALARS, &r->object));
+ NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, &r->trustee));
+ size = ndr->offset - start_ofs;
+ if (r->size < size) {
+ return ndr_pull_error(ndr, NDR_ERR_BUFSIZE,
+ "ndr_pull_security_ace: r->size %u < size %u",
+ (unsigned)r->size, size);
+ }
+ pad = r->size - size;
+ NDR_PULL_NEED_BYTES(ndr, pad);
+ ndr->offset += pad;
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ NDR_CHECK(ndr_pull_security_ace_object_ctr(ndr, NDR_BUFFERS, &r->object));
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+/*
+ return the wire size of a security_acl
+*/
+size_t ndr_size_security_acl(const struct security_acl *acl, int flags)
+{
+ size_t ret;
+ int i;
+ if (!acl) return 0;
+ ret = 8;
+ for (i=0;i<acl->num_aces;i++) {
+ ret += ndr_size_security_ace(&acl->aces[i], flags);
+ }
+ return ret;
+}
+
+/*
+ return the wire size of a security descriptor
+*/
+size_t ndr_size_security_descriptor(const struct security_descriptor *sd, int flags)
+{
+ size_t ret;
+ if (!sd) return 0;
+
+ ret = 20;
+ ret += ndr_size_dom_sid(sd->owner_sid, flags);
+ ret += ndr_size_dom_sid(sd->group_sid, flags);
+ ret += ndr_size_security_acl(sd->dacl, flags);
+ ret += ndr_size_security_acl(sd->sacl, flags);
+ return ret;
+}
+
diff --git a/librpc/ndr/uuid.c b/librpc/ndr/uuid.c
index 1e6ee0a3db..aa24ac4494 100644
--- a/librpc/ndr/uuid.c
+++ b/librpc/ndr/uuid.c
@@ -23,33 +23,66 @@
#include "includes.h"
#include "librpc/ndr/libndr.h"
+#include "librpc/gen_ndr/ndr_misc.h"
/**
build a GUID from a string
*/
-_PUBLIC_ NTSTATUS GUID_from_string(const char *s, struct GUID *guid)
+_PUBLIC_ NTSTATUS GUID_from_data_blob(const DATA_BLOB *s, struct GUID *guid)
{
NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
uint32_t time_low;
uint32_t time_mid, time_hi_and_version;
uint32_t clock_seq[2];
uint32_t node[6];
+ uint8_t buf16[16];
+ DATA_BLOB blob16 = data_blob_const(buf16, sizeof(buf16));
int i;
- if (s == NULL) {
+ if (s->data == NULL) {
return NT_STATUS_INVALID_PARAMETER;
}
- if (11 == sscanf(s, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ if (s->length == 36 &&
+ 11 == sscanf((const char *)s->data,
+ "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
&time_low, &time_mid, &time_hi_and_version,
&clock_seq[0], &clock_seq[1],
&node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
status = NT_STATUS_OK;
- } else if (11 == sscanf(s, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
- &time_low, &time_mid, &time_hi_and_version,
- &clock_seq[0], &clock_seq[1],
- &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
+ } else if (s->length == 38
+ && 11 == sscanf((const char *)s->data,
+ "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+ &time_low, &time_mid, &time_hi_and_version,
+ &clock_seq[0], &clock_seq[1],
+ &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
status = NT_STATUS_OK;
+ } else if (s->length == 32) {
+ size_t rlen = strhex_to_str((char *)blob16.data, blob16.length,
+ (const char *)s->data, s->length);
+ if (rlen == blob16.length) {
+ /* goto the ndr_pull_struct_blob() path */
+ status = NT_STATUS_OK;
+ s = &blob16;
+ }
+ }
+
+ if (s->length == 16) {
+ enum ndr_err_code ndr_err;
+ struct GUID guid2;
+ TALLOC_CTX *mem_ctx;
+
+ mem_ctx = talloc_new(NULL);
+ NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
+
+ ndr_err = ndr_pull_struct_blob(s, mem_ctx, NULL, &guid2,
+ (ndr_pull_flags_fn_t)ndr_pull_GUID);
+ talloc_free(mem_ctx);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return ndr_map_error2ntstatus(ndr_err);
+ }
+ *guid = guid2;
+ return NT_STATUS_OK;
}
if (!NT_STATUS_IS_OK(status)) {
@@ -71,6 +104,16 @@ _PUBLIC_ NTSTATUS GUID_from_string(const char *s, struct GUID *guid)
/**
build a GUID from a string
*/
+_PUBLIC_ NTSTATUS GUID_from_string(const char *s, struct GUID *guid)
+{
+ DATA_BLOB blob = data_blob_string_const(s);
+ return GUID_from_data_blob(&blob, guid);
+ return NT_STATUS_OK;
+}
+
+/**
+ build a GUID from a string
+*/
_PUBLIC_ NTSTATUS NS_GUID_from_string(const char *s, struct GUID *guid)
{
NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
@@ -208,6 +251,31 @@ _PUBLIC_ char *GUID_string2(TALLOC_CTX *mem_ctx, const struct GUID *guid)
return ret;
}
+_PUBLIC_ char *GUID_hexstring(TALLOC_CTX *mem_ctx, const struct GUID *guid)
+{
+ char *ret;
+ DATA_BLOB guid_blob;
+ enum ndr_err_code ndr_err;
+ TALLOC_CTX *tmp_mem;
+
+ tmp_mem = talloc_new(mem_ctx);
+ if (!tmp_mem) {
+ return NULL;
+ }
+ ndr_err = ndr_push_struct_blob(&guid_blob, tmp_mem,
+ NULL,
+ guid,
+ (ndr_push_flags_fn_t)ndr_push_GUID);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ talloc_free(tmp_mem);
+ return NULL;
+ }
+
+ ret = data_blob_hex_string(mem_ctx, &guid_blob);
+ talloc_free(tmp_mem);
+ return ret;
+}
+
_PUBLIC_ char *NS_GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid)
{
return talloc_asprintf(mem_ctx,
diff --git a/librpc/rpc/binding.c b/librpc/rpc/binding.c
index b755431034..a660989d19 100644
--- a/librpc/rpc/binding.c
+++ b/librpc/rpc/binding.c
@@ -251,8 +251,8 @@ _PUBLIC_ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struc
if (p && PTR_DIFF(p, s) == 36) { /* 36 is the length of a UUID */
NTSTATUS status;
-
- status = GUID_from_string(s, &b->object.uuid);
+ DATA_BLOB blob = data_blob(s, 36);
+ status = GUID_from_data_blob(&blob, &b->object.uuid);
if (NT_STATUS_IS_ERR(status)) {
DEBUG(0, ("Failed parsing UUID\n"));
diff --git a/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm b/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
index 2a23fad4a7..4109ce9962 100644
--- a/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
+++ b/pidl/lib/Parse/Pidl/Samba3/ClientNDR.pm
@@ -215,7 +215,10 @@ sub ParseInterface($$)
$self->pidl_hdr("#ifndef __CLI_$uif\__");
$self->pidl_hdr("#define __CLI_$uif\__");
- $self->ParseFunction($if->{NAME}, $_) foreach (@{$if->{FUNCTIONS}});
+ foreach (@{$if->{FUNCTIONS}}) {
+ next if ($_->{PROPERTIES}{noopnum});
+ $self->ParseFunction($if->{NAME}, $_);
+ }
$self->pidl_hdr("#endif /* __CLI_$uif\__ */");
}
diff --git a/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm b/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
index 6034fb6f16..eb3cdf20cb 100644
--- a/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
+++ b/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
@@ -142,6 +142,13 @@ sub ParseFunction($$)
my @dir = @{$_->{DIRECTION}};
if (grep(/in/, @dir) and grep(/out/, @dir)) {
pidl "r->out.$_->{NAME} = r->in.$_->{NAME};";
+ }
+ }
+
+ foreach (@{$fn->{ELEMENTS}}) {
+ my @dir = @{$_->{DIRECTION}};
+ if (grep(/in/, @dir) and grep(/out/, @dir)) {
+ # noop
} elsif (grep(/out/, @dir) and not
has_property($_, "represent_as")) {
AllocOutVar($_, "r", "r->out.$_->{NAME}", $env);
@@ -205,7 +212,11 @@ sub ParseInterface($)
pidl_hdr "#ifndef __SRV_$uif\__";
pidl_hdr "#define __SRV_$uif\__";
- ParseFunction($if, $_) foreach (@{$if->{FUNCTIONS}});
+
+ foreach (@{$if->{FUNCTIONS}}) {
+ next if ($_->{PROPERTIES}{noopnum});
+ ParseFunction($if, $_);
+ }
pidl "";
pidl "/* Tables */";
@@ -214,6 +225,7 @@ sub ParseInterface($)
indent;
foreach (@{$if->{FUNCTIONS}}) {
+ next if ($_->{PROPERTIES}{noopnum});
pidl "{\"" . uc($_->{NAME}) . "\", NDR_" . uc($_->{NAME}) . ", api_$_->{NAME}},";
}
diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm b/pidl/lib/Parse/Pidl/Samba4/Python.pm
index 38aee2c9d1..a3107d4672 100644
--- a/pidl/lib/Parse/Pidl/Samba4/Python.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm
@@ -702,7 +702,7 @@ sub Interface($$$)
$self->pidl("if (!NT_STATUS_IS_OK(status)) {");
$self->indent;
$self->pidl("PyErr_SetNTSTATUS(status);");
- $self->pidl("return;");
+ $self->pidl("return NULL;");
$self->deindent;
$self->pidl("}");
@@ -1181,7 +1181,6 @@ sub Parse($$$$$)
$self->pidl("{");
$self->indent;
$self->pidl("PyObject *m;");
- $self->pidl("NTSTATUS status;");
$self->pidl("");
foreach (@{$self->{ready_types}}) {
diff --git a/release-scripts/build-docs b/release-scripts/build-docs
index fa38d8dd2c..c138149f6c 100755
--- a/release-scripts/build-docs
+++ b/release-scripts/build-docs
@@ -4,7 +4,7 @@ DOCSRCDIR=`dirname $0`/../docs-xml
cd $DOCSRCDIR || exit 1
-git-clean -d -x -f
+git clean -d -x -f
autoconf && \
./configure --with-papersize=letter && \
make smbdotconf/parameters.all.xml && \
diff --git a/release-scripts/create-tarball b/release-scripts/create-tarball
index 04728d835d..ab27f08222 100755
--- a/release-scripts/create-tarball
+++ b/release-scripts/create-tarball
@@ -137,7 +137,7 @@ function createReleaseTag
return 0
fi
- if [ "x`git-tag -l ${OPT_TAG}`" != "x" ]; then
+ if [ "x`git tag -l ${OPT_TAG}`" != "x" ]; then
echo -n "Tag exists. Do you wish to overwrite? (y/N): "
read answer
@@ -155,7 +155,7 @@ function createReleaseTag
fi
fi
- git-tag -u ${OPT_KEYID} ${OPT_TAG}
+ git tag -u ${OPT_KEYID} ${OPT_TAG}
exitOnError $? "Failed to create tag"
return 0
@@ -170,7 +170,7 @@ function main
cd $TOPDIR
- git-checkout ${OPT_BRANCH}
+ git checkout ${OPT_BRANCH}
exitOnError $? "Invalid branch name \"${OPT_BRANCH}\""
(cd source3 && ./script/mkversion.sh)
@@ -188,7 +188,7 @@ function main
echo "Creating release tarball for Samba $version"
/bin/rm -rf ../samba-${version}
- git-archive --format=tar --prefix=samba-${version}/ HEAD | (cd .. && tar xf -)
+ git archive --format=tar --prefix=samba-${version}/ HEAD | (cd .. && tar xf -)
exitOnError $? "Failed to create release directory tree"
pushd ../samba-${version}
diff --git a/source3/Makefile.in b/source3/Makefile.in
index ce24001fd2..83e94a4382 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -17,6 +17,7 @@ localstatedir=@localstatedir@
datarootdir=@datarootdir@
selftest_prefix=@selftest_prefix@
+selftest_shrdir=@selftest_shrdir@
smbtorture4_path=@smbtorture4_path@
LIBS=@LIBS@
@@ -139,6 +140,9 @@ PRIVATE_DIR = $(PRIVATEDIR)
# This is where SWAT images and help files go
SWATDIR = @swatdir@
+# This is where locale(mo) files go
+LOCALEDIR= @localedir@
+
# the directory where lock files go
LOCKDIR = @lockdir@
@@ -172,7 +176,8 @@ PATH_FLAGS = -DSMB_PASSWD_FILE=\"$(SMB_PASSWD_FILE)\" \
-DCONFIGDIR=\"$(CONFIGDIR)\" \
-DCODEPAGEDIR=\"$(CODEPAGEDIR)\" \
-DCACHEDIR=\"$(CACHEDIR)\" \
- -DSTATEDIR=\"$(STATEDIR)\"
+ -DSTATEDIR=\"$(STATEDIR)\" \
+ -DLOCALEDIR=\"$(LOCALEDIR)\"
# Note that all executable programs now provide for an optional executable suffix.
@@ -224,6 +229,8 @@ MODULES = $(VFS_MODULES) $(PDB_MODULES) $(RPC_MODULES) $(IDMAP_MODULES) \
$(CHARSET_MODULES) $(AUTH_MODULES) $(NSS_INFO_MODULES) \
$(GPEXT_MODULES)
+EXTRA_ALL_TARGETS = @EXTRA_ALL_TARGETS@
+
######################################################################
# object file lists
######################################################################
@@ -267,7 +274,7 @@ LIBNDR_OBJ = ../librpc/ndr/ndr_basic.o \
../librpc/ndr/ndr_misc.o \
librpc/gen_ndr/ndr_misc.o \
librpc/gen_ndr/ndr_security.o \
- librpc/ndr/ndr_sec_helper.o \
+ ../librpc/ndr/ndr_sec_helper.o \
librpc/ndr/ndr_string.o \
librpc/ndr/sid.o \
../librpc/ndr/uuid.o \
@@ -278,7 +285,8 @@ RPCCLIENT_NDR_OBJ = rpc_client/ndr.o
LIBNDR_GEN_OBJ0 = librpc/gen_ndr/ndr_samr.o \
librpc/gen_ndr/ndr_lsa.o
-LIBNDR_GEN_OBJ1 = librpc/gen_ndr/ndr_netlogon.o
+LIBNDR_GEN_OBJ1 = librpc/gen_ndr/ndr_netlogon.o \
+ ../librpc/ndr/ndr_netlogon.o
LIBNDR_GEN_OBJ = librpc/gen_ndr/ndr_wkssvc.o \
$(LIBNDR_GEN_OBJ0) \
@@ -293,6 +301,7 @@ LIBNDR_GEN_OBJ = librpc/gen_ndr/ndr_wkssvc.o \
librpc/gen_ndr/ndr_notify.o \
librpc/gen_ndr/ndr_xattr.o \
librpc/gen_ndr/ndr_epmapper.o \
+ librpc/gen_ndr/ndr_named_pipe_auth.o \
librpc/gen_ndr/ndr_ntsvcs.o
RPC_PARSE_OBJ0 = rpc_parse/parse_prs.o rpc_parse/parse_misc.o
@@ -639,7 +648,9 @@ VFS_FILEID_OBJ = modules/vfs_fileid.o
VFS_AIO_FORK_OBJ = modules/vfs_aio_fork.o
VFS_SYNCOPS_OBJ = modules/vfs_syncops.o
VFS_ACL_XATTR_OBJ = modules/vfs_acl_xattr.o
+VFS_ACL_TDB_OBJ = modules/vfs_acl_tdb.o
VFS_SMB_TRAFFIC_ANALYZER_OBJ = modules/vfs_smb_traffic_analyzer.o
+VFS_ONEFS_OBJ = modules/vfs_onefs.o modules/onefs_acl.o
PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o
@@ -797,7 +808,7 @@ RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \
$(LIBADS_OBJ) $(POPT_LIB_OBJ) \
$(SMBLDAP_OBJ) $(DCUTIL_OBJ) $(LDB_OBJ)
-PAM_WINBIND_OBJ = nsswitch/pam_winbind.o $(WBCOMMON_OBJ) \
+PAM_WINBIND_OBJ = nsswitch/pam_winbind.o localedir.o $(WBCOMMON_OBJ) \
$(LIBREPLACE_OBJ) @BUILD_INIPARSER@
LIBSMBCLIENT_OBJ0 = \
@@ -903,9 +914,9 @@ CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
$(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) \
$(LIBNDR_GEN_OBJ0)
-CIFS_MOUNT_OBJ = client/mount.cifs.o
+CIFS_MOUNT_OBJ = client/mount.cifs.o client/mtab.o
-CIFS_UMOUNT_OBJ = client/umount.cifs.o
+CIFS_UMOUNT_OBJ = client/umount.cifs.o client/mtab.o
CIFS_UPCALL_OBJ = client/cifs.upcall.o
@@ -921,7 +932,7 @@ SMBTORTURE_OBJ = $(SMBTORTURE_OBJ1) $(PARAM_OBJ) \
MASKTEST_OBJ = torture/masktest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
$(LIB_NONSMBD_OBJ) \
- $(LIBNDR_GEN_OBJ0) $(ZLIB_LIBS)
+ $(LIBNDR_GEN_OBJ0)
MSGTEST_OBJ = torture/msgtest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
$(LIB_NONSMBD_OBJ) \
@@ -929,7 +940,7 @@ MSGTEST_OBJ = torture/msgtest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
LOCKTEST_OBJ = torture/locktest.o $(PARAM_OBJ) $(LOCKING_OBJ) $(KRBCLIENT_OBJ) \
$(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) \
- $(LIBNDR_GEN_OBJ0) $(ZLIB_LIBS)
+ $(LIBNDR_GEN_OBJ0)
NSSTEST_OBJ = torture/nsstest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
$(LIB_NONSMBD_OBJ) \
@@ -948,7 +959,7 @@ LOG2PCAP_OBJ = utils/log2pcaphex.o
LOCKTEST2_OBJ = torture/locktest2.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) \
$(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \
- $(LIBNDR_GEN_OBJ0) $(ZLIB_LIBS)
+ $(LIBNDR_GEN_OBJ0)
SMBCACLS_OBJ = utils/smbcacls.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
$(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(RPC_PARSE_OBJ) \
@@ -1156,7 +1167,8 @@ RPC_OPEN_TCP_OBJ = torture/rpc_open_tcp.o \
# now the rules...
######################################################################
all:: SHOWFLAGS basics libs $(SBIN_PROGS) $(BIN_PROGS) $(ROOT_SBIN_PROGS) \
- $(MODULES) $(NSS_MODULES) $(PAM_MODULES) @EXTRA_ALL_TARGETS@
+ $(MODULES) $(NSS_MODULES) $(PAM_MODULES) @CIFSUPCALL_PROGS@ \
+ $(EXTRA_ALL_TARGETS)
basics::
@@ -1219,14 +1231,18 @@ samba3-idl::
../librpc/idl/initshutdown.idl ../librpc/idl/srvsvc.idl ../librpc/idl/svcctl.idl \
../librpc/idl/eventlog.idl ../librpc/idl/wkssvc.idl ../librpc/idl/netlogon.idl \
../librpc/idl/notify.idl ../librpc/idl/epmapper.idl librpc/idl/messaging.idl \
- ../librpc/idl/xattr.idl ../librpc/idl/misc.idl librpc/idl/samr.idl \
+ ../librpc/idl/xattr.idl ../librpc/idl/misc.idl ../librpc/idl/samr.idl \
../librpc/idl/security.idl ../librpc/idl/dssetup.idl ../librpc/idl/krb5pac.idl \
../librpc/idl/ntsvcs.idl librpc/idl/libnetapi.idl ../librpc/idl/drsuapi.idl \
- ../librpc/idl/drsblobs.idl ../librpc/idl/nbt.idl
+ ../librpc/idl/drsblobs.idl ../librpc/idl/nbt.idl \
+ ../librpc/idl/named_pipe_auth.idl librpc/idl/dom_sid.idl
+ @$(MAKE) ndr-tables
+
+NDR_TABLES = librpc/gen_ndr/tables.c
-librpc/gen_ndr/tables.c:: librpc/gen_ndr/*.h
- @echo "Generating $@"
- @$(PERL) ../librpc/tables.pl $^ > $@
+ndr-tables:: librpc/gen_ndr/*.h
+ @echo "Generating $(NDR_TABLES)"
+ @$(PERL) ../librpc/tables.pl $^ > $(NDR_TABLES)
#####################################################################
@@ -1304,6 +1320,13 @@ dynconfig.o: dynconfig.c Makefile
echo "$(COMPILE_CC_PATH)" 1>&2;\
$(COMPILE_CC_PATH) >/dev/null 2>&1
+localedir.o: localedir.c Makefile
+ @echo Compiling $*.c
+ @$(COMPILE_CC_PATH) && exit 0;\
+ echo "The following command failed:" 1>&2;\
+ echo "$(COMPILE_CC_PATH)" 1>&2;\
+ $(COMPILE_CC_PATH) >/dev/null 2>&1
+
lib/pidfile.o: lib/pidfile.c
@echo Compiling $*.c
@$(COMPILE_CC_PATH) && exit 0;\
@@ -2453,6 +2476,14 @@ bin/smb_traffic_analyzer.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_SMB_TRAFFIC_ANALYZE
@echo "Building plugin $@"
@$(SHLD_MODULE) $(VFS_SMB_TRAFFIC_ANALYZER_OBJ)
+bin/acl_tdb.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_ACL_TDB_OBJ)
+ @echo "Building plugin $@"
+ @$(SHLD_MODULE) $(VFS_ACL_TDB_OBJ)
+
+bin/onefs.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_ONEFS_OBJ)
+ @echo "Building plugin $@"
+ @$(SHLD_MODULE) $(VFS_ONEFS_OBJ) @ONEFS_LIBS@
+
bin/registry.@SHLIBEXT@: $(BINARY_PREREQS) libgpo/gpext/registry.o
@echo "Building plugin $@"
@$(SHLD_MODULE) libgpo/gpext/registry.o
@@ -2546,7 +2577,7 @@ bin/test_lp_load@EXEEXT@: $(BINARY_PREREQS) $(TEST_LP_LOAD_OBJ) @BUILD_POPT@ @LI
install:: installservers installbin @INSTALL_CIFSMOUNT@ @INSTALL_CIFSUPCALL@ installman \
installscripts installdat installmodules @SWAT_INSTALL_TARGETS@ \
- @INSTALL_PAM_MODULES@ installlibs
+ @INSTALL_PAM_MODULES@ installlibs installmo
install-everything:: install installmodules
@@ -2559,7 +2590,7 @@ install-everything:: install installmodules
# is not used
installdirs::
- @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(BINDIR) $(SBINDIR) $(LIBDIR) $(VARDIR) $(PRIVATEDIR) $(PIDDIR) $(LOCKDIR) $(MANDIR) $(CODEPAGEDIR) $(MODULESDIR)
+ @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(BINDIR) $(SBINDIR) $(LIBDIR) $(VARDIR) $(PRIVATEDIR) $(PIDDIR) $(LOCKDIR) $(MANDIR) $(CODEPAGEDIR) $(MODULESDIR) $(LOCALEDIR)
installservers:: all installdirs
@$(SHELL) script/installbin.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(SBINDIR) $(SBIN_PROGS)
@@ -2625,6 +2656,9 @@ revert::
installman:: installdirs
@$(SHELL) $(srcdir)/script/installman.sh $(DESTDIR)$(MANDIR) $(srcdir) C "@ROFF@"
+installmo:: all installdirs
+ @$(SHELL) $(srcdir)/script/installmo.sh $(DESTDIR) $(LOCALEDIR) $(srcdir)
+
.PHONY: showlayout
showlayout::
@@ -2644,7 +2678,10 @@ showlayout::
@echo " codepagedir: $(CODEPAGEDIR)"
-uninstall:: uninstallman uninstallservers uninstallbin @UNINSTALL_CIFSMOUNT@ @UNINSTALL_CIFSUPCALL@ uninstallscripts uninstalldat uninstallswat uninstallmodules uninstalllibs @UNINSTALL_PAM_MODULES@
+uninstall:: uninstallmo uninstallman uninstallservers uninstallbin @UNINSTALL_CIFSMOUNT@ @UNINSTALL_CIFSUPCALL@ uninstallscripts uninstalldat uninstallswat uninstallmodules uninstalllibs @UNINSTALL_PAM_MODULES@
+
+uninstallmo::
+ @$(SHELL) $(srcdir)/script/uninstallmo.sh $(DESTDIR) $(LOCALEDIR) $(srcdir)
uninstallman::
@$(SHELL) $(srcdir)/script/uninstallman.sh $(DESTDIR)$(MANDIR) $(srcdir) C
@@ -2689,7 +2726,7 @@ uninstallpammodules::
done
# Toplevel clean files
-TOPFILES=dynconfig.o
+TOPFILES=dynconfig.o localedir.o
cleanlibs::
-rm -f ../lib/*/*.o ../lib/*/*/*.o \
@@ -2759,7 +2796,7 @@ etags::
etags --append `find $(srcdir)/../source4/dsdb -name "*.[ch]"`
ctags::
- ctags `find $(srcdir)/.. -name "*.[ch]"`
+ ctags `find $(srcdir)/.. -name "*.[ch]" | grep -v include/proto\.h`
realclean:: clean
-rm -f config.log bin/.dummy script/findsmb script/gen-8bit-gap.sh
@@ -2835,7 +2872,7 @@ test_pam_modules:: pam_modules
##
test:: all torture timelimit
@echo Running Test suite
- @LIB_PATH_VAR=$(LIB_PATH_VAR) PERL="$(PERL)" $(srcdir)/script/tests/selftest.sh ${selftest_prefix} all "${smbtorture4_path}"
+ @LIB_PATH_VAR=$(LIB_PATH_VAR) PERL="$(PERL)" $(srcdir)/script/tests/selftest.sh ${selftest_prefix} all "${smbtorture4_path}" ${selftest_shrdir}
valgrindtest:: all torture timelimit
@echo Running Test suite with valgrind
diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index 7f95656bef..505098c76a 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -469,13 +469,13 @@ NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context)
{
case SEC_DOMAIN:
DEBUG(5,("Making default auth method list for security=domain\n"));
- auth_method_list = str_list_make(
+ auth_method_list = str_list_make_v3(
talloc_tos(), "guest sam winbind:ntdomain",
NULL);
break;
case SEC_SERVER:
DEBUG(5,("Making default auth method list for security=server\n"));
- auth_method_list = str_list_make(
+ auth_method_list = str_list_make_v3(
talloc_tos(), "guest sam smbserver",
NULL);
break;
@@ -483,36 +483,36 @@ NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context)
if (lp_encrypted_passwords()) {
if ((lp_server_role() == ROLE_DOMAIN_PDC) || (lp_server_role() == ROLE_DOMAIN_BDC)) {
DEBUG(5,("Making default auth method list for DC, security=user, encrypt passwords = yes\n"));
- auth_method_list = str_list_make(
+ auth_method_list = str_list_make_v3(
talloc_tos(),
"guest sam winbind:trustdomain",
NULL);
} else {
DEBUG(5,("Making default auth method list for standalone security=user, encrypt passwords = yes\n"));
- auth_method_list = str_list_make(
+ auth_method_list = str_list_make_v3(
talloc_tos(), "guest sam",
NULL);
}
} else {
DEBUG(5,("Making default auth method list for security=user, encrypt passwords = no\n"));
- auth_method_list = str_list_make(
+ auth_method_list = str_list_make_v3(
talloc_tos(), "guest unix", NULL);
}
break;
case SEC_SHARE:
if (lp_encrypted_passwords()) {
DEBUG(5,("Making default auth method list for security=share, encrypt passwords = yes\n"));
- auth_method_list = str_list_make(
+ auth_method_list = str_list_make_v3(
talloc_tos(), "guest sam", NULL);
} else {
DEBUG(5,("Making default auth method list for security=share, encrypt passwords = no\n"));
- auth_method_list = str_list_make(
+ auth_method_list = str_list_make_v3(
talloc_tos(), "guest unix", NULL);
}
break;
case SEC_ADS:
DEBUG(5,("Making default auth method list for security=ADS\n"));
- auth_method_list = str_list_make(
+ auth_method_list = str_list_make_v3(
talloc_tos(), "guest sam winbind:ntdomain",
NULL);
break;
diff --git a/source3/auth/token_util.c b/source3/auth/token_util.c
index e739fdaabe..28d6601b5f 100644
--- a/source3/auth/token_util.c
+++ b/source3/auth/token_util.c
@@ -77,7 +77,7 @@ bool nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid )
NT_USER_TOKEN *get_root_nt_token( void )
{
- struct nt_user_token *token = NULL;
+ struct nt_user_token *token, *for_cache;
DOM_SID u_sid, g_sid;
struct passwd *pw;
void *cache_data;
@@ -102,14 +102,16 @@ NT_USER_TOKEN *get_root_nt_token( void )
uid_to_sid(&u_sid, pw->pw_uid);
gid_to_sid(&g_sid, pw->pw_gid);
- token = create_local_nt_token(NULL, &u_sid, False,
+ token = create_local_nt_token(talloc_autofree_context(), &u_sid, False,
1, &global_sid_Builtin_Administrators);
token->privileges = se_disk_operators;
+ for_cache = token;
+
memcache_add_talloc(
NULL, SINGLETON_CACHE_TALLOC,
- data_blob_string_const_null("root_nt_token"), token);
+ data_blob_string_const_null("root_nt_token"), &for_cache);
return token;
}
diff --git a/source3/client/mount.cifs.c b/source3/client/mount.cifs.c
index 2a9c2b7304..da2f98bff8 100644
--- a/source3/client/mount.cifs.c
+++ b/source3/client/mount.cifs.c
@@ -39,9 +39,10 @@
#include <mntent.h>
#include <fcntl.h>
#include <limits.h>
+#include "mount.h"
#define MOUNT_CIFS_VERSION_MAJOR "1"
-#define MOUNT_CIFS_VERSION_MINOR "11"
+#define MOUNT_CIFS_VERSION_MINOR "12"
#ifndef MOUNT_CIFS_VENDOR_SUFFIX
#ifdef _SAMBA_BUILD_
@@ -79,15 +80,6 @@
#define MOUNT_PASSWD_SIZE 64
#define DOMAIN_SIZE 64
-/* exit status - bits below are ORed */
-#define EX_USAGE 1 /* incorrect invocation or permission */
-#define EX_SYSERR 2 /* out of memory, cannot fork, ... */
-#define EX_SOFTWARE 4 /* internal mount bug or wrong version */
-#define EX_USER 8 /* user interrupt */
-#define EX_FILEIO 16 /* problems writing, locking, ... mtab/fstab */
-#define EX_FAIL 32 /* mount failure */
-#define EX_SOMEOK 64 /* some mount succeeded */
-
const char *thisprogram;
int verboseflag = 0;
static int got_password = 0;
@@ -1424,48 +1416,57 @@ mount_retry:
printf("Refer to the mount.cifs(8) manual page (e.g.man mount.cifs)\n");
rc = EX_FAIL;
} else {
+ atexit(unlock_mtab);
+ rc = lock_mtab();
+ if (rc) {
+ printf("cannot lock mtab");
+ goto mount_exit;
+ }
pmntfile = setmntent(MOUNTED, "a+");
- if(pmntfile) {
- mountent.mnt_fsname = dev_name;
- mountent.mnt_dir = mountpoint;
- mountent.mnt_type = CONST_DISCARD(char *,"cifs");
- mountent.mnt_opts = (char *)malloc(220);
- if(mountent.mnt_opts) {
- char * mount_user = getusername();
- memset(mountent.mnt_opts,0,200);
- if(flags & MS_RDONLY)
- strlcat(mountent.mnt_opts,"ro",220);
- else
- strlcat(mountent.mnt_opts,"rw",220);
- if(flags & MS_MANDLOCK)
- strlcat(mountent.mnt_opts,",mand",220);
- if(flags & MS_NOEXEC)
- strlcat(mountent.mnt_opts,",noexec",220);
- if(flags & MS_NOSUID)
- strlcat(mountent.mnt_opts,",nosuid",220);
- if(flags & MS_NODEV)
- strlcat(mountent.mnt_opts,",nodev",220);
- if(flags & MS_SYNCHRONOUS)
- strlcat(mountent.mnt_opts,",synch",220);
- if(mount_user) {
- if(getuid() != 0) {
- strlcat(mountent.mnt_opts,",user=",220);
- strlcat(mountent.mnt_opts,mount_user,220);
- }
- /* free(mount_user); do not free static mem */
- }
- }
- mountent.mnt_freq = 0;
- mountent.mnt_passno = 0;
- rc = addmntent(pmntfile,&mountent);
- endmntent(pmntfile);
- SAFE_FREE(mountent.mnt_opts);
- if (rc)
- rc = EX_FILEIO;
- } else {
+ if (!pmntfile) {
printf("could not update mount table\n");
+ unlock_mtab();
rc = EX_FILEIO;
+ goto mount_exit;
}
+ mountent.mnt_fsname = dev_name;
+ mountent.mnt_dir = mountpoint;
+ mountent.mnt_type = CONST_DISCARD(char *,"cifs");
+ mountent.mnt_opts = (char *)malloc(220);
+ if(mountent.mnt_opts) {
+ char * mount_user = getusername();
+ memset(mountent.mnt_opts,0,200);
+ if(flags & MS_RDONLY)
+ strlcat(mountent.mnt_opts,"ro",220);
+ else
+ strlcat(mountent.mnt_opts,"rw",220);
+ if(flags & MS_MANDLOCK)
+ strlcat(mountent.mnt_opts,",mand",220);
+ if(flags & MS_NOEXEC)
+ strlcat(mountent.mnt_opts,",noexec",220);
+ if(flags & MS_NOSUID)
+ strlcat(mountent.mnt_opts,",nosuid",220);
+ if(flags & MS_NODEV)
+ strlcat(mountent.mnt_opts,",nodev",220);
+ if(flags & MS_SYNCHRONOUS)
+ strlcat(mountent.mnt_opts,",sync",220);
+ if(mount_user) {
+ if(getuid() != 0) {
+ strlcat(mountent.mnt_opts,
+ ",user=", 220);
+ strlcat(mountent.mnt_opts,
+ mount_user, 220);
+ }
+ }
+ }
+ mountent.mnt_freq = 0;
+ mountent.mnt_passno = 0;
+ rc = addmntent(pmntfile,&mountent);
+ endmntent(pmntfile);
+ unlock_mtab();
+ SAFE_FREE(mountent.mnt_opts);
+ if (rc)
+ rc = EX_FILEIO;
}
mount_exit:
if(mountpassword) {
diff --git a/source3/client/mount.h b/source3/client/mount.h
new file mode 100644
index 0000000000..23ea4f0cbd
--- /dev/null
+++ b/source3/client/mount.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2008 Jeff Layton (jlayton@samba.org)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * 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/>.
+ */
+
+/* most of this info was taken from the util-linux-ng sources */
+
+#ifndef _MOUNT_H_
+#define _MOUNT_H_
+
+/* exit status - bits below are ORed */
+#define EX_USAGE 1 /* incorrect invocation or permission */
+#define EX_SYSERR 2 /* out of memory, cannot fork, ... */
+#define EX_SOFTWARE 4 /* internal mount bug or wrong version */
+#define EX_USER 8 /* user interrupt */
+#define EX_FILEIO 16 /* problems writing, locking, ... mtab/fstab */
+#define EX_FAIL 32 /* mount failure */
+#define EX_SOMEOK 64 /* some mount succeeded */
+
+#define _PATH_MOUNTED_LOCK _PATH_MOUNTED "~"
+#define _PATH_MOUNTED_TMP _PATH_MOUNTED ".tmp"
+
+extern int lock_mtab(void);
+extern void unlock_mtab(void);
+
+#endif /* ! _MOUNT_H_ */
diff --git a/source3/client/mtab.c b/source3/client/mtab.c
new file mode 100644
index 0000000000..93fbd11359
--- /dev/null
+++ b/source3/client/mtab.c
@@ -0,0 +1,219 @@
+/*
+ * mtab locking routines for use with mount.cifs and umount.cifs
+ * Copyright (C) 2008 Jeff Layton (jlayton@samba.org)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * 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/>.
+*/
+
+/*
+ * This code was copied from the util-linux-ng sources and modified:
+ *
+ * git://git.kernel.org/pub/scm/utils/util-linux-ng/util-linux-ng.git
+ *
+ * ...specifically from mount/fstab.c. That file has no explicit license. The
+ * "default" license for anything in that tree is apparently GPLv2+, so I
+ * believe we're OK to copy it here.
+ *
+ * Jeff Layton <jlayton@samba.org>
+ */
+
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <time.h>
+#include <fcntl.h>
+#include <mntent.h>
+#include <stdlib.h>
+#include <signal.h>
+#include "mount.h"
+
+
+/* Updating mtab ----------------------------------------------*/
+
+/* Flag for already existing lock file. */
+static int we_created_lockfile = 0;
+static int lockfile_fd = -1;
+
+/* Flag to indicate that signals have been set up. */
+static int signals_have_been_setup = 0;
+
+static void
+handler (int sig) {
+ exit(EX_USER);
+}
+
+static void
+setlkw_timeout (int sig) {
+ /* nothing, fcntl will fail anyway */
+}
+
+/* Remove lock file. */
+void
+unlock_mtab (void) {
+ if (we_created_lockfile) {
+ close(lockfile_fd);
+ lockfile_fd = -1;
+ unlink (_PATH_MOUNTED_LOCK);
+ we_created_lockfile = 0;
+ }
+}
+
+/* Create the lock file.
+ The lock file will be removed if we catch a signal or when we exit. */
+/* The old code here used flock on a lock file /etc/mtab~ and deleted
+ this lock file afterwards. However, as rgooch remarks, that has a
+ race: a second mount may be waiting on the lock and proceed as
+ soon as the lock file is deleted by the first mount, and immediately
+ afterwards a third mount comes, creates a new /etc/mtab~, applies
+ flock to that, and also proceeds, so that the second and third mount
+ now both are scribbling in /etc/mtab.
+ The new code uses a link() instead of a creat(), where we proceed
+ only if it was us that created the lock, and hence we always have
+ to delete the lock afterwards. Now the use of flock() is in principle
+ superfluous, but avoids an arbitrary sleep(). */
+
+/* Where does the link point to? Obvious choices are mtab and mtab~~.
+ HJLu points out that the latter leads to races. Right now we use
+ mtab~.<pid> instead. Use 20 as upper bound for the length of %d. */
+#define MOUNTLOCK_LINKTARGET _PATH_MOUNTED_LOCK "%d"
+#define MOUNTLOCK_LINKTARGET_LTH (sizeof(_PATH_MOUNTED_LOCK)+20)
+
+/*
+ * The original mount locking code has used sleep(1) between attempts and
+ * maximal number of attemps has been 5.
+ *
+ * There was very small number of attempts and extremely long waiting (1s)
+ * that is useless on machines with large number of concurret mount processes.
+ *
+ * Now we wait few thousand microseconds between attempts and we have global
+ * time limit (30s) rather than limit for number of attempts. The advantage
+ * is that this method also counts time which we spend in fcntl(F_SETLKW) and
+ * number of attempts is not so much restricted.
+ *
+ * -- kzak@redhat.com [2007-Mar-2007]
+ */
+
+/* maximum seconds between first and last attempt */
+#define MOUNTLOCK_MAXTIME 30
+
+/* sleep time (in microseconds, max=999999) between attempts */
+#define MOUNTLOCK_WAITTIME 5000
+
+int
+lock_mtab (void) {
+ int i;
+ struct timespec waittime;
+ struct timeval maxtime;
+ char linktargetfile[MOUNTLOCK_LINKTARGET_LTH];
+
+ if (!signals_have_been_setup) {
+ int sig = 0;
+ struct sigaction sa;
+
+ sa.sa_handler = handler;
+ sa.sa_flags = 0;
+ sigfillset (&sa.sa_mask);
+
+ while (sigismember (&sa.sa_mask, ++sig) != -1
+ && sig != SIGCHLD) {
+ if (sig == SIGALRM)
+ sa.sa_handler = setlkw_timeout;
+ else
+ sa.sa_handler = handler;
+ sigaction (sig, &sa, (struct sigaction *) 0);
+ }
+ signals_have_been_setup = 1;
+ }
+
+ sprintf(linktargetfile, MOUNTLOCK_LINKTARGET, getpid ());
+
+ i = open (linktargetfile, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
+ if (i < 0) {
+ /* linktargetfile does not exist (as a file)
+ and we cannot create it. Read-only filesystem?
+ Too many files open in the system?
+ Filesystem full? */
+ return EX_FILEIO;
+ }
+ close(i);
+
+ gettimeofday(&maxtime, NULL);
+ maxtime.tv_sec += MOUNTLOCK_MAXTIME;
+
+ waittime.tv_sec = 0;
+ waittime.tv_nsec = (1000 * MOUNTLOCK_WAITTIME);
+
+ /* Repeat until it was us who made the link */
+ while (!we_created_lockfile) {
+ struct timeval now;
+ struct flock flock;
+ int errsv, j;
+
+ j = link(linktargetfile, _PATH_MOUNTED_LOCK);
+ errsv = errno;
+
+ if (j == 0)
+ we_created_lockfile = 1;
+
+ if (j < 0 && errsv != EEXIST) {
+ (void) unlink(linktargetfile);
+ return EX_FILEIO;
+ }
+
+ lockfile_fd = open (_PATH_MOUNTED_LOCK, O_WRONLY);
+
+ if (lockfile_fd < 0) {
+ /* Strange... Maybe the file was just deleted? */
+ gettimeofday(&now, NULL);
+ if (errno == ENOENT && now.tv_sec < maxtime.tv_sec) {
+ we_created_lockfile = 0;
+ continue;
+ }
+ (void) unlink(linktargetfile);
+ return EX_FILEIO;
+ }
+
+ flock.l_type = F_WRLCK;
+ flock.l_whence = SEEK_SET;
+ flock.l_start = 0;
+ flock.l_len = 0;
+
+ if (j == 0) {
+ /* We made the link. Now claim the lock. If we can't
+ * get it, continue anyway
+ */
+ fcntl (lockfile_fd, F_SETLK, &flock);
+ (void) unlink(linktargetfile);
+ } else {
+ /* Someone else made the link. Wait. */
+ gettimeofday(&now, NULL);
+ if (now.tv_sec < maxtime.tv_sec) {
+ alarm(maxtime.tv_sec - now.tv_sec);
+ if (fcntl (lockfile_fd, F_SETLKW, &flock) == -1) {
+ (void) unlink(linktargetfile);
+ return EX_FILEIO;
+ }
+ alarm(0);
+ nanosleep(&waittime, NULL);
+ } else {
+ (void) unlink(linktargetfile);
+ return EX_FILEIO;
+ }
+ close(lockfile_fd);
+ }
+ }
+ return 0;
+}
+
diff --git a/source3/client/umount.cifs.c b/source3/client/umount.cifs.c
index 3e2415ad00..aff7cea397 100644
--- a/source3/client/umount.cifs.c
+++ b/source3/client/umount.cifs.c
@@ -33,9 +33,10 @@
#include <errno.h>
#include <string.h>
#include <mntent.h>
+#include "mount.h"
#define UNMOUNT_CIFS_VERSION_MAJOR "0"
-#define UNMOUNT_CIFS_VERSION_MINOR "5"
+#define UNMOUNT_CIFS_VERSION_MINOR "6"
#ifndef UNMOUNT_CIFS_VENDOR_SUFFIX
#ifdef _SAMBA_BUILD_
@@ -137,24 +138,6 @@ static int umount_check_perm(char * dir)
return rc;
}
-static int lock_mtab(void)
-{
- int rc;
-
- rc = mknod(MOUNTED_LOCK , 0600, 0);
- if(rc == -1)
- printf("\ngetting lock file %s failed with %s\n",MOUNTED_LOCK,
- strerror(errno));
-
- return rc;
-
-}
-
-static void unlock_mtab(void)
-{
- unlink(MOUNTED_LOCK);
-}
-
static int remove_from_mtab(char * mountpoint)
{
int rc;
@@ -168,6 +151,7 @@ static int remove_from_mtab(char * mountpoint)
/* Do we first need to check if it is writable? */
+ atexit(unlock_mtab);
if (lock_mtab()) {
printf("Mount table locked\n");
return -EACCES;
diff --git a/source3/configure.in b/source3/configure.in
index 0aeefe4180..40e78e89d9 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -399,7 +399,7 @@ dnl These have to be built static:
default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl2 rpc_ntsvcs2 rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss rpc_eventlog2 auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin auth_netlogond vfs_default nss_info_template"
dnl These are preferably build shared, and static if dlopen() is not available
-default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_acl_xattr vfs_smb_traffic_analyzer"
+default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_streams_depot vfs_acl_xattr vfs_acl_tdb vfs_smb_traffic_analyzer"
if test "x$developer" = xyes; then
default_static_modules="$default_static_modules rpc_rpcecho"
@@ -654,7 +654,7 @@ AUTH_LIBS="${AUTH_LIBS} ${CRYPT_LIBS}"
AC_CHECK_HEADERS(aio.h sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h rpc/nettype.h)
AC_CHECK_HEADERS(unistd.h grp.h sys/id.h memory.h alloca.h)
-AC_CHECK_HEADERS(limits.h float.h pthread.h)
+AC_CHECK_HEADERS(limits.h float.h pthread.h libintl.h)
AC_CHECK_HEADERS(rpc/rpc.h rpcsvc/nis.h rpcsvc/ypclnt.h)
AC_CHECK_HEADERS(sys/param.h ctype.h sys/wait.h sys/resource.h sys/ioctl.h sys/ipc.h sys/prctl.h)
AC_CHECK_HEADERS(sys/mman.h sys/filio.h sys/priv.h sys/shm.h string.h strings.h stdlib.h)
@@ -1029,9 +1029,12 @@ AC_CHECK_FUNCS(memalign posix_memalign hstrerror)
AC_CHECK_HEADERS(sys/mman.h)
# setbuffer, shmget, shm_open are needed for smbtorture
AC_CHECK_FUNCS(shmget shm_open)
+AC_CHECK_FUNCS(gettext dgettext)
# Find a method of generating a stack trace
AC_CHECK_HEADERS(execinfo.h libexc.h libunwind.h)
+# libexecinfo provides backtrace_symbols on FreeBSD
+AC_SEARCH_LIBS(backtrace_symbols, [execinfo])
AC_CHECK_FUNCS(backtrace_symbols)
AC_CHECK_LIB(exc, trace_back_stack)
@@ -1049,6 +1052,24 @@ if test x"$samba_cv_HAVE_GPFS" = x"yes"; then
fi
LIBS="$save_LIBS"
+#############################################
+# check if building on Isilon OneFS
+printf "%s" "checking for Isilon OneFS... "
+save_LIBS="$LIBS"
+LIBS="$LIBS -lisi_version"
+AC_TRY_LINK([#include <isi_version/isi_version.h>],
+ [get_isilon_copyright()],
+ samba_cv_HAVE_ONEFS=yes,
+ samba_cv_HAVE_ONEFS=no)
+echo $samba_cv_HAVE_ONEFS
+if test x"$samba_cv_HAVE_ONEFS" = x"yes"; then
+ AC_DEFINE(HAVE_ONEFS,1,[Whether building on Isilon OneFS])
+ default_shared_modules="$default_shared_modules vfs_onefs"
+ ONEFS_LIBS="-lisi_acl"
+fi
+AC_SUBST(ONEFS_LIBS)
+LIBS="$save_LIBS"
+
# Note that all the libunwind symbols in the API are defined to internal
# platform-specific version, so we must include libunwind.h before checking
# any of them.
@@ -1433,6 +1454,25 @@ if test x"$samba_cv_stat_st_birthtime" = x"yes" ; then
AC_DEFINE(HAVE_STAT_ST_BIRTHTIME, 1, [whether struct stat contains st_birthtime])
fi
+AC_CACHE_CHECK([whether there is DOS flags support in the stat struct], samba_cv_stat_dos_flags,
+ [
+ AC_TRY_COMPILE(
+ [#include <sys/stat.h>],
+ [
+ int a = UF_DOS_ARCHIVE;
+ int h = UF_DOS_HIDDEN;
+ int r = UF_DOS_RO;
+ int s = UF_DOS_SYSTEM;
+ int i = UF_DOS_NOINDEX;
+ int f = UF_DOS_FLAGS;
+ ],
+ samba_cv_stat_dos_flags=yes, samba_cv_stat_dos_flags=no)
+ ])
+
+if test x"$samba_cv_stat_dos_flags" = x"yes" ; then
+ AC_DEFINE(HAVE_STAT_DOS_FLAGS, 1, [whether there is DOS flags support in the stat struct])
+fi
+
#####################################
# needed for SRV lookups
AC_CHECK_LIB(resolv, dn_expand)
@@ -4347,6 +4387,22 @@ AC_ARG_WITH(syslog,
)
#################################################
+# check for custom syslog facility
+AC_MSG_CHECKING(whether to use a custom syslog facility)
+AC_ARG_WITH(syslog-facility,
+[AS_HELP_STRING([--with-syslog-facility], [Use a custom syslog facility (default=none)])],
+[
+ if test "$withval" = "no" ; then
+ AC_MSG_ERROR([argument to --with-syslog-facility must be a string])
+ else
+ if test "$withval" != "yes" ; then
+ syslog_facility="$withval"
+ AC_DEFINE_UNQUOTED(SYSLOG_FACILITY,$syslog_facility, [syslog facility to log to])
+ fi
+ fi
+])
+
+#################################################
# check for experimental disk-quotas support
samba_cv_WITH_QUOTAS=auto
@@ -6087,7 +6143,9 @@ SMB_MODULE(vfs_syncops, \$(VFS_SYNCOPS_OBJ), "bin/syncops.$SHLIBEXT", VFS)
SMB_MODULE(vfs_zfsacl, \$(VFS_ZFSACL_OBJ), "bin/zfsacl.$SHLIBEXT", VFS)
SMB_MODULE(vfs_notify_fam, \$(VFS_NOTIFY_FAM_OBJ), "bin/notify_fam.$SHLIBEXT", VFS)
SMB_MODULE(vfs_acl_xattr, \$(VFS_ACL_XATTR_OBJ), "bin/acl_xattr.$SHLIBEXT", VFS)
+SMB_MODULE(vfs_acl_tdb, \$(VFS_ACL_TDB_OBJ), "bin/acl_tdb.$SHLIBEXT", VFS)
SMB_MODULE(vfs_smb_traffic_analyzer, \$(VFS_SMB_TRAFFIC_ANALYZER_OBJ), "bin/smb_traffic_analyzer.$SHLIBEXT", VFS)
+SMB_MODULE(vfs_onefs, \$(VFS_ONEFS), "bin/onefs.$SHLIBEXT", VFS)
SMB_SUBSYSTEM(VFS,smbd/vfs.o)
@@ -6233,7 +6291,7 @@ AC_ZLIB([ZLIB_OBJS=""], [
do
ZLIB_OBJS="$ZLIB_OBJS ../lib/zlib/$o"
done
- CFLAGS="$CFLAGS -I../lib/zlib"
+ CFLAGS="-I../lib/zlib $CFLAGS"
])
dnl Remove -L/usr/lib/? from LDFLAGS and LIBS
diff --git a/source3/include/eventlog.h b/source3/include/eventlog.h
new file mode 100644
index 0000000000..16affe3313
--- /dev/null
+++ b/source3/include/eventlog.h
@@ -0,0 +1,41 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * RPC Pipe client / server routines
+ * Copyright (C) Marcin Krzysztof Porwit 2005.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 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/>.
+ */
+
+/* Defines for TDB keys */
+#define EVT_OLDEST_ENTRY "INFO/oldest_entry"
+#define EVT_NEXT_RECORD "INFO/next_record"
+#define EVT_VERSION "INFO/version"
+#define EVT_MAXSIZE "INFO/maxsize"
+#define EVT_RETENTION "INFO/retention"
+
+#define ELOG_APPL "Application"
+#define ELOG_SYS "System"
+#define ELOG_SEC "Security"
+
+typedef struct elog_tdb {
+ struct elog_tdb *prev, *next;
+ char *name;
+ TDB_CONTEXT *tdb;
+ int ref_count;
+} ELOG_TDB;
+
+#define ELOG_TDB_CTX(x) ((x)->tdb)
+
+
+#define EVENTLOG_DATABASE_VERSION_V1 1
diff --git a/source3/include/includes.h b/source3/include/includes.h
index 4399c734d0..38d6ec06b9 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -654,6 +654,7 @@ struct smb_iconv_convenience *lp_iconv_convenience(void *lp_ctx);
#include "async_smb.h"
#include "async_sock.h"
#include "services.h"
+#include "eventlog.h"
#include "lib/smbconf/smbconf.h"
diff --git a/source3/include/localedir.h b/source3/include/localedir.h
new file mode 100644
index 0000000000..2a291d3ceb
--- /dev/null
+++ b/source3/include/localedir.h
@@ -0,0 +1,6 @@
+#ifndef __LOCALEDIR_H__
+#define __LOCALEDIR_H__
+
+extern const char *dyn_LOCALEDIR;
+
+#endif
diff --git a/source3/include/nss_info.h b/source3/include/nss_info.h
index e756136b76..0224be099f 100644
--- a/source3/include/nss_info.h
+++ b/source3/include/nss_info.h
@@ -66,10 +66,12 @@ struct nss_info_methods {
TALLOC_CTX *ctx,
ADS_STRUCT *ads, LDAPMessage *msg,
char **homedir, char **shell, char **gecos, gid_t *p_gid);
- NTSTATUS (*map_to_alias)( TALLOC_CTX *mem_ctx, const char *domain,
- const char *name, char **alias );
- NTSTATUS (*map_from_alias)( TALLOC_CTX *mem_ctx, const char *domain,
- const char *alias, char **name );
+ NTSTATUS (*map_to_alias)(TALLOC_CTX *mem_ctx,
+ struct nss_domain_entry *e,
+ const char *name, char **alias);
+ NTSTATUS (*map_from_alias)(TALLOC_CTX *mem_ctx,
+ struct nss_domain_entry *e,
+ const char *alias, char **name);
NTSTATUS (*close_fn)( void );
};
diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h
index e6c97c69dc..cc99ad74c2 100644
--- a/source3/include/ntdomain.h
+++ b/source3/include/ntdomain.h
@@ -5,17 +5,17 @@
Copyright (C) Luke Kenneth Casson Leighton 1996-1997
Copyright (C) Paul Ashton 1997
Copyright (C) Jeremy Allison 2000-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/>.
*/
@@ -27,7 +27,7 @@
* A bunch of stuff that was put into smb.h
* in the NTDOM branch - it didn't belong there.
*/
-
+
typedef struct _prs_struct {
bool io; /* parsing in or out of data stream */
/*
@@ -138,7 +138,7 @@ struct dcinfo {
struct netr_Credential seed_chal;
struct netr_Credential clnt_chal; /* Client credential */
struct netr_Credential srv_chal; /* Server credential */
-
+
unsigned char sess_key[16]; /* Session key - 8 bytes followed by 8 zero bytes */
unsigned char mach_pw[16]; /* md4(machine password) */
@@ -154,13 +154,13 @@ struct dcinfo {
typedef struct pipe_rpc_fns {
struct pipe_rpc_fns *next, *prev;
-
+
/* RPC function table associated with the current rpc_bind (associated by context) */
-
+
const struct api_struct *cmds;
int n_cmds;
uint32 context_id;
-
+
} PIPE_RPC_FNS;
/*
@@ -217,12 +217,12 @@ typedef struct pipes_struct {
fstring name;
fstring pipe_srv_name;
-
+
/* linked list of rpc dispatch tables associated
with the open rpc contexts */
-
+
PIPE_RPC_FNS *contexts;
-
+
RPC_HDR hdr; /* Incoming RPC header. */
RPC_HDR_REQ hdr_req; /* Incoming request header. */
@@ -231,21 +231,15 @@ typedef struct pipes_struct {
struct dcinfo *dc; /* Keeps the creds data from netlogon. */
/*
- * Unix user name and credentials used when a pipe is authenticated.
- */
-
- struct current_user pipe_user;
-
- /*
* Set to true when an RPC bind has been done on this pipe.
*/
-
+
bool pipe_bound;
-
+
/*
* Set to true when we should return fault PDU's for everything.
*/
-
+
bool fault_state;
/*
@@ -259,13 +253,13 @@ typedef struct pipes_struct {
*/
bool rng_fault_state;
-
+
/*
* Set to RPC_BIG_ENDIAN when dealing with big-endian PDU's
*/
-
+
bool endian;
-
+
/*
* Struct to deal with multiple pdu inputs.
*/
diff --git a/source3/include/ntlmssp.h b/source3/include/ntlmssp.h
index b014b2170c..55b9249ea7 100644
--- a/source3/include/ntlmssp.h
+++ b/source3/include/ntlmssp.h
@@ -77,7 +77,6 @@ enum NTLM_MESSAGE_TYPE
typedef struct ntlmssp_state
{
- TALLOC_CTX *mem_ctx;
unsigned int ref_count;
enum NTLMSSP_ROLE role;
enum server_types server_role;
@@ -98,9 +97,9 @@ typedef struct ntlmssp_state
DATA_BLOB lm_resp;
DATA_BLOB nt_resp;
DATA_BLOB session_key;
-
+
uint32 neg_flags; /* the current state of negotiation with the NTLMSSP partner */
-
+
void *auth_context;
/**
@@ -171,5 +170,4 @@ typedef struct ntlmssp_state
response in at the time we want to process it.
Store it here, until we need it */
DATA_BLOB stored_response;
-
} NTLMSSP_STATE;
diff --git a/source3/include/passdb.h b/source3/include/passdb.h
index 360a0d0444..744b723c83 100644
--- a/source3/include/passdb.h
+++ b/source3/include/passdb.h
@@ -23,16 +23,6 @@
#ifndef _PASSDB_H
#define _PASSDB_H
-
-/*
- * in samba4 idl
- * ACCT_NT_PWD_SET == SAMR_FIELD_PASSWORD and
- * ACCT_LM_PWD_SET == SAMR_FIELD_PASSWORD2
- */
-
-#define ACCT_NT_PWD_SET 0x01000000
-#define ACCT_LM_PWD_SET 0x02000000
-
/*
* bit flags representing initialized fields in struct samu
*/
diff --git a/source3/include/proto.h b/source3/include/proto.h
index ac55a67c19..f2bbb07f92 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1251,6 +1251,7 @@ char *procid_str_static(const struct server_id *pid);
bool procid_valid(const struct server_id *pid);
bool procid_is_local(const struct server_id *pid);
int this_is_smp(void);
+bool trans_oob(uint32_t bufsize, uint32_t offset, uint32_t length);
bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off);
char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off);
char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off);
@@ -1582,6 +1583,7 @@ bool validate_net_name( const char *name,
const char *invalid_chars,
int max_len);
char *escape_shell_string(const char *src);
+char **str_list_make_v3(TALLOC_CTX *mem_ctx, const char *string, const char *sep);
/* The following definitions come from lib/util_unistr.c */
@@ -1919,10 +1921,10 @@ ADS_STATUS ads_get_joinable_ous(ADS_STRUCT *ads,
TALLOC_CTX *mem_ctx,
char ***ous,
size_t *num_ous);
-bool ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx,
- const char *extended_dn,
- enum ads_extended_dn_flags flags,
- DOM_SID *sid);
+ADS_STATUS ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx,
+ const char *extended_dn,
+ enum ads_extended_dn_flags flags,
+ DOM_SID *sid);
char* ads_get_dnshostname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name );
char* ads_get_upn( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name );
char* ads_get_samaccountname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine_name );
@@ -4772,10 +4774,12 @@ bool delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR
void update_a_form(nt_forms_struct **list, const FORM *form, int count);
int get_ntdrivers(fstring **list, const char *architecture, uint32 version);
const char *get_short_archi(const char *long_archi);
-WERROR clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
- uint32 level, struct current_user *user);
-WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level,
- struct current_user *user, WERROR *perr);
+WERROR clean_up_driver_struct(struct pipes_struct *rpc_pipe,
+ NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
+ uint32 level);
+WERROR move_driver_to_download_area(struct pipes_struct *p,
+ NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
+ uint32 level, WERROR *perr);
int pack_devicemode(NT_DEVICEMODE *nt_devmode, uint8 *buf, int buflen);
uint32 del_a_printer(const char *sharename);
NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename);
@@ -4818,8 +4822,9 @@ WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level);
bool printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3 );
bool printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info );
-WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct current_user *user,
- uint32 version, bool delete_files );
+WERROR delete_printer_driver(struct pipes_struct *rpc_pipe,
+ NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3,
+ uint32 version, bool delete_files );
WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr);
bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **secdesc_ctr);
void map_printer_permissions(SEC_DESC *sd);
@@ -4865,7 +4870,7 @@ bool sysv_cache_reload(void);
NTSTATUS print_fsp_open(struct smb_request *req, connection_struct *conn,
const char *fname,
- uint16_t current_vuid, files_struct **result);
+ uint16_t current_vuid, files_struct *fsp);
void print_fsp_end(files_struct *fsp, enum file_close_type close_type);
/* The following definitions come from printing/printing.c */
@@ -5295,7 +5300,6 @@ NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
NTSTATUS rpccli_winreg_Connect(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
uint32 reg_type, uint32 access_mask,
POLICY_HND *reg_hnd);
-uint32 reg_init_regval_buffer( REGVAL_BUFFER *buf2, REGISTRY_VALUE *val );
/* The following definitions come from rpc_client/cli_samr.c */
@@ -5549,7 +5553,8 @@ void init_netr_SamInfo3(struct netr_SamInfo3 *r,
uint32_t sidcount,
struct netr_SidAttr *sids);
NTSTATUS serverinfo_to_SamInfo3(struct auth_serversupplied_info *server_info,
- uint8_t pipe_session_key[16],
+ uint8_t *pipe_session_key,
+ size_t pipe_session_key_len,
struct netr_SamInfo3 *sam3);
void init_netr_IdentityInfo(struct netr_IdentityInfo *r,
const char *domain_name,
@@ -5595,7 +5600,7 @@ void init_samr_DomGeneralInformation(struct samr_DomGeneralInformation *r,
const char *domain_name,
const char *primary,
uint64_t sequence_num,
- uint32_t unknown2,
+ enum samr_DomainServerState domain_server_state,
enum samr_Role role,
uint32_t unknown3,
uint32_t num_users,
@@ -5615,7 +5620,7 @@ void init_samr_DomInfo8(struct samr_DomInfo8 *r,
uint64_t sequence_num,
NTTIME domain_create_time);
void init_samr_DomInfo9(struct samr_DomInfo9 *r,
- uint32_t unknown);
+ enum samr_DomainServerState domain_server_state);
void init_samr_DomInfo12(struct samr_DomInfo12 *r,
uint64_t lockout_duration,
uint64_t lockout_window,
@@ -5640,6 +5645,25 @@ void init_samr_alias_info1(struct samr_AliasInfoAll *r,
const char *description);
void init_samr_alias_info3(struct lsa_String *r,
const char *description);
+void init_samr_user_info5(struct samr_UserInfo5 *r,
+ const char *account_name,
+ const char *full_name,
+ uint32_t rid,
+ uint32_t primary_gid,
+ const char *home_directory,
+ const char *home_drive,
+ const char *logon_script,
+ const char *profile_path,
+ const char *description,
+ const char *workstations,
+ NTTIME last_logon,
+ NTTIME last_logoff,
+ struct samr_LogonHours logon_hours,
+ uint16_t bad_password_count,
+ uint16_t logon_count,
+ NTTIME last_password_change,
+ NTTIME acct_expiry,
+ uint32_t acct_flags);
void init_samr_user_info7(struct samr_UserInfo7 *r,
const char *account_name);
void init_samr_user_info9(struct samr_UserInfo9 *r,
@@ -5709,11 +5733,43 @@ void init_samr_user_info23(struct samr_UserInfo23 *r,
uint8_t nt_password_set,
uint8_t lm_password_set,
uint8_t password_expired,
- uint8_t data[516],
- uint8_t pw_len);
+ struct samr_CryptPassword *pwd_buf);
void init_samr_user_info24(struct samr_UserInfo24 *r,
- uint8_t data[516],
- uint8_t pw_len);
+ struct samr_CryptPassword *pwd_buf,
+ uint8_t password_expired);
+void init_samr_user_info25(struct samr_UserInfo25 *r,
+ NTTIME last_logon,
+ NTTIME last_logoff,
+ NTTIME last_password_change,
+ NTTIME acct_expiry,
+ NTTIME allow_password_change,
+ NTTIME force_password_change,
+ const char *account_name,
+ const char *full_name,
+ const char *home_directory,
+ const char *home_drive,
+ const char *logon_script,
+ const char *profile_path,
+ const char *description,
+ const char *workstations,
+ const char *comment,
+ struct lsa_BinaryString *parameters,
+ uint32_t rid,
+ uint32_t primary_gid,
+ uint32_t acct_flags,
+ uint32_t fields_present,
+ struct samr_LogonHours logon_hours,
+ uint16_t bad_password_count,
+ uint16_t logon_count,
+ uint16_t country_code,
+ uint16_t code_page,
+ uint8_t nt_password_set,
+ uint8_t lm_password_set,
+ uint8_t password_expired,
+ struct samr_CryptPasswordEx *pwd_buf);
+void init_samr_user_info26(struct samr_UserInfo26 *r,
+ struct samr_CryptPasswordEx *pwd_buf,
+ uint8_t password_expired);
void init_samr_CryptPasswordEx(const char *pwd,
DATA_BLOB *session_key,
struct samr_CryptPasswordEx *pwd_buf);
@@ -5908,8 +5964,6 @@ void init_rpc_blob_str(RPC_DATA_BLOB *str, const char *buf, int len);
void init_rpc_blob_hex(RPC_DATA_BLOB *str, const char *buf);
void init_rpc_blob_bytes(RPC_DATA_BLOB *str, uint8 *buf, size_t len);
bool smb_io_buffer5(const char *desc, BUFFER5 *buf5, prs_struct *ps, int depth);
-void init_regval_buffer(REGVAL_BUFFER *str, const uint8 *buf, size_t len);
-bool smb_io_regval_buffer(const char *desc, prs_struct *ps, int depth, REGVAL_BUFFER *buf2);
void init_buf_unistr2(UNISTR2 *str, uint32 *ptr, const char *buf);
void copy_unistr2(UNISTR2 *str, const UNISTR2 *from);
void init_string2(STRING2 *str, const char *buf, size_t max_len, size_t str_len);
@@ -5972,8 +6026,6 @@ bool policy_handle_is_valid(const POLICY_HND *hnd);
bool ntsvcs_io_q_get_device_list(const char *desc, NTSVCS_Q_GET_DEVICE_LIST *q_u, prs_struct *ps, int depth);
bool ntsvcs_io_r_get_device_list(const char *desc, NTSVCS_R_GET_DEVICE_LIST *r_u, prs_struct *ps, int depth);
-bool ntsvcs_io_q_get_device_reg_property(const char *desc, NTSVCS_Q_GET_DEVICE_REG_PROPERTY *q_u, prs_struct *ps, int depth);
-bool ntsvcs_io_r_get_device_reg_property(const char *desc, NTSVCS_R_GET_DEVICE_REG_PROPERTY *r_u, prs_struct *ps, int depth);
/* The following definitions come from rpc_parse/parse_prs.c */
@@ -6029,7 +6081,6 @@ bool prs_uint16s(bool charmode, const char *name, prs_struct *ps, int depth, uin
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_buffer5(bool charmode, const char *name, prs_struct *ps, int depth, BUFFER5 *str);
-bool prs_regval_buffer(bool charmode, const char *name, prs_struct *ps, int depth, REGVAL_BUFFER *buf);
bool prs_string2(bool charmode, const char *name, prs_struct *ps, int depth, STRING2 *str);
bool prs_unistr2(bool charmode, const char *name, prs_struct *ps, int depth, UNISTR2 *str);
bool prs_unistr3(bool charmode, const char *name, UNISTR3 *str, prs_struct *ps, int depth);
@@ -6822,7 +6873,6 @@ WERROR _PNP_GetVersion(pipes_struct *p,
WERROR _PNP_GetDeviceListSize(pipes_struct *p,
struct PNP_GetDeviceListSize *r);
WERROR _ntsvcs_get_device_list( pipes_struct *p, NTSVCS_Q_GET_DEVICE_LIST *q_u, NTSVCS_R_GET_DEVICE_LIST *r_u );
-WERROR _ntsvcs_get_device_reg_property( pipes_struct *p, NTSVCS_Q_GET_DEVICE_REG_PROPERTY *q_u, NTSVCS_R_GET_DEVICE_REG_PROPERTY *r_u );
WERROR _PNP_ValidateDeviceInstance(pipes_struct *p,
struct PNP_ValidateDeviceInstance *r);
WERROR _PNP_GetHwProfInfo(pipes_struct *p,
@@ -6968,7 +7018,6 @@ bool api_pipe_alter_context(pipes_struct *p, prs_struct *rpc_in_p);
bool api_pipe_ntlmssp_auth_process(pipes_struct *p, prs_struct *rpc_in,
uint32 *p_ss_padding_len, NTSTATUS *pstatus);
bool api_pipe_schannel_process(pipes_struct *p, prs_struct *rpc_in, uint32 *p_ss_padding_len);
-struct current_user *get_current_user(struct current_user *user, pipes_struct *p);
void free_pipe_rpc_context( PIPE_RPC_FNS *list );
bool api_pipe_request(pipes_struct *p);
@@ -6979,8 +7028,8 @@ pipes_struct *get_next_internal_pipe(pipes_struct *p);
void init_rpc_pipe_hnd(void);
bool fsp_is_np(struct files_struct *fsp);
-NTSTATUS np_open(struct smb_request *smb_req, struct connection_struct *conn,
- const char *name, struct files_struct **pfsp);
+NTSTATUS np_open(struct smb_request *smb_req, const char *name,
+ struct files_struct **pfsp);
NTSTATUS np_write(struct files_struct *fsp, const uint8_t *data, size_t len,
ssize_t *nwritten);
NTSTATUS np_read(struct files_struct *fsp, uint8_t *data, size_t len,
@@ -7865,9 +7914,9 @@ 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);
-NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *fsp,
+void dup_file_fsp(struct smb_request *req, files_struct *from,
uint32 access_mask, uint32 share_access,
- uint32 create_options, files_struct **result);
+ uint32 create_options, files_struct *to);
/* The following definitions come from smbd/ipc.c */
@@ -7962,7 +8011,8 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
connection_struct **pconn,
int snum,
const char *path,
- char **poldcwd);
+ struct auth_serversupplied_info *server_info,
+ char **poldcwd);
/* The following definitions come from smbd/negprot.c */
@@ -7971,11 +8021,11 @@ void reply_negprot(struct smb_request *req);
/* The following definitions come from smbd/notify.c */
void change_notify_reply(connection_struct *conn,
- const uint8 *request_buf, uint32 max_param,
+ struct smb_request *req, uint32 max_param,
struct notify_change_buf *notify_buf);
NTSTATUS change_notify_create(struct files_struct *fsp, uint32 filter,
bool recursive);
-NTSTATUS change_notify_add_request(const struct smb_request *req,
+NTSTATUS change_notify_add_request(struct smb_request *req,
uint32 max_param,
uint32 filter, bool recursive,
struct files_struct *fsp);
@@ -8176,6 +8226,7 @@ void reply_pipe_close(connection_struct *conn, struct smb_request *req);
/* The following definitions come from smbd/posix_acls.c */
void create_file_sids(const SMB_STRUCT_STAT *psbuf, DOM_SID *powner_sid, DOM_SID *pgroup_sid);
+bool nt4_compatible_acls(void);
NTSTATUS unpack_nt_owners(int snum, uid_t *puser, gid_t *pgrp, uint32 security_info_sent, const SEC_DESC *psd);
SMB_ACL_T free_empty_sys_acl(connection_struct *conn, SMB_ACL_T the_acl);
NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info,
@@ -8231,7 +8282,6 @@ void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes);
const char *smb_fn_name(int type);
void add_to_common_flags2(uint32 v);
void remove_from_common_flags2(uint32 v);
-void construct_reply_common(const char *inbuf, char *outbuf);
void construct_reply_common_req(struct smb_request *req, char *outbuf);
void chain_reply(struct smb_request *req);
void check_reload(time_t t);
@@ -8424,10 +8474,6 @@ bool set_current_service(connection_struct *conn, uint16 flags, bool do_chdir);
void load_registry_shares(void);
int add_home_service(const char *service, const char *username, const char *homedir);
int find_service(fstring service);
-connection_struct *make_connection_with_chdir(const char *service_in,
- DATA_BLOB password,
- const char *dev, uint16 vuid,
- NTSTATUS *status);
connection_struct *make_connection(const char *service_in, DATA_BLOB password,
const char *pdev, uint16 vuid,
NTSTATUS *status);
@@ -8458,7 +8504,8 @@ bool user_ok_token(const char *username, const char *domain,
struct nt_user_token *token, int snum);
bool is_share_read_only_for_token(const char *username,
const char *domain,
- struct nt_user_token *token, int snum);
+ struct nt_user_token *token,
+ connection_struct *conn);
/* The following definitions come from smbd/srvstr.c */
@@ -8663,6 +8710,7 @@ NTSTATUS idmap_backends_sid_to_unixid(const char *domname,
NTSTATUS idmap_new_mapping(const struct dom_sid *psid, enum id_type type,
struct unixid *pxid);
NTSTATUS idmap_set_mapping(const struct id_map *map);
+NTSTATUS idmap_remove_mapping(const struct id_map *map);
/* The following definitions come from winbindd/idmap_cache.c */
diff --git a/source3/include/rpc_eventlog.h b/source3/include/rpc_eventlog.h
index 3f5d03ed63..f17e448d9e 100644
--- a/source3/include/rpc_eventlog.h
+++ b/source3/include/rpc_eventlog.h
@@ -35,29 +35,6 @@
/* Event types */
/* defined in librpc/gen_ndr/eventlog.h */
-/* Defines for TDB keys */
-#define EVT_OLDEST_ENTRY "INFO/oldest_entry"
-#define EVT_NEXT_RECORD "INFO/next_record"
-#define EVT_VERSION "INFO/version"
-#define EVT_MAXSIZE "INFO/maxsize"
-#define EVT_RETENTION "INFO/retention"
-
-#define ELOG_APPL "Application"
-#define ELOG_SYS "System"
-#define ELOG_SEC "Security"
-
-typedef struct elog_tdb {
- struct elog_tdb *prev, *next;
- char *name;
- TDB_CONTEXT *tdb;
- int ref_count;
-} ELOG_TDB;
-
-#define ELOG_TDB_CTX(x) ((x)->tdb)
-
-
-#define EVENTLOG_DATABASE_VERSION_V1 1
-
/***********************************/
typedef struct
diff --git a/source3/include/rpc_ntsvcs.h b/source3/include/rpc_ntsvcs.h
index 0056d16eb9..dc74298cb9 100644
--- a/source3/include/rpc_ntsvcs.h
+++ b/source3/include/rpc_ntsvcs.h
@@ -47,23 +47,4 @@ typedef struct {
WERROR status;
} NTSVCS_R_GET_DEVICE_LIST;
-/**************************/
-
-typedef struct {
- UNISTR2 devicepath;
- uint32 property;
- uint32 unknown2;
- uint32 buffer_size1;
- uint32 buffer_size2;
- uint32 unknown5;
-} NTSVCS_Q_GET_DEVICE_REG_PROPERTY;
-
-typedef struct {
- uint32 unknown1;
- REGVAL_BUFFER value;
- uint32 size;
- uint32 needed;
- WERROR status;
-} NTSVCS_R_GET_DEVICE_REG_PROPERTY;
-
#endif /* _RPC_NTSVCS_H */
diff --git a/source3/include/rpc_svcctl.h b/source3/include/rpc_svcctl.h
index 27858405e7..7dd849d5b4 100644
--- a/source3/include/rpc_svcctl.h
+++ b/source3/include/rpc_svcctl.h
@@ -103,14 +103,6 @@
#define SVCCTL_DEMAND_START 0x00000003
#define SVCCTL_DISABLED 0x00000004
-/* Service Controls */
-
-#define SVCCTL_CONTROL_STOP 0x00000001
-#define SVCCTL_CONTROL_PAUSE 0x00000002
-#define SVCCTL_CONTROL_CONTINUE 0x00000003
-#define SVCCTL_CONTROL_INTERROGATE 0x00000004
-#define SVCCTL_CONTROL_SHUTDOWN 0x00000005
-
#define SVC_HANDLE_IS_SCM 0x0000001
#define SVC_HANDLE_IS_SERVICE 0x0000002
#define SVC_HANDLE_IS_DBLOCK 0x0000003
diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h
index 46ca236553..119ceeb158 100644
--- a/source3/include/smb_macros.h
+++ b/source3/include/smb_macros.h
@@ -52,8 +52,8 @@
return ERROR_NT(NT_STATUS_INVALID_HANDLE); \
} while(0)
-#define CHECK_READ(fsp,inbuf) (((fsp)->fh->fd != -1) && ((fsp)->can_read || \
- ((SVAL((inbuf),smb_flg2) & FLAGS2_READ_PERMIT_EXECUTE) && \
+#define CHECK_READ(fsp,req) (((fsp)->fh->fd != -1) && ((fsp)->can_read || \
+ ((req->flags2 & FLAGS2_READ_PERMIT_EXECUTE) && \
(fsp->access_mask & FILE_EXECUTE))))
#define CHECK_WRITE(fsp) ((fsp)->can_write && ((fsp)->fh->fd != -1))
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index 7b3aeaa2c7..8fbc21b12d 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -92,7 +92,7 @@
/* POSIX ACL operations. */
#define SMB_VFS_CHMOD_ACL(conn, name, mode) ((conn)->vfs.ops.chmod_acl((conn)->vfs.handles.chmod_acl, (name), (mode)))
-#define SMB_VFS_FCHMOD_ACL(fsp, mode) ((fsp)->conn->vfs.ops.fchmod_acl((fsp)->conn->vfs.handles.chmod_acl, (fsp), (mode)))
+#define SMB_VFS_FCHMOD_ACL(fsp, mode) ((fsp)->conn->vfs.ops.fchmod_acl((fsp)->conn->vfs.handles.fchmod_acl, (fsp), (mode)))
#define SMB_VFS_SYS_ACL_GET_ENTRY(conn, theacl, entry_id, entry_p) ((conn)->vfs.ops.sys_acl_get_entry((conn)->vfs.handles.sys_acl_get_entry, (theacl), (entry_id), (entry_p)))
#define SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry_d, tag_type_p) ((conn)->vfs.ops.sys_acl_get_tag_type((conn)->vfs.handles.sys_acl_get_tag_type, (entry_d), (tag_type_p)))
@@ -217,7 +217,7 @@
/* POSIX ACL operations. */
#define SMB_VFS_OPAQUE_CHMOD_ACL(conn, name, mode) ((conn)->vfs_opaque.ops.chmod_acl((conn)->vfs_opaque.handles.chmod_acl, (name), (mode)))
-#define SMB_VFS_OPAQUE_FCHMOD_ACL(fsp, mode) ((fsp)->conn->vfs_opaque.ops.fchmod_acl((fsp)->conn->vfs_opaque.handles.chmod_acl, (fsp), (mode)))
+#define SMB_VFS_OPAQUE_FCHMOD_ACL(fsp, mode) ((fsp)->conn->vfs_opaque.ops.fchmod_acl((fsp)->conn->vfs_opaque.handles.fchmod_acl, (fsp), (mode)))
#define SMB_VFS_OPAQUE_SYS_ACL_GET_ENTRY(conn, theacl, entry_id, entry_p) ((conn)->vfs_opaque.ops.sys_acl_get_entry((conn)->vfs_opaque.handles.sys_acl_get_entry, (theacl), (entry_id), (entry_p)))
#define SMB_VFS_OPAQUE_SYS_ACL_GET_TAG_TYPE(conn, entry_d, tag_type_p) ((conn)->vfs_opaque.ops.sys_acl_get_tag_type((conn)->vfs_opaque.handles.sys_acl_get_tag_type, (entry_d), (tag_type_p)))
@@ -343,7 +343,7 @@
/* POSIX ACL operations. */
#define SMB_VFS_NEXT_CHMOD_ACL(handle, name, mode) ((handle)->vfs_next.ops.chmod_acl((handle)->vfs_next.handles.chmod_acl, (name), (mode)))
-#define SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode) ((handle)->vfs_next.ops.fchmod_acl((handle)->vfs_next.handles.chmod_acl, (fsp), (mode)))
+#define SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode) ((handle)->vfs_next.ops.fchmod_acl((handle)->vfs_next.handles.fchmod_acl, (fsp), (mode)))
#define SMB_VFS_NEXT_SYS_ACL_GET_ENTRY(handle, theacl, entry_id, entry_p) ((handle)->vfs_next.ops.sys_acl_get_entry((handle)->vfs_next.handles.sys_acl_get_entry, (theacl), (entry_id), (entry_p)))
#define SMB_VFS_NEXT_SYS_ACL_GET_TAG_TYPE(handle, entry_d, tag_type_p) ((handle)->vfs_next.ops.sys_acl_get_tag_type((handle)->vfs_next.handles.sys_acl_get_tag_type, (entry_d), (tag_type_p)))
diff --git a/source3/lib/debug.c b/source3/lib/debug.c
index 986dff48d7..d64fcb66d9 100644
--- a/source3/lib/debug.c
+++ b/source3/lib/debug.c
@@ -472,7 +472,7 @@ bool debug_parse_levels(const char *params_str)
if (AllowDebugChange == False)
return True;
- params = str_list_make(talloc_tos(), params_str, NULL);
+ params = str_list_make_v3(talloc_tos(), params_str, NULL);
if (debug_parse_params(params)) {
debug_dump_status(5);
diff --git a/source3/lib/memcache.c b/source3/lib/memcache.c
index 9c892fedfa..606d72ab5a 100644
--- a/source3/lib/memcache.c
+++ b/source3/lib/memcache.c
@@ -63,14 +63,6 @@ static int memcache_destructor(struct memcache *cache) {
for (e = cache->mru; e != NULL; e = next) {
next = e->next;
- if (memcache_is_talloc((enum memcache_number)e->n)
- && (e->valuelength == sizeof(void *))) {
- DATA_BLOB key, value;
- void *ptr;
- memcache_element_parse(e, &key, &value);
- memcpy(&ptr, value.data, sizeof(ptr));
- TALLOC_FREE(ptr);
- }
SAFE_FREE(e);
}
return 0;
@@ -214,6 +206,16 @@ static void memcache_delete_element(struct memcache *cache,
}
DLIST_REMOVE(cache->mru, e);
+ if (memcache_is_talloc(e->n)) {
+ DATA_BLOB cache_key, cache_value;
+ void *ptr;
+
+ memcache_element_parse(e, &cache_key, &cache_value);
+ SMB_ASSERT(cache_value.length == sizeof(ptr));
+ memcpy(&ptr, cache_value.data, sizeof(ptr));
+ TALLOC_FREE(ptr);
+ }
+
cache->size -= memcache_element_size(e->keylength, e->valuelength);
SAFE_FREE(e);
@@ -276,6 +278,12 @@ void memcache_add(struct memcache *cache, enum memcache_number n,
memcache_element_parse(e, &cache_key, &cache_value);
if (value.length <= cache_value.length) {
+ if (memcache_is_talloc(e->n)) {
+ void *ptr;
+ SMB_ASSERT(cache_value.length == sizeof(ptr));
+ memcpy(&ptr, cache_value.data, sizeof(ptr));
+ TALLOC_FREE(ptr);
+ }
/*
* We can reuse the existing record
*/
@@ -332,9 +340,20 @@ void memcache_add(struct memcache *cache, enum memcache_number n,
}
void memcache_add_talloc(struct memcache *cache, enum memcache_number n,
- DATA_BLOB key, void *ptr)
+ DATA_BLOB key, void *pptr)
{
- memcache_add(cache, n, key, data_blob_const(&ptr, sizeof(ptr)));
+ void **ptr = (void **)pptr;
+ void *p;
+
+ if (cache == NULL) {
+ cache = global_cache;
+ }
+ if (cache == NULL) {
+ return;
+ }
+
+ p = talloc_move(cache, ptr);
+ memcache_add(cache, n, key, data_blob_const(&p, sizeof(p)));
}
void memcache_flush(struct memcache *cache, enum memcache_number n)
diff --git a/source3/lib/secdesc.c b/source3/lib/secdesc.c
index 2987306066..df85336603 100644
--- a/source3/lib/secdesc.c
+++ b/source3/lib/secdesc.c
@@ -546,6 +546,9 @@ NTSTATUS se_create_child_secdesc(TALLOC_CTX *ctx,
ptrustee = creator;
new_flags |= SEC_ACE_FLAG_INHERIT_ONLY;
+ } else if (container &&
+ !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
+ ptrustee = &ace->trustee;
}
init_sec_ace(new_ace, ptrustee, ace->type,
@@ -563,19 +566,20 @@ NTSTATUS se_create_child_secdesc(TALLOC_CTX *ctx,
}
/* Create child security descriptor to return */
-
- new_dacl = make_sec_acl(ctx,
+ if (new_ace_list_ndx) {
+ new_dacl = make_sec_acl(ctx,
NT4_ACL_REVISION,
new_ace_list_ndx,
new_ace_list);
- if (!new_dacl) {
- return NT_STATUS_NO_MEMORY;
+ if (!new_dacl) {
+ return NT_STATUS_NO_MEMORY;
+ }
}
+
*ppsd = make_sec_desc(ctx,
SECURITY_DESCRIPTOR_REVISION_1,
- SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT|
- SEC_DESC_DACL_DEFAULTED,
+ SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT,
owner_sid,
group_sid,
NULL,
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 820cf376be..074b523ae0 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -1497,7 +1497,7 @@ uid_t nametouid(const char *name)
char *p;
uid_t u;
- pass = getpwnam_alloc(NULL, name);
+ pass = getpwnam_alloc(talloc_autofree_context(), name);
if (pass) {
u = pass->pw_uid;
TALLOC_FREE(pass);
@@ -2255,8 +2255,8 @@ char *myhostname(void)
static char *ret;
if (ret == NULL) {
/* This is cached forever so
- * use NULL talloc ctx. */
- ret = talloc_get_myname(NULL);
+ * use talloc_autofree_context() ctx. */
+ ret = talloc_get_myname(talloc_autofree_context());
}
return ret;
}
@@ -2879,6 +2879,25 @@ int this_is_smp(void)
}
/****************************************************************
+ Check if offset/length fit into bufsize. Should probably be
+ merged with is_offset_safe, but this would require a rewrite
+ of lanman.c. Later :-)
+****************************************************************/
+
+bool trans_oob(uint32_t bufsize, uint32_t offset, uint32_t length)
+{
+ if ((offset + length < offset) || (offset + length < length)) {
+ /* wrap */
+ return true;
+ }
+ if ((offset > bufsize) || (offset + length > bufsize)) {
+ /* overflow */
+ return true;
+ }
+ return false;
+}
+
+/****************************************************************
Check if an offset into a buffer is safe.
If this returns True it's safe to indirect into the byte at
pointer ptr+off.
diff --git a/source3/lib/util_pw.c b/source3/lib/util_pw.c
index c0d37f1094..b0baa12c3e 100644
--- a/source3/lib/util_pw.c
+++ b/source3/lib/util_pw.c
@@ -44,30 +44,28 @@ void flush_pwnam_cache(void)
struct passwd *getpwnam_alloc(TALLOC_CTX *mem_ctx, const char *name)
{
- struct passwd *temp, *cached;
+ struct passwd *pw, *for_cache;
- temp = (struct passwd *)memcache_lookup_talloc(
+ pw = (struct passwd *)memcache_lookup_talloc(
NULL, GETPWNAM_CACHE, data_blob_string_const_null(name));
- if (temp != NULL) {
- return tcopy_passwd(mem_ctx, temp);
+ if (pw != NULL) {
+ return tcopy_passwd(mem_ctx, pw);
}
- temp = sys_getpwnam(name);
- if (temp == NULL) {
+ pw = sys_getpwnam(name);
+ if (pw == NULL) {
return NULL;
}
- cached = tcopy_passwd(NULL, temp);
- if (cached == NULL) {
- /*
- * Just don't add this into the cache, ignore the failure
- */
- return temp;
+ for_cache = tcopy_passwd(talloc_autofree_context(), pw);
+ if (for_cache == NULL) {
+ return NULL;
}
- memcache_add_talloc(NULL, GETPWNAM_CACHE, data_blob_string_const_null(name),
- cached);
- return tcopy_passwd(mem_ctx, temp);
+ memcache_add_talloc(NULL, GETPWNAM_CACHE,
+ data_blob_string_const_null(name), &for_cache);
+
+ return tcopy_passwd(mem_ctx, pw);
}
struct passwd *getpwuid_alloc(TALLOC_CTX *mem_ctx, uid_t uid)
diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c
index 046ce61ea3..fde4f825e8 100644
--- a/source3/lib/util_str.c
+++ b/source3/lib/util_str.c
@@ -2532,3 +2532,19 @@ char *escape_shell_string(const char *src)
*dest++ = '\0';
return ret;
}
+
+/***************************************************
+ Wrapper for str_list_make() to restore the s3 behavior.
+ In samba 3.2 passing NULL or an empty string returned NULL.
+
+ In master, it now returns a list of length 1 with the first string set
+ to NULL (an empty list)
+***************************************************/
+
+char **str_list_make_v3(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
+{
+ if (!string || !*string) {
+ return NULL;
+ }
+ return str_list_make(mem_ctx, string, sep);
+}
diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c
index 883f582445..c4e67091dd 100644
--- a/source3/libads/kerberos_keytab.c
+++ b/source3/libads/kerberos_keytab.c
@@ -725,8 +725,11 @@ int ads_keytab_list(const char *keytab_name)
ret = smb_krb5_enctype_to_string(context, enctype, &etype_s);
if (ret) {
- SAFE_FREE(princ_s);
- goto out;
+ if (asprintf(&etype_s, "UNKNOWN: %d\n", enctype) == -1)
+ {
+ SAFE_FREE(princ_s);
+ goto out;
+ }
}
printf("%3d %s\t\t %s\n", kt_entry.vno, etype_s, princ_s);
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index 2dcd1fd6ae..932e42e076 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -301,11 +301,11 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads)
if ( use_own_domain )
c_realm = lp_workgroup();
}
+ }
- if ( !c_realm || !*c_realm ) {
- DEBUG(0,("ads_find_dc: no realm or workgroup! Don't know what to do\n"));
- return NT_STATUS_INVALID_PARAMETER; /* rather need MISSING_PARAMETER ... */
- }
+ if ( !c_realm || !*c_realm ) {
+ DEBUG(0,("ads_find_dc: no realm or workgroup! Don't know what to do\n"));
+ return NT_STATUS_INVALID_PARAMETER; /* rather need MISSING_PARAMETER ... */
}
realm = c_realm;
@@ -3111,60 +3111,66 @@ ADS_STATUS ads_get_joinable_ous(ADS_STRUCT *ads,
/**
* pull a DOM_SID from an extended dn string
- * @param mem_ctx TALLOC_CTX
+ * @param mem_ctx TALLOC_CTX
* @param extended_dn string
* @param flags string type of extended_dn
* @param sid pointer to a DOM_SID
- * @return boolean inidicating success
+ * @return NT_STATUS_OK on success,
+ * NT_INVALID_PARAMETER on error,
+ * NT_STATUS_NOT_FOUND if no SID present
**/
-bool ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx,
- const char *extended_dn,
- enum ads_extended_dn_flags flags,
- DOM_SID *sid)
+ADS_STATUS ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx,
+ const char *extended_dn,
+ enum ads_extended_dn_flags flags,
+ DOM_SID *sid)
{
char *p, *q, *dn;
if (!extended_dn) {
- return False;
+ return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
/* otherwise extended_dn gets stripped off */
if ((dn = talloc_strdup(mem_ctx, extended_dn)) == NULL) {
- return False;
+ return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
- /*
+ /*
* ADS_EXTENDED_DN_HEX_STRING:
* <GUID=238e1963cb390f4bb032ba0105525a29>;<SID=010500000000000515000000bb68c8fd6b61b427572eb04556040000>;CN=gd,OU=berlin,OU=suse,DC=ber,DC=suse,DC=de
*
* ADS_EXTENDED_DN_STRING (only with w2k3):
- <GUID=63198e23-39cb-4b0f-b032-ba0105525a29>;<SID=S-1-5-21-4257769659-666132843-1169174103-1110>;CN=gd,OU=berlin,OU=suse,DC=ber,DC=suse,DC=de
+ * <GUID=63198e23-39cb-4b0f-b032-ba0105525a29>;<SID=S-1-5-21-4257769659-666132843-1169174103-1110>;CN=gd,OU=berlin,OU=suse,DC=ber,DC=suse,DC=de
+ *
+ * Object with no SID, such as an Exchange Public Folder
+ * <GUID=28907fb4bdf6854993e7f0a10b504e7c>;CN=public,CN=Microsoft Exchange System Objects,DC=sd2k3ms,DC=west,DC=isilon,DC=com
*/
p = strchr(dn, ';');
if (!p) {
- return False;
+ return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
if (strncmp(p, ";<SID=", strlen(";<SID=")) != 0) {
- return False;
+ DEBUG(5,("No SID present in extended dn\n"));
+ return ADS_ERROR_NT(NT_STATUS_NOT_FOUND);
}
p += strlen(";<SID=");
q = strchr(p, '>');
if (!q) {
- return False;
+ return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
-
+
*q = '\0';
DEBUG(100,("ads_get_sid_from_extended_dn: sid string is %s\n", p));
switch (flags) {
-
+
case ADS_EXTENDED_DN_STRING:
if (!string_to_sid(sid, p)) {
- return False;
+ return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
break;
case ADS_EXTENDED_DN_HEX_STRING: {
@@ -3173,21 +3179,21 @@ bool ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx,
buf_len = strhex_to_str(buf, sizeof(buf), p, strlen(p));
if (buf_len == 0) {
- return False;
+ return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
if (!sid_parse(buf, buf_len, sid)) {
DEBUG(10,("failed to parse sid\n"));
- return False;
+ return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
break;
}
default:
DEBUG(10,("unknown extended dn format\n"));
- return False;
+ return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
- return True;
+ return ADS_ERROR_NT(NT_STATUS_OK);
}
/**
@@ -3200,18 +3206,19 @@ bool ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx,
* @param sids pointer to sid array to allocate
* @return the count of SIDs pulled
**/
- int ads_pull_sids_from_extendeddn(ADS_STRUCT *ads,
- TALLOC_CTX *mem_ctx,
- LDAPMessage *msg,
+ int ads_pull_sids_from_extendeddn(ADS_STRUCT *ads,
+ TALLOC_CTX *mem_ctx,
+ LDAPMessage *msg,
const char *field,
enum ads_extended_dn_flags flags,
DOM_SID **sids)
{
int i;
- size_t dn_count;
+ ADS_STATUS rc;
+ size_t dn_count, ret_count = 0;
char **dn_strings;
- if ((dn_strings = ads_pull_strings(ads, mem_ctx, msg, field,
+ if ((dn_strings = ads_pull_strings(ads, mem_ctx, msg, field,
&dn_count)) == NULL) {
return 0;
}
@@ -3223,18 +3230,25 @@ bool ads_get_sid_from_extended_dn(TALLOC_CTX *mem_ctx,
}
for (i=0; i<dn_count; i++) {
-
- if (!ads_get_sid_from_extended_dn(mem_ctx, dn_strings[i],
- flags, &(*sids)[i])) {
- TALLOC_FREE(*sids);
- TALLOC_FREE(dn_strings);
- return 0;
+ rc = ads_get_sid_from_extended_dn(mem_ctx, dn_strings[i],
+ flags, &(*sids)[i]);
+ if (!ADS_ERR_OK(rc)) {
+ if (NT_STATUS_EQUAL(ads_ntstatus(rc),
+ NT_STATUS_NOT_FOUND)) {
+ continue;
+ }
+ else {
+ TALLOC_FREE(*sids);
+ TALLOC_FREE(dn_strings);
+ return 0;
+ }
}
+ ret_count++;
}
TALLOC_FREE(dn_strings);
- return dn_count;
+ return ret_count;
}
/********************************************************************
diff --git a/source3/libgpo/gpo_ldap.c b/source3/libgpo/gpo_ldap.c
index 0e77f0a856..26813864e5 100644
--- a/source3/libgpo/gpo_ldap.c
+++ b/source3/libgpo/gpo_ldap.c
@@ -44,7 +44,7 @@ bool ads_parse_gp_ext(TALLOC_CTX *mem_ctx,
goto parse_error;
}
- ext_list = str_list_make(mem_ctx, extension_raw, "]");
+ ext_list = str_list_make_v3(mem_ctx, extension_raw, "]");
if (!ext_list) {
goto parse_error;
}
@@ -87,7 +87,7 @@ bool ads_parse_gp_ext(TALLOC_CTX *mem_ctx,
p++;
}
- ext_strings = str_list_make(mem_ctx, p, "}");
+ ext_strings = str_list_make_v3(mem_ctx, p, "}");
if (ext_strings == NULL) {
goto parse_error;
}
@@ -162,7 +162,7 @@ static ADS_STATUS gpo_parse_gplink(TALLOC_CTX *mem_ctx,
DEBUG(10,("gpo_parse_gplink: gPLink: %s\n", gp_link_raw));
- link_list = str_list_make(mem_ctx, gp_link_raw, "]");
+ link_list = str_list_make_v3(mem_ctx, gp_link_raw, "]");
if (!link_list) {
goto parse_error;
}
diff --git a/source3/libnet/libnet_dssync_keytab.c b/source3/libnet/libnet_dssync_keytab.c
index 6a3139d6ad..a05bfdcbe2 100644
--- a/source3/libnet/libnet_dssync_keytab.c
+++ b/source3/libnet/libnet_dssync_keytab.c
@@ -24,39 +24,6 @@
#if defined(HAVE_ADS) && defined(ENCTYPE_ARCFOUR_HMAC)
-/**
- * Internal helper function to add data to the list
- * of keytab entries. It builds the prefix from the input.
- */
-static NTSTATUS add_to_keytab_entries(TALLOC_CTX *mem_ctx,
- struct libnet_keytab_context *ctx,
- uint32_t kvno,
- const char *name,
- const char *prefix,
- const krb5_enctype enctype,
- DATA_BLOB blob)
-{
- struct libnet_keytab_entry entry;
-
- entry.kvno = kvno;
- entry.name = talloc_strdup(mem_ctx, name);
- entry.principal = talloc_asprintf(mem_ctx, "%s%s%s@%s",
- prefix ? prefix : "",
- prefix ? "/" : "",
- name, ctx->dns_domain_name);
- entry.enctype = enctype;
- entry.password = blob;
- NT_STATUS_HAVE_NO_MEMORY(entry.name);
- NT_STATUS_HAVE_NO_MEMORY(entry.principal);
- NT_STATUS_HAVE_NO_MEMORY(entry.password.data);
-
- ADD_TO_ARRAY(mem_ctx, struct libnet_keytab_entry, entry,
- &ctx->entries, &ctx->count);
- NT_STATUS_HAVE_NO_MEMORY(ctx->entries);
-
- return NT_STATUS_OK;
-}
-
static NTSTATUS keytab_startup(struct dssync_context *ctx, TALLOC_CTX *mem_ctx,
struct replUpToDateVectorBlob **pold_utdv)
{
@@ -134,10 +101,10 @@ static NTSTATUS keytab_finish(struct dssync_context *ctx, TALLOC_CTX *mem_ctx,
goto done;
}
- status = add_to_keytab_entries(mem_ctx, keytab_ctx, 0,
- ctx->nc_dn, "UTDV",
- ENCTYPE_NULL,
- blob);
+ status = libnet_keytab_add_to_keytab_entries(mem_ctx, keytab_ctx, 0,
+ ctx->nc_dn, "UTDV",
+ ENCTYPE_NULL,
+ blob);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
@@ -391,11 +358,11 @@ static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
}
if (name) {
- status = add_to_keytab_entries(mem_ctx, ctx, 0, object_dn,
- "SAMACCOUNTNAME",
- ENCTYPE_NULL,
- data_blob_talloc(mem_ctx, name,
- strlen(name) + 1));
+ status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, 0, object_dn,
+ "SAMACCOUNTNAME",
+ ENCTYPE_NULL,
+ data_blob_talloc(mem_ctx, name,
+ strlen(name) + 1));
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -454,9 +421,9 @@ static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
}
DEBUGADD(1,("\n"));
- status = add_to_keytab_entries(mem_ctx, ctx, kvno, name, NULL,
- ENCTYPE_ARCFOUR_HMAC,
- data_blob_talloc(mem_ctx, nt_passwd, 16));
+ status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, kvno, name, NULL,
+ ENCTYPE_ARCFOUR_HMAC,
+ data_blob_talloc(mem_ctx, nt_passwd, 16));
if (!NT_STATUS_IS_OK(status)) {
return status;
@@ -469,11 +436,11 @@ static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
if (!pkb4->keys[i].value) {
continue;
}
- status = add_to_keytab_entries(mem_ctx, ctx, kvno,
- name,
- NULL,
- pkb4->keys[i].keytype,
- *pkb4->keys[i].value);
+ status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, kvno,
+ name,
+ NULL,
+ pkb4->keys[i].keytype,
+ *pkb4->keys[i].value);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -482,11 +449,11 @@ static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
if (!pkb4->old_keys[i].value) {
continue;
}
- status = add_to_keytab_entries(mem_ctx, ctx, kvno - 1,
- name,
- NULL,
- pkb4->old_keys[i].keytype,
- *pkb4->old_keys[i].value);
+ status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, kvno - 1,
+ name,
+ NULL,
+ pkb4->old_keys[i].keytype,
+ *pkb4->old_keys[i].value);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -495,11 +462,11 @@ static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
if (!pkb4->older_keys[i].value) {
continue;
}
- status = add_to_keytab_entries(mem_ctx, ctx, kvno - 2,
- name,
- NULL,
- pkb4->older_keys[i].keytype,
- *pkb4->older_keys[i].value);
+ status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, kvno - 2,
+ name,
+ NULL,
+ pkb4->older_keys[i].keytype,
+ *pkb4->older_keys[i].value);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -511,10 +478,10 @@ static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
if (!pkb3->keys[i].value) {
continue;
}
- status = add_to_keytab_entries(mem_ctx, ctx, kvno, name,
- NULL,
- pkb3->keys[i].keytype,
- *pkb3->keys[i].value);
+ status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, kvno, name,
+ NULL,
+ pkb3->keys[i].keytype,
+ *pkb3->keys[i].value);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -523,11 +490,11 @@ static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
if (!pkb3->old_keys[i].value) {
continue;
}
- status = add_to_keytab_entries(mem_ctx, ctx, kvno - 1,
- name,
- NULL,
- pkb3->old_keys[i].keytype,
- *pkb3->old_keys[i].value);
+ status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, kvno - 1,
+ name,
+ NULL,
+ pkb3->old_keys[i].keytype,
+ *pkb3->old_keys[i].value);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -549,9 +516,9 @@ static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
}
for (; i<pwd_history_len; i++) {
- status = add_to_keytab_entries(mem_ctx, ctx, kvno--, name, NULL,
- ENCTYPE_ARCFOUR_HMAC,
- data_blob_talloc(mem_ctx, &pwd_history[i*16], 16));
+ status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, kvno--, name, NULL,
+ ENCTYPE_ARCFOUR_HMAC,
+ data_blob_talloc(mem_ctx, &pwd_history[i*16], 16));
if (!NT_STATUS_IS_OK(status)) {
break;
}
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index 6935e000dc..908fb78ab4 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -762,7 +762,6 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx,
struct lsa_String lsa_acct_name;
uint32_t user_rid;
uint32_t acct_flags = ACB_WSTRUST;
- uchar md4_trust_password[16];
struct samr_Ids user_rids;
struct samr_Ids name_types;
union samr_UserInfo user_info;
@@ -898,14 +897,6 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx,
goto done;
}
- /* Create a random machine account password and generate the hash */
-
- E_md4hash(r->in.machine_password, md4_trust_password);
-
- init_samr_CryptPasswordEx(r->in.machine_password,
- &cli->user_session_key,
- &crypt_pwd_ex);
-
/* Fill in the additional account flags now */
acct_flags |= ACB_PWNOEXP;
@@ -916,23 +907,40 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx,
;;
}
- /* Set password and account flags on machine account */
-
- ZERO_STRUCT(user_info.info25);
-
- user_info.info25.info.fields_present = ACCT_NT_PWD_SET |
- ACCT_LM_PWD_SET |
- SAMR_FIELD_ACCT_FLAGS;
-
- user_info.info25.info.acct_flags = acct_flags;
- memcpy(&user_info.info25.password.data, crypt_pwd_ex.data,
- sizeof(crypt_pwd_ex.data));
+ /* Set account flags on machine account */
+ ZERO_STRUCT(user_info.info16);
+ user_info.info16.acct_flags = acct_flags;
status = rpccli_samr_SetUserInfo(pipe_hnd, mem_ctx,
&user_pol,
- 25,
+ 16,
&user_info);
+ if (!NT_STATUS_IS_OK(status)) {
+
+ rpccli_samr_DeleteUser(pipe_hnd, mem_ctx,
+ &user_pol);
+
+ libnet_join_set_error_string(mem_ctx, r,
+ "Failed to set account flags for machine account (%s)\n",
+ nt_errstr(status));
+ goto done;
+ }
+
+ /* Set password on machine account - first try level 26 */
+
+ init_samr_CryptPasswordEx(r->in.machine_password,
+ &cli->user_session_key,
+ &crypt_pwd_ex);
+
+ init_samr_user_info26(&user_info.info26, &crypt_pwd_ex,
+ PASS_DONT_CHANGE_AT_NEXT_LOGON);
+
+ status = rpccli_samr_SetUserInfo2(pipe_hnd, mem_ctx,
+ &user_pol,
+ 26,
+ &user_info);
+
if (NT_STATUS_EQUAL(status, NT_STATUS(DCERPC_FAULT_INVALID_TAG))) {
/* retry with level 24 */
@@ -941,7 +949,8 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx,
&cli->user_session_key,
&crypt_pwd);
- init_samr_user_info24(&user_info.info24, crypt_pwd.data, 24);
+ init_samr_user_info24(&user_info.info24, &crypt_pwd,
+ PASS_DONT_CHANGE_AT_NEXT_LOGON);
status = rpccli_samr_SetUserInfo2(pipe_hnd, mem_ctx,
&user_pol,
@@ -1638,24 +1647,31 @@ WERROR libnet_init_UnjoinCtx(TALLOC_CTX *mem_ctx,
static WERROR libnet_join_check_config(TALLOC_CTX *mem_ctx,
struct libnet_JoinCtx *r)
{
+ bool valid_security = false;
+ bool valid_workgroup = false;
+ bool valid_realm = false;
+
/* check if configuration is already set correctly */
+ valid_workgroup = strequal(lp_workgroup(), r->out.netbios_domain_name);
+
switch (r->out.domain_is_ad) {
case false:
- if ((strequal(lp_workgroup(),
- r->out.netbios_domain_name)) &&
- (lp_security() == SEC_DOMAIN)) {
+ valid_security = (lp_security() == SEC_DOMAIN);
+ if (valid_workgroup && valid_security) {
/* nothing to be done */
return WERR_OK;
}
break;
case true:
- if ((strequal(lp_workgroup(),
- r->out.netbios_domain_name)) &&
- (strequal(lp_realm(),
- r->out.dns_domain_name)) &&
- ((lp_security() == SEC_ADS) ||
- (lp_security() == SEC_DOMAIN))) {
+ valid_realm = strequal(lp_realm(), r->out.dns_domain_name);
+ switch (lp_security()) {
+ case SEC_DOMAIN:
+ case SEC_ADS:
+ valid_security = true;
+ }
+
+ if (valid_workgroup && valid_realm && valid_security) {
/* nothing to be done */
return WERR_OK;
}
@@ -1665,9 +1681,41 @@ static WERROR libnet_join_check_config(TALLOC_CTX *mem_ctx,
/* check if we are supposed to manipulate configuration */
if (!r->in.modify_config) {
+
+ char *wrong_conf = talloc_strdup(mem_ctx, "");
+
+ if (!valid_workgroup) {
+ wrong_conf = talloc_asprintf_append(wrong_conf,
+ "\"workgroup\" set to '%s', should be '%s'",
+ lp_workgroup(), r->out.netbios_domain_name);
+ W_ERROR_HAVE_NO_MEMORY(wrong_conf);
+ }
+
+ if (!valid_realm) {
+ wrong_conf = talloc_asprintf_append(wrong_conf,
+ "\"realm\" set to '%s', should be '%s'",
+ lp_realm(), r->out.dns_domain_name);
+ W_ERROR_HAVE_NO_MEMORY(wrong_conf);
+ }
+
+ if (!valid_security) {
+ const char *sec = NULL;
+ switch (lp_security()) {
+ case SEC_SHARE: sec = "share"; break;
+ case SEC_USER: sec = "user"; break;
+ case SEC_DOMAIN: sec = "domain"; break;
+ case SEC_ADS: sec = "ads"; break;
+ }
+ wrong_conf = talloc_asprintf_append(wrong_conf,
+ "\"security\" set to '%s', should be %s",
+ sec, r->out.domain_is_ad ?
+ "either 'domain' or 'ads'" : "'domain'");
+ W_ERROR_HAVE_NO_MEMORY(wrong_conf);
+ }
+
libnet_join_set_error_string(mem_ctx, r,
- "Invalid configuration and configuration modification "
- "was not requested");
+ "Invalid configuration (%s) and configuration modification "
+ "was not requested", wrong_conf);
return WERR_CAN_NOT_COMPLETE;
}
diff --git a/source3/libnet/libnet_keytab.c b/source3/libnet/libnet_keytab.c
index 46c17b219c..990f6f6a63 100644
--- a/source3/libnet/libnet_keytab.c
+++ b/source3/libnet/libnet_keytab.c
@@ -401,4 +401,37 @@ cont:
return entry;
}
+/**
+ * Helper function to add data to the list
+ * of keytab entries. It builds the prefix from the input.
+ */
+NTSTATUS libnet_keytab_add_to_keytab_entries(TALLOC_CTX *mem_ctx,
+ struct libnet_keytab_context *ctx,
+ uint32_t kvno,
+ const char *name,
+ const char *prefix,
+ const krb5_enctype enctype,
+ DATA_BLOB blob)
+{
+ struct libnet_keytab_entry entry;
+
+ entry.kvno = kvno;
+ entry.name = talloc_strdup(mem_ctx, name);
+ entry.principal = talloc_asprintf(mem_ctx, "%s%s%s@%s",
+ prefix ? prefix : "",
+ prefix ? "/" : "",
+ name, ctx->dns_domain_name);
+ entry.enctype = enctype;
+ entry.password = blob;
+ NT_STATUS_HAVE_NO_MEMORY(entry.name);
+ NT_STATUS_HAVE_NO_MEMORY(entry.principal);
+ NT_STATUS_HAVE_NO_MEMORY(entry.password.data);
+
+ ADD_TO_ARRAY(mem_ctx, struct libnet_keytab_entry, entry,
+ &ctx->entries, &ctx->count);
+ NT_STATUS_HAVE_NO_MEMORY(ctx->entries);
+
+ return NT_STATUS_OK;
+}
+
#endif /* HAVE_KRB5 */
diff --git a/source3/libnet/libnet_proto.h b/source3/libnet/libnet_proto.h
index 69a16c1c7d..9a193b724d 100644
--- a/source3/libnet/libnet_proto.h
+++ b/source3/libnet/libnet_proto.h
@@ -55,6 +55,13 @@ struct libnet_keytab_entry *libnet_keytab_search(struct libnet_keytab_context *c
const char *principal, int kvno,
const krb5_enctype enctype,
TALLOC_CTX *mem_ctx);
+NTSTATUS libnet_keytab_add_to_keytab_entries(TALLOC_CTX *mem_ctx,
+ struct libnet_keytab_context *ctx,
+ uint32_t kvno,
+ const char *name,
+ const char *prefix,
+ const krb5_enctype enctype,
+ DATA_BLOB blob);
#endif
/* The following definitions come from libnet/libnet_samsync.c */
diff --git a/source3/libnet/libnet_samsync.c b/source3/libnet/libnet_samsync.c
index 00caf2b8c1..4351810169 100644
--- a/source3/libnet/libnet_samsync.c
+++ b/source3/libnet/libnet_samsync.c
@@ -282,47 +282,112 @@ static const char *samsync_debug_str(TALLOC_CTX *mem_ctx,
* libnet_samsync
*/
-NTSTATUS libnet_samsync(enum netr_SamDatabaseID database_id,
- struct samsync_context *ctx)
+void libnet_init_netr_ChangeLogEntry(struct samsync_object *o,
+ struct netr_ChangeLogEntry *e)
+{
+ ZERO_STRUCTP(e);
+
+ e->db_index = o->database_id;
+ e->delta_type = o->object_type;
+
+ switch (e->delta_type) {
+ case NETR_DELTA_DOMAIN:
+ case NETR_DELTA_DELETE_GROUP:
+ case NETR_DELTA_RENAME_GROUP:
+ case NETR_DELTA_DELETE_USER:
+ case NETR_DELTA_RENAME_USER:
+ case NETR_DELTA_DELETE_ALIAS:
+ case NETR_DELTA_RENAME_ALIAS:
+ case NETR_DELTA_DELETE_TRUST:
+ case NETR_DELTA_DELETE_ACCOUNT:
+ case NETR_DELTA_DELETE_SECRET:
+ case NETR_DELTA_DELETE_GROUP2:
+ case NETR_DELTA_DELETE_USER2:
+ case NETR_DELTA_MODIFY_COUNT:
+ break;
+ case NETR_DELTA_USER:
+ case NETR_DELTA_GROUP:
+ case NETR_DELTA_GROUP_MEMBER:
+ case NETR_DELTA_ALIAS:
+ case NETR_DELTA_ALIAS_MEMBER:
+ e->object_rid = o->object_identifier.rid;
+ break;
+ case NETR_DELTA_SECRET:
+ e->object.object_name = o->object_identifier.name;
+ e->flags = NETR_CHANGELOG_NAME_INCLUDED;
+ break;
+ case NETR_DELTA_TRUSTED_DOMAIN:
+ case NETR_DELTA_ACCOUNT:
+ case NETR_DELTA_POLICY:
+ e->object.object_sid = o->object_identifier.sid;
+ e->flags = NETR_CHANGELOG_SID_INCLUDED;
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * libnet_samsync_delta
+ */
+
+static NTSTATUS libnet_samsync_delta(TALLOC_CTX *mem_ctx,
+ enum netr_SamDatabaseID database_id,
+ uint64_t *sequence_num,
+ struct samsync_context *ctx,
+ struct netr_ChangeLogEntry *e)
{
NTSTATUS result;
- TALLOC_CTX *mem_ctx;
+ NTSTATUS callback_status;
const char *logon_server = ctx->cli->desthost;
const char *computername = global_myname();
struct netr_Authenticator credential;
struct netr_Authenticator return_authenticator;
uint16_t restart_state = 0;
uint32_t sync_context = 0;
- const char *debug_str;
DATA_BLOB session_key;
ZERO_STRUCT(return_authenticator);
- if (!(mem_ctx = talloc_init("libnet_samsync"))) {
- return NT_STATUS_NO_MEMORY;
- }
-
- debug_str = samsync_debug_str(mem_ctx, ctx->mode, database_id);
- if (debug_str) {
- d_fprintf(stderr, "%s\n", debug_str);
- }
-
do {
struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
- NTSTATUS callback_status;
netlogon_creds_client_step(ctx->cli->dc, &credential);
- result = rpccli_netr_DatabaseSync2(ctx->cli, mem_ctx,
- logon_server,
- computername,
- &credential,
- &return_authenticator,
- database_id,
- restart_state,
- &sync_context,
- &delta_enum_array,
- 0xffff);
+ if (ctx->single_object_replication &&
+ !ctx->force_full_replication) {
+ result = rpccli_netr_DatabaseRedo(ctx->cli, mem_ctx,
+ logon_server,
+ computername,
+ &credential,
+ &return_authenticator,
+ *e,
+ 0,
+ &delta_enum_array);
+ } else if (!ctx->force_full_replication &&
+ sequence_num && (*sequence_num > 0)) {
+ result = rpccli_netr_DatabaseDeltas(ctx->cli, mem_ctx,
+ logon_server,
+ computername,
+ &credential,
+ &return_authenticator,
+ database_id,
+ sequence_num,
+ &delta_enum_array,
+ 0xffff);
+ } else {
+ result = rpccli_netr_DatabaseSync2(ctx->cli, mem_ctx,
+ logon_server,
+ computername,
+ &credential,
+ &return_authenticator,
+ database_id,
+ restart_state,
+ &sync_context,
+ &delta_enum_array,
+ 0xffff);
+ }
+
if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED)) {
return result;
}
@@ -346,9 +411,10 @@ NTSTATUS libnet_samsync(enum netr_SamDatabaseID database_id,
delta_enum_array);
/* Process results */
- callback_status = ctx->delta_fn(mem_ctx, database_id,
- delta_enum_array,
- NT_STATUS_IS_OK(result), ctx);
+ callback_status = ctx->ops->process_objects(mem_ctx, database_id,
+ delta_enum_array,
+ sequence_num,
+ ctx);
if (!NT_STATUS_IS_OK(callback_status)) {
result = callback_status;
goto out;
@@ -362,14 +428,86 @@ NTSTATUS libnet_samsync(enum netr_SamDatabaseID database_id,
} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
out:
- if (NT_STATUS_IS_ERR(result) && !ctx->error_message) {
+
+ return result;
+}
+
+/**
+ * libnet_samsync
+ */
+
+NTSTATUS libnet_samsync(enum netr_SamDatabaseID database_id,
+ struct samsync_context *ctx)
+{
+ NTSTATUS status = NT_STATUS_OK;
+ NTSTATUS callback_status;
+ TALLOC_CTX *mem_ctx;
+ const char *debug_str;
+ uint64_t sequence_num = 0;
+ int i = 0;
+
+ if (!(mem_ctx = talloc_new(ctx))) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (!ctx->ops) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (ctx->ops->startup) {
+ status = ctx->ops->startup(mem_ctx, ctx,
+ database_id, &sequence_num);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+ }
+
+ debug_str = samsync_debug_str(mem_ctx, ctx->mode, database_id);
+ if (debug_str) {
+ d_fprintf(stderr, "%s\n", debug_str);
+ }
+
+ if (!ctx->single_object_replication) {
+ status = libnet_samsync_delta(mem_ctx, database_id,
+ &sequence_num, ctx, NULL);
+ goto done;
+ }
+
+ for (i=0; i<ctx->num_objects; i++) {
+
+ struct netr_ChangeLogEntry e;
+
+ if (ctx->objects[i].database_id != database_id) {
+ continue;
+ }
+
+ libnet_init_netr_ChangeLogEntry(&ctx->objects[i], &e);
+
+ status = libnet_samsync_delta(mem_ctx, database_id,
+ &sequence_num, ctx, &e);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+ }
+
+ done:
+
+ if (NT_STATUS_IS_OK(status) && ctx->ops->finish) {
+ callback_status = ctx->ops->finish(mem_ctx, ctx,
+ database_id, sequence_num);
+ if (!NT_STATUS_IS_OK(callback_status)) {
+ status = callback_status;
+ }
+ }
+
+ if (NT_STATUS_IS_ERR(status) && !ctx->error_message) {
ctx->error_message = talloc_asprintf(ctx,
"Failed to fetch %s database: %s",
samsync_database_str(database_id),
- nt_errstr(result));
+ nt_errstr(status));
- if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED)) {
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
ctx->error_message =
talloc_asprintf_append(ctx->error_message,
@@ -380,7 +518,7 @@ NTSTATUS libnet_samsync(enum netr_SamDatabaseID database_id,
talloc_destroy(mem_ctx);
- return result;
+ return status;
}
/**
diff --git a/source3/libnet/libnet_samsync.h b/source3/libnet/libnet_samsync.h
index 1f10d2c1c0..3a686a7f45 100644
--- a/source3/libnet/libnet_samsync.h
+++ b/source3/libnet/libnet_samsync.h
@@ -27,11 +27,31 @@ enum net_samsync_mode {
struct samsync_context;
-typedef NTSTATUS (*samsync_delta_fn_t)(TALLOC_CTX *,
- enum netr_SamDatabaseID,
- struct netr_DELTA_ENUM_ARRAY *,
- bool,
- struct samsync_context *);
+struct samsync_ops {
+ NTSTATUS (*startup)(TALLOC_CTX *mem_ctx,
+ struct samsync_context *ctx,
+ enum netr_SamDatabaseID id,
+ uint64_t *sequence_num);
+ NTSTATUS (*process_objects)(TALLOC_CTX *mem_ctx,
+ enum netr_SamDatabaseID id,
+ struct netr_DELTA_ENUM_ARRAY *array,
+ uint64_t *sequence_num,
+ struct samsync_context *ctx);
+ NTSTATUS (*finish)(TALLOC_CTX *mem_ctx,
+ struct samsync_context *ctx,
+ enum netr_SamDatabaseID id,
+ uint64_t sequence_num);
+};
+
+struct samsync_object {
+ uint16_t database_id;
+ uint16_t object_type;
+ union {
+ uint32_t rid;
+ const char *name;
+ struct dom_sid sid;
+ } object_identifier;
+};
struct samsync_context {
enum net_samsync_mode mode;
@@ -46,28 +66,21 @@ struct samsync_context {
char *result_message;
char *error_message;
+ bool single_object_replication;
+ bool force_full_replication;
+ bool clean_old_entries;
+
+ uint32_t num_objects;
+ struct samsync_object *objects;
+
struct rpc_pipe_client *cli;
- samsync_delta_fn_t delta_fn;
+
+ const struct samsync_ops *ops;
+
void *private_data;
};
-NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
- enum netr_SamDatabaseID database_id,
- struct netr_DELTA_ENUM_ARRAY *r,
- bool last_query,
- struct samsync_context *ctx);
-NTSTATUS fetch_sam_entries(TALLOC_CTX *mem_ctx,
- enum netr_SamDatabaseID database_id,
- struct netr_DELTA_ENUM_ARRAY *r,
- bool last_query,
- struct samsync_context *ctx);
-NTSTATUS display_sam_entries(TALLOC_CTX *mem_ctx,
- enum netr_SamDatabaseID database_id,
- struct netr_DELTA_ENUM_ARRAY *r,
- bool last_query,
- struct samsync_context *ctx);
-NTSTATUS fetch_sam_entries_keytab(TALLOC_CTX *mem_ctx,
- enum netr_SamDatabaseID database_id,
- struct netr_DELTA_ENUM_ARRAY *r,
- bool last_query,
- struct samsync_context *ctx);
+extern const struct samsync_ops libnet_samsync_ldif_ops;
+extern const struct samsync_ops libnet_samsync_keytab_ops;
+extern const struct samsync_ops libnet_samsync_display_ops;
+extern const struct samsync_ops libnet_samsync_passdb_ops;
diff --git a/source3/libnet/libnet_samsync_display.c b/source3/libnet/libnet_samsync_display.c
index 1dd9a1add5..c8d9ec6f09 100644
--- a/source3/libnet/libnet_samsync_display.c
+++ b/source3/libnet/libnet_samsync_display.c
@@ -163,7 +163,6 @@ static void display_rename_alias(uint32_t rid, struct netr_DELTA_RENAME *r)
static NTSTATUS display_sam_entry(TALLOC_CTX *mem_ctx,
enum netr_SamDatabaseID database_id,
struct netr_DELTA_ENUM *r,
- bool last_query,
struct samsync_context *ctx)
{
union netr_DELTA_UNION u = r->delta_union;
@@ -285,18 +284,22 @@ static NTSTATUS display_sam_entry(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
-NTSTATUS display_sam_entries(TALLOC_CTX *mem_ctx,
- enum netr_SamDatabaseID database_id,
- struct netr_DELTA_ENUM_ARRAY *r,
- bool last_query,
- struct samsync_context *ctx)
+static NTSTATUS display_sam_entries(TALLOC_CTX *mem_ctx,
+ enum netr_SamDatabaseID database_id,
+ struct netr_DELTA_ENUM_ARRAY *r,
+ uint64_t *sequence_num,
+ struct samsync_context *ctx)
{
int i;
for (i = 0; i < r->num_deltas; i++) {
display_sam_entry(mem_ctx, database_id, &r->delta_enum[i],
- last_query, ctx);
+ ctx);
}
return NT_STATUS_OK;
}
+
+const struct samsync_ops libnet_samsync_display_ops = {
+ .process_objects = display_sam_entries,
+};
diff --git a/source3/libnet/libnet_samsync_keytab.c b/source3/libnet/libnet_samsync_keytab.c
index 4b0cc06d94..cdb344604d 100644
--- a/source3/libnet/libnet_samsync_keytab.c
+++ b/source3/libnet/libnet_samsync_keytab.c
@@ -75,30 +75,28 @@ static NTSTATUS fetch_sam_entry_keytab(TALLOC_CTX *mem_ctx,
enum netr_SamDatabaseID database_id,
uint32_t rid,
struct netr_DELTA_USER *r,
- bool last_query,
struct libnet_keytab_context *ctx)
{
- struct libnet_keytab_entry entry;
+ NTSTATUS status;
+ uint32_t kvno = 0;
+ DATA_BLOB blob;
if (memcmp(r->ntpassword.hash, ctx->zero_buf, 16) == 0) {
return NT_STATUS_OK;
}
- entry.name = talloc_strdup(mem_ctx, r->account_name.string);
- entry.principal = talloc_asprintf(mem_ctx, "%s@%s",
- r->account_name.string,
- ctx->dns_domain_name);
- entry.password = data_blob_talloc(mem_ctx, r->ntpassword.hash, 16);
- entry.kvno = ads_get_kvno(ctx->ads, entry.name);
- entry.enctype = ENCTYPE_NULL;
-
- NT_STATUS_HAVE_NO_MEMORY(entry.name);
- NT_STATUS_HAVE_NO_MEMORY(entry.principal);
- NT_STATUS_HAVE_NO_MEMORY(entry.password.data);
-
+ kvno = ads_get_kvno(ctx->ads, r->account_name.string);
+ blob = data_blob_const(r->ntpassword.hash, 16);
- ADD_TO_ARRAY(mem_ctx, struct libnet_keytab_entry, entry,
- &ctx->entries, &ctx->count);
+ status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx,
+ kvno,
+ r->account_name.string,
+ NULL,
+ ENCTYPE_ARCFOUR_HMAC,
+ blob);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
return NT_STATUS_OK;
}
@@ -106,72 +104,163 @@ static NTSTATUS fetch_sam_entry_keytab(TALLOC_CTX *mem_ctx,
/****************************************************************
****************************************************************/
-NTSTATUS fetch_sam_entries_keytab(TALLOC_CTX *mem_ctx,
- enum netr_SamDatabaseID database_id,
- struct netr_DELTA_ENUM_ARRAY *r,
- bool last_query,
- struct samsync_context *ctx)
+static NTSTATUS init_keytab(TALLOC_CTX *mem_ctx,
+ struct samsync_context *ctx,
+ enum netr_SamDatabaseID database_id,
+ uint64_t *sequence_num)
{
- NTSTATUS status = NT_STATUS_OK;
krb5_error_code ret = 0;
- static struct libnet_keytab_context *keytab_ctx = NULL;
- int i;
-
- if (!keytab_ctx) {
- ret = libnet_keytab_init(mem_ctx, ctx->output_filename,
- &keytab_ctx);
- if (ret) {
- status = krb5_to_nt_status(ret);
- goto out;
- }
+ NTSTATUS status;
+ struct libnet_keytab_context *keytab_ctx;
+ struct libnet_keytab_entry *entry;
+ uint64_t old_sequence_num = 0;
+ const char *principal = NULL;
+
+ ret = libnet_keytab_init(mem_ctx, ctx->output_filename, &keytab_ctx);
+ if (ret) {
+ return krb5_to_nt_status(ret);
}
+ keytab_ctx->clean_old_entries = ctx->clean_old_entries;
+ ctx->private_data = keytab_ctx;
+
status = keytab_ad_connect(mem_ctx,
ctx->domain_name,
ctx->username,
ctx->password,
keytab_ctx);
if (!NT_STATUS_IS_OK(status)) {
- goto out;
+ TALLOC_FREE(keytab_ctx);
+ return status;
}
+ principal = talloc_asprintf(mem_ctx, "SEQUENCE_NUM@%s",
+ keytab_ctx->dns_domain_name);
+ NT_STATUS_HAVE_NO_MEMORY(principal);
+
+ entry = libnet_keytab_search(keytab_ctx, principal, 0, ENCTYPE_NULL,
+ mem_ctx);
+ if (entry && (entry->password.length == 8)) {
+ old_sequence_num = BVAL(entry->password.data, 0);
+ }
+
+ if (sequence_num) {
+ *sequence_num = old_sequence_num;
+ }
+
+ return status;
+}
+
+/****************************************************************
+****************************************************************/
+
+static NTSTATUS fetch_sam_entries_keytab(TALLOC_CTX *mem_ctx,
+ enum netr_SamDatabaseID database_id,
+ struct netr_DELTA_ENUM_ARRAY *r,
+ uint64_t *sequence_num,
+ struct samsync_context *ctx)
+{
+ struct libnet_keytab_context *keytab_ctx =
+ (struct libnet_keytab_context *)ctx->private_data;
+
+ NTSTATUS status = NT_STATUS_OK;
+ int i;
+
for (i = 0; i < r->num_deltas; i++) {
- if (r->delta_enum[i].delta_type != NETR_DELTA_USER) {
+ switch (r->delta_enum[i].delta_type) {
+ case NETR_DELTA_USER:
+ break;
+ case NETR_DELTA_DOMAIN:
+ if (sequence_num) {
+ *sequence_num =
+ r->delta_enum[i].delta_union.domain->sequence_num;
+ }
+ continue;
+ case NETR_DELTA_MODIFY_COUNT:
+ if (sequence_num) {
+ *sequence_num =
+ *r->delta_enum[i].delta_union.modified_count;
+ }
+ continue;
+ default:
continue;
}
status = fetch_sam_entry_keytab(mem_ctx, database_id,
r->delta_enum[i].delta_id_union.rid,
r->delta_enum[i].delta_union.user,
- last_query,
keytab_ctx);
if (!NT_STATUS_IS_OK(status)) {
goto out;
}
}
+ out:
+ return status;
+}
- if (last_query) {
+/****************************************************************
+****************************************************************/
+
+static NTSTATUS close_keytab(TALLOC_CTX *mem_ctx,
+ struct samsync_context *ctx,
+ enum netr_SamDatabaseID database_id,
+ uint64_t sequence_num)
+{
+ struct libnet_keytab_context *keytab_ctx =
+ (struct libnet_keytab_context *)ctx->private_data;
+ krb5_error_code ret;
+ NTSTATUS status;
+ struct libnet_keytab_entry *entry;
+ uint64_t old_sequence_num = 0;
+ const char *principal = NULL;
+
+ principal = talloc_asprintf(mem_ctx, "SEQUENCE_NUM@%s",
+ keytab_ctx->dns_domain_name);
+ NT_STATUS_HAVE_NO_MEMORY(principal);
+
+
+ entry = libnet_keytab_search(keytab_ctx, principal, 0, ENCTYPE_NULL,
+ mem_ctx);
+ if (entry && (entry->password.length == 8)) {
+ old_sequence_num = BVAL(entry->password.data, 0);
+ }
- ret = libnet_keytab_add(keytab_ctx);
- if (ret) {
- status = krb5_to_nt_status(ret);
- ctx->error_message = talloc_asprintf(mem_ctx,
- "Failed to add entries to keytab %s: %s",
- keytab_ctx->keytab_name, error_message(ret));
- goto out;
- }
- ctx->result_message = talloc_asprintf(mem_ctx,
- "Vampired %d accounts to keytab %s",
- keytab_ctx->count,
- keytab_ctx->keytab_name);
+ if (sequence_num > old_sequence_num) {
+ DATA_BLOB blob;
+ blob = data_blob_talloc_zero(mem_ctx, 8);
+ SBVAL(blob.data, 0, sequence_num);
+
+ status = libnet_keytab_add_to_keytab_entries(mem_ctx, keytab_ctx,
+ 0,
+ "SEQUENCE_NUM",
+ NULL,
+ ENCTYPE_NULL,
+ blob);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+ }
+ ret = libnet_keytab_add(keytab_ctx);
+ if (ret) {
+ status = krb5_to_nt_status(ret);
+ ctx->error_message = talloc_asprintf(ctx,
+ "Failed to add entries to keytab %s: %s",
+ keytab_ctx->keytab_name, error_message(ret));
TALLOC_FREE(keytab_ctx);
+ return status;
}
- return NT_STATUS_OK;
- out:
+ ctx->result_message = talloc_asprintf(ctx,
+ "Vampired %d accounts to keytab %s",
+ keytab_ctx->count,
+ keytab_ctx->keytab_name);
+
+ status = NT_STATUS_OK;
+
+ done:
TALLOC_FREE(keytab_ctx);
return status;
@@ -179,13 +268,35 @@ NTSTATUS fetch_sam_entries_keytab(TALLOC_CTX *mem_ctx,
#else
-NTSTATUS fetch_sam_entries_keytab(TALLOC_CTX *mem_ctx,
- enum netr_SamDatabaseID database_id,
- struct netr_DELTA_ENUM_ARRAY *r,
- bool last_query,
- struct samsync_context *ctx)
+static NTSTATUS init_keytab(TALLOC_CTX *mem_ctx,
+ struct samsync_context *ctx,
+ enum netr_SamDatabaseID database_id,
+ uint64_t *sequence_num)
+{
+ return NT_STATUS_NOT_SUPPORTED;
+}
+
+static NTSTATUS fetch_sam_entries_keytab(TALLOC_CTX *mem_ctx,
+ enum netr_SamDatabaseID database_id,
+ struct netr_DELTA_ENUM_ARRAY *r,
+ uint64_t *sequence_num,
+ struct samsync_context *ctx)
+{
+ return NT_STATUS_NOT_SUPPORTED;
+}
+
+static NTSTATUS close_keytab(TALLOC_CTX *mem_ctx,
+ struct samsync_context *ctx,
+ enum netr_SamDatabaseID database_id,
+ uint64_t sequence_num)
{
return NT_STATUS_NOT_SUPPORTED;
}
#endif /* defined(HAVE_ADS) && defined(ENCTYPE_ARCFOUR_HMAC) */
+
+const struct samsync_ops libnet_samsync_keytab_ops = {
+ .startup = init_keytab,
+ .process_objects = fetch_sam_entries_keytab,
+ .finish = close_keytab
+};
diff --git a/source3/libnet/libnet_samsync_ldif.c b/source3/libnet/libnet_samsync_ldif.c
index dd5380b6b8..c72eadf03f 100644
--- a/source3/libnet/libnet_samsync_ldif.c
+++ b/source3/libnet/libnet_samsync_ldif.c
@@ -32,6 +32,10 @@
static uint32 ldif_gid = 999;
static uint32 ldif_uid = 999;
+/* global counters */
+static uint32_t g_index = 0;
+static uint32_t a_index = 0;
+
/* Structure for mapping accounts to groups */
/* Array element is the group rid */
typedef struct _groupmap {
@@ -1046,8 +1050,8 @@ static NTSTATUS fetch_sam_entry_ldif(TALLOC_CTX *mem_ctx,
enum netr_SamDatabaseID database_id,
struct netr_DELTA_ENUM *r,
struct samsync_context *ctx,
- uint32_t *a_index,
- uint32_t *g_index)
+ uint32_t *a_index_p,
+ uint32_t *g_index_p)
{
union netr_DELTA_UNION u = r->delta_union;
union netr_DELTA_ID_UNION id = r->delta_id_union;
@@ -1061,34 +1065,34 @@ static NTSTATUS fetch_sam_entry_ldif(TALLOC_CTX *mem_ctx,
case NETR_DELTA_GROUP:
fetch_group_info_to_ldif(mem_ctx,
u.group,
- &l->groupmap[*g_index],
+ &l->groupmap[*g_index_p],
l->add_file,
ctx->domain_sid_str,
l->suffix);
- (*g_index)++;
+ (*g_index_p)++;
break;
case NETR_DELTA_USER:
fetch_account_info_to_ldif(mem_ctx,
u.user,
l->groupmap,
- &l->accountmap[*a_index],
+ &l->accountmap[*a_index_p],
l->add_file,
ctx->domain_sid_str,
l->suffix,
l->num_alloced);
- (*a_index)++;
+ (*a_index_p)++;
break;
case NETR_DELTA_ALIAS:
fetch_alias_info_to_ldif(mem_ctx,
u.alias,
- &l->groupmap[*g_index],
+ &l->groupmap[*g_index_p],
l->add_file,
ctx->domain_sid_str,
l->suffix,
database_id);
- (*g_index)++;
+ (*g_index_p)++;
break;
case NETR_DELTA_GROUP_MEMBER:
@@ -1156,15 +1160,12 @@ static NTSTATUS ldif_realloc_maps(TALLOC_CTX *mem_ctx,
/****************************************************************
****************************************************************/
-NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
- enum netr_SamDatabaseID database_id,
- struct netr_DELTA_ENUM_ARRAY *r,
- bool last_query,
- struct samsync_context *ctx)
+static NTSTATUS init_ldif(TALLOC_CTX *mem_ctx,
+ struct samsync_context *ctx,
+ enum netr_SamDatabaseID database_id,
+ uint64_t *sequence_num)
{
NTSTATUS status;
- int i;
- uint32_t g_index = 0, a_index = 0;
struct samsync_ldif_context *ldif_ctx =
(struct samsync_ldif_context *)ctx->private_data;
@@ -1174,11 +1175,28 @@ NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
ctx->domain_sid_str,
&ldif_ctx);
if (!NT_STATUS_IS_OK(status)) {
- goto failed;
+ return status;
}
ctx->private_data = ldif_ctx;
+ return NT_STATUS_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
+static NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
+ enum netr_SamDatabaseID database_id,
+ struct netr_DELTA_ENUM_ARRAY *r,
+ uint64_t *sequence_num,
+ struct samsync_context *ctx)
+{
+ NTSTATUS status;
+ int i;
+ struct samsync_ldif_context *ldif_ctx =
+ (struct samsync_ldif_context *)ctx->private_data;
+
status = ldif_realloc_maps(mem_ctx, ldif_ctx, r->num_deltas);
if (!NT_STATUS_IS_OK(status)) {
goto failed;
@@ -1193,18 +1211,6 @@ NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
}
}
- /* This was the last query */
- if (last_query) {
- ldif_write_output(database_id, ldif_ctx);
- if (ldif_ctx->ldif_file != stdout) {
- ctx->result_message = talloc_asprintf(mem_ctx,
- "Vampired %d accounts and %d groups to %s",
- a_index, g_index, ctx->output_filename);
- }
- ldif_free_context(ldif_ctx);
- ctx->private_data = NULL;
- }
-
return NT_STATUS_OK;
failed:
@@ -1214,15 +1220,62 @@ NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
return status;
}
+/****************************************************************
+****************************************************************/
+
+static NTSTATUS close_ldif(TALLOC_CTX *mem_ctx,
+ struct samsync_context *ctx,
+ enum netr_SamDatabaseID database_id,
+ uint64_t sequence_num)
+{
+ struct samsync_ldif_context *ldif_ctx =
+ (struct samsync_ldif_context *)ctx->private_data;
+
+ /* This was the last query */
+ ldif_write_output(database_id, ldif_ctx);
+ if (ldif_ctx->ldif_file != stdout) {
+ ctx->result_message = talloc_asprintf(ctx,
+ "Vampired %d accounts and %d groups to %s",
+ a_index, g_index, ctx->output_filename);
+ }
+
+ ldif_free_context(ldif_ctx);
+ ctx->private_data = NULL;
+
+ return NT_STATUS_OK;
+}
+
#else /* HAVE_LDAP */
-NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
- enum netr_SamDatabaseID database_id,
- struct netr_DELTA_ENUM_ARRAY *r,
- bool last_query,
- struct samsync_context *ctx)
+static NTSTATUS init_ldif(TALLOC_CTX *mem_ctx,
+ struct samsync_context *ctx,
+ enum netr_SamDatabaseID database_id,
+ uint64_t *sequence_num)
+{
+ return NT_STATUS_NOT_SUPPORTED;
+}
+
+static NTSTATUS fetch_sam_entries_ldif(TALLOC_CTX *mem_ctx,
+ enum netr_SamDatabaseID database_id,
+ struct netr_DELTA_ENUM_ARRAY *r,
+ uint64_t *sequence_num,
+ struct samsync_context *ctx)
+{
+ return NT_STATUS_NOT_SUPPORTED;
+}
+
+static NTSTATUS close_ldif(TALLOC_CTX *mem_ctx,
+ struct samsync_context *ctx,
+ enum netr_SamDatabaseID database_id,
+ uint64_t sequence_num)
{
return NT_STATUS_NOT_SUPPORTED;
}
#endif
+
+const struct samsync_ops libnet_samsync_ldif_ops = {
+ .startup = init_ldif,
+ .process_objects = fetch_sam_entries_ldif,
+ .finish = close_ldif,
+};
diff --git a/source3/libnet/libnet_samsync_passdb.c b/source3/libnet/libnet_samsync_passdb.c
index 1faef7b3eb..388b10a0fa 100644
--- a/source3/libnet/libnet_samsync_passdb.c
+++ b/source3/libnet/libnet_samsync_passdb.c
@@ -118,12 +118,12 @@ static NTSTATUS sam_account_from_delta(struct samu *account,
pdb_set_profile_path(account, new_string, PDB_CHANGED);
}
- if (r->parameters.string) {
+ if (r->parameters.array) {
DATA_BLOB mung;
char *newstr;
old_string = pdb_get_munged_dial(account);
- mung.length = r->parameters.length;
- mung.data = (uint8 *) r->parameters.string;
+ mung.length = r->parameters.length * 2;
+ mung.data = (uint8_t *) r->parameters.array;
newstr = (mung.length == 0) ? NULL :
base64_encode_data_blob(talloc_tos(), mung);
@@ -772,11 +772,11 @@ static NTSTATUS fetch_sam_entry(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
-NTSTATUS fetch_sam_entries(TALLOC_CTX *mem_ctx,
- enum netr_SamDatabaseID database_id,
- struct netr_DELTA_ENUM_ARRAY *r,
- bool last_query,
- struct samsync_context *ctx)
+static NTSTATUS fetch_sam_entries(TALLOC_CTX *mem_ctx,
+ enum netr_SamDatabaseID database_id,
+ struct netr_DELTA_ENUM_ARRAY *r,
+ uint64_t *sequence_num,
+ struct samsync_context *ctx)
{
int i;
@@ -786,3 +786,7 @@ NTSTATUS fetch_sam_entries(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
+
+const struct samsync_ops libnet_samsync_passdb_ops = {
+ .process_objects = fetch_sam_entries,
+};
diff --git a/source3/librpc/gen_ndr/cli_eventlog.c b/source3/librpc/gen_ndr/cli_eventlog.c
index 08456fc994..02d8fb2e65 100644
--- a/source3/librpc/gen_ndr/cli_eventlog.c
+++ b/source3/librpc/gen_ndr/cli_eventlog.c
@@ -278,8 +278,8 @@ NTSTATUS rpccli_eventlog_OpenEventLogW(struct rpc_pipe_client *cli,
struct eventlog_OpenUnknown0 *unknown0 /* [in] [unique] */,
struct lsa_String *logname /* [in] [ref] */,
struct lsa_String *servername /* [in] [ref] */,
- uint32_t unknown2 /* [in] */,
- uint32_t unknown3 /* [in] */,
+ uint32_t major_version /* [in] */,
+ uint32_t minor_version /* [in] */,
struct policy_handle *handle /* [out] [ref] */)
{
struct eventlog_OpenEventLogW r;
@@ -289,8 +289,8 @@ NTSTATUS rpccli_eventlog_OpenEventLogW(struct rpc_pipe_client *cli,
r.in.unknown0 = unknown0;
r.in.logname = logname;
r.in.servername = servername;
- r.in.unknown2 = unknown2;
- r.in.unknown3 = unknown3;
+ r.in.major_version = major_version;
+ r.in.minor_version = minor_version;
if (DEBUGLEVEL >= 10) {
NDR_PRINT_IN_DEBUG(eventlog_OpenEventLogW, &r);
diff --git a/source3/librpc/gen_ndr/cli_eventlog.h b/source3/librpc/gen_ndr/cli_eventlog.h
index 6945683340..0594a06f59 100644
--- a/source3/librpc/gen_ndr/cli_eventlog.h
+++ b/source3/librpc/gen_ndr/cli_eventlog.h
@@ -27,8 +27,8 @@ NTSTATUS rpccli_eventlog_OpenEventLogW(struct rpc_pipe_client *cli,
struct eventlog_OpenUnknown0 *unknown0 /* [in] [unique] */,
struct lsa_String *logname /* [in] [ref] */,
struct lsa_String *servername /* [in] [ref] */,
- uint32_t unknown2 /* [in] */,
- uint32_t unknown3 /* [in] */,
+ uint32_t major_version /* [in] */,
+ uint32_t minor_version /* [in] */,
struct policy_handle *handle /* [out] [ref] */);
NTSTATUS rpccli_eventlog_RegisterEventSourceW(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx);
diff --git a/source3/librpc/gen_ndr/cli_netlogon.c b/source3/librpc/gen_ndr/cli_netlogon.c
index 275c83a450..1af3249473 100644
--- a/source3/librpc/gen_ndr/cli_netlogon.c
+++ b/source3/librpc/gen_ndr/cli_netlogon.c
@@ -892,8 +892,8 @@ NTSTATUS rpccli_netr_DatabaseRedo(struct rpc_pipe_client *cli,
const char *computername /* [in] [charset(UTF16)] */,
struct netr_Authenticator *credential /* [in] [ref] */,
struct netr_Authenticator *return_authenticator /* [in,out] [ref] */,
- uint8_t *change_log_entry /* [in] [ref,size_is(change_log_entry_size)] */,
- uint32_t change_log_entry_size /* [in] */,
+ struct netr_ChangeLogEntry change_log_entry /* [in] [subcontext_size(change_log_entry_size),subcontext(4)] */,
+ uint32_t change_log_entry_size /* [in] [value(ndr_size_netr_ChangeLogEntry(&change_log_entry,ndr->flags))] */,
struct netr_DELTA_ENUM_ARRAY **delta_enum_array /* [out] [ref] */)
{
struct netr_DatabaseRedo r;
diff --git a/source3/librpc/gen_ndr/cli_netlogon.h b/source3/librpc/gen_ndr/cli_netlogon.h
index 5adf8e8cad..9f5eac15b2 100644
--- a/source3/librpc/gen_ndr/cli_netlogon.h
+++ b/source3/librpc/gen_ndr/cli_netlogon.h
@@ -158,8 +158,8 @@ NTSTATUS rpccli_netr_DatabaseRedo(struct rpc_pipe_client *cli,
const char *computername /* [in] [charset(UTF16)] */,
struct netr_Authenticator *credential /* [in] [ref] */,
struct netr_Authenticator *return_authenticator /* [in,out] [ref] */,
- uint8_t *change_log_entry /* [in] [ref,size_is(change_log_entry_size)] */,
- uint32_t change_log_entry_size /* [in] */,
+ struct netr_ChangeLogEntry change_log_entry /* [in] [subcontext_size(change_log_entry_size),subcontext(4)] */,
+ uint32_t change_log_entry_size /* [in] [value(ndr_size_netr_ChangeLogEntry(&change_log_entry,ndr->flags))] */,
struct netr_DELTA_ENUM_ARRAY **delta_enum_array /* [out] [ref] */);
NTSTATUS rpccli_netr_LogonControl2Ex(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
diff --git a/source3/librpc/gen_ndr/cli_ntsvcs.c b/source3/librpc/gen_ndr/cli_ntsvcs.c
index f8ef7a99ad..0f97970e0b 100644
--- a/source3/librpc/gen_ndr/cli_ntsvcs.c
+++ b/source3/librpc/gen_ndr/cli_ntsvcs.c
@@ -564,7 +564,7 @@ NTSTATUS rpccli_PNP_GetDeviceRegProp(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
const char *devicepath /* [in] [ref,charset(UTF16)] */,
uint32_t property /* [in] */,
- uint32_t *reg_data_type /* [in,out] [ref] */,
+ enum winreg_Type *reg_data_type /* [in,out] [ref] */,
uint8_t *buffer /* [out] [ref,length_is(*buffer_size),size_is(*buffer_size)] */,
uint32_t *buffer_size /* [in,out] [ref] */,
uint32_t *needed /* [in,out] [ref] */,
@@ -1686,29 +1686,29 @@ NTSTATUS rpccli_PNP_RequestEjectPC(struct rpc_pipe_client *cli,
NTSTATUS rpccli_PNP_HwProfFlags(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
- uint32_t unknown1 /* [in] */,
+ uint32_t action /* [in] */,
const char *devicepath /* [in] [ref,charset(UTF16)] */,
- uint32_t unknown2 /* [in] */,
- uint32_t *unknown3 /* [in,out] [ref] */,
- uint16_t *unknown4 /* [in,out] [unique] */,
+ uint32_t config /* [in] */,
+ uint32_t *profile_flags /* [in,out] [ref] */,
+ uint16_t *veto_type /* [in,out] [unique] */,
const char *unknown5 /* [in] [unique,charset(UTF16)] */,
const char **unknown5a /* [out] [unique,charset(UTF16)] */,
- uint32_t unknown6 /* [in] */,
- uint32_t unknown7 /* [in] */,
+ uint32_t name_length /* [in] */,
+ uint32_t flags /* [in] */,
WERROR *werror)
{
struct PNP_HwProfFlags r;
NTSTATUS status;
/* In parameters */
- r.in.unknown1 = unknown1;
+ r.in.action = action;
r.in.devicepath = devicepath;
- r.in.unknown2 = unknown2;
- r.in.unknown3 = unknown3;
- r.in.unknown4 = unknown4;
+ r.in.config = config;
+ r.in.profile_flags = profile_flags;
+ r.in.veto_type = veto_type;
r.in.unknown5 = unknown5;
- r.in.unknown6 = unknown6;
- r.in.unknown7 = unknown7;
+ r.in.name_length = name_length;
+ r.in.flags = flags;
if (DEBUGLEVEL >= 10) {
NDR_PRINT_IN_DEBUG(PNP_HwProfFlags, &r);
@@ -1733,9 +1733,9 @@ NTSTATUS rpccli_PNP_HwProfFlags(struct rpc_pipe_client *cli,
}
/* Return variables */
- *unknown3 = *r.out.unknown3;
- if (unknown4 && r.out.unknown4) {
- *unknown4 = *r.out.unknown4;
+ *profile_flags = *r.out.profile_flags;
+ if (veto_type && r.out.veto_type) {
+ *veto_type = *r.out.veto_type;
}
if (unknown5a && r.out.unknown5a) {
*unknown5a = *r.out.unknown5a;
@@ -1753,8 +1753,8 @@ NTSTATUS rpccli_PNP_GetHwProfInfo(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
uint32_t idx /* [in] */,
struct PNP_HwProfInfo *info /* [in,out] [ref] */,
- uint32_t unknown1 /* [in] */,
- uint32_t unknown2 /* [in] */,
+ uint32_t size /* [in] */,
+ uint32_t flags /* [in] */,
WERROR *werror)
{
struct PNP_GetHwProfInfo r;
@@ -1763,8 +1763,8 @@ NTSTATUS rpccli_PNP_GetHwProfInfo(struct rpc_pipe_client *cli,
/* In parameters */
r.in.idx = idx;
r.in.info = info;
- r.in.unknown1 = unknown1;
- r.in.unknown2 = unknown2;
+ r.in.size = size;
+ r.in.flags = flags;
if (DEBUGLEVEL >= 10) {
NDR_PRINT_IN_DEBUG(PNP_GetHwProfInfo, &r);
diff --git a/source3/librpc/gen_ndr/cli_ntsvcs.h b/source3/librpc/gen_ndr/cli_ntsvcs.h
index 4ed8a401ec..fc4a9f4a71 100644
--- a/source3/librpc/gen_ndr/cli_ntsvcs.h
+++ b/source3/librpc/gen_ndr/cli_ntsvcs.h
@@ -54,7 +54,7 @@ NTSTATUS rpccli_PNP_GetDeviceRegProp(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
const char *devicepath /* [in] [ref,charset(UTF16)] */,
uint32_t property /* [in] */,
- uint32_t *reg_data_type /* [in,out] [ref] */,
+ enum winreg_Type *reg_data_type /* [in,out] [ref] */,
uint8_t *buffer /* [out] [ref,length_is(*buffer_size),size_is(*buffer_size)] */,
uint32_t *buffer_size /* [in,out] [ref] */,
uint32_t *needed /* [in,out] [ref] */,
@@ -140,22 +140,22 @@ NTSTATUS rpccli_PNP_RequestEjectPC(struct rpc_pipe_client *cli,
WERROR *werror);
NTSTATUS rpccli_PNP_HwProfFlags(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
- uint32_t unknown1 /* [in] */,
+ uint32_t action /* [in] */,
const char *devicepath /* [in] [ref,charset(UTF16)] */,
- uint32_t unknown2 /* [in] */,
- uint32_t *unknown3 /* [in,out] [ref] */,
- uint16_t *unknown4 /* [in,out] [unique] */,
+ uint32_t config /* [in] */,
+ uint32_t *profile_flags /* [in,out] [ref] */,
+ uint16_t *veto_type /* [in,out] [unique] */,
const char *unknown5 /* [in] [unique,charset(UTF16)] */,
const char **unknown5a /* [out] [unique,charset(UTF16)] */,
- uint32_t unknown6 /* [in] */,
- uint32_t unknown7 /* [in] */,
+ uint32_t name_length /* [in] */,
+ uint32_t flags /* [in] */,
WERROR *werror);
NTSTATUS rpccli_PNP_GetHwProfInfo(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
uint32_t idx /* [in] */,
struct PNP_HwProfInfo *info /* [in,out] [ref] */,
- uint32_t unknown1 /* [in] */,
- uint32_t unknown2 /* [in] */,
+ uint32_t size /* [in] */,
+ uint32_t flags /* [in] */,
WERROR *werror);
NTSTATUS rpccli_PNP_AddEmptyLogConf(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
diff --git a/source3/librpc/gen_ndr/cli_samr.c b/source3/librpc/gen_ndr/cli_samr.c
index 179bd0007f..7edb790286 100644
--- a/source3/librpc/gen_ndr/cli_samr.c
+++ b/source3/librpc/gen_ndr/cli_samr.c
@@ -2838,7 +2838,7 @@ NTSTATUS rpccli_samr_RidToSid(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
struct policy_handle *domain_handle /* [in] [ref] */,
uint32_t rid /* [in] */,
- struct dom_sid2 *sid /* [out] [ref] */)
+ struct dom_sid2 **sid /* [out] [ref] */)
{
struct samr_RidToSid r;
NTSTATUS status;
diff --git a/source3/librpc/gen_ndr/cli_samr.h b/source3/librpc/gen_ndr/cli_samr.h
index 7216d0cf3d..b57d63334e 100644
--- a/source3/librpc/gen_ndr/cli_samr.h
+++ b/source3/librpc/gen_ndr/cli_samr.h
@@ -375,7 +375,7 @@ NTSTATUS rpccli_samr_RidToSid(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
struct policy_handle *domain_handle /* [in] [ref] */,
uint32_t rid /* [in] */,
- struct dom_sid2 *sid /* [out] [ref] */);
+ struct dom_sid2 **sid /* [out] [ref] */);
NTSTATUS rpccli_samr_SetDsrmPassword(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
struct lsa_String *name /* [in] [unique] */,
diff --git a/source3/librpc/gen_ndr/cli_svcctl.c b/source3/librpc/gen_ndr/cli_svcctl.c
index e5fd4dac87..9f11a40d7e 100644
--- a/source3/librpc/gen_ndr/cli_svcctl.c
+++ b/source3/librpc/gen_ndr/cli_svcctl.c
@@ -53,7 +53,7 @@ NTSTATUS rpccli_svcctl_CloseServiceHandle(struct rpc_pipe_client *cli,
NTSTATUS rpccli_svcctl_ControlService(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
struct policy_handle *handle /* [in] [ref] */,
- uint32_t control /* [in] */,
+ enum SERVICE_CONTROL control /* [in] */,
struct SERVICE_STATUS *service_status /* [out] [ref] */,
WERROR *werror)
{
@@ -702,10 +702,10 @@ NTSTATUS rpccli_svcctl_EnumServicesStatusW(struct rpc_pipe_client *cli,
struct policy_handle *handle /* [in] [ref] */,
uint32_t type /* [in] */,
uint32_t state /* [in] */,
- uint32_t buf_size /* [in] */,
- uint8_t *service /* [out] [size_is(buf_size)] */,
- uint32_t *bytes_needed /* [out] [ref] */,
- uint32_t *services_returned /* [out] [ref] */,
+ uint8_t *service /* [out] [ref,size_is(buf_size)] */,
+ uint32_t buf_size /* [in] [range(0,262144)] */,
+ uint32_t *bytes_needed /* [out] [ref,range(0,262144)] */,
+ uint32_t *services_returned /* [out] [ref,range(0,262144)] */,
uint32_t *resume_handle /* [in,out] [unique] */,
WERROR *werror)
{
@@ -1976,9 +1976,9 @@ NTSTATUS rpccli_svcctl_QueryServiceConfig2W(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
struct policy_handle *handle /* [in] [ref] */,
uint32_t info_level /* [in] */,
- uint8_t *buffer /* [out] */,
- uint32_t buf_size /* [in] */,
- uint32_t *bytes_needed /* [out] [ref] */,
+ uint8_t *buffer /* [out] [ref,size_is(buf_size)] */,
+ uint32_t buf_size /* [in] [range(0,8192)] */,
+ uint32_t *bytes_needed /* [out] [ref,range(0,8192)] */,
WERROR *werror)
{
struct svcctl_QueryServiceConfig2W r;
@@ -2027,9 +2027,9 @@ NTSTATUS rpccli_svcctl_QueryServiceStatusEx(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
struct policy_handle *handle /* [in] [ref] */,
uint32_t info_level /* [in] */,
- uint8_t *buffer /* [out] */,
- uint32_t buf_size /* [in] */,
- uint32_t *bytes_needed /* [out] [ref] */,
+ uint8_t *buffer /* [out] [ref,size_is(buf_size)] */,
+ uint32_t buf_size /* [in] [range(0,8192)] */,
+ uint32_t *bytes_needed /* [out] [ref,range(0,8192)] */,
WERROR *werror)
{
struct svcctl_QueryServiceStatusEx r;
@@ -2144,12 +2144,12 @@ NTSTATUS rpccli_EnumServicesStatusExW(struct rpc_pipe_client *cli,
uint32_t info_level /* [in] */,
uint32_t type /* [in] */,
uint32_t state /* [in] */,
- uint8_t *services /* [out] */,
- uint32_t buf_size /* [in] */,
- uint32_t *bytes_needed /* [out] [ref] */,
- uint32_t *service_returned /* [out] [ref] */,
- uint32_t *resume_handle /* [in,out] [unique] */,
- const char **group_name /* [out] [ref,charset(UTF16)] */,
+ uint8_t *services /* [out] [ref,size_is(buf_size)] */,
+ uint32_t buf_size /* [in] [range(0,262144)] */,
+ uint32_t *bytes_needed /* [out] [ref,range(0,262144)] */,
+ uint32_t *service_returned /* [out] [ref,range(0,262144)] */,
+ uint32_t *resume_handle /* [in,out] [unique,range(0,262144)] */,
+ const char *group_name /* [in] [unique,charset(UTF16)] */,
WERROR *werror)
{
struct EnumServicesStatusExW r;
@@ -2162,6 +2162,7 @@ NTSTATUS rpccli_EnumServicesStatusExW(struct rpc_pipe_client *cli,
r.in.state = state;
r.in.buf_size = buf_size;
r.in.resume_handle = resume_handle;
+ r.in.group_name = group_name;
if (DEBUGLEVEL >= 10) {
NDR_PRINT_IN_DEBUG(EnumServicesStatusExW, &r);
@@ -2192,7 +2193,6 @@ NTSTATUS rpccli_EnumServicesStatusExW(struct rpc_pipe_client *cli,
if (resume_handle && r.out.resume_handle) {
*resume_handle = *r.out.resume_handle;
}
- *group_name = *r.out.group_name;
/* Return result */
if (werror) {
diff --git a/source3/librpc/gen_ndr/cli_svcctl.h b/source3/librpc/gen_ndr/cli_svcctl.h
index 02abbadf1e..78c9bf40d8 100644
--- a/source3/librpc/gen_ndr/cli_svcctl.h
+++ b/source3/librpc/gen_ndr/cli_svcctl.h
@@ -8,7 +8,7 @@ NTSTATUS rpccli_svcctl_CloseServiceHandle(struct rpc_pipe_client *cli,
NTSTATUS rpccli_svcctl_ControlService(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
struct policy_handle *handle /* [in] [ref] */,
- uint32_t control /* [in] */,
+ enum SERVICE_CONTROL control /* [in] */,
struct SERVICE_STATUS *service_status /* [out] [ref] */,
WERROR *werror);
NTSTATUS rpccli_svcctl_DeleteService(struct rpc_pipe_client *cli,
@@ -104,10 +104,10 @@ NTSTATUS rpccli_svcctl_EnumServicesStatusW(struct rpc_pipe_client *cli,
struct policy_handle *handle /* [in] [ref] */,
uint32_t type /* [in] */,
uint32_t state /* [in] */,
- uint32_t buf_size /* [in] */,
- uint8_t *service /* [out] [size_is(buf_size)] */,
- uint32_t *bytes_needed /* [out] [ref] */,
- uint32_t *services_returned /* [out] [ref] */,
+ uint8_t *service /* [out] [ref,size_is(buf_size)] */,
+ uint32_t buf_size /* [in] [range(0,262144)] */,
+ uint32_t *bytes_needed /* [out] [ref,range(0,262144)] */,
+ uint32_t *services_returned /* [out] [ref,range(0,262144)] */,
uint32_t *resume_handle /* [in,out] [unique] */,
WERROR *werror);
NTSTATUS rpccli_svcctl_OpenSCManagerW(struct rpc_pipe_client *cli,
@@ -292,17 +292,17 @@ NTSTATUS rpccli_svcctl_QueryServiceConfig2W(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
struct policy_handle *handle /* [in] [ref] */,
uint32_t info_level /* [in] */,
- uint8_t *buffer /* [out] */,
- uint32_t buf_size /* [in] */,
- uint32_t *bytes_needed /* [out] [ref] */,
+ uint8_t *buffer /* [out] [ref,size_is(buf_size)] */,
+ uint32_t buf_size /* [in] [range(0,8192)] */,
+ uint32_t *bytes_needed /* [out] [ref,range(0,8192)] */,
WERROR *werror);
NTSTATUS rpccli_svcctl_QueryServiceStatusEx(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
struct policy_handle *handle /* [in] [ref] */,
uint32_t info_level /* [in] */,
- uint8_t *buffer /* [out] */,
- uint32_t buf_size /* [in] */,
- uint32_t *bytes_needed /* [out] [ref] */,
+ uint8_t *buffer /* [out] [ref,size_is(buf_size)] */,
+ uint32_t buf_size /* [in] [range(0,8192)] */,
+ uint32_t *bytes_needed /* [out] [ref,range(0,8192)] */,
WERROR *werror);
NTSTATUS rpccli_EnumServicesStatusExA(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
@@ -323,12 +323,12 @@ NTSTATUS rpccli_EnumServicesStatusExW(struct rpc_pipe_client *cli,
uint32_t info_level /* [in] */,
uint32_t type /* [in] */,
uint32_t state /* [in] */,
- uint8_t *services /* [out] */,
- uint32_t buf_size /* [in] */,
- uint32_t *bytes_needed /* [out] [ref] */,
- uint32_t *service_returned /* [out] [ref] */,
- uint32_t *resume_handle /* [in,out] [unique] */,
- const char **group_name /* [out] [ref,charset(UTF16)] */,
+ uint8_t *services /* [out] [ref,size_is(buf_size)] */,
+ uint32_t buf_size /* [in] [range(0,262144)] */,
+ uint32_t *bytes_needed /* [out] [ref,range(0,262144)] */,
+ uint32_t *service_returned /* [out] [ref,range(0,262144)] */,
+ uint32_t *resume_handle /* [in,out] [unique,range(0,262144)] */,
+ const char *group_name /* [in] [unique,charset(UTF16)] */,
WERROR *werror);
NTSTATUS rpccli_svcctl_SCSendTSMessage(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
diff --git a/source3/librpc/gen_ndr/dom_sid.h b/source3/librpc/gen_ndr/dom_sid.h
new file mode 100644
index 0000000000..57dd16855a
--- /dev/null
+++ b/source3/librpc/gen_ndr/dom_sid.h
@@ -0,0 +1,15 @@
+/* header auto-generated by pidl */
+
+#include <stdint.h>
+
+#define dom_sid2 dom_sid
+#define dom_sid28 dom_sid
+#define dom_sid0 dom_sid
+#ifndef _HEADER_dom_sid
+#define _HEADER_dom_sid
+
+struct _dummy_domsid {
+ uint8_t dummy;
+};
+
+#endif /* _HEADER_dom_sid */
diff --git a/source3/librpc/gen_ndr/eventlog.h b/source3/librpc/gen_ndr/eventlog.h
index 0fd929dd99..76b9e863bb 100644
--- a/source3/librpc/gen_ndr/eventlog.h
+++ b/source3/librpc/gen_ndr/eventlog.h
@@ -131,8 +131,8 @@ struct eventlog_OpenEventLogW {
struct eventlog_OpenUnknown0 *unknown0;/* [unique] */
struct lsa_String *logname;/* [ref] */
struct lsa_String *servername;/* [ref] */
- uint32_t unknown2;
- uint32_t unknown3;
+ uint32_t major_version;
+ uint32_t minor_version;
} in;
struct {
diff --git a/source3/librpc/gen_ndr/misc.h b/source3/librpc/gen_ndr/misc.h
index b3740faf34..d1cf64e0eb 100644
--- a/source3/librpc/gen_ndr/misc.h
+++ b/source3/librpc/gen_ndr/misc.h
@@ -42,36 +42,4 @@ enum netr_SchannelType
#endif
;
-enum netr_SamDatabaseID
-#ifndef USE_UINT_ENUMS
- {
- SAM_DATABASE_DOMAIN=0,
- SAM_DATABASE_BUILTIN=1,
- SAM_DATABASE_PRIVS=2
-}
-#else
- { __donnot_use_enum_netr_SamDatabaseID=0x7FFFFFFF}
-#define SAM_DATABASE_DOMAIN ( 0 )
-#define SAM_DATABASE_BUILTIN ( 1 )
-#define SAM_DATABASE_PRIVS ( 2 )
-#endif
-;
-
-enum samr_RejectReason
-#ifndef USE_UINT_ENUMS
- {
- SAMR_REJECT_OTHER=0,
- SAMR_REJECT_TOO_SHORT=1,
- SAMR_REJECT_IN_HISTORY=2,
- SAMR_REJECT_COMPLEXITY=5
-}
-#else
- { __donnot_use_enum_samr_RejectReason=0x7FFFFFFF}
-#define SAMR_REJECT_OTHER ( 0 )
-#define SAMR_REJECT_TOO_SHORT ( 1 )
-#define SAMR_REJECT_IN_HISTORY ( 2 )
-#define SAMR_REJECT_COMPLEXITY ( 5 )
-#endif
-;
-
#endif /* _HEADER_misc */
diff --git a/source3/librpc/gen_ndr/named_pipe_auth.h b/source3/librpc/gen_ndr/named_pipe_auth.h
new file mode 100644
index 0000000000..5f4ba9afb1
--- /dev/null
+++ b/source3/librpc/gen_ndr/named_pipe_auth.h
@@ -0,0 +1,32 @@
+/* header auto-generated by pidl */
+
+#include <stdint.h>
+
+#include "librpc/gen_ndr/netlogon.h"
+#ifndef _HEADER_named_pipe_auth
+#define _HEADER_named_pipe_auth
+
+#define NAMED_PIPE_AUTH_MAGIC ( "NPAM" )
+union named_pipe_auth_req_info {
+ struct netr_SamInfo3 info1;/* [case] */
+}/* [switch_type(uint32)] */;
+
+struct named_pipe_auth_req {
+ uint32_t length;/* [value(ndr_size_named_pipe_auth_req(r,ndr->flags)-4),flag(LIBNDR_FLAG_BIGENDIAN)] */
+ const char *magic;/* [value(NAMED_PIPE_AUTH_MAGIC),charset(DOS)] */
+ uint32_t level;
+ union named_pipe_auth_req_info info;/* [switch_is(level)] */
+}/* [gensize,public] */;
+
+union named_pipe_auth_rep_info {
+}/* [switch_type(uint32)] */;
+
+struct named_pipe_auth_rep {
+ uint32_t length;/* [value(ndr_size_named_pipe_auth_rep(r,ndr->flags)-4),flag(LIBNDR_FLAG_BIGENDIAN)] */
+ const char *magic;/* [value(NAMED_PIPE_AUTH_MAGIC),charset(DOS)] */
+ uint32_t level;
+ union named_pipe_auth_rep_info info;/* [switch_is(level)] */
+ NTSTATUS status;
+}/* [gensize,public] */;
+
+#endif /* _HEADER_named_pipe_auth */
diff --git a/source3/librpc/gen_ndr/ndr_dom_sid.h b/source3/librpc/gen_ndr/ndr_dom_sid.h
new file mode 100644
index 0000000000..145ec1db46
--- /dev/null
+++ b/source3/librpc/gen_ndr/ndr_dom_sid.h
@@ -0,0 +1,10 @@
+/* header auto-generated by pidl */
+
+#include "librpc/ndr/libndr.h"
+#include "librpc/gen_ndr/dom_sid.h"
+
+#ifndef _HEADER_NDR_dom_sid
+#define _HEADER_NDR_dom_sid
+
+#define NDR_DOM_SID_CALL_COUNT (0)
+#endif /* _HEADER_NDR_dom_sid */
diff --git a/source3/librpc/gen_ndr/ndr_eventlog.c b/source3/librpc/gen_ndr/ndr_eventlog.c
index f0c7ee4d61..12fa9fcec4 100644
--- a/source3/librpc/gen_ndr/ndr_eventlog.c
+++ b/source3/librpc/gen_ndr/ndr_eventlog.c
@@ -5,6 +5,31 @@
#include "librpc/gen_ndr/ndr_lsa.h"
#include "librpc/gen_ndr/ndr_security.h"
+static enum ndr_err_code ndr_push_eventlogReadFlags(struct ndr_push *ndr, int ndr_flags, uint32_t r)
+{
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
+ return NDR_ERR_SUCCESS;
+}
+
+static enum ndr_err_code ndr_pull_eventlogReadFlags(struct ndr_pull *ndr, int ndr_flags, uint32_t *r)
+{
+ uint32_t v;
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
+ *r = v;
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_eventlogReadFlags(struct ndr_print *ndr, const char *name, uint32_t r)
+{
+ ndr_print_uint32(ndr, name, r);
+ ndr->depth++;
+ ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "EVENTLOG_SEQUENTIAL_READ", EVENTLOG_SEQUENTIAL_READ, r);
+ ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "EVENTLOG_SEEK_READ", EVENTLOG_SEEK_READ, r);
+ ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "EVENTLOG_FORWARDS_READ", EVENTLOG_FORWARDS_READ, r);
+ ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "EVENTLOG_BACKWARDS_READ", EVENTLOG_BACKWARDS_READ, r);
+ ndr->depth--;
+}
+
static enum ndr_err_code ndr_push_eventlog_OpenUnknown0(struct ndr_push *ndr, int ndr_flags, const struct eventlog_OpenUnknown0 *r)
{
if (ndr_flags & NDR_SCALARS) {
@@ -635,8 +660,8 @@ static enum ndr_err_code ndr_push_eventlog_OpenEventLogW(struct ndr_push *ndr, i
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.servername));
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.unknown2));
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.unknown3));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.major_version));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.minor_version));
}
if (flags & NDR_OUT) {
if (r->out.handle == NULL) {
@@ -684,8 +709,8 @@ static enum ndr_err_code ndr_pull_eventlog_OpenEventLogW(struct ndr_pull *ndr, i
NDR_PULL_SET_MEM_CTX(ndr, r->in.servername, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.servername));
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_servername_0, LIBNDR_FLAG_REF_ALLOC);
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown2));
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown3));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.major_version));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.minor_version));
NDR_PULL_ALLOC(ndr, r->out.handle);
ZERO_STRUCTP(r->out.handle);
}
@@ -726,8 +751,8 @@ _PUBLIC_ void ndr_print_eventlog_OpenEventLogW(struct ndr_print *ndr, const char
ndr->depth++;
ndr_print_lsa_String(ndr, "servername", r->in.servername);
ndr->depth--;
- ndr_print_uint32(ndr, "unknown2", r->in.unknown2);
- ndr_print_uint32(ndr, "unknown3", r->in.unknown3);
+ ndr_print_uint32(ndr, "major_version", r->in.major_version);
+ ndr_print_uint32(ndr, "minor_version", r->in.minor_version);
ndr->depth--;
}
if (flags & NDR_OUT) {
@@ -832,7 +857,7 @@ static enum ndr_err_code ndr_push_eventlog_ReadEventLogW(struct ndr_push *ndr, i
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
}
NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->in.handle));
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.flags));
+ NDR_CHECK(ndr_push_eventlogReadFlags(ndr, NDR_SCALARS, r->in.flags));
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.offset));
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.number_of_bytes));
}
@@ -870,7 +895,7 @@ static enum ndr_err_code ndr_pull_eventlog_ReadEventLogW(struct ndr_pull *ndr, i
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);
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.flags));
+ NDR_CHECK(ndr_pull_eventlogReadFlags(ndr, NDR_SCALARS, &r->in.flags));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.offset));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.number_of_bytes));
if (r->in.number_of_bytes < 0 || r->in.number_of_bytes > 0x7FFFF) {
@@ -925,7 +950,7 @@ _PUBLIC_ void ndr_print_eventlog_ReadEventLogW(struct ndr_print *ndr, const char
ndr->depth++;
ndr_print_policy_handle(ndr, "handle", r->in.handle);
ndr->depth--;
- ndr_print_uint32(ndr, "flags", r->in.flags);
+ ndr_print_eventlogReadFlags(ndr, "flags", r->in.flags);
ndr_print_uint32(ndr, "offset", r->in.offset);
ndr_print_uint32(ndr, "number_of_bytes", r->in.number_of_bytes);
ndr->depth--;
diff --git a/source3/librpc/gen_ndr/ndr_eventlog.h b/source3/librpc/gen_ndr/ndr_eventlog.h
index 6c6e679eca..6002f35a7d 100644
--- a/source3/librpc/gen_ndr/ndr_eventlog.h
+++ b/source3/librpc/gen_ndr/ndr_eventlog.h
@@ -60,6 +60,7 @@ extern const struct ndr_interface_table ndr_table_eventlog;
#define NDR_EVENTLOG_FLUSHEVENTLOG (0x17)
#define NDR_EVENTLOG_CALL_COUNT (24)
+void ndr_print_eventlogReadFlags(struct ndr_print *ndr, const char *name, uint32_t r);
void ndr_print_eventlog_OpenUnknown0(struct ndr_print *ndr, const char *name, const struct eventlog_OpenUnknown0 *r);
enum ndr_err_code ndr_push_eventlog_Record(struct ndr_push *ndr, int ndr_flags, const struct eventlog_Record *r);
enum ndr_err_code ndr_pull_eventlog_Record(struct ndr_pull *ndr, int ndr_flags, struct eventlog_Record *r);
diff --git a/source3/librpc/gen_ndr/ndr_misc.c b/source3/librpc/gen_ndr/ndr_misc.c
index 22c416a0d7..971cbdac24 100644
--- a/source3/librpc/gen_ndr/ndr_misc.c
+++ b/source3/librpc/gen_ndr/ndr_misc.c
@@ -132,56 +132,3 @@ _PUBLIC_ void ndr_print_netr_SchannelType(struct ndr_print *ndr, const char *nam
ndr_print_enum(ndr, name, "ENUM", val, r);
}
-_PUBLIC_ enum ndr_err_code ndr_push_netr_SamDatabaseID(struct ndr_push *ndr, int ndr_flags, enum netr_SamDatabaseID r)
-{
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
- return NDR_ERR_SUCCESS;
-}
-
-_PUBLIC_ enum ndr_err_code ndr_pull_netr_SamDatabaseID(struct ndr_pull *ndr, int ndr_flags, enum netr_SamDatabaseID *r)
-{
- uint32_t v;
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
- *r = v;
- return NDR_ERR_SUCCESS;
-}
-
-_PUBLIC_ void ndr_print_netr_SamDatabaseID(struct ndr_print *ndr, const char *name, enum netr_SamDatabaseID r)
-{
- const char *val = NULL;
-
- switch (r) {
- case SAM_DATABASE_DOMAIN: val = "SAM_DATABASE_DOMAIN"; break;
- case SAM_DATABASE_BUILTIN: val = "SAM_DATABASE_BUILTIN"; break;
- case SAM_DATABASE_PRIVS: val = "SAM_DATABASE_PRIVS"; break;
- }
- ndr_print_enum(ndr, name, "ENUM", val, r);
-}
-
-_PUBLIC_ enum ndr_err_code ndr_push_samr_RejectReason(struct ndr_push *ndr, int ndr_flags, enum samr_RejectReason r)
-{
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
- return NDR_ERR_SUCCESS;
-}
-
-_PUBLIC_ enum ndr_err_code ndr_pull_samr_RejectReason(struct ndr_pull *ndr, int ndr_flags, enum samr_RejectReason *r)
-{
- uint32_t v;
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
- *r = v;
- return NDR_ERR_SUCCESS;
-}
-
-_PUBLIC_ void ndr_print_samr_RejectReason(struct ndr_print *ndr, const char *name, enum samr_RejectReason r)
-{
- const char *val = NULL;
-
- switch (r) {
- case SAMR_REJECT_OTHER: val = "SAMR_REJECT_OTHER"; break;
- case SAMR_REJECT_TOO_SHORT: val = "SAMR_REJECT_TOO_SHORT"; break;
- case SAMR_REJECT_IN_HISTORY: val = "SAMR_REJECT_IN_HISTORY"; break;
- case SAMR_REJECT_COMPLEXITY: val = "SAMR_REJECT_COMPLEXITY"; break;
- }
- ndr_print_enum(ndr, name, "ENUM", val, r);
-}
-
diff --git a/source3/librpc/gen_ndr/ndr_misc.h b/source3/librpc/gen_ndr/ndr_misc.h
index a15a781367..b907af0605 100644
--- a/source3/librpc/gen_ndr/ndr_misc.h
+++ b/source3/librpc/gen_ndr/ndr_misc.h
@@ -20,10 +20,4 @@ void ndr_print_policy_handle(struct ndr_print *ndr, const char *name, const stru
enum ndr_err_code ndr_push_netr_SchannelType(struct ndr_push *ndr, int ndr_flags, enum netr_SchannelType r);
enum ndr_err_code ndr_pull_netr_SchannelType(struct ndr_pull *ndr, int ndr_flags, enum netr_SchannelType *r);
void ndr_print_netr_SchannelType(struct ndr_print *ndr, const char *name, enum netr_SchannelType r);
-enum ndr_err_code ndr_push_netr_SamDatabaseID(struct ndr_push *ndr, int ndr_flags, enum netr_SamDatabaseID r);
-enum ndr_err_code ndr_pull_netr_SamDatabaseID(struct ndr_pull *ndr, int ndr_flags, enum netr_SamDatabaseID *r);
-void ndr_print_netr_SamDatabaseID(struct ndr_print *ndr, const char *name, enum netr_SamDatabaseID r);
-enum ndr_err_code ndr_push_samr_RejectReason(struct ndr_push *ndr, int ndr_flags, enum samr_RejectReason r);
-enum ndr_err_code ndr_pull_samr_RejectReason(struct ndr_pull *ndr, int ndr_flags, enum samr_RejectReason *r);
-void ndr_print_samr_RejectReason(struct ndr_print *ndr, const char *name, enum samr_RejectReason r);
#endif /* _HEADER_NDR_misc */
diff --git a/source3/librpc/gen_ndr/ndr_named_pipe_auth.c b/source3/librpc/gen_ndr/ndr_named_pipe_auth.c
new file mode 100644
index 0000000000..69412bf427
--- /dev/null
+++ b/source3/librpc/gen_ndr/ndr_named_pipe_auth.c
@@ -0,0 +1,302 @@
+/* parser auto-generated by pidl */
+
+#include "includes.h"
+#include "librpc/gen_ndr/ndr_named_pipe_auth.h"
+
+#include "librpc/gen_ndr/ndr_netlogon.h"
+static enum ndr_err_code ndr_push_named_pipe_auth_req_info(struct ndr_push *ndr, int ndr_flags, const union named_pipe_auth_req_info *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ int level = ndr_push_get_switch_value(ndr, r);
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, level));
+ switch (level) {
+ case 0: {
+ break; }
+
+ case 1: {
+ NDR_CHECK(ndr_push_netr_SamInfo3(ndr, NDR_SCALARS, &r->info1));
+ break; }
+
+ default:
+ return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level);
+ }
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ int level = ndr_push_get_switch_value(ndr, r);
+ switch (level) {
+ case 0:
+ break;
+
+ case 1:
+ NDR_CHECK(ndr_push_netr_SamInfo3(ndr, NDR_BUFFERS, &r->info1));
+ break;
+
+ default:
+ return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level);
+ }
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+static enum ndr_err_code ndr_pull_named_pipe_auth_req_info(struct ndr_pull *ndr, int ndr_flags, union named_pipe_auth_req_info *r)
+{
+ int level;
+ uint32_t _level;
+ level = ndr_pull_get_switch_value(ndr, r);
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &_level));
+ if (_level != level) {
+ return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u for r", _level);
+ }
+ switch (level) {
+ case 0: {
+ break; }
+
+ case 1: {
+ NDR_CHECK(ndr_pull_netr_SamInfo3(ndr, NDR_SCALARS, &r->info1));
+ break; }
+
+ default:
+ return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level);
+ }
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ switch (level) {
+ case 0:
+ break;
+
+ case 1:
+ NDR_CHECK(ndr_pull_netr_SamInfo3(ndr, NDR_BUFFERS, &r->info1));
+ break;
+
+ default:
+ return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level);
+ }
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_named_pipe_auth_req_info(struct ndr_print *ndr, const char *name, const union named_pipe_auth_req_info *r)
+{
+ int level;
+ level = ndr_print_get_switch_value(ndr, r);
+ ndr_print_union(ndr, name, level, "named_pipe_auth_req_info");
+ switch (level) {
+ case 0:
+ break;
+
+ case 1:
+ ndr_print_netr_SamInfo3(ndr, "info1", &r->info1);
+ break;
+
+ default:
+ ndr_print_bad_level(ndr, name, level);
+ }
+}
+
+_PUBLIC_ enum ndr_err_code ndr_push_named_pipe_auth_req(struct ndr_push *ndr, int ndr_flags, const struct named_pipe_auth_req *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_push_align(ndr, 4));
+ {
+ uint32_t _flags_save_uint32 = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_BIGENDIAN);
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_size_named_pipe_auth_req(r, ndr->flags) - 4));
+ ndr->flags = _flags_save_uint32;
+ }
+ NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, NAMED_PIPE_AUTH_MAGIC, 4, sizeof(uint8_t), CH_DOS));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->level));
+ NDR_CHECK(ndr_push_set_switch_value(ndr, &r->info, r->level));
+ NDR_CHECK(ndr_push_named_pipe_auth_req_info(ndr, NDR_SCALARS, &r->info));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ NDR_CHECK(ndr_push_named_pipe_auth_req_info(ndr, NDR_BUFFERS, &r->info));
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_pull_named_pipe_auth_req(struct ndr_pull *ndr, int ndr_flags, struct named_pipe_auth_req *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_pull_align(ndr, 4));
+ {
+ uint32_t _flags_save_uint32 = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_BIGENDIAN);
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->length));
+ ndr->flags = _flags_save_uint32;
+ }
+ NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->magic, 4, sizeof(uint8_t), CH_DOS));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->level));
+ NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->info, r->level));
+ NDR_CHECK(ndr_pull_named_pipe_auth_req_info(ndr, NDR_SCALARS, &r->info));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ NDR_CHECK(ndr_pull_named_pipe_auth_req_info(ndr, NDR_BUFFERS, &r->info));
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_named_pipe_auth_req(struct ndr_print *ndr, const char *name, const struct named_pipe_auth_req *r)
+{
+ ndr_print_struct(ndr, name, "named_pipe_auth_req");
+ ndr->depth++;
+ ndr_print_uint32(ndr, "length", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?ndr_size_named_pipe_auth_req(r, ndr->flags) - 4:r->length);
+ ndr_print_string(ndr, "magic", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?NAMED_PIPE_AUTH_MAGIC:r->magic);
+ ndr_print_uint32(ndr, "level", r->level);
+ ndr_print_set_switch_value(ndr, &r->info, r->level);
+ ndr_print_named_pipe_auth_req_info(ndr, "info", &r->info);
+ ndr->depth--;
+}
+
+_PUBLIC_ size_t ndr_size_named_pipe_auth_req(const struct named_pipe_auth_req *r, int flags)
+{
+ return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_named_pipe_auth_req);
+}
+
+static enum ndr_err_code ndr_push_named_pipe_auth_rep_info(struct ndr_push *ndr, int ndr_flags, const union named_pipe_auth_rep_info *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ int level = ndr_push_get_switch_value(ndr, r);
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, level));
+ switch (level) {
+ case 0: {
+ break; }
+
+ case 1: {
+ break; }
+
+ default:
+ return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level);
+ }
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ int level = ndr_push_get_switch_value(ndr, r);
+ switch (level) {
+ case 0:
+ break;
+
+ case 1:
+ break;
+
+ default:
+ return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level);
+ }
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+static enum ndr_err_code ndr_pull_named_pipe_auth_rep_info(struct ndr_pull *ndr, int ndr_flags, union named_pipe_auth_rep_info *r)
+{
+ int level;
+ uint32_t _level;
+ level = ndr_pull_get_switch_value(ndr, r);
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &_level));
+ if (_level != level) {
+ return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u for r", _level);
+ }
+ switch (level) {
+ case 0: {
+ break; }
+
+ case 1: {
+ break; }
+
+ default:
+ return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level);
+ }
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ switch (level) {
+ case 0:
+ break;
+
+ case 1:
+ break;
+
+ default:
+ return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level);
+ }
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_named_pipe_auth_rep_info(struct ndr_print *ndr, const char *name, const union named_pipe_auth_rep_info *r)
+{
+ int level;
+ level = ndr_print_get_switch_value(ndr, r);
+ ndr_print_union(ndr, name, level, "named_pipe_auth_rep_info");
+ switch (level) {
+ case 0:
+ break;
+
+ case 1:
+ break;
+
+ default:
+ ndr_print_bad_level(ndr, name, level);
+ }
+}
+
+_PUBLIC_ enum ndr_err_code ndr_push_named_pipe_auth_rep(struct ndr_push *ndr, int ndr_flags, const struct named_pipe_auth_rep *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_push_align(ndr, 4));
+ {
+ uint32_t _flags_save_uint32 = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_BIGENDIAN);
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_size_named_pipe_auth_rep(r, ndr->flags) - 4));
+ ndr->flags = _flags_save_uint32;
+ }
+ NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, NAMED_PIPE_AUTH_MAGIC, 4, sizeof(uint8_t), CH_DOS));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->level));
+ NDR_CHECK(ndr_push_set_switch_value(ndr, &r->info, r->level));
+ NDR_CHECK(ndr_push_named_pipe_auth_rep_info(ndr, NDR_SCALARS, &r->info));
+ NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->status));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ NDR_CHECK(ndr_push_named_pipe_auth_rep_info(ndr, NDR_BUFFERS, &r->info));
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_pull_named_pipe_auth_rep(struct ndr_pull *ndr, int ndr_flags, struct named_pipe_auth_rep *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_pull_align(ndr, 4));
+ {
+ uint32_t _flags_save_uint32 = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_BIGENDIAN);
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->length));
+ ndr->flags = _flags_save_uint32;
+ }
+ NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->magic, 4, sizeof(uint8_t), CH_DOS));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->level));
+ NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->info, r->level));
+ NDR_CHECK(ndr_pull_named_pipe_auth_rep_info(ndr, NDR_SCALARS, &r->info));
+ NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->status));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ NDR_CHECK(ndr_pull_named_pipe_auth_rep_info(ndr, NDR_BUFFERS, &r->info));
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_named_pipe_auth_rep(struct ndr_print *ndr, const char *name, const struct named_pipe_auth_rep *r)
+{
+ ndr_print_struct(ndr, name, "named_pipe_auth_rep");
+ ndr->depth++;
+ ndr_print_uint32(ndr, "length", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?ndr_size_named_pipe_auth_rep(r, ndr->flags) - 4:r->length);
+ ndr_print_string(ndr, "magic", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?NAMED_PIPE_AUTH_MAGIC:r->magic);
+ ndr_print_uint32(ndr, "level", r->level);
+ ndr_print_set_switch_value(ndr, &r->info, r->level);
+ ndr_print_named_pipe_auth_rep_info(ndr, "info", &r->info);
+ ndr_print_NTSTATUS(ndr, "status", r->status);
+ ndr->depth--;
+}
+
+_PUBLIC_ size_t ndr_size_named_pipe_auth_rep(const struct named_pipe_auth_rep *r, int flags)
+{
+ return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_named_pipe_auth_rep);
+}
+
diff --git a/source3/librpc/gen_ndr/ndr_named_pipe_auth.h b/source3/librpc/gen_ndr/ndr_named_pipe_auth.h
new file mode 100644
index 0000000000..fbef9d5f1c
--- /dev/null
+++ b/source3/librpc/gen_ndr/ndr_named_pipe_auth.h
@@ -0,0 +1,20 @@
+/* header auto-generated by pidl */
+
+#include "librpc/ndr/libndr.h"
+#include "librpc/gen_ndr/named_pipe_auth.h"
+
+#ifndef _HEADER_NDR_named_pipe_auth
+#define _HEADER_NDR_named_pipe_auth
+
+#define NDR_NAMED_PIPE_AUTH_CALL_COUNT (0)
+void ndr_print_named_pipe_auth_req_info(struct ndr_print *ndr, const char *name, const union named_pipe_auth_req_info *r);
+enum ndr_err_code ndr_push_named_pipe_auth_req(struct ndr_push *ndr, int ndr_flags, const struct named_pipe_auth_req *r);
+enum ndr_err_code ndr_pull_named_pipe_auth_req(struct ndr_pull *ndr, int ndr_flags, struct named_pipe_auth_req *r);
+void ndr_print_named_pipe_auth_req(struct ndr_print *ndr, const char *name, const struct named_pipe_auth_req *r);
+size_t ndr_size_named_pipe_auth_req(const struct named_pipe_auth_req *r, int flags);
+void ndr_print_named_pipe_auth_rep_info(struct ndr_print *ndr, const char *name, const union named_pipe_auth_rep_info *r);
+enum ndr_err_code ndr_push_named_pipe_auth_rep(struct ndr_push *ndr, int ndr_flags, const struct named_pipe_auth_rep *r);
+enum ndr_err_code ndr_pull_named_pipe_auth_rep(struct ndr_pull *ndr, int ndr_flags, struct named_pipe_auth_rep *r);
+void ndr_print_named_pipe_auth_rep(struct ndr_print *ndr, const char *name, const struct named_pipe_auth_rep *r);
+size_t ndr_size_named_pipe_auth_rep(const struct named_pipe_auth_rep *r, int flags);
+#endif /* _HEADER_NDR_named_pipe_auth */
diff --git a/source3/librpc/gen_ndr/ndr_netlogon.c b/source3/librpc/gen_ndr/ndr_netlogon.c
index 12ab98e610..c4102eba6e 100644
--- a/source3/librpc/gen_ndr/ndr_netlogon.c
+++ b/source3/librpc/gen_ndr/ndr_netlogon.c
@@ -363,8 +363,6 @@ static enum ndr_err_code ndr_push_netr_PasswordInfo(struct ndr_push *ndr, int nd
}
if (ndr_flags & NDR_BUFFERS) {
NDR_CHECK(ndr_push_netr_IdentityInfo(ndr, NDR_BUFFERS, &r->identity_info));
- NDR_CHECK(ndr_push_samr_Password(ndr, NDR_BUFFERS, &r->lmpassword));
- NDR_CHECK(ndr_push_samr_Password(ndr, NDR_BUFFERS, &r->ntpassword));
}
return NDR_ERR_SUCCESS;
}
@@ -379,8 +377,6 @@ static enum ndr_err_code ndr_pull_netr_PasswordInfo(struct ndr_pull *ndr, int nd
}
if (ndr_flags & NDR_BUFFERS) {
NDR_CHECK(ndr_pull_netr_IdentityInfo(ndr, NDR_BUFFERS, &r->identity_info));
- NDR_CHECK(ndr_pull_samr_Password(ndr, NDR_BUFFERS, &r->lmpassword));
- NDR_CHECK(ndr_pull_samr_Password(ndr, NDR_BUFFERS, &r->ntpassword));
}
return NDR_ERR_SUCCESS;
}
@@ -2212,7 +2208,6 @@ static enum ndr_err_code ndr_push_netr_USER_KEY16(struct ndr_push *ndr, int ndr_
NDR_CHECK(ndr_push_samr_Password(ndr, NDR_SCALARS, &r->pwd));
}
if (ndr_flags & NDR_BUFFERS) {
- NDR_CHECK(ndr_push_samr_Password(ndr, NDR_BUFFERS, &r->pwd));
}
return NDR_ERR_SUCCESS;
}
@@ -2227,7 +2222,6 @@ static enum ndr_err_code ndr_pull_netr_USER_KEY16(struct ndr_pull *ndr, int ndr_
NDR_CHECK(ndr_pull_samr_Password(ndr, NDR_SCALARS, &r->pwd));
}
if (ndr_flags & NDR_BUFFERS) {
- NDR_CHECK(ndr_pull_samr_Password(ndr, NDR_BUFFERS, &r->pwd));
}
return NDR_ERR_SUCCESS;
}
@@ -2305,8 +2299,6 @@ static enum ndr_err_code ndr_push_netr_USER_KEYS2(struct ndr_push *ndr, int ndr_
NDR_CHECK(ndr_push_netr_PasswordHistory(ndr, NDR_SCALARS, &r->history));
}
if (ndr_flags & NDR_BUFFERS) {
- NDR_CHECK(ndr_push_netr_USER_KEY16(ndr, NDR_BUFFERS, &r->lmpassword));
- NDR_CHECK(ndr_push_netr_USER_KEY16(ndr, NDR_BUFFERS, &r->ntpassword));
}
return NDR_ERR_SUCCESS;
}
@@ -2320,8 +2312,6 @@ static enum ndr_err_code ndr_pull_netr_USER_KEYS2(struct ndr_pull *ndr, int ndr_
NDR_CHECK(ndr_pull_netr_PasswordHistory(ndr, NDR_SCALARS, &r->history));
}
if (ndr_flags & NDR_BUFFERS) {
- NDR_CHECK(ndr_pull_netr_USER_KEY16(ndr, NDR_BUFFERS, &r->lmpassword));
- NDR_CHECK(ndr_pull_netr_USER_KEY16(ndr, NDR_BUFFERS, &r->ntpassword));
}
return NDR_ERR_SUCCESS;
}
@@ -2343,7 +2333,6 @@ static enum ndr_err_code ndr_push_netr_USER_KEY_UNION(struct ndr_push *ndr, int
NDR_CHECK(ndr_push_netr_USER_KEYS2(ndr, NDR_SCALARS, &r->keys2));
}
if (ndr_flags & NDR_BUFFERS) {
- NDR_CHECK(ndr_push_netr_USER_KEYS2(ndr, NDR_BUFFERS, &r->keys2));
}
return NDR_ERR_SUCCESS;
}
@@ -2355,7 +2344,6 @@ static enum ndr_err_code ndr_pull_netr_USER_KEY_UNION(struct ndr_pull *ndr, int
NDR_CHECK(ndr_pull_netr_USER_KEYS2(ndr, NDR_SCALARS, &r->keys2));
}
if (ndr_flags & NDR_BUFFERS) {
- NDR_CHECK(ndr_pull_netr_USER_KEYS2(ndr, NDR_BUFFERS, &r->keys2));
}
return NDR_ERR_SUCCESS;
}
@@ -2376,7 +2364,6 @@ _PUBLIC_ enum ndr_err_code ndr_push_netr_USER_KEYS(struct ndr_push *ndr, int ndr
NDR_CHECK(ndr_push_netr_USER_KEY_UNION(ndr, NDR_SCALARS, &r->keys));
}
if (ndr_flags & NDR_BUFFERS) {
- NDR_CHECK(ndr_push_netr_USER_KEY_UNION(ndr, NDR_BUFFERS, &r->keys));
}
return NDR_ERR_SUCCESS;
}
@@ -2389,7 +2376,6 @@ _PUBLIC_ enum ndr_err_code ndr_pull_netr_USER_KEYS(struct ndr_pull *ndr, int ndr
NDR_CHECK(ndr_pull_netr_USER_KEY_UNION(ndr, NDR_SCALARS, &r->keys));
}
if (ndr_flags & NDR_BUFFERS) {
- NDR_CHECK(ndr_pull_netr_USER_KEY_UNION(ndr, NDR_BUFFERS, &r->keys));
}
return NDR_ERR_SUCCESS;
}
@@ -2513,7 +2499,7 @@ static enum ndr_err_code ndr_push_netr_DELTA_USER(struct ndr_push *ndr, int ndr_
NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->lm_password_present));
NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->password_expired));
NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS, &r->comment));
- NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS, &r->parameters));
+ NDR_CHECK(ndr_push_lsa_BinaryString(ndr, NDR_SCALARS, &r->parameters));
NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->country_code));
NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->code_page));
NDR_CHECK(ndr_push_netr_USER_PRIVATE_INFO(ndr, NDR_SCALARS, &r->user_private_info));
@@ -2537,10 +2523,8 @@ static enum ndr_err_code ndr_push_netr_DELTA_USER(struct ndr_push *ndr, int ndr_
NDR_CHECK(ndr_push_lsa_String(ndr, NDR_BUFFERS, &r->description));
NDR_CHECK(ndr_push_lsa_String(ndr, NDR_BUFFERS, &r->workstations));
NDR_CHECK(ndr_push_samr_LogonHours(ndr, NDR_BUFFERS, &r->logon_hours));
- NDR_CHECK(ndr_push_samr_Password(ndr, NDR_BUFFERS, &r->lmpassword));
- NDR_CHECK(ndr_push_samr_Password(ndr, NDR_BUFFERS, &r->ntpassword));
NDR_CHECK(ndr_push_lsa_String(ndr, NDR_BUFFERS, &r->comment));
- NDR_CHECK(ndr_push_lsa_String(ndr, NDR_BUFFERS, &r->parameters));
+ NDR_CHECK(ndr_push_lsa_BinaryString(ndr, NDR_BUFFERS, &r->parameters));
NDR_CHECK(ndr_push_netr_USER_PRIVATE_INFO(ndr, NDR_BUFFERS, &r->user_private_info));
NDR_CHECK(ndr_push_sec_desc_buf(ndr, NDR_BUFFERS, &r->sdbuf));
NDR_CHECK(ndr_push_lsa_String(ndr, NDR_BUFFERS, &r->profile_path));
@@ -2578,7 +2562,7 @@ static enum ndr_err_code ndr_pull_netr_DELTA_USER(struct ndr_pull *ndr, int ndr_
NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->lm_password_present));
NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->password_expired));
NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS, &r->comment));
- NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS, &r->parameters));
+ NDR_CHECK(ndr_pull_lsa_BinaryString(ndr, NDR_SCALARS, &r->parameters));
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->country_code));
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->code_page));
NDR_CHECK(ndr_pull_netr_USER_PRIVATE_INFO(ndr, NDR_SCALARS, &r->user_private_info));
@@ -2602,10 +2586,8 @@ static enum ndr_err_code ndr_pull_netr_DELTA_USER(struct ndr_pull *ndr, int ndr_
NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_BUFFERS, &r->description));
NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_BUFFERS, &r->workstations));
NDR_CHECK(ndr_pull_samr_LogonHours(ndr, NDR_BUFFERS, &r->logon_hours));
- NDR_CHECK(ndr_pull_samr_Password(ndr, NDR_BUFFERS, &r->lmpassword));
- NDR_CHECK(ndr_pull_samr_Password(ndr, NDR_BUFFERS, &r->ntpassword));
NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_BUFFERS, &r->comment));
- NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_BUFFERS, &r->parameters));
+ NDR_CHECK(ndr_pull_lsa_BinaryString(ndr, NDR_BUFFERS, &r->parameters));
NDR_CHECK(ndr_pull_netr_USER_PRIVATE_INFO(ndr, NDR_BUFFERS, &r->user_private_info));
NDR_CHECK(ndr_pull_sec_desc_buf(ndr, NDR_BUFFERS, &r->sdbuf));
NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_BUFFERS, &r->profile_path));
@@ -2643,7 +2625,7 @@ _PUBLIC_ void ndr_print_netr_DELTA_USER(struct ndr_print *ndr, const char *name,
ndr_print_uint8(ndr, "lm_password_present", r->lm_password_present);
ndr_print_uint8(ndr, "password_expired", r->password_expired);
ndr_print_lsa_String(ndr, "comment", &r->comment);
- ndr_print_lsa_String(ndr, "parameters", &r->parameters);
+ ndr_print_lsa_BinaryString(ndr, "parameters", &r->parameters);
ndr_print_uint16(ndr, "country_code", r->country_code);
ndr_print_uint16(ndr, "code_page", r->code_page);
ndr_print_netr_USER_PRIVATE_INFO(ndr, "user_private_info", &r->user_private_info);
@@ -6232,6 +6214,192 @@ _PUBLIC_ void ndr_print_netr_NegotiateFlags(struct ndr_print *ndr, const char *n
ndr->depth--;
}
+static enum ndr_err_code ndr_push_netr_ChangeLogFlags(struct ndr_push *ndr, int ndr_flags, uint16_t r)
+{
+ NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r));
+ return NDR_ERR_SUCCESS;
+}
+
+static enum ndr_err_code ndr_pull_netr_ChangeLogFlags(struct ndr_pull *ndr, int ndr_flags, uint16_t *r)
+{
+ uint16_t v;
+ NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &v));
+ *r = v;
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_netr_ChangeLogFlags(struct ndr_print *ndr, const char *name, uint16_t r)
+{
+ ndr_print_uint16(ndr, name, r);
+ ndr->depth++;
+ ndr_print_bitmap_flag(ndr, sizeof(uint16_t), "NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED", NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED, r);
+ ndr_print_bitmap_flag(ndr, sizeof(uint16_t), "NETR_CHANGELOG_CHANGED_PASSWORD", NETR_CHANGELOG_CHANGED_PASSWORD, r);
+ ndr_print_bitmap_flag(ndr, sizeof(uint16_t), "NETR_CHANGELOG_SID_INCLUDED", NETR_CHANGELOG_SID_INCLUDED, r);
+ ndr_print_bitmap_flag(ndr, sizeof(uint16_t), "NETR_CHANGELOG_NAME_INCLUDED", NETR_CHANGELOG_NAME_INCLUDED, r);
+ ndr_print_bitmap_flag(ndr, sizeof(uint16_t), "NETR_CHANGELOG_FIRST_PROMOTION_OBJ", NETR_CHANGELOG_FIRST_PROMOTION_OBJ, r);
+ ndr->depth--;
+}
+
+static enum ndr_err_code ndr_push_netr_ChangeLogObject(struct ndr_push *ndr, int ndr_flags, const union netr_ChangeLogObject *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ int level = ndr_push_get_switch_value(ndr, r);
+ switch (level) {
+ case NETR_CHANGELOG_SID_INCLUDED: {
+ NDR_CHECK(ndr_push_dom_sid(ndr, NDR_SCALARS, &r->object_sid));
+ break; }
+
+ case NETR_CHANGELOG_NAME_INCLUDED: {
+ {
+ uint32_t _flags_save_string = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
+ NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->object_name));
+ ndr->flags = _flags_save_string;
+ }
+ break; }
+
+ default: {
+ break; }
+
+ }
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ int level = ndr_push_get_switch_value(ndr, r);
+ switch (level) {
+ case NETR_CHANGELOG_SID_INCLUDED:
+ NDR_CHECK(ndr_push_dom_sid(ndr, NDR_BUFFERS, &r->object_sid));
+ break;
+
+ case NETR_CHANGELOG_NAME_INCLUDED:
+ break;
+
+ default:
+ break;
+
+ }
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+static enum ndr_err_code ndr_pull_netr_ChangeLogObject(struct ndr_pull *ndr, int ndr_flags, union netr_ChangeLogObject *r)
+{
+ int level;
+ level = ndr_pull_get_switch_value(ndr, r);
+ if (ndr_flags & NDR_SCALARS) {
+ switch (level) {
+ case NETR_CHANGELOG_SID_INCLUDED: {
+ NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, &r->object_sid));
+ break; }
+
+ case NETR_CHANGELOG_NAME_INCLUDED: {
+ {
+ uint32_t _flags_save_string = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
+ NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->object_name));
+ ndr->flags = _flags_save_string;
+ }
+ break; }
+
+ default: {
+ break; }
+
+ }
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ switch (level) {
+ case NETR_CHANGELOG_SID_INCLUDED:
+ NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_BUFFERS, &r->object_sid));
+ break;
+
+ case NETR_CHANGELOG_NAME_INCLUDED:
+ break;
+
+ default:
+ break;
+
+ }
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_netr_ChangeLogObject(struct ndr_print *ndr, const char *name, const union netr_ChangeLogObject *r)
+{
+ int level;
+ level = ndr_print_get_switch_value(ndr, r);
+ ndr_print_union(ndr, name, level, "netr_ChangeLogObject");
+ switch (level) {
+ case NETR_CHANGELOG_SID_INCLUDED:
+ ndr_print_dom_sid(ndr, "object_sid", &r->object_sid);
+ break;
+
+ case NETR_CHANGELOG_NAME_INCLUDED:
+ ndr_print_string(ndr, "object_name", r->object_name);
+ break;
+
+ default:
+ break;
+
+ }
+}
+
+_PUBLIC_ enum ndr_err_code ndr_push_netr_ChangeLogEntry(struct ndr_push *ndr, int ndr_flags, const struct netr_ChangeLogEntry *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_push_align(ndr, 4));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->serial_number1));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->serial_number2));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->object_rid));
+ NDR_CHECK(ndr_push_netr_ChangeLogFlags(ndr, NDR_SCALARS, r->flags));
+ NDR_CHECK(ndr_push_netr_SamDatabaseID8Bit(ndr, NDR_SCALARS, r->db_index));
+ NDR_CHECK(ndr_push_netr_DeltaEnum8Bit(ndr, NDR_SCALARS, r->delta_type));
+ NDR_CHECK(ndr_push_set_switch_value(ndr, &r->object, r->flags & (NETR_CHANGELOG_SID_INCLUDED | NETR_CHANGELOG_NAME_INCLUDED)));
+ NDR_CHECK(ndr_push_netr_ChangeLogObject(ndr, NDR_SCALARS, &r->object));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ NDR_CHECK(ndr_push_netr_ChangeLogObject(ndr, NDR_BUFFERS, &r->object));
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_pull_netr_ChangeLogEntry(struct ndr_pull *ndr, int ndr_flags, struct netr_ChangeLogEntry *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_pull_align(ndr, 4));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->serial_number1));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->serial_number2));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->object_rid));
+ NDR_CHECK(ndr_pull_netr_ChangeLogFlags(ndr, NDR_SCALARS, &r->flags));
+ NDR_CHECK(ndr_pull_netr_SamDatabaseID8Bit(ndr, NDR_SCALARS, &r->db_index));
+ NDR_CHECK(ndr_pull_netr_DeltaEnum8Bit(ndr, NDR_SCALARS, &r->delta_type));
+ NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->object, r->flags & (NETR_CHANGELOG_SID_INCLUDED | NETR_CHANGELOG_NAME_INCLUDED)));
+ NDR_CHECK(ndr_pull_netr_ChangeLogObject(ndr, NDR_SCALARS, &r->object));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ NDR_CHECK(ndr_pull_netr_ChangeLogObject(ndr, NDR_BUFFERS, &r->object));
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_netr_ChangeLogEntry(struct ndr_print *ndr, const char *name, const struct netr_ChangeLogEntry *r)
+{
+ ndr_print_struct(ndr, name, "netr_ChangeLogEntry");
+ ndr->depth++;
+ ndr_print_uint32(ndr, "serial_number1", r->serial_number1);
+ ndr_print_uint32(ndr, "serial_number2", r->serial_number2);
+ ndr_print_uint32(ndr, "object_rid", r->object_rid);
+ ndr_print_netr_ChangeLogFlags(ndr, "flags", r->flags);
+ ndr_print_netr_SamDatabaseID8Bit(ndr, "db_index", r->db_index);
+ ndr_print_netr_DeltaEnum8Bit(ndr, "delta_type", r->delta_type);
+ ndr_print_set_switch_value(ndr, &r->object, r->flags & (NETR_CHANGELOG_SID_INCLUDED | NETR_CHANGELOG_NAME_INCLUDED));
+ ndr_print_netr_ChangeLogObject(ndr, "object", &r->object);
+ ndr->depth--;
+}
+
+_PUBLIC_ size_t ndr_size_netr_ChangeLogEntry(const struct netr_ChangeLogEntry *r, int flags)
+{
+ return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_netr_ChangeLogEntry);
+}
+
static enum ndr_err_code ndr_push_netr_Blob(struct ndr_push *ndr, int ndr_flags, const struct netr_Blob *r)
{
if (ndr_flags & NDR_SCALARS) {
@@ -9422,7 +9590,7 @@ static enum ndr_err_code ndr_push_netr_ServerPasswordSet(struct ndr_push *ndr, i
if (r->in.new_password == NULL) {
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
}
- NDR_CHECK(ndr_push_samr_Password(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.new_password));
+ NDR_CHECK(ndr_push_samr_Password(ndr, NDR_SCALARS, r->in.new_password));
}
if (flags & NDR_OUT) {
if (r->out.return_authenticator == NULL) {
@@ -9489,7 +9657,7 @@ static enum ndr_err_code ndr_pull_netr_ServerPasswordSet(struct ndr_pull *ndr, i
}
_mem_save_new_password_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->in.new_password, LIBNDR_FLAG_REF_ALLOC);
- NDR_CHECK(ndr_pull_samr_Password(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.new_password));
+ NDR_CHECK(ndr_pull_samr_Password(ndr, NDR_SCALARS, r->in.new_password));
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_new_password_0, LIBNDR_FLAG_REF_ALLOC);
NDR_PULL_ALLOC(ndr, r->out.return_authenticator);
ZERO_STRUCTP(r->out.return_authenticator);
@@ -11307,12 +11475,13 @@ static enum ndr_err_code ndr_push_netr_DatabaseRedo(struct ndr_push *ndr, int fl
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
}
NDR_CHECK(ndr_push_netr_Authenticator(ndr, NDR_SCALARS, r->in.return_authenticator));
- if (r->in.change_log_entry == NULL) {
- return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ {
+ struct ndr_push *_ndr_change_log_entry;
+ NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_change_log_entry, 4, ndr_size_netr_ChangeLogEntry(&r->in.change_log_entry, ndr->flags)));
+ NDR_CHECK(ndr_push_netr_ChangeLogEntry(_ndr_change_log_entry, NDR_SCALARS|NDR_BUFFERS, &r->in.change_log_entry));
+ NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_change_log_entry, 4, ndr_size_netr_ChangeLogEntry(&r->in.change_log_entry, ndr->flags)));
}
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.change_log_entry_size));
- NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->in.change_log_entry, r->in.change_log_entry_size));
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.change_log_entry_size));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_size_netr_ChangeLogEntry(&r->in.change_log_entry, ndr->flags)));
}
if (flags & NDR_OUT) {
if (r->out.return_authenticator == NULL) {
@@ -11369,19 +11538,17 @@ static enum ndr_err_code ndr_pull_netr_DatabaseRedo(struct ndr_pull *ndr, int fl
NDR_PULL_SET_MEM_CTX(ndr, r->in.return_authenticator, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_netr_Authenticator(ndr, NDR_SCALARS, r->in.return_authenticator));
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_return_authenticator_0, LIBNDR_FLAG_REF_ALLOC);
- NDR_CHECK(ndr_pull_array_size(ndr, &r->in.change_log_entry));
- if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
- NDR_PULL_ALLOC_N(ndr, r->in.change_log_entry, ndr_get_array_size(ndr, &r->in.change_log_entry));
+ {
+ struct ndr_pull *_ndr_change_log_entry;
+ NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_change_log_entry, 4, r->in.change_log_entry_size));
+ NDR_CHECK(ndr_pull_netr_ChangeLogEntry(_ndr_change_log_entry, NDR_SCALARS|NDR_BUFFERS, &r->in.change_log_entry));
+ NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_change_log_entry, 4, r->in.change_log_entry_size));
}
- NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->in.change_log_entry, ndr_get_array_size(ndr, &r->in.change_log_entry)));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.change_log_entry_size));
NDR_PULL_ALLOC(ndr, r->out.return_authenticator);
*r->out.return_authenticator = *r->in.return_authenticator;
NDR_PULL_ALLOC(ndr, r->out.delta_enum_array);
ZERO_STRUCTP(r->out.delta_enum_array);
- if (r->in.change_log_entry) {
- NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->in.change_log_entry, r->in.change_log_entry_size));
- }
}
if (flags & NDR_OUT) {
if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
@@ -11434,11 +11601,8 @@ _PUBLIC_ void ndr_print_netr_DatabaseRedo(struct ndr_print *ndr, const char *nam
ndr->depth++;
ndr_print_netr_Authenticator(ndr, "return_authenticator", r->in.return_authenticator);
ndr->depth--;
- ndr_print_ptr(ndr, "change_log_entry", r->in.change_log_entry);
- ndr->depth++;
- ndr_print_array_uint8(ndr, "change_log_entry", r->in.change_log_entry, r->in.change_log_entry_size);
- ndr->depth--;
- ndr_print_uint32(ndr, "change_log_entry_size", r->in.change_log_entry_size);
+ ndr_print_netr_ChangeLogEntry(ndr, "change_log_entry", &r->in.change_log_entry);
+ ndr_print_uint32(ndr, "change_log_entry_size", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?ndr_size_netr_ChangeLogEntry(&r->in.change_log_entry, ndr->flags):r->in.change_log_entry_size);
ndr->depth--;
}
if (flags & NDR_OUT) {
@@ -13028,7 +13192,7 @@ static enum ndr_err_code ndr_push_netr_ServerPasswordGet(struct ndr_push *ndr, i
if (r->out.password == NULL) {
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
}
- NDR_CHECK(ndr_push_samr_Password(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.password));
+ NDR_CHECK(ndr_push_samr_Password(ndr, NDR_SCALARS, r->out.password));
NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result));
}
return NDR_ERR_SUCCESS;
@@ -13102,7 +13266,7 @@ static enum ndr_err_code ndr_pull_netr_ServerPasswordGet(struct ndr_pull *ndr, i
}
_mem_save_password_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->out.password, LIBNDR_FLAG_REF_ALLOC);
- NDR_CHECK(ndr_pull_samr_Password(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.password));
+ NDR_CHECK(ndr_pull_samr_Password(ndr, NDR_SCALARS, r->out.password));
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_password_0, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result));
}
@@ -14522,11 +14686,11 @@ static enum ndr_err_code ndr_push_netr_ServerTrustPasswordsGet(struct ndr_push *
if (r->out.password == NULL) {
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
}
- NDR_CHECK(ndr_push_samr_Password(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.password));
+ NDR_CHECK(ndr_push_samr_Password(ndr, NDR_SCALARS, r->out.password));
if (r->out.password2 == NULL) {
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
}
- NDR_CHECK(ndr_push_samr_Password(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.password2));
+ NDR_CHECK(ndr_push_samr_Password(ndr, NDR_SCALARS, r->out.password2));
NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result));
}
return NDR_ERR_SUCCESS;
@@ -14603,14 +14767,14 @@ static enum ndr_err_code ndr_pull_netr_ServerTrustPasswordsGet(struct ndr_pull *
}
_mem_save_password_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->out.password, LIBNDR_FLAG_REF_ALLOC);
- NDR_CHECK(ndr_pull_samr_Password(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.password));
+ NDR_CHECK(ndr_pull_samr_Password(ndr, NDR_SCALARS, r->out.password));
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_password_0, LIBNDR_FLAG_REF_ALLOC);
if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
NDR_PULL_ALLOC(ndr, r->out.password2);
}
_mem_save_password2_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->out.password2, LIBNDR_FLAG_REF_ALLOC);
- NDR_CHECK(ndr_pull_samr_Password(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.password2));
+ NDR_CHECK(ndr_pull_samr_Password(ndr, NDR_SCALARS, r->out.password2));
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_password2_0, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result));
}
diff --git a/source3/librpc/gen_ndr/ndr_netlogon.h b/source3/librpc/gen_ndr/ndr_netlogon.h
index 8561a5b5ca..be20448636 100644
--- a/source3/librpc/gen_ndr/ndr_netlogon.h
+++ b/source3/librpc/gen_ndr/ndr_netlogon.h
@@ -6,6 +6,7 @@
#ifndef _HEADER_NDR_netlogon
#define _HEADER_NDR_netlogon
+#include "../librpc/ndr/ndr_netlogon.h"
#define NDR_NETLOGON_UUID "12345678-1234-abcd-ef00-01234567cffb"
#define NDR_NETLOGON_VERSION 1.0
#define NDR_NETLOGON_NAME "netlogon"
@@ -190,6 +191,12 @@ void ndr_print_netr_CONTROL_QUERY_INFORMATION(struct ndr_print *ndr, const char
void ndr_print_netr_LogonControlCode(struct ndr_print *ndr, const char *name, enum netr_LogonControlCode r);
void ndr_print_netr_CONTROL_DATA_INFORMATION(struct ndr_print *ndr, const char *name, const union netr_CONTROL_DATA_INFORMATION *r);
void ndr_print_netr_NegotiateFlags(struct ndr_print *ndr, const char *name, uint32_t r);
+void ndr_print_netr_ChangeLogFlags(struct ndr_print *ndr, const char *name, uint16_t r);
+void ndr_print_netr_ChangeLogObject(struct ndr_print *ndr, const char *name, const union netr_ChangeLogObject *r);
+enum ndr_err_code ndr_push_netr_ChangeLogEntry(struct ndr_push *ndr, int ndr_flags, const struct netr_ChangeLogEntry *r);
+enum ndr_err_code ndr_pull_netr_ChangeLogEntry(struct ndr_pull *ndr, int ndr_flags, struct netr_ChangeLogEntry *r);
+void ndr_print_netr_ChangeLogEntry(struct ndr_print *ndr, const char *name, const struct netr_ChangeLogEntry *r);
+size_t ndr_size_netr_ChangeLogEntry(const struct netr_ChangeLogEntry *r, int flags);
void ndr_print_netr_Blob(struct ndr_print *ndr, const char *name, const struct netr_Blob *r);
void ndr_print_netr_DsRGetDCName_flags(struct ndr_print *ndr, const char *name, uint32_t r);
void ndr_print_netr_DsRGetDCNameInfo_AddressType(struct ndr_print *ndr, const char *name, enum netr_DsRGetDCNameInfo_AddressType r);
diff --git a/source3/librpc/gen_ndr/ndr_ntsvcs.c b/source3/librpc/gen_ndr/ndr_ntsvcs.c
index 35d02a0dcb..ced6fb7767 100644
--- a/source3/librpc/gen_ndr/ndr_ntsvcs.c
+++ b/source3/librpc/gen_ndr/ndr_ntsvcs.c
@@ -3,16 +3,17 @@
#include "includes.h"
#include "librpc/gen_ndr/ndr_ntsvcs.h"
+#include "librpc/gen_ndr/ndr_winreg.h"
static enum ndr_err_code ndr_push_PNP_HwProfInfo(struct ndr_push *ndr, int ndr_flags, const struct PNP_HwProfInfo *r)
{
- uint32_t cntr_unknown2_0;
+ uint32_t cntr_friendly_name_0;
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_push_align(ndr, 4));
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->unknown1));
- for (cntr_unknown2_0 = 0; cntr_unknown2_0 < 160; cntr_unknown2_0++) {
- NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->unknown2[cntr_unknown2_0]));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->profile_handle));
+ for (cntr_friendly_name_0 = 0; cntr_friendly_name_0 < 80; cntr_friendly_name_0++) {
+ NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->friendly_name[cntr_friendly_name_0]));
}
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->unknown3));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->flags));
}
if (ndr_flags & NDR_BUFFERS) {
}
@@ -21,14 +22,14 @@ static enum ndr_err_code ndr_push_PNP_HwProfInfo(struct ndr_push *ndr, int ndr_f
static enum ndr_err_code ndr_pull_PNP_HwProfInfo(struct ndr_pull *ndr, int ndr_flags, struct PNP_HwProfInfo *r)
{
- uint32_t cntr_unknown2_0;
+ uint32_t cntr_friendly_name_0;
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_pull_align(ndr, 4));
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown1));
- for (cntr_unknown2_0 = 0; cntr_unknown2_0 < 160; cntr_unknown2_0++) {
- NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->unknown2[cntr_unknown2_0]));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->profile_handle));
+ for (cntr_friendly_name_0 = 0; cntr_friendly_name_0 < 80; cntr_friendly_name_0++) {
+ NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->friendly_name[cntr_friendly_name_0]));
}
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown3));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->flags));
}
if (ndr_flags & NDR_BUFFERS) {
}
@@ -37,21 +38,21 @@ static enum ndr_err_code ndr_pull_PNP_HwProfInfo(struct ndr_pull *ndr, int ndr_f
_PUBLIC_ void ndr_print_PNP_HwProfInfo(struct ndr_print *ndr, const char *name, const struct PNP_HwProfInfo *r)
{
- uint32_t cntr_unknown2_0;
+ uint32_t cntr_friendly_name_0;
ndr_print_struct(ndr, name, "PNP_HwProfInfo");
ndr->depth++;
- ndr_print_uint32(ndr, "unknown1", r->unknown1);
- ndr->print(ndr, "%s: ARRAY(%d)", "unknown2", (int)160);
+ ndr_print_uint32(ndr, "profile_handle", r->profile_handle);
+ ndr->print(ndr, "%s: ARRAY(%d)", "friendly_name", (int)80);
ndr->depth++;
- for (cntr_unknown2_0=0;cntr_unknown2_0<160;cntr_unknown2_0++) {
+ for (cntr_friendly_name_0=0;cntr_friendly_name_0<80;cntr_friendly_name_0++) {
char *idx_0=NULL;
- if (asprintf(&idx_0, "[%d]", cntr_unknown2_0) != -1) {
- ndr_print_uint16(ndr, "unknown2", r->unknown2[cntr_unknown2_0]);
+ if (asprintf(&idx_0, "[%d]", cntr_friendly_name_0) != -1) {
+ ndr_print_uint16(ndr, "friendly_name", r->friendly_name[cntr_friendly_name_0]);
free(idx_0);
}
}
ndr->depth--;
- ndr_print_uint32(ndr, "unknown3", r->unknown3);
+ ndr_print_uint32(ndr, "flags", r->flags);
ndr->depth--;
}
@@ -818,7 +819,7 @@ static enum ndr_err_code ndr_push_PNP_GetDeviceRegProp(struct ndr_push *ndr, int
if (r->in.reg_data_type == NULL) {
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
}
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->in.reg_data_type));
+ NDR_CHECK(ndr_push_winreg_Type(ndr, NDR_SCALARS, *r->in.reg_data_type));
if (r->in.buffer_size == NULL) {
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
}
@@ -833,7 +834,7 @@ static enum ndr_err_code ndr_push_PNP_GetDeviceRegProp(struct ndr_push *ndr, int
if (r->out.reg_data_type == NULL) {
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
}
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.reg_data_type));
+ NDR_CHECK(ndr_push_winreg_Type(ndr, NDR_SCALARS, *r->out.reg_data_type));
if (r->out.buffer == NULL) {
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
}
@@ -875,7 +876,7 @@ static enum ndr_err_code ndr_pull_PNP_GetDeviceRegProp(struct ndr_pull *ndr, int
}
_mem_save_reg_data_type_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->in.reg_data_type, LIBNDR_FLAG_REF_ALLOC);
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->in.reg_data_type));
+ NDR_CHECK(ndr_pull_winreg_Type(ndr, NDR_SCALARS, r->in.reg_data_type));
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_reg_data_type_0, LIBNDR_FLAG_REF_ALLOC);
if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
NDR_PULL_ALLOC(ndr, r->in.buffer_size);
@@ -907,7 +908,7 @@ static enum ndr_err_code ndr_pull_PNP_GetDeviceRegProp(struct ndr_pull *ndr, int
}
_mem_save_reg_data_type_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->out.reg_data_type, LIBNDR_FLAG_REF_ALLOC);
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.reg_data_type));
+ NDR_CHECK(ndr_pull_winreg_Type(ndr, NDR_SCALARS, r->out.reg_data_type));
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_reg_data_type_0, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_array_size(ndr, &r->out.buffer));
NDR_CHECK(ndr_pull_array_length(ndr, &r->out.buffer));
@@ -960,7 +961,7 @@ _PUBLIC_ void ndr_print_PNP_GetDeviceRegProp(struct ndr_print *ndr, const char *
ndr_print_uint32(ndr, "property", r->in.property);
ndr_print_ptr(ndr, "reg_data_type", r->in.reg_data_type);
ndr->depth++;
- ndr_print_uint32(ndr, "reg_data_type", *r->in.reg_data_type);
+ ndr_print_winreg_Type(ndr, "reg_data_type", *r->in.reg_data_type);
ndr->depth--;
ndr_print_ptr(ndr, "buffer_size", r->in.buffer_size);
ndr->depth++;
@@ -978,7 +979,7 @@ _PUBLIC_ void ndr_print_PNP_GetDeviceRegProp(struct ndr_print *ndr, const char *
ndr->depth++;
ndr_print_ptr(ndr, "reg_data_type", r->out.reg_data_type);
ndr->depth++;
- ndr_print_uint32(ndr, "reg_data_type", *r->out.reg_data_type);
+ ndr_print_winreg_Type(ndr, "reg_data_type", *r->out.reg_data_type);
ndr->depth--;
ndr_print_ptr(ndr, "buffer", r->out.buffer);
ndr->depth++;
@@ -2067,7 +2068,7 @@ _PUBLIC_ void ndr_print_PNP_RequestEjectPC(struct ndr_print *ndr, const char *na
static enum ndr_err_code ndr_push_PNP_HwProfFlags(struct ndr_push *ndr, int flags, const struct PNP_HwProfFlags *r)
{
if (flags & NDR_IN) {
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.unknown1));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.action));
if (r->in.devicepath == NULL) {
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
}
@@ -2075,14 +2076,14 @@ static enum ndr_err_code ndr_push_PNP_HwProfFlags(struct ndr_push *ndr, int flag
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.devicepath, CH_UTF16)));
NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.devicepath, ndr_charset_length(r->in.devicepath, CH_UTF16), sizeof(uint16_t), CH_UTF16));
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.unknown2));
- if (r->in.unknown3 == NULL) {
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.config));
+ if (r->in.profile_flags == NULL) {
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
}
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->in.unknown3));
- NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.unknown4));
- if (r->in.unknown4) {
- NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, *r->in.unknown4));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->in.profile_flags));
+ NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.veto_type));
+ if (r->in.veto_type) {
+ NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, *r->in.veto_type));
}
NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.unknown5));
if (r->in.unknown5) {
@@ -2091,17 +2092,17 @@ static enum ndr_err_code ndr_push_PNP_HwProfFlags(struct ndr_push *ndr, int flag
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.unknown5, CH_UTF16)));
NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.unknown5, ndr_charset_length(r->in.unknown5, CH_UTF16), sizeof(uint16_t), CH_UTF16));
}
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.unknown6));
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.unknown7));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.name_length));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.flags));
}
if (flags & NDR_OUT) {
- if (r->out.unknown3 == NULL) {
+ if (r->out.profile_flags == NULL) {
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
}
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.unknown3));
- NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.unknown4));
- if (r->out.unknown4) {
- NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, *r->out.unknown4));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.profile_flags));
+ NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.veto_type));
+ if (r->out.veto_type) {
+ NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, *r->out.veto_type));
}
NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.unknown5a));
if (r->out.unknown5a) {
@@ -2120,18 +2121,18 @@ static enum ndr_err_code ndr_push_PNP_HwProfFlags(struct ndr_push *ndr, int flag
static enum ndr_err_code ndr_pull_PNP_HwProfFlags(struct ndr_pull *ndr, int flags, struct PNP_HwProfFlags *r)
{
- uint32_t _ptr_unknown4;
+ uint32_t _ptr_veto_type;
uint32_t _ptr_unknown5;
uint32_t _ptr_unknown5a;
- TALLOC_CTX *_mem_save_unknown3_0;
- TALLOC_CTX *_mem_save_unknown4_0;
+ TALLOC_CTX *_mem_save_profile_flags_0;
+ TALLOC_CTX *_mem_save_veto_type_0;
TALLOC_CTX *_mem_save_unknown5_0;
TALLOC_CTX *_mem_save_unknown5a_0;
TALLOC_CTX *_mem_save_unknown5a_1;
if (flags & NDR_IN) {
ZERO_STRUCT(r->out);
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown1));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.action));
NDR_CHECK(ndr_pull_array_size(ndr, &r->in.devicepath));
NDR_CHECK(ndr_pull_array_length(ndr, &r->in.devicepath));
if (ndr_get_array_length(ndr, &r->in.devicepath) > ndr_get_array_size(ndr, &r->in.devicepath)) {
@@ -2139,25 +2140,25 @@ static enum ndr_err_code ndr_pull_PNP_HwProfFlags(struct ndr_pull *ndr, int flag
}
NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.devicepath), sizeof(uint16_t)));
NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.devicepath, ndr_get_array_length(ndr, &r->in.devicepath), sizeof(uint16_t), CH_UTF16));
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown2));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.config));
if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
- NDR_PULL_ALLOC(ndr, r->in.unknown3);
- }
- _mem_save_unknown3_0 = NDR_PULL_GET_MEM_CTX(ndr);
- NDR_PULL_SET_MEM_CTX(ndr, r->in.unknown3, LIBNDR_FLAG_REF_ALLOC);
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->in.unknown3));
- NDR_PULL_SET_MEM_CTX(ndr, _mem_save_unknown3_0, LIBNDR_FLAG_REF_ALLOC);
- NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_unknown4));
- if (_ptr_unknown4) {
- NDR_PULL_ALLOC(ndr, r->in.unknown4);
+ NDR_PULL_ALLOC(ndr, r->in.profile_flags);
+ }
+ _mem_save_profile_flags_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->in.profile_flags, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->in.profile_flags));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_profile_flags_0, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_veto_type));
+ if (_ptr_veto_type) {
+ NDR_PULL_ALLOC(ndr, r->in.veto_type);
} else {
- r->in.unknown4 = NULL;
+ r->in.veto_type = NULL;
}
- if (r->in.unknown4) {
- _mem_save_unknown4_0 = NDR_PULL_GET_MEM_CTX(ndr);
- NDR_PULL_SET_MEM_CTX(ndr, r->in.unknown4, 0);
- NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, r->in.unknown4));
- NDR_PULL_SET_MEM_CTX(ndr, _mem_save_unknown4_0, 0);
+ if (r->in.veto_type) {
+ _mem_save_veto_type_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->in.veto_type, 0);
+ NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, r->in.veto_type));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_veto_type_0, 0);
}
NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_unknown5));
if (_ptr_unknown5) {
@@ -2177,30 +2178,30 @@ static enum ndr_err_code ndr_pull_PNP_HwProfFlags(struct ndr_pull *ndr, int flag
NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.unknown5, ndr_get_array_length(ndr, &r->in.unknown5), sizeof(uint16_t), CH_UTF16));
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_unknown5_0, 0);
}
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown6));
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown7));
- NDR_PULL_ALLOC(ndr, r->out.unknown3);
- *r->out.unknown3 = *r->in.unknown3;
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.name_length));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.flags));
+ NDR_PULL_ALLOC(ndr, r->out.profile_flags);
+ *r->out.profile_flags = *r->in.profile_flags;
}
if (flags & NDR_OUT) {
if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
- NDR_PULL_ALLOC(ndr, r->out.unknown3);
- }
- _mem_save_unknown3_0 = NDR_PULL_GET_MEM_CTX(ndr);
- NDR_PULL_SET_MEM_CTX(ndr, r->out.unknown3, LIBNDR_FLAG_REF_ALLOC);
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.unknown3));
- NDR_PULL_SET_MEM_CTX(ndr, _mem_save_unknown3_0, LIBNDR_FLAG_REF_ALLOC);
- NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_unknown4));
- if (_ptr_unknown4) {
- NDR_PULL_ALLOC(ndr, r->out.unknown4);
+ NDR_PULL_ALLOC(ndr, r->out.profile_flags);
+ }
+ _mem_save_profile_flags_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->out.profile_flags, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.profile_flags));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_profile_flags_0, LIBNDR_FLAG_REF_ALLOC);
+ NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_veto_type));
+ if (_ptr_veto_type) {
+ NDR_PULL_ALLOC(ndr, r->out.veto_type);
} else {
- r->out.unknown4 = NULL;
+ r->out.veto_type = NULL;
}
- if (r->out.unknown4) {
- _mem_save_unknown4_0 = NDR_PULL_GET_MEM_CTX(ndr);
- NDR_PULL_SET_MEM_CTX(ndr, r->out.unknown4, 0);
- NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, r->out.unknown4));
- NDR_PULL_SET_MEM_CTX(ndr, _mem_save_unknown4_0, 0);
+ if (r->out.veto_type) {
+ _mem_save_veto_type_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->out.veto_type, 0);
+ NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, r->out.veto_type));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_veto_type_0, 0);
}
NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_unknown5a));
if (_ptr_unknown5a) {
@@ -2246,20 +2247,20 @@ _PUBLIC_ void ndr_print_PNP_HwProfFlags(struct ndr_print *ndr, const char *name,
if (flags & NDR_IN) {
ndr_print_struct(ndr, "in", "PNP_HwProfFlags");
ndr->depth++;
- ndr_print_uint32(ndr, "unknown1", r->in.unknown1);
+ ndr_print_uint32(ndr, "action", r->in.action);
ndr_print_ptr(ndr, "devicepath", r->in.devicepath);
ndr->depth++;
ndr_print_string(ndr, "devicepath", r->in.devicepath);
ndr->depth--;
- ndr_print_uint32(ndr, "unknown2", r->in.unknown2);
- ndr_print_ptr(ndr, "unknown3", r->in.unknown3);
+ ndr_print_uint32(ndr, "config", r->in.config);
+ ndr_print_ptr(ndr, "profile_flags", r->in.profile_flags);
ndr->depth++;
- ndr_print_uint32(ndr, "unknown3", *r->in.unknown3);
+ ndr_print_uint32(ndr, "profile_flags", *r->in.profile_flags);
ndr->depth--;
- ndr_print_ptr(ndr, "unknown4", r->in.unknown4);
+ ndr_print_ptr(ndr, "veto_type", r->in.veto_type);
ndr->depth++;
- if (r->in.unknown4) {
- ndr_print_uint16(ndr, "unknown4", *r->in.unknown4);
+ if (r->in.veto_type) {
+ ndr_print_uint16(ndr, "veto_type", *r->in.veto_type);
}
ndr->depth--;
ndr_print_ptr(ndr, "unknown5", r->in.unknown5);
@@ -2268,21 +2269,21 @@ _PUBLIC_ void ndr_print_PNP_HwProfFlags(struct ndr_print *ndr, const char *name,
ndr_print_string(ndr, "unknown5", r->in.unknown5);
}
ndr->depth--;
- ndr_print_uint32(ndr, "unknown6", r->in.unknown6);
- ndr_print_uint32(ndr, "unknown7", r->in.unknown7);
+ ndr_print_uint32(ndr, "name_length", r->in.name_length);
+ ndr_print_uint32(ndr, "flags", r->in.flags);
ndr->depth--;
}
if (flags & NDR_OUT) {
ndr_print_struct(ndr, "out", "PNP_HwProfFlags");
ndr->depth++;
- ndr_print_ptr(ndr, "unknown3", r->out.unknown3);
+ ndr_print_ptr(ndr, "profile_flags", r->out.profile_flags);
ndr->depth++;
- ndr_print_uint32(ndr, "unknown3", *r->out.unknown3);
+ ndr_print_uint32(ndr, "profile_flags", *r->out.profile_flags);
ndr->depth--;
- ndr_print_ptr(ndr, "unknown4", r->out.unknown4);
+ ndr_print_ptr(ndr, "veto_type", r->out.veto_type);
ndr->depth++;
- if (r->out.unknown4) {
- ndr_print_uint16(ndr, "unknown4", *r->out.unknown4);
+ if (r->out.veto_type) {
+ ndr_print_uint16(ndr, "veto_type", *r->out.veto_type);
}
ndr->depth--;
ndr_print_ptr(ndr, "unknown5a", r->out.unknown5a);
@@ -2310,8 +2311,8 @@ static enum ndr_err_code ndr_push_PNP_GetHwProfInfo(struct ndr_push *ndr, int fl
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
}
NDR_CHECK(ndr_push_PNP_HwProfInfo(ndr, NDR_SCALARS, r->in.info));
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.unknown1));
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.unknown2));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.size));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.flags));
}
if (flags & NDR_OUT) {
if (r->out.info == NULL) {
@@ -2337,8 +2338,8 @@ static enum ndr_err_code ndr_pull_PNP_GetHwProfInfo(struct ndr_pull *ndr, int fl
NDR_PULL_SET_MEM_CTX(ndr, r->in.info, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_PNP_HwProfInfo(ndr, NDR_SCALARS, r->in.info));
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, LIBNDR_FLAG_REF_ALLOC);
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown1));
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown2));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.size));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.flags));
NDR_PULL_ALLOC(ndr, r->out.info);
*r->out.info = *r->in.info;
}
@@ -2370,8 +2371,8 @@ _PUBLIC_ void ndr_print_PNP_GetHwProfInfo(struct ndr_print *ndr, const char *nam
ndr->depth++;
ndr_print_PNP_HwProfInfo(ndr, "info", r->in.info);
ndr->depth--;
- ndr_print_uint32(ndr, "unknown1", r->in.unknown1);
- ndr_print_uint32(ndr, "unknown2", r->in.unknown2);
+ ndr_print_uint32(ndr, "size", r->in.size);
+ ndr_print_uint32(ndr, "flags", r->in.flags);
ndr->depth--;
}
if (flags & NDR_OUT) {
@@ -3856,10 +3857,11 @@ static const struct ndr_interface_call ntsvcs_calls[] = {
static const char * const ntsvcs_endpoint_strings[] = {
"ncacn_np:[\\pipe\\ntsvcs]",
+ "ncacn_np:[\\pipe\\plugplay]",
};
static const struct ndr_interface_string_array ntsvcs_endpoints = {
- .count = 1,
+ .count = 2,
.names = ntsvcs_endpoint_strings
};
diff --git a/source3/librpc/gen_ndr/ndr_samr.c b/source3/librpc/gen_ndr/ndr_samr.c
index f83d0f0875..975bde3340 100644
--- a/source3/librpc/gen_ndr/ndr_samr.c
+++ b/source3/librpc/gen_ndr/ndr_samr.c
@@ -6,6 +6,59 @@
#include "librpc/gen_ndr/ndr_misc.h"
#include "librpc/gen_ndr/ndr_lsa.h"
#include "librpc/gen_ndr/ndr_security.h"
+_PUBLIC_ enum ndr_err_code ndr_push_netr_SamDatabaseID(struct ndr_push *ndr, int ndr_flags, enum netr_SamDatabaseID r)
+{
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_pull_netr_SamDatabaseID(struct ndr_pull *ndr, int ndr_flags, enum netr_SamDatabaseID *r)
+{
+ uint32_t v;
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
+ *r = v;
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_netr_SamDatabaseID(struct ndr_print *ndr, const char *name, enum netr_SamDatabaseID r)
+{
+ const char *val = NULL;
+
+ switch (r) {
+ case SAM_DATABASE_DOMAIN: val = "SAM_DATABASE_DOMAIN"; break;
+ case SAM_DATABASE_BUILTIN: val = "SAM_DATABASE_BUILTIN"; break;
+ case SAM_DATABASE_PRIVS: val = "SAM_DATABASE_PRIVS"; break;
+ }
+ ndr_print_enum(ndr, name, "ENUM", val, r);
+}
+
+_PUBLIC_ enum ndr_err_code ndr_push_samr_RejectReason(struct ndr_push *ndr, int ndr_flags, enum samr_RejectReason r)
+{
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_pull_samr_RejectReason(struct ndr_pull *ndr, int ndr_flags, enum samr_RejectReason *r)
+{
+ uint32_t v;
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
+ *r = v;
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_samr_RejectReason(struct ndr_print *ndr, const char *name, enum samr_RejectReason r)
+{
+ const char *val = NULL;
+
+ switch (r) {
+ case SAMR_REJECT_OTHER: val = "SAMR_REJECT_OTHER"; break;
+ case SAMR_REJECT_TOO_SHORT: val = "SAMR_REJECT_TOO_SHORT"; break;
+ case SAMR_REJECT_IN_HISTORY: val = "SAMR_REJECT_IN_HISTORY"; break;
+ case SAMR_REJECT_COMPLEXITY: val = "SAMR_REJECT_COMPLEXITY"; break;
+ }
+ ndr_print_enum(ndr, name, "ENUM", val, r);
+}
+
_PUBLIC_ enum ndr_err_code ndr_push_samr_AcctFlags(struct ndr_push *ndr, int ndr_flags, uint32_t r)
{
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
@@ -364,6 +417,31 @@ _PUBLIC_ void ndr_print_samr_PasswordProperties(struct ndr_print *ndr, const cha
ndr->depth--;
}
+static enum ndr_err_code ndr_push_samr_DomainServerState(struct ndr_push *ndr, int ndr_flags, enum samr_DomainServerState r)
+{
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
+ return NDR_ERR_SUCCESS;
+}
+
+static enum ndr_err_code ndr_pull_samr_DomainServerState(struct ndr_pull *ndr, int ndr_flags, enum samr_DomainServerState *r)
+{
+ uint32_t v;
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
+ *r = v;
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_samr_DomainServerState(struct ndr_print *ndr, const char *name, enum samr_DomainServerState r)
+{
+ const char *val = NULL;
+
+ switch (r) {
+ case DOMAIN_SERVER_ENABLED: val = "DOMAIN_SERVER_ENABLED"; break;
+ case DOMAIN_SERVER_DISABLED: val = "DOMAIN_SERVER_DISABLED"; break;
+ }
+ ndr_print_enum(ndr, name, "ENUM", val, r);
+}
+
static enum ndr_err_code ndr_push_samr_DomInfo1(struct ndr_push *ndr, int ndr_flags, const struct samr_DomInfo1 *r)
{
if (ndr_flags & NDR_SCALARS) {
@@ -415,7 +493,7 @@ static enum ndr_err_code ndr_push_samr_DomGeneralInformation(struct ndr_push *nd
NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS, &r->domain_name));
NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS, &r->primary));
NDR_CHECK(ndr_push_udlong(ndr, NDR_SCALARS, r->sequence_num));
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->unknown2));
+ NDR_CHECK(ndr_push_samr_DomainServerState(ndr, NDR_SCALARS, r->domain_server_state));
NDR_CHECK(ndr_push_samr_Role(ndr, NDR_SCALARS, r->role));
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->unknown3));
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->num_users));
@@ -439,7 +517,7 @@ static enum ndr_err_code ndr_pull_samr_DomGeneralInformation(struct ndr_pull *nd
NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS, &r->domain_name));
NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS, &r->primary));
NDR_CHECK(ndr_pull_udlong(ndr, NDR_SCALARS, &r->sequence_num));
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown2));
+ NDR_CHECK(ndr_pull_samr_DomainServerState(ndr, NDR_SCALARS, &r->domain_server_state));
NDR_CHECK(ndr_pull_samr_Role(ndr, NDR_SCALARS, &r->role));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown3));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->num_users));
@@ -463,7 +541,7 @@ _PUBLIC_ void ndr_print_samr_DomGeneralInformation(struct ndr_print *ndr, const
ndr_print_lsa_String(ndr, "domain_name", &r->domain_name);
ndr_print_lsa_String(ndr, "primary", &r->primary);
ndr_print_udlong(ndr, "sequence_num", r->sequence_num);
- ndr_print_uint32(ndr, "unknown2", r->unknown2);
+ ndr_print_samr_DomainServerState(ndr, "domain_server_state", r->domain_server_state);
ndr_print_samr_Role(ndr, "role", r->role);
ndr_print_uint32(ndr, "unknown3", r->unknown3);
ndr_print_uint32(ndr, "num_users", r->num_users);
@@ -665,7 +743,7 @@ static enum ndr_err_code ndr_push_samr_DomInfo9(struct ndr_push *ndr, int ndr_fl
{
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_push_align(ndr, 4));
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->unknown));
+ NDR_CHECK(ndr_push_samr_DomainServerState(ndr, NDR_SCALARS, r->domain_server_state));
}
if (ndr_flags & NDR_BUFFERS) {
}
@@ -676,7 +754,7 @@ static enum ndr_err_code ndr_pull_samr_DomInfo9(struct ndr_pull *ndr, int ndr_fl
{
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_pull_align(ndr, 4));
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown));
+ NDR_CHECK(ndr_pull_samr_DomainServerState(ndr, NDR_SCALARS, &r->domain_server_state));
}
if (ndr_flags & NDR_BUFFERS) {
}
@@ -687,7 +765,7 @@ _PUBLIC_ void ndr_print_samr_DomInfo9(struct ndr_print *ndr, const char *name, c
{
ndr_print_struct(ndr, name, "samr_DomInfo9");
ndr->depth++;
- ndr_print_uint32(ndr, "unknown", r->unknown);
+ ndr_print_samr_DomainServerState(ndr, "domain_server_state", r->domain_server_state);
ndr->depth--;
}
@@ -2961,7 +3039,7 @@ static enum ndr_err_code ndr_push_samr_UserInfo24(struct ndr_push *ndr, int ndr_
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_push_align(ndr, 1));
NDR_CHECK(ndr_push_samr_CryptPassword(ndr, NDR_SCALARS, &r->password));
- NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->pw_len));
+ NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->password_expired));
}
if (ndr_flags & NDR_BUFFERS) {
}
@@ -2973,7 +3051,7 @@ static enum ndr_err_code ndr_pull_samr_UserInfo24(struct ndr_pull *ndr, int ndr_
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_pull_align(ndr, 1));
NDR_CHECK(ndr_pull_samr_CryptPassword(ndr, NDR_SCALARS, &r->password));
- NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->pw_len));
+ NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->password_expired));
}
if (ndr_flags & NDR_BUFFERS) {
}
@@ -2985,7 +3063,7 @@ _PUBLIC_ void ndr_print_samr_UserInfo24(struct ndr_print *ndr, const char *name,
ndr_print_struct(ndr, name, "samr_UserInfo24");
ndr->depth++;
ndr_print_samr_CryptPassword(ndr, "password", &r->password);
- ndr_print_uint8(ndr, "pw_len", r->pw_len);
+ ndr_print_uint8(ndr, "password_expired", r->password_expired);
ndr->depth--;
}
@@ -3074,7 +3152,7 @@ static enum ndr_err_code ndr_push_samr_UserInfo26(struct ndr_push *ndr, int ndr_
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_push_align(ndr, 1));
NDR_CHECK(ndr_push_samr_CryptPasswordEx(ndr, NDR_SCALARS, &r->password));
- NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->pw_len));
+ NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->password_expired));
}
if (ndr_flags & NDR_BUFFERS) {
}
@@ -3086,7 +3164,7 @@ static enum ndr_err_code ndr_pull_samr_UserInfo26(struct ndr_pull *ndr, int ndr_
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_pull_align(ndr, 1));
NDR_CHECK(ndr_pull_samr_CryptPasswordEx(ndr, NDR_SCALARS, &r->password));
- NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->pw_len));
+ NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->password_expired));
}
if (ndr_flags & NDR_BUFFERS) {
}
@@ -3098,7 +3176,7 @@ _PUBLIC_ void ndr_print_samr_UserInfo26(struct ndr_print *ndr, const char *name,
ndr_print_struct(ndr, name, "samr_UserInfo26");
ndr->depth++;
ndr_print_samr_CryptPasswordEx(ndr, "password", &r->password);
- ndr_print_uint8(ndr, "pw_len", r->pw_len);
+ ndr_print_uint8(ndr, "password_expired", r->password_expired);
ndr->depth--;
}
@@ -11907,7 +11985,10 @@ static enum ndr_err_code ndr_push_samr_RidToSid(struct ndr_push *ndr, int flags,
if (r->out.sid == NULL) {
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
}
- NDR_CHECK(ndr_push_dom_sid2(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.sid));
+ NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.sid));
+ if (*r->out.sid) {
+ NDR_CHECK(ndr_push_dom_sid2(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.sid));
+ }
NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result));
}
return NDR_ERR_SUCCESS;
@@ -11915,8 +11996,10 @@ static enum ndr_err_code ndr_push_samr_RidToSid(struct ndr_push *ndr, int flags,
static enum ndr_err_code ndr_pull_samr_RidToSid(struct ndr_pull *ndr, int flags, struct samr_RidToSid *r)
{
+ uint32_t _ptr_sid;
TALLOC_CTX *_mem_save_domain_handle_0;
TALLOC_CTX *_mem_save_sid_0;
+ TALLOC_CTX *_mem_save_sid_1;
if (flags & NDR_IN) {
ZERO_STRUCT(r->out);
@@ -11937,7 +12020,18 @@ static enum ndr_err_code ndr_pull_samr_RidToSid(struct ndr_pull *ndr, int flags,
}
_mem_save_sid_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->out.sid, LIBNDR_FLAG_REF_ALLOC);
- NDR_CHECK(ndr_pull_dom_sid2(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.sid));
+ NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_sid));
+ if (_ptr_sid) {
+ NDR_PULL_ALLOC(ndr, *r->out.sid);
+ } else {
+ *r->out.sid = NULL;
+ }
+ if (*r->out.sid) {
+ _mem_save_sid_1 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, *r->out.sid, 0);
+ NDR_CHECK(ndr_pull_dom_sid2(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.sid));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sid_1, 0);
+ }
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sid_0, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result));
}
@@ -11966,7 +12060,12 @@ _PUBLIC_ void ndr_print_samr_RidToSid(struct ndr_print *ndr, const char *name, i
ndr->depth++;
ndr_print_ptr(ndr, "sid", r->out.sid);
ndr->depth++;
- ndr_print_dom_sid2(ndr, "sid", r->out.sid);
+ ndr_print_ptr(ndr, "sid", *r->out.sid);
+ ndr->depth++;
+ if (*r->out.sid) {
+ ndr_print_dom_sid2(ndr, "sid", *r->out.sid);
+ }
+ ndr->depth--;
ndr->depth--;
ndr_print_NTSTATUS(ndr, "result", r->out.result);
ndr->depth--;
diff --git a/source3/librpc/gen_ndr/ndr_samr.h b/source3/librpc/gen_ndr/ndr_samr.h
index 1f582061f9..64c60ee704 100644
--- a/source3/librpc/gen_ndr/ndr_samr.h
+++ b/source3/librpc/gen_ndr/ndr_samr.h
@@ -148,6 +148,12 @@ extern const struct ndr_interface_table ndr_table_samr;
#define NDR_SAMR_VALIDATEPASSWORD (0x43)
#define NDR_SAMR_CALL_COUNT (68)
+enum ndr_err_code ndr_push_netr_SamDatabaseID(struct ndr_push *ndr, int ndr_flags, enum netr_SamDatabaseID r);
+enum ndr_err_code ndr_pull_netr_SamDatabaseID(struct ndr_pull *ndr, int ndr_flags, enum netr_SamDatabaseID *r);
+void ndr_print_netr_SamDatabaseID(struct ndr_print *ndr, const char *name, enum netr_SamDatabaseID r);
+enum ndr_err_code ndr_push_samr_RejectReason(struct ndr_push *ndr, int ndr_flags, enum samr_RejectReason r);
+enum ndr_err_code ndr_pull_samr_RejectReason(struct ndr_pull *ndr, int ndr_flags, enum samr_RejectReason *r);
+void ndr_print_samr_RejectReason(struct ndr_print *ndr, const char *name, enum samr_RejectReason r);
enum ndr_err_code ndr_push_samr_AcctFlags(struct ndr_push *ndr, int ndr_flags, uint32_t r);
enum ndr_err_code ndr_pull_samr_AcctFlags(struct ndr_pull *ndr, int ndr_flags, uint32_t *r);
void ndr_print_samr_AcctFlags(struct ndr_print *ndr, const char *name, uint32_t r);
@@ -162,6 +168,7 @@ void ndr_print_samr_Role(struct ndr_print *ndr, const char *name, enum samr_Role
enum ndr_err_code ndr_push_samr_PasswordProperties(struct ndr_push *ndr, int ndr_flags, uint32_t r);
enum ndr_err_code ndr_pull_samr_PasswordProperties(struct ndr_pull *ndr, int ndr_flags, uint32_t *r);
void ndr_print_samr_PasswordProperties(struct ndr_print *ndr, const char *name, uint32_t r);
+void ndr_print_samr_DomainServerState(struct ndr_print *ndr, const char *name, enum samr_DomainServerState r);
void ndr_print_samr_DomInfo1(struct ndr_print *ndr, const char *name, const struct samr_DomInfo1 *r);
void ndr_print_samr_DomGeneralInformation(struct ndr_print *ndr, const char *name, const struct samr_DomGeneralInformation *r);
void ndr_print_samr_DomInfo3(struct ndr_print *ndr, const char *name, const struct samr_DomInfo3 *r);
diff --git a/source3/librpc/gen_ndr/ndr_security.c b/source3/librpc/gen_ndr/ndr_security.c
index de899241ab..108f2f689c 100644
--- a/source3/librpc/gen_ndr/ndr_security.c
+++ b/source3/librpc/gen_ndr/ndr_security.c
@@ -4,13 +4,14 @@
#include "librpc/gen_ndr/ndr_security.h"
#include "librpc/gen_ndr/ndr_misc.h"
-static enum ndr_err_code ndr_push_security_ace_flags(struct ndr_push *ndr, int ndr_flags, uint8_t r)
+#include "librpc/gen_ndr/ndr_dom_sid.h"
+_PUBLIC_ enum ndr_err_code ndr_push_security_ace_flags(struct ndr_push *ndr, int ndr_flags, uint8_t r)
{
NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r));
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_security_ace_flags(struct ndr_pull *ndr, int ndr_flags, uint8_t *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_security_ace_flags(struct ndr_pull *ndr, int ndr_flags, uint8_t *r)
{
uint8_t v;
NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &v));
@@ -33,13 +34,13 @@ _PUBLIC_ void ndr_print_security_ace_flags(struct ndr_print *ndr, const char *na
ndr->depth--;
}
-static enum ndr_err_code ndr_push_security_ace_type(struct ndr_push *ndr, int ndr_flags, enum security_ace_type r)
+_PUBLIC_ enum ndr_err_code ndr_push_security_ace_type(struct ndr_push *ndr, int ndr_flags, enum security_ace_type r)
{
NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r));
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_security_ace_type(struct ndr_pull *ndr, int ndr_flags, enum security_ace_type *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_security_ace_type(struct ndr_pull *ndr, int ndr_flags, enum security_ace_type *r)
{
uint8_t v;
NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &v));
@@ -278,7 +279,7 @@ _PUBLIC_ void ndr_print_security_ace_object(struct ndr_print *ndr, const char *n
ndr->depth--;
}
-static enum ndr_err_code ndr_push_security_ace_object_ctr(struct ndr_push *ndr, int ndr_flags, const union security_ace_object_ctr *r)
+_PUBLIC_ enum ndr_err_code ndr_push_security_ace_object_ctr(struct ndr_push *ndr, int ndr_flags, const union security_ace_object_ctr *r)
{
if (ndr_flags & NDR_SCALARS) {
int level = ndr_push_get_switch_value(ndr, r);
@@ -331,7 +332,7 @@ static enum ndr_err_code ndr_push_security_ace_object_ctr(struct ndr_push *ndr,
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_security_ace_object_ctr(struct ndr_pull *ndr, int ndr_flags, union security_ace_object_ctr *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_security_ace_object_ctr(struct ndr_pull *ndr, int ndr_flags, union security_ace_object_ctr *r)
{
int level;
level = ndr_pull_get_switch_value(ndr, r);
@@ -431,25 +432,6 @@ _PUBLIC_ enum ndr_err_code ndr_push_security_ace(struct ndr_push *ndr, int ndr_f
return NDR_ERR_SUCCESS;
}
-_PUBLIC_ enum ndr_err_code ndr_pull_security_ace(struct ndr_pull *ndr, int ndr_flags, struct security_ace *r)
-{
- if (ndr_flags & NDR_SCALARS) {
- NDR_CHECK(ndr_pull_align(ndr, 4));
- NDR_CHECK(ndr_pull_security_ace_type(ndr, NDR_SCALARS, &r->type));
- NDR_CHECK(ndr_pull_security_ace_flags(ndr, NDR_SCALARS, &r->flags));
- NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->size));
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->access_mask));
- NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->object, r->type));
- NDR_CHECK(ndr_pull_security_ace_object_ctr(ndr, NDR_SCALARS, &r->object));
- NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, &r->trustee));
- }
- if (ndr_flags & NDR_BUFFERS) {
- NDR_CHECK(ndr_pull_security_ace_object_ctr(ndr, NDR_BUFFERS, &r->object));
- NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_BUFFERS, &r->trustee));
- }
- return NDR_ERR_SUCCESS;
-}
-
_PUBLIC_ void ndr_print_security_ace(struct ndr_print *ndr, const char *name, const struct security_ace *r)
{
ndr_print_struct(ndr, name, "security_ace");
diff --git a/source3/librpc/gen_ndr/ndr_security.h b/source3/librpc/gen_ndr/ndr_security.h
index 7a2ff74309..bddf1bd2b7 100644
--- a/source3/librpc/gen_ndr/ndr_security.h
+++ b/source3/librpc/gen_ndr/ndr_security.h
@@ -6,13 +6,20 @@
#ifndef _HEADER_NDR_security
#define _HEADER_NDR_security
+#include "librpc/gen_ndr/ndr_dom_sid.h"
#define NDR_SECURITY_CALL_COUNT (0)
+enum ndr_err_code ndr_push_security_ace_flags(struct ndr_push *ndr, int ndr_flags, uint8_t r);
+enum ndr_err_code ndr_pull_security_ace_flags(struct ndr_pull *ndr, int ndr_flags, uint8_t *r);
void ndr_print_security_ace_flags(struct ndr_print *ndr, const char *name, uint8_t r);
+enum ndr_err_code ndr_push_security_ace_type(struct ndr_push *ndr, int ndr_flags, enum security_ace_type r);
+enum ndr_err_code ndr_pull_security_ace_type(struct ndr_pull *ndr, int ndr_flags, enum security_ace_type *r);
void ndr_print_security_ace_type(struct ndr_print *ndr, const char *name, enum security_ace_type r);
void ndr_print_security_ace_object_flags(struct ndr_print *ndr, const char *name, uint32_t r);
void ndr_print_security_ace_object_type(struct ndr_print *ndr, const char *name, const union security_ace_object_type *r);
void ndr_print_security_ace_object_inherited_type(struct ndr_print *ndr, const char *name, const union security_ace_object_inherited_type *r);
void ndr_print_security_ace_object(struct ndr_print *ndr, const char *name, const struct security_ace_object *r);
+enum ndr_err_code ndr_push_security_ace_object_ctr(struct ndr_push *ndr, int ndr_flags, const union security_ace_object_ctr *r);
+enum ndr_err_code ndr_pull_security_ace_object_ctr(struct ndr_pull *ndr, int ndr_flags, union security_ace_object_ctr *r);
void ndr_print_security_ace_object_ctr(struct ndr_print *ndr, const char *name, const union security_ace_object_ctr *r);
enum ndr_err_code ndr_push_security_ace(struct ndr_push *ndr, int ndr_flags, const struct security_ace *r);
enum ndr_err_code ndr_pull_security_ace(struct ndr_pull *ndr, int ndr_flags, struct security_ace *r);
diff --git a/source3/librpc/gen_ndr/ndr_svcctl.c b/source3/librpc/gen_ndr/ndr_svcctl.c
index d04c89b9a1..2bccde9ba0 100644
--- a/source3/librpc/gen_ndr/ndr_svcctl.c
+++ b/source3/librpc/gen_ndr/ndr_svcctl.c
@@ -297,6 +297,34 @@ _PUBLIC_ void ndr_print_svcctl_ServerType(struct ndr_print *ndr, const char *nam
ndr->depth--;
}
+static enum ndr_err_code ndr_push_SERVICE_CONTROL(struct ndr_push *ndr, int ndr_flags, enum SERVICE_CONTROL r)
+{
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
+ return NDR_ERR_SUCCESS;
+}
+
+static enum ndr_err_code ndr_pull_SERVICE_CONTROL(struct ndr_pull *ndr, int ndr_flags, enum SERVICE_CONTROL *r)
+{
+ uint32_t v;
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
+ *r = v;
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_SERVICE_CONTROL(struct ndr_print *ndr, const char *name, enum SERVICE_CONTROL r)
+{
+ const char *val = NULL;
+
+ switch (r) {
+ case SVCCTL_CONTROL_STOP: val = "SVCCTL_CONTROL_STOP"; break;
+ case SVCCTL_CONTROL_PAUSE: val = "SVCCTL_CONTROL_PAUSE"; break;
+ case SVCCTL_CONTROL_CONTINUE: val = "SVCCTL_CONTROL_CONTINUE"; break;
+ case SVCCTL_CONTROL_INTERROGATE: val = "SVCCTL_CONTROL_INTERROGATE"; break;
+ case SVCCTL_CONTROL_SHUTDOWN: val = "SVCCTL_CONTROL_SHUTDOWN"; break;
+ }
+ ndr_print_enum(ndr, name, "ENUM", val, r);
+}
+
static enum ndr_err_code ndr_push_svcctl_MgrAccessMask(struct ndr_push *ndr, int ndr_flags, uint32_t r)
{
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r));
@@ -646,7 +674,7 @@ static enum ndr_err_code ndr_push_svcctl_ControlService(struct ndr_push *ndr, in
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
}
NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS, r->in.handle));
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.control));
+ NDR_CHECK(ndr_push_SERVICE_CONTROL(ndr, NDR_SCALARS, r->in.control));
}
if (flags & NDR_OUT) {
if (r->out.service_status == NULL) {
@@ -672,7 +700,7 @@ static enum ndr_err_code ndr_pull_svcctl_ControlService(struct ndr_pull *ndr, in
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);
- NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.control));
+ NDR_CHECK(ndr_pull_SERVICE_CONTROL(ndr, NDR_SCALARS, &r->in.control));
NDR_PULL_ALLOC(ndr, r->out.service_status);
ZERO_STRUCTP(r->out.service_status);
}
@@ -703,7 +731,7 @@ _PUBLIC_ void ndr_print_svcctl_ControlService(struct ndr_print *ndr, const char
ndr->depth++;
ndr_print_policy_handle(ndr, "handle", r->in.handle);
ndr->depth--;
- ndr_print_uint32(ndr, "control", r->in.control);
+ ndr_print_SERVICE_CONTROL(ndr, "control", r->in.control);
ndr->depth--;
}
if (flags & NDR_OUT) {
@@ -2095,6 +2123,9 @@ static enum ndr_err_code ndr_push_svcctl_EnumServicesStatusW(struct ndr_push *nd
}
}
if (flags & NDR_OUT) {
+ if (r->out.service == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.buf_size));
NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->out.service, r->in.buf_size));
if (r->out.bytes_needed == NULL) {
@@ -2134,6 +2165,9 @@ static enum ndr_err_code ndr_pull_svcctl_EnumServicesStatusW(struct ndr_pull *nd
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.type));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.state));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.buf_size));
+ if (r->in.buf_size < 0 || r->in.buf_size > 262144) {
+ return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
+ }
NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_resume_handle));
if (_ptr_resume_handle) {
NDR_PULL_ALLOC(ndr, r->in.resume_handle);
@@ -2146,6 +2180,8 @@ static enum ndr_err_code ndr_pull_svcctl_EnumServicesStatusW(struct ndr_pull *nd
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->in.resume_handle));
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_resume_handle_0, 0);
}
+ NDR_PULL_ALLOC_N(ndr, r->out.service, r->in.buf_size);
+ memset(r->out.service, 0, (r->in.buf_size) * sizeof(*r->out.service));
NDR_PULL_ALLOC(ndr, r->out.bytes_needed);
ZERO_STRUCTP(r->out.bytes_needed);
NDR_PULL_ALLOC(ndr, r->out.services_returned);
@@ -2153,7 +2189,9 @@ static enum ndr_err_code ndr_pull_svcctl_EnumServicesStatusW(struct ndr_pull *nd
}
if (flags & NDR_OUT) {
NDR_CHECK(ndr_pull_array_size(ndr, &r->out.service));
- NDR_PULL_ALLOC_N(ndr, r->out.service, ndr_get_array_size(ndr, &r->out.service));
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC_N(ndr, r->out.service, ndr_get_array_size(ndr, &r->out.service));
+ }
NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.service, ndr_get_array_size(ndr, &r->out.service)));
if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
NDR_PULL_ALLOC(ndr, r->out.bytes_needed);
@@ -2161,6 +2199,9 @@ static enum ndr_err_code ndr_pull_svcctl_EnumServicesStatusW(struct ndr_pull *nd
_mem_save_bytes_needed_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->out.bytes_needed, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.bytes_needed));
+ if (*r->out.bytes_needed < 0 || *r->out.bytes_needed > 262144) {
+ return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
+ }
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_bytes_needed_0, LIBNDR_FLAG_REF_ALLOC);
if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
NDR_PULL_ALLOC(ndr, r->out.services_returned);
@@ -2168,6 +2209,9 @@ static enum ndr_err_code ndr_pull_svcctl_EnumServicesStatusW(struct ndr_pull *nd
_mem_save_services_returned_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->out.services_returned, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.services_returned));
+ if (*r->out.services_returned < 0 || *r->out.services_returned > 262144) {
+ return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
+ }
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_services_returned_0, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_resume_handle));
if (_ptr_resume_handle) {
@@ -2217,7 +2261,10 @@ _PUBLIC_ void ndr_print_svcctl_EnumServicesStatusW(struct ndr_print *ndr, const
if (flags & NDR_OUT) {
ndr_print_struct(ndr, "out", "svcctl_EnumServicesStatusW");
ndr->depth++;
+ ndr_print_ptr(ndr, "service", r->out.service);
+ ndr->depth++;
ndr_print_array_uint8(ndr, "service", r->out.service, r->in.buf_size);
+ ndr->depth--;
ndr_print_ptr(ndr, "bytes_needed", r->out.bytes_needed);
ndr->depth++;
ndr_print_uint32(ndr, "bytes_needed", *r->out.bytes_needed);
@@ -5305,6 +5352,10 @@ static enum ndr_err_code ndr_push_svcctl_QueryServiceConfig2W(struct ndr_push *n
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.buf_size));
}
if (flags & NDR_OUT) {
+ if (r->out.buffer == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.buf_size));
NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->out.buffer, r->in.buf_size));
if (r->out.bytes_needed == NULL) {
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
@@ -5331,20 +5382,34 @@ static enum ndr_err_code ndr_pull_svcctl_QueryServiceConfig2W(struct ndr_pull *n
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.info_level));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.buf_size));
+ if (r->in.buf_size < 0 || r->in.buf_size > 8192) {
+ return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
+ }
+ NDR_PULL_ALLOC_N(ndr, r->out.buffer, r->in.buf_size);
+ memset(r->out.buffer, 0, (r->in.buf_size) * sizeof(*r->out.buffer));
NDR_PULL_ALLOC(ndr, r->out.bytes_needed);
ZERO_STRUCTP(r->out.bytes_needed);
}
if (flags & NDR_OUT) {
- NDR_PULL_ALLOC_N(ndr, r->out.buffer, r->in.buf_size);
- NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.buffer, r->in.buf_size));
+ NDR_CHECK(ndr_pull_array_size(ndr, &r->out.buffer));
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC_N(ndr, r->out.buffer, ndr_get_array_size(ndr, &r->out.buffer));
+ }
+ NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.buffer, ndr_get_array_size(ndr, &r->out.buffer)));
if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
NDR_PULL_ALLOC(ndr, r->out.bytes_needed);
}
_mem_save_bytes_needed_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->out.bytes_needed, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.bytes_needed));
+ if (*r->out.bytes_needed < 0 || *r->out.bytes_needed > 8192) {
+ return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
+ }
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_bytes_needed_0, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result));
+ if (r->out.buffer) {
+ NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->out.buffer, r->in.buf_size));
+ }
}
return NDR_ERR_SUCCESS;
}
@@ -5370,7 +5435,10 @@ _PUBLIC_ void ndr_print_svcctl_QueryServiceConfig2W(struct ndr_print *ndr, const
if (flags & NDR_OUT) {
ndr_print_struct(ndr, "out", "svcctl_QueryServiceConfig2W");
ndr->depth++;
+ ndr_print_ptr(ndr, "buffer", r->out.buffer);
+ ndr->depth++;
ndr_print_array_uint8(ndr, "buffer", r->out.buffer, r->in.buf_size);
+ ndr->depth--;
ndr_print_ptr(ndr, "bytes_needed", r->out.bytes_needed);
ndr->depth++;
ndr_print_uint32(ndr, "bytes_needed", *r->out.bytes_needed);
@@ -5392,6 +5460,10 @@ static enum ndr_err_code ndr_push_svcctl_QueryServiceStatusEx(struct ndr_push *n
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.buf_size));
}
if (flags & NDR_OUT) {
+ if (r->out.buffer == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.buf_size));
NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->out.buffer, r->in.buf_size));
if (r->out.bytes_needed == NULL) {
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
@@ -5418,20 +5490,34 @@ static enum ndr_err_code ndr_pull_svcctl_QueryServiceStatusEx(struct ndr_pull *n
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.info_level));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.buf_size));
+ if (r->in.buf_size < 0 || r->in.buf_size > 8192) {
+ return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
+ }
+ NDR_PULL_ALLOC_N(ndr, r->out.buffer, r->in.buf_size);
+ memset(r->out.buffer, 0, (r->in.buf_size) * sizeof(*r->out.buffer));
NDR_PULL_ALLOC(ndr, r->out.bytes_needed);
ZERO_STRUCTP(r->out.bytes_needed);
}
if (flags & NDR_OUT) {
- NDR_PULL_ALLOC_N(ndr, r->out.buffer, r->in.buf_size);
- NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.buffer, r->in.buf_size));
+ NDR_CHECK(ndr_pull_array_size(ndr, &r->out.buffer));
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC_N(ndr, r->out.buffer, ndr_get_array_size(ndr, &r->out.buffer));
+ }
+ NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.buffer, ndr_get_array_size(ndr, &r->out.buffer)));
if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
NDR_PULL_ALLOC(ndr, r->out.bytes_needed);
}
_mem_save_bytes_needed_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->out.bytes_needed, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.bytes_needed));
+ if (*r->out.bytes_needed < 0 || *r->out.bytes_needed > 8192) {
+ return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
+ }
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_bytes_needed_0, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result));
+ if (r->out.buffer) {
+ NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->out.buffer, r->in.buf_size));
+ }
}
return NDR_ERR_SUCCESS;
}
@@ -5457,7 +5543,10 @@ _PUBLIC_ void ndr_print_svcctl_QueryServiceStatusEx(struct ndr_print *ndr, const
if (flags & NDR_OUT) {
ndr_print_struct(ndr, "out", "svcctl_QueryServiceStatusEx");
ndr->depth++;
+ ndr_print_ptr(ndr, "buffer", r->out.buffer);
+ ndr->depth++;
ndr_print_array_uint8(ndr, "buffer", r->out.buffer, r->in.buf_size);
+ ndr->depth--;
ndr_print_ptr(ndr, "bytes_needed", r->out.bytes_needed);
ndr->depth++;
ndr_print_uint32(ndr, "bytes_needed", *r->out.bytes_needed);
@@ -5688,8 +5777,19 @@ static enum ndr_err_code ndr_push_EnumServicesStatusExW(struct ndr_push *ndr, in
if (r->in.resume_handle) {
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->in.resume_handle));
}
+ NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.group_name));
+ if (r->in.group_name) {
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.group_name, CH_UTF16)));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.group_name, CH_UTF16)));
+ NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.group_name, ndr_charset_length(r->in.group_name, CH_UTF16), sizeof(uint16_t), CH_UTF16));
+ }
}
if (flags & NDR_OUT) {
+ if (r->out.services == NULL) {
+ return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
+ }
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.buf_size));
NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->out.services, r->in.buf_size));
if (r->out.bytes_needed == NULL) {
return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
@@ -5703,16 +5803,6 @@ static enum ndr_err_code ndr_push_EnumServicesStatusExW(struct ndr_push *ndr, in
if (r->out.resume_handle) {
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.resume_handle));
}
- if (r->out.group_name == NULL) {
- return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer");
- }
- NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.group_name));
- if (*r->out.group_name) {
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(*r->out.group_name, CH_UTF16)));
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
- NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(*r->out.group_name, CH_UTF16)));
- NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, *r->out.group_name, ndr_charset_length(*r->out.group_name, CH_UTF16), sizeof(uint16_t), CH_UTF16));
- }
NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result));
}
return NDR_ERR_SUCCESS;
@@ -5727,7 +5817,6 @@ static enum ndr_err_code ndr_pull_EnumServicesStatusExW(struct ndr_pull *ndr, in
TALLOC_CTX *_mem_save_service_returned_0;
TALLOC_CTX *_mem_save_resume_handle_0;
TALLOC_CTX *_mem_save_group_name_0;
- TALLOC_CTX *_mem_save_group_name_1;
if (flags & NDR_IN) {
ZERO_STRUCT(r->out);
@@ -5742,6 +5831,9 @@ static enum ndr_err_code ndr_pull_EnumServicesStatusExW(struct ndr_pull *ndr, in
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.type));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.state));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.buf_size));
+ if (r->in.buf_size < 0 || r->in.buf_size > 262144) {
+ return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
+ }
NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_resume_handle));
if (_ptr_resume_handle) {
NDR_PULL_ALLOC(ndr, r->in.resume_handle);
@@ -5752,24 +5844,51 @@ static enum ndr_err_code ndr_pull_EnumServicesStatusExW(struct ndr_pull *ndr, in
_mem_save_resume_handle_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->in.resume_handle, 0);
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->in.resume_handle));
+ if (*r->in.resume_handle < 0 || *r->in.resume_handle > 262144) {
+ return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
+ }
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_resume_handle_0, 0);
}
+ NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_group_name));
+ if (_ptr_group_name) {
+ NDR_PULL_ALLOC(ndr, r->in.group_name);
+ } else {
+ r->in.group_name = NULL;
+ }
+ if (r->in.group_name) {
+ _mem_save_group_name_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->in.group_name, 0);
+ NDR_CHECK(ndr_pull_array_size(ndr, &r->in.group_name));
+ NDR_CHECK(ndr_pull_array_length(ndr, &r->in.group_name));
+ if (ndr_get_array_length(ndr, &r->in.group_name) > ndr_get_array_size(ndr, &r->in.group_name)) {
+ return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->in.group_name), ndr_get_array_length(ndr, &r->in.group_name));
+ }
+ NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.group_name), sizeof(uint16_t)));
+ NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.group_name, ndr_get_array_length(ndr, &r->in.group_name), sizeof(uint16_t), CH_UTF16));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_group_name_0, 0);
+ }
+ NDR_PULL_ALLOC_N(ndr, r->out.services, r->in.buf_size);
+ memset(r->out.services, 0, (r->in.buf_size) * sizeof(*r->out.services));
NDR_PULL_ALLOC(ndr, r->out.bytes_needed);
ZERO_STRUCTP(r->out.bytes_needed);
NDR_PULL_ALLOC(ndr, r->out.service_returned);
ZERO_STRUCTP(r->out.service_returned);
- NDR_PULL_ALLOC(ndr, r->out.group_name);
- ZERO_STRUCTP(r->out.group_name);
}
if (flags & NDR_OUT) {
- NDR_PULL_ALLOC_N(ndr, r->out.services, r->in.buf_size);
- NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.services, r->in.buf_size));
+ NDR_CHECK(ndr_pull_array_size(ndr, &r->out.services));
+ if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
+ NDR_PULL_ALLOC_N(ndr, r->out.services, ndr_get_array_size(ndr, &r->out.services));
+ }
+ NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.services, ndr_get_array_size(ndr, &r->out.services)));
if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
NDR_PULL_ALLOC(ndr, r->out.bytes_needed);
}
_mem_save_bytes_needed_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->out.bytes_needed, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.bytes_needed));
+ if (*r->out.bytes_needed < 0 || *r->out.bytes_needed > 262144) {
+ return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
+ }
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_bytes_needed_0, LIBNDR_FLAG_REF_ALLOC);
if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
NDR_PULL_ALLOC(ndr, r->out.service_returned);
@@ -5777,6 +5896,9 @@ static enum ndr_err_code ndr_pull_EnumServicesStatusExW(struct ndr_pull *ndr, in
_mem_save_service_returned_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->out.service_returned, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.service_returned));
+ if (*r->out.service_returned < 0 || *r->out.service_returned > 262144) {
+ return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
+ }
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_service_returned_0, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_resume_handle));
if (_ptr_resume_handle) {
@@ -5788,33 +5910,15 @@ static enum ndr_err_code ndr_pull_EnumServicesStatusExW(struct ndr_pull *ndr, in
_mem_save_resume_handle_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->out.resume_handle, 0);
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.resume_handle));
- NDR_PULL_SET_MEM_CTX(ndr, _mem_save_resume_handle_0, 0);
- }
- if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {
- NDR_PULL_ALLOC(ndr, r->out.group_name);
- }
- _mem_save_group_name_0 = NDR_PULL_GET_MEM_CTX(ndr);
- NDR_PULL_SET_MEM_CTX(ndr, r->out.group_name, LIBNDR_FLAG_REF_ALLOC);
- NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_group_name));
- if (_ptr_group_name) {
- NDR_PULL_ALLOC(ndr, *r->out.group_name);
- } else {
- *r->out.group_name = NULL;
- }
- if (*r->out.group_name) {
- _mem_save_group_name_1 = NDR_PULL_GET_MEM_CTX(ndr);
- NDR_PULL_SET_MEM_CTX(ndr, *r->out.group_name, 0);
- NDR_CHECK(ndr_pull_array_size(ndr, r->out.group_name));
- NDR_CHECK(ndr_pull_array_length(ndr, r->out.group_name));
- if (ndr_get_array_length(ndr, r->out.group_name) > ndr_get_array_size(ndr, r->out.group_name)) {
- return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, r->out.group_name), ndr_get_array_length(ndr, r->out.group_name));
+ if (*r->out.resume_handle < 0 || *r->out.resume_handle > 262144) {
+ return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range");
}
- NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, r->out.group_name), sizeof(uint16_t)));
- NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, r->out.group_name, ndr_get_array_length(ndr, r->out.group_name), sizeof(uint16_t), CH_UTF16));
- NDR_PULL_SET_MEM_CTX(ndr, _mem_save_group_name_1, 0);
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_resume_handle_0, 0);
}
- NDR_PULL_SET_MEM_CTX(ndr, _mem_save_group_name_0, LIBNDR_FLAG_REF_ALLOC);
NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result));
+ if (r->out.services) {
+ NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->out.services, r->in.buf_size));
+ }
}
return NDR_ERR_SUCCESS;
}
@@ -5843,12 +5947,21 @@ _PUBLIC_ void ndr_print_EnumServicesStatusExW(struct ndr_print *ndr, const char
ndr_print_uint32(ndr, "resume_handle", *r->in.resume_handle);
}
ndr->depth--;
+ ndr_print_ptr(ndr, "group_name", r->in.group_name);
+ ndr->depth++;
+ if (r->in.group_name) {
+ ndr_print_string(ndr, "group_name", r->in.group_name);
+ }
+ ndr->depth--;
ndr->depth--;
}
if (flags & NDR_OUT) {
ndr_print_struct(ndr, "out", "EnumServicesStatusExW");
ndr->depth++;
+ ndr_print_ptr(ndr, "services", r->out.services);
+ ndr->depth++;
ndr_print_array_uint8(ndr, "services", r->out.services, r->in.buf_size);
+ ndr->depth--;
ndr_print_ptr(ndr, "bytes_needed", r->out.bytes_needed);
ndr->depth++;
ndr_print_uint32(ndr, "bytes_needed", *r->out.bytes_needed);
@@ -5863,15 +5976,6 @@ _PUBLIC_ void ndr_print_EnumServicesStatusExW(struct ndr_print *ndr, const char
ndr_print_uint32(ndr, "resume_handle", *r->out.resume_handle);
}
ndr->depth--;
- ndr_print_ptr(ndr, "group_name", r->out.group_name);
- ndr->depth++;
- ndr_print_ptr(ndr, "group_name", *r->out.group_name);
- ndr->depth++;
- if (*r->out.group_name) {
- ndr_print_string(ndr, "group_name", *r->out.group_name);
- }
- ndr->depth--;
- ndr->depth--;
ndr_print_WERROR(ndr, "result", r->out.result);
ndr->depth--;
}
diff --git a/source3/librpc/gen_ndr/ndr_svcctl.h b/source3/librpc/gen_ndr/ndr_svcctl.h
index 0bebd3401a..8d7739a7db 100644
--- a/source3/librpc/gen_ndr/ndr_svcctl.h
+++ b/source3/librpc/gen_ndr/ndr_svcctl.h
@@ -106,6 +106,7 @@ void ndr_print_ENUM_SERVICE_STATUS(struct ndr_print *ndr, const char *name, cons
enum ndr_err_code ndr_push_svcctl_ServerType(struct ndr_push *ndr, int ndr_flags, uint32_t r);
enum ndr_err_code ndr_pull_svcctl_ServerType(struct ndr_pull *ndr, int ndr_flags, uint32_t *r);
void ndr_print_svcctl_ServerType(struct ndr_print *ndr, const char *name, uint32_t r);
+void ndr_print_SERVICE_CONTROL(struct ndr_print *ndr, const char *name, enum SERVICE_CONTROL r);
void ndr_print_svcctl_MgrAccessMask(struct ndr_print *ndr, const char *name, uint32_t r);
void ndr_print_svcctl_ServiceAccessMask(struct ndr_print *ndr, const char *name, uint32_t r);
enum ndr_err_code ndr_push_QUERY_SERVICE_CONFIG(struct ndr_push *ndr, int ndr_flags, const struct QUERY_SERVICE_CONFIG *r);
diff --git a/source3/librpc/gen_ndr/ndr_xattr.c b/source3/librpc/gen_ndr/ndr_xattr.c
index 0e9dda9f47..75781d763d 100644
--- a/source3/librpc/gen_ndr/ndr_xattr.c
+++ b/source3/librpc/gen_ndr/ndr_xattr.c
@@ -546,12 +546,12 @@ _PUBLIC_ void ndr_print_xattr_DosStreams(struct ndr_print *ndr, const char *name
ndr->depth--;
}
-_PUBLIC_ enum ndr_err_code ndr_push_security_descriptor_timestamp(struct ndr_push *ndr, int ndr_flags, const struct security_descriptor_timestamp *r)
+_PUBLIC_ enum ndr_err_code ndr_push_security_descriptor_hash(struct ndr_push *ndr, int ndr_flags, const struct security_descriptor_hash *r)
{
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_push_align(ndr, 4));
NDR_CHECK(ndr_push_unique_ptr(ndr, r->sd));
- NDR_CHECK(ndr_push_NTTIME(ndr, NDR_SCALARS, r->last_changed));
+ NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->hash, 16));
}
if (ndr_flags & NDR_BUFFERS) {
if (r->sd) {
@@ -561,7 +561,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_security_descriptor_timestamp(struct ndr_pus
return NDR_ERR_SUCCESS;
}
-_PUBLIC_ enum ndr_err_code ndr_pull_security_descriptor_timestamp(struct ndr_pull *ndr, int ndr_flags, struct security_descriptor_timestamp *r)
+_PUBLIC_ enum ndr_err_code ndr_pull_security_descriptor_hash(struct ndr_pull *ndr, int ndr_flags, struct security_descriptor_hash *r)
{
uint32_t _ptr_sd;
TALLOC_CTX *_mem_save_sd_0;
@@ -573,7 +573,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_security_descriptor_timestamp(struct ndr_pul
} else {
r->sd = NULL;
}
- NDR_CHECK(ndr_pull_NTTIME(ndr, NDR_SCALARS, &r->last_changed));
+ NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->hash, 16));
}
if (ndr_flags & NDR_BUFFERS) {
if (r->sd) {
@@ -586,9 +586,9 @@ _PUBLIC_ enum ndr_err_code ndr_pull_security_descriptor_timestamp(struct ndr_pul
return NDR_ERR_SUCCESS;
}
-_PUBLIC_ void ndr_print_security_descriptor_timestamp(struct ndr_print *ndr, const char *name, const struct security_descriptor_timestamp *r)
+_PUBLIC_ void ndr_print_security_descriptor_hash(struct ndr_print *ndr, const char *name, const struct security_descriptor_hash *r)
{
- ndr_print_struct(ndr, name, "security_descriptor_timestamp");
+ ndr_print_struct(ndr, name, "security_descriptor_hash");
ndr->depth++;
ndr_print_ptr(ndr, "sd", r->sd);
ndr->depth++;
@@ -596,7 +596,7 @@ _PUBLIC_ void ndr_print_security_descriptor_timestamp(struct ndr_print *ndr, con
ndr_print_security_descriptor(ndr, "sd", r->sd);
}
ndr->depth--;
- ndr_print_NTTIME(ndr, "last_changed", r->last_changed);
+ ndr_print_array_uint8(ndr, "hash", r->hash, 16);
ndr->depth--;
}
@@ -611,7 +611,7 @@ static enum ndr_err_code ndr_push_xattr_NTACL_Info(struct ndr_push *ndr, int ndr
break; }
case 2: {
- NDR_CHECK(ndr_push_unique_ptr(ndr, r->sd_ts));
+ NDR_CHECK(ndr_push_unique_ptr(ndr, r->sd_hs));
break; }
default:
@@ -628,8 +628,8 @@ static enum ndr_err_code ndr_push_xattr_NTACL_Info(struct ndr_push *ndr, int ndr
break;
case 2:
- if (r->sd_ts) {
- NDR_CHECK(ndr_push_security_descriptor_timestamp(ndr, NDR_SCALARS|NDR_BUFFERS, r->sd_ts));
+ if (r->sd_hs) {
+ NDR_CHECK(ndr_push_security_descriptor_hash(ndr, NDR_SCALARS|NDR_BUFFERS, r->sd_hs));
}
break;
@@ -645,7 +645,7 @@ static enum ndr_err_code ndr_pull_xattr_NTACL_Info(struct ndr_pull *ndr, int ndr
int level;
uint16_t _level;
TALLOC_CTX *_mem_save_sd_0;
- TALLOC_CTX *_mem_save_sd_ts_0;
+ TALLOC_CTX *_mem_save_sd_hs_0;
level = ndr_pull_get_switch_value(ndr, r);
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &_level));
@@ -664,12 +664,12 @@ static enum ndr_err_code ndr_pull_xattr_NTACL_Info(struct ndr_pull *ndr, int ndr
break; }
case 2: {
- uint32_t _ptr_sd_ts;
- NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_sd_ts));
- if (_ptr_sd_ts) {
- NDR_PULL_ALLOC(ndr, r->sd_ts);
+ uint32_t _ptr_sd_hs;
+ NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_sd_hs));
+ if (_ptr_sd_hs) {
+ NDR_PULL_ALLOC(ndr, r->sd_hs);
} else {
- r->sd_ts = NULL;
+ r->sd_hs = NULL;
}
break; }
@@ -689,11 +689,11 @@ static enum ndr_err_code ndr_pull_xattr_NTACL_Info(struct ndr_pull *ndr, int ndr
break;
case 2:
- if (r->sd_ts) {
- _mem_save_sd_ts_0 = NDR_PULL_GET_MEM_CTX(ndr);
- NDR_PULL_SET_MEM_CTX(ndr, r->sd_ts, 0);
- NDR_CHECK(ndr_pull_security_descriptor_timestamp(ndr, NDR_SCALARS|NDR_BUFFERS, r->sd_ts));
- NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sd_ts_0, 0);
+ if (r->sd_hs) {
+ _mem_save_sd_hs_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->sd_hs, 0);
+ NDR_CHECK(ndr_pull_security_descriptor_hash(ndr, NDR_SCALARS|NDR_BUFFERS, r->sd_hs));
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sd_hs_0, 0);
}
break;
@@ -720,10 +720,10 @@ _PUBLIC_ void ndr_print_xattr_NTACL_Info(struct ndr_print *ndr, const char *name
break;
case 2:
- ndr_print_ptr(ndr, "sd_ts", r->sd_ts);
+ ndr_print_ptr(ndr, "sd_hs", r->sd_hs);
ndr->depth++;
- if (r->sd_ts) {
- ndr_print_security_descriptor_timestamp(ndr, "sd_ts", r->sd_ts);
+ if (r->sd_hs) {
+ ndr_print_security_descriptor_hash(ndr, "sd_hs", r->sd_hs);
}
ndr->depth--;
break;
diff --git a/source3/librpc/gen_ndr/ndr_xattr.h b/source3/librpc/gen_ndr/ndr_xattr.h
index 38701b1aca..c565e8513a 100644
--- a/source3/librpc/gen_ndr/ndr_xattr.h
+++ b/source3/librpc/gen_ndr/ndr_xattr.h
@@ -24,9 +24,9 @@ void ndr_print_xattr_DosStream(struct ndr_print *ndr, const char *name, const st
enum ndr_err_code ndr_push_xattr_DosStreams(struct ndr_push *ndr, int ndr_flags, const struct xattr_DosStreams *r);
enum ndr_err_code ndr_pull_xattr_DosStreams(struct ndr_pull *ndr, int ndr_flags, struct xattr_DosStreams *r);
void ndr_print_xattr_DosStreams(struct ndr_print *ndr, const char *name, const struct xattr_DosStreams *r);
-enum ndr_err_code ndr_push_security_descriptor_timestamp(struct ndr_push *ndr, int ndr_flags, const struct security_descriptor_timestamp *r);
-enum ndr_err_code ndr_pull_security_descriptor_timestamp(struct ndr_pull *ndr, int ndr_flags, struct security_descriptor_timestamp *r);
-void ndr_print_security_descriptor_timestamp(struct ndr_print *ndr, const char *name, const struct security_descriptor_timestamp *r);
+enum ndr_err_code ndr_push_security_descriptor_hash(struct ndr_push *ndr, int ndr_flags, const struct security_descriptor_hash *r);
+enum ndr_err_code ndr_pull_security_descriptor_hash(struct ndr_pull *ndr, int ndr_flags, struct security_descriptor_hash *r);
+void ndr_print_security_descriptor_hash(struct ndr_print *ndr, const char *name, const struct security_descriptor_hash *r);
void ndr_print_xattr_NTACL_Info(struct ndr_print *ndr, const char *name, const union xattr_NTACL_Info *r);
enum ndr_err_code ndr_push_xattr_NTACL(struct ndr_push *ndr, int ndr_flags, const struct xattr_NTACL *r);
enum ndr_err_code ndr_pull_xattr_NTACL(struct ndr_pull *ndr, int ndr_flags, struct xattr_NTACL *r);
diff --git a/source3/librpc/gen_ndr/netlogon.h b/source3/librpc/gen_ndr/netlogon.h
index fd9e08b461..4d9b549e75 100644
--- a/source3/librpc/gen_ndr/netlogon.h
+++ b/source3/librpc/gen_ndr/netlogon.h
@@ -7,11 +7,17 @@
#include "librpc/gen_ndr/samr.h"
#include "librpc/gen_ndr/security.h"
#include "librpc/gen_ndr/nbt.h"
+#define netr_DeltaEnum8Bit netr_DeltaEnum
+#define netr_SamDatabaseID8Bit netr_SamDatabaseID
#ifndef _HEADER_netlogon
#define _HEADER_netlogon
#define DSGETDC_VALID_FLAGS ( (DS_FORCE_REDISCOVERY|DS_DIRECTORY_SERVICE_REQUIRED|DS_DIRECTORY_SERVICE_PREFERRED|DS_GC_SERVER_REQUIRED|DS_PDC_REQUIRED|DS_BACKGROUND_ONLY|DS_IP_REQUIRED|DS_KDC_REQUIRED|DS_TIMESERV_REQUIRED|DS_WRITABLE_REQUIRED|DS_GOOD_TIMESERV_PREFERRED|DS_AVOID_SELF|DS_ONLY_LDAP_NEEDED|DS_IS_FLAT_NAME|DS_IS_DNS_NAME|DS_RETURN_FLAT_NAME|DS_RETURN_DNS_NAME) )
#define DS_GFTI_UPDATE_TDO ( 0x1 )
+enum netr_DeltaEnum8Bit;
+
+enum netr_SamDatabaseID8Bit;
+
struct netr_UasInfo {
const char *account_name;/* [unique,charset(UTF16)] */
uint32_t priv;
@@ -324,7 +330,7 @@ struct netr_DELTA_USER {
uint8_t lm_password_present;
uint8_t password_expired;
struct lsa_String comment;
- struct lsa_String parameters;
+ struct lsa_BinaryString parameters;
uint16_t country_code;
uint16_t code_page;
struct netr_USER_PRIVATE_INFO user_private_info;
@@ -712,6 +718,28 @@ union netr_CONTROL_DATA_INFORMATION {
#define NETLOGON_NEG_AUTHENTICATED_RPC_LSASS ( 0x20000000 )
#define NETLOGON_NEG_SCHANNEL ( 0x40000000 )
+/* bitmap netr_ChangeLogFlags */
+#define NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED ( 0x0001 )
+#define NETR_CHANGELOG_CHANGED_PASSWORD ( 0x0002 )
+#define NETR_CHANGELOG_SID_INCLUDED ( 0x0004 )
+#define NETR_CHANGELOG_NAME_INCLUDED ( 0x0008 )
+#define NETR_CHANGELOG_FIRST_PROMOTION_OBJ ( 0x0010 )
+
+union netr_ChangeLogObject {
+ struct dom_sid object_sid;/* [case(NETR_CHANGELOG_SID_INCLUDED)] */
+ const char * object_name;/* [flag(LIBNDR_FLAG_STR_NULLTERM),case(NETR_CHANGELOG_NAME_INCLUDED)] */
+}/* [nodiscriminant] */;
+
+struct netr_ChangeLogEntry {
+ uint32_t serial_number1;
+ uint32_t serial_number2;
+ uint32_t object_rid;
+ uint16_t flags;
+ enum netr_SamDatabaseID8Bit db_index;
+ enum netr_DeltaEnum8Bit delta_type;
+ union netr_ChangeLogObject object;/* [switch_is(flags&(NETR_CHANGELOG_SID_INCLUDED|NETR_CHANGELOG_NAME_INCLUDED))] */
+}/* [gensize,public] */;
+
struct netr_Blob {
uint32_t length;
uint8_t *data;/* [unique,size_is(length)] */
@@ -1252,8 +1280,8 @@ struct netr_DatabaseRedo {
const char *logon_server;/* [charset(UTF16)] */
const char *computername;/* [charset(UTF16)] */
struct netr_Authenticator *credential;/* [ref] */
- uint8_t *change_log_entry;/* [ref,size_is(change_log_entry_size)] */
- uint32_t change_log_entry_size;
+ struct netr_ChangeLogEntry change_log_entry;/* [subcontext_size(change_log_entry_size),subcontext(4)] */
+ uint32_t change_log_entry_size;/* [value(ndr_size_netr_ChangeLogEntry(&change_log_entry,ndr->flags))] */
struct netr_Authenticator *return_authenticator;/* [ref] */
} in;
diff --git a/source3/librpc/gen_ndr/ntsvcs.h b/source3/librpc/gen_ndr/ntsvcs.h
index b56b552ae2..5021aa2252 100644
--- a/source3/librpc/gen_ndr/ntsvcs.h
+++ b/source3/librpc/gen_ndr/ntsvcs.h
@@ -2,14 +2,15 @@
#include <stdint.h>
+#include "librpc/gen_ndr/winreg.h"
#ifndef _HEADER_ntsvcs
#define _HEADER_ntsvcs
#define DEV_REGPROP_DESC ( 1 )
struct PNP_HwProfInfo {
- uint32_t unknown1;
- uint16_t unknown2[160];
- uint32_t unknown3;
+ uint32_t profile_handle;
+ uint16_t friendly_name[80];
+ uint32_t flags;
};
@@ -142,14 +143,14 @@ struct PNP_GetDeviceRegProp {
const char *devicepath;/* [ref,charset(UTF16)] */
uint32_t property;
uint32_t flags;
- uint32_t *reg_data_type;/* [ref] */
+ enum winreg_Type *reg_data_type;/* [ref] */
uint32_t *buffer_size;/* [ref] */
uint32_t *needed;/* [ref] */
} in;
struct {
uint8_t *buffer;/* [ref,length_is(*buffer_size),size_is(*buffer_size)] */
- uint32_t *reg_data_type;/* [ref] */
+ enum winreg_Type *reg_data_type;/* [ref] */
uint32_t *buffer_size;/* [ref] */
uint32_t *needed;/* [ref] */
WERROR result;
@@ -368,20 +369,20 @@ struct PNP_RequestEjectPC {
struct PNP_HwProfFlags {
struct {
- uint32_t unknown1;
+ uint32_t action;
const char *devicepath;/* [ref,charset(UTF16)] */
- uint32_t unknown2;
+ uint32_t config;
const char *unknown5;/* [unique,charset(UTF16)] */
- uint32_t unknown6;
- uint32_t unknown7;
- uint32_t *unknown3;/* [ref] */
- uint16_t *unknown4;/* [unique] */
+ uint32_t name_length;
+ uint32_t flags;
+ uint32_t *profile_flags;/* [ref] */
+ uint16_t *veto_type;/* [unique] */
} in;
struct {
const char **unknown5a;/* [unique,charset(UTF16)] */
- uint32_t *unknown3;/* [ref] */
- uint16_t *unknown4;/* [unique] */
+ uint32_t *profile_flags;/* [ref] */
+ uint16_t *veto_type;/* [unique] */
WERROR result;
} out;
@@ -391,8 +392,8 @@ struct PNP_HwProfFlags {
struct PNP_GetHwProfInfo {
struct {
uint32_t idx;
- uint32_t unknown1;
- uint32_t unknown2;
+ uint32_t size;
+ uint32_t flags;
struct PNP_HwProfInfo *info;/* [ref] */
} in;
diff --git a/source3/librpc/gen_ndr/samr.h b/source3/librpc/gen_ndr/samr.h
index 8c8f3f70f9..537f144940 100644
--- a/source3/librpc/gen_ndr/samr.h
+++ b/source3/librpc/gen_ndr/samr.h
@@ -33,11 +33,41 @@
#define GENERIC_RIGHTS_ALIAS_READ ( (STANDARD_RIGHTS_READ_ACCESS|SAMR_ALIAS_ACCESS_GET_MEMBERS) )
#define GENERIC_RIGHTS_ALIAS_WRITE ( (STANDARD_RIGHTS_WRITE_ACCESS|SAMR_ALIAS_ACCESS_REMOVE_MEMBER|SAMR_ALIAS_ACCESS_ADD_MEMBER|SAMR_ALIAS_ACCESS_SET_INFO) )
#define GENERIC_RIGHTS_ALIAS_EXECUTE ( (STANDARD_RIGHTS_EXECUTE_ACCESS|SAMR_ALIAS_ACCESS_LOOKUP_INFO) )
-#define MAX_SAM_ENTRIES_W2K ( 0x400 )
-#define MAX_SAM_ENTRIES_W95 ( 50 )
#define SAMR_ENUM_USERS_MULTIPLIER ( 54 )
#define PASS_MUST_CHANGE_AT_NEXT_LOGON ( 0x01 )
#define PASS_DONT_CHANGE_AT_NEXT_LOGON ( 0x00 )
+enum netr_SamDatabaseID
+#ifndef USE_UINT_ENUMS
+ {
+ SAM_DATABASE_DOMAIN=0,
+ SAM_DATABASE_BUILTIN=1,
+ SAM_DATABASE_PRIVS=2
+}
+#else
+ { __donnot_use_enum_netr_SamDatabaseID=0x7FFFFFFF}
+#define SAM_DATABASE_DOMAIN ( 0 )
+#define SAM_DATABASE_BUILTIN ( 1 )
+#define SAM_DATABASE_PRIVS ( 2 )
+#endif
+;
+
+enum samr_RejectReason
+#ifndef USE_UINT_ENUMS
+ {
+ SAMR_REJECT_OTHER=0,
+ SAMR_REJECT_TOO_SHORT=1,
+ SAMR_REJECT_IN_HISTORY=2,
+ SAMR_REJECT_COMPLEXITY=5
+}
+#else
+ { __donnot_use_enum_samr_RejectReason=0x7FFFFFFF}
+#define SAMR_REJECT_OTHER ( 0 )
+#define SAMR_REJECT_TOO_SHORT ( 1 )
+#define SAMR_REJECT_IN_HISTORY ( 2 )
+#define SAMR_REJECT_COMPLEXITY ( 5 )
+#endif
+;
+
/* bitmap samr_AcctFlags */
#define ACB_DISABLED ( 0x00000001 )
#define ACB_HOMDIRREQ ( 0x00000002 )
@@ -142,6 +172,19 @@ enum samr_Role
#define DOMAIN_PASSWORD_STORE_CLEARTEXT ( 0x00000010 )
#define DOMAIN_REFUSE_PASSWORD_CHANGE ( 0x00000020 )
+enum samr_DomainServerState
+#ifndef USE_UINT_ENUMS
+ {
+ DOMAIN_SERVER_ENABLED=1,
+ DOMAIN_SERVER_DISABLED=2
+}
+#else
+ { __donnot_use_enum_samr_DomainServerState=0x7FFFFFFF}
+#define DOMAIN_SERVER_ENABLED ( 1 )
+#define DOMAIN_SERVER_DISABLED ( 2 )
+#endif
+;
+
struct samr_DomInfo1 {
uint16_t min_password_length;
uint16_t password_history_length;
@@ -156,7 +199,7 @@ struct samr_DomGeneralInformation {
struct lsa_String domain_name;
struct lsa_String primary;
uint64_t sequence_num;
- uint32_t unknown2;
+ enum samr_DomainServerState domain_server_state;
enum samr_Role role;
uint32_t unknown3;
uint32_t num_users;
@@ -190,7 +233,7 @@ struct samr_DomInfo8 {
};
struct samr_DomInfo9 {
- uint32_t unknown;
+ enum samr_DomainServerState domain_server_state;
};
struct samr_DomGeneralInformation2 {
@@ -524,7 +567,7 @@ struct samr_UserInfo23 {
struct samr_UserInfo24 {
struct samr_CryptPassword password;
- uint8_t pw_len;
+ uint8_t password_expired;
};
struct samr_CryptPasswordEx {
@@ -538,7 +581,7 @@ struct samr_UserInfo25 {
struct samr_UserInfo26 {
struct samr_CryptPasswordEx password;
- uint8_t pw_len;
+ uint8_t password_expired;
};
union samr_UserInfo {
@@ -1747,7 +1790,7 @@ struct samr_RidToSid {
} in;
struct {
- struct dom_sid2 *sid;/* [ref] */
+ struct dom_sid2 **sid;/* [ref] */
NTSTATUS result;
} out;
diff --git a/source3/librpc/gen_ndr/security.h b/source3/librpc/gen_ndr/security.h
index bb06dc2584..fe23347fdf 100644
--- a/source3/librpc/gen_ndr/security.h
+++ b/source3/librpc/gen_ndr/security.h
@@ -3,9 +3,7 @@
#include <stdint.h>
#include "librpc/gen_ndr/misc.h"
-#define dom_sid2 dom_sid
-#define dom_sid28 dom_sid
-#define dom_sid0 dom_sid
+#include "librpc/gen_ndr/dom_sid.h"
#ifndef _HEADER_security
#define _HEADER_security
@@ -245,7 +243,7 @@ struct security_ace_object {
union security_ace_object_ctr {
struct security_ace_object object;/* [case(SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT)] */
-}/* [nodiscriminant] */;
+}/* [public,nodiscriminant] */;
struct security_ace {
enum security_ace_type type;
@@ -254,7 +252,7 @@ struct security_ace {
uint32_t access_mask;
union security_ace_object_ctr object;/* [switch_is(type)] */
struct dom_sid trustee;
-}/* [gensize,public,nosize] */;
+}/* [gensize,public,nopull,nosize] */;
enum security_acl_revision
#ifndef USE_UINT_ENUMS
diff --git a/source3/librpc/gen_ndr/srv_lsa.c b/source3/librpc/gen_ndr/srv_lsa.c
index b0893623a8..c30f276800 100644
--- a/source3/librpc/gen_ndr/srv_lsa.c
+++ b/source3/librpc/gen_ndr/srv_lsa.c
@@ -1128,14 +1128,14 @@ static bool api_lsa_LookupNames(pipes_struct *p)
}
ZERO_STRUCT(r->out);
+ r->out.sids = r->in.sids;
+ r->out.count = r->in.count;
r->out.domains = talloc_zero(r, struct lsa_RefDomainList *);
if (r->out.domains == NULL) {
talloc_free(r);
return false;
}
- r->out.sids = r->in.sids;
- r->out.count = r->in.count;
r->out.result = _lsa_LookupNames(p, r);
if (p->rng_fault_state) {
@@ -1210,14 +1210,14 @@ static bool api_lsa_LookupSids(pipes_struct *p)
}
ZERO_STRUCT(r->out);
+ r->out.names = r->in.names;
+ r->out.count = r->in.count;
r->out.domains = talloc_zero(r, struct lsa_RefDomainList *);
if (r->out.domains == NULL) {
talloc_free(r);
return false;
}
- r->out.names = r->in.names;
- r->out.count = r->in.count;
r->out.result = _lsa_LookupSids(p, r);
if (p->rng_fault_state) {
@@ -4444,14 +4444,14 @@ static bool api_lsa_LookupSids2(pipes_struct *p)
}
ZERO_STRUCT(r->out);
+ r->out.names = r->in.names;
+ r->out.count = r->in.count;
r->out.domains = talloc_zero(r, struct lsa_RefDomainList *);
if (r->out.domains == NULL) {
talloc_free(r);
return false;
}
- r->out.names = r->in.names;
- r->out.count = r->in.count;
r->out.result = _lsa_LookupSids2(p, r);
if (p->rng_fault_state) {
@@ -4526,14 +4526,14 @@ static bool api_lsa_LookupNames2(pipes_struct *p)
}
ZERO_STRUCT(r->out);
+ r->out.sids = r->in.sids;
+ r->out.count = r->in.count;
r->out.domains = talloc_zero(r, struct lsa_RefDomainList *);
if (r->out.domains == NULL) {
talloc_free(r);
return false;
}
- r->out.sids = r->in.sids;
- r->out.count = r->in.count;
r->out.result = _lsa_LookupNames2(p, r);
if (p->rng_fault_state) {
@@ -5272,14 +5272,14 @@ static bool api_lsa_LookupNames3(pipes_struct *p)
}
ZERO_STRUCT(r->out);
+ r->out.sids = r->in.sids;
+ r->out.count = r->in.count;
r->out.domains = talloc_zero(r, struct lsa_RefDomainList *);
if (r->out.domains == NULL) {
talloc_free(r);
return false;
}
- r->out.sids = r->in.sids;
- r->out.count = r->in.count;
r->out.result = _lsa_LookupNames3(p, r);
if (p->rng_fault_state) {
@@ -5872,14 +5872,14 @@ static bool api_lsa_LookupSids3(pipes_struct *p)
}
ZERO_STRUCT(r->out);
+ r->out.names = r->in.names;
+ r->out.count = r->in.count;
r->out.domains = talloc_zero(r, struct lsa_RefDomainList *);
if (r->out.domains == NULL) {
talloc_free(r);
return false;
}
- r->out.names = r->in.names;
- r->out.count = r->in.count;
r->out.result = _lsa_LookupSids3(p, r);
if (p->rng_fault_state) {
@@ -5954,14 +5954,14 @@ static bool api_lsa_LookupNames4(pipes_struct *p)
}
ZERO_STRUCT(r->out);
+ r->out.sids = r->in.sids;
+ r->out.count = r->in.count;
r->out.domains = talloc_zero(r, struct lsa_RefDomainList *);
if (r->out.domains == NULL) {
talloc_free(r);
return false;
}
- r->out.sids = r->in.sids;
- r->out.count = r->in.count;
r->out.result = _lsa_LookupNames4(p, r);
if (p->rng_fault_state) {
diff --git a/source3/librpc/gen_ndr/srv_netlogon.c b/source3/librpc/gen_ndr/srv_netlogon.c
index 9546b2551b..2cb2978af2 100644
--- a/source3/librpc/gen_ndr/srv_netlogon.c
+++ b/source3/librpc/gen_ndr/srv_netlogon.c
@@ -871,6 +871,7 @@ static bool api_netr_AccountSync(pipes_struct *p)
ZERO_STRUCT(r->out);
r->out.return_authenticator = r->in.return_authenticator;
+ r->out.recordid = r->in.recordid;
r->out.buffer = talloc_zero(r, struct netr_AccountBuffer);
if (r->out.buffer == NULL) {
talloc_free(r);
@@ -895,7 +896,6 @@ static bool api_netr_AccountSync(pipes_struct *p)
return false;
}
- r->out.recordid = r->in.recordid;
r->out.result = _netr_AccountSync(p, r);
if (p->rng_fault_state) {
@@ -1290,13 +1290,13 @@ static bool api_netr_ServerAuthenticate2(pipes_struct *p)
}
ZERO_STRUCT(r->out);
+ r->out.negotiate_flags = r->in.negotiate_flags;
r->out.return_credentials = talloc_zero(r, struct netr_Credential);
if (r->out.return_credentials == NULL) {
talloc_free(r);
return false;
}
- r->out.negotiate_flags = r->in.negotiate_flags;
r->out.result = _netr_ServerAuthenticate2(p, r);
if (p->rng_fault_state) {
@@ -2146,13 +2146,13 @@ static bool api_netr_ServerAuthenticate3(pipes_struct *p)
}
ZERO_STRUCT(r->out);
+ r->out.negotiate_flags = r->in.negotiate_flags;
r->out.return_credentials = talloc_zero(r, struct netr_Credential);
if (r->out.return_credentials == NULL) {
talloc_free(r);
return false;
}
- r->out.negotiate_flags = r->in.negotiate_flags;
r->out.rid = talloc_zero(r, uint32_t);
if (r->out.rid == NULL) {
talloc_free(r);
@@ -3186,6 +3186,7 @@ static bool api_netr_LogonSamLogonEx(pipes_struct *p)
}
ZERO_STRUCT(r->out);
+ r->out.flags = r->in.flags;
r->out.validation = talloc_zero(r, union netr_Validation);
if (r->out.validation == NULL) {
talloc_free(r);
@@ -3198,7 +3199,6 @@ static bool api_netr_LogonSamLogonEx(pipes_struct *p)
return false;
}
- r->out.flags = r->in.flags;
r->out.result = _netr_LogonSamLogonEx(p, r);
if (p->rng_fault_state) {
@@ -3685,6 +3685,7 @@ static bool api_netr_LogonSamLogonWithFlags(pipes_struct *p)
ZERO_STRUCT(r->out);
r->out.return_authenticator = r->in.return_authenticator;
+ r->out.flags = r->in.flags;
r->out.validation = talloc_zero(r, union netr_Validation);
if (r->out.validation == NULL) {
talloc_free(r);
@@ -3697,7 +3698,6 @@ static bool api_netr_LogonSamLogonWithFlags(pipes_struct *p)
return false;
}
- r->out.flags = r->in.flags;
r->out.result = _netr_LogonSamLogonWithFlags(p, r);
if (p->rng_fault_state) {
diff --git a/source3/librpc/gen_ndr/srv_ntsvcs.c b/source3/librpc/gen_ndr/srv_ntsvcs.c
index 87f5d51695..288f3ed5d7 100644
--- a/source3/librpc/gen_ndr/srv_ntsvcs.c
+++ b/source3/librpc/gen_ndr/srv_ntsvcs.c
@@ -782,13 +782,13 @@ static bool api_PNP_GetDeviceList(pipes_struct *p)
}
ZERO_STRUCT(r->out);
+ r->out.length = r->in.length;
r->out.buffer = talloc_zero_array(r, uint16_t, *r->out.length);
if (r->out.buffer == NULL) {
talloc_free(r);
return false;
}
- r->out.length = r->in.length;
r->out.result = _PNP_GetDeviceList(p, r);
if (p->rng_fault_state) {
@@ -1017,14 +1017,14 @@ static bool api_PNP_GetDeviceRegProp(pipes_struct *p)
ZERO_STRUCT(r->out);
r->out.reg_data_type = r->in.reg_data_type;
+ r->out.buffer_size = r->in.buffer_size;
+ r->out.needed = r->in.needed;
r->out.buffer = talloc_zero_array(r, uint8_t, *r->out.buffer_size);
if (r->out.buffer == NULL) {
talloc_free(r);
return false;
}
- r->out.buffer_size = r->in.buffer_size;
- r->out.needed = r->in.needed;
r->out.result = _PNP_GetDeviceRegProp(p, r);
if (p->rng_fault_state) {
@@ -2997,8 +2997,8 @@ static bool api_PNP_HwProfFlags(pipes_struct *p)
}
ZERO_STRUCT(r->out);
- r->out.unknown3 = r->in.unknown3;
- r->out.unknown4 = r->in.unknown4;
+ r->out.profile_flags = r->in.profile_flags;
+ r->out.veto_type = r->in.veto_type;
r->out.unknown5a = talloc_zero(r, const char *);
if (r->out.unknown5a == NULL) {
talloc_free(r);
diff --git a/source3/librpc/gen_ndr/srv_samr.c b/source3/librpc/gen_ndr/srv_samr.c
index 3e3a1cc6c1..f4facd2914 100644
--- a/source3/librpc/gen_ndr/srv_samr.c
+++ b/source3/librpc/gen_ndr/srv_samr.c
@@ -5202,7 +5202,7 @@ static bool api_samr_RidToSid(pipes_struct *p)
}
ZERO_STRUCT(r->out);
- r->out.sid = talloc_zero(r, struct dom_sid2);
+ r->out.sid = talloc_zero(r, struct dom_sid2 *);
if (r->out.sid == NULL) {
talloc_free(r);
return false;
diff --git a/source3/librpc/gen_ndr/srv_srvsvc.c b/source3/librpc/gen_ndr/srv_srvsvc.c
index f995930b89..59f51ba774 100644
--- a/source3/librpc/gen_ndr/srv_srvsvc.c
+++ b/source3/librpc/gen_ndr/srv_srvsvc.c
@@ -46,13 +46,13 @@ static bool api_srvsvc_NetCharDevEnum(pipes_struct *p)
ZERO_STRUCT(r->out);
r->out.info_ctr = r->in.info_ctr;
+ r->out.resume_handle = r->in.resume_handle;
r->out.totalentries = talloc_zero(r, uint32_t);
if (r->out.totalentries == NULL) {
talloc_free(r);
return false;
}
- r->out.resume_handle = r->in.resume_handle;
r->out.result = _srvsvc_NetCharDevEnum(p, r);
if (p->rng_fault_state) {
@@ -281,13 +281,13 @@ static bool api_srvsvc_NetCharDevQEnum(pipes_struct *p)
ZERO_STRUCT(r->out);
r->out.info_ctr = r->in.info_ctr;
+ r->out.resume_handle = r->in.resume_handle;
r->out.totalentries = talloc_zero(r, uint32_t);
if (r->out.totalentries == NULL) {
talloc_free(r);
return false;
}
- r->out.resume_handle = r->in.resume_handle;
r->out.result = _srvsvc_NetCharDevQEnum(p, r);
if (p->rng_fault_state) {
@@ -664,13 +664,13 @@ static bool api_srvsvc_NetConnEnum(pipes_struct *p)
ZERO_STRUCT(r->out);
r->out.info_ctr = r->in.info_ctr;
+ r->out.resume_handle = r->in.resume_handle;
r->out.totalentries = talloc_zero(r, uint32_t);
if (r->out.totalentries == NULL) {
talloc_free(r);
return false;
}
- r->out.resume_handle = r->in.resume_handle;
r->out.result = _srvsvc_NetConnEnum(p, r);
if (p->rng_fault_state) {
@@ -746,13 +746,13 @@ static bool api_srvsvc_NetFileEnum(pipes_struct *p)
ZERO_STRUCT(r->out);
r->out.info_ctr = r->in.info_ctr;
+ r->out.resume_handle = r->in.resume_handle;
r->out.totalentries = talloc_zero(r, uint32_t);
if (r->out.totalentries == NULL) {
talloc_free(r);
return false;
}
- r->out.resume_handle = r->in.resume_handle;
r->out.result = _srvsvc_NetFileEnum(p, r);
if (p->rng_fault_state) {
@@ -981,13 +981,13 @@ static bool api_srvsvc_NetSessEnum(pipes_struct *p)
ZERO_STRUCT(r->out);
r->out.info_ctr = r->in.info_ctr;
+ r->out.resume_handle = r->in.resume_handle;
r->out.totalentries = talloc_zero(r, uint32_t);
if (r->out.totalentries == NULL) {
talloc_free(r);
return false;
}
- r->out.resume_handle = r->in.resume_handle;
r->out.result = _srvsvc_NetSessEnum(p, r);
if (p->rng_fault_state) {
@@ -1211,13 +1211,13 @@ static bool api_srvsvc_NetShareEnumAll(pipes_struct *p)
ZERO_STRUCT(r->out);
r->out.info_ctr = r->in.info_ctr;
+ r->out.resume_handle = r->in.resume_handle;
r->out.totalentries = talloc_zero(r, uint32_t);
if (r->out.totalentries == NULL) {
talloc_free(r);
return false;
}
- r->out.resume_handle = r->in.resume_handle;
r->out.result = _srvsvc_NetShareEnumAll(p, r);
if (p->rng_fault_state) {
@@ -1829,13 +1829,13 @@ static bool api_srvsvc_NetDiskEnum(pipes_struct *p)
ZERO_STRUCT(r->out);
r->out.info = r->in.info;
+ r->out.resume_handle = r->in.resume_handle;
r->out.totalentries = talloc_zero(r, uint32_t);
if (r->out.totalentries == NULL) {
talloc_free(r);
return false;
}
- r->out.resume_handle = r->in.resume_handle;
r->out.result = _srvsvc_NetDiskEnum(p, r);
if (p->rng_fault_state) {
@@ -2064,13 +2064,13 @@ static bool api_srvsvc_NetTransportEnum(pipes_struct *p)
ZERO_STRUCT(r->out);
r->out.transports = r->in.transports;
+ r->out.resume_handle = r->in.resume_handle;
r->out.totalentries = talloc_zero(r, uint32_t);
if (r->out.totalentries == NULL) {
talloc_free(r);
return false;
}
- r->out.resume_handle = r->in.resume_handle;
r->out.result = _srvsvc_NetTransportEnum(p, r);
if (p->rng_fault_state) {
@@ -2451,13 +2451,13 @@ static bool api_srvsvc_NetPathCanonicalize(pipes_struct *p)
}
ZERO_STRUCT(r->out);
+ r->out.pathtype = r->in.pathtype;
r->out.can_path = talloc_zero_array(r, uint8_t, r->in.maxbuf);
if (r->out.can_path == NULL) {
talloc_free(r);
return false;
}
- r->out.pathtype = r->in.pathtype;
r->out.result = _srvsvc_NetPathCanonicalize(p, r);
if (p->rng_fault_state) {
@@ -2825,13 +2825,13 @@ static bool api_srvsvc_NetShareEnum(pipes_struct *p)
ZERO_STRUCT(r->out);
r->out.info_ctr = r->in.info_ctr;
+ r->out.resume_handle = r->in.resume_handle;
r->out.totalentries = talloc_zero(r, uint32_t);
if (r->out.totalentries == NULL) {
talloc_free(r);
return false;
}
- r->out.resume_handle = r->in.resume_handle;
r->out.result = _srvsvc_NetShareEnum(p, r);
if (p->rng_fault_state) {
diff --git a/source3/librpc/gen_ndr/srv_svcctl.c b/source3/librpc/gen_ndr/srv_svcctl.c
index 2349b4fd93..5b30bf00f7 100644
--- a/source3/librpc/gen_ndr/srv_svcctl.c
+++ b/source3/librpc/gen_ndr/srv_svcctl.c
@@ -1139,6 +1139,7 @@ static bool api_svcctl_EnumServicesStatusW(pipes_struct *p)
}
ZERO_STRUCT(r->out);
+ r->out.resume_handle = r->in.resume_handle;
r->out.service = talloc_zero_array(r, uint8_t, r->in.buf_size);
if (r->out.service == NULL) {
talloc_free(r);
@@ -1157,7 +1158,6 @@ static bool api_svcctl_EnumServicesStatusW(pipes_struct *p)
return false;
}
- r->out.resume_handle = r->in.resume_handle;
r->out.result = _svcctl_EnumServicesStatusW(p, r);
if (p->rng_fault_state) {
@@ -1637,13 +1637,13 @@ static bool api_svcctl_GetServiceDisplayNameW(pipes_struct *p)
}
ZERO_STRUCT(r->out);
+ r->out.display_name_length = r->in.display_name_length;
r->out.display_name = talloc_zero(r, const char *);
if (r->out.display_name == NULL) {
talloc_free(r);
return false;
}
- r->out.display_name_length = r->in.display_name_length;
r->out.result = _svcctl_GetServiceDisplayNameW(p, r);
if (p->rng_fault_state) {
@@ -1718,13 +1718,13 @@ static bool api_svcctl_GetServiceKeyNameW(pipes_struct *p)
}
ZERO_STRUCT(r->out);
+ r->out.display_name_length = r->in.display_name_length;
r->out.key_name = talloc_zero(r, const char *);
if (r->out.key_name == NULL) {
talloc_free(r);
return false;
}
- r->out.display_name_length = r->in.display_name_length;
r->out.result = _svcctl_GetServiceKeyNameW(p, r);
if (p->rng_fault_state) {
@@ -2124,6 +2124,7 @@ static bool api_svcctl_EnumServicesStatusA(pipes_struct *p)
}
ZERO_STRUCT(r->out);
+ r->out.resume_handle = r->in.resume_handle;
r->out.service = talloc_zero_array(r, uint8_t, r->in.buf_size);
if (r->out.service == NULL) {
talloc_free(r);
@@ -2142,7 +2143,6 @@ static bool api_svcctl_EnumServicesStatusA(pipes_struct *p)
return false;
}
- r->out.resume_handle = r->in.resume_handle;
r->out.result = _svcctl_EnumServicesStatusA(p, r);
if (p->rng_fault_state) {
@@ -2615,13 +2615,13 @@ static bool api_svcctl_GetServiceDisplayNameA(pipes_struct *p)
}
ZERO_STRUCT(r->out);
+ r->out.display_name_length = r->in.display_name_length;
r->out.display_name = talloc_zero(r, const char *);
if (r->out.display_name == NULL) {
talloc_free(r);
return false;
}
- r->out.display_name_length = r->in.display_name_length;
r->out.result = _svcctl_GetServiceDisplayNameA(p, r);
if (p->rng_fault_state) {
@@ -2696,13 +2696,13 @@ static bool api_svcctl_GetServiceKeyNameA(pipes_struct *p)
}
ZERO_STRUCT(r->out);
+ r->out.display_name_length = r->in.display_name_length;
r->out.key_name = talloc_zero(r, const char *);
if (r->out.key_name == NULL) {
talloc_free(r);
return false;
}
- r->out.display_name_length = r->in.display_name_length;
r->out.result = _svcctl_GetServiceKeyNameA(p, r);
if (p->rng_fault_state) {
@@ -3327,6 +3327,7 @@ static bool api_EnumServicesStatusExA(pipes_struct *p)
}
ZERO_STRUCT(r->out);
+ r->out.resume_handle = r->in.resume_handle;
r->out.services = talloc_zero_array(r, uint8_t, r->in.buf_size);
if (r->out.services == NULL) {
talloc_free(r);
@@ -3345,7 +3346,6 @@ static bool api_EnumServicesStatusExA(pipes_struct *p)
return false;
}
- r->out.resume_handle = r->in.resume_handle;
r->out.group_name = talloc_zero(r, const char *);
if (r->out.group_name == NULL) {
talloc_free(r);
@@ -3426,6 +3426,7 @@ static bool api_EnumServicesStatusExW(pipes_struct *p)
}
ZERO_STRUCT(r->out);
+ r->out.resume_handle = r->in.resume_handle;
r->out.services = talloc_zero_array(r, uint8_t, r->in.buf_size);
if (r->out.services == NULL) {
talloc_free(r);
@@ -3444,13 +3445,6 @@ static bool api_EnumServicesStatusExW(pipes_struct *p)
return false;
}
- r->out.resume_handle = r->in.resume_handle;
- r->out.group_name = talloc_zero(r, const char *);
- if (r->out.group_name == NULL) {
- talloc_free(r);
- return false;
- }
-
r->out.result = _EnumServicesStatusExW(p, r);
if (p->rng_fault_state) {
diff --git a/source3/librpc/gen_ndr/srv_winreg.c b/source3/librpc/gen_ndr/srv_winreg.c
index 77b0a1c5d2..ac70b41219 100644
--- a/source3/librpc/gen_ndr/srv_winreg.c
+++ b/source3/librpc/gen_ndr/srv_winreg.c
@@ -520,13 +520,13 @@ static bool api_winreg_CreateKey(pipes_struct *p)
}
ZERO_STRUCT(r->out);
+ r->out.action_taken = r->in.action_taken;
r->out.new_handle = talloc_zero(r, struct policy_handle);
if (r->out.new_handle == NULL) {
talloc_free(r);
return false;
}
- r->out.action_taken = r->in.action_taken;
r->out.result = _winreg_CreateKey(p, r);
if (p->rng_fault_state) {
diff --git a/source3/librpc/gen_ndr/srv_wkssvc.c b/source3/librpc/gen_ndr/srv_wkssvc.c
index 9c07fa86ea..61a5be081f 100644
--- a/source3/librpc/gen_ndr/srv_wkssvc.c
+++ b/source3/librpc/gen_ndr/srv_wkssvc.c
@@ -201,13 +201,13 @@ static bool api_wkssvc_NetWkstaEnumUsers(pipes_struct *p)
ZERO_STRUCT(r->out);
r->out.info = r->in.info;
+ r->out.resume_handle = r->in.resume_handle;
r->out.entries_read = talloc_zero(r, uint32_t);
if (r->out.entries_read == NULL) {
talloc_free(r);
return false;
}
- r->out.resume_handle = r->in.resume_handle;
r->out.result = _wkssvc_NetWkstaEnumUsers(p, r);
if (p->rng_fault_state) {
@@ -438,13 +438,13 @@ static bool api_wkssvc_NetWkstaTransportEnum(pipes_struct *p)
ZERO_STRUCT(r->out);
r->out.info = r->in.info;
+ r->out.resume_handle = r->in.resume_handle;
r->out.total_entries = talloc_zero(r, uint32_t);
if (r->out.total_entries == NULL) {
talloc_free(r);
return false;
}
- r->out.resume_handle = r->in.resume_handle;
r->out.result = _wkssvc_NetWkstaTransportEnum(p, r);
if (p->rng_fault_state) {
@@ -896,13 +896,13 @@ static bool api_wkssvc_NetrUseEnum(pipes_struct *p)
ZERO_STRUCT(r->out);
r->out.info = r->in.info;
+ r->out.resume_handle = r->in.resume_handle;
r->out.entries_read = talloc_zero(r, uint32_t);
if (r->out.entries_read == NULL) {
talloc_free(r);
return false;
}
- r->out.resume_handle = r->in.resume_handle;
r->out.result = _wkssvc_NetrUseEnum(p, r);
if (p->rng_fault_state) {
diff --git a/source3/librpc/gen_ndr/svcctl.h b/source3/librpc/gen_ndr/svcctl.h
index b098eb1c42..9baa122e56 100644
--- a/source3/librpc/gen_ndr/svcctl.h
+++ b/source3/librpc/gen_ndr/svcctl.h
@@ -81,11 +81,19 @@ struct ENUM_SERVICE_STATUS {
enum SERVICE_CONTROL
#ifndef USE_UINT_ENUMS
{
- FIXME=1
+ SVCCTL_CONTROL_STOP=0x00000001,
+ SVCCTL_CONTROL_PAUSE=0x00000002,
+ SVCCTL_CONTROL_CONTINUE=0x00000003,
+ SVCCTL_CONTROL_INTERROGATE=0x00000004,
+ SVCCTL_CONTROL_SHUTDOWN=0x00000005
}
#else
{ __donnot_use_enum_SERVICE_CONTROL=0x7FFFFFFF}
-#define FIXME ( 1 )
+#define SVCCTL_CONTROL_STOP ( 0x00000001 )
+#define SVCCTL_CONTROL_PAUSE ( 0x00000002 )
+#define SVCCTL_CONTROL_CONTINUE ( 0x00000003 )
+#define SVCCTL_CONTROL_INTERROGATE ( 0x00000004 )
+#define SVCCTL_CONTROL_SHUTDOWN ( 0x00000005 )
#endif
;
@@ -137,7 +145,7 @@ struct svcctl_CloseServiceHandle {
struct svcctl_ControlService {
struct {
struct policy_handle *handle;/* [ref] */
- uint32_t control;
+ enum SERVICE_CONTROL control;
} in;
struct {
@@ -333,14 +341,14 @@ struct svcctl_EnumServicesStatusW {
struct policy_handle *handle;/* [ref] */
uint32_t type;
uint32_t state;
- uint32_t buf_size;
+ uint32_t buf_size;/* [range(0,262144)] */
uint32_t *resume_handle;/* [unique] */
} in;
struct {
- uint8_t *service;/* [size_is(buf_size)] */
- uint32_t *bytes_needed;/* [ref] */
- uint32_t *services_returned;/* [ref] */
+ uint8_t *service;/* [ref,size_is(buf_size)] */
+ uint32_t *bytes_needed;/* [ref,range(0,262144)] */
+ uint32_t *services_returned;/* [ref,range(0,262144)] */
uint32_t *resume_handle;/* [unique] */
WERROR result;
} out;
@@ -721,12 +729,12 @@ struct svcctl_QueryServiceConfig2W {
struct {
struct policy_handle *handle;/* [ref] */
uint32_t info_level;
- uint32_t buf_size;
+ uint32_t buf_size;/* [range(0,8192)] */
} in;
struct {
- uint8_t *buffer;
- uint32_t *bytes_needed;/* [ref] */
+ uint8_t *buffer;/* [ref,size_is(buf_size)] */
+ uint32_t *bytes_needed;/* [ref,range(0,8192)] */
WERROR result;
} out;
@@ -737,12 +745,12 @@ struct svcctl_QueryServiceStatusEx {
struct {
struct policy_handle *handle;/* [ref] */
uint32_t info_level;
- uint32_t buf_size;
+ uint32_t buf_size;/* [range(0,8192)] */
} in;
struct {
- uint8_t *buffer;
- uint32_t *bytes_needed;/* [ref] */
+ uint8_t *buffer;/* [ref,size_is(buf_size)] */
+ uint32_t *bytes_needed;/* [ref,range(0,8192)] */
WERROR result;
} out;
@@ -777,16 +785,16 @@ struct EnumServicesStatusExW {
uint32_t info_level;
uint32_t type;
uint32_t state;
- uint32_t buf_size;
- uint32_t *resume_handle;/* [unique] */
+ uint32_t buf_size;/* [range(0,262144)] */
+ const char *group_name;/* [unique,charset(UTF16)] */
+ uint32_t *resume_handle;/* [unique,range(0,262144)] */
} in;
struct {
- uint8_t *services;
- uint32_t *bytes_needed;/* [ref] */
- uint32_t *service_returned;/* [ref] */
- const char **group_name;/* [ref,charset(UTF16)] */
- uint32_t *resume_handle;/* [unique] */
+ uint8_t *services;/* [ref,size_is(buf_size)] */
+ uint32_t *bytes_needed;/* [ref,range(0,262144)] */
+ uint32_t *service_returned;/* [ref,range(0,262144)] */
+ uint32_t *resume_handle;/* [unique,range(0,262144)] */
WERROR result;
} out;
diff --git a/source3/librpc/gen_ndr/xattr.h b/source3/librpc/gen_ndr/xattr.h
index 1d8da3f5e2..1148a0acec 100644
--- a/source3/librpc/gen_ndr/xattr.h
+++ b/source3/librpc/gen_ndr/xattr.h
@@ -73,14 +73,14 @@ struct xattr_DosStreams {
struct xattr_DosStream *streams;/* [unique,size_is(num_streams)] */
}/* [public] */;
-struct security_descriptor_timestamp {
+struct security_descriptor_hash {
struct security_descriptor *sd;/* [unique] */
- NTTIME last_changed;
+ uint8_t hash[16];
}/* [public] */;
union xattr_NTACL_Info {
struct security_descriptor *sd;/* [unique,case] */
- struct security_descriptor_timestamp *sd_ts;/* [unique,case(2)] */
+ struct security_descriptor_hash *sd_hs;/* [unique,case(2)] */
}/* [switch_type(uint16)] */;
struct xattr_NTACL {
diff --git a/source3/librpc/idl/dom_sid.idl b/source3/librpc/idl/dom_sid.idl
new file mode 100644
index 0000000000..c405c18726
--- /dev/null
+++ b/source3/librpc/idl/dom_sid.idl
@@ -0,0 +1,29 @@
+/*
+ use the same structure for dom_sid2 as dom_sid. A dom_sid2 is really
+ just a dom sid, but with the sub_auths represented as a conformant
+ array. As with all in-structure conformant arrays, the array length
+ is placed before the start of the structure. That's what gives rise
+ to the extra num_auths elemenent. We don't want the Samba code to
+ have to bother with such esoteric NDR details, so its easier to just
+ define it as a dom_sid and use pidl magic to make it all work. It
+ just means you need to mark a sid as a "dom_sid2" in the IDL when you
+ know it is of the conformant array variety
+*/
+cpp_quote("#define dom_sid2 dom_sid")
+
+/* same struct as dom_sid but inside a 28 bytes fixed buffer in NDR */
+cpp_quote("#define dom_sid28 dom_sid")
+
+/* same struct as dom_sid but in a variable byte buffer, which is maybe empty in NDR */
+cpp_quote("#define dom_sid0 dom_sid")
+
+[
+ pointer_default(unique)
+]
+interface dom_sid
+{
+ struct _dummy_domsid {
+ uint8 dummy;
+ };
+}
+
diff --git a/source3/librpc/ndr/ndr_sec.h b/source3/librpc/ndr/ndr_sec.h
deleted file mode 100644
index 8034367223..0000000000
--- a/source3/librpc/ndr/ndr_sec.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef __LIBRPC_NDR_NDR_SEC_H__
-#define __LIBRPC_NDR_NDR_SEC_H__
-
-#undef _PRINTF_ATTRIBUTE
-#define _PRINTF_ATTRIBUTE(a1, a2) PRINTF_ATTRIBUTE(a1, a2)
-/* This file was automatically generated by mkproto.pl. DO NOT EDIT */
-
-#ifndef _PUBLIC_
-#define _PUBLIC_
-#endif
-
-
-/* The following definitions come from librpc/ndr/ndr_sec_helper.c */
-
-size_t ndr_size_dom_sid(const struct dom_sid *sid);
-size_t ndr_length_dom_sid(const struct dom_sid *sid);
-size_t ndr_size_security_ace(const struct security_ace *ace);
-size_t ndr_size_security_acl(const struct security_acl *acl);
-size_t ndr_size_security_descriptor(const struct security_descriptor *sd);
-void ndr_print_dom_sid(struct ndr_print *ndr, const char *name, const struct dom_sid *sid);
-void ndr_print_dom_sid2(struct ndr_print *ndr, const char *name, const struct dom_sid *sid);
-void ndr_print_dom_sid28(struct ndr_print *ndr, const char *name, const struct dom_sid *sid);
-char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid);
-
-/* The following definitions come from librpc/ndr/ndr_sec.c */
-
-enum ndr_err_code ndr_pull_dom_sid2(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid);
-enum ndr_err_code ndr_push_dom_sid2(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid);
-enum ndr_err_code ndr_pull_dom_sid28(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid);
-enum ndr_err_code ndr_push_dom_sid28(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid);
-#undef _PRINTF_ATTRIBUTE
-#define _PRINTF_ATTRIBUTE(a1, a2)
-
-#endif /* __LIBRPC_NDR_NDR_SEC_H__ */
-
diff --git a/source3/librpc/ndr/ndr_sec_helper.c b/source3/librpc/ndr/ndr_sec_helper.c
deleted file mode 100644
index 18d343799e..0000000000
--- a/source3/librpc/ndr/ndr_sec_helper.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- fast routines for getting the wire size of security objects
-
- Copyright (C) Andrew Tridgell 2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 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"
-
-/*
- return the wire size of a dom_sid
-*/
-size_t ndr_size_dom_sid(const struct dom_sid *sid, int flags)
-{
- if (!sid) return 0;
- return 8 + 4*sid->num_auths;
-}
-
-size_t ndr_size_dom_sid28(const struct dom_sid *sid, int flags)
-{
- struct dom_sid zero_sid;
-
- if (!sid) return 0;
-
- ZERO_STRUCT(zero_sid);
-
- if (memcmp(&zero_sid, sid, sizeof(zero_sid)) == 0) {
- return 0;
- }
-
- return 8 + 4*sid->num_auths;
-}
-
-size_t ndr_size_dom_sid0(const struct dom_sid *sid, int flags)
-{
- return ndr_size_dom_sid28(sid, flags);
-}
-
-/*
- return the wire size of a security_ace
-*/
-size_t ndr_size_security_ace(const struct security_ace *ace, int flags)
-{
- if (!ace) return 0;
- return 8 + ndr_size_dom_sid(&ace->trustee, flags);
-}
-
-
-/*
- return the wire size of a security_acl
-*/
-size_t ndr_size_security_acl(const struct security_acl *acl, int flags)
-{
- size_t ret;
- int i;
- if (!acl) return 0;
- ret = 8;
- for (i=0;i<acl->num_aces;i++) {
- ret += ndr_size_security_ace(&acl->aces[i], flags);
- }
- return ret;
-}
-
-/*
- return the wire size of a security descriptor
-*/
-size_t ndr_size_security_descriptor(const struct security_descriptor *sd, int flags)
-{
- size_t ret;
- if (!sd) return 0;
-
- ret = 20;
- ret += ndr_size_dom_sid(sd->owner_sid, flags);
- ret += ndr_size_dom_sid(sd->group_sid, flags);
- ret += ndr_size_security_acl(sd->dacl, flags);
- ret += ndr_size_security_acl(sd->sacl, flags);
- return ret;
-}
-
-/*
- print a dom_sid
-*/
-void ndr_print_dom_sid(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
-{
- ndr->print(ndr, "%-25s: %s", name, dom_sid_string(ndr, sid));
-}
-
-void ndr_print_dom_sid2(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
-{
- ndr_print_dom_sid(ndr, name, sid);
-}
-
-void ndr_print_dom_sid28(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
-{
- ndr_print_dom_sid(ndr, name, sid);
-}
-
-void ndr_print_dom_sid0(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
-{
- ndr_print_dom_sid(ndr, name, sid);
-}
-
diff --git a/source3/librpc/ndr/sid.c b/source3/librpc/ndr/sid.c
index ed27375de1..39b7e3cd59 100644
--- a/source3/librpc/ndr/sid.c
+++ b/source3/librpc/ndr/sid.c
@@ -21,6 +21,35 @@
#include "includes.h"
+/*
+ return the wire size of a dom_sid
+*/
+size_t ndr_size_dom_sid(const struct dom_sid *sid, int flags)
+{
+ if (!sid) return 0;
+ return 8 + 4*sid->num_auths;
+}
+
+size_t ndr_size_dom_sid28(const struct dom_sid *sid, int flags)
+{
+ struct dom_sid zero_sid;
+
+ if (!sid) return 0;
+
+ ZERO_STRUCT(zero_sid);
+
+ if (memcmp(&zero_sid, sid, sizeof(zero_sid)) == 0) {
+ return 0;
+ }
+
+ return 8 + 4*sid->num_auths;
+}
+
+size_t ndr_size_dom_sid0(const struct dom_sid *sid, int flags)
+{
+ return ndr_size_dom_sid28(sid, flags);
+}
+
enum ndr_err_code ndr_push_dom_sid(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *r)
{
uint32_t cntr_sub_auths_0;
@@ -228,3 +257,27 @@ enum ndr_err_code ndr_push_dom_sid0(struct ndr_push *ndr, int ndr_flags, const s
return ndr_push_dom_sid(ndr, ndr_flags, sid);
}
+
+/*
+ print a dom_sid
+*/
+void ndr_print_dom_sid(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
+{
+ ndr->print(ndr, "%-25s: %s", name, dom_sid_string(ndr, sid));
+}
+
+void ndr_print_dom_sid2(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
+{
+ ndr_print_dom_sid(ndr, name, sid);
+}
+
+void ndr_print_dom_sid28(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
+{
+ ndr_print_dom_sid(ndr, name, sid);
+}
+
+void ndr_print_dom_sid0(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
+{
+ ndr_print_dom_sid(ndr, name, sid);
+}
+
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 1588ae3efe..8b7ac7d718 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -468,7 +468,7 @@ static bool cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob)
SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
cli_setup_packet(cli);
-
+
SCVAL(cli->outbuf,smb_vwv0,0xFF);
SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
SSVAL(cli->outbuf,smb_vwv3,2);
@@ -504,10 +504,10 @@ static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli)
NT_STATUS_MORE_PROCESSING_REQUIRED)) {
return blob2;
}
-
+
/* use the returned vuid from now on */
cli->vuid = SVAL(cli->inbuf,smb_uid);
-
+
p = smb_buf(cli->inbuf);
blob2 = data_blob(p, SVAL(cli->inbuf, smb_vwv3));
@@ -696,14 +696,14 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use
/* wrap it in SPNEGO */
msg1 = spnego_gen_auth(blob_out);
}
-
+
/* now send that blob on its way */
if (!cli_session_setup_blob_send(cli, msg1)) {
DEBUG(3, ("Failed to send NTLMSSP/SPNEGO blob to server!\n"));
nt_status = NT_STATUS_UNSUCCESSFUL;
} else {
blob = cli_session_setup_blob_receive(cli);
-
+
nt_status = cli_nt_error(cli);
if (cli_is_error(cli) && NT_STATUS_IS_OK(nt_status)) {
if (cli->smb_rw_error == SMB_READ_BAD_SIG) {
@@ -715,7 +715,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use
}
data_blob_free(&msg1);
}
-
+
if (!blob.length) {
if (NT_STATUS_IS_OK(nt_status)) {
nt_status = NT_STATUS_UNSUCCESSFUL;
@@ -761,11 +761,11 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use
data_blob_free(&key);
if (res) {
-
+
/* 'resign' the last message, so we get the right sequence numbers
for checking the first reply from the server */
cli_calculate_sign_mac(cli, cli->outbuf);
-
+
if (!cli_check_sign_mac(cli, cli->inbuf)) {
nt_status = NT_STATUS_ACCESS_DENIED;
}
@@ -849,10 +849,10 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
if (pass && *pass) {
int ret;
-
+
use_in_memory_ccache();
ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL);
-
+
if (ret){
TALLOC_FREE(principal);
DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
@@ -861,7 +861,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
return ADS_ERROR_KRB5(ret);
}
}
-
+
/* If we get a bad principal, try to guess it if
we have a valid host NetBIOS name.
*/
@@ -1132,7 +1132,7 @@ bool cli_send_tconX(struct cli_state *cli,
* Non-encrypted passwords - convert to DOS codepage before using.
*/
passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
-
+
} else {
if (passlen) {
memcpy(pword, pass, passlen);
@@ -1175,7 +1175,7 @@ bool cli_send_tconX(struct cli_state *cli,
/* almost certainly win95 - enable bug fixes */
cli->win95 = True;
}
-
+
/* Make sure that we have the optional support 16-bit field. WCT > 2 */
/* Avoids issues when connecting to Win9x boxes sharing files */
@@ -1198,11 +1198,11 @@ bool cli_tdis(struct cli_state *cli)
SCVAL(cli->outbuf,smb_com,SMBtdis);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
-
+
cli_send_smb(cli);
if (!cli_receive_smb(cli))
return False;
-
+
if (cli_is_error(cli)) {
return False;
}
@@ -1265,7 +1265,7 @@ bool cli_negprot(struct cli_state *cli)
prots[numprots].name && prots[numprots].prot<=cli->protocol;
numprots++)
plength += strlen(prots[numprots].name)+2;
-
+
cli_set_message(cli->outbuf,0,plength,True);
p = smb_buf(cli->outbuf);
@@ -1397,9 +1397,13 @@ bool cli_session_request(struct cli_state *cli,
char *p;
int len = 4;
+ /* 445 doesn't have session request */
+ if (cli->port == 445)
+ return True;
+
memcpy(&(cli->calling), calling, sizeof(*calling));
memcpy(&(cli->called ), called , sizeof(*called ));
-
+
/* put in the destination name */
p = cli->outbuf+len;
name_mangle(cli->called .name, p, cli->called .name_type);
@@ -1410,10 +1414,6 @@ bool cli_session_request(struct cli_state *cli,
name_mangle(cli->calling.name, p, cli->calling.name_type);
len += name_len(p);
- /* 445 doesn't have session request */
- if (cli->port == 445)
- return True;
-
/* send a session request (RFC 1002) */
/* setup the packet length
* Remove four bytes from the length count, since the length
@@ -1605,11 +1605,11 @@ NTSTATUS cli_start_connection(struct cli_state **output_cli,
if (!my_name)
my_name = global_myname();
-
+
if (!(cli = cli_initialise())) {
return NT_STATUS_NO_MEMORY;
}
-
+
make_nmb_name(&calling, my_name, 0x0);
make_nmb_name(&called , dest_host, 0x20);
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 1c525363f7..a9e81082ea 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -66,7 +66,7 @@ static bool cli_link_internal(struct cli_state *cli, const char *oldname, const
-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 */
+ data, data_len, cli->max_xmit /* data, length, max */
)) {
SAFE_FREE(data);
SAFE_FREE(param);
diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c
index c929f0b7a9..bbdfb75fcd 100644
--- a/source3/libsmb/clitrans.c
+++ b/source3/libsmb/clitrans.c
@@ -978,19 +978,6 @@ static void cli_trans_ship_rest(struct async_req *req,
}
}
-static bool cli_trans_oob(uint32_t bufsize, uint32_t offset, uint32_t length)
-{
- if ((offset + length < offset) || (offset + length < length)) {
- /* wrap */
- return true;
- }
- if ((offset > bufsize) || (offset + length > bufsize)) {
- /* overflow */
- return true;
- }
- return false;
-}
-
static NTSTATUS cli_pull_trans(struct async_req *req,
struct cli_request *cli_req,
uint8_t smb_cmd, bool expect_first_reply,
@@ -1072,10 +1059,10 @@ static NTSTATUS cli_pull_trans(struct async_req *req,
* length. Likewise for param_ofs/param_disp.
*/
- if (cli_trans_oob(smb_len(cli_req->inbuf), param_ofs, *pnum_param)
- || cli_trans_oob(*ptotal_param, *pparam_disp, *pnum_param)
- || cli_trans_oob(smb_len(cli_req->inbuf), data_ofs, *pnum_data)
- || cli_trans_oob(*ptotal_data, *pdata_disp, *pnum_data)) {
+ if (trans_oob(smb_len(cli_req->inbuf), param_ofs, *pnum_param)
+ || trans_oob(*ptotal_param, *pparam_disp, *pnum_param)
+ || trans_oob(smb_len(cli_req->inbuf), data_ofs, *pnum_data)
+ || trans_oob(*ptotal_data, *pdata_disp, *pnum_data)) {
return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c
index ff0a8f9808..d8c2b70175 100644
--- a/source3/libsmb/dsgetdcname.c
+++ b/source3/libsmb/dsgetdcname.c
@@ -1040,6 +1040,8 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx,
r->data.nt4 = logon1;
r->ntver = nt_version;
+ map_netlogon_samlogon_response(r);
+
namecache_store(tmp_dc_name, NBT_NAME_SERVER, 1, &ip_list);
goto make_reply;
diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c
index 1ba230cefe..465d88a9b6 100644
--- a/source3/libsmb/nterr.c
+++ b/source3/libsmb/nterr.c
@@ -532,6 +532,7 @@ static const nt_err_code_struct nt_errs[] =
{ "NT_STATUS_TOO_MANY_LINKS", NT_STATUS_TOO_MANY_LINKS },
{ "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT },
{ "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE },
+ { "NT_STATUS_DS_BUSY", NT_STATUS_DS_BUSY },
{ "NT_STATUS_DS_NO_MORE_RIDS", NT_STATUS_DS_NO_MORE_RIDS },
{ "NT_STATUS_NOT_A_REPARSE_POINT", NT_STATUS_NOT_A_REPARSE_POINT },
{ "NT_STATUS_DOWNGRADE_DETECTED", NT_STATUS_DOWNGRADE_DETECTED },
diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c
index a0e54ce769..cc13476935 100644
--- a/source3/libsmb/ntlmssp.c
+++ b/source3/libsmb/ntlmssp.c
@@ -11,12 +11,12 @@
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/>.
*/
@@ -60,7 +60,7 @@ static const struct ntlmssp_callbacks {
void debug_ntlmssp_flags(uint32 neg_flags)
{
DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags));
-
+
if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE)
DEBUGADD(4, (" NTLMSSP_NEGOTIATE_UNICODE\n"));
if (neg_flags & NTLMSSP_NEGOTIATE_OEM)
@@ -109,7 +109,7 @@ void debug_ntlmssp_flags(uint32 neg_flags)
* Default challenge generation code.
*
*/
-
+
static const uint8 *get_challenge(const struct ntlmssp_state *ntlmssp_state)
{
static uchar chal[8];
@@ -122,7 +122,7 @@ static const uint8 *get_challenge(const struct ntlmssp_state *ntlmssp_state)
* Default 'we can set the challenge to anything we like' implementation
*
*/
-
+
static bool may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
{
return True;
@@ -134,7 +134,7 @@ static bool may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
* Does not actually do anything, as the value is always in the structure anyway.
*
*/
-
+
static NTSTATUS set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
{
SMB_ASSERT(challenge->length == 8);
@@ -148,7 +148,7 @@ static NTSTATUS set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *ch
NTSTATUS ntlmssp_set_username(NTLMSSP_STATE *ntlmssp_state, const char *user)
{
- ntlmssp_state->user = talloc_strdup(ntlmssp_state->mem_ctx, user ? user : "" );
+ ntlmssp_state->user = talloc_strdup(ntlmssp_state, user ? user : "" );
if (!ntlmssp_state->user) {
return NT_STATUS_NO_MEMORY;
}
@@ -164,9 +164,9 @@ NTSTATUS ntlmssp_set_hashes(NTLMSSP_STATE *ntlmssp_state,
const unsigned char nt_hash[16])
{
ntlmssp_state->lm_hash = (unsigned char *)
- TALLOC_MEMDUP(ntlmssp_state->mem_ctx, lm_hash, 16);
+ TALLOC_MEMDUP(ntlmssp_state, lm_hash, 16);
ntlmssp_state->nt_hash = (unsigned char *)
- TALLOC_MEMDUP(ntlmssp_state->mem_ctx, nt_hash, 16);
+ TALLOC_MEMDUP(ntlmssp_state, nt_hash, 16);
if (!ntlmssp_state->lm_hash || !ntlmssp_state->nt_hash) {
TALLOC_FREE(ntlmssp_state->lm_hash);
TALLOC_FREE(ntlmssp_state->nt_hash);
@@ -201,7 +201,8 @@ NTSTATUS ntlmssp_set_password(NTLMSSP_STATE *ntlmssp_state, const char *password
*/
NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain)
{
- ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain ? domain : "" );
+ ntlmssp_state->domain = talloc_strdup(ntlmssp_state,
+ domain ? domain : "" );
if (!ntlmssp_state->domain) {
return NT_STATUS_NO_MEMORY;
}
@@ -214,7 +215,7 @@ NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain)
*/
NTSTATUS ntlmssp_set_workstation(NTLMSSP_STATE *ntlmssp_state, const char *workstation)
{
- ntlmssp_state->workstation = talloc_strdup(ntlmssp_state->mem_ctx, workstation);
+ ntlmssp_state->workstation = talloc_strdup(ntlmssp_state, workstation);
if (!ntlmssp_state->workstation) {
return NT_STATUS_NO_MEMORY;
}
@@ -229,8 +230,9 @@ NTSTATUS ntlmssp_set_workstation(NTLMSSP_STATE *ntlmssp_state, const char *works
NTSTATUS ntlmssp_store_response(NTLMSSP_STATE *ntlmssp_state,
DATA_BLOB response)
{
- ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state->mem_ctx,
- response.data, response.length);
+ ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state,
+ response.data,
+ response.length);
return NT_STATUS_OK;
}
@@ -277,7 +279,7 @@ void ntlmssp_want_feature(NTLMSSP_STATE *ntlmssp_state, uint32 feature)
ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
}
}
-
+
/**
* Next state function for the NTLMSSP state machine
*
@@ -304,7 +306,7 @@ NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state,
if (!in.length && ntlmssp_state->stored_response.length) {
input = ntlmssp_state->stored_response;
-
+
/* we only want to read the stored response once - overwrite it */
ntlmssp_state->stored_response = data_blob_null;
} else {
@@ -357,16 +359,13 @@ NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state,
void ntlmssp_end(NTLMSSP_STATE **ntlmssp_state)
{
- TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx;
-
(*ntlmssp_state)->ref_count--;
if ((*ntlmssp_state)->ref_count == 0) {
data_blob_free(&(*ntlmssp_state)->chal);
data_blob_free(&(*ntlmssp_state)->lm_resp);
data_blob_free(&(*ntlmssp_state)->nt_resp);
-
- talloc_destroy(mem_ctx);
+ TALLOC_FREE(*ntlmssp_state);
}
*ntlmssp_state = NULL;
@@ -562,13 +561,14 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
if (target_name == NULL)
return NT_STATUS_INVALID_PARAMETER;
- ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8);
- ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8);
+ ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);
+ ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state,
+ cryptkey, 8);
/* This should be a 'netbios domain -> DNS domain' mapping */
- dnsdomname = get_mydnsdomname(ntlmssp_state->mem_ctx);
+ dnsdomname = get_mydnsdomname(ntlmssp_state);
if (!dnsdomname) {
- dnsdomname = talloc_strdup(ntlmssp_state->mem_ctx, "");
+ dnsdomname = talloc_strdup(ntlmssp_state, "");
}
if (!dnsdomname) {
return NT_STATUS_NO_MEMORY;
@@ -685,7 +685,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
SAFE_FREE(workstation);
data_blob_free(&encrypted_session_key);
auth_flags = 0;
-
+
/* Try again with a shorter string (Win9X truncates this packet) */
if (ntlmssp_state->unicode) {
parse_string = "CdBBUUU";
@@ -753,24 +753,25 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
/* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a
client challenge
-
+
However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
*/
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
struct MD5Context md5_session_nonce_ctx;
SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8);
-
+
doing_ntlm2 = True;
memcpy(session_nonce, ntlmssp_state->internal_chal.data, 8);
memcpy(&session_nonce[8], ntlmssp_state->lm_resp.data, 8);
-
+
MD5Init(&md5_session_nonce_ctx);
MD5Update(&md5_session_nonce_ctx, session_nonce, 16);
MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
-
- ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, session_nonce_hash, 8);
+
+ ntlmssp_state->chal = data_blob_talloc(
+ ntlmssp_state, session_nonce_hash, 8);
/* LM response is no longer useful */
data_blob_free(&ntlmssp_state->lm_resp);
@@ -807,12 +808,13 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
/* Handle the different session key derivation for NTLM2 */
if (doing_ntlm2) {
if (user_session_key.data && user_session_key.length == 16) {
- session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
+ session_key = data_blob_talloc(ntlmssp_state,
+ NULL, 16);
hmac_md5(user_session_key.data, session_nonce,
sizeof(session_nonce), session_key.data);
DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
-
+
} else {
DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
session_key = data_blob_null;
@@ -820,7 +822,8 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
} else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
if (lm_session_key.data && lm_session_key.length >= 8) {
if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
- session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
+ session_key = data_blob_talloc(ntlmssp_state,
+ NULL, 16);
if (session_key.data == NULL) {
return NT_STATUS_NO_MEMORY;
}
@@ -831,7 +834,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
uint8 zeros[24];
ZERO_STRUCT(zeros);
session_key = data_blob_talloc(
- ntlmssp_state->mem_ctx, NULL, 16);
+ ntlmssp_state, NULL, 16);
if (session_key.data == NULL) {
return NT_STATUS_NO_MEMORY;
}
@@ -875,9 +878,9 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
SamOEMhash(encrypted_session_key.data,
session_key.data,
encrypted_session_key.length);
- ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state->mem_ctx,
- encrypted_session_key.data,
- encrypted_session_key.length);
+ ntlmssp_state->session_key = data_blob_talloc(
+ ntlmssp_state, encrypted_session_key.data,
+ encrypted_session_key.length);
dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data,
encrypted_session_key.length);
}
@@ -892,7 +895,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
}
data_blob_free(&encrypted_session_key);
-
+
/* Only one authentication allowed per server state. */
ntlmssp_state->expected_state = NTLMSSP_DONE;
@@ -907,20 +910,15 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state)
{
- TALLOC_CTX *mem_ctx;
-
- mem_ctx = talloc_init("NTLMSSP context");
-
- *ntlmssp_state = TALLOC_ZERO_P(mem_ctx, NTLMSSP_STATE);
+ *ntlmssp_state = TALLOC_ZERO_P(NULL, NTLMSSP_STATE);
if (!*ntlmssp_state) {
DEBUG(0,("ntlmssp_server_start: talloc failed!\n"));
- talloc_destroy(mem_ctx);
+ talloc_destroy(*ntlmssp_state);
return NT_STATUS_NO_MEMORY;
}
(*ntlmssp_state)->role = NTLMSSP_SERVER;
- (*ntlmssp_state)->mem_ctx = mem_ctx;
(*ntlmssp_state)->get_challenge = get_challenge;
(*ntlmssp_state)->set_challenge = set_challenge;
(*ntlmssp_state)->may_set_challenge = may_set_challenge;
@@ -968,7 +966,7 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
} else {
ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
}
-
+
if (ntlmssp_state->use_ntlmv2) {
ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
}
@@ -1021,7 +1019,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
return NT_STATUS_INVALID_PARAMETER;
}
-
+
data_blob_free(&server_domain_blob);
DEBUG(3, ("Got challenge flags:\n"));
@@ -1062,7 +1060,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
return NT_STATUS_INVALID_PARAMETER;
}
- ntlmssp_state->server_domain = talloc_strdup(ntlmssp_state->mem_ctx,
+ ntlmssp_state->server_domain = talloc_strdup(ntlmssp_state,
server_domain);
SAFE_FREE(server_domain);
@@ -1078,8 +1076,8 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
ZERO_STRUCT(zeros);
/* session key is all zeros */
- session_key = data_blob_talloc(ntlmssp_state->mem_ctx, zeros, 16);
-
+ session_key = data_blob_talloc(ntlmssp_state, zeros, 16);
+
/* not doing NLTM2 without a password */
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
} else if (ntlmssp_state->use_ntlmv2) {
@@ -1092,7 +1090,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
/* TODO: if the remote server is standalone, then we should replace 'domain'
with the server name as supplied above */
-
+
if (!SMBNTLMv2encrypt_hash(ntlmssp_state->user,
ntlmssp_state->domain,
ntlmssp_state->nt_hash, &challenge_blob,
@@ -1107,14 +1105,14 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
uchar session_nonce[16];
uchar session_nonce_hash[16];
uchar user_session_key[16];
-
- lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
+
+ lm_response = data_blob_talloc(ntlmssp_state, NULL, 24);
generate_random_buffer(lm_response.data, 8);
memset(lm_response.data+8, 0, 16);
memcpy(session_nonce, challenge_blob.data, 8);
memcpy(&session_nonce[8], lm_response.data, 8);
-
+
MD5Init(&md5_session_nonce_ctx);
MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8);
MD5Update(&md5_session_nonce_ctx, lm_response.data, 8);
@@ -1123,13 +1121,13 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
DEBUG(5, ("NTLMSSP challenge set by NTLM2\n"));
DEBUG(5, ("challenge is: \n"));
dump_data(5, session_nonce_hash, 8);
-
- nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
+
+ nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
SMBNTencrypt_hash(ntlmssp_state->nt_hash,
session_nonce_hash,
nt_response.data);
- session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
+ session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, NULL, user_session_key);
hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data);
@@ -1137,16 +1135,17 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
} else {
/* lanman auth is insecure, it may be disabled */
if (lp_client_lanman_auth()) {
- lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
+ lm_response = data_blob_talloc(ntlmssp_state,
+ NULL, 24);
SMBencrypt_hash(ntlmssp_state->lm_hash,challenge_blob.data,
lm_response.data);
}
-
- nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
+
+ nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
SMBNTencrypt_hash(ntlmssp_state->nt_hash,challenge_blob.data,
nt_response.data);
-
- session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
+
+ session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
&& lp_client_lanman_auth()) {
SMBsesskeygen_lm_sess_key(ntlmssp_state->lm_hash, lm_response.data,
@@ -1174,7 +1173,9 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
/* Mark the new session key as the 'real' session key */
data_blob_free(&session_key);
- session_key = data_blob_talloc(ntlmssp_state->mem_ctx, client_session_key, sizeof(client_session_key));
+ session_key = data_blob_talloc(ntlmssp_state,
+ client_session_key,
+ sizeof(client_session_key));
}
/* this generates the actual auth packet */
@@ -1188,7 +1189,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
ntlmssp_state->get_global_myname(),
encrypted_session_key.data, encrypted_session_key.length,
ntlmssp_state->neg_flags)) {
-
+
return NT_STATUS_NO_MEMORY;
}
@@ -1213,21 +1214,15 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state)
{
- TALLOC_CTX *mem_ctx;
-
- mem_ctx = talloc_init("NTLMSSP Client context");
-
- *ntlmssp_state = TALLOC_ZERO_P(mem_ctx, NTLMSSP_STATE);
+ *ntlmssp_state = TALLOC_ZERO_P(NULL, NTLMSSP_STATE);
if (!*ntlmssp_state) {
DEBUG(0,("ntlmssp_client_start: talloc failed!\n"));
- talloc_destroy(mem_ctx);
+ talloc_destroy(*ntlmssp_state);
return NT_STATUS_NO_MEMORY;
}
(*ntlmssp_state)->role = NTLMSSP_CLIENT;
- (*ntlmssp_state)->mem_ctx = mem_ctx;
-
(*ntlmssp_state)->get_global_myname = global_myname;
(*ntlmssp_state)->get_domain = lp_workgroup;
diff --git a/source3/locale/pam_winbind/de.po b/source3/locale/pam_winbind/de.po
new file mode 100644
index 0000000000..5a7223d63d
--- /dev/null
+++ b/source3/locale/pam_winbind/de.po
@@ -0,0 +1,181 @@
+# pam_winbind message translations (german)
+# Copyright (C) 2008 Guenther Deschner <gd@samba.org>
+# This file is distributed under the same license as the pam_winbind package.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: @PACKAGE@\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2008-11-17 12:00+0100\n"
+"PO-Revision-Date: 2008-11-13 14:29+0100\n"
+"Last-Translator: Guenther Deschner <gd@samba.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: ../../nsswitch/pam_winbind.c:579
+msgid "Success"
+msgstr "Erfolgreich"
+
+#: ../../nsswitch/pam_winbind.c:581
+msgid "No primary Domain Controler available"
+msgstr "Kein primärer Domänen-Controller verfügbar"
+
+#: ../../nsswitch/pam_winbind.c:583
+msgid "No domain controllers found"
+msgstr "Keine Domänen-Controller gefunden"
+
+#: ../../nsswitch/pam_winbind.c:585
+msgid "No logon servers"
+msgstr "Keine Anmeldeserver verfügbar"
+
+#: ../../nsswitch/pam_winbind.c:587
+msgid "Password too short"
+msgstr "Passwort ist zu kurz"
+
+#: ../../nsswitch/pam_winbind.c:589
+msgid "The password of this user is too recent to change"
+msgstr "Das Passwort des Benutzers kann noch nicht erneut geändert werden"
+
+#: ../../nsswitch/pam_winbind.c:591
+msgid "Password is already in password history"
+msgstr "Das neue Passwort ist bereits in der Passwort-Historie enthalten"
+
+#: ../../nsswitch/pam_winbind.c:593
+msgid "Your password has expired"
+msgstr "Ihr Passwort ist abgelaufen"
+
+#: ../../nsswitch/pam_winbind.c:595
+msgid "You need to change your password now"
+msgstr "Sie müssen Ihr Passwort unmittelbar ändern"
+
+#: ../../nsswitch/pam_winbind.c:597
+msgid "You are not allowed to logon from this workstation"
+msgstr "Sie können sich nicht von diesem Arbeitsplatz aus anmelden"
+
+#: ../../nsswitch/pam_winbind.c:599
+msgid "You are not allowed to logon at this time"
+msgstr "Sie können sich zum jetzigen Zeitpunkt nicht anmelden"
+
+#: ../../nsswitch/pam_winbind.c:601
+msgid "Your account has expired. Please contact your System administrator"
+msgstr "Ihr Benutzerkonto ist abgelaufen. Bitte kontaktieren Sie ihren System-Administrator"
+
+#: ../../nsswitch/pam_winbind.c:604
+msgid "Your account is disabled. Please contact your System administrator"
+msgstr "Ihr Benutzerkonto ist deaktiviert. Bitte kontaktieren Sie ihren System-Administrator"
+
+#: ../../nsswitch/pam_winbind.c:607
+msgid "Your account has been locked. Please contact your System administrator"
+msgstr "Ihr Benutzerkonto wurde gesperrt. Bitte kontaktieren Sie ihren System-Administrator"
+
+#: ../../nsswitch/pam_winbind.c:610 ../../nsswitch/pam_winbind.c:612 ../../nsswitch/pam_winbind.c:614
+msgid "Invalid Trust Account"
+msgstr "Ungültiges Maschinen-Konto"
+
+#: ../../nsswitch/pam_winbind.c:616
+msgid "Access is denied"
+msgstr "Zugriff verweigert"
+
+#: ../../nsswitch/pam_winbind.c:854
+msgid "Your password expires today"
+msgstr "Ihr Passwort läuft heute ab"
+
+#: ../../nsswitch/pam_winbind.c:860
+#, c-format
+msgid "Your password will expire in %d %s"
+msgstr "Ihr Passwort wird in %d %s ungültig"
+
+#: ../../nsswitch/pam_winbind.c:861
+msgid "days"
+msgstr "Tagen"
+
+#: ../../nsswitch/pam_winbind.c:861
+msgid "day"
+msgstr "Tag"
+
+#: ../../nsswitch/pam_winbind.c:1253
+msgid "Grace login. Please change your password as soon you're online again"
+msgstr "Kulanzanmeldung. Bitte ändern sie ihr Passwort sobald sie wieder online sind"
+
+#: ../../nsswitch/pam_winbind.c:1263
+msgid "Domain Controller unreachable, using cached credentials instead. Network resources may be unavailable"
+msgstr "Domänen-Controller unerreichbar. Anmeldung erfolgte mit gespeicherten Anmeldedaten. Netzwerk Ressourcen können momentan nicht verfügbar sein"
+
+#: ../../nsswitch/pam_winbind.c:1288
+msgid ""
+"Failed to establish your Kerberos Ticket cache due time differences\n"
+"with the domain controller. Please verify the system time.\n"
+msgstr ""
+"Anforderung eines Kerberos Tickets aufgrund Zeitunterscheid zum \n"
+"Domänen-Controller fehlgeschlagen. Bitte überprüfen Sie die Systemzeit.\n"
+
+#: ../../nsswitch/pam_winbind.c:1356
+msgid "Your password "
+msgstr "Ihr Passwort "
+
+#: ../../nsswitch/pam_winbind.c:1363
+#, c-format
+msgid "must be at least %d characters; "
+msgstr "muß mindestens %d Zeichen lang sein; "
+
+#: ../../nsswitch/pam_winbind.c:1372
+#, c-format
+msgid "cannot repeat any of your previous %d passwords; "
+msgstr "kann keines der %d vorherigen Passwörter enthalten; "
+
+#: ../../nsswitch/pam_winbind.c:1382
+msgid "must contain capitals, numerals or punctuation; and cannot contain your account or full name; "
+msgstr "muß Großbuchstaben, Ziffern oder Punktzeichen enthalten; kann nicht den Benutzer- oder vollen Namen enthalten; "
+
+#: ../../nsswitch/pam_winbind.c:1392
+msgid "Please type a different password. Type a password which meets these requirements in both text boxes."
+msgstr "Bitte wählen Sie ein anderes Passwort. Geben Sie ein geeignetes Passwort in beide Textfelder ein."
+
+#: ../../nsswitch/pam_winbind.c:1419
+#, c-format
+msgid "Creating directory: %s failed: %s"
+msgstr "Anlegen des Verzeichnis: %s fehlgeschlagen: %s"
+
+#: ../../nsswitch/pam_winbind.c:1877
+msgid "Password does not meet complexity requirements"
+msgstr "Passwort genügt nicht den Komplexitätsanforderungen"
+
+#.
+#. * First get the name of a user
+#.
+#: ../../nsswitch/pam_winbind.c:2336 ../../nsswitch/pam_winbind.c:2883
+msgid "Username: "
+msgstr "Benuzername: "
+
+#: ../../nsswitch/pam_winbind.c:2513
+msgid "Password: "
+msgstr "Passwort: "
+
+#. instruct user what is happening
+#: ../../nsswitch/pam_winbind.c:2921
+#, fuzzy
+msgid "Changing password for"
+msgstr "Ändere Passwort für"
+
+#: ../../nsswitch/pam_winbind.c:2934
+msgid "(current) NT password: "
+msgstr "(aktuelles) NT Passwort: "
+
+#: ../../nsswitch/pam_winbind.c:3004
+msgid "Enter new NT password: "
+msgstr "Neues NT Passwort eingeben: "
+
+#: ../../nsswitch/pam_winbind.c:3005
+msgid "Retype new NT password: "
+msgstr "Neues NT Passwort wiederholen: "
+
+#.
+#. * here is the string to inform the user that the new passwords they
+#. * typed were not the same.
+#.
+#: ../../nsswitch/pam_winbind.h:122
+msgid "Sorry, passwords do not match"
+msgstr "Passwörter stimmen leider nicht überein"
diff --git a/source3/locale/pam_winbind/genmsg b/source3/locale/pam_winbind/genmsg
new file mode 100755
index 0000000000..5aa258aa85
--- /dev/null
+++ b/source3/locale/pam_winbind/genmsg
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+FILES="../../nsswitch/pam_winbind.c ../../nsswitch/pam_winbind.h"
+LANGS="af ar bg bn bs ca cs cy da de el en_GB en_US es et fi fr gl gu he hi hr hu id it ja ka km ko lo lt mk mr nb nl pa pl pt_BR pt ro ru si sk sl sr sv ta th tr uk vi wa xh zh_CN zh_TW zu"
+
+XGETTEXT=xgettext
+MSGMERGE=msgmerge
+
+WIDTH=256
+
+$XGETTEXT --default-domain="pam_winbind" \
+ --add-comments \
+ --keyword=_ --keyword=N_ \
+ --width=${WIDTH} \
+ ${FILES}
+
+for lang in ${LANGS}; do
+ echo -n $lang
+ touch ${lang}.po
+ mv ${lang}.po ${lang}.po.old
+ ${MSGMERGE} --width=${WIDTH} ${lang}.po.old pam_winbind.po -o ${lang}.po
+ rm -fr ${lang}.po.old
+done
+
+rm -fr pam_winbind.po
diff --git a/source3/localedir.c b/source3/localedir.c
new file mode 100644
index 0000000000..20f69219ed
--- /dev/null
+++ b/source3/localedir.c
@@ -0,0 +1,3 @@
+#include "localedir.h"
+
+const char *dyn_LOCALEDIR = LOCALEDIR;
diff --git a/source3/m4/check_path.m4 b/source3/m4/check_path.m4
index 9c99468084..da6c922233 100644
--- a/source3/m4/check_path.m4
+++ b/source3/m4/check_path.m4
@@ -30,6 +30,7 @@ swatdir="\${prefix}/swat"
codepagedir="\${MODULESDIR}"
statedir="\${LOCKDIR}"
cachedir="\${LOCKDIR}"
+localedir="\${prefix}/share/locale"
AC_ARG_WITH(fhs,
[AS_HELP_STRING([--with-fhs],[Use FHS-compliant paths (default=no)])],
@@ -242,6 +243,23 @@ AC_ARG_WITH(mandir,
;;
esac])
+################################################
+# set locale directory location
+AC_ARG_WITH(localedir,
+[ --with-localedir=DIR Where to put po files ($ac_default_prefix/share/locale)],
+[ case "$withval" in
+ yes|no)
+ #
+ # Just in case anybody does it
+ #
+ AC_MSG_WARN([--with-localedir called without argument - will use default])
+ ;;
+ *)
+ localedir="$withval"
+ ;;
+ esac])
+
+
AC_SUBST(configdir)
AC_SUBST(lockdir)
AC_SUBST(piddir)
@@ -258,6 +276,7 @@ AC_SUBST(cachedir)
AC_SUBST(rootsbindir)
AC_SUBST(pammodulesdir)
AC_SUBST(modulesdir)
+AC_SUBST(localedir)
#################################################
# set prefix for 'make test'
@@ -276,6 +295,22 @@ AC_ARG_WITH(selftest-prefix,
])
#################################################
+# set shrdir for 'make test'
+selftest_shrdir=""
+AC_SUBST(selftest_shrdir)
+AC_ARG_WITH(selftest-shrdir,
+[AS_HELP_STRING([--with-selftest-shrdir=DIR], [The share directory that make test will be run against ($selftest_shrdir)])],
+[ case "$withval" in
+ yes|no)
+ AC_MSG_WARN([--with-selftest-shrdir called without argument - will use default])
+ ;;
+ * )
+ selftest_shrdir="$withval"
+ ;;
+ esac
+])
+
+#################################################
# set path of samba4's smbtorture
smbtorture4_path=""
AC_SUBST(smbtorture4_path)
diff --git a/source3/modules/gpfs.c b/source3/modules/gpfs.c
index a0d33fa33a..4e76b97ccf 100644
--- a/source3/modules/gpfs.c
+++ b/source3/modules/gpfs.c
@@ -24,7 +24,6 @@
#include "gpfs_gpl.h"
#include "vfs_gpfs.h"
-static void *libgpfs_handle = NULL;
static bool gpfs_share_modes;
static bool gpfs_leases;
@@ -135,65 +134,64 @@ int smbd_gpfs_putacl(char *pathname, int flags, void *acl)
return gpfs_putacl_fn(pathname, flags, acl);
}
-void init_gpfs(void)
+static bool init_gpfs_function_lib(void *plibhandle_pointer,
+ const char *libname,
+ void *pfn_pointer, const char *fn_name)
{
- if (libgpfs_handle != NULL) {
- return;
- }
-
- libgpfs_handle = dlopen("libgpfs_gpl.so", RTLD_LAZY);
-
- if (libgpfs_handle == NULL) {
- DEBUG(10, ("dlopen for libgpfs_gpl failed: %s\n",
- strerror(errno)));
- return;
+ bool did_open_here = false;
+ void **libhandle_pointer = (void **)plibhandle_pointer;
+ void **fn_pointer = (void **)pfn_pointer;
+
+ if (*libhandle_pointer == NULL) {
+ *libhandle_pointer = dlopen(libname, RTLD_LAZY);
+ did_open_here = true;
+ }
+ if (*libhandle_pointer == NULL) {
+ DEBUG(10, ("Could not open lib %s\n", libname));
+ return false;
+ }
+
+ *fn_pointer = dlsym(*libhandle_pointer, fn_name);
+ if (*fn_pointer == NULL) {
+ DEBUG(10, ("Did not find symbol %s in lib %s\n",
+ fn_name, libname));
+ if (did_open_here) {
+ dlclose(*libhandle_pointer);
+ *libhandle_pointer = NULL;
+ }
+ return false;
}
- DEBUG(10, ("libgpfs_gpl.so loaded\n"));
-
- gpfs_set_share_fn = dlsym(libgpfs_handle, "gpfs_set_share");
- if (gpfs_set_share_fn == NULL) {
- DEBUG(3, ("libgpfs_gpl.so does not contain the symbol "
- "'gpfs_set_share'\n"));
- goto failed;
- }
+ return true;
+}
- gpfs_set_lease_fn = dlsym(libgpfs_handle, "gpfs_set_lease");
- if (gpfs_set_lease_fn == NULL) {
- DEBUG(3, ("libgpfs_gpl.so does not contain the symbol "
- "'gpfs_set_lease'\n"));
- dlclose(libgpfs_handle);
+static bool init_gpfs_function(void *fn_pointer, const char *fn_name)
+{
+ static void *libgpfs_handle = NULL;
+ static void *libgpfs_gpl_handle = NULL;
- goto failed;
+ if (init_gpfs_function_lib(&libgpfs_handle, "libgpfs.so",
+ fn_pointer, fn_name)) {
+ return true;
}
-
- gpfs_getacl_fn = dlsym(libgpfs_handle, "gpfs_getacl");
- if (gpfs_getacl_fn == NULL) {
- DEBUG(3, ("libgpfs_gpl.so does not contain the symbol "
- "'gpfs_getacl'\n"));
- goto failed;
+ if (init_gpfs_function_lib(&libgpfs_gpl_handle, "libgpfs_gpl.so",
+ fn_pointer, fn_name)) {
+ return true;
}
+ return false;
+}
- gpfs_putacl_fn = dlsym(libgpfs_handle, "gpfs_putacl");
- if (gpfs_putacl_fn == NULL) {
- DEBUG(3, ("libgpfs_gpl.so does not contain the symbol "
- "'gpfs_putacl'\n"));
- goto failed;
- }
+void init_gpfs(void)
+{
+ init_gpfs_function(&gpfs_set_share_fn, "gpfs_set_share");
+ init_gpfs_function(&gpfs_set_lease_fn, "gpfs_set_lease");
+ init_gpfs_function(&gpfs_getacl_fn, "gpfs_getacl");
+ init_gpfs_function(&gpfs_putacl_fn, "gpfs_putacl");
gpfs_share_modes = lp_parm_bool(-1, "gpfs", "sharemodes", True);
gpfs_leases = lp_parm_bool(-1, "gpfs", "leases", True);
return;
-
-failed:
- dlclose(libgpfs_handle);
- /* leave libgpfs_handle != NULL around, no point
- in trying twice */
- gpfs_set_share_fn = NULL;
- gpfs_set_lease_fn = NULL;
- gpfs_getacl_fn = NULL;
- gpfs_putacl_fn = NULL;
}
#else
diff --git a/source3/modules/nfs4_acls.h b/source3/modules/nfs4_acls.h
index 0f783aa977..a227c6e0fc 100644
--- a/source3/modules/nfs4_acls.h
+++ b/source3/modules/nfs4_acls.h
@@ -144,7 +144,7 @@ typedef bool (*set_nfs4acl_native_fn_t)(files_struct *, SMB4ACL_T *);
NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
uint32 security_info_sent,
- SEC_DESC *psd,
+ const SEC_DESC *psd,
set_nfs4acl_native_fn_t set_nfs4_native);
#endif /* __NFS4_ACLS_H__ */
diff --git a/source3/modules/onefs.h b/source3/modules/onefs.h
new file mode 100644
index 0000000000..965f39509a
--- /dev/null
+++ b/source3/modules/onefs.h
@@ -0,0 +1,52 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Support for OneFS
+ *
+ * Copyright (C) Steven Danneman, 2008
+ *
+ * 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 _ONEFS_H
+#define _ONEFS_H
+
+/* OneFS Module smb.conf parameters and defaults */
+
+/**
+* Specifies when ACLs presented to Windows should be canonicalized
+* into the ordering which Explorer expects.
+*/
+enum onefs_acl_wire_format
+{
+ ACL_FORMAT_RAW, /**< Never canonicalize */
+ ACL_FORMAT_WINDOWS_SD, /**< Only canonicalize synthetic ACLs */
+ ACL_FORMAT_ALWAYS /**< Always canonicalize */
+};
+
+const struct enum_list enum_onefs_acl_wire_format[] = {
+ {ACL_FORMAT_RAW, "No Format"},
+ {ACL_FORMAT_WINDOWS_SD, "Format Windows SD"},
+ {ACL_FORMAT_ALWAYS, "Always Format SD"},
+ {-1, NULL}
+};
+
+#define PARM_ONEFS_TYPE "onefs"
+#define PARM_ACL_WIRE_FORMAT "acl wire format"
+#define PARM_ACL_WIRE_FORMAT_DEFAULT ACL_FORMAT_WINDOWS_SD
+#define PARM_SIMPLE_FILE_SHARING_COMPATIBILITY_MODE "simple file sharing compatibility mode"
+#define PARM_SIMPLE_FILE_SHARING_COMPATIBILITY_MODE_DEFAULT false
+#define PARM_CREATOR_OWNER_GETS_FULL_CONTROL "creator owner gets full control"
+#define PARM_CREATOR_OWNER_GETS_FULL_CONTROL_DEFAULT true
+
+#endif /* _ONEFS_H */
diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c
new file mode 100644
index 0000000000..3a692c95ab
--- /dev/null
+++ b/source3/modules/onefs_acl.c
@@ -0,0 +1,807 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Support for OneFS native NTFS ACLs
+ *
+ * Copyright (C) Steven Danneman, 2008
+ *
+ * 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 <sys/isi_acl.h>
+#include <isi_acl/isi_acl_util.h>
+#include <sys/isi_oplock.h>
+#include <ifs/ifs_syscalls.h>
+
+#include "onefs.h"
+
+/**
+ * Turn SID into UID/GID and setup a struct ifs_identity
+ */
+static bool
+onefs_sid_to_identity(DOM_SID *sid, struct ifs_identity *id, bool is_group)
+{
+ enum ifs_identity_type type = IFS_ID_TYPE_LAST+1;
+ uid_t uid = 0;
+ gid_t gid = 0;
+
+ if (!sid || sid_equal(sid, &global_sid_NULL))
+ type = IFS_ID_TYPE_NULL;
+ else if (sid_equal(sid, &global_sid_World))
+ type = IFS_ID_TYPE_EVERYONE;
+ else if (sid_equal(sid, &global_sid_Creator_Owner))
+ type = IFS_ID_TYPE_CREATOR_OWNER;
+ else if (sid_equal(sid, &global_sid_Creator_Group))
+ type = IFS_ID_TYPE_CREATOR_GROUP;
+ else if (is_group) {
+ if (!sid_to_gid(sid, &gid))
+ return false;
+ type = IFS_ID_TYPE_GID;
+ } else {
+ if (sid_to_uid(sid, &uid))
+ type = IFS_ID_TYPE_UID;
+ else if (sid_to_gid(sid, &gid))
+ type = IFS_ID_TYPE_GID;
+ else
+ return false;
+ }
+
+ if (aclu_initialize_identity(id, type, uid, gid, is_group)) {
+ DEBUG(3, ("Call to aclu_initialize_identity failed! id=%x, "
+ "type=%d, uid=%u, gid=%u, is_group=%d\n",
+ (unsigned int)id, type, uid, gid, is_group));
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Turn struct ifs_identity into SID
+ */
+static bool
+onefs_identity_to_sid(struct ifs_identity *id, DOM_SID *sid)
+{
+ if (!id || !sid)
+ return false;
+
+ if (id->type >= IFS_ID_TYPE_LAST)
+ return false;
+
+ switch (id->type) {
+ case IFS_ID_TYPE_UID:
+ uid_to_sid(sid, id->id.uid);
+ break;
+ case IFS_ID_TYPE_GID:
+ gid_to_sid(sid, id->id.gid);
+ break;
+ case IFS_ID_TYPE_EVERYONE:
+ sid_copy(sid, &global_sid_World);
+ break;
+ case IFS_ID_TYPE_NULL:
+ sid_copy(sid, &global_sid_NULL);
+ break;
+ case IFS_ID_TYPE_CREATOR_OWNER:
+ sid_copy(sid, &global_sid_Creator_Owner);
+ break;
+ case IFS_ID_TYPE_CREATOR_GROUP:
+ sid_copy(sid, &global_sid_Creator_Group);
+ break;
+ default:
+ DEBUG(0, ("Unknown identity type: %d\n", id->type));
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Convert a SEC_ACL to a struct ifs_security_acl
+ */
+static bool
+onefs_samba_acl_to_acl(SEC_ACL *samba_acl, struct ifs_security_acl **acl)
+{
+ int num_aces = 0;
+ struct ifs_ace *aces = NULL;
+ struct ifs_identity temp;
+ SEC_ACE *samba_aces;
+ int i, j;
+
+ if ((!acl) || (!samba_acl))
+ return false;
+
+ samba_aces = samba_acl->aces;
+
+ if (samba_acl->num_aces > 0 && samba_aces) {
+ /* Setup ACES */
+ num_aces = samba_acl->num_aces;
+ aces = SMB_MALLOC_ARRAY(struct ifs_ace, num_aces);
+
+ for (i = 0, j = 0; j < num_aces; i++, j++) {
+ if (!onefs_sid_to_identity(&samba_aces[j].trustee,
+ &temp, false))
+ goto err_free;
+
+ /*
+ * XXX Act like we did pre-Thai: Silently fail setting
+ * ACEs for BUILTIN accounts.
+ */
+ if (temp.id.uid == -1) {
+ DEBUG(3, ("Silently failing to set ACE "
+ "because our id was == -1.\n"));
+ i--;
+ continue;
+ }
+
+ if (aclu_initialize_ace(&aces[i], samba_aces[i].type,
+ samba_aces[i].access_mask, samba_aces[i].flags,
+ 0, &temp))
+ goto err_free;
+
+ if ((aces[i].trustee.type == IFS_ID_TYPE_CREATOR_OWNER ||
+ aces[i].trustee.type == IFS_ID_TYPE_CREATOR_GROUP) &&
+ nt4_compatible_acls())
+ aces[i].flags |= IFS_ACE_FLAG_INHERIT_ONLY;
+ }
+ num_aces = i;
+ }
+
+ if (aclu_initialize_acl(acl, aces, num_aces))
+ goto err_free;
+
+ /* Currently aclu_initialize_acl should copy the aces over, allowing us
+ * to immediately free */
+ free(aces);
+ return true;
+
+err_free:
+ free(aces);
+ return false;
+}
+
+/**
+ * Convert a struct ifs_security_acl to a SEC_ACL
+ */
+static bool
+onefs_acl_to_samba_acl(struct ifs_security_acl *acl, SEC_ACL **samba_acl)
+{
+ SEC_ACE *samba_aces = NULL;
+ SEC_ACL *tmp_samba_acl = NULL;
+ int i, num_aces = 0;
+
+ if (!samba_acl)
+ return false;
+
+ /* NULL ACL */
+ if (!acl) {
+ *samba_acl = NULL;
+ return true;
+ }
+
+ /* Determine number of aces in ACL */
+ if (!acl->aces)
+ num_aces = 0;
+ else
+ num_aces = acl->num_aces;
+
+ /* Allocate the ace list. */
+ if (num_aces > 0) {
+ if ((samba_aces = SMB_MALLOC_ARRAY(SEC_ACE, num_aces)) == NULL)
+ {
+ DEBUG(0, ("Unable to malloc space for %d aces.\n",
+ num_aces));
+ return false;
+ }
+ memset(samba_aces, '\0', (num_aces) * sizeof(SEC_ACE));
+ }
+
+ for (i = 0; i < num_aces; i++) {
+ DOM_SID sid;
+
+ if (!onefs_identity_to_sid(&acl->aces[i].trustee, &sid))
+ goto err_free;
+
+ init_sec_ace(&samba_aces[i], &sid, acl->aces[i].type,
+ acl->aces[i].access_mask, acl->aces[i].flags);
+ }
+
+ if ((tmp_samba_acl = make_sec_acl(talloc_tos(), acl->revision, num_aces,
+ samba_aces)) == NULL) {
+ DEBUG(0, ("Unable to malloc space for acl.\n"));
+ goto err_free;
+ }
+
+ *samba_acl = tmp_samba_acl;
+ SAFE_FREE(samba_aces);
+ return true;
+err_free:
+ SAFE_FREE(samba_aces);
+ return false;
+}
+
+/**
+ * @brief Reorder ACLs into the "correct" order for Windows Explorer.
+ *
+ * Windows Explorer expects ACLs to be in a standard order (inherited first,
+ * then deny, then permit.) When ACLs are composed from POSIX file permissions
+ * bits, they may not match these expectations, generating an annoying warning
+ * dialog for the user. This function will, if configured appropriately,
+ * reorder the ACLs for these "synthetic" (POSIX-derived) descriptors to prevent
+ * this. The list is changed within the security descriptor passed in.
+ *
+ * @param fsp files_struct with service configs; must not be NULL
+ * @param sd security descriptor being normalized;
+ * sd->dacl->aces is rewritten in-place, so must not be NULL
+ * @return true on success, errno will be set on error
+ *
+ * @bug Although Windows Explorer likes the reordering, they seem to cause
+ * problems with Excel and Word sending back the reordered ACLs to us and
+ * changing policy; see Isilon bug 30165.
+ */
+static bool
+onefs_canon_acl(files_struct *fsp, struct ifs_security_descriptor *sd)
+{
+ int error = 0;
+ int cur;
+ struct ifs_ace *new_aces = NULL;
+ int new_aces_count = 0;
+ SMB_STRUCT_STAT sbuf;
+
+ if (sd == NULL || sd->dacl == NULL || sd->dacl->num_aces == 0)
+ return true;
+
+ /*
+ * Find out if this is a windows bit, and if the smb policy wants us to
+ * lie about the sd.
+ */
+ SMB_ASSERT(fsp != NULL);
+ switch (lp_parm_enum(SNUM(fsp->conn), PARM_ONEFS_TYPE,
+ PARM_ACL_WIRE_FORMAT, enum_onefs_acl_wire_format,
+ PARM_ACL_WIRE_FORMAT_DEFAULT)) {
+ case ACL_FORMAT_RAW:
+ return true;
+
+ case ACL_FORMAT_WINDOWS_SD:
+ error = SMB_VFS_FSTAT(fsp, &sbuf);
+ if (error)
+ return false;
+
+ if ((sbuf.st_flags & SF_HASNTFSACL) != 0) {
+ DEBUG(10, ("Did not canonicalize ACLs because a "
+ "Windows ACL set was found for file %s\n",
+ fsp->fsp_name));
+ return true;
+ }
+ break;
+
+ case ACL_FORMAT_ALWAYS:
+ break;
+
+ default:
+ SMB_ASSERT(false);
+ return false;
+ }
+
+ new_aces = SMB_MALLOC_ARRAY(struct ifs_ace, sd->dacl->num_aces);
+ if (new_aces == NULL)
+ return false;
+
+ /*
+ * By walking down the list 3 separate times, we can avoid the need
+ * to create multiple temp buffers and extra copies.
+ */
+ for (cur = 0; cur < sd->dacl->num_aces; cur++) {
+ if (sd->dacl->aces[cur].flags & IFS_ACE_FLAG_INHERITED_ACE)
+ new_aces[new_aces_count++] = sd->dacl->aces[cur];
+ }
+
+ for (cur = 0; cur < sd->dacl->num_aces; cur++) {
+ if (!(sd->dacl->aces[cur].flags & IFS_ACE_FLAG_INHERITED_ACE) &&
+ (sd->dacl->aces[cur].type == IFS_ACE_TYPE_ACCESS_DENIED))
+ new_aces[new_aces_count++] = sd->dacl->aces[cur];
+ }
+
+ for (cur = 0; cur < sd->dacl->num_aces; cur++) {
+ if (!(sd->dacl->aces[cur].flags & IFS_ACE_FLAG_INHERITED_ACE) &&
+ !(sd->dacl->aces[cur].type == IFS_ACE_TYPE_ACCESS_DENIED))
+ new_aces[new_aces_count++] = sd->dacl->aces[cur];
+ }
+
+ SMB_ASSERT(new_aces_count == sd->dacl->num_aces);
+ DEBUG(10, ("Performed canonicalization of ACLs for file %s\n",
+ fsp->fsp_name));
+
+ /*
+ * At this point you would think we could just do this:
+ * SAFE_FREE(sd->dacl->aces);
+ * sd->dacl->aces = new_aces;
+ * However, in some cases the existing aces pointer does not point
+ * to the beginning of an allocated block. So we have to do a more
+ * expensive memcpy()
+ */
+ memcpy(sd->dacl->aces, new_aces,
+ sizeof(struct ifs_ace) * new_aces_count);
+
+ SAFE_FREE(new_aces);
+ return true;
+}
+
+
+/**
+ * This enum is a helper for onefs_fget_nt_acl() to communicate with
+ * onefs_init_ace().
+ */
+enum mode_ident { USR, GRP, OTH };
+
+/**
+ * Initializes an ACE for addition to a synthetic ACL.
+ */
+static struct ifs_ace onefs_init_ace(struct connection_struct *conn,
+ mode_t mode,
+ bool isdir,
+ enum mode_ident ident)
+{
+ struct ifs_ace result;
+ enum ifs_ace_rights r,w,x;
+
+ r = isdir ? UNIX_DIRECTORY_ACCESS_R : UNIX_ACCESS_R;
+ w = isdir ? UNIX_DIRECTORY_ACCESS_W : UNIX_ACCESS_W;
+ x = isdir ? UNIX_DIRECTORY_ACCESS_X : UNIX_ACCESS_X;
+
+ result.type = IFS_ACE_TYPE_ACCESS_ALLOWED;
+ result.ifs_flags = 0;
+ result.flags = isdir ? IFS_ACE_FLAG_CONTAINER_INHERIT :
+ IFS_ACE_FLAG_OBJECT_INHERIT;
+ result.flags |= IFS_ACE_FLAG_INHERIT_ONLY;
+
+ switch (ident) {
+ case USR:
+ result.access_mask =
+ ((mode & S_IRUSR) ? r : 0 ) |
+ ((mode & S_IWUSR) ? w : 0 ) |
+ ((mode & S_IXUSR) ? x : 0 );
+ if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
+ PARM_CREATOR_OWNER_GETS_FULL_CONTROL,
+ PARM_CREATOR_OWNER_GETS_FULL_CONTROL_DEFAULT))
+ result.access_mask |= GENERIC_ALL_ACCESS;
+ result.trustee.type = IFS_ID_TYPE_CREATOR_OWNER;
+ break;
+ case GRP:
+ result.access_mask =
+ ((mode & S_IRGRP) ? r : 0 ) |
+ ((mode & S_IWGRP) ? w : 0 ) |
+ ((mode & S_IXGRP) ? x : 0 );
+ result.trustee.type = IFS_ID_TYPE_CREATOR_GROUP;
+ break;
+ case OTH:
+ result.access_mask =
+ ((mode & S_IROTH) ? r : 0 ) |
+ ((mode & S_IWOTH) ? w : 0 ) |
+ ((mode & S_IXOTH) ? x : 0 );
+ result.trustee.type = IFS_ID_TYPE_EVERYONE;
+ break;
+ }
+
+ return result;
+}
+
+/**
+ * This adds inheritable ACEs to the end of the DACL, with the ACEs
+ * being derived from the mode bits. This is useful for clients that have the
+ * MoveSecurityAttributes regkey set to 0 or are in Simple File Sharing Mode.
+ *
+ * On these clients, when copying files from one folder to another inside the
+ * same volume/share, the DACL is explicitely cleared. Without inheritable
+ * aces on the target folder the mode bits of the copied file are set to 000.
+ *
+ * See Isilon Bug 27990
+ *
+ * Note: This function allocates additional memory onto sd->dacl->aces, that
+ * must be freed by the caller.
+ */
+static bool add_sfs_aces(files_struct *fsp, struct ifs_security_descriptor *sd)
+{
+ int error;
+ SMB_STRUCT_STAT sbuf;
+
+ error = SMB_VFS_FSTAT(fsp, &sbuf);
+ if (error) {
+ DEBUG(0, ("Failed to stat %s in simple files sharing "
+ "compatibility mode. errno=%d\n",
+ fsp->fsp_name, errno));
+ return false;
+ }
+
+ /* Only continue if this is a synthetic ACL and a directory. */
+ if (S_ISDIR(sbuf.st_mode) && (sbuf.st_flags & SF_HASNTFSACL) == 0) {
+ 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;
+
+ /* Use existing samba logic to derive the mode bits. */
+ file_mode = unix_mode(fsp->conn, 0, fsp->fsp_name, false);
+ dir_mode = unix_mode(fsp->conn, aDIR, fsp->fsp_name, false);
+
+ /* Initialize ACEs. */
+ new_aces[0] = onefs_init_ace(fsp->conn, file_mode, false, USR);
+ new_aces[1] = onefs_init_ace(fsp->conn, file_mode, false, GRP);
+ new_aces[2] = onefs_init_ace(fsp->conn, file_mode, false, OTH);
+ new_aces[3] = onefs_init_ace(fsp->conn, dir_mode, true, USR);
+ new_aces[4] = onefs_init_ace(fsp->conn, dir_mode, true, GRP);
+ new_aces[5] = onefs_init_ace(fsp->conn, dir_mode, true, OTH);
+
+ for (i = 0; i < 6; i++)
+ if (new_aces[i].access_mask != 0)
+ num_aces_to_add++;
+
+ /* Expand the ACEs array */
+ if (num_aces_to_add != 0) {
+ old_aces = sd->dacl->aces;
+
+ sd->dacl->aces = SMB_MALLOC_ARRAY(struct ifs_ace,
+ sd->dacl->num_aces + num_aces_to_add);
+ if (!sd->dacl->aces) {
+ DEBUG(0, ("Unable to malloc space for "
+ "new_aces: %d.\n",
+ sd->dacl->num_aces + num_aces_to_add));
+ return false;
+ }
+ memcpy(sd->dacl->aces, old_aces,
+ sizeof(struct ifs_ace) * sd->dacl->num_aces);
+
+ /* Add the new ACEs to the DACL. */
+ for (i = 0; i < 6; i++) {
+ if (new_aces[i].access_mask != 0) {
+ sd->dacl->aces[sd->dacl->num_aces] =
+ new_aces[i];
+ sd->dacl->num_aces++;
+ }
+ }
+ }
+ }
+ return true;
+}
+
+/**
+ * Isilon-specific function for getting an NTFS ACL from an open file.
+ *
+ * @param[out] ppdesc SecDesc to allocate and fill in
+ *
+ * @return NTSTATUS based off errno on error
+ */
+NTSTATUS
+onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
+ uint32 security_info, SEC_DESC **ppdesc)
+{
+ int error;
+ uint32_t sd_size = 0;
+ size_t size = 0;
+ struct ifs_security_descriptor *sd = NULL;
+ DOM_SID owner_sid, group_sid;
+ DOM_SID *ownerp, *groupp;
+ SEC_ACL *dacl, *sacl;
+ SEC_DESC *pdesc;
+ bool alloced = false;
+ bool new_aces_alloced = false;
+ bool fopened = false;
+ NTSTATUS status = NT_STATUS_OK;
+
+ *ppdesc = NULL;
+
+ DEBUG(5, ("Getting sd for file %s. security_info=%u\n",
+ fsp->fsp_name, security_info));
+
+ if (fsp->fh->fd == -1) {
+ enum ifs_ace_rights desired_access = 0;
+
+ if (security_info & (OWNER_SECURITY_INFORMATION |
+ GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION))
+ desired_access |= IFS_RTS_STD_READ_CONTROL;
+ if (security_info & SACL_SECURITY_INFORMATION)
+ desired_access |= IFS_RTS_SACL_ACCESS;
+
+ if ((fsp->fh->fd = ifs_createfile(-1,
+ fsp->fsp_name,
+ desired_access,
+ 0, 0,
+ OPLOCK_NONE,
+ 0, NULL, 0,
+ NULL, 0, NULL)) == -1) {
+ DEBUG(0, ("Error opening file %s. errno=%d\n",
+ fsp->fsp_name, errno));
+ status = map_nt_error_from_unix(errno);
+ goto out;
+ }
+ fopened = true;
+ }
+
+ /* Get security descriptor */
+ sd_size = 0;
+ do {
+ /* Allocate memory for get_security_descriptor */
+ if (sd_size > 0) {
+ sd = SMB_REALLOC(sd, sd_size);
+ if (!sd) {
+ DEBUG(0, ("Unable to malloc %u bytes of space "
+ "for security descriptor.\n", sd_size));
+ status = map_nt_error_from_unix(errno);
+ goto out;
+ }
+
+ alloced = true;
+ }
+
+ error = ifs_get_security_descriptor(fsp->fh->fd, security_info,
+ &sd_size, sd);
+ if (error && (errno != EMSGSIZE)) {
+ DEBUG(0, ("Failed getting size of security descriptor! "
+ "errno=%d\n", errno));
+ status = map_nt_error_from_unix(errno);
+ goto out;
+ }
+ } while (error);
+
+ DEBUG(5, ("Got sd, size=%u:\n", sd_size));
+
+ if (lp_parm_bool(SNUM(fsp->conn),
+ PARM_ONEFS_TYPE,
+ PARM_SIMPLE_FILE_SHARING_COMPATIBILITY_MODE,
+ PARM_SIMPLE_FILE_SHARING_COMPATIBILITY_MODE_DEFAULT) &&
+ sd->dacl) {
+ if(!(new_aces_alloced = add_sfs_aces(fsp, sd)))
+ goto out;
+ }
+
+ if (!(onefs_canon_acl(fsp, sd))) {
+ status = map_nt_error_from_unix(errno);
+ goto out;
+ }
+
+ DEBUG(5, ("Finished canonicalizing ACL\n"));
+
+ ownerp = NULL;
+ groupp = NULL;
+ dacl = NULL;
+ sacl = NULL;
+
+ /* Copy owner into ppdesc */
+ if (security_info & OWNER_SECURITY_INFORMATION) {
+ if (!onefs_identity_to_sid(sd->owner, &owner_sid)) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto out;
+ }
+
+ ownerp = &owner_sid;
+ }
+
+ /* Copy group into ppdesc */
+ if (security_info & GROUP_SECURITY_INFORMATION) {
+ if (!onefs_identity_to_sid(sd->group, &group_sid)) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto out;
+ }
+
+ groupp = &group_sid;
+ }
+
+ /* Copy DACL into ppdesc */
+ if (security_info & DACL_SECURITY_INFORMATION) {
+ if (!onefs_acl_to_samba_acl(sd->dacl, &dacl)) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto out;
+ }
+ }
+
+ /* Copy SACL into ppdesc */
+ if (security_info & SACL_SECURITY_INFORMATION) {
+ if (!onefs_acl_to_samba_acl(sd->sacl, &sacl)) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto out;
+ }
+ }
+
+ /* AUTO_INHERIT_REQ bits are not returned over the wire so strip them
+ * off. Eventually we should stop storing these in the kernel
+ * all together. See Isilon bug 40364 */
+ sd->control &= ~(IFS_SD_CTRL_DACL_AUTO_INHERIT_REQ |
+ IFS_SD_CTRL_SACL_AUTO_INHERIT_REQ);
+
+ pdesc = make_sec_desc(talloc_tos(), sd->revision, sd->control,
+ ownerp, groupp, sacl, dacl, &size);
+
+ if (!pdesc) {
+ DEBUG(0, ("Problem with make_sec_desc. Memory?\n"));
+ status = map_nt_error_from_unix(errno);
+ goto out;
+ }
+
+ *ppdesc = pdesc;
+
+ DEBUG(5, ("Finished retrieving/canonicalizing SD!\n"));
+ /* FALLTHROUGH */
+out:
+ if (alloced && sd) {
+ if (new_aces_alloced && sd->dacl->aces)
+ SAFE_FREE(sd->dacl->aces);
+
+ SAFE_FREE(sd);
+ }
+
+ if (fopened) {
+ close(fsp->fh->fd);
+ fsp->fh->fd = -1;
+ }
+
+ return status;
+}
+
+/**
+ * Isilon-specific function for getting an NTFS ACL from a file path.
+ *
+ * Since onefs_fget_nt_acl() needs to open a filepath if the fd is invalid,
+ * we just mock up a files_struct with the path and bad fd and call into it.
+ *
+ * @param[out] ppdesc SecDesc to allocate and fill in
+ *
+ * @return NTSTATUS based off errno on error
+ */
+NTSTATUS
+onefs_get_nt_acl(vfs_handle_struct *handle, const char* name,
+ uint32 security_info, SEC_DESC **ppdesc)
+{
+ files_struct finfo;
+ struct fd_handle fh;
+
+ ZERO_STRUCT(finfo);
+ ZERO_STRUCT(fh);
+
+ finfo.fnum = -1;
+ finfo.conn = handle->conn;
+ finfo.fh = &fh;
+ finfo.fh->fd = -1;
+ finfo.fsp_name = CONST_DISCARD(char *, name);
+
+ return onefs_fget_nt_acl(handle, &finfo, security_info, ppdesc);
+}
+
+/**
+ * Isilon-specific function for setting an NTFS ACL on an open file.
+ *
+ * @return NT_STATUS_UNSUCCESSFUL for userspace errors, NTSTATUS based off
+ * errno on syscall errors
+ */
+NTSTATUS
+onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
+ uint32 security_info_sent, SEC_DESC *psd)
+{
+ struct ifs_security_descriptor sd = {};
+ struct ifs_security_acl dacl, sacl, *daclp, *saclp;
+ struct ifs_identity owner, group, *ownerp, *groupp;
+ int fd;
+ bool fopened = false;
+
+ DEBUG(5,("Setting SD on file %s.\n", fsp->fsp_name ));
+
+ ownerp = NULL;
+ groupp = NULL;
+ daclp = NULL;
+ saclp = NULL;
+
+ /* Setup owner */
+ if (security_info_sent & OWNER_SECURITY_INFORMATION) {
+ if (!onefs_sid_to_identity(psd->owner_sid, &owner, false))
+ return NT_STATUS_UNSUCCESSFUL;
+
+ /*
+ * XXX Act like we did pre-Thai: Silently fail setting the
+ * owner to a BUILTIN account.
+ */
+ if (owner.id.uid == -1) {
+ DEBUG(3, ("Silently failing to set owner because our "
+ "id was == -1.\n"));
+ security_info_sent &= ~OWNER_SECURITY_INFORMATION;
+ if (!security_info_sent)
+ return NT_STATUS_OK;
+ }
+ else
+ ownerp = &owner;
+ }
+
+ /* Setup group */
+ if (security_info_sent & GROUP_SECURITY_INFORMATION) {
+ if (!onefs_sid_to_identity(psd->group_sid, &group, true))
+ return NT_STATUS_UNSUCCESSFUL;
+
+ /*
+ * XXX Act like we did pre-Thai: Silently fail setting the
+ * group to a BUILTIN account.
+ */
+ if (group.id.gid == -1) {
+ DEBUG(3, ("Silently failing to set group because our "
+ "id was == -1.\n"));
+ security_info_sent &= ~GROUP_SECURITY_INFORMATION;
+ if (!security_info_sent)
+ return NT_STATUS_OK;
+ }
+ else
+ groupp = &group;
+ }
+
+ /* Setup DACL */
+ if ((security_info_sent & DACL_SECURITY_INFORMATION) && (psd->dacl)) {
+ daclp = &dacl;
+
+ if (!onefs_samba_acl_to_acl(psd->dacl, &daclp))
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* Setup SACL */
+ if ((security_info_sent & SACL_SECURITY_INFORMATION) && (psd->sacl)) {
+ saclp = &sacl;
+
+ if (!onefs_samba_acl_to_acl(psd->sacl, &saclp))
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* Setup ifs_security_descriptor */
+ DEBUG(5,("Setting up SD\n"));
+ if (aclu_initialize_sd(&sd, psd->type, ownerp, groupp,
+ (daclp ? &daclp : NULL), (saclp ? &saclp : NULL), false))
+ return NT_STATUS_UNSUCCESSFUL;
+
+ fd = fsp->fh->fd;
+ if (fd == -1) {
+ enum ifs_ace_rights desired_access = 0;
+
+ if (security_info_sent &
+ (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION))
+ desired_access |= IFS_RTS_STD_WRITE_OWNER;
+ if (security_info_sent & DACL_SECURITY_INFORMATION)
+ desired_access |= IFS_RTS_STD_WRITE_DAC;
+ if (security_info_sent & SACL_SECURITY_INFORMATION)
+ desired_access |= IFS_RTS_SACL_ACCESS;
+
+ if ((fd = ifs_createfile(-1,
+ fsp->fsp_name,
+ desired_access,
+ 0, 0,
+ OPLOCK_NONE,
+ 0, NULL, 0,
+ NULL, 0, NULL)) == -1) {
+ DEBUG(0, ("Error opening file %s. errno=%d\n",
+ fsp->fsp_name, errno));
+ return map_nt_error_from_unix(errno);
+ }
+ fopened = true;
+ }
+
+ errno = 0;
+ if (ifs_set_security_descriptor(fd, security_info_sent, &sd)) {
+ DEBUG(0, ("Error setting security descriptor = %d\n", errno));
+ goto out;
+ }
+
+ DEBUG(5, ("Security descriptor set correctly!\n"));
+
+ /* FALLTHROUGH */
+out:
+ if (fopened)
+ close(fd);
+
+ aclu_free_sd(&sd, false);
+ return errno ? map_nt_error_from_unix(errno) : NT_STATUS_OK;
+}
diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c
new file mode 100644
index 0000000000..915f73233d
--- /dev/null
+++ b/source3/modules/vfs_acl_tdb.c
@@ -0,0 +1,891 @@
+/*
+ * Store Windows ACLs in a tdb.
+ *
+ * Copyright (C) Volker Lendecke, 2008
+ * Copyright (C) Jeremy Allison, 2008
+ *
+ * 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/>.
+ */
+
+/* NOTE: This is an experimental module, not yet finished. JRA. */
+
+#include "includes.h"
+#include "librpc/gen_ndr/xattr.h"
+#include "librpc/gen_ndr/ndr_xattr.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_VFS
+
+static unsigned int ref_count;
+static struct db_context *acl_db;
+
+/*******************************************************************
+ Open acl_db if not already open, increment ref count.
+*******************************************************************/
+
+static bool acl_tdb_init(struct db_context **pp_db)
+{
+ const char *dbname;
+
+ if (acl_db) {
+ *pp_db = acl_db;
+ ref_count++;
+ return true;
+ }
+
+ dbname = lock_path("file_ntacls.tdb");
+
+ if (dbname == NULL) {
+ errno = ENOSYS;
+ return false;
+ }
+
+ become_root();
+ *pp_db = db_open(NULL, dbname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+ unbecome_root();
+
+ if (*pp_db == NULL) {
+#if defined(ENOTSUP)
+ errno = ENOTSUP;
+#else
+ errno = ENOSYS;
+#endif
+ return false;
+ }
+
+ ref_count++;
+ return true;
+}
+
+/*******************************************************************
+ Lower ref count and close acl_db if zero.
+*******************************************************************/
+
+static void free_acl_tdb_data(void **pptr)
+{
+ struct db_context **pp_db = (struct db_context **)pptr;
+
+ ref_count--;
+ if (ref_count == 0) {
+ TALLOC_FREE(*pp_db);
+ acl_db = NULL;
+ }
+}
+
+/*******************************************************************
+ Fetch_lock the tdb acl record for a file
+*******************************************************************/
+
+static struct db_record *acl_tdb_lock(TALLOC_CTX *mem_ctx,
+ struct db_context *db,
+ const struct file_id *id)
+{
+ uint8 id_buf[16];
+ push_file_id_16((char *)id_buf, id);
+ return db->fetch_locked(db,
+ mem_ctx,
+ make_tdb_data(id_buf,
+ sizeof(id_buf)));
+}
+
+/*******************************************************************
+ Delete the tdb acl record for a file
+*******************************************************************/
+
+static NTSTATUS acl_tdb_delete(vfs_handle_struct *handle,
+ struct db_context *db,
+ SMB_STRUCT_STAT *psbuf)
+{
+ NTSTATUS status;
+ struct file_id id = vfs_file_id_from_sbuf(handle->conn, psbuf);
+ struct db_record *rec = acl_tdb_lock(talloc_tos(), db, &id);
+
+ /*
+ * If rec == NULL there's not much we can do about it
+ */
+
+ if (rec == NULL) {
+ DEBUG(10,("acl_tdb_delete: rec == NULL\n"));
+ TALLOC_FREE(rec);
+ return NT_STATUS_OK;
+ }
+
+ status = rec->delete_rec(rec);
+ TALLOC_FREE(rec);
+ return status;
+}
+
+/*******************************************************************
+ 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)
+{
+ TALLOC_CTX *ctx = talloc_tos();
+ struct xattr_NTACL xacl;
+ enum ndr_err_code ndr_err;
+ size_t sd_size;
+
+ ndr_err = ndr_pull_struct_blob(pblob, ctx, NULL, &xacl,
+ (ndr_pull_flags_fn_t)ndr_pull_xattr_NTACL);
+
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(5, ("parse_acl_blob: ndr_pull_xattr_NTACL failed: %s\n",
+ ndr_errstr(ndr_err)));
+ return ndr_map_error2ntstatus(ndr_err);;
+ }
+
+ if (xacl.version != 2) {
+ return NT_STATUS_REVISION_MISMATCH;
+ }
+
+ *ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION, xacl.info.sd_hs->sd->type | SEC_DESC_SELF_RELATIVE,
+ (security_info & OWNER_SECURITY_INFORMATION)
+ ? xacl.info.sd_hs->sd->owner_sid : NULL,
+ (security_info & GROUP_SECURITY_INFORMATION)
+ ? xacl.info.sd_hs->sd->group_sid : NULL,
+ (security_info & SACL_SECURITY_INFORMATION)
+ ? xacl.info.sd_hs->sd->sacl : NULL,
+ (security_info & DACL_SECURITY_INFORMATION)
+ ? xacl.info.sd_hs->sd->dacl : NULL,
+ &sd_size);
+
+ TALLOC_FREE(xacl.info.sd);
+
+ return (*ppdesc != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
+}
+
+/*******************************************************************
+ Pull a security descriptor into a DATA_BLOB from a tdb store.
+*******************************************************************/
+
+static NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
+ vfs_handle_struct *handle,
+ files_struct *fsp,
+ const char *name,
+ DATA_BLOB *pblob)
+{
+ uint8 id_buf[16];
+ TDB_DATA data;
+ struct file_id id;
+ struct db_context *db;
+ SMB_STRUCT_STAT sbuf;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
+ return NT_STATUS_INTERNAL_DB_CORRUPTION);
+
+ if (fsp && fsp->fh->fd != -1) {
+ if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
+ return map_nt_error_from_unix(errno);
+ }
+ } else {
+ if (SMB_VFS_STAT(handle->conn, name, &sbuf) == -1) {
+ return map_nt_error_from_unix(errno);
+ }
+ }
+ id = vfs_file_id_from_sbuf(handle->conn, &sbuf);
+
+ push_file_id_16((char *)id_buf, &id);
+
+ if (db->fetch(db,
+ ctx,
+ make_tdb_data(id_buf, sizeof(id_buf)),
+ &data) == -1) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ pblob->data = data.dptr;
+ pblob->length = data.dsize;
+
+ DEBUG(10,("get_acl_blob: returned %u bytes from file %s\n",
+ (unsigned int)data.dsize, name ));
+
+ if (pblob->length == 0 || pblob->data == NULL) {
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
+ Create a DATA_BLOB from a security descriptor.
+*******************************************************************/
+
+static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB *pblob)
+{
+ struct xattr_NTACL xacl;
+ struct security_descriptor_hash sd_hs;
+ enum ndr_err_code ndr_err;
+ TALLOC_CTX *ctx = talloc_tos();
+
+ ZERO_STRUCT(xacl);
+ ZERO_STRUCT(sd_hs);
+
+ 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);
+
+ ndr_err = ndr_push_struct_blob(
+ pblob, ctx, NULL, &xacl,
+ (ndr_push_flags_fn_t)ndr_push_xattr_NTACL);
+
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(5, ("create_acl_blob: ndr_push_xattr_NTACL failed: %s\n",
+ ndr_errstr(ndr_err)));
+ return ndr_map_error2ntstatus(ndr_err);;
+ }
+
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
+ Store a DATA_BLOB into a tdb record given an fsp pointer.
+*******************************************************************/
+
+static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
+ files_struct *fsp,
+ DATA_BLOB *pblob)
+{
+ uint8 id_buf[16];
+ struct file_id id;
+ SMB_STRUCT_STAT sbuf;
+ TDB_DATA data;
+ struct db_context *db;
+ struct db_record *rec;
+
+ DEBUG(10,("store_acl_blob_fsp: storing blob length %u on file %s\n",
+ (unsigned int)pblob->length, fsp->fsp_name));
+
+ SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
+ return NT_STATUS_INTERNAL_DB_CORRUPTION);
+
+ if (fsp->fh->fd != -1) {
+ if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
+ return map_nt_error_from_unix(errno);
+ }
+ } else {
+ if (SMB_VFS_STAT(handle->conn, fsp->fsp_name, &sbuf) == -1) {
+ return map_nt_error_from_unix(errno);
+ }
+ }
+ id = vfs_file_id_from_sbuf(handle->conn, &sbuf);
+
+ push_file_id_16((char *)id_buf, &id);
+ rec = db->fetch_locked(db, talloc_tos(),
+ make_tdb_data(id_buf,
+ sizeof(id_buf)));
+ if (rec == NULL) {
+ DEBUG(0, ("store_acl_blob_fsp_tdb: fetch_lock failed\n"));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+ data.dptr = pblob->data;
+ data.dsize = pblob->length;
+ return rec->store(rec, data, 0);
+}
+
+/*******************************************************************
+ Store a DATA_BLOB into a tdb record given a pathname.
+*******************************************************************/
+
+static NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle,
+ const char *fname,
+ DATA_BLOB *pblob)
+{
+ uint8 id_buf[16];
+ struct file_id id;
+ TDB_DATA data;
+ SMB_STRUCT_STAT sbuf;
+ struct db_context *db;
+ struct db_record *rec;
+
+ DEBUG(10,("store_acl_blob_pathname: storing blob "
+ "length %u on file %s\n",
+ (unsigned int)pblob->length, fname));
+
+ SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
+ return NT_STATUS_INTERNAL_DB_CORRUPTION);
+
+ if (SMB_VFS_STAT(handle->conn, fname, &sbuf) == -1) {
+ return map_nt_error_from_unix(errno);
+ }
+
+ id = vfs_file_id_from_sbuf(handle->conn, &sbuf);
+ push_file_id_16((char *)id_buf, &id);
+
+ rec = db->fetch_locked(db, talloc_tos(),
+ make_tdb_data(id_buf,
+ sizeof(id_buf)));
+ if (rec == NULL) {
+ DEBUG(0, ("store_acl_blob_pathname_tdb: fetch_lock failed\n"));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+ data.dptr = pblob->data;
+ data.dsize = pblob->length;
+ return rec->store(rec, data, 0);
+}
+
+/*******************************************************************
+ Store a DATA_BLOB into an tdb given a pathname.
+*******************************************************************/
+
+static NTSTATUS get_nt_acl_tdb_internal(vfs_handle_struct *handle,
+ files_struct *fsp,
+ const char *name,
+ uint32 security_info,
+ struct security_descriptor **ppdesc)
+{
+ TALLOC_CTX *ctx = talloc_tos();
+ DATA_BLOB blob;
+ NTSTATUS status;
+
+ if (fsp && name == NULL) {
+ name = fsp->fsp_name;
+ }
+
+ DEBUG(10, ("get_nt_acl_tdb_internal: name=%s\n", name));
+
+ status = get_acl_blob(ctx, 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);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("parse_acl_blob returned %s\n",
+ nt_errstr(status)));
+ return status;
+ }
+
+ TALLOC_FREE(blob.data);
+ return status;
+}
+
+/*********************************************************************
+ Create a default security descriptor for a file in case no inheritance
+ exists. All permissions to the owner and SYSTEM.
+*********************************************************************/
+
+static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx,
+ SMB_STRUCT_STAT *psbuf)
+{
+ struct dom_sid owner_sid, group_sid;
+ size_t sd_size;
+ struct security_ace *pace = NULL;
+ struct security_acl *pacl = NULL;
+
+ uid_to_sid(&owner_sid, psbuf->st_uid);
+ gid_to_sid(&group_sid, psbuf->st_gid);
+
+ pace = TALLOC_ARRAY(mem_ctx, struct security_ace, 2);
+ if (!pace) {
+ return NULL;
+ }
+
+ init_sec_ace(&pace[0], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
+ SEC_RIGHTS_FILE_ALL, 0);
+ init_sec_ace(&pace[1], &global_sid_System, SEC_ACE_TYPE_ACCESS_ALLOWED,
+ SEC_RIGHTS_FILE_ALL, 0);
+
+ pacl = make_sec_acl(mem_ctx,
+ NT4_ACL_REVISION,
+ 2,
+ pace);
+ if (!pacl) {
+ return NULL;
+ }
+ return make_sec_desc(mem_ctx,
+ SECURITY_DESCRIPTOR_REVISION_1,
+ SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT,
+ &owner_sid,
+ &group_sid,
+ NULL,
+ pacl,
+ &sd_size);
+}
+
+/*********************************************************************
+*********************************************************************/
+
+static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
+ const char *fname,
+ files_struct *fsp,
+ bool container)
+{
+ TALLOC_CTX *ctx = talloc_tos();
+ NTSTATUS status;
+ struct security_descriptor *parent_desc = NULL;
+ struct security_descriptor *psd = NULL;
+ DATA_BLOB blob;
+ size_t size;
+ char *parent_name;
+
+ if (!parent_dirname_talloc(ctx,
+ fname,
+ &parent_name,
+ NULL)) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ DEBUG(10,("inherit_new_acl: check directory %s\n",
+ parent_name));
+
+ status = get_nt_acl_tdb_internal(handle,
+ NULL,
+ parent_name,
+ (OWNER_SECURITY_INFORMATION |
+ GROUP_SECURITY_INFORMATION |
+ DACL_SECURITY_INFORMATION),
+ &parent_desc);
+ if (NT_STATUS_IS_OK(status)) {
+ /* Create an inherited descriptor from the parent. */
+
+ if (DEBUGLEVEL >= 10) {
+ DEBUG(10,("inherit_new_acl: parent acl is:\n"));
+ NDR_PRINT_DEBUG(security_descriptor, parent_desc);
+ }
+
+ status = se_create_child_secdesc(ctx,
+ &psd,
+ &size,
+ parent_desc,
+ &handle->conn->server_info->ptok->user_sids[PRIMARY_USER_SID_INDEX],
+ &handle->conn->server_info->ptok->user_sids[PRIMARY_GROUP_SID_INDEX],
+ container);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (DEBUGLEVEL >= 10) {
+ DEBUG(10,("inherit_new_acl: child acl is:\n"));
+ NDR_PRINT_DEBUG(security_descriptor, psd);
+ }
+
+ } else {
+ DEBUG(10,("inherit_new_acl: directory %s failed "
+ "to get acl %s\n",
+ parent_name,
+ nt_errstr(status) ));
+ }
+
+ 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);
+ } else {
+ ret = SMB_VFS_STAT(handle->conn,fname, &sbuf);
+ }
+ if (ret == -1) {
+ return map_nt_error_from_unix(errno);
+ }
+ psd = default_file_sd(ctx, &sbuf);
+ if (!psd) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (DEBUGLEVEL >= 10) {
+ DEBUG(10,("inherit_new_acl: default acl is:\n"));
+ NDR_PRINT_DEBUG(security_descriptor, psd);
+ }
+ }
+
+ status = create_acl_blob(psd, &blob);
+ 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);
+ }
+}
+
+/*********************************************************************
+ Check ACL on open. For new files inherit from parent directory.
+*********************************************************************/
+
+static int open_acl_tdb(vfs_handle_struct *handle,
+ const char *fname,
+ files_struct *fsp,
+ int flags,
+ mode_t mode)
+{
+ uint32_t access_granted = 0;
+ struct security_descriptor *pdesc = NULL;
+ bool file_existed = true;
+ NTSTATUS status = get_nt_acl_tdb_internal(handle,
+ NULL,
+ fname,
+ (OWNER_SECURITY_INFORMATION |
+ GROUP_SECURITY_INFORMATION |
+ DACL_SECURITY_INFORMATION),
+ &pdesc);
+ if (NT_STATUS_IS_OK(status)) {
+ /* See if we can access it. */
+ status = smb1_file_se_access_check(pdesc,
+ handle->conn->server_info->ptok,
+ fsp->access_mask,
+ &access_granted);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10,("open_acl_tdb: file %s open "
+ "refused with error %s\n",
+ fname,
+ nt_errstr(status) ));
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
+ } else if (NT_STATUS_EQUAL(status,NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+ file_existed = false;
+ }
+
+ DEBUG(10,("open_acl_tdb: get_nt_acl_attr_internal for "
+ "file %s returned %s\n",
+ fname,
+ nt_errstr(status) ));
+
+ fsp->fh->fd = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
+
+ 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);
+ }
+
+ return fsp->fh->fd;
+}
+
+/*********************************************************************
+ On unlink we need to delete the tdb record (if using tdb).
+*********************************************************************/
+
+static int unlink_acl_tdb(vfs_handle_struct *handle, const char *path)
+{
+ SMB_STRUCT_STAT sbuf;
+ struct db_context *db;
+ int ret;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
+
+ if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) {
+ return -1;
+ }
+
+ ret = SMB_VFS_NEXT_UNLINK(handle, path);
+
+ if (ret == -1) {
+ return -1;
+ }
+
+ acl_tdb_delete(handle, db, &sbuf);
+ return 0;
+}
+
+/*********************************************************************
+ Store an inherited SD on mkdir.
+*********************************************************************/
+
+static int mkdir_acl_tdb(vfs_handle_struct *handle, const char *path, mode_t mode)
+{
+ int ret = SMB_VFS_NEXT_MKDIR(handle, path, mode);
+
+ if (ret == -1) {
+ return ret;
+ }
+ /* New directory - inherit from parent. */
+ inherit_new_acl(handle, path, NULL, true);
+ return ret;
+}
+
+/*********************************************************************
+ On rmdir we need to delete the tdb record (if using tdb).
+*********************************************************************/
+
+static int rmdir_acl_tdb(vfs_handle_struct *handle, const char *path)
+{
+
+ SMB_STRUCT_STAT sbuf;
+ struct db_context *db;
+ int ret;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
+
+ if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) {
+ return -1;
+ }
+
+ ret = SMB_VFS_NEXT_RMDIR(handle, path);
+ if (ret == -1) {
+ return -1;
+ }
+
+ acl_tdb_delete(handle, db, &sbuf);
+ return 0;
+}
+
+/*********************************************************************
+ Fetch a security descriptor given an fsp.
+*********************************************************************/
+
+static NTSTATUS fget_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp,
+ uint32 security_info, struct security_descriptor **ppdesc)
+{
+ NTSTATUS status = get_nt_acl_tdb_internal(handle, fsp,
+ NULL, security_info, ppdesc);
+ 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));
+ 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) ));
+
+ return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp,
+ security_info, ppdesc);
+}
+
+/*********************************************************************
+ Fetch a security descriptor given a pathname.
+*********************************************************************/
+
+static NTSTATUS get_nt_acl_tdb(vfs_handle_struct *handle,
+ const char *name, uint32 security_info, struct security_descriptor **ppdesc)
+{
+ NTSTATUS status = get_nt_acl_tdb_internal(handle, NULL,
+ name, security_info, ppdesc);
+ if (NT_STATUS_IS_OK(status)) {
+ if (DEBUGLEVEL >= 10) {
+ DEBUG(10,("get_nt_acl_tdb: returning tdb sd for file %s\n",
+ name));
+ NDR_PRINT_DEBUG(security_descriptor, *ppdesc);
+ }
+ return NT_STATUS_OK;
+ }
+
+ DEBUG(10,("get_nt_acl_tdb: failed to get tdb sd for file %s, Error %s\n",
+ name,
+ nt_errstr(status) ));
+
+ return SMB_VFS_NEXT_GET_NT_ACL(handle, name,
+ security_info, ppdesc);
+}
+
+/*********************************************************************
+ Store a security descriptor given an fsp.
+*********************************************************************/
+
+static NTSTATUS fset_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp,
+ uint32 security_info_sent, const struct security_descriptor *psd)
+{
+ NTSTATUS status;
+ DATA_BLOB blob;
+
+ if (DEBUGLEVEL >= 10) {
+ DEBUG(10,("fset_nt_acl_tdb: incoming sd for file %s\n",
+ fsp->fsp_name));
+ 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);
+
+ if (!nc_psd) {
+ return NT_STATUS_OK;
+ }
+ if (fsp->is_directory || fsp->fh->fd == -1) {
+ ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf);
+ } else {
+ ret = SMB_VFS_FSTAT(fsp, &sbuf);
+ }
+ if (ret == -1) {
+ /* Lower level acl set succeeded,
+ * so still return OK. */
+ return NT_STATUS_OK;
+ }
+ create_file_sids(&sbuf, &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;
+ security_info_sent |= (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION);
+ psd = nc_psd;
+ }
+
+ if ((security_info_sent & DACL_SECURITY_INFORMATION) &&
+ psd->dacl != NULL &&
+ (psd->type & (SE_DESC_DACL_AUTO_INHERITED|
+ SE_DESC_DACL_AUTO_INHERIT_REQ))==
+ (SE_DESC_DACL_AUTO_INHERITED|
+ SE_DESC_DACL_AUTO_INHERIT_REQ) ) {
+ struct security_descriptor *new_psd = NULL;
+ status = append_parent_acl(fsp, psd, &new_psd);
+ if (!NT_STATUS_IS_OK(status)) {
+ /* Lower level acl set succeeded,
+ * so still return OK. */
+ return NT_STATUS_OK;
+ }
+ psd = new_psd;
+ }
+
+ if (DEBUGLEVEL >= 10) {
+ DEBUG(10,("fset_nt_acl_tdb: storing tdb sd for file %s\n",
+ fsp->fsp_name));
+ NDR_PRINT_DEBUG(security_descriptor,
+ CONST_DISCARD(struct security_descriptor *,psd));
+ }
+ create_acl_blob(psd, &blob);
+ store_acl_blob_fsp(handle, fsp, &blob);
+
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
+ Handle opening the storage tdb if so configured.
+*******************************************************************/
+
+static int connect_acl_tdb(struct vfs_handle_struct *handle,
+ const char *service,
+ const char *user)
+{
+ struct db_context *db;
+ int res;
+
+ res = SMB_VFS_NEXT_CONNECT(handle, service, user);
+ if (res < 0) {
+ return res;
+ }
+
+ if (!acl_tdb_init(&db)) {
+ SMB_VFS_NEXT_DISCONNECT(handle);
+ return -1;
+ }
+
+ SMB_VFS_HANDLE_SET_DATA(handle, db, free_acl_tdb_data,
+ struct db_context, return -1);
+
+ return 0;
+}
+
+/*********************************************************************
+ Remove a Windows ACL - we're setting the underlying POSIX ACL.
+*********************************************************************/
+
+static int sys_acl_set_file_tdb(vfs_handle_struct *handle,
+ const char *path,
+ SMB_ACL_TYPE_T type,
+ SMB_ACL_T theacl)
+{
+ SMB_STRUCT_STAT sbuf;
+ struct db_context *db;
+ int ret;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
+
+ if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) {
+ return -1;
+ }
+
+ ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle,
+ path,
+ type,
+ theacl);
+ if (ret == -1) {
+ return -1;
+ }
+
+ acl_tdb_delete(handle, db, &sbuf);
+ return 0;
+}
+
+/*********************************************************************
+ Remove a Windows ACL - we're setting the underlying POSIX ACL.
+*********************************************************************/
+
+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;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);
+
+ if (fsp->is_directory || fsp->fh->fd == -1) {
+ ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf);
+ } else {
+ ret = SMB_VFS_FSTAT(fsp, &sbuf);
+ }
+ if (ret == -1) {
+ return -1;
+ }
+
+ ret = SMB_VFS_NEXT_SYS_ACL_SET_FD(handle,
+ fsp,
+ theacl);
+ if (ret == -1) {
+ return -1;
+ }
+
+ acl_tdb_delete(handle, db, &sbuf);
+ return 0;
+}
+
+/* VFS operations structure */
+
+static vfs_op_tuple skel_op_tuples[] =
+{
+ {SMB_VFS_OP(connect_acl_tdb), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT},
+
+ {SMB_VFS_OP(mkdir_acl_tdb), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(rmdir_acl_tdb), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT},
+
+ {SMB_VFS_OP(open_acl_tdb), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(unlink_acl_tdb), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT},
+
+ /* NT File ACL operations */
+
+ {SMB_VFS_OP(fget_nt_acl_tdb),SMB_VFS_OP_FGET_NT_ACL,SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(get_nt_acl_tdb), SMB_VFS_OP_GET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(fset_nt_acl_tdb),SMB_VFS_OP_FSET_NT_ACL,SMB_VFS_LAYER_TRANSPARENT},
+
+ /* POSIX ACL operations. */
+ {SMB_VFS_OP(sys_acl_set_file_tdb), SMB_VFS_OP_SYS_ACL_SET_FILE, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(sys_acl_set_fd_tdb), SMB_VFS_OP_SYS_ACL_SET_FD, SMB_VFS_LAYER_TRANSPARENT},
+
+ {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+};
+
+NTSTATUS vfs_acl_tdb_init(void)
+{
+ return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "acl_tdb", skel_op_tuples);
+}
diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c
index 5dfe43e55b..2edb441741 100644
--- a/source3/modules/vfs_acl_xattr.c
+++ b/source3/modules/vfs_acl_xattr.c
@@ -27,8 +27,11 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_VFS
+/*******************************************************************
+ Parse out a struct security_descriptor from a DATA_BLOB.
+*******************************************************************/
+
static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob,
- const struct timespec cts,
uint32 security_info,
struct security_descriptor **ppdesc)
{
@@ -50,39 +53,15 @@ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob,
return NT_STATUS_REVISION_MISMATCH;
}
-#if 0
- {
- struct timespec ts;
- /* Arg. This doesn't work. Too many activities
- * change the ctime. May have to roll back to
- * version 1.
- */
- /*
- * Check that the ctime timestamp is ealier
- * than the stored timestamp.
- */
-
- ts = nt_time_to_unix_timespec(&xacl.info.sd_ts->last_changed);
-
- if (timespec_compare(&cts, &ts) > 0) {
- DEBUG(5, ("parse_acl_blob: stored ACL out of date "
- "(%s > %s.\n",
- timestring(ctx, cts.tv_sec),
- timestring(ctx, ts.tv_sec)));
- return NT_STATUS_EA_CORRUPT_ERROR;
- }
- }
-#endif
-
- *ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
+ *ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION, xacl.info.sd_hs->sd->type | SEC_DESC_SELF_RELATIVE,
(security_info & OWNER_SECURITY_INFORMATION)
- ? xacl.info.sd_ts->sd->owner_sid : NULL,
+ ? xacl.info.sd_hs->sd->owner_sid : NULL,
(security_info & GROUP_SECURITY_INFORMATION)
- ? xacl.info.sd_ts->sd->group_sid : NULL,
+ ? xacl.info.sd_hs->sd->group_sid : NULL,
(security_info & SACL_SECURITY_INFORMATION)
- ? xacl.info.sd_ts->sd->sacl : NULL,
+ ? xacl.info.sd_hs->sd->sacl : NULL,
(security_info & DACL_SECURITY_INFORMATION)
- ? xacl.info.sd_ts->sd->dacl : NULL,
+ ? xacl.info.sd_hs->sd->dacl : NULL,
&sd_size);
TALLOC_FREE(xacl.info.sd);
@@ -90,6 +69,10 @@ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob,
return (*ppdesc != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
}
+/*******************************************************************
+ Pull a security descriptor into a DATA_BLOB from a xattr.
+*******************************************************************/
+
static NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
vfs_handle_struct *handle,
files_struct *fsp,
@@ -144,30 +127,24 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
return NT_STATUS_OK;
}
+/*******************************************************************
+ Create a DATA_BLOB from a security descriptor.
+*******************************************************************/
+
static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB *pblob)
{
struct xattr_NTACL xacl;
- struct security_descriptor_timestamp sd_ts;
+ struct security_descriptor_hash sd_hs;
enum ndr_err_code ndr_err;
TALLOC_CTX *ctx = talloc_tos();
- struct timespec curr = timespec_current();
ZERO_STRUCT(xacl);
- ZERO_STRUCT(sd_ts);
-
- /* Horrid hack as setting an xattr changes the ctime
- * on Linux. This gives a race of 1 second during
- * which we would not see a POSIX ACL set.
- */
- curr.tv_sec += 1;
+ ZERO_STRUCT(sd_hs);
xacl.version = 2;
- xacl.info.sd_ts = &sd_ts;
- xacl.info.sd_ts->sd = CONST_DISCARD(struct security_descriptor *, psd);
- unix_timespec_to_nt_time(&xacl.info.sd_ts->last_changed, curr);
-
- DEBUG(10, ("create_acl_blob: timestamp stored as %s\n",
- timestring(ctx, curr.tv_sec) ));
+ 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);
ndr_err = ndr_push_struct_blob(
pblob, ctx, NULL, &xacl,
@@ -182,7 +159,12 @@ static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB
return NT_STATUS_OK;
}
-static NTSTATUS store_acl_blob_fsp(files_struct *fsp,
+/*******************************************************************
+ Store a DATA_BLOB into an xattr given an fsp pointer.
+*******************************************************************/
+
+static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
+ files_struct *fsp,
DATA_BLOB *pblob)
{
int ret;
@@ -215,10 +197,15 @@ static NTSTATUS store_acl_blob_fsp(files_struct *fsp,
return NT_STATUS_OK;
}
-static NTSTATUS store_acl_blob_pathname(connection_struct *conn,
+/*******************************************************************
+ Store a DATA_BLOB into an xattr given a pathname.
+*******************************************************************/
+
+static NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle,
const char *fname,
DATA_BLOB *pblob)
{
+ connection_struct *conn = handle->conn;
int ret;
int saved_errno = 0;
@@ -245,6 +232,9 @@ static NTSTATUS store_acl_blob_pathname(connection_struct *conn,
return NT_STATUS_OK;
}
+/*******************************************************************
+ Store a DATA_BLOB into an xattr given a pathname.
+*******************************************************************/
static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle,
files_struct *fsp,
@@ -254,7 +244,6 @@ static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle,
{
TALLOC_CTX *ctx = talloc_tos();
DATA_BLOB blob;
- SMB_STRUCT_STAT sbuf;
NTSTATUS status;
if (fsp && name == NULL) {
@@ -269,18 +258,7 @@ static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle,
return status;
}
- if (fsp && fsp->fh->fd != -1) {
- if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
- return map_nt_error_from_unix(errno);
- }
- } else {
- if (SMB_VFS_STAT(handle->conn, name, &sbuf) == -1) {
- return map_nt_error_from_unix(errno);
- }
- }
-
- status = parse_acl_blob(&blob, get_ctimespec(&sbuf),
- security_info, ppdesc);
+ status = parse_acl_blob(&blob, security_info, ppdesc);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("parse_acl_blob returned %s\n",
nt_errstr(status)));
@@ -326,8 +304,7 @@ static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx,
}
return make_sec_desc(mem_ctx,
SECURITY_DESCRIPTOR_REVISION_1,
- SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT|
- SEC_DESC_DACL_DEFAULTED,
+ SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT,
&owner_sid,
&group_sid,
NULL,
@@ -364,28 +341,42 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
status = get_nt_acl_xattr_internal(handle,
NULL,
parent_name,
- DACL_SECURITY_INFORMATION,
+ (OWNER_SECURITY_INFORMATION |
+ GROUP_SECURITY_INFORMATION |
+ DACL_SECURITY_INFORMATION),
&parent_desc);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(10,("inherit_new_acl: directory %s failed "
- "to get acl %s\n",
- parent_name,
- nt_errstr(status) ));
- return status;
- }
+ if (NT_STATUS_IS_OK(status)) {
+ /* Create an inherited descriptor from the parent. */
+
+ if (DEBUGLEVEL >= 10) {
+ DEBUG(10,("inherit_new_acl: parent acl is:\n"));
+ NDR_PRINT_DEBUG(security_descriptor, parent_desc);
+ }
- /* Create an inherited descriptor from the parent. */
- status = se_create_child_secdesc(ctx,
+ status = se_create_child_secdesc(ctx,
&psd,
&size,
parent_desc,
&handle->conn->server_info->ptok->user_sids[PRIMARY_USER_SID_INDEX],
&handle->conn->server_info->ptok->user_sids[PRIMARY_GROUP_SID_INDEX],
container);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (DEBUGLEVEL >= 10) {
+ DEBUG(10,("inherit_new_acl: child acl is:\n"));
+ NDR_PRINT_DEBUG(security_descriptor, psd);
+ }
+
+ } else {
+ DEBUG(10,("inherit_new_acl: directory %s failed "
+ "to get acl %s\n",
+ parent_name,
+ nt_errstr(status) ));
}
- if (psd->dacl == NULL) {
+
+ if (!psd || psd->dacl == NULL) {
SMB_STRUCT_STAT sbuf;
int ret;
@@ -393,7 +384,7 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
if (fsp && !fsp->is_directory && fsp->fh->fd != -1) {
ret = SMB_VFS_FSTAT(fsp, &sbuf);
} else {
- ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf);
+ ret = SMB_VFS_STAT(handle->conn,fname, &sbuf);
}
if (ret == -1) {
return map_nt_error_from_unix(errno);
@@ -402,6 +393,11 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
if (!psd) {
return NT_STATUS_NO_MEMORY;
}
+
+ if (DEBUGLEVEL >= 10) {
+ DEBUG(10,("inherit_new_acl: default acl is:\n"));
+ NDR_PRINT_DEBUG(security_descriptor, psd);
+ }
}
status = create_acl_blob(psd, &blob);
@@ -409,9 +405,9 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
return status;
}
if (fsp) {
- return store_acl_blob_fsp(fsp, &blob);
+ return store_acl_blob_fsp(handle, fsp, &blob);
} else {
- return store_acl_blob_pathname(handle->conn, fname, &blob);
+ return store_acl_blob_pathname(handle, fname, &blob);
}
}
@@ -481,6 +477,10 @@ static int mkdir_acl_xattr(vfs_handle_struct *handle, const char *path, mode_t m
return ret;
}
+/*********************************************************************
+ Fetch a security descriptor given an fsp.
+*********************************************************************/
+
static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
uint32 security_info, struct security_descriptor **ppdesc)
{
@@ -494,10 +494,19 @@ static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
}
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);
}
+/*********************************************************************
+ Fetch a security descriptor given a pathname.
+*********************************************************************/
+
static NTSTATUS get_nt_acl_xattr(vfs_handle_struct *handle,
const char *name, uint32 security_info, struct security_descriptor **ppdesc)
{
@@ -511,10 +520,19 @@ static NTSTATUS get_nt_acl_xattr(vfs_handle_struct *handle,
}
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);
}
+/*********************************************************************
+ Store a security descriptor given an fsp.
+*********************************************************************/
+
static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
uint32 security_info_sent, const struct security_descriptor *psd)
{
@@ -584,11 +602,57 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
CONST_DISCARD(struct security_descriptor *,psd));
}
create_acl_blob(psd, &blob);
- store_acl_blob_fsp(fsp, &blob);
+ store_acl_blob_fsp(handle, fsp, &blob);
return NT_STATUS_OK;
}
+/*********************************************************************
+ Remove a Windows ACL - we're setting the underlying POSIX ACL.
+*********************************************************************/
+
+static int sys_acl_set_file_xattr(vfs_handle_struct *handle,
+ const char *name,
+ SMB_ACL_TYPE_T type,
+ SMB_ACL_T theacl)
+{
+ int ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle,
+ name,
+ type,
+ theacl);
+ if (ret == -1) {
+ return -1;
+ }
+
+ become_root();
+ SMB_VFS_REMOVEXATTR(handle->conn, name, XATTR_NTACL_NAME);
+ unbecome_root();
+
+ return ret;
+}
+
+/*********************************************************************
+ Remove a Windows ACL - we're setting the underlying POSIX ACL.
+*********************************************************************/
+
+static int sys_acl_set_fd_xattr(vfs_handle_struct *handle,
+ files_struct *fsp,
+ SMB_ACL_T theacl)
+{
+ int ret = SMB_VFS_NEXT_SYS_ACL_SET_FD(handle,
+ fsp,
+ theacl);
+ if (ret == -1) {
+ return -1;
+ }
+
+ become_root();
+ SMB_VFS_FREMOVEXATTR(fsp, XATTR_NTACL_NAME);
+ unbecome_root();
+
+ return ret;
+}
+
/* VFS operations structure */
static vfs_op_tuple skel_op_tuples[] =
@@ -602,7 +666,11 @@ static vfs_op_tuple skel_op_tuples[] =
{SMB_VFS_OP(get_nt_acl_xattr), SMB_VFS_OP_GET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(fset_nt_acl_xattr),SMB_VFS_OP_FSET_NT_ACL,SMB_VFS_LAYER_TRANSPARENT},
- {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+ /* POSIX ACL operations. */
+ {SMB_VFS_OP(sys_acl_set_file_xattr), SMB_VFS_OP_SYS_ACL_SET_FILE, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(sys_acl_set_fd_xattr), SMB_VFS_OP_SYS_ACL_SET_FD, SMB_VFS_LAYER_TRANSPARENT},
+
+ {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
};
NTSTATUS vfs_acl_xattr_init(void)
diff --git a/source3/modules/vfs_onefs.c b/source3/modules/vfs_onefs.c
new file mode 100644
index 0000000000..193a986cf6
--- /dev/null
+++ b/source3/modules/vfs_onefs.c
@@ -0,0 +1,48 @@
+/*
+ * Support for OneFS
+ *
+ * Copyright (C) Tim Prouty, 2008
+ *
+ * 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"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_VFS
+
+NTSTATUS onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
+ uint32 security_info, SEC_DESC **ppdesc);
+
+NTSTATUS onefs_get_nt_acl(vfs_handle_struct *handle, const char* name,
+ uint32 security_info, SEC_DESC **ppdesc);
+
+NTSTATUS onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
+ uint32 security_info_sent, SEC_DESC *psd);
+
+static vfs_op_tuple onefs_ops[] = {
+ {SMB_VFS_OP(onefs_fget_nt_acl), SMB_VFS_OP_FGET_NT_ACL,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(onefs_get_nt_acl), SMB_VFS_OP_GET_NT_ACL,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(onefs_fset_nt_acl), SMB_VFS_OP_FSET_NT_ACL,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+};
+
+NTSTATUS vfs_onefs_init(void)
+{
+ return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "onefs",
+ onefs_ops);
+}
diff --git a/source3/modules/vfs_readonly.c b/source3/modules/vfs_readonly.c
index d4ddf32e3a..58c83e5e1b 100644
--- a/source3/modules/vfs_readonly.c
+++ b/source3/modules/vfs_readonly.c
@@ -64,12 +64,25 @@ static int readonly_connect(vfs_handle_struct *handle,
"period", period_def);
if (period && period[0] && period[1]) {
+ int i;
time_t current_time = time(NULL);
time_t begin_period = get_date(period[0], &current_time);
time_t end_period = get_date(period[1], &current_time);
if ((current_time >= begin_period) && (current_time <= end_period)) {
+ connection_struct *conn = handle->conn;
+
handle->conn->read_only = True;
+
+ /* Wipe out the VUID cache. */
+ for (i=0; i< VUID_CACHE_SIZE; i++) {
+ struct vuid_cache_entry *ent = ent = &conn->vuid_cache.array[i];
+ ent->vuid = UID_FIELD_INVALID;
+ TALLOC_FREE(ent->server_info);
+ ent->read_only = false;
+ ent->admin_user = false;
+ }
+ conn->vuid_cache.next_entry = 0;
}
return SMB_VFS_NEXT_CONNECT(handle, service, user);
diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c
index d8c476f96f..69d34940fd 100644
--- a/source3/modules/vfs_streams_depot.c
+++ b/source3/modules/vfs_streams_depot.c
@@ -67,10 +67,15 @@ static uint32_t hash_fn(DATA_BLOB key)
#define SAMBA_XATTR_MARKER "user.SAMBA_STREAMS"
-static bool file_is_valid(vfs_handle_struct *handle, const char *path)
+static bool file_is_valid(vfs_handle_struct *handle, const char *path,
+ bool check_valid)
{
char buf;
+ if (!check_valid) {
+ return true;
+ }
+
DEBUG(10, ("file_is_valid (%s) called\n", path));
if (SMB_VFS_NEXT_GETXATTR(handle, path, SAMBA_XATTR_MARKER,
@@ -87,11 +92,16 @@ static bool file_is_valid(vfs_handle_struct *handle, const char *path)
return true;
}
-static bool mark_file_valid(vfs_handle_struct *handle, const char *path)
+static bool mark_file_valid(vfs_handle_struct *handle, const char *path,
+ bool check_valid)
{
char buf = '1';
int ret;
+ if (!check_valid) {
+ return true;
+ }
+
DEBUG(10, ("marking file %s as valid\n", path));
ret = SMB_VFS_NEXT_SETXATTR(handle, path, SAMBA_XATTR_MARKER,
@@ -116,10 +126,22 @@ static char *stream_dir(vfs_handle_struct *handle, const char *base_path,
char *id_hex;
struct file_id id;
uint8 id_buf[16];
+ bool check_valid;
+ const char *rootdir;
+
+ check_valid = lp_parm_bool(SNUM(handle->conn),
+ "streams_depot", "check_valid", true);
+
+ tmp = talloc_asprintf(talloc_tos(), "%s/.streams", handle->conn->connectpath);
- const char *rootdir = lp_parm_const_string(
+ if (tmp == NULL) {
+ errno = ENOMEM;
+ goto fail;
+ }
+
+ rootdir = lp_parm_const_string(
SNUM(handle->conn), "streams_depot", "directory",
- handle->conn->connectpath);
+ tmp);
if (base_sbuf == NULL) {
if (SMB_VFS_NEXT_STAT(handle, base_path, &sbuf) == -1) {
@@ -141,7 +163,7 @@ static char *stream_dir(vfs_handle_struct *handle, const char *base_path,
first = hash & 0xff;
second = (hash >> 8) & 0xff;
- id_hex = hex_encode(talloc_tos(), id_buf, sizeof(id_buf));
+ id_hex = hex_encode_talloc(talloc_tos(), id_buf, sizeof(id_buf));
if (id_hex == NULL) {
errno = ENOMEM;
@@ -166,7 +188,7 @@ static char *stream_dir(vfs_handle_struct *handle, const char *base_path,
goto fail;
}
- if (file_is_valid(handle, base_path)) {
+ if (file_is_valid(handle, base_path, check_valid)) {
return result;
}
@@ -236,7 +258,7 @@ static char *stream_dir(vfs_handle_struct *handle, const char *base_path,
goto fail;
}
- if (!mark_file_valid(handle, base_path)) {
+ if (!mark_file_valid(handle, base_path, check_valid)) {
goto fail;
}
@@ -262,6 +284,11 @@ static char *stream_name(vfs_handle_struct *handle, const char *fname,
goto fail;
}
+ /* if it's the ::$DATA stream just return the base file name */
+ if (!sname) {
+ return base;
+ }
+
dirname = stream_dir(handle, base, NULL, create_dir);
if (dirname == NULL) {
@@ -401,6 +428,7 @@ static int streams_depot_open(vfs_handle_struct *handle, const char *fname,
{
TALLOC_CTX *frame;
char *base = NULL;
+ char *sname = NULL;
SMB_STRUCT_STAT base_sbuf;
char *stream_fname;
int ret = -1;
@@ -412,11 +440,16 @@ static int streams_depot_open(vfs_handle_struct *handle, const char *fname,
frame = talloc_stackframe();
if (!NT_STATUS_IS_OK(split_ntfs_stream_name(talloc_tos(), fname,
- &base, NULL))) {
+ &base, &sname))) {
errno = ENOMEM;
goto done;
}
+ if (!sname) {
+ ret = SMB_VFS_NEXT_OPEN(handle, base, fsp, flags, mode);
+ goto done;
+ }
+
ret = SMB_VFS_NEXT_STAT(handle, base, &base_sbuf);
if (ret == -1) {
@@ -478,6 +511,78 @@ static int streams_depot_unlink(vfs_handle_struct *handle, const char *fname)
return SMB_VFS_NEXT_UNLINK(handle, fname);
}
+static int streams_depot_rename(vfs_handle_struct *handle,
+ const char *oldname,
+ const char *newname)
+{
+ TALLOC_CTX *frame = NULL;
+ int ret = -1;
+ bool old_is_stream;
+ bool new_is_stream;
+ char *obase = NULL;
+ char *osname = NULL;
+ char *nbase = NULL;
+ char *nsname = NULL;
+ char *ostream_fname = NULL;
+ char *nstream_fname = NULL;
+
+ DEBUG(10, ("streams_depot_rename called for %s => %s\n",
+ oldname, newname));
+
+ old_is_stream = is_ntfs_stream_name(oldname);
+ new_is_stream = is_ntfs_stream_name(newname);
+
+ if (!old_is_stream && !new_is_stream) {
+ return SMB_VFS_NEXT_RENAME(handle, oldname, newname);
+ }
+
+ if (!(old_is_stream && new_is_stream)) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ frame = talloc_stackframe();
+
+ if (!NT_STATUS_IS_OK(split_ntfs_stream_name(talloc_tos(), oldname,
+ &obase, &osname))) {
+ errno = ENOMEM;
+ goto done;
+ }
+
+ if (!NT_STATUS_IS_OK(split_ntfs_stream_name(talloc_tos(), oldname,
+ &nbase, &nsname))) {
+ errno = ENOMEM;
+ goto done;
+ }
+
+ /* for now don't allow renames from or to the default stream */
+ if (!osname || !nsname) {
+ errno = ENOSYS;
+ goto done;
+ }
+
+ if (StrCaseCmp(obase, nbase) != 0) {
+ errno = ENOSYS;
+ goto done;
+ }
+
+ ostream_fname = stream_name(handle, oldname, false);
+ if (ostream_fname == NULL) {
+ return -1;
+ }
+
+ nstream_fname = stream_name(handle, newname, false);
+ if (nstream_fname == NULL) {
+ return -1;
+ }
+
+ ret = SMB_VFS_NEXT_RENAME(handle, ostream_fname, nstream_fname);
+
+done:
+ TALLOC_FREE(frame);
+ return ret;
+}
+
static bool add_one_stream(TALLOC_CTX *mem_ctx, unsigned int *num_streams,
struct stream_struct **streams,
const char *name, SMB_OFF_T size,
@@ -628,6 +733,8 @@ static vfs_op_tuple streams_depot_ops[] = {
SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(streams_depot_unlink), SMB_VFS_OP_UNLINK,
SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(streams_depot_rename), SMB_VFS_OP_RENAME,
+ SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(streams_depot_streaminfo), SMB_VFS_OP_STREAMINFO,
SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
index b74c4f7902..ecfc31970d 100644
--- a/source3/modules/vfs_streams_xattr.c
+++ b/source3/modules/vfs_streams_xattr.c
@@ -29,6 +29,9 @@
struct stream_io {
char *base;
char *xattr_name;
+ void *fsp_name_ptr;
+ files_struct *fsp;
+ vfs_handle_struct *handle;
};
static SMB_INO_T stream_inode(const SMB_STRUCT_STAT *sbuf, const char *sname)
@@ -64,14 +67,16 @@ static SMB_INO_T stream_inode(const SMB_STRUCT_STAT *sbuf, const char *sname)
return result;
}
-static ssize_t get_xattr_size(connection_struct *conn, const char *fname,
- const char *xattr_name)
+static ssize_t get_xattr_size(connection_struct *conn,
+ files_struct *fsp,
+ const char *fname,
+ const char *xattr_name)
{
NTSTATUS status;
struct ea_struct ea;
ssize_t result;
- status = get_ea_value(talloc_tos(), conn, NULL, fname,
+ status = get_ea_value(talloc_tos(), conn, fsp, fname,
xattr_name, &ea);
if (!NT_STATUS_IS_OK(status)) {
@@ -83,6 +88,49 @@ static ssize_t get_xattr_size(connection_struct *conn, const char *fname,
return result;
}
+static bool streams_xattr_recheck(struct stream_io *sio)
+{
+ NTSTATUS status;
+ char *base = NULL;
+ char *sname = NULL;
+ char *xattr_name = NULL;
+
+ if (sio->fsp->fsp_name == sio->fsp_name_ptr) {
+ return true;
+ }
+
+ status = split_ntfs_stream_name(talloc_tos(), sio->fsp->fsp_name,
+ &base, &sname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+
+ if (sname == NULL) {
+ /* how can this happen */
+ errno = EINVAL;
+ return false;
+ }
+
+ xattr_name = talloc_asprintf(talloc_tos(), "%s%s",
+ SAMBA_XATTR_DOSSTREAM_PREFIX, sname);
+ if (xattr_name == NULL) {
+ return false;
+ }
+
+ TALLOC_FREE(sio->xattr_name);
+ TALLOC_FREE(sio->base);
+ 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),
+ base);
+ sio->fsp_name_ptr = sio->fsp->fsp_name;
+
+ if ((sio->xattr_name == NULL) || (sio->base == NULL)) {
+ return false;
+ }
+
+ return true;
+}
static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp,
SMB_STRUCT_STAT *sbuf)
@@ -92,15 +140,20 @@ static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp,
DEBUG(10, ("streams_xattr_fstat called for %d\n", fsp->fh->fd));
- if (io == NULL) {
+ if (io == NULL || fsp->base_fsp == NULL) {
return SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
}
- if (SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf) == -1) {
+ if (!streams_xattr_recheck(io)) {
return -1;
}
- sbuf->st_size = get_xattr_size(handle->conn, io->base, io->xattr_name);
+ if (SMB_VFS_STAT(handle->conn, io->base, sbuf) == -1) {
+ return -1;
+ }
+
+ sbuf->st_size = get_xattr_size(handle->conn, fsp->base_fsp,
+ io->base, io->xattr_name);
if (sbuf->st_size == -1) {
return -1;
}
@@ -133,6 +186,10 @@ static int streams_xattr_stat(vfs_handle_struct *handle, const char *fname,
return -1;
}
+ if (sname == NULL){
+ return SMB_VFS_NEXT_STAT(handle, base, sbuf);
+ }
+
if (SMB_VFS_STAT(handle->conn, base, sbuf) == -1) {
goto fail;
}
@@ -144,7 +201,7 @@ static int streams_xattr_stat(vfs_handle_struct *handle, const char *fname,
goto fail;
}
- sbuf->st_size = get_xattr_size(handle->conn, base, xattr_name);
+ sbuf->st_size = get_xattr_size(handle->conn, NULL, base, xattr_name);
if (sbuf->st_size == -1) {
errno = ENOENT;
goto fail;
@@ -180,6 +237,10 @@ static int streams_xattr_lstat(vfs_handle_struct *handle, const char *fname,
goto fail;
}
+ if (sname == NULL){
+ return SMB_VFS_NEXT_LSTAT(handle, base, sbuf);
+ }
+
if (SMB_VFS_LSTAT(handle->conn, base, sbuf) == -1) {
goto fail;
}
@@ -191,7 +252,7 @@ static int streams_xattr_lstat(vfs_handle_struct *handle, const char *fname,
goto fail;
}
- sbuf->st_size = get_xattr_size(handle->conn, base, xattr_name);
+ sbuf->st_size = get_xattr_size(handle->conn, NULL, base, xattr_name);
if (sbuf->st_size == -1) {
errno = ENOENT;
goto fail;
@@ -236,6 +297,12 @@ static int streams_xattr_open(vfs_handle_struct *handle, const char *fname,
goto fail;
}
+ if (sname == NULL) {
+ hostfd = SMB_VFS_NEXT_OPEN(handle, base, fsp, flags, mode);
+ talloc_free(frame);
+ return hostfd;
+ }
+
xattr_name = talloc_asprintf(talloc_tos(), "%s%s",
SAMBA_XATTR_DOSSTREAM_PREFIX, sname);
if (xattr_name == NULL) {
@@ -300,22 +367,40 @@ static int streams_xattr_open(vfs_handle_struct *handle, const char *fname,
DEBUG(10, ("creating attribute %s on file %s\n",
xattr_name, base));
- if (SMB_VFS_SETXATTR(
- handle->conn, base, xattr_name,
- &null, sizeof(null),
- flags & O_EXCL ? XATTR_CREATE : 0) == -1) {
- goto fail;
+ if (fsp->base_fsp->fh->fd != -1) {
+ if (SMB_VFS_FSETXATTR(
+ fsp->base_fsp, xattr_name,
+ &null, sizeof(null),
+ flags & O_EXCL ? XATTR_CREATE : 0) == -1) {
+ goto fail;
+ }
+ } else {
+ if (SMB_VFS_SETXATTR(
+ handle->conn, base, xattr_name,
+ &null, sizeof(null),
+ flags & O_EXCL ? XATTR_CREATE : 0) == -1) {
+ goto fail;
+ }
}
}
}
if (flags & O_TRUNC) {
char null = '\0';
- if (SMB_VFS_SETXATTR(
- handle->conn, base, xattr_name,
- &null, sizeof(null),
- flags & O_EXCL ? XATTR_CREATE : 0) == -1) {
- goto fail;
+ if (fsp->base_fsp->fh->fd != -1) {
+ if (SMB_VFS_FSETXATTR(
+ fsp->base_fsp, xattr_name,
+ &null, sizeof(null),
+ flags & O_EXCL ? XATTR_CREATE : 0) == -1) {
+ goto fail;
+ }
+ } else {
+ if (SMB_VFS_SETXATTR(
+ handle->conn, base, xattr_name,
+ &null, sizeof(null),
+ flags & O_EXCL ? XATTR_CREATE : 0) == -1) {
+ goto fail;
+ }
}
}
@@ -330,6 +415,9 @@ static int streams_xattr_open(vfs_handle_struct *handle, const char *fname,
xattr_name);
sio->base = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handle, fsp),
base);
+ sio->fsp_name_ptr = fsp->fsp_name;
+ sio->handle = handle;
+ sio->fsp = fsp;
if ((sio->xattr_name == NULL) || (sio->base == NULL)) {
errno = ENOMEM;
@@ -370,6 +458,10 @@ static int streams_xattr_unlink(vfs_handle_struct *handle, const char *fname)
goto fail;
}
+ if (sname == NULL){
+ return SMB_VFS_NEXT_UNLINK(handle, base);
+ }
+
xattr_name = talloc_asprintf(talloc_tos(), "%s%s",
SAMBA_XATTR_DOSSTREAM_PREFIX, sname);
if (xattr_name == NULL) {
@@ -392,6 +484,127 @@ static int streams_xattr_unlink(vfs_handle_struct *handle, const char *fname)
return ret;
}
+static int streams_xattr_rename(vfs_handle_struct *handle,
+ const char *oldname,
+ const char *newname)
+{
+ NTSTATUS status;
+ TALLOC_CTX *frame = NULL;
+ char *obase;
+ char *ostream;
+ char *nbase;
+ char *nstream;
+ const char *base;
+ int ret = -1;
+ char *oxattr_name;
+ char *nxattr_name;
+ bool o_is_stream;
+ bool n_is_stream;
+ ssize_t oret;
+ ssize_t nret;
+ struct ea_struct ea;
+
+ o_is_stream = is_ntfs_stream_name(oldname);
+ n_is_stream = is_ntfs_stream_name(newname);
+
+ if (!o_is_stream && !n_is_stream) {
+ return SMB_VFS_NEXT_RENAME(handle, oldname, newname);
+ }
+
+ if (!(o_is_stream && n_is_stream)) {
+ errno = ENOSYS;
+ goto fail;
+ }
+
+ frame = talloc_stackframe();
+ if (!frame) {
+ goto fail;
+ }
+
+ status = split_ntfs_stream_name(talloc_tos(), oldname, &obase, &ostream);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = EINVAL;
+ goto fail;
+ }
+
+ status = split_ntfs_stream_name(talloc_tos(), newname, &nbase, &nstream);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = EINVAL;
+ goto fail;
+ }
+
+ /*TODO: maybe call SMB_VFS_NEXT_RENAME() both streams are NULL (::$DATA) */
+ if (ostream == NULL) {
+ errno = ENOSYS;
+ goto fail;
+ }
+
+ if (nstream == NULL) {
+ errno = ENOSYS;
+ goto fail;
+ }
+
+ /* the new base should be empty */
+ if (StrCaseCmp(obase, nbase) != 0) {
+ errno = ENOSYS;
+ goto fail;
+ }
+
+ if (StrCaseCmp(ostream, nstream) == 0) {
+ goto done;
+ }
+
+ base = obase;
+
+ oxattr_name = talloc_asprintf(talloc_tos(), "%s%s",
+ SAMBA_XATTR_DOSSTREAM_PREFIX, ostream);
+ if (oxattr_name == NULL) {
+ errno = ENOMEM;
+ goto fail;
+ }
+
+ nxattr_name = talloc_asprintf(talloc_tos(), "%s%s",
+ SAMBA_XATTR_DOSSTREAM_PREFIX, nstream);
+ if (nxattr_name == NULL) {
+ errno = ENOMEM;
+ goto fail;
+ }
+
+ /* read the old stream */
+ status = get_ea_value(talloc_tos(), handle->conn, NULL,
+ base, oxattr_name, &ea);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = ENOENT;
+ goto fail;
+ }
+
+ /* (over)write the new stream */
+ nret = SMB_VFS_SETXATTR(handle->conn, base, nxattr_name,
+ ea.value.data, ea.value.length, 0);
+ if (nret < 0) {
+ if (errno == ENOATTR) {
+ errno = ENOENT;
+ }
+ goto fail;
+ }
+
+ /* remove the old stream */
+ oret = SMB_VFS_REMOVEXATTR(handle->conn, base, oxattr_name);
+ if (oret < 0) {
+ if (errno == ENOATTR) {
+ errno = ENOENT;
+ }
+ goto fail;
+ }
+
+ done:
+ errno = 0;
+ ret = 0;
+ fail:
+ TALLOC_FREE(frame);
+ return ret;
+}
+
static NTSTATUS walk_xattr_streams(connection_struct *conn, files_struct *fsp,
const char *fname,
bool (*fn)(struct ea_struct *ea,
@@ -579,6 +792,10 @@ static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle,
return SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
}
+ if (!streams_xattr_recheck(sio)) {
+ return -1;
+ }
+
status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp,
sio->base, sio->xattr_name, &ea);
if (!NT_STATUS_IS_OK(status)) {
@@ -603,10 +820,15 @@ static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle,
memcpy(ea.value.data + offset, data, n);
- ret = SMB_VFS_SETXATTR(fsp->conn, fsp->base_fsp->fsp_name,
+ if (fsp->base_fsp->fh->fd != -1) {
+ ret = SMB_VFS_FSETXATTR(fsp->base_fsp,
sio->xattr_name,
ea.value.data, ea.value.length, 0);
-
+ } else {
+ ret = SMB_VFS_SETXATTR(fsp->conn, fsp->base_fsp->fsp_name,
+ sio->xattr_name,
+ ea.value.data, ea.value.length, 0);
+ }
TALLOC_FREE(ea.value.data);
if (ret == -1) {
@@ -624,12 +846,16 @@ static ssize_t streams_xattr_pread(vfs_handle_struct *handle,
(struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
struct ea_struct ea;
NTSTATUS status;
- size_t length, overlap;
+ size_t length, overlap;
if (sio == NULL) {
return SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
}
+ if (!streams_xattr_recheck(sio)) {
+ return -1;
+ }
+
status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp,
sio->base, sio->xattr_name, &ea);
if (!NT_STATUS_IS_OK(status)) {
@@ -651,6 +877,73 @@ static ssize_t streams_xattr_pread(vfs_handle_struct *handle,
return overlap;
}
+static int streams_xattr_ftruncate(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ SMB_OFF_T offset)
+{
+ int ret;
+ uint8 *tmp;
+ struct ea_struct ea;
+ NTSTATUS status;
+ struct stream_io *sio =
+ (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 ));
+
+ if (sio == NULL) {
+ return SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset);
+ }
+
+ if (!streams_xattr_recheck(sio)) {
+ return -1;
+ }
+
+ status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp,
+ sio->base, sio->xattr_name, &ea);
+ if (!NT_STATUS_IS_OK(status)) {
+ return -1;
+ }
+
+ tmp = TALLOC_REALLOC_ARRAY(talloc_tos(), ea.value.data, uint8,
+ offset + 1);
+
+ if (tmp == NULL) {
+ TALLOC_FREE(ea.value.data);
+ errno = ENOMEM;
+ return -1;
+ }
+
+ /* Did we expand ? */
+ if (ea.value.length < offset + 1) {
+ memset(&tmp[ea.value.length], '\0',
+ offset + 1 - ea.value.length);
+ }
+
+ ea.value.data = tmp;
+ ea.value.length = offset + 1;
+ ea.value.data[offset] = 0;
+
+ if (fsp->base_fsp->fh->fd != -1) {
+ ret = SMB_VFS_FSETXATTR(fsp->base_fsp,
+ sio->xattr_name,
+ ea.value.data, ea.value.length, 0);
+ } else {
+ ret = SMB_VFS_SETXATTR(fsp->conn, fsp->base_fsp->fsp_name,
+ sio->xattr_name,
+ ea.value.data, ea.value.length, 0);
+ }
+
+ TALLOC_FREE(ea.value.data);
+
+ if (ret == -1) {
+ return -1;
+ }
+
+ return 0;
+}
+
/* VFS operations structure */
static vfs_op_tuple streams_xattr_ops[] = {
@@ -672,6 +965,10 @@ static vfs_op_tuple streams_xattr_ops[] = {
SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(streams_xattr_unlink), SMB_VFS_OP_UNLINK,
SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(streams_xattr_rename), SMB_VFS_OP_RENAME,
+ SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(streams_xattr_ftruncate), SMB_VFS_OP_FTRUNCATE,
+ SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(streams_xattr_streaminfo), SMB_VFS_OP_STREAMINFO,
SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
diff --git a/source3/modules/vfs_tsmsm.c b/source3/modules/vfs_tsmsm.c
index ee958b1be5..6fb1d1d2d4 100644
--- a/source3/modules/vfs_tsmsm.c
+++ b/source3/modules/vfs_tsmsm.c
@@ -148,7 +148,7 @@ static bool tsmsm_is_offline(struct vfs_handle_struct *handle,
dm_attrname_t dmname;
int ret, lerrno;
bool offline;
- char *buf;
+ char *buf = NULL;
size_t buflen;
/* if the file has more than FILE_IS_ONLINE_RATIO of blocks available,
diff --git a/source3/modules/vfs_zfsacl.c b/source3/modules/vfs_zfsacl.c
index 3688b2386e..a5b0490c8d 100644
--- a/source3/modules/vfs_zfsacl.c
+++ b/source3/modules/vfs_zfsacl.c
@@ -212,9 +212,92 @@ static NTSTATUS zfsacl_fset_nt_acl(vfs_handle_struct *handle,
return zfs_set_nt_acl(handle, fsp, security_info_sent, psd);
}
+/* nils.goroll@hamburg.de 2008-06-16 :
+
+ See also
+ - https://bugzilla.samba.org/show_bug.cgi?id=5446
+ - http://bugs.opensolaris.org/view_bug.do?bug_id=6688240
+
+ Solaris supports NFSv4 and ZFS ACLs through a common system call, acl(2)
+ with ACE_SETACL / ACE_GETACL / ACE_GETACLCNT, which is being wrapped for
+ use by samba in this module.
+
+ As the acl(2) interface is identical for ZFS and for NFS, this module,
+ vfs_zfsacl, can not only be used for ZFS, but also for sharing NFSv4
+ mounts on Solaris.
+
+ But while "traditional" POSIX DRAFT ACLs (using acl(2) with SETACL
+ / GETACL / GETACLCNT) fail for ZFS, the Solaris NFS client
+ implemets a compatibility wrapper, which will make calls to
+ traditional ACL calls though vfs_solarisacl succeed. As the
+ compatibility wrapper's implementation is (by design) incomplete,
+ we want to make sure that it is never being called.
+
+ As long as Samba does not support an exiplicit method for a module
+ to define conflicting vfs methods, we should override all conflicting
+ methods here.
+
+ For this to work, we need to make sure that this module is initialised
+ *after* vfs_solarisacl
+
+ Function declarations taken from vfs_solarisacl
+*/
+
+SMB_ACL_T zfsacl_fail__sys_acl_get_file(vfs_handle_struct *handle,
+ const char *path_p,
+ SMB_ACL_TYPE_T type)
+{
+ return (SMB_ACL_T)NULL;
+}
+SMB_ACL_T zfsacl_fail__sys_acl_get_fd(vfs_handle_struct *handle,
+ files_struct *fsp,
+ int fd)
+{
+ return (SMB_ACL_T)NULL;
+}
+
+int zfsacl_fail__sys_acl_set_file(vfs_handle_struct *handle,
+ const char *name,
+ SMB_ACL_TYPE_T type,
+ SMB_ACL_T theacl)
+{
+ return -1;
+}
+
+int zfsacl_fail__sys_acl_set_fd(vfs_handle_struct *handle,
+ files_struct *fsp,
+ int fd, SMB_ACL_T theacl)
+{
+ return -1;
+}
+
+int zfsacl_fail__sys_acl_delete_def_file(vfs_handle_struct *handle,
+ const char *path)
+{
+ return -1;
+}
+
/* VFS operations structure */
static vfs_op_tuple zfsacl_ops[] = {
+ /* invalidate conflicting VFS methods */
+ {SMB_VFS_OP(zfsacl_fail__sys_acl_get_file),
+ SMB_VFS_OP_SYS_ACL_GET_FILE,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(zfsacl_fail__sys_acl_get_fd),
+ SMB_VFS_OP_SYS_ACL_GET_FD,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(zfsacl_fail__sys_acl_set_file),
+ SMB_VFS_OP_SYS_ACL_SET_FILE,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(zfsacl_fail__sys_acl_set_fd),
+ SMB_VFS_OP_SYS_ACL_SET_FD,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(zfsacl_fail__sys_acl_delete_def_file),
+ SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE,
+ SMB_VFS_LAYER_OPAQUE},
+
+ /* actual methods */
{SMB_VFS_OP(zfsacl_fget_nt_acl), SMB_VFS_OP_FGET_NT_ACL,
SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(zfsacl_get_nt_acl), SMB_VFS_OP_GET_NT_ACL,
diff --git a/source3/nsswitch/libwbclient/wbc_idmap.c b/source3/nsswitch/libwbclient/wbc_idmap.c
index 1615fd33ee..81b369c87c 100644
--- a/source3/nsswitch/libwbclient/wbc_idmap.c
+++ b/source3/nsswitch/libwbclient/wbc_idmap.c
@@ -24,7 +24,7 @@
#include "libwbclient.h"
-/** @brief Convert a Windows SID to a Unix uid
+/** @brief Convert a Windows SID to a Unix uid, allocating an uid if needed
*
* @param *sid Pointer to the domain SID to be resolved
* @param *puid Pointer to the resolved uid_t value
@@ -71,7 +71,22 @@ wbcErr wbcSidToUid(const struct wbcDomainSid *sid, uid_t *puid)
return wbc_status;
}
-/** @brief Convert a Unix uid to a Windows SID
+/** @brief Convert a Windows SID to a Unix uid if there already is a mapping
+ *
+ * @param *sid Pointer to the domain SID to be resolved
+ * @param *puid Pointer to the resolved uid_t value
+ *
+ * @return #wbcErr
+ *
+ **/
+
+wbcErr wbcQuerySidToUid(const struct wbcDomainSid *sid,
+ uid_t *puid)
+{
+ return WBC_ERR_NOT_IMPLEMENTED;
+}
+
+/** @brief Convert a Unix uid to a Windows SID, allocating a SID if needed
*
* @param uid Unix uid to be resolved
* @param *sid Pointer to the resolved domain SID
@@ -112,7 +127,22 @@ done:
return wbc_status;
}
-/** @brief Convert a Windows SID to a Unix gid
+/** @brief Convert a Unix uid to a Windows SID if there already is a mapping
+ *
+ * @param uid Unix uid to be resolved
+ * @param *sid Pointer to the resolved domain SID
+ *
+ * @return #wbcErr
+ *
+ **/
+
+wbcErr wbcQueryUidToSid(uid_t uid,
+ struct wbcDomainSid *sid)
+{
+ return WBC_ERR_NOT_IMPLEMENTED;
+}
+
+/** @brief Convert a Windows SID to a Unix gid, allocating a gid if needed
*
* @param *sid Pointer to the domain SID to be resolved
* @param *pgid Pointer to the resolved gid_t value
@@ -159,7 +189,22 @@ wbcErr wbcSidToGid(const struct wbcDomainSid *sid, gid_t *pgid)
return wbc_status;
}
-/** @brief Convert a Unix uid to a Windows SID
+/** @brief Convert a Windows SID to a Unix gid if there already is a mapping
+ *
+ * @param *sid Pointer to the domain SID to be resolved
+ * @param *pgid Pointer to the resolved gid_t value
+ *
+ * @return #wbcErr
+ *
+ **/
+
+wbcErr wbcQuerySidToGid(const struct wbcDomainSid *sid,
+ gid_t *pgid)
+{
+ return WBC_ERR_NOT_IMPLEMENTED;
+}
+
+/** @brief Convert a Unix gid to a Windows SID, allocating a SID if needed
*
* @param gid Unix gid to be resolved
* @param *sid Pointer to the resolved domain SID
@@ -200,6 +245,21 @@ done:
return wbc_status;
}
+/** @brief Convert a Unix gid to a Windows SID if there already is a mapping
+ *
+ * @param gid Unix gid to be resolved
+ * @param *sid Pointer to the resolved domain SID
+ *
+ * @return #wbcErr
+ *
+ **/
+
+wbcErr wbcQueryGidToSid(gid_t gid,
+ struct wbcDomainSid *sid)
+{
+ return WBC_ERR_NOT_IMPLEMENTED;
+}
+
/** @brief Obtain a new uid from Winbind
*
* @param *puid *pointer to the allocated uid
@@ -362,6 +422,92 @@ wbcErr wbcSetGidMapping(gid_t gid, const struct wbcDomainSid *sid)
return wbc_status;
}
+/** @brief Remove a user id mapping
+ *
+ * @param uid Uid of the mapping to remove.
+ * @param *sid Pointer to the sid of the mapping to remove.
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcRemoveUidMapping(uid_t uid, const struct wbcDomainSid *sid)
+{
+ struct winbindd_request request;
+ struct winbindd_response response;
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ char *sid_string = NULL;
+
+ if (!sid) {
+ return WBC_ERR_INVALID_PARAM;
+ }
+
+ /* Initialise request */
+
+ ZERO_STRUCT(request);
+ ZERO_STRUCT(response);
+
+ /* Make request */
+
+ request.data.dual_idmapset.id = uid;
+ request.data.dual_idmapset.type = _ID_TYPE_UID;
+
+ wbc_status = wbcSidToString(sid, &sid_string);
+ BAIL_ON_WBC_ERROR(wbc_status);
+
+ strncpy(request.data.dual_idmapset.sid, sid_string,
+ sizeof(request.data.dual_idmapset.sid)-1);
+ wbcFreeMemory(sid_string);
+
+ wbc_status = wbcRequestResponse(WINBINDD_REMOVE_MAPPING,
+ &request, &response);
+ BAIL_ON_WBC_ERROR(wbc_status);
+
+ done:
+ return wbc_status;
+}
+
+/** @brief Remove a group id mapping
+ *
+ * @param gid Gid of the mapping to remove.
+ * @param *sid Pointer to the sid of the mapping to remove.
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcRemoveGidMapping(gid_t gid, const struct wbcDomainSid *sid)
+{
+ struct winbindd_request request;
+ struct winbindd_response response;
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ char *sid_string = NULL;
+
+ if (!sid) {
+ return WBC_ERR_INVALID_PARAM;
+ }
+
+ /* Initialise request */
+
+ ZERO_STRUCT(request);
+ ZERO_STRUCT(response);
+
+ /* Make request */
+
+ request.data.dual_idmapset.id = gid;
+ request.data.dual_idmapset.type = _ID_TYPE_GID;
+
+ wbc_status = wbcSidToString(sid, &sid_string);
+ BAIL_ON_WBC_ERROR(wbc_status);
+
+ strncpy(request.data.dual_idmapset.sid, sid_string,
+ sizeof(request.data.dual_idmapset.sid)-1);
+ wbcFreeMemory(sid_string);
+
+ wbc_status = wbcRequestResponse(WINBINDD_REMOVE_MAPPING,
+ &request, &response);
+ BAIL_ON_WBC_ERROR(wbc_status);
+
+ done:
+ return wbc_status;
+}
+
/** @brief Set the highwater mark for allocated uids.
*
* @param uid_hwm The new uid highwater mark value
diff --git a/source3/nsswitch/libwbclient/wbc_pam.c b/source3/nsswitch/libwbclient/wbc_pam.c
index 713ba2e65b..401d2ad2c3 100644
--- a/source3/nsswitch/libwbclient/wbc_pam.c
+++ b/source3/nsswitch/libwbclient/wbc_pam.c
@@ -1095,3 +1095,18 @@ done:
return wbc_status;
}
+
+/** @brief Authenticate a user with cached credentials
+ *
+ * @param *params Pointer to a wbcCredentialCacheParams structure
+ * @param **info Pointer to a pointer to a wbcCredentialCacheInfo structure
+ * @param **error Pointer to a pointer to a wbcAuthErrorInfo structure
+ *
+ * @return #wbcErr
+ **/
+wbcErr wbcCredentialCache(struct wbcCredentialCacheParams *params,
+ struct wbcCredentialCacheInfo **info,
+ struct wbcAuthErrorInfo **error)
+{
+ return WBC_ERR_NOT_IMPLEMENTED;
+}
diff --git a/source3/nsswitch/libwbclient/wbc_pwd.c b/source3/nsswitch/libwbclient/wbc_pwd.c
index 0d17b312ef..d54a5af4fc 100644
--- a/source3/nsswitch/libwbclient/wbc_pwd.c
+++ b/source3/nsswitch/libwbclient/wbc_pwd.c
@@ -24,6 +24,16 @@
#include "libwbclient.h"
+/** @brief The maximum number of pwent structs to get from winbindd
+ *
+ */
+#define MAX_GETPWENT_USERS 500
+
+/** @brief The maximum number of grent structs to get from winbindd
+ *
+ */
+#define MAX_GETGRENT_GROUPS 500
+
/**
*
**/
@@ -284,6 +294,21 @@ wbcErr wbcGetgrgid(gid_t gid, struct group **grp)
return wbc_status;
}
+/** @brief Number of cached passwd structs
+ *
+ */
+static uint32_t pw_cache_size;
+
+/** @brief Position of the pwent context
+ *
+ */
+static uint32_t pw_cache_idx;
+
+/** @brief Winbindd response containing the passwd structs
+ *
+ */
+static struct winbindd_response pw_response;
+
/** @brief Reset the passwd iterator
*
* @return #wbcErr
@@ -293,6 +318,15 @@ wbcErr wbcSetpwent(void)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ if (pw_cache_size > 0) {
+ pw_cache_idx = pw_cache_size = 0;
+ if (pw_response.extra_data.data) {
+ free(pw_response.extra_data.data);
+ }
+ }
+
+ ZERO_STRUCT(pw_response);
+
wbc_status = wbcRequestResponse(WINBINDD_SETPWENT,
NULL, NULL);
BAIL_ON_WBC_ERROR(wbc_status);
@@ -310,6 +344,13 @@ wbcErr wbcEndpwent(void)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ if (pw_cache_size > 0) {
+ pw_cache_idx = pw_cache_size = 0;
+ if (pw_response.extra_data.data) {
+ free(pw_response.extra_data.data);
+ }
+ }
+
wbc_status = wbcRequestResponse(WINBINDD_ENDPWENT,
NULL, NULL);
BAIL_ON_WBC_ERROR(wbc_status);
@@ -320,16 +361,70 @@ wbcErr wbcEndpwent(void)
/** @brief Return the next struct passwd* entry from the pwent iterator
*
- * @param **pwd Pointer to resulting struct group* from the query.
+ * @param **pwd Pointer to resulting struct passwd* from the query.
*
* @return #wbcErr
**/
wbcErr wbcGetpwent(struct passwd **pwd)
{
- return WBC_ERR_NOT_IMPLEMENTED;
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ struct winbindd_request request;
+ struct winbindd_pw *wb_pw;
+
+ /* If there's a cached result, return that. */
+ if (pw_cache_idx < pw_cache_size) {
+ goto return_result;
+ }
+
+ /* Otherwise, query winbindd for some entries. */
+
+ pw_cache_idx = 0;
+
+ if (pw_response.extra_data.data) {
+ free(pw_response.extra_data.data);
+ ZERO_STRUCT(pw_response);
+ }
+
+ ZERO_STRUCT(request);
+ request.data.num_entries = MAX_GETPWENT_USERS;
+
+ wbc_status = wbcRequestResponse(WINBINDD_GETPWENT, &request,
+ &pw_response);
+
+ BAIL_ON_WBC_ERROR(wbc_status);
+
+ pw_cache_size = pw_response.data.num_entries;
+
+return_result:
+
+ wb_pw = (struct winbindd_pw *) pw_response.extra_data.data;
+
+ *pwd = copy_passwd_entry(&wb_pw[pw_cache_idx]);
+
+ BAIL_ON_PTR_ERROR(*pwd, wbc_status);
+
+ pw_cache_idx++;
+
+done:
+ return wbc_status;
}
+/** @brief Number of cached group structs
+ *
+ */
+static uint32_t gr_cache_size;
+
+/** @brief Position of the grent context
+ *
+ */
+static uint32_t gr_cache_idx;
+
+/** @brief Winbindd response containing the group structs
+ *
+ */
+static struct winbindd_response gr_response;
+
/** @brief Reset the group iterator
*
* @return #wbcErr
@@ -339,6 +434,15 @@ wbcErr wbcSetgrent(void)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ if (gr_cache_size > 0) {
+ gr_cache_idx = gr_cache_size = 0;
+ if (gr_response.extra_data.data) {
+ free(gr_response.extra_data.data);
+ }
+ }
+
+ ZERO_STRUCT(gr_response);
+
wbc_status = wbcRequestResponse(WINBINDD_SETGRENT,
NULL, NULL);
BAIL_ON_WBC_ERROR(wbc_status);
@@ -356,6 +460,13 @@ wbcErr wbcEndgrent(void)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ if (gr_cache_size > 0) {
+ gr_cache_idx = gr_cache_size = 0;
+ if (gr_response.extra_data.data) {
+ free(gr_response.extra_data.data);
+ }
+ }
+
wbc_status = wbcRequestResponse(WINBINDD_ENDGRENT,
NULL, NULL);
BAIL_ON_WBC_ERROR(wbc_status);
@@ -364,7 +475,7 @@ wbcErr wbcEndgrent(void)
return wbc_status;
}
-/** @brief Return the next struct passwd* entry from the pwent iterator
+/** @brief Return the next struct group* entry from the pwent iterator
*
* @param **grp Pointer to resulting struct group* from the query.
*
@@ -373,7 +484,104 @@ wbcErr wbcEndgrent(void)
wbcErr wbcGetgrent(struct group **grp)
{
- return WBC_ERR_NOT_IMPLEMENTED;
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ struct winbindd_request request;
+ struct winbindd_gr *wb_gr;
+ uint32_t mem_ofs;
+
+ /* If there's a cached result, return that. */
+ if (gr_cache_idx < gr_cache_size) {
+ goto return_result;
+ }
+
+ /* Otherwise, query winbindd for some entries. */
+
+ gr_cache_idx = 0;
+
+ if (gr_response.extra_data.data) {
+ free(gr_response.extra_data.data);
+ ZERO_STRUCT(gr_response);
+ }
+
+ ZERO_STRUCT(request);
+ request.data.num_entries = MAX_GETGRENT_GROUPS;
+
+ wbc_status = wbcRequestResponse(WINBINDD_GETGRENT, &request,
+ &gr_response);
+
+ BAIL_ON_WBC_ERROR(wbc_status);
+
+ gr_cache_size = gr_response.data.num_entries;
+
+return_result:
+
+ wb_gr = (struct winbindd_gr *) gr_response.extra_data.data;
+
+ mem_ofs = wb_gr[gr_cache_idx].gr_mem_ofs +
+ gr_cache_size * sizeof(struct winbindd_gr);
+
+ *grp = copy_group_entry(&wb_gr[gr_cache_idx],
+ ((char *)gr_response.extra_data.data)+mem_ofs);
+
+ BAIL_ON_PTR_ERROR(*grp, wbc_status);
+
+ gr_cache_idx++;
+
+done:
+ return wbc_status;
+}
+
+/** @brief Return the next struct group* entry from the pwent iterator
+ *
+ * This is similar to #wbcGetgrent, just that the member list is empty
+ *
+ * @param **grp Pointer to resulting struct group* from the query.
+ *
+ * @return #wbcErr
+ **/
+
+wbcErr wbcGetgrlist(struct group **grp)
+{
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ struct winbindd_request request;
+ struct winbindd_gr *wb_gr;
+
+ /* If there's a cached result, return that. */
+ if (gr_cache_idx < gr_cache_size) {
+ goto return_result;
+ }
+
+ /* Otherwise, query winbindd for some entries. */
+
+ gr_cache_idx = 0;
+
+ if (gr_response.extra_data.data) {
+ free(gr_response.extra_data.data);
+ ZERO_STRUCT(gr_response);
+ }
+
+ ZERO_STRUCT(request);
+ request.data.num_entries = MAX_GETGRENT_GROUPS;
+
+ wbc_status = wbcRequestResponse(WINBINDD_GETGRLST, &request,
+ &gr_response);
+
+ BAIL_ON_WBC_ERROR(wbc_status);
+
+ gr_cache_size = gr_response.data.num_entries;
+
+return_result:
+
+ wb_gr = (struct winbindd_gr *) gr_response.extra_data.data;
+
+ *grp = copy_group_entry(&wb_gr[gr_cache_idx], NULL);
+
+ BAIL_ON_PTR_ERROR(*grp, wbc_status);
+
+ gr_cache_idx++;
+
+done:
+ return wbc_status;
}
/** @brief Return the unix group array belonging to the given user
diff --git a/source3/nsswitch/libwbclient/wbclient.c b/source3/nsswitch/libwbclient/wbclient.c
index bdde562a93..c0b7e0675a 100644
--- a/source3/nsswitch/libwbclient/wbclient.c
+++ b/source3/nsswitch/libwbclient/wbclient.c
@@ -59,7 +59,7 @@ wbcErr wbcRequestResponse(int cmd,
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
NSS_STATUS nss_status;
- /* for some calls the request and/or response cna be NULL */
+ /* for some calls the request and/or response can be NULL */
nss_status = winbindd_request_response(cmd, request, response);
diff --git a/source3/nsswitch/libwbclient/wbclient.h b/source3/nsswitch/libwbclient/wbclient.h
index 662e0cdf8d..cb31360407 100644
--- a/source3/nsswitch/libwbclient/wbclient.h
+++ b/source3/nsswitch/libwbclient/wbclient.h
@@ -57,9 +57,12 @@ const char *wbcErrorString(wbcErr error);
/**
* @brief Some useful details about the wbclient library
*
+ * 0.1: Initial version
+ * 0.2: Added wbcRemoveUidMapping()
+ * Added wbcRemoveGidMapping()
**/
#define WBCLIENT_MAJOR_VERSION 0
-#define WBCLIENT_MINOR_VERSION 1
+#define WBCLIENT_MINOR_VERSION 2
#define WBCLIENT_VENDOR_VERSION "Samba libwbclient"
struct wbcLibraryDetails {
uint16_t major_version;
@@ -358,7 +361,7 @@ struct wbcLogonUserInfo {
#define WBC_AUTH_USER_INFO_NOENCRYPTION 0x00000002
#define WBC_AUTH_USER_INFO_CACHED_ACCOUNT 0x00000004
#define WBC_AUTH_USER_INFO_USED_LM_PASSWORD 0x00000008
-#define WBC_AUTH_USER_INFO_EXTRA_SIDS 0x00000020
+#define WBC_AUTH_USER_INFO_EXTRA_SIDS 0x00000020
#define WBC_AUTH_USER_INFO_SUBAUTH_SESSION_KEY 0x00000040
#define WBC_AUTH_USER_INFO_SERVER_TRUST_ACCOUNT 0x00000080
#define WBC_AUTH_USER_INFO_NTLMV2_ENABLED 0x00000100
@@ -385,7 +388,7 @@ struct wbcLogonUserInfo {
#define WBC_ACB_NOT_DELEGATED 0x00004000 /* 1 Not delegated */
#define WBC_ACB_USE_DES_KEY_ONLY 0x00008000 /* 1 Use DES key only */
#define WBC_ACB_DONT_REQUIRE_PREAUTH 0x00010000 /* 1 Preauth not required */
-#define WBC_ACB_PW_EXPIRED 0x00020000 /* 1 Password Expired */
+#define WBC_ACB_PW_EXPIRED 0x00020000 /* 1 Password Expired */
#define WBC_ACB_NO_AUTH_DATA_REQD 0x00080000 /* 1 = No authorization data required */
struct wbcAuthErrorInfo {
@@ -437,6 +440,30 @@ struct wbcLogoffUserParams {
struct wbcNamedBlob *blobs;
};
+/** @brief Credential cache log-on parameters
+ *
+ */
+
+struct wbcCredentialCacheParams {
+ const char *account_name;
+ const char *domain_name;
+ enum wbcCredentialCacheLevel {
+ WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP = 1
+ } level;
+ size_t num_blobs;
+ struct wbcNamedBlob *blobs;
+};
+
+
+/** @brief Info returned by credential cache auth
+ *
+ */
+
+struct wbcCredentialCacheInfo {
+ size_t num_blobs;
+ struct wbcNamedBlob *blobs;
+};
+
/*
* DomainControllerInfo struct
*/
@@ -538,15 +565,27 @@ wbcErr wbcGetDisplayName(const struct wbcDomainSid *sid,
wbcErr wbcSidToUid(const struct wbcDomainSid *sid,
uid_t *puid);
+wbcErr wbcQuerySidToUid(const struct wbcDomainSid *sid,
+ uid_t *puid);
+
wbcErr wbcUidToSid(uid_t uid,
struct wbcDomainSid *sid);
+wbcErr wbcQueryUidToSid(uid_t uid,
+ struct wbcDomainSid *sid);
+
wbcErr wbcSidToGid(const struct wbcDomainSid *sid,
gid_t *pgid);
+wbcErr wbcQuerySidToGid(const struct wbcDomainSid *sid,
+ gid_t *pgid);
+
wbcErr wbcGidToSid(gid_t gid,
struct wbcDomainSid *sid);
+wbcErr wbcQueryGidToSid(gid_t gid,
+ struct wbcDomainSid *sid);
+
wbcErr wbcAllocateUid(uid_t *puid);
wbcErr wbcAllocateGid(gid_t *pgid);
@@ -555,6 +594,10 @@ wbcErr wbcSetUidMapping(uid_t uid, const struct wbcDomainSid *sid);
wbcErr wbcSetGidMapping(gid_t gid, const struct wbcDomainSid *sid);
+wbcErr wbcRemoveUidMapping(uid_t uid, const struct wbcDomainSid *sid);
+
+wbcErr wbcRemoveGidMapping(gid_t gid, const struct wbcDomainSid *sid);
+
wbcErr wbcSetUidHwm(uid_t uid_hwm);
wbcErr wbcSetGidHwm(gid_t gid_hwm);
@@ -583,6 +626,8 @@ wbcErr wbcEndgrent(void);
wbcErr wbcGetgrent(struct group **grp);
+wbcErr wbcGetgrlist(struct group **grp);
+
wbcErr wbcGetGroups(const char *account,
uint32_t *num_groups,
gid_t **_groups);
@@ -662,6 +707,10 @@ wbcErr wbcChangeUserPasswordEx(const struct wbcChangePasswordParams *params,
enum wbcPasswordChangeRejectReason *reject_reason,
struct wbcUserPasswordPolicyInfo **policy);
+wbcErr wbcCredentialCache(struct wbcCredentialCacheParams *params,
+ struct wbcCredentialCacheInfo **info,
+ struct wbcAuthErrorInfo **error);
+
/*
* Resolve functions
*/
diff --git a/source3/nsswitch/pam_winbind.c b/source3/nsswitch/pam_winbind.c
index 1c927259e5..be22ff3f5e 100644
--- a/source3/nsswitch/pam_winbind.c
+++ b/source3/nsswitch/pam_winbind.c
@@ -147,6 +147,21 @@ static const char *_pam_error_code_str(int err)
#define MAX_PASSWD_TRIES 3
+#ifdef HAVE_GETTEXT
+static char initialized = 0;
+
+static inline void textdomain_init(void);
+static inline void textdomain_init(void)
+{
+ if (!initialized) {
+ bindtextdomain(MODULE_NAME, dyn_LOCALEDIR);
+ initialized = 1;
+ }
+ return;
+}
+#endif
+
+
/*
* Work around the pam API that has functions with void ** as parameters
* These lead to strict aliasing warnings with gcc.
@@ -515,6 +530,10 @@ static int _pam_winbind_init_context(pam_handle_t *pamh,
{
struct pwb_context *r = NULL;
+#ifdef HAVE_GETTEXT
+ textdomain_init();
+#endif
+
r = TALLOC_ZERO_P(NULL, struct pwb_context);
if (!r) {
return PAM_BUF_ERR;
@@ -557,44 +576,44 @@ static const struct ntstatus_errors {
const char *error_string;
} ntstatus_errors[] = {
{"NT_STATUS_OK",
- "Success"},
+ N_("Success")},
{"NT_STATUS_BACKUP_CONTROLLER",
- "No primary Domain Controler available"},
+ N_("No primary Domain Controler available")},
{"NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND",
- "No domain controllers found"},
+ N_("No domain controllers found")},
{"NT_STATUS_NO_LOGON_SERVERS",
- "No logon servers"},
+ N_("No logon servers")},
{"NT_STATUS_PWD_TOO_SHORT",
- "Password too short"},
+ N_("Password too short")},
{"NT_STATUS_PWD_TOO_RECENT",
- "The password of this user is too recent to change"},
+ N_("The password of this user is too recent to change")},
{"NT_STATUS_PWD_HISTORY_CONFLICT",
- "Password is already in password history"},
+ N_("Password is already in password history")},
{"NT_STATUS_PASSWORD_EXPIRED",
- "Your password has expired"},
+ N_("Your password has expired")},
{"NT_STATUS_PASSWORD_MUST_CHANGE",
- "You need to change your password now"},
+ N_("You need to change your password now")},
{"NT_STATUS_INVALID_WORKSTATION",
- "You are not allowed to logon from this workstation"},
+ N_("You are not allowed to logon from this workstation")},
{"NT_STATUS_INVALID_LOGON_HOURS",
- "You are not allowed to logon at this time"},
+ N_("You are not allowed to logon at this time")},
{"NT_STATUS_ACCOUNT_EXPIRED",
- "Your account has expired. "
- "Please contact your System administrator"}, /* SCNR */
+ N_("Your account has expired. "
+ "Please contact your System administrator")}, /* SCNR */
{"NT_STATUS_ACCOUNT_DISABLED",
- "Your account is disabled. "
- "Please contact your System administrator"}, /* SCNR */
+ N_("Your account is disabled. "
+ "Please contact your System administrator")}, /* SCNR */
{"NT_STATUS_ACCOUNT_LOCKED_OUT",
- "Your account has been locked. "
- "Please contact your System administrator"}, /* SCNR */
+ N_("Your account has been locked. "
+ "Please contact your System administrator")}, /* SCNR */
{"NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT",
- "Invalid Trust Account"},
+ N_("Invalid Trust Account")},
{"NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT",
- "Invalid Trust Account"},
+ N_("Invalid Trust Account")},
{"NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT",
- "Invalid Trust Account"},
+ N_("Invalid Trust Account")},
{"NT_STATUS_ACCESS_DENIED",
- "Access is denied"},
+ N_("Access is denied")},
{NULL, NULL}
};
@@ -604,7 +623,7 @@ static const char *_get_ntstatus_error_string(const char *nt_status_string)
for (i=0; ntstatus_errors[i].ntstatus_string != NULL; i++) {
if (!strcasecmp(ntstatus_errors[i].ntstatus_string,
nt_status_string)) {
- return ntstatus_errors[i].error_string;
+ return _(ntstatus_errors[i].error_string);
}
}
return NULL;
@@ -832,14 +851,14 @@ static bool _pam_send_password_expiry_message(struct pwb_context *ctx,
if (days == 0) {
_make_remark(ctx, PAM_TEXT_INFO,
- "Your password expires today");
+ _("Your password expires today"));
return true;
}
if (days > 0 && days < warn_pwd_expire) {
_make_remark_format(ctx, PAM_TEXT_INFO,
- "Your password will expire in %d %s",
- days, (days > 1) ? "days":"day");
+ _("Your password will expire in %d %s"),
+ days, (days > 1) ? _("days"):_("day"));
return true;
}
@@ -1231,9 +1250,9 @@ static void _pam_warn_logon_type(struct pwb_context *ctx,
if (PAM_WB_GRACE_LOGON(info3_user_flgs)) {
_make_remark(ctx, PAM_ERROR_MSG,
- "Grace login. "
- "Please change your password as soon you're "
- "online again");
+ _("Grace login. "
+ "Please change your password as soon you're "
+ "online again"));
_pam_log_debug(ctx, LOG_DEBUG,
"User %s logged on using grace logon\n",
username);
@@ -1241,9 +1260,9 @@ static void _pam_warn_logon_type(struct pwb_context *ctx,
} else if (PAM_WB_CACHED_LOGON(info3_user_flgs)) {
_make_remark(ctx, PAM_ERROR_MSG,
- "Domain Controller unreachable, "
- "using cached credentials instead. "
- "Network resources may be unavailable");
+ _("Domain Controller unreachable, "
+ "using cached credentials instead. "
+ "Network resources may be unavailable"));
_pam_log_debug(ctx, LOG_DEBUG,
"User %s logged on using cached credentials\n",
username);
@@ -1266,10 +1285,10 @@ static void _pam_warn_krb5_failure(struct pwb_context *ctx,
{
if (PAM_WB_KRB5_CLOCK_SKEW(info3_user_flgs)) {
_make_remark(ctx, PAM_ERROR_MSG,
- "Failed to establish your Kerberos Ticket cache "
- "due time differences\n"
- "with the domain controller. "
- "Please verify the system time.\n");
+ _("Failed to establish your Kerberos Ticket cache "
+ "due time differences\n"
+ "with the domain controller. "
+ "Please verify the system time.\n"));
_pam_log_debug(ctx, LOG_DEBUG,
"User %s: Clock skew when getting Krb5 TGT\n",
username);
@@ -1334,14 +1353,14 @@ static char *_pam_compose_pwd_restriction_string(struct pwb_context *ctx,
goto failed;
}
- str = talloc_asprintf(ctx, "Your password ");
+ str = talloc_asprintf(ctx, _("Your password "));
if (!str) {
goto failed;
}
if (i->min_length_password > 0) {
str = talloc_asprintf_append(str,
- "must be at least %d characters; ",
+ _("must be at least %d characters; "),
i->min_length_password);
if (!str) {
goto failed;
@@ -1350,8 +1369,8 @@ static char *_pam_compose_pwd_restriction_string(struct pwb_context *ctx,
if (i->password_history > 0) {
str = talloc_asprintf_append(str,
- "cannot repeat any of your previous %d "
- "passwords; ",
+ _("cannot repeat any of your previous %d "
+ "passwords; "),
i->password_history);
if (!str) {
goto failed;
@@ -1360,19 +1379,19 @@ static char *_pam_compose_pwd_restriction_string(struct pwb_context *ctx,
if (i->password_properties & WBC_DOMAIN_PASSWORD_COMPLEX) {
str = talloc_asprintf_append(str,
- "must contain capitals, numerals "
- "or punctuation; "
- "and cannot contain your account "
- "or full name; ");
+ _("must contain capitals, numerals "
+ "or punctuation; "
+ "and cannot contain your account "
+ "or full name; "));
if (!str) {
goto failed;
}
}
str = talloc_asprintf_append(str,
- "Please type a different password. "
- "Type a password which meets these requirements in "
- "both text boxes.");
+ _("Please type a different password. "
+ "Type a password which meets these requirements in "
+ "both text boxes."));
if (!str) {
goto failed;
}
@@ -1397,7 +1416,7 @@ static int _pam_create_homedir(struct pwb_context *ctx,
if (mkdir(dirname, mode) != 0) {
_make_remark_format(ctx, PAM_TEXT_INFO,
- "Creating directory: %s failed: %s",
+ _("Creating directory: %s failed: %s"),
dirname, strerror(errno));
_pam_log(ctx, LOG_ERR, "could not create dir: %s (%s)",
dirname, strerror(errno));
@@ -1615,14 +1634,16 @@ static int winbind_auth_request(struct pwb_context *ctx,
logon.username = user;
logon.password = pass;
- wbc_status = wbcAddNamedBlob(&logon.num_blobs,
- &logon.blobs,
- "krb5_cc_type",
- 0,
- (uint8_t *)cctype,
- strlen(cctype)+1);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- goto done;
+ if (cctype) {
+ wbc_status = wbcAddNamedBlob(&logon.num_blobs,
+ &logon.blobs,
+ "krb5_cc_type",
+ 0,
+ (uint8_t *)cctype,
+ strlen(cctype)+1);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ goto done;
+ }
}
wbc_status = wbcAddNamedBlob(&logon.num_blobs,
@@ -1645,14 +1666,16 @@ static int winbind_auth_request(struct pwb_context *ctx,
goto done;
}
- wbc_status = wbcAddNamedBlob(&logon.num_blobs,
- &logon.blobs,
- "membership_of",
- 0,
- (uint8_t *)membership_of,
- sizeof(membership_of));
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- goto done;
+ if (member) {
+ wbc_status = wbcAddNamedBlob(&logon.num_blobs,
+ &logon.blobs,
+ "membership_of",
+ 0,
+ (uint8_t *)membership_of,
+ sizeof(membership_of));
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ goto done;
+ }
}
wbc_status = wbcLogonUser(&logon, &info, &error, &policy);
@@ -1851,8 +1874,8 @@ static int winbind_chauthtok_request(struct pwb_context *ctx,
break;
case WBC_PWD_CHANGE_REJECT_COMPLEXITY:
_make_remark(ctx, PAM_ERROR_MSG,
- "Password does not meet "
- "complexity requirements");
+ _("Password does not meet "
+ "complexity requirements"));
break;
default:
_pam_log_debug(ctx, LOG_DEBUG,
@@ -2293,7 +2316,7 @@ static int _pam_delete_cred(pam_handle_t *pamh, int flags,
struct wbcLogoffUserParams logoff;
struct wbcAuthErrorInfo *error = NULL;
const char *user;
- wbcErr wbc_status;
+ wbcErr wbc_status = WBC_ERR_SUCCESS;
retval = _pam_winbind_init_context(pamh, flags, argc, argv, &ctx);
if (retval) {
@@ -2310,7 +2333,7 @@ static int _pam_delete_cred(pam_handle_t *pamh, int flags,
const char *ccname = NULL;
struct passwd *pwd = NULL;
- retval = pam_get_user(pamh, &user, "Username: ");
+ retval = pam_get_user(pamh, &user, _("Username: "));
if (retval) {
_pam_log(ctx, LOG_ERR,
"could not identify user");
@@ -2346,14 +2369,16 @@ static int _pam_delete_cred(pam_handle_t *pamh, int flags,
logoff.username = user;
- wbc_status = wbcAddNamedBlob(&logoff.num_blobs,
- &logoff.blobs,
- "ccfilename",
- 0,
- (uint8_t *)ccname,
- strlen(ccname)+1);
- if (!WBC_ERROR_IS_OK(wbc_status)) {
- goto out;
+ if (ccname) {
+ wbc_status = wbcAddNamedBlob(&logoff.num_blobs,
+ &logoff.blobs,
+ "ccfilename",
+ 0,
+ (uint8_t *)ccname,
+ strlen(ccname)+1);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ goto out;
+ }
}
wbc_status = wbcAddNamedBlob(&logoff.num_blobs,
@@ -2485,7 +2510,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
}
retval = _winbind_read_password(ctx, ctx->ctrl, NULL,
- "Password: ", NULL,
+ _("Password: "), NULL,
&password);
if (retval != PAM_SUCCESS) {
@@ -2855,7 +2880,7 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
/*
* First get the name of a user
*/
- ret = pam_get_user(pamh, &user, "Username: ");
+ ret = pam_get_user(pamh, &user, _("Username: "));
if (ret) {
_pam_log(ctx, LOG_ERR,
"password - could not identify user");
@@ -2893,7 +2918,7 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
/* instruct user what is happening */
-#define greeting "Changing password for"
+#define greeting _("Changing password for")
Announce = talloc_asprintf(ctx, "%s %s", greeting, user);
if (!Announce) {
_pam_log(ctx, LOG_CRIT,
@@ -2906,7 +2931,7 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
lctrl = ctx->ctrl | WINBIND__OLD_PASSWORD;
ret = _winbind_read_password(ctx, lctrl,
Announce,
- "(current) NT password: ",
+ _("(current) NT password: "),
NULL,
(const char **) &pass_old);
TALLOC_FREE(Announce);
@@ -2976,8 +3001,8 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
ret = _winbind_read_password(ctx, lctrl,
NULL,
- "Enter new NT password: ",
- "Retype new NT password: ",
+ _("Enter new NT password: "),
+ _("Retype new NT password: "),
(const char **)&pass_new);
if (ret != PAM_SUCCESS) {
diff --git a/source3/nsswitch/pam_winbind.h b/source3/nsswitch/pam_winbind.h
index cb6f450ccb..0656f5972e 100644
--- a/source3/nsswitch/pam_winbind.h
+++ b/source3/nsswitch/pam_winbind.h
@@ -9,6 +9,7 @@
#include "system/time.h"
#include <talloc.h>
#include "libwbclient/wbclient.h"
+#include "localedir.h"
#define MODULE_NAME "pam_winbind"
#define PAM_SM_AUTH
@@ -22,6 +23,10 @@
#include <iniparser.h>
+#ifdef HAVE_LIBINTL_H
+#include <libintl.h>
+#endif
+
#ifndef LINUX
/* Solaris always uses dynamic pam modules */
@@ -101,12 +106,20 @@ do { \
#define WINBIND_WARN_PWD_EXPIRE 0x00002000
#define WINBIND_MKHOMEDIR 0x00004000
+#if defined(HAVE_GETTEXT) && !defined(__LCLINT__)
+#define _(string) dgettext(MODULE_NAME, string)
+#else
+#define _(string) string
+#endif
+
+#define N_(string) string
+
/*
* here is the string to inform the user that the new passwords they
* typed were not the same.
*/
-#define MISTYPED_PASS "Sorry, passwords do not match"
+#define MISTYPED_PASS _("Sorry, passwords do not match")
#define on(x, y) (x & y)
#define off(x, y) (!(x & y))
diff --git a/source3/nsswitch/wb_common.c b/source3/nsswitch/wb_common.c
index 6e6d2bbbf8..a1646215bd 100644
--- a/source3/nsswitch/wb_common.c
+++ b/source3/nsswitch/wb_common.c
@@ -314,7 +314,7 @@ static int winbind_open_pipe_sock(int recursing, int need_priv)
if ((need_priv != 0) && (is_privileged == 0)) {
winbind_close_sock();
}
-
+
if (winbindd_fd != -1) {
return winbindd_fd;
}
diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c
index 84f01e19ff..d14cfe94b7 100644
--- a/source3/nsswitch/wbinfo.c
+++ b/source3/nsswitch/wbinfo.c
@@ -75,7 +75,7 @@ static char winbind_separator_int(bool strict)
/* HACK: (this module should not call lp_ funtions) */
sep = *lp_winbind_separator();
}
-
+
return sep;
}
@@ -130,6 +130,31 @@ static bool parse_wbinfo_domain_user(const char *domuser, fstring domain,
return true;
}
+/* Parse string of "uid,sid" or "gid,sid" into separate int and string values.
+ * Return true if input was valid, false otherwise. */
+static bool parse_mapping_arg(char *arg, int *id, char **sid)
+{
+ char *tmp, *endptr;
+
+ if (!arg || !*arg)
+ return false;
+
+ tmp = strtok(arg, ",");
+ *sid = strtok(NULL, ",");
+
+ if (!tmp || !*tmp || !*sid || !**sid)
+ return false;
+
+ /* Because atoi() can return 0 on invalid input, which would be a valid
+ * UID/GID we must use strtol() and do error checking */
+ *id = strtol(tmp, &endptr, 10);
+
+ if (endptr[0] != '\0')
+ return false;
+
+ return true;
+}
+
/* pull pwent info for a given user */
static bool wbinfo_get_userinfo(char *user)
@@ -738,6 +763,102 @@ static bool wbinfo_allocate_gid(void)
return true;
}
+static bool wbinfo_set_uid_mapping(uid_t uid, const char *sid_str)
+{
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ struct wbcDomainSid sid;
+
+ /* Send request */
+
+ wbc_status = wbcStringToSid(sid_str, &sid);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return false;
+ }
+
+ wbc_status = wbcSetUidMapping(uid, &sid);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return false;
+ }
+
+ /* Display response */
+
+ d_printf("uid %d now mapped to sid %s\n", uid, sid_str);
+
+ return true;
+}
+
+static bool wbinfo_set_gid_mapping(gid_t gid, const char *sid_str)
+{
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ struct wbcDomainSid sid;
+
+ /* Send request */
+
+ wbc_status = wbcStringToSid(sid_str, &sid);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return false;
+ }
+
+ wbc_status = wbcSetGidMapping(gid, &sid);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return false;
+ }
+
+ /* Display response */
+
+ d_printf("gid %d now mapped to sid %s\n", gid, sid_str);
+
+ return true;
+}
+
+static bool wbinfo_remove_uid_mapping(uid_t uid, const char *sid_str)
+{
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ struct wbcDomainSid sid;
+
+ /* Send request */
+
+ wbc_status = wbcStringToSid(sid_str, &sid);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return false;
+ }
+
+ wbc_status = wbcRemoveUidMapping(uid, &sid);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return false;
+ }
+
+ /* Display response */
+
+ d_printf("Removed uid %d to sid %s mapping\n", uid, sid_str);
+
+ return true;
+}
+
+static bool wbinfo_remove_gid_mapping(gid_t gid, const char *sid_str)
+{
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ struct wbcDomainSid sid;
+
+ /* Send request */
+
+ wbc_status = wbcStringToSid(sid_str, &sid);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return false;
+ }
+
+ wbc_status = wbcRemoveGidMapping(gid, &sid);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return false;
+ }
+
+ /* Display response */
+
+ d_printf("Removed gid %d to sid %s mapping\n", gid, sid_str);
+
+ return true;
+}
+
/* Convert sid to string */
static bool wbinfo_lookupsid(const char *sid_str)
@@ -1414,6 +1535,10 @@ enum {
OPT_USERSIDS,
OPT_ALLOCATE_UID,
OPT_ALLOCATE_GID,
+ OPT_SET_UID_MAPPING,
+ OPT_SET_GID_MAPPING,
+ OPT_REMOVE_UID_MAPPING,
+ OPT_REMOVE_GID_MAPPING,
OPT_SEPARATOR,
OPT_LIST_ALL_DOMAINS,
OPT_LIST_OWN_DOMAIN,
@@ -1431,8 +1556,10 @@ int main(int argc, char **argv, char **envp)
TALLOC_CTX *frame = talloc_stackframe();
poptContext pc;
static char *string_arg;
+ char *string_subarg = NULL;
static char *opt_domain_name;
static int int_arg;
+ int int_subarg = -1;
int result = 1;
bool verbose = false;
@@ -1459,6 +1586,10 @@ int main(int argc, char **argv, char **envp)
"Get a new UID out of idmap" },
{ "allocate-gid", 0, POPT_ARG_NONE, 0, OPT_ALLOCATE_GID,
"Get a new GID out of idmap" },
+ { "set-uid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_SET_UID_MAPPING, "Create or modify uid to sid mapping in idmap", "UID,SID" },
+ { "set-gid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_SET_GID_MAPPING, "Create or modify gid to sid mapping in idmap", "GID,SID" },
+ { "remove-uid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_REMOVE_UID_MAPPING, "Remove uid to sid mapping in idmap", "UID,SID" },
+ { "remove-gid-mapping", 0, POPT_ARG_STRING, &string_arg, OPT_REMOVE_GID_MAPPING, "Remove gid to sid mapping in idmap", "GID,SID" },
{ "check-secret", 't', POPT_ARG_NONE, 0, 't', "Check shared secret" },
{ "trusted-domains", 'm', POPT_ARG_NONE, 0, 'm', "List trusted domains" },
{ "all-domains", 0, POPT_ARG_NONE, 0, OPT_LIST_ALL_DOMAINS, "List all domains (trusted and own domain)" },
@@ -1473,7 +1604,7 @@ int main(int argc, char **argv, char **envp)
{ "user-domgroups", 0, POPT_ARG_STRING, &string_arg,
OPT_USERDOMGROUPS, "Get user domain groups", "SID" },
{ "user-sids", 0, POPT_ARG_STRING, &string_arg, OPT_USERSIDS, "Get user group sids for user SID", "SID" },
- { "authenticate", 'a', POPT_ARG_STRING, &string_arg, 'a', "authenticate user", "user%password" },
+ { "authenticate", 'a', POPT_ARG_STRING, &string_arg, 'a', "authenticate user", "user%password" },
{ "set-auth-user", 0, POPT_ARG_STRING, &string_arg, OPT_SET_AUTH_USER, "Store user and password used by winbindd (root only)", "user%password" },
{ "getdcname", 0, POPT_ARG_STRING, &string_arg, OPT_GETDCNAME,
"Get a DC name for a foreign domain", "domainname" },
@@ -1482,7 +1613,7 @@ int main(int argc, char **argv, char **envp)
{ "ping", 'p', POPT_ARG_NONE, 0, 'p', "Ping winbindd to see if it is alive" },
{ "domain", 0, POPT_ARG_STRING, &opt_domain_name, OPT_DOMAIN_NAME, "Define to the domain to restrict operation", "domain" },
#ifdef WITH_FAKE_KASERVER
- { "klog", 'k', POPT_ARG_STRING, &string_arg, 'k', "set an AFS token from winbind", "user%password" },
+ { "klog", 'k', POPT_ARG_STRING, &string_arg, 'k', "set an AFS token from winbind", "user%password" },
#endif
#ifdef HAVE_KRB5
{ "krb5auth", 'K', POPT_ARG_STRING, &string_arg, 'K', "authenticate user using Kerberos", "user%password" },
@@ -1534,7 +1665,7 @@ int main(int argc, char **argv, char **envp)
load_interfaces();
- pc = poptGetContext(NULL, argc, (const char **)argv, long_options,
+ pc = poptGetContext(NULL, argc, (const char **)argv, long_options,
POPT_CONTEXT_KEEP_FIRST);
while((opt = poptGetNextOpt(pc)) != -1) {
@@ -1627,6 +1758,48 @@ int main(int argc, char **argv, char **envp)
goto done;
}
break;
+ case OPT_SET_UID_MAPPING:
+ if (!parse_mapping_arg(string_arg, &int_subarg,
+ &string_subarg) ||
+ !wbinfo_set_uid_mapping(int_subarg, string_subarg))
+ {
+ d_fprintf(stderr, "Could not create or modify "
+ "uid to sid mapping\n");
+ goto done;
+ }
+ break;
+ case OPT_SET_GID_MAPPING:
+ if (!parse_mapping_arg(string_arg, &int_subarg,
+ &string_subarg) ||
+ !wbinfo_set_gid_mapping(int_subarg, string_subarg))
+ {
+ d_fprintf(stderr, "Could not create or modify "
+ "gid to sid mapping\n");
+ goto done;
+ }
+ break;
+ case OPT_REMOVE_UID_MAPPING:
+ if (!parse_mapping_arg(string_arg, &int_subarg,
+ &string_subarg) ||
+ !wbinfo_remove_uid_mapping(int_subarg,
+ string_subarg))
+ {
+ d_fprintf(stderr, "Could not remove uid to sid "
+ "mapping\n");
+ goto done;
+ }
+ break;
+ case OPT_REMOVE_GID_MAPPING:
+ if (!parse_mapping_arg(string_arg, &int_subarg,
+ &string_subarg) ||
+ !wbinfo_remove_gid_mapping(int_subarg,
+ string_subarg))
+ {
+ d_fprintf(stderr, "Could not remove gid to sid "
+ "mapping\n");
+ goto done;
+ }
+ break;
case 't':
if (!wbinfo_check_secret()) {
d_fprintf(stderr, "Could not check secret\n");
diff --git a/source3/nsswitch/winbind_struct_protocol.h b/source3/nsswitch/winbind_struct_protocol.h
index ff52dbddaf..36873f2096 100644
--- a/source3/nsswitch/winbind_struct_protocol.h
+++ b/source3/nsswitch/winbind_struct_protocol.h
@@ -41,7 +41,9 @@
/* Update this when you change the interface. */
-#define WINBIND_INTERFACE_VERSION 19
+/* Version 20: added WINBINDD_REMOVE_MAPPING command */
+
+#define WINBIND_INTERFACE_VERSION 20
/* Have to deal with time_t being 4 or 8 bytes due to structure alignment.
On a 64bit Linux box, we have to support a constant structure size
@@ -95,7 +97,7 @@ enum winbindd_cmd {
/* Lookup functions */
- WINBINDD_SID_TO_UID,
+ WINBINDD_SID_TO_UID,
WINBINDD_SID_TO_GID,
WINBINDD_SIDS_TO_XIDS,
WINBINDD_UID_TO_SID,
@@ -104,6 +106,7 @@ enum winbindd_cmd {
WINBINDD_ALLOCATE_UID,
WINBINDD_ALLOCATE_GID,
WINBINDD_SET_MAPPING,
+ WINBINDD_REMOVE_MAPPING,
WINBINDD_SET_HWM,
/* Miscellaneous other stuff */
@@ -150,6 +153,7 @@ enum winbindd_cmd {
WINBINDD_DUAL_UID2SID,
WINBINDD_DUAL_GID2SID,
WINBINDD_DUAL_SET_MAPPING,
+ WINBINDD_DUAL_REMOVE_MAPPING,
WINBINDD_DUAL_SET_HWM,
/* Wrapper around possibly blocking unix nss calls */
@@ -202,7 +206,9 @@ typedef struct winbindd_gr {
#define WBFLAG_IS_PRIVILEGED 0x00000400 /* not used */
/* Flag to say this is a winbindd internal send - don't recurse. */
#define WBFLAG_RECURSE 0x00000800
-
+/* Flag to tell winbind the NTLMv2 blob is too big for the struct and is in the
+ * extra_data field */
+#define WBFLAG_BIG_NTLMV2_BLOB 0x00010000
#define WINBINDD_MAX_EXTRA_DATA (128*1024)
diff --git a/source3/nsswitch/wins.c b/source3/nsswitch/wins.c
index 2f82997aaf..e028eb8cf2 100644
--- a/source3/nsswitch/wins.c
+++ b/source3/nsswitch/wins.c
@@ -24,6 +24,14 @@
#include <ns_daemon.h>
#endif
+#if HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+
+#if HAVE_PTHREAD
+static pthread_mutex_t wins_nss_mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
+
#ifndef INADDRSZ
#define INADDRSZ 4
#endif
@@ -320,11 +328,16 @@ NSS_STATUS
_nss_wins_gethostbyname_r(const char *hostname, struct hostent *he,
char *buffer, size_t buflen, int *h_errnop)
{
+ NSS_STATUS nss_status = NSS_STATUS_SUCCESS;
struct in_addr *ip_list;
int i, count;
fstring name;
size_t namelen;
+#if HAVE_PTHREAD
+ pthread_mutex_lock(&wins_nss_mutex);
+#endif
+
memset(he, '\0', sizeof(*he));
fstrcpy(name, hostname);
@@ -332,8 +345,10 @@ _nss_wins_gethostbyname_r(const char *hostname, struct hostent *he,
ip_list = lookup_byname_backend(name, &count);
- if (!ip_list)
- return NSS_STATUS_NOTFOUND;
+ if (!ip_list) {
+ nss_status = NSS_STATUS_NOTFOUND;
+ goto out;
+ }
/* Copy h_name */
@@ -341,7 +356,8 @@ _nss_wins_gethostbyname_r(const char *hostname, struct hostent *he,
if ((he->h_name = get_static(&buffer, &buflen, namelen)) == NULL) {
free(ip_list);
- return NSS_STATUS_TRYAGAIN;
+ nss_status = NSS_STATUS_TRYAGAIN;
+ goto out;
}
memcpy(he->h_name, name, namelen);
@@ -353,20 +369,23 @@ _nss_wins_gethostbyname_r(const char *hostname, struct hostent *he,
if (get_static(&buffer, &buflen, i) == NULL) {
free(ip_list);
- return NSS_STATUS_TRYAGAIN;
+ nss_status = NSS_STATUS_TRYAGAIN;
+ goto out;
}
if ((he->h_addr_list = (char **)get_static(
&buffer, &buflen, (count + 1) * sizeof(char *))) == NULL) {
free(ip_list);
- return NSS_STATUS_TRYAGAIN;
+ nss_status = NSS_STATUS_TRYAGAIN;
+ goto out;
}
for (i = 0; i < count; i++) {
if ((he->h_addr_list[i] = get_static(&buffer, &buflen,
INADDRSZ)) == NULL) {
free(ip_list);
- return NSS_STATUS_TRYAGAIN;
+ nss_status = NSS_STATUS_TRYAGAIN;
+ goto out;
}
memcpy(he->h_addr_list[i], &ip_list[i], INADDRSZ);
}
@@ -385,16 +404,27 @@ _nss_wins_gethostbyname_r(const char *hostname, struct hostent *he,
if ((i = (unsigned long)(buffer) % sizeof(char*)) != 0)
i = sizeof(char*) - i;
- if (get_static(&buffer, &buflen, i) == NULL)
- return NSS_STATUS_TRYAGAIN;
+ if (get_static(&buffer, &buflen, i) == NULL) {
+ nss_status = NSS_STATUS_TRYAGAIN;
+ goto out;
+ }
if ((he->h_aliases = (char **)get_static(
- &buffer, &buflen, sizeof(char *))) == NULL)
- return NSS_STATUS_TRYAGAIN;
+ &buffer, &buflen, sizeof(char *))) == NULL) {
+ nss_status = NSS_STATUS_TRYAGAIN;
+ goto out;
+ }
he->h_aliases[0] = NULL;
- return NSS_STATUS_SUCCESS;
+ nss_status = NSS_STATUS_SUCCESS;
+
+ out:
+
+#if HAVE_PTHREAD
+ pthread_mutex_unlock(&wins_nss_mutex);
+#endif
+ return nss_status;
}
@@ -402,12 +432,15 @@ NSS_STATUS
_nss_wins_gethostbyname2_r(const char *name, int af, struct hostent *he,
char *buffer, size_t buflen, int *h_errnop)
{
+ NSS_STATUS nss_status;
+
if(af!=AF_INET) {
*h_errnop = NO_DATA;
- return NSS_STATUS_UNAVAIL;
+ nss_status = NSS_STATUS_UNAVAIL;
+ } else {
+ nss_status = _nss_wins_gethostbyname_r(
+ name, he, buffer, buflen, h_errnop);
}
-
- return _nss_wins_gethostbyname_r(
- name, he, buffer, buflen, h_errnop);
+ return nss_status;
}
#endif
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 84f6fb907a..217957ab37 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -4899,7 +4899,7 @@ static void init_globals(bool first_time_only)
Globals.bWinbindTrustedDomainsOnly = False;
Globals.bWinbindNestedGroups = True;
Globals.winbind_expand_groups = 1;
- Globals.szWinbindNssInfo = str_list_make(NULL, "template", NULL);
+ Globals.szWinbindNssInfo = str_list_make_v3(talloc_autofree_context(), "template", NULL);
Globals.bWinbindRefreshTickets = False;
Globals.bWinbindOfflineLogon = False;
@@ -5615,7 +5615,7 @@ const char **lp_parm_string_list(int snum, const char *type, const char *option,
return (const char **)def;
if (data->list==NULL) {
- data->list = str_list_make(NULL, data->value, NULL);
+ data->list = str_list_make_v3(talloc_autofree_context(), data->value, NULL);
}
return (const char **)data->list;
@@ -6859,7 +6859,7 @@ static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
{
TALLOC_FREE(Globals.szNetbiosAliases);
- Globals.szNetbiosAliases = str_list_make(NULL, pszParmValue, NULL);
+ Globals.szNetbiosAliases = str_list_make_v3(talloc_autofree_context(), pszParmValue, NULL);
return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
}
@@ -7261,8 +7261,8 @@ bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
case P_LIST:
TALLOC_FREE(*((char ***)parm_ptr));
- *(char ***)parm_ptr = str_list_make(
- NULL, pszParmValue, NULL);
+ *(char ***)parm_ptr = str_list_make_v3(
+ talloc_autofree_context(), pszParmValue, NULL);
break;
case P_STRING:
diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c
index 60699615f0..8367d6a9ad 100644
--- a/source3/passdb/passdb.c
+++ b/source3/passdb/passdb.c
@@ -665,7 +665,7 @@ NTSTATUS local_password_change(const char *user_name,
DEBUGLEVEL = 1;
}
- if ( !(pwd = getpwnam_alloc( NULL, user_name)) ) {
+ if ( !(pwd = getpwnam_alloc(talloc_autofree_context(), user_name)) ) {
return NT_STATUS_NO_SUCH_USER;
}
diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c
index 2a1024cc56..5a79f09db0 100644
--- a/source3/passdb/pdb_interface.c
+++ b/source3/passdb/pdb_interface.c
@@ -207,28 +207,28 @@ static struct pdb_methods *pdb_get_methods(void)
bool pdb_getsampwnam(struct samu *sam_acct, const char *username)
{
struct pdb_methods *pdb = pdb_get_methods();
- struct samu *cache_copy;
+ struct samu *for_cache;
const struct dom_sid *user_sid;
if (!NT_STATUS_IS_OK(pdb->getsampwnam(pdb, sam_acct, username))) {
return False;
}
- cache_copy = samu_new(NULL);
- if (cache_copy == NULL) {
+ for_cache = samu_new(NULL);
+ if (for_cache == NULL) {
return False;
}
- if (!pdb_copy_sam_account(cache_copy, sam_acct)) {
- TALLOC_FREE(cache_copy);
+ if (!pdb_copy_sam_account(for_cache, sam_acct)) {
+ TALLOC_FREE(for_cache);
return False;
}
- user_sid = pdb_get_user_sid(cache_copy);
+ user_sid = pdb_get_user_sid(for_cache);
memcache_add_talloc(NULL, PDB_GETPWSID_CACHE,
data_blob_const(user_sid, sizeof(*user_sid)),
- cache_copy);
+ &for_cache);
return True;
}
@@ -242,7 +242,7 @@ bool guest_user_info( struct samu *user )
NTSTATUS result;
const char *guestname = lp_guestaccount();
- if ( !(pwd = getpwnam_alloc( NULL, guestname ) ) ) {
+ if ( !(pwd = getpwnam_alloc(talloc_autofree_context(), guestname ) ) ) {
DEBUG(0,("guest_user_info: Unable to locate guest account [%s]!\n",
guestname));
return False;
@@ -1150,7 +1150,9 @@ static NTSTATUS pdb_default_rename_sam_account (struct pdb_methods *methods, str
static NTSTATUS pdb_default_update_login_attempts (struct pdb_methods *methods, struct samu *newpwd, bool success)
{
- return NT_STATUS_NOT_IMPLEMENTED;
+ /* Only the pdb_nds backend implements this, by
+ * default just return ok. */
+ return NT_STATUS_OK;
}
static NTSTATUS pdb_default_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value)
@@ -2014,7 +2016,7 @@ NTSTATUS make_pdb_method( struct pdb_methods **methods )
{
/* allocate memory for the structure as its own talloc CTX */
- if ( !(*methods = TALLOC_ZERO_P(NULL, struct pdb_methods) ) ) {
+ if ( !(*methods = TALLOC_ZERO_P(talloc_autofree_context(), struct pdb_methods) ) ) {
return NT_STATUS_NO_MEMORY;
}
diff --git a/source3/passdb/util_unixsids.c b/source3/passdb/util_unixsids.c
index 1b674d02a2..ad4e70256d 100644
--- a/source3/passdb/util_unixsids.c
+++ b/source3/passdb/util_unixsids.c
@@ -56,7 +56,7 @@ bool lookup_unix_user_name(const char *name, DOM_SID *sid)
{
struct passwd *pwd;
- pwd = getpwnam_alloc(NULL, name);
+ pwd = getpwnam_alloc(talloc_autofree_context(), name);
if (pwd == NULL) {
return False;
}
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index 11370272a2..244b3aee03 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -1454,18 +1454,21 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
/****************************************************************************
Determine the correct cVersion associated with an architecture and driver
****************************************************************************/
-static uint32 get_correct_cversion(const char *architecture, fstring driverpath_in,
- struct current_user *user, WERROR *perr)
+static uint32 get_correct_cversion(struct pipes_struct *p,
+ const char *architecture,
+ fstring driverpath_in,
+ WERROR *perr)
{
int cversion;
NTSTATUS nt_status;
char *driverpath = NULL;
- DATA_BLOB null_pw;
- fstring res_type;
files_struct *fsp = NULL;
SMB_STRUCT_STAT st;
- connection_struct *conn;
+ connection_struct *conn = NULL;
NTSTATUS status;
+ char *oldcwd;
+ fstring printdollar;
+ int printdollar_snum;
SET_STAT_INVALID(st);
@@ -1485,28 +1488,21 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
return 3;
}
- /*
- * Connect to the print$ share under the same account as the user connected
- * to the rpc pipe. Note we must still be root to do this.
- */
-
- /* Null password is ok - we are already an authenticated user... */
- null_pw = data_blob_null;
- fstrcpy(res_type, "A:");
- become_root();
- conn = make_connection_with_chdir("print$", null_pw, res_type, user->vuid, &nt_status);
- unbecome_root();
+ fstrcpy(printdollar, "print$");
- if (conn == NULL) {
- DEBUG(0,("get_correct_cversion: Unable to connect\n"));
- *perr = ntstatus_to_werror(nt_status);
+ printdollar_snum = find_service(printdollar);
+ if (printdollar_snum == -1) {
+ *perr = WERR_NO_SUCH_SHARE;
return -1;
}
- /* We are temporarily becoming the connection user. */
- if (!become_user(conn, user->vuid)) {
- DEBUG(0,("get_correct_cversion: Can't become user!\n"));
- *perr = WERR_ACCESS_DENIED;
+ nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
+ lp_pathname(printdollar_snum),
+ p->server_info, &oldcwd);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(0,("get_correct_cversion: create_conn_struct "
+ "returned %s\n", nt_errstr(nt_status)));
+ *perr = ntstatus_to_werror(nt_status);
return -1;
}
@@ -1583,27 +1579,28 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
driverpath, cversion));
- close_file(NULL, fsp, NORMAL_CLOSE);
- close_cnum(conn, user->vuid);
- unbecome_user();
- *perr = WERR_OK;
- return cversion;
-
-
- error_exit:
+ goto done;
- if(fsp)
+ error_exit:
+ cversion = -1;
+ done:
+ if (fsp != NULL) {
close_file(NULL, fsp, NORMAL_CLOSE);
-
- close_cnum(conn, user->vuid);
- unbecome_user();
- return -1;
+ }
+ if (conn != NULL) {
+ vfs_ChDir(conn, oldcwd);
+ conn_free_internal(conn);
+ }
+ if (cversion != -1) {
+ *perr = WERR_OK;
+ }
+ return cversion;
}
/****************************************************************************
****************************************************************************/
-static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver,
- struct current_user *user)
+static WERROR clean_up_driver_struct_level_3(struct pipes_struct *rpc_pipe,
+ NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
{
const char *architecture;
fstring new_name;
@@ -1661,7 +1658,9 @@ static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dri
* NT 4: cversion=2
* NT2K: cversion=3
*/
- if ((driver->cversion = get_correct_cversion( architecture, driver->driverpath, user, &err)) == -1)
+ if ((driver->cversion = get_correct_cversion(rpc_pipe, architecture,
+ driver->driverpath,
+ &err)) == -1)
return err;
return WERR_OK;
@@ -1669,7 +1668,8 @@ static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dri
/****************************************************************************
****************************************************************************/
-static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver, struct current_user *user)
+static WERROR clean_up_driver_struct_level_6(struct pipes_struct *rpc_pipe,
+ NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
{
const char *architecture;
fstring new_name;
@@ -1728,7 +1728,9 @@ static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *dri
* NT2K: cversion=3
*/
- if ((driver->version = get_correct_cversion(architecture, driver->driverpath, user, &err)) == -1)
+ if ((driver->version = get_correct_cversion(rpc_pipe, architecture,
+ driver->driverpath,
+ &err)) == -1)
return err;
return WERR_OK;
@@ -1736,21 +1738,24 @@ static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *dri
/****************************************************************************
****************************************************************************/
-WERROR clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
- uint32 level, struct current_user *user)
+WERROR clean_up_driver_struct(struct pipes_struct *rpc_pipe,
+ NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
+ uint32 level)
{
switch (level) {
case 3:
{
NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
driver=driver_abstract.info_3;
- return clean_up_driver_struct_level_3(driver, user);
+ return clean_up_driver_struct_level_3(rpc_pipe,
+ driver);
}
case 6:
{
NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
driver=driver_abstract.info_6;
- return clean_up_driver_struct_level_6(driver, user);
+ return clean_up_driver_struct_level_6(rpc_pipe,
+ driver);
}
default:
return WERR_INVALID_PARAM;
@@ -1796,8 +1801,9 @@ static char* ffmt(unsigned char *c){
/****************************************************************************
****************************************************************************/
-WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level,
- struct current_user *user, WERROR *perr)
+WERROR move_driver_to_download_area(struct pipes_struct *p,
+ NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
+ uint32 level, WERROR *perr)
{
NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
@@ -1805,14 +1811,15 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
char *new_dir = NULL;
char *old_name = NULL;
char *new_name = NULL;
- DATA_BLOB null_pw;
- connection_struct *conn;
+ connection_struct *conn = NULL;
NTSTATUS nt_status;
- fstring res_type;
SMB_STRUCT_STAT st;
int i;
TALLOC_CTX *ctx = talloc_tos();
int ver = 0;
+ char *oldcwd;
+ fstring printdollar;
+ int printdollar_snum;
*perr = WERR_OK;
@@ -1831,38 +1838,24 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
return WERR_UNKNOWN_PRINTER_DRIVER;
}
- /*
- * Connect to the print$ share under the same account as the user connected to the rpc pipe.
- * Note we must be root to do this.
- */
-
- null_pw = data_blob_null;
- fstrcpy(res_type, "A:");
- become_root();
- conn = make_connection_with_chdir("print$", null_pw, res_type, user->vuid, &nt_status);
- unbecome_root();
+ fstrcpy(printdollar, "print$");
- if (conn == NULL) {
- DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
- *perr = ntstatus_to_werror(nt_status);
+ printdollar_snum = find_service(printdollar);
+ if (printdollar_snum == -1) {
+ *perr = WERR_NO_SUCH_SHARE;
return WERR_NO_SUCH_SHARE;
}
- /*
- * Save who we are - we are temporarily becoming the connection user.
- */
-
- if (!become_user(conn, conn->vuid)) {
- DEBUG(0,("move_driver_to_download_area: Can't become user!\n"));
- return WERR_ACCESS_DENIED;
+ nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
+ lp_pathname(printdollar_snum),
+ p->server_info, &oldcwd);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(0,("move_driver_to_download_area: create_conn_struct "
+ "returned %s\n", nt_errstr(nt_status)));
+ *perr = ntstatus_to_werror(nt_status);
+ return *perr;
}
- /* WE ARE NOW RUNNING AS USER conn->vuid !!!!! */
-
- /*
- * make the directories version and version\driver_name
- * under the architecture directory.
- */
DEBUG(5,("Creating first directory\n"));
new_dir = talloc_asprintf(ctx,
"%s/%d",
@@ -2092,8 +2085,10 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
err_exit:
- close_cnum(conn, user->vuid);
- unbecome_user();
+ if (conn != NULL) {
+ vfs_ChDir(conn, oldcwd);
+ conn_free_internal(conn);
+ }
if (W_ERROR_EQUAL(*perr, WERR_OK)) {
return WERR_OK;
@@ -5201,49 +5196,44 @@ bool printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
this.
****************************************************************************/
-static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct current_user *user )
+static bool delete_driver_files(struct pipes_struct *rpc_pipe,
+ NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3)
{
int i = 0;
char *s;
const char *file;
connection_struct *conn;
- DATA_BLOB null_pw;
NTSTATUS nt_status;
- fstring res_type;
SMB_STRUCT_STAT st;
+ char *oldcwd;
+ fstring printdollar;
+ int printdollar_snum;
+ bool ret = false;
if ( !info_3 )
return False;
DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n", info_3->name, info_3->cversion));
- /*
- * Connect to the print$ share under the same account as the
- * user connected to the rpc pipe. Note we must be root to
- * do this.
- */
+ fstrcpy(printdollar, "print$");
- null_pw = data_blob_null;
- fstrcpy(res_type, "A:");
- become_root();
- conn = make_connection_with_chdir( "print$", null_pw, res_type, user->vuid, &nt_status );
- unbecome_root();
+ printdollar_snum = find_service(printdollar);
+ if (printdollar_snum == -1) {
+ return false;
+ }
- if ( !conn ) {
- DEBUG(0,("delete_driver_files: Unable to connect\n"));
- return False;
+ nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
+ lp_pathname(printdollar_snum),
+ rpc_pipe->server_info, &oldcwd);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(0,("delete_driver_files: create_conn_struct "
+ "returned %s\n", nt_errstr(nt_status)));
+ return false;
}
if ( !CAN_WRITE(conn) ) {
DEBUG(3,("delete_driver_files: Cannot delete print driver when [print$] is read-only\n"));
- return False;
- }
-
- /* Save who we are - we are temporarily becoming the connection user. */
-
- if ( !become_user(conn, conn->vuid) ) {
- DEBUG(0,("delete_driver_files: Can't become user!\n"));
- return False;
+ goto fail;
}
/* now delete the files; must strip the '\print$' string from
@@ -5304,9 +5294,15 @@ static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
}
}
- unbecome_user();
-
- return true;
+ goto done;
+ fail:
+ ret = false;
+ done:
+ if (conn != NULL) {
+ vfs_ChDir(conn, oldcwd);
+ conn_free_internal(conn);
+ }
+ return ret;
}
/****************************************************************************
@@ -5314,8 +5310,9 @@ static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
previously looked up.
***************************************************************************/
-WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct current_user *user,
- uint32 version, bool delete_files )
+WERROR delete_printer_driver(struct pipes_struct *rpc_pipe,
+ NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3,
+ uint32 version, bool delete_files )
{
char *key = NULL;
const char *arch;
@@ -5365,7 +5362,7 @@ WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct cur
*/
if ( delete_files )
- delete_driver_files( info_3, user );
+ delete_driver_files(rpc_pipe, info_3);
DEBUG(5,("delete_printer_driver: driver delete successful [%s]\n", key));
SAFE_FREE(key);
diff --git a/source3/printing/printfsp.c b/source3/printing/printfsp.c
index a247cd8427..5481d95650 100644
--- a/source3/printing/printfsp.c
+++ b/source3/printing/printfsp.c
@@ -27,19 +27,13 @@ print_job_start().
NTSTATUS print_fsp_open(struct smb_request *req, connection_struct *conn,
const char *fname,
- uint16_t current_vuid, files_struct **result)
+ uint16_t current_vuid, files_struct *fsp)
{
int jobid;
SMB_STRUCT_STAT sbuf;
- files_struct *fsp;
fstring name;
NTSTATUS status;
- status = file_new(req, conn, &fsp);
- if(!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
fstrcpy( name, "Remote Downlevel Document");
if (fname) {
const char *p = strrchr(fname, '/');
@@ -53,7 +47,6 @@ NTSTATUS print_fsp_open(struct smb_request *req, connection_struct *conn,
jobid = print_job_start(conn->server_info, SNUM(conn), name, NULL);
if (jobid == -1) {
status = map_nt_error_from_unix(errno);
- file_free(req, fsp);
return status;
}
@@ -62,7 +55,6 @@ NTSTATUS print_fsp_open(struct smb_request *req, connection_struct *conn,
if (fsp->rap_print_jobid == 0) {
/* We need to delete the entry in the tdb. */
pjob_delete(lp_const_servicename(SNUM(conn)), jobid);
- file_free(req, fsp);
return NT_STATUS_ACCESS_DENIED; /* No errno around here */
}
@@ -81,14 +73,11 @@ NTSTATUS print_fsp_open(struct smb_request *req, connection_struct *conn,
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;
+ fsp->wcp = NULL;
SMB_VFS_FSTAT(fsp, &sbuf);
fsp->mode = sbuf.st_mode;
fsp->file_id = vfs_file_id_from_sbuf(conn, &sbuf);
- conn->num_files_open++;
-
- *result = fsp;
return NT_STATUS_OK;
}
diff --git a/source3/rpc_client/cli_reg.c b/source3/rpc_client/cli_reg.c
index ba98e25d63..2ed7119f4b 100644
--- a/source3/rpc_client/cli_reg.c
+++ b/source3/rpc_client/cli_reg.c
@@ -60,20 +60,3 @@ NTSTATUS rpccli_winreg_Connect(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
return NT_STATUS_INVALID_PARAMETER;
}
-
-/*******************************************************************
- Fill in a REGVAL_BUFFER for the data given a REGISTRY_VALUE
- *******************************************************************/
-
-uint32 reg_init_regval_buffer( REGVAL_BUFFER *buf2, REGISTRY_VALUE *val )
-{
- uint32 real_size = 0;
-
- if ( !buf2 || !val )
- return 0;
-
- real_size = regval_size(val);
- init_regval_buffer( buf2, (unsigned char*)regval_data_p(val), real_size );
-
- return real_size;
-}
diff --git a/source3/rpc_client/init_netlogon.c b/source3/rpc_client/init_netlogon.c
index e4c39e739e..6f7a541f72 100644
--- a/source3/rpc_client/init_netlogon.c
+++ b/source3/rpc_client/init_netlogon.c
@@ -172,7 +172,8 @@ static NTSTATUS nt_token_to_group_list(TALLOC_CTX *mem_ctx,
*****************************************************************************/
NTSTATUS serverinfo_to_SamInfo3(struct auth_serversupplied_info *server_info,
- uint8_t pipe_session_key[16],
+ uint8_t *pipe_session_key,
+ size_t pipe_session_key_len,
struct netr_SamInfo3 *sam3)
{
struct samu *sampw;
@@ -203,6 +204,13 @@ NTSTATUS serverinfo_to_SamInfo3(struct auth_serversupplied_info *server_info,
user_sid = pdb_get_user_sid(sampw);
group_sid = pdb_get_group_sid(sampw);
+ if (pipe_session_key && pipe_session_key_len != 16) {
+ DEBUG(0,("serverinfo_to_SamInfo3: invalid "
+ "pipe_session_key_len[%zu] != 16\n",
+ pipe_session_key_len));
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+
if ((user_sid == NULL) || (group_sid == NULL)) {
DEBUG(1, ("_netr_LogonSamLogon: User without group or user SID\n"));
return NT_STATUS_UNSUCCESSFUL;
@@ -248,14 +256,18 @@ NTSTATUS serverinfo_to_SamInfo3(struct auth_serversupplied_info *server_info,
server_info->user_session_key.data,
MIN(sizeof(user_session_key.key),
server_info->user_session_key.length));
- SamOEMhash(user_session_key.key, pipe_session_key, 16);
+ if (pipe_session_key) {
+ SamOEMhash(user_session_key.key, pipe_session_key, 16);
+ }
}
if (server_info->lm_session_key.length) {
memcpy(lm_session_key.key,
server_info->lm_session_key.data,
MIN(sizeof(lm_session_key.key),
server_info->lm_session_key.length));
- SamOEMhash(lm_session_key.key, pipe_session_key, 8);
+ if (pipe_session_key) {
+ SamOEMhash(lm_session_key.key, pipe_session_key, 8);
+ }
}
groups.count = num_gids;
diff --git a/source3/rpc_client/init_samr.c b/source3/rpc_client/init_samr.c
index 283be0d98b..6a9e6d1682 100644
--- a/source3/rpc_client/init_samr.c
+++ b/source3/rpc_client/init_samr.c
@@ -47,7 +47,7 @@ void init_samr_DomGeneralInformation(struct samr_DomGeneralInformation *r,
const char *domain_name,
const char *primary,
uint64_t sequence_num,
- uint32_t unknown2,
+ enum samr_DomainServerState domain_server_state,
enum samr_Role role,
uint32_t unknown3,
uint32_t num_users,
@@ -59,7 +59,7 @@ void init_samr_DomGeneralInformation(struct samr_DomGeneralInformation *r,
init_lsa_String(&r->domain_name, domain_name);
init_lsa_String(&r->primary, primary);
r->sequence_num = sequence_num;
- r->unknown2 = unknown2;
+ r->domain_server_state = domain_server_state;
r->role = role;
r->unknown3 = unknown3;
r->num_users = num_users;
@@ -134,11 +134,12 @@ void init_samr_DomInfo8(struct samr_DomInfo8 *r,
********************************************************************/
void init_samr_DomInfo9(struct samr_DomInfo9 *r,
- uint32_t unknown)
+ enum samr_DomainServerState domain_server_state)
{
- r->unknown = unknown;
+ r->domain_server_state = domain_server_state;
}
+
/*******************************************************************
inits a structure.
********************************************************************/
@@ -252,6 +253,53 @@ void init_samr_alias_info3(struct lsa_String *r,
}
/*******************************************************************
+ inits a samr_UserInfo5 structure.
+********************************************************************/
+
+void init_samr_user_info5(struct samr_UserInfo5 *r,
+ const char *account_name,
+ const char *full_name,
+ uint32_t rid,
+ uint32_t primary_gid,
+ const char *home_directory,
+ const char *home_drive,
+ const char *logon_script,
+ const char *profile_path,
+ const char *description,
+ const char *workstations,
+ NTTIME last_logon,
+ NTTIME last_logoff,
+ struct samr_LogonHours logon_hours,
+ uint16_t bad_password_count,
+ uint16_t logon_count,
+ NTTIME last_password_change,
+ NTTIME acct_expiry,
+ uint32_t acct_flags)
+{
+ DEBUG(5, ("init_samr_user_info5\n"));
+
+ init_lsa_String(&r->account_name, account_name);
+ init_lsa_String(&r->full_name, full_name);
+ r->rid = rid;
+ r->primary_gid = primary_gid;
+ init_lsa_String(&r->home_directory, home_directory);
+ init_lsa_String(&r->home_drive, home_drive);
+ init_lsa_String(&r->logon_script, logon_script);
+ init_lsa_String(&r->profile_path, profile_path);
+ init_lsa_String(&r->description, description);
+ init_lsa_String(&r->workstations, workstations);
+ r->last_logon = last_logon;
+ r->last_logoff = last_logoff;
+ r->logon_hours = logon_hours;
+ r->bad_password_count = bad_password_count;
+ r->logon_count = logon_count;
+ r->last_password_change = last_password_change;
+ r->acct_expiry = acct_expiry;
+ r->acct_flags = acct_flags;
+}
+
+
+/*******************************************************************
inits a samr_UserInfo7 structure.
********************************************************************/
@@ -410,8 +458,7 @@ void init_samr_user_info23(struct samr_UserInfo23 *r,
uint8_t nt_password_set,
uint8_t lm_password_set,
uint8_t password_expired,
- uint8_t data[516],
- uint8_t pw_len)
+ struct samr_CryptPassword *pwd_buf)
{
memset(r, '\0', sizeof(*r));
init_samr_user_info21(&r->info,
@@ -444,7 +491,7 @@ void init_samr_user_info23(struct samr_UserInfo23 *r,
lm_password_set,
password_expired);
- memcpy(r->password.data, data, sizeof(r->password.data));
+ r->password = *pwd_buf;
}
/*************************************************************************
@@ -452,13 +499,98 @@ void init_samr_user_info23(struct samr_UserInfo23 *r,
*************************************************************************/
void init_samr_user_info24(struct samr_UserInfo24 *r,
- uint8_t data[516],
- uint8_t pw_len)
+ struct samr_CryptPassword *pwd_buf,
+ uint8_t password_expired)
{
DEBUG(10, ("init_samr_user_info24:\n"));
- memcpy(r->password.data, data, sizeof(r->password.data));
- r->pw_len = pw_len;
+ r->password = *pwd_buf;
+ r->password_expired = password_expired;
+}
+
+/*************************************************************************
+ init_samr_user_info25
+ *************************************************************************/
+
+void init_samr_user_info25(struct samr_UserInfo25 *r,
+ NTTIME last_logon,
+ NTTIME last_logoff,
+ NTTIME last_password_change,
+ NTTIME acct_expiry,
+ NTTIME allow_password_change,
+ NTTIME force_password_change,
+ const char *account_name,
+ const char *full_name,
+ const char *home_directory,
+ const char *home_drive,
+ const char *logon_script,
+ const char *profile_path,
+ const char *description,
+ const char *workstations,
+ const char *comment,
+ struct lsa_BinaryString *parameters,
+ uint32_t rid,
+ uint32_t primary_gid,
+ uint32_t acct_flags,
+ uint32_t fields_present,
+ struct samr_LogonHours logon_hours,
+ uint16_t bad_password_count,
+ uint16_t logon_count,
+ uint16_t country_code,
+ uint16_t code_page,
+ uint8_t nt_password_set,
+ uint8_t lm_password_set,
+ uint8_t password_expired,
+ struct samr_CryptPasswordEx *pwd_buf)
+{
+ DEBUG(10, ("init_samr_user_info25:\n"));
+
+ memset(r, '\0', sizeof(*r));
+ init_samr_user_info21(&r->info,
+ last_logon,
+ last_logoff,
+ last_password_change,
+ acct_expiry,
+ allow_password_change,
+ force_password_change,
+ account_name,
+ full_name,
+ home_directory,
+ home_drive,
+ logon_script,
+ profile_path,
+ description,
+ workstations,
+ comment,
+ parameters,
+ rid,
+ primary_gid,
+ acct_flags,
+ fields_present,
+ logon_hours,
+ bad_password_count,
+ logon_count,
+ country_code,
+ code_page,
+ nt_password_set,
+ lm_password_set,
+ password_expired);
+
+ r->password = *pwd_buf;
+}
+
+/*************************************************************************
+ init_samr_user_info26
+ *************************************************************************/
+
+void init_samr_user_info26(struct samr_UserInfo26 *r,
+ struct samr_CryptPasswordEx *pwd_buf,
+ uint8_t password_expired)
+{
+ DEBUG(10, ("init_samr_user_info26:\n"));
+
+ r->password = *pwd_buf;
+ r->password_expired = password_expired;
}
/*************************************************************************
diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c
index cf989c8b5e..169e5cb560 100644
--- a/source3/rpc_parse/parse_misc.c
+++ b/source3/rpc_parse/parse_misc.c
@@ -558,60 +558,6 @@ bool smb_io_buffer5(const char *desc, BUFFER5 *buf5, prs_struct *ps, int depth)
}
/*******************************************************************
- Inits a REGVAL_BUFFER structure.
-********************************************************************/
-
-void init_regval_buffer(REGVAL_BUFFER *str, const uint8 *buf, size_t len)
-{
- ZERO_STRUCTP(str);
-
- /* max buffer size (allocated size) */
- str->buf_max_len = len;
- str->offset = 0;
- str->buf_len = buf != NULL ? len : 0;
-
- if (buf != NULL) {
- SMB_ASSERT(str->buf_max_len >= str->buf_len);
- str->buffer = (uint16 *)TALLOC_ZERO(talloc_tos(),
- str->buf_max_len);
- if (str->buffer == NULL)
- smb_panic("init_regval_buffer: talloc fail");
- memcpy(str->buffer, buf, str->buf_len);
- }
-}
-
-/*******************************************************************
- Reads or writes a REGVAL_BUFFER structure.
- the uni_max_len member tells you how large the buffer is.
- the uni_str_len member tells you how much of the buffer is really used.
-********************************************************************/
-
-bool smb_io_regval_buffer(const char *desc, prs_struct *ps, int depth, REGVAL_BUFFER *buf2)
-{
-
- prs_debug(ps, depth, desc, "smb_io_regval_buffer");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("buf_max_len", ps, depth, &buf2->buf_max_len))
- return False;
- if(!prs_uint32("offset ", ps, depth, &buf2->offset))
- return False;
- if(!prs_uint32("buf_len ", ps, depth, &buf2->buf_len))
- return False;
-
- /* buffer advanced by indicated length of string
- NOT by searching for null-termination */
-
- if(!prs_regval_buffer(True, "buffer ", ps, depth, buf2))
- return False;
-
- return True;
-}
-
-/*******************************************************************
creates a UNISTR2 structure: sets up the buffer, too
********************************************************************/
diff --git a/source3/rpc_parse/parse_ntsvcs.c b/source3/rpc_parse/parse_ntsvcs.c
index 2b15a45506..17b51fa751 100644
--- a/source3/rpc_parse/parse_ntsvcs.c
+++ b/source3/rpc_parse/parse_ntsvcs.c
@@ -77,71 +77,3 @@ bool ntsvcs_io_r_get_device_list(const char *desc, NTSVCS_R_GET_DEVICE_LIST *r_u
return True;
}
-
-/*******************************************************************
-********************************************************************/
-
-bool ntsvcs_io_q_get_device_reg_property(const char *desc, NTSVCS_Q_GET_DEVICE_REG_PROPERTY *q_u, prs_struct *ps, int depth)
-{
- if (q_u == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "ntsvcs_io_q_get_device_reg_property");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if ( !prs_io_unistr2("devicepath", ps, depth, &q_u->devicepath) )
- return False;
- if( !prs_align(ps) )
- return False;
-
- if ( !prs_uint32("property", ps, depth, &q_u->property) )
- return False;
- if ( !prs_uint32("unknown2", ps, depth, &q_u->unknown2) )
- return False;
- if ( !prs_uint32("buffer_size1", ps, depth, &q_u->buffer_size1) )
- return False;
- if ( !prs_uint32("buffer_size2", ps, depth, &q_u->buffer_size2) )
- return False;
- if ( !prs_uint32("unknown5", ps, depth, &q_u->unknown5) )
- return False;
-
- return True;
-
-}
-
-/*******************************************************************
-********************************************************************/
-
-bool ntsvcs_io_r_get_device_reg_property(const char *desc, NTSVCS_R_GET_DEVICE_REG_PROPERTY *r_u, prs_struct *ps, int depth)
-{
- if ( !r_u )
- return False;
-
- prs_debug(ps, depth, desc, "ntsvcs_io_r_get_device_reg_property");
- depth++;
-
- if ( !prs_align(ps) )
- return False;
-
- if ( !prs_uint32("unknown1", ps, depth, &r_u->unknown1) )
- return False;
-
- if ( !smb_io_regval_buffer("value", ps, depth, &r_u->value) )
- return False;
- if ( !prs_align(ps) )
- return False;
-
- if ( !prs_uint32("size", ps, depth, &r_u->size) )
- return False;
-
- if ( !prs_uint32("needed", ps, depth, &r_u->needed) )
- return False;
-
- if(!prs_werror("status", ps, depth, &r_u->status))
- return False;
-
- return True;
-}
diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c
index a0d3ed7397..acc0cc88ef 100644
--- a/source3/rpc_parse/parse_prs.c
+++ b/source3/rpc_parse/parse_prs.c
@@ -1056,39 +1056,6 @@ bool prs_buffer5(bool charmode, const char *name, prs_struct *ps, int depth, BUF
}
/******************************************************************
- Stream a "not" unicode string, length/buffer specified separately,
- in byte chars. String is in little-endian format.
- ********************************************************************/
-
-bool prs_regval_buffer(bool charmode, const char *name, prs_struct *ps, int depth, REGVAL_BUFFER *buf)
-{
- char *p;
- char *q = prs_mem_get(ps, buf->buf_len);
- if (q == NULL)
- return False;
-
- if (UNMARSHALLING(ps)) {
- if (buf->buf_len > buf->buf_max_len) {
- return False;
- }
- if ( buf->buf_max_len ) {
- buf->buffer = PRS_ALLOC_MEM(ps, uint16, buf->buf_max_len);
- if ( buf->buffer == NULL )
- return False;
- } else {
- buf->buffer = NULL;
- }
- }
-
- p = (char *)buf->buffer;
-
- dbg_rw_punival(charmode, name, depth, ps, q, p, buf->buf_len/2);
- ps->data_offset += buf->buf_len;
-
- return True;
-}
-
-/******************************************************************
Stream a string, length/buffer specified separately,
in uint8 chars.
********************************************************************/
diff --git a/source3/rpc_server/srv_dfs_nt.c b/source3/rpc_server/srv_dfs_nt.c
index 661d262dc4..bef8d83103 100644
--- a/source3/rpc_server/srv_dfs_nt.c
+++ b/source3/rpc_server/srv_dfs_nt.c
@@ -48,7 +48,7 @@ WERROR _dfs_Add(pipes_struct *p, struct dfs_Add *r)
NTSTATUS status;
TALLOC_CTX *ctx = talloc_tos();
- if (p->pipe_user.ut.uid != sec_initial_uid()) {
+ if (p->server_info->utok.uid != sec_initial_uid()) {
DEBUG(10,("_dfs_add: uid != 0. Access denied.\n"));
return WERR_ACCESS_DENIED;
}
@@ -113,7 +113,7 @@ WERROR _dfs_Remove(pipes_struct *p, struct dfs_Remove *r)
TALLOC_CTX *ctx = talloc_tos();
char *altpath = NULL;
- if (p->pipe_user.ut.uid != sec_initial_uid()) {
+ if (p->server_info->utok.uid != sec_initial_uid()) {
DEBUG(10,("_dfs_remove: uid != 0. Access denied.\n"));
return WERR_ACCESS_DENIED;
}
diff --git a/source3/rpc_server/srv_eventlog_lib.c b/source3/rpc_server/srv_eventlog_lib.c
index 9215a86d3f..c4a7828b6c 100644
--- a/source3/rpc_server/srv_eventlog_lib.c
+++ b/source3/rpc_server/srv_eventlog_lib.c
@@ -140,13 +140,13 @@ int elog_tdb_size( TDB_CONTEXT * tdb, int *MaxSize, int *Retention )
return True if we made enough room to accommodate needed bytes
********************************************************************/
-static bool make_way_for_eventlogs( TDB_CONTEXT * the_tdb, int32 needed,
+static bool make_way_for_eventlogs( TDB_CONTEXT * the_tdb, int32_t needed,
bool whack_by_date )
{
- int start_record, i, new_start;
- int end_record;
- int nbytes, reclen, len, Retention, MaxSize;
- int tresv1, trecnum, timegen, timewr;
+ int32_t start_record, i, new_start;
+ int32_t end_record;
+ int32_t reclen, tresv1, trecnum, timegen, timewr;
+ int nbytes, len, Retention, MaxSize;
TDB_DATA key, ret;
time_t current_time, exp_time;
@@ -173,16 +173,17 @@ static bool make_way_for_eventlogs( TDB_CONTEXT * the_tdb, int32 needed,
nbytes = 0;
DEBUG( 3,
- ( "MaxSize [%d] Retention [%d] Current Time [%d] exp_time [%d]\n",
- MaxSize, Retention, (uint32)current_time, (uint32)exp_time ) );
+ ( "MaxSize [%d] Retention [%d] Current Time [%u] exp_time [%u]\n",
+ MaxSize, Retention, (unsigned int)current_time, (unsigned int)exp_time ) );
DEBUG( 3,
- ( "Start Record [%d] End Record [%d]\n", start_record,
- end_record ) );
+ ( "Start Record [%u] End Record [%u]\n",
+ (unsigned int)start_record,
+ (unsigned int)end_record ));
for ( i = start_record; i < end_record; i++ ) {
/* read a record, add the amt to nbytes */
- key.dsize = sizeof( int32 );
- key.dptr = ( uint8 * ) ( int32 * ) & i;
+ key.dsize = sizeof(int32_t);
+ key.dptr = (unsigned char *)&i;
ret = tdb_fetch( the_tdb, key );
if ( ret.dsize == 0 ) {
DEBUG( 8,
@@ -198,12 +199,13 @@ static bool make_way_for_eventlogs( TDB_CONTEXT * the_tdb, int32 needed,
if (len == -1) {
DEBUG( 10,("make_way_for_eventlogs: tdb_unpack failed.\n"));
tdb_unlock_bystring( the_tdb, EVT_NEXT_RECORD );
+ SAFE_FREE( ret.dptr );
return False;
}
DEBUG( 8,
- ( "read record %d, record size is [%d], total so far [%d]\n",
- i, reclen, nbytes ) );
+ ( "read record %u, record size is [%d], total so far [%d]\n",
+ (unsigned int)i, reclen, nbytes ) );
SAFE_FREE( ret.dptr );
@@ -220,14 +222,14 @@ static bool make_way_for_eventlogs( TDB_CONTEXT * the_tdb, int32 needed,
}
DEBUG( 3,
- ( "nbytes [%d] needed [%d] start_record is [%d], should be set to [%d]\n",
- nbytes, needed, start_record, i ) );
+ ( "nbytes [%d] needed [%d] start_record is [%u], should be set to [%u]\n",
+ nbytes, needed, (unsigned int)start_record, (unsigned int)i ) );
/* todo - remove eventlog entries here and set starting record to start_record... */
new_start = i;
if ( start_record != new_start ) {
for ( i = start_record; i < new_start; i++ ) {
- key.dsize = sizeof( int32 );
- key.dptr = ( uint8 * ) ( int32 * ) & i;
+ key.dsize = sizeof(int32_t);
+ key.dptr = (unsigned char *)&i;
tdb_delete( the_tdb, key );
}
@@ -267,7 +269,7 @@ bool prune_eventlog( TDB_CONTEXT * tdb )
/********************************************************************
********************************************************************/
-bool can_write_to_eventlog( TDB_CONTEXT * tdb, int32 needed )
+bool can_write_to_eventlog( TDB_CONTEXT * tdb, int32_t needed )
{
int calcd_size;
int MaxSize, Retention;
@@ -313,7 +315,7 @@ bool can_write_to_eventlog( TDB_CONTEXT * tdb, int32 needed )
ELOG_TDB *elog_open_tdb( char *logname, bool force_clear )
{
TDB_CONTEXT *tdb = NULL;
- uint32 vers_id;
+ uint32_t vers_id;
ELOG_TDB *ptr;
char *tdbpath = NULL;
ELOG_TDB *tdb_node = NULL;
@@ -454,7 +456,7 @@ int write_eventlog_tdb( TDB_CONTEXT * the_tdb, Eventlog_entry * ee )
uint8 *packed_ee;
TALLOC_CTX *mem_ctx = NULL;
TDB_DATA kbuf, ebuf;
- uint32 n_packed;
+ uint32_t n_packed;
if ( !ee )
return 0;
diff --git a/source3/rpc_server/srv_eventlog_nt.c b/source3/rpc_server/srv_eventlog_nt.c
index 3c7469f3ef..d12b490d21 100644
--- a/source3/rpc_server/srv_eventlog_nt.c
+++ b/source3/rpc_server/srv_eventlog_nt.c
@@ -1,20 +1,20 @@
-/*
+/*
* Unix SMB/CIFS implementation.
* RPC Pipe client / server routines
* Copyright (C) Marcin Krzysztof Porwit 2005,
* Copyright (C) Brian Moran 2005,
* Copyright (C) Gerald (Jerry) Carter 2005.
- *
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* 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/>.
*/
@@ -40,10 +40,10 @@ typedef struct {
static void free_eventlog_info( void *ptr )
{
EVENTLOG_INFO *elog = (EVENTLOG_INFO *)ptr;
-
+
if ( elog->etdb )
elog_close_tdb( elog->etdb, False );
-
+
TALLOC_FREE( elog );
}
@@ -72,21 +72,21 @@ static bool elog_check_access( EVENTLOG_INFO *info, NT_USER_TOKEN *token )
char *tdbname = elog_tdbname(talloc_tos(), info->logname );
SEC_DESC *sec_desc;
NTSTATUS status;
-
- if ( !tdbname )
+
+ if ( !tdbname )
return False;
-
+
/* get the security descriptor for the file */
-
+
sec_desc = get_nt_acl_no_snum( info, tdbname );
- SAFE_FREE( tdbname );
-
+ TALLOC_FREE( tdbname );
+
if ( !sec_desc ) {
- DEBUG(5,("elog_check_access: Unable to get NT ACL for %s\n",
+ DEBUG(5,("elog_check_access: Unable to get NT ACL for %s\n",
tdbname));
return False;
}
-
+
/* root free pass */
if ( geteuid() == sec_initial_uid() ) {
@@ -95,21 +95,21 @@ static bool elog_check_access( EVENTLOG_INFO *info, NT_USER_TOKEN *token )
}
/* run the check, try for the max allowed */
-
+
status = se_access_check( sec_desc, token, MAXIMUM_ALLOWED_ACCESS,
&info->access_granted);
-
+
if ( sec_desc )
TALLOC_FREE( sec_desc );
-
+
if (!NT_STATUS_IS_OK(status)) {
DEBUG(8,("elog_check_access: se_access_check() return %s\n",
nt_errstr(status)));
return False;
}
-
+
/* we have to have READ permission for a successful open */
-
+
return ( info->access_granted & SA_RIGHT_FILE_READ_DATA );
}
@@ -120,7 +120,7 @@ static bool elog_validate_logname( const char *name )
{
int i;
const char **elogs = lp_eventlog_list();
-
+
if (!elogs) {
return False;
}
@@ -129,7 +129,7 @@ static bool elog_validate_logname( const char *name )
if ( strequal( name, elogs[i] ) )
return True;
}
-
+
return False;
}
@@ -178,19 +178,19 @@ static bool get_oldest_entry_hook( EVENTLOG_INFO * info )
static NTSTATUS elog_open( pipes_struct * p, const char *logname, POLICY_HND *hnd )
{
EVENTLOG_INFO *elog;
-
+
/* first thing is to validate the eventlog name */
if ( !elog_validate_logname( logname ) )
return NT_STATUS_OBJECT_PATH_INVALID;
-
+
if ( !(elog = TALLOC_ZERO_P( NULL, EVENTLOG_INFO )) )
return NT_STATUS_NO_MEMORY;
-
+
elog->logname = talloc_strdup( elog, logname );
-
+
/* Open the tdb first (so that we can create any new tdbs if necessary).
- We have to do this as root and then use an internal access check
+ We have to do this as root and then use an internal access check
on the file permissions since you can only have a tdb open once
in a single process */
@@ -201,40 +201,40 @@ static NTSTATUS elog_open( pipes_struct * p, const char *logname, POLICY_HND *hn
if ( !elog->etdb ) {
/* according to MSDN, if the logfile cannot be found, we should
default to the "Application" log */
-
+
if ( !strequal( logname, ELOG_APPL ) ) {
-
+
TALLOC_FREE( elog->logname );
-
- elog->logname = talloc_strdup( elog, ELOG_APPL );
+
+ elog->logname = talloc_strdup( elog, ELOG_APPL );
/* do the access check */
- if ( !elog_check_access( elog, p->pipe_user.nt_user_token ) ) {
+ if ( !elog_check_access( elog, p->server_info->ptok ) ) {
TALLOC_FREE( elog );
return NT_STATUS_ACCESS_DENIED;
}
-
+
become_root();
elog->etdb = elog_open_tdb( elog->logname, False );
unbecome_root();
- }
-
+ }
+
if ( !elog->etdb ) {
TALLOC_FREE( elog );
- return NT_STATUS_ACCESS_DENIED; /* ??? */
+ return NT_STATUS_ACCESS_DENIED; /* ??? */
}
}
-
+
/* now do the access check. Close the tdb if we fail here */
- if ( !elog_check_access( elog, p->pipe_user.nt_user_token ) ) {
+ if ( !elog_check_access( elog, p->server_info->ptok ) ) {
elog_close_tdb( elog->etdb, False );
TALLOC_FREE( elog );
return NT_STATUS_ACCESS_DENIED;
}
-
+
/* create the policy handle */
-
+
if ( !create_policy_hnd
( p, hnd, free_eventlog_info, ( void * ) elog ) ) {
free_eventlog_info( elog );
@@ -246,7 +246,7 @@ static NTSTATUS elog_open( pipes_struct * p, const char *logname, POLICY_HND *hn
if ( !get_oldest_entry_hook( elog ) ) {
DEBUG(3,("elog_open: Successfully opened eventlog but can't "
"get any information on internal records!\n"));
- }
+ }
elog->current_record = elog->oldest_entry;
@@ -283,15 +283,15 @@ static int elog_size( EVENTLOG_INFO *info )
Eventlog_entry. returns NULL if it can't get the record for some reason.
********************************************************************/
-static Eventlog_entry *get_eventlog_record(prs_struct *ps,
+static Eventlog_entry *get_eventlog_record(TALLOC_CTX *mem_ctx,
TDB_CONTEXT *tdb,
int recno)
{
Eventlog_entry *ee = NULL;
TDB_DATA ret, key;
- int srecno;
- int reclen;
+ int32_t srecno;
+ int32_t reclen;
int len;
char *wpsource = NULL;
@@ -300,10 +300,10 @@ static Eventlog_entry *get_eventlog_record(prs_struct *ps,
char *wpstrs = NULL;
char *puserdata = NULL;
- key.dsize = sizeof(int32);
+ key.dsize = sizeof(int32_t);
srecno = recno;
- key.dptr = ( uint8 * ) &srecno;
+ key.dptr = (unsigned char *)&srecno;
ret = tdb_fetch( tdb, key );
@@ -321,7 +321,7 @@ static Eventlog_entry *get_eventlog_record(prs_struct *ps,
if ( !len )
return NULL;
- ee = TALLOC_ARRAY(ps->mem_ctx, Eventlog_entry, 1);
+ ee = TALLOC_ARRAY(mem_ctx, Eventlog_entry, 1);
if (!ee) {
return NULL;
}
@@ -413,7 +413,7 @@ static Eventlog_entry *get_eventlog_record(prs_struct *ps,
}
/********************************************************************
- note that this can only be called AFTER the table is constructed,
+ note that this can only be called AFTER the table is constructed,
since it uses the table to find the tdb handle
********************************************************************/
@@ -426,28 +426,28 @@ static bool sync_eventlog_params( EVENTLOG_INFO *info )
struct registry_value *value;
WERROR wresult;
char *elogname = info->logname;
- TALLOC_CTX *ctx = talloc_tos();
+ TALLOC_CTX *ctx = talloc_stackframe();
bool ret = false;
DEBUG( 4, ( "sync_eventlog_params with %s\n", elogname ) );
if ( !info->etdb ) {
DEBUG( 4, ( "No open tdb! (%s)\n", info->logname ) );
- return False;
+ goto done;
}
/* set resonable defaults. 512Kb on size and 1 week on time */
uiMaxSize = 0x80000;
uiRetention = 604800;
- /* the general idea is to internally open the registry
- key and retrieve the values. That way we can continue
- to use the same fetch/store api that we use in
+ /* the general idea is to internally open the registry
+ key and retrieve the values. That way we can continue
+ to use the same fetch/store api that we use in
srv_reg_nt.c */
path = talloc_asprintf(ctx, "%s/%s", KEY_EVENTLOG, elogname );
if (!path) {
- return false;
+ goto done;
}
wresult = reg_open_path(ctx, path, REG_KEY_READ, get_root_nt_token(),
@@ -457,14 +457,13 @@ static bool sync_eventlog_params( EVENTLOG_INFO *info )
DEBUG( 4,
( "sync_eventlog_params: Failed to open key [%s] (%s)\n",
path, win_errstr( wresult ) ) );
- return false;
+ goto done;
}
wresult = reg_queryvalue(key, key, "Retention", &value);
if (!W_ERROR_IS_OK(wresult)) {
DEBUG(4, ("Failed to query value \"Retention\": %s\n",
win_errstr(wresult)));
- ret = false;
goto done;
}
uiRetention = value->v.dword;
@@ -473,7 +472,6 @@ static bool sync_eventlog_params( EVENTLOG_INFO *info )
if (!W_ERROR_IS_OK(wresult)) {
DEBUG(4, ("Failed to query value \"MaxSize\": %s\n",
win_errstr(wresult)));
- ret = false;
goto done;
}
uiMaxSize = value->v.dword;
@@ -491,13 +489,13 @@ done:
/********************************************************************
********************************************************************/
-static Eventlog_entry *read_package_entry( prs_struct * ps,
+static Eventlog_entry *read_package_entry( TALLOC_CTX *mem_ctx,
Eventlog_entry * entry )
{
uint8 *offset;
Eventlog_entry *ee_new = NULL;
- ee_new = PRS_ALLOC_MEM( ps, Eventlog_entry, 1 );
+ ee_new = TALLOC_ZERO_ARRAY(mem_ctx, Eventlog_entry, 1 );
if ( ee_new == NULL ) {
return NULL;
}
@@ -536,10 +534,10 @@ static Eventlog_entry *read_package_entry( prs_struct * ps,
DEBUG( 10,
( "entry->record.length is [%d].\n", entry->record.length ) );
entry->data =
- PRS_ALLOC_MEM( ps, uint8,
- entry->record.length -
- sizeof( Eventlog_record ) -
- sizeof( entry->record.length ) );
+ TALLOC_ZERO_ARRAY(mem_ctx, uint8_t,
+ entry->record.length -
+ sizeof( Eventlog_record ) -
+ sizeof( entry->record.length ));
if ( entry->data == NULL ) {
return NULL;
}
@@ -625,13 +623,13 @@ NTSTATUS _eventlog_OpenEventLogW(pipes_struct *p,
if (r->in.logname->string) {
logname = r->in.logname->string;
}
-
+
DEBUG( 10,("_eventlog_open_eventlog: Server [%s], Log [%s]\n",
servername, logname ));
-
+
/* according to MSDN, if the logfile cannot be found, we should
default to the "Application" log */
-
+
if ( !NT_STATUS_IS_OK( result = elog_open( p, logname, r->out.handle )) )
return result;
@@ -761,7 +759,7 @@ NTSTATUS _eventlog_read_eventlog( pipes_struct * p,
/* assume that when the record fetch fails, that we are done */
- entry = get_eventlog_record (ps, ELOG_TDB_CTX(info->etdb), record_number);
+ entry = get_eventlog_record (ps->mem_ctx, ELOG_TDB_CTX(info->etdb), record_number);
if (!entry) {
break;
}
@@ -770,7 +768,7 @@ NTSTATUS _eventlog_read_eventlog( pipes_struct * p,
/* Now see if there is enough room to add */
- if ( !(ee_new = read_package_entry( ps, entry )) )
+ if ( !(ee_new = read_package_entry( ps->mem_ctx, entry )) )
return NT_STATUS_NO_MEMORY;
if ( r_u->num_bytes_in_resp + ee_new->record.length > q_u->max_read_size ) {
diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c
index f4e891ca8c..05452112ca 100644
--- a/source3/rpc_server/srv_lsa_nt.c
+++ b/source3/rpc_server/srv_lsa_nt.c
@@ -381,9 +381,10 @@ NTSTATUS _lsa_OpenPolicy2(pipes_struct *p,
/* get the generic lsa policy SD until we store it */
lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
- status = se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted);
+ status = se_access_check(psd, p->server_info->ptok, des_access,
+ &acc_granted);
if (!NT_STATUS_IS_OK(status)) {
- if (p->pipe_user.ut.uid != sec_initial_uid()) {
+ if (p->server_info->utok.uid != sec_initial_uid()) {
return status;
}
DEBUG(4,("ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
@@ -393,7 +394,7 @@ NTSTATUS _lsa_OpenPolicy2(pipes_struct *p,
/* This is needed for lsa_open_account and rpcclient .... :-) */
- if (p->pipe_user.ut.uid == sec_initial_uid())
+ if (p->server_info->utok.uid == sec_initial_uid())
acc_granted = LSA_POLICY_ALL_ACCESS;
/* associate the domain SID with the (unique) handle. */
@@ -432,9 +433,10 @@ NTSTATUS _lsa_OpenPolicy(pipes_struct *p,
/* get the generic lsa policy SD until we store it */
lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
- status = se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted);
+ status = se_access_check(psd, p->server_info->ptok, des_access,
+ &acc_granted);
if (!NT_STATUS_IS_OK(status)) {
- if (p->pipe_user.ut.uid != sec_initial_uid()) {
+ if (p->server_info->utok.uid != sec_initial_uid()) {
return status;
}
DEBUG(4,("ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
@@ -1539,8 +1541,9 @@ NTSTATUS _lsa_CreateAccount(pipes_struct *p,
/* check to see if the pipe_user is a Domain Admin since
account_pol.tdb was already opened as root, this is all we have */
- if ( p->pipe_user.ut.uid != sec_initial_uid()
- && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
+ if ( p->server_info->utok.uid != sec_initial_uid()
+ && !nt_token_check_domain_rid( p->server_info->ptok,
+ DOMAIN_GROUP_RID_ADMINS ) )
return NT_STATUS_ACCESS_DENIED;
if ( is_privileged_sid( r->in.sid ) )
@@ -1726,8 +1729,9 @@ NTSTATUS _lsa_SetSystemAccessAccount(pipes_struct *p,
/* check to see if the pipe_user is a Domain Admin since
account_pol.tdb was already opened as root, this is all we have */
- if ( p->pipe_user.ut.uid != sec_initial_uid()
- && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
+ if ( p->server_info->utok.uid != sec_initial_uid()
+ && !nt_token_check_domain_rid( p->server_info->ptok,
+ DOMAIN_GROUP_RID_ADMINS ) )
return NT_STATUS_ACCESS_DENIED;
if (!pdb_getgrsid(&map, info->sid))
@@ -1755,8 +1759,9 @@ NTSTATUS _lsa_AddPrivilegesToAccount(pipes_struct *p,
/* check to see if the pipe_user is root or a Domain Admin since
account_pol.tdb was already opened as root, this is all we have */
- if ( p->pipe_user.ut.uid != sec_initial_uid()
- && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
+ if ( p->server_info->utok.uid != sec_initial_uid()
+ && !nt_token_check_domain_rid( p->server_info->ptok,
+ DOMAIN_GROUP_RID_ADMINS ) )
{
return NT_STATUS_ACCESS_DENIED;
}
@@ -1795,8 +1800,9 @@ NTSTATUS _lsa_RemovePrivilegesFromAccount(pipes_struct *p,
/* check to see if the pipe_user is root or a Domain Admin since
account_pol.tdb was already opened as root, this is all we have */
- if ( p->pipe_user.ut.uid != sec_initial_uid()
- && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
+ if ( p->server_info->utok.uid != sec_initial_uid()
+ && !nt_token_check_domain_rid( p->server_info->ptok,
+ DOMAIN_GROUP_RID_ADMINS ) )
{
return NT_STATUS_ACCESS_DENIED;
}
@@ -1952,8 +1958,9 @@ NTSTATUS _lsa_AddAccountRights(pipes_struct *p,
/* check to see if the pipe_user is a Domain Admin since
account_pol.tdb was already opened as root, this is all we have */
- if ( p->pipe_user.ut.uid != sec_initial_uid()
- && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
+ if ( p->server_info->utok.uid != sec_initial_uid()
+ && !nt_token_check_domain_rid( p->server_info->ptok,
+ DOMAIN_GROUP_RID_ADMINS ) )
{
return NT_STATUS_ACCESS_DENIED;
}
@@ -2001,8 +2008,9 @@ NTSTATUS _lsa_RemoveAccountRights(pipes_struct *p,
/* check to see if the pipe_user is a Domain Admin since
account_pol.tdb was already opened as root, this is all we have */
- if ( p->pipe_user.ut.uid != sec_initial_uid()
- && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
+ if ( p->server_info->utok.uid != sec_initial_uid()
+ && !nt_token_check_domain_rid( p->server_info->ptok,
+ DOMAIN_GROUP_RID_ADMINS ) )
{
return NT_STATUS_ACCESS_DENIED;
}
diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c
index 75fc99401e..45acd3ed48 100644
--- a/source3/rpc_server/srv_netlog_nt.c
+++ b/source3/rpc_server/srv_netlog_nt.c
@@ -981,7 +981,7 @@ NTSTATUS _netr_LogonSamLogon(pipes_struct *p,
memcpy(pipe_session_key, p->auth.a_u.schannel_auth->sess_key, 16);
}
- status = serverinfo_to_SamInfo3(server_info, pipe_session_key, sam3);
+ status = serverinfo_to_SamInfo3(server_info, pipe_session_key, 16, sam3);
TALLOC_FREE(server_info);
return status;
}
diff --git a/source3/rpc_server/srv_ntsvcs.c b/source3/rpc_server/srv_ntsvcs.c
index 5010990b58..840da3eec4 100644
--- a/source3/rpc_server/srv_ntsvcs.c
+++ b/source3/rpc_server/srv_ntsvcs.c
@@ -97,23 +97,7 @@ static bool api_ntsvcs_validate_device_instance(pipes_struct *p)
static bool api_ntsvcs_get_device_reg_property(pipes_struct *p)
{
- NTSVCS_Q_GET_DEVICE_REG_PROPERTY q_u;
- NTSVCS_R_GET_DEVICE_REG_PROPERTY r_u;
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- if(!ntsvcs_io_q_get_device_reg_property("", &q_u, data, 0))
- return False;
-
- r_u.status = _ntsvcs_get_device_reg_property(p, &q_u, &r_u);
-
- if(!ntsvcs_io_r_get_device_reg_property("", &r_u, rdata, 0))
- return False;
-
- return True;
+ return proxy_ntsvcs_call(p, NDR_PNP_GETDEVICEREGPROP);
}
/*******************************************************************
diff --git a/source3/rpc_server/srv_ntsvcs_nt.c b/source3/rpc_server/srv_ntsvcs_nt.c
index 268da52896..f2c85bbd3e 100644
--- a/source3/rpc_server/srv_ntsvcs_nt.c
+++ b/source3/rpc_server/srv_ntsvcs_nt.c
@@ -93,30 +93,31 @@ WERROR _ntsvcs_get_device_list( pipes_struct *p, NTSVCS_Q_GET_DEVICE_LIST *q_u,
}
/********************************************************************
+_PNP_GetDeviceRegProp
********************************************************************/
-WERROR _ntsvcs_get_device_reg_property( pipes_struct *p, NTSVCS_Q_GET_DEVICE_REG_PROPERTY *q_u, NTSVCS_R_GET_DEVICE_REG_PROPERTY *r_u )
+WERROR _PNP_GetDeviceRegProp(pipes_struct *p,
+ struct PNP_GetDeviceRegProp *r)
{
- fstring devicepath;
char *ptr;
REGVAL_CTR *values;
REGISTRY_VALUE *val;
- rpcstr_pull(devicepath, q_u->devicepath.buffer, sizeof(devicepath), q_u->devicepath.uni_str_len*2, 0);
-
- switch( q_u->property ) {
+ switch( r->in.property ) {
case DEV_REGPROP_DESC:
+
/* just parse the service name from the device path and then
lookup the display name */
- if ( !(ptr = strrchr_m( devicepath, '\\' )) )
+ if ( !(ptr = strrchr_m( r->in.devicepath, '\\' )) )
return WERR_GENERAL_FAILURE;
*ptr = '\0';
- if ( !(ptr = strrchr_m( devicepath, '_' )) )
+ if ( !(ptr = strrchr_m( r->in.devicepath, '_' )) )
return WERR_GENERAL_FAILURE;
ptr++;
- if ( !(values = svcctl_fetch_regvalues( ptr, p->pipe_user.nt_user_token )) )
+ if ( !(values = svcctl_fetch_regvalues(
+ ptr, p->server_info->ptok)))
return WERR_GENERAL_FAILURE;
if ( !(val = regval_ctr_getvalue( values, "DisplayName" )) ) {
@@ -124,16 +125,27 @@ WERROR _ntsvcs_get_device_reg_property( pipes_struct *p, NTSVCS_Q_GET_DEVICE_REG
return WERR_GENERAL_FAILURE;
}
- r_u->unknown1 = 0x1; /* always 1...tested using a remove device manager connection */
- r_u->size = reg_init_regval_buffer( &r_u->value, val );
- r_u->needed = r_u->size;
+ if (*r->in.buffer_size < val->size) {
+ *r->out.needed = val->size;
+ *r->out.buffer_size = 0;
+ TALLOC_FREE( values );
+ return WERR_CM_BUFFER_SMALL;
+ }
+ r->out.buffer = (uint8_t *)talloc_memdup(p->mem_ctx, val->data_p, val->size);
TALLOC_FREE(values);
+ if (!r->out.buffer) {
+ return WERR_NOMEM;
+ }
+
+ *r->out.reg_data_type = REG_SZ; /* always 1...tested using a remove device manager connection */
+ *r->out.buffer_size = val->size;
+ *r->out.needed = val->size;
break;
default:
- r_u->unknown1 = 0x00437c98;
+ *r->out.reg_data_type = 0x00437c98; /* ??? */
return WERR_CM_NO_SUCH_VALUE;
}
@@ -279,16 +291,6 @@ WERROR _PNP_GetDepth(pipes_struct *p,
/****************************************************************
****************************************************************/
-WERROR _PNP_GetDeviceRegProp(pipes_struct *p,
- struct PNP_GetDeviceRegProp *r)
-{
- p->rng_fault_state = true;
- return WERR_NOT_SUPPORTED;
-}
-
-/****************************************************************
-****************************************************************/
-
WERROR _PNP_SetDeviceRegProp(pipes_struct *p,
struct PNP_SetDeviceRegProp *r)
{
diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c
index 2c31d7b3f1..5610e0bf71 100644
--- a/source3/rpc_server/srv_pipe.c
+++ b/source3/rpc_server/srv_pipe.c
@@ -614,11 +614,6 @@ static bool pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob)
ZERO_STRUCT(reply);
- /* Set up for non-authenticated user. */
- TALLOC_FREE(p->pipe_user.nt_user_token);
- p->pipe_user.ut.ngroups = 0;
- SAFE_FREE( p->pipe_user.ut.groups);
-
/* this has to be done as root in order to verify the password */
become_root();
status = auth_ntlmssp_update(a, *p_resp_blob, &reply);
@@ -656,29 +651,8 @@ static bool pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob)
"workstation: %s\n", a->ntlmssp_state->user,
a->ntlmssp_state->domain, a->ntlmssp_state->workstation));
- /*
- * Store the UNIX credential data (uid/gid pair) in the pipe structure.
- */
-
- p->pipe_user.ut.uid = a->server_info->utok.uid;
- p->pipe_user.ut.gid = a->server_info->utok.gid;
-
- p->pipe_user.ut.ngroups = a->server_info->utok.ngroups;
- if (p->pipe_user.ut.ngroups) {
- if (!(p->pipe_user.ut.groups = (gid_t *)memdup(
- a->server_info->utok.groups,
- sizeof(gid_t) * p->pipe_user.ut.ngroups))) {
- DEBUG(0,("failed to memdup group list to p->pipe_user.groups\n"));
- return False;
- }
- }
-
- if (a->server_info->ptok) {
- p->pipe_user.nt_user_token =
- dup_nt_token(NULL, a->server_info->ptok);
- } else {
+ if (a->server_info->ptok == NULL) {
DEBUG(1,("Error: Authmodule failed to provide nt_user_token\n"));
- p->pipe_user.nt_user_token = NULL;
return False;
}
@@ -1711,11 +1685,6 @@ bool api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
case RPC_ANONYMOUS_AUTH_TYPE:
/* Unauthenticated bind request. */
- /* Get the authenticated pipe user from current_user */
- if (!copy_current_user(&p->pipe_user, &current_user)) {
- DEBUG(10, ("Could not copy current user\n"));
- goto err_exit;
- }
/* We're finished - no more packets. */
p->auth.auth_type = PIPE_AUTH_TYPE_NONE;
/* We must set the pipe auth_level here also. */
@@ -2226,23 +2195,6 @@ bool api_pipe_schannel_process(pipes_struct *p, prs_struct *rpc_in, uint32 *p_ss
}
/****************************************************************************
- Return a user struct for a pipe user.
-****************************************************************************/
-
-struct current_user *get_current_user(struct current_user *user, pipes_struct *p)
-{
- if (p->pipe_bound &&
- (p->auth.auth_type == PIPE_AUTH_TYPE_NTLMSSP ||
- (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) {
- memcpy(user, &p->pipe_user, sizeof(struct current_user));
- } else {
- memcpy(user, &current_user, sizeof(struct current_user));
- }
-
- return user;
-}
-
-/****************************************************************************
Find the set of RPC functions associated with this context_id
****************************************************************************/
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
index 92f89282cf..1cff95dcab 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -20,6 +20,7 @@
*/
#include "includes.h"
+#include "librpc/gen_ndr/ndr_named_pipe_auth.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
@@ -161,13 +162,6 @@ static struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx,
p->endian = RPC_LITTLE_ENDIAN;
- ZERO_STRUCT(p->pipe_user);
-
- p->pipe_user.vuid = vuid;
- p->pipe_user.ut.uid = (uid_t)-1;
- p->pipe_user.ut.gid = (gid_t)-1;
- p->pipe_user.nt_user_token = dup_nt_token(NULL, server_info->ptok);
-
/*
* Initialize the outgoing RPC data buffer with no memory.
*/
@@ -899,9 +893,6 @@ static int close_internal_rpc_pipe_hnd(struct pipes_struct *p)
/* Free the handles database. */
close_policy_by_pipe(p);
- TALLOC_FREE(p->pipe_user.nt_user_token);
- SAFE_FREE(p->pipe_user.ut.groups);
-
DLIST_REMOVE(InternalPipes, p);
ZERO_STRUCTP(p);
@@ -944,6 +935,17 @@ static struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx,
struct np_proxy_state *result;
struct sockaddr_un addr;
char *socket_path;
+ const char *socket_dir;
+
+ DATA_BLOB req_blob;
+ struct netr_SamInfo3 *info3;
+ struct named_pipe_auth_req req;
+ DATA_BLOB rep_blob;
+ uint8 rep_buf[20];
+ struct named_pipe_auth_rep rep;
+ enum ndr_err_code ndr_err;
+ NTSTATUS status;
+ ssize_t written;
result = talloc(mem_ctx, struct np_proxy_state);
if (result == NULL) {
@@ -961,8 +963,16 @@ static struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx,
ZERO_STRUCT(addr);
addr.sun_family = AF_UNIX;
- socket_path = talloc_asprintf(talloc_tos(), "%s/%s",
- get_dyn_NCALRPCDIR(), "DEFAULT");
+ socket_dir = lp_parm_const_string(
+ GLOBAL_SECTION_SNUM, "external_rpc_pipe", "socket_dir",
+ get_dyn_NCALRPCDIR());
+ if (socket_dir == NULL) {
+ DEBUG(0, ("externan_rpc_pipe:socket_dir not set\n"));
+ goto fail;
+ }
+
+ socket_path = talloc_asprintf(talloc_tos(), "%s/np/%s",
+ socket_dir, pipe_name);
if (socket_path == NULL) {
DEBUG(0, ("talloc_asprintf failed\n"));
goto fail;
@@ -970,11 +980,96 @@ static struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx,
strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
TALLOC_FREE(socket_path);
+ become_root();
if (sys_connect(result->fd, (struct sockaddr *)&addr) == -1) {
+ unbecome_root();
DEBUG(0, ("connect(%s) failed: %s\n", addr.sun_path,
strerror(errno)));
goto fail;
}
+ unbecome_root();
+
+ info3 = talloc(talloc_tos(), struct netr_SamInfo3);
+ if (info3 == NULL) {
+ DEBUG(0, ("talloc failed\n"));
+ goto fail;
+ }
+
+ status = serverinfo_to_SamInfo3(server_info, NULL, 0, info3);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(info3);
+ DEBUG(0, ("serverinfo_to_SamInfo3 failed: %s\n",
+ nt_errstr(status)));
+ goto fail;
+ }
+
+ req.level = 1;
+ req.info.info1 = *info3;
+
+ ndr_err = ndr_push_struct_blob(
+ &req_blob, talloc_tos(), NULL, &req,
+ (ndr_push_flags_fn_t)ndr_push_named_pipe_auth_req);
+
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(10, ("ndr_push_named_pipe_auth_req failed: %s\n",
+ ndr_errstr(ndr_err)));
+ goto fail;
+ }
+
+ DEBUG(10, ("named_pipe_auth_req(client)[%u]\n", (uint32_t)req_blob.length));
+ dump_data(10, req_blob.data, req_blob.length);
+
+ written = write_data(result->fd, (char *)req_blob.data,
+ req_blob.length);
+ if (written == -1) {
+ DEBUG(3, ("Could not write auth req data to RPC server\n"));
+ goto fail;
+ }
+
+ status = read_data(result->fd, (char *)rep_buf, sizeof(rep_buf));
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(3, ("Could not read auth result\n"));
+ goto fail;
+ }
+
+ rep_blob = data_blob_const(rep_buf, sizeof(rep_buf));
+
+ DEBUG(10,("name_pipe_auth_rep(client)[%u]\n", (uint32_t)rep_blob.length));
+ dump_data(10, rep_blob.data, rep_blob.length);
+
+ ndr_err = ndr_pull_struct_blob(
+ &rep_blob, talloc_tos(), NULL, &rep,
+ (ndr_pull_flags_fn_t)ndr_pull_named_pipe_auth_rep);
+
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(0, ("ndr_pull_named_pipe_auth_rep failed: %s\n",
+ ndr_errstr(ndr_err)));
+ goto fail;
+ }
+
+ if (rep.length != 16) {
+ DEBUG(0, ("req invalid length: %u != 16\n",
+ rep.length));
+ goto fail;
+ }
+
+ if (strcmp(NAMED_PIPE_AUTH_MAGIC, rep.magic) != 0) {
+ DEBUG(0, ("req invalid magic: %s != %s\n",
+ rep.magic, NAMED_PIPE_AUTH_MAGIC));
+ goto fail;
+ }
+
+ if (!NT_STATUS_IS_OK(rep.status)) {
+ DEBUG(0, ("req failed: %s\n",
+ nt_errstr(rep.status)));
+ goto fail;
+ }
+
+ if (rep.level != 1) {
+ DEBUG(0, ("req invalid level: %u != 1\n",
+ rep.level));
+ goto fail;
+ }
return result;
@@ -983,9 +1078,10 @@ static struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx,
return NULL;
}
-NTSTATUS np_open(struct smb_request *smb_req, struct connection_struct *conn,
- const char *name, struct files_struct **pfsp)
+NTSTATUS np_open(struct smb_request *smb_req, const char *name,
+ struct files_struct **pfsp)
{
+ struct connection_struct *conn = smb_req->conn;
NTSTATUS status;
struct files_struct *fsp;
const char **proxy_list;
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index c573173900..cbcd4de60c 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -45,6 +45,9 @@
#define DISP_INFO_CACHE_TIMEOUT 10
+#define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
+#define MAX_SAM_ENTRIES_W95 50
+
typedef struct disp_info {
DOM_SID sid; /* identify which domain this is. */
bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
@@ -629,7 +632,7 @@ NTSTATUS _samr_OpenDomain(pipes_struct *p,
return status;
/*check if access can be granted as requested by client. */
- map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
+ map_max_allowed_access(p->server_info->ptok, &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 );
@@ -637,7 +640,7 @@ NTSTATUS _samr_OpenDomain(pipes_struct *p,
se_priv_copy( &se_rights, &se_machine_account );
se_priv_add( &se_rights, &se_add_users );
- status = access_check_samr_object( psd, p->pipe_user.nt_user_token,
+ status = access_check_samr_object( psd, p->server_info->ptok,
&se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
&acc_granted, "_samr_OpenDomain" );
@@ -1009,6 +1012,7 @@ NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
if (!samr_array) {
return NT_STATUS_NO_MEMORY;
}
+ *r->out.sam = samr_array;
become_root();
@@ -1068,7 +1072,6 @@ NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
samr_array->entries = samr_entries;
*r->out.resume_handle = *r->in.resume_handle + num_account;
- *r->out.sam = samr_array;
*r->out.num_entries = num_account;
DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
@@ -1481,6 +1484,11 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
return NT_STATUS_INVALID_HANDLE;
+ if (info->builtin_domain) {
+ DEBUG(5,("_samr_QueryDisplayInfo: Nothing in BUILTIN\n"));
+ return NT_STATUS_OK;
+ }
+
status = access_check_samr_function(info->acc_granted,
SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
"_samr_QueryDisplayInfo");
@@ -1791,6 +1799,7 @@ NTSTATUS _samr_LookupNames(pipes_struct *p,
DOM_SID pol_sid;
uint32 acc_granted;
struct samr_Ids rids, types;
+ uint32_t num_mapped = 0;
DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
@@ -1838,10 +1847,18 @@ NTSTATUS _samr_LookupNames(pipes_struct *p,
}
if (type[i] != SID_NAME_UNKNOWN) {
- status = NT_STATUS_OK;
+ num_mapped++;
}
}
+ if (num_mapped == num_rids) {
+ status = NT_STATUS_OK;
+ } else if (num_mapped == 0) {
+ status = NT_STATUS_NONE_MAPPED;
+ } else {
+ status = STATUS_SOME_UNMAPPED;
+ }
+
rids.count = num_rids;
rids.ids = rid;
@@ -2163,7 +2180,7 @@ NTSTATUS _samr_OpenUser(pipes_struct *p,
/* check if access can be granted as requested by client. */
- map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
+ map_max_allowed_access(p->server_info->ptok, &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);
@@ -2171,7 +2188,7 @@ NTSTATUS _samr_OpenUser(pipes_struct *p,
se_priv_copy( &se_rights, &se_machine_account );
se_priv_add( &se_rights, &se_add_users );
- nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
+ nt_status = access_check_samr_object(psd, p->server_info->ptok,
&se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
&acc_granted, "_samr_OpenUser");
@@ -2236,79 +2253,117 @@ static NTSTATUS init_samr_parameters_string(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
-/*************************************************************************
- get_user_info_7. Safe. Only gives out account_name.
- *************************************************************************/
-
-static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
- struct samr_UserInfo7 *r,
- DOM_SID *user_sid)
+static NTSTATUS get_user_info_5(TALLOC_CTX *mem_ctx,
+ struct samr_UserInfo5 *r,
+ struct samu *pw,
+ DOM_SID *domain_sid)
{
- struct samu *smbpass=NULL;
- bool ret;
- const char *account_name = NULL;
+ const DOM_SID *sid_user, *sid_group;
+ uint32_t rid, primary_gid;
+ NTTIME last_logon, last_logoff, last_password_change,
+ acct_expiry;
+ const char *account_name, *full_name, *home_directory, *home_drive,
+ *logon_script, *profile_path, *description,
+ *workstations, *comment;
+ struct samr_LogonHours logon_hours;
ZERO_STRUCTP(r);
- if ( !(smbpass = samu_new( mem_ctx )) ) {
- return NT_STATUS_NO_MEMORY;
+ sid_user = pdb_get_user_sid(pw);
+
+ if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
+ DEBUG(0, ("get_user_info_5: User %s has SID %s, \nwhich conflicts with "
+ "the domain sid %s. Failing operation.\n",
+ pdb_get_username(pw), sid_string_dbg(sid_user),
+ sid_string_dbg(domain_sid)));
+ return NT_STATUS_UNSUCCESSFUL;
}
become_root();
- ret = pdb_getsampwsid(smbpass, user_sid);
+ sid_group = pdb_get_group_sid(pw);
unbecome_root();
- if ( !ret ) {
- DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
- return NT_STATUS_NO_SUCH_USER;
+ if (!sid_peek_check_rid(domain_sid, sid_group, &primary_gid)) {
+ DEBUG(0, ("get_user_info_5: User %s has Primary Group SID %s, \n"
+ "which conflicts with the domain sid %s. Failing operation.\n",
+ pdb_get_username(pw), sid_string_dbg(sid_group),
+ sid_string_dbg(domain_sid)));
+ return NT_STATUS_UNSUCCESSFUL;
}
- account_name = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
- if (!account_name) {
- TALLOC_FREE(smbpass);
- return NT_STATUS_NO_MEMORY;
- }
- TALLOC_FREE(smbpass);
+ unix_to_nt_time(&last_logon, pdb_get_logon_time(pw));
+ unix_to_nt_time(&last_logoff, pdb_get_logoff_time(pw));
+ unix_to_nt_time(&acct_expiry, pdb_get_kickoff_time(pw));
+ unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(pw));
+
+ account_name = talloc_strdup(mem_ctx, pdb_get_username(pw));
+ full_name = talloc_strdup(mem_ctx, pdb_get_fullname(pw));
+ home_directory = talloc_strdup(mem_ctx, pdb_get_homedir(pw));
+ home_drive = talloc_strdup(mem_ctx, pdb_get_dir_drive(pw));
+ logon_script = talloc_strdup(mem_ctx, pdb_get_logon_script(pw));
+ profile_path = talloc_strdup(mem_ctx, pdb_get_profile_path(pw));
+ description = talloc_strdup(mem_ctx, pdb_get_acct_desc(pw));
+ workstations = talloc_strdup(mem_ctx, pdb_get_workstations(pw));
+ comment = talloc_strdup(mem_ctx, pdb_get_comment(pw));
- DEBUG(3,("User:[%s]\n", account_name));
+ logon_hours = get_logon_hours_from_pdb(mem_ctx, pw);
- init_samr_user_info7(r, account_name);
+ init_samr_user_info5(r,
+ account_name,
+ full_name,
+ rid,
+ primary_gid,
+ home_directory,
+ home_drive,
+ logon_script,
+ profile_path,
+ description,
+ workstations,
+ last_logon,
+ last_logoff,
+ logon_hours,
+ pdb_get_bad_password_count(pw),
+ pdb_get_logon_count(pw),
+ last_password_change,
+ acct_expiry,
+ pdb_get_acct_ctrl(pw));
return NT_STATUS_OK;
}
/*************************************************************************
- get_user_info_9. Only gives out primary group SID.
+ get_user_info_7. Safe. Only gives out account_name.
*************************************************************************/
-static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
- struct samr_UserInfo9 *r,
- DOM_SID *user_sid)
+static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx,
+ struct samr_UserInfo7 *r,
+ struct samu *smbpass)
{
- struct samu *smbpass=NULL;
- bool ret;
+ const char *account_name = NULL;
ZERO_STRUCTP(r);
- if ( !(smbpass = samu_new( mem_ctx )) ) {
+ account_name = talloc_strdup(mem_ctx, pdb_get_username(smbpass));
+ if (!account_name) {
return NT_STATUS_NO_MEMORY;
}
- become_root();
- ret = pdb_getsampwsid(smbpass, user_sid);
- unbecome_root();
+ init_samr_user_info7(r, account_name);
- if (ret==False) {
- DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
- TALLOC_FREE(smbpass);
- return NT_STATUS_NO_SUCH_USER;
- }
+ return NT_STATUS_OK;
+}
- DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
+/*************************************************************************
+ get_user_info_9. Only gives out primary group SID.
+ *************************************************************************/
- init_samr_user_info9(r, pdb_get_group_rid(smbpass));
+static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
+ struct samr_UserInfo9 *r,
+ struct samu *smbpass)
+{
+ ZERO_STRUCTP(r);
- TALLOC_FREE(smbpass);
+ init_samr_user_info9(r, pdb_get_group_rid(smbpass));
return NT_STATUS_OK;
}
@@ -2319,33 +2374,12 @@ static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx,
static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx,
struct samr_UserInfo16 *r,
- DOM_SID *user_sid)
+ struct samu *smbpass)
{
- struct samu *smbpass=NULL;
- bool ret;
-
ZERO_STRUCTP(r);
- if ( !(smbpass = samu_new( mem_ctx )) ) {
- return NT_STATUS_NO_MEMORY;
- }
-
- become_root();
- ret = pdb_getsampwsid(smbpass, user_sid);
- unbecome_root();
-
- if (ret==False) {
- DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
- TALLOC_FREE(smbpass);
- return NT_STATUS_NO_SUCH_USER;
- }
-
- DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
-
init_samr_user_info16(r, pdb_get_acct_ctrl(smbpass));
- TALLOC_FREE(smbpass);
-
return NT_STATUS_OK;
}
@@ -2410,10 +2444,8 @@ static NTSTATUS get_user_info_18(pipes_struct *p,
static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
struct samr_UserInfo20 *r,
- DOM_SID *user_sid)
+ struct samu *sampass)
{
- struct samu *sampass=NULL;
- bool ret;
const char *munged_dial = NULL;
DATA_BLOB blob;
NTSTATUS status;
@@ -2421,24 +2453,8 @@ static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
ZERO_STRUCTP(r);
- if ( !(sampass = samu_new( mem_ctx )) ) {
- return NT_STATUS_NO_MEMORY;
- }
-
- become_root();
- ret = pdb_getsampwsid(sampass, user_sid);
- unbecome_root();
-
- if (ret == False) {
- DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
- TALLOC_FREE(sampass);
- return NT_STATUS_NO_SUCH_USER;
- }
-
munged_dial = pdb_get_munged_dial(sampass);
- samr_clear_sam_passwd(sampass);
-
DEBUG(3,("User:[%s] has [%s] (length: %d)\n", pdb_get_username(sampass),
munged_dial, (int)strlen(munged_dial)));
@@ -2450,7 +2466,6 @@ static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
data_blob_free(&blob);
- TALLOC_FREE(sampass);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -2467,12 +2482,10 @@ static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx,
static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
struct samr_UserInfo21 *r,
- DOM_SID *user_sid,
+ struct samu *pw,
DOM_SID *domain_sid)
{
NTSTATUS status;
- struct samu *pw = NULL;
- bool ret;
const DOM_SID *sid_user, *sid_group;
uint32_t rid, primary_gid;
NTTIME last_logon, last_logoff, last_password_change,
@@ -2489,24 +2502,6 @@ static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
ZERO_STRUCTP(r);
- if (!(pw = samu_new(mem_ctx))) {
- return NT_STATUS_NO_MEMORY;
- }
-
- become_root();
- ret = pdb_getsampwsid(pw, user_sid);
- unbecome_root();
-
- if (ret == False) {
- DEBUG(4,("User %s not found\n", sid_string_dbg(user_sid)));
- TALLOC_FREE(pw);
- return NT_STATUS_NO_SUCH_USER;
- }
-
- samr_clear_sam_passwd(pw);
-
- DEBUG(3,("User:[%s]\n", pdb_get_username(pw)));
-
sid_user = pdb_get_user_sid(pw);
if (!sid_peek_check_rid(domain_sid, sid_user, &rid)) {
@@ -2514,7 +2509,6 @@ static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
"the domain sid %s. Failing operation.\n",
pdb_get_username(pw), sid_string_dbg(sid_user),
sid_string_dbg(domain_sid)));
- TALLOC_FREE(pw);
return NT_STATUS_UNSUCCESSFUL;
}
@@ -2527,7 +2521,6 @@ static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
"which conflicts with the domain sid %s. Failing operation.\n",
pdb_get_username(pw), sid_string_dbg(sid_group),
sid_string_dbg(domain_sid)));
- TALLOC_FREE(pw);
return NT_STATUS_UNSUCCESSFUL;
}
@@ -2560,7 +2553,6 @@ static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
status = init_samr_parameters_string(mem_ctx, &blob, &parameters);
data_blob_free(&blob);
if (!NT_STATUS_IS_OK(status)) {
- TALLOC_FREE(pw);
return status;
}
@@ -2618,7 +2610,6 @@ static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx,
0, /* nt_password_set */
0, /* lm_password_set */
password_expired);
- TALLOC_FREE(pw);
return NT_STATUS_OK;
}
@@ -2635,6 +2626,8 @@ NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
struct samr_info *info = NULL;
DOM_SID domain_sid;
uint32 rid;
+ bool ret = false;
+ struct samu *pwd = NULL;
/* search for the handle */
if (!find_policy_by_hnd(p, r->in.user_handle, (void **)(void *)&info))
@@ -2664,52 +2657,54 @@ NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
DEBUG(5,("_samr_QueryUserInfo: user info level: %d\n", r->in.level));
+ if (!(pwd = samu_new(p->mem_ctx))) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ become_root();
+ ret = pdb_getsampwsid(pwd, &info->sid);
+ unbecome_root();
+
+ if (ret == false) {
+ DEBUG(4,("User %s not found\n", sid_string_dbg(&info->sid)));
+ TALLOC_FREE(pwd);
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ DEBUG(3,("User:[%s]\n", pdb_get_username(pwd)));
+
+ samr_clear_sam_passwd(pwd);
+
switch (r->in.level) {
+ case 5:
+ status = get_user_info_5(p->mem_ctx, &user_info->info5, pwd, &domain_sid);
+ break;
case 7:
- status = get_user_info_7(p->mem_ctx, &user_info->info7, &info->sid);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
+ status = get_user_info_7(p->mem_ctx, &user_info->info7, pwd);
break;
case 9:
- status = get_user_info_9(p->mem_ctx, &user_info->info9, &info->sid);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
+ status = get_user_info_9(p->mem_ctx, &user_info->info9, pwd);
break;
case 16:
- status = get_user_info_16(p->mem_ctx, &user_info->info16, &info->sid);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
+ status = get_user_info_16(p->mem_ctx, &user_info->info16, pwd);
break;
-
case 18:
+ /* level 18 is special */
status = get_user_info_18(p, p->mem_ctx, &user_info->info18, &info->sid);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
break;
-
case 20:
- status = get_user_info_20(p->mem_ctx, &user_info->info20, &info->sid);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
+ status = get_user_info_20(p->mem_ctx, &user_info->info20, pwd);
break;
-
case 21:
- status = get_user_info_21(p->mem_ctx, &user_info->info21,
- &info->sid, &domain_sid);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
+ status = get_user_info_21(p->mem_ctx, &user_info->info21, pwd, &domain_sid);
break;
-
default:
- return NT_STATUS_INVALID_INFO_CLASS;
+ status = NT_STATUS_INVALID_INFO_CLASS;
+ break;
}
+ TALLOC_FREE(pwd);
+
*r->out.info = user_info;
DEBUG(5,("_samr_QueryUserInfo: %d\n", __LINE__));
@@ -2717,6 +2712,21 @@ NTSTATUS _samr_QueryUserInfo(pipes_struct *p,
return status;
}
+/****************************************************************
+****************************************************************/
+
+NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
+ struct samr_QueryUserInfo2 *r)
+{
+ struct samr_QueryUserInfo u;
+
+ u.in.user_handle = r->in.user_handle;
+ u.in.level = r->in.level;
+ u.out.info = r->out.info;
+
+ return _samr_QueryUserInfo(p, &u);
+}
+
/*******************************************************************
_samr_GetGroupsForUser
********************************************************************/
@@ -2969,7 +2979,7 @@ NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
lp_workgroup(),
global_myname(),
seq_num,
- 1,
+ DOMAIN_SERVER_ENABLED,
server_role,
1,
num_users,
@@ -3146,6 +3156,11 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p,
&disp_info))
return NT_STATUS_INVALID_HANDLE;
+ if (disp_info->builtin_domain) {
+ DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
nt_status = access_check_samr_function(acc_granted,
SAMR_DOMAIN_ACCESS_CREATE_USER,
"_samr_CreateUser2");
@@ -3176,7 +3191,7 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p,
{
se_priv_copy( &se_rights, &se_machine_account );
can_add_account = user_has_privileges(
- p->pipe_user.nt_user_token, &se_rights );
+ p->server_info->ptok, &se_rights );
}
/* usrmgr.exe (and net rpc trustdom grant) creates a normal user
account for domain trusts and changes the ACB flags later */
@@ -3185,7 +3200,7 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p,
{
se_priv_copy( &se_rights, &se_add_users );
can_add_account = user_has_privileges(
- p->pipe_user.nt_user_token, &se_rights );
+ p->server_info->ptok, &se_rights );
}
else /* implicit assumption of a BDC or domain trust account here
* (we already check the flags earlier) */
@@ -3194,13 +3209,13 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p,
/* only Domain Admins can add a BDC or domain trust */
se_priv_copy( &se_rights, &se_priv_none );
can_add_account = nt_token_check_domain_rid(
- p->pipe_user.nt_user_token,
+ p->server_info->ptok,
DOMAIN_GROUP_RID_ADMINS );
}
}
DEBUG(5, ("_samr_CreateUser2: %s can add this account : %s\n",
- uidtoname(p->pipe_user.ut.uid),
+ uidtoname(p->server_info->utok.uid),
can_add_account ? "True":"False" ));
/********** BEGIN Admin BLOCK **********/
@@ -3225,13 +3240,13 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p,
sid_compose(&sid, get_global_sam_sid(), *r->out.rid);
- map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
+ map_max_allowed_access(p->server_info->ptok, &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);
- nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
+ nt_status = access_check_samr_object(psd, p->server_info->ptok,
&se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
&acc_granted, "_samr_CreateUser2");
@@ -3261,6 +3276,26 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p,
return NT_STATUS_OK;
}
+/****************************************************************
+****************************************************************/
+
+NTSTATUS _samr_CreateUser(pipes_struct *p,
+ struct samr_CreateUser *r)
+{
+ struct samr_CreateUser2 c;
+ uint32_t access_granted;
+
+ c.in.domain_handle = r->in.domain_handle;
+ c.in.account_name = r->in.account_name;
+ c.in.acct_flags = ACB_NORMAL;
+ c.in.access_mask = r->in.access_mask;
+ c.out.user_handle = r->out.user_handle;
+ c.out.access_granted = &access_granted;
+ c.out.rid = r->out.rid;
+
+ return _samr_CreateUser2(p, &c);
+}
+
/*******************************************************************
_samr_Connect
********************************************************************/
@@ -3288,7 +3323,7 @@ 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->pipe_user.nt_user_token, &des_access);
+ map_max_allowed_access(p->server_info->ptok, &des_access);
se_map_generic( &des_access, &sam_generic_mapping );
info->acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS|SAMR_ACCESS_OPEN_DOMAIN);
@@ -3313,24 +3348,36 @@ NTSTATUS _samr_Connect2(pipes_struct *p,
uint32 des_access = r->in.access_mask;
NTSTATUS nt_status;
size_t sd_size;
+ const char *fn = "_samr_Connect2";
+ switch (p->hdr_req.opnum) {
+ case NDR_SAMR_CONNECT2:
+ fn = "_samr_Connect2";
+ break;
+ case NDR_SAMR_CONNECT4:
+ fn = "_samr_Connect4";
+ break;
+ case NDR_SAMR_CONNECT5:
+ fn = "_samr_Connect5";
+ break;
+ }
- DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
+ DEBUG(5,("%s: %d\n", fn, __LINE__));
/* Access check */
if (!pipe_access_check(p)) {
- DEBUG(3, ("access denied to _samr_Connect2\n"));
+ DEBUG(3, ("access denied to %s\n", fn));
return NT_STATUS_ACCESS_DENIED;
}
- map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
+ map_max_allowed_access(p->server_info->ptok, &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);
- nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
- NULL, 0, des_access, &acc_granted, "_samr_Connect2");
+ nt_status = access_check_samr_object(psd, p->server_info->ptok,
+ NULL, 0, des_access, &acc_granted, fn);
if ( !NT_STATUS_IS_OK(nt_status) )
return nt_status;
@@ -3346,7 +3393,7 @@ NTSTATUS _samr_Connect2(pipes_struct *p,
if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
- DEBUG(5,("_samr_Connect2: %d\n", __LINE__));
+ DEBUG(5,("%s: %d\n", fn, __LINE__));
return nt_status;
}
@@ -3358,48 +3405,13 @@ NTSTATUS _samr_Connect2(pipes_struct *p,
NTSTATUS _samr_Connect4(pipes_struct *p,
struct samr_Connect4 *r)
{
- struct samr_info *info = NULL;
- SEC_DESC *psd = NULL;
- uint32 acc_granted;
- uint32 des_access = r->in.access_mask;
- NTSTATUS nt_status;
- size_t sd_size;
-
-
- DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
-
- /* Access check */
-
- if (!pipe_access_check(p)) {
- DEBUG(3, ("access denied to samr_Connect4\n"));
- return NT_STATUS_ACCESS_DENIED;
- }
-
- map_max_allowed_access(p->pipe_user.nt_user_token, &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);
-
- nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
- NULL, 0, des_access, &acc_granted, "_samr_Connect4");
+ struct samr_Connect2 c;
- if ( !NT_STATUS_IS_OK(nt_status) )
- return nt_status;
-
- /* associate the user's SID and access granted with the new handle. */
- if ((info = get_samr_info_by_sid(NULL)) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- info->acc_granted = acc_granted;
- info->status = r->in.access_mask; /* ??? */
-
- /* get a (unique) handle. open a policy on it. */
- if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ c.in.system_name = r->in.system_name;
+ c.in.access_mask = r->in.access_mask;
+ c.out.connect_handle = r->out.connect_handle;
- DEBUG(5,("_samr_Connect4: %d\n", __LINE__));
-
- return NT_STATUS_OK;
+ return _samr_Connect2(p, &c);
}
/*******************************************************************
@@ -3409,50 +3421,22 @@ NTSTATUS _samr_Connect4(pipes_struct *p,
NTSTATUS _samr_Connect5(pipes_struct *p,
struct samr_Connect5 *r)
{
- struct samr_info *info = NULL;
- SEC_DESC *psd = NULL;
- uint32 acc_granted;
- uint32 des_access = r->in.access_mask;
- NTSTATUS nt_status;
- size_t sd_size;
+ NTSTATUS status;
+ struct samr_Connect2 c;
struct samr_ConnectInfo1 info1;
- DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
+ info1.client_version = SAMR_CONNECT_AFTER_W2K;
+ info1.unknown2 = 0;
- /* Access check */
+ c.in.system_name = r->in.system_name;
+ c.in.access_mask = r->in.access_mask;
+ c.out.connect_handle = r->out.connect_handle;
- if (!pipe_access_check(p)) {
- DEBUG(3, ("access denied to samr_Connect5\n"));
- return NT_STATUS_ACCESS_DENIED;
+ status = _samr_Connect2(p, &c);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
- map_max_allowed_access(p->pipe_user.nt_user_token, &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);
-
- nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
- NULL, 0, des_access, &acc_granted, "_samr_Connect5");
-
- if ( !NT_STATUS_IS_OK(nt_status) )
- return nt_status;
-
- /* associate the user's SID and access granted with the new handle. */
- if ((info = get_samr_info_by_sid(NULL)) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- info->acc_granted = acc_granted;
- info->status = r->in.access_mask; /* ??? */
-
- /* get a (unique) handle. open a policy on it. */
- if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info))
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
-
- DEBUG(5,("_samr_Connect5: %d\n", __LINE__));
-
- info1.client_version = SAMR_CONNECT_AFTER_W2K;
- info1.unknown2 = 0;
-
*r->out.level_out = 1;
r->out.info_out->info1 = info1;
@@ -3485,6 +3469,9 @@ NTSTATUS _samr_LookupDomain(pipes_struct *p,
}
domain_name = r->in.domain_name->string;
+ if (!domain_name) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
sid = TALLOC_ZERO_P(p->mem_ctx, struct dom_sid2);
if (!sid) {
@@ -3595,7 +3582,7 @@ NTSTATUS _samr_OpenAlias(pipes_struct *p,
/*check if access can be granted as requested by client. */
- map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
+ map_max_allowed_access(p->server_info->ptok, &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);
@@ -3603,7 +3590,7 @@ NTSTATUS _samr_OpenAlias(pipes_struct *p,
se_priv_copy( &se_rights, &se_add_users );
- status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
+ status = access_check_samr_object(psd, p->server_info->ptok,
&se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
&acc_granted, "_samr_OpenAlias");
@@ -3657,13 +3644,11 @@ static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
if (id7 == NULL) {
DEBUG(5, ("set_user_info_7: NULL id7\n"));
- TALLOC_FREE(pwd);
return NT_STATUS_ACCESS_DENIED;
}
if (!id7->account_name.string) {
DEBUG(5, ("set_user_info_7: failed to get new username\n"));
- TALLOC_FREE(pwd);
return NT_STATUS_ACCESS_DENIED;
}
@@ -3683,7 +3668,6 @@ static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
rc = pdb_rename_sam_account(pwd, id7->account_name.string);
- TALLOC_FREE(pwd);
return rc;
}
@@ -3696,23 +3680,18 @@ static bool set_user_info_16(struct samr_UserInfo16 *id16,
{
if (id16 == NULL) {
DEBUG(5, ("set_user_info_16: NULL id16\n"));
- TALLOC_FREE(pwd);
return False;
}
/* FIX ME: check if the value is really changed --metze */
if (!pdb_set_acct_ctrl(pwd, id16->acct_flags, PDB_CHANGED)) {
- TALLOC_FREE(pwd);
return False;
}
if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
- TALLOC_FREE(pwd);
return False;
}
- TALLOC_FREE(pwd);
-
return True;
}
@@ -3725,29 +3704,23 @@ static bool set_user_info_18(struct samr_UserInfo18 *id18,
{
if (id18 == NULL) {
DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
- TALLOC_FREE(pwd);
return False;
}
if (!pdb_set_lanman_passwd (pwd, id18->lm_pwd.hash, PDB_CHANGED)) {
- TALLOC_FREE(pwd);
return False;
}
if (!pdb_set_nt_passwd (pwd, id18->nt_pwd.hash, PDB_CHANGED)) {
- TALLOC_FREE(pwd);
return False;
}
if (!pdb_set_pass_last_set_time (pwd, time(NULL), PDB_CHANGED)) {
- TALLOC_FREE(pwd);
return False;
}
if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
- TALLOC_FREE(pwd);
return False;
}
- TALLOC_FREE(pwd);
return True;
}
@@ -3767,12 +3740,9 @@ static bool set_user_info_20(struct samr_UserInfo20 *id20,
/* write the change out */
if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
- TALLOC_FREE(pwd);
return False;
}
- TALLOC_FREE(pwd);
-
return True;
}
@@ -3791,6 +3761,14 @@ static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx,
return NT_STATUS_INVALID_PARAMETER;
}
+ if (id21->fields_present == 0) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (id21->fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
/* we need to separately check for an account rename first */
if (id21->account_name.string &&
@@ -3816,7 +3794,6 @@ static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx,
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("set_user_info_21: failed to rename account: %s\n",
nt_errstr(status)));
- TALLOC_FREE(pwd);
return status;
}
@@ -3847,12 +3824,9 @@ static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx,
/* write the change out */
if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
- TALLOC_FREE(pwd);
return status;
}
- TALLOC_FREE(pwd);
-
return NT_STATUS_OK;
}
@@ -3866,7 +3840,7 @@ static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
{
char *plaintext_buf = NULL;
uint32 len = 0;
- uint16 acct_ctrl;
+ uint32_t acct_ctrl;
NTSTATUS status;
if (id23 == NULL) {
@@ -3874,39 +3848,48 @@ static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
return NT_STATUS_INVALID_PARAMETER;
}
- DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
- pdb_get_username(pwd)));
-
- acct_ctrl = pdb_get_acct_ctrl(pwd);
-
- if (!decode_pw_buffer(mem_ctx,
- id23->password.data,
- &plaintext_buf,
- &len,
- STR_UNICODE)) {
- TALLOC_FREE(pwd);
+ if (id23->info.fields_present == 0) {
return NT_STATUS_INVALID_PARAMETER;
- }
+ }
- if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
- TALLOC_FREE(pwd);
+ if (id23->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
return NT_STATUS_ACCESS_DENIED;
}
+ if ((id23->info.fields_present & SAMR_FIELD_PASSWORD) ||
+ (id23->info.fields_present & SAMR_FIELD_PASSWORD2)) {
+
+ DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
+ pdb_get_username(pwd)));
+
+ if (!decode_pw_buffer(mem_ctx,
+ id23->password.data,
+ &plaintext_buf,
+ &len,
+ STR_UNICODE)) {
+ return NT_STATUS_WRONG_PASSWORD;
+ }
+
+ if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+
copy_id23_to_sam_passwd(pwd, id23);
+ acct_ctrl = pdb_get_acct_ctrl(pwd);
+
/* if it's a trust account, don't update /etc/passwd */
if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
DEBUG(5, ("Changing trust account. Not updating /etc/passwd\n"));
- } else {
+ } else if (plaintext_buf) {
/* update the UNIX password */
if (lp_unix_password_sync() ) {
struct passwd *passwd;
if (pdb_get_username(pwd) == NULL) {
DEBUG(1, ("chgpasswd: User without name???\n"));
- TALLOC_FREE(pwd);
return NT_STATUS_ACCESS_DENIED;
}
@@ -3916,29 +3899,26 @@ static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
}
if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
- TALLOC_FREE(pwd);
return NT_STATUS_ACCESS_DENIED;
}
TALLOC_FREE(passwd);
}
}
- memset(plaintext_buf, '\0', strlen(plaintext_buf));
+ if (plaintext_buf) {
+ memset(plaintext_buf, '\0', strlen(plaintext_buf));
+ }
if (IS_SAM_CHANGED(pwd, PDB_GROUPSID) &&
(!NT_STATUS_IS_OK(status = pdb_set_unix_primary_group(mem_ctx,
pwd)))) {
- TALLOC_FREE(pwd);
return status;
}
if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
- TALLOC_FREE(pwd);
return status;
}
- TALLOC_FREE(pwd);
-
return NT_STATUS_OK;
}
@@ -3969,12 +3949,10 @@ static bool set_user_info_pw(uint8 *pass, struct samu *pwd,
&plaintext_buf,
&len,
STR_UNICODE)) {
- TALLOC_FREE(pwd);
return False;
}
if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
- TALLOC_FREE(pwd);
return False;
}
@@ -3990,7 +3968,6 @@ static bool set_user_info_pw(uint8 *pass, struct samu *pwd,
if (pdb_get_username(pwd) == NULL) {
DEBUG(1, ("chgpasswd: User without name???\n"));
- TALLOC_FREE(pwd);
return False;
}
@@ -4000,7 +3977,6 @@ static bool set_user_info_pw(uint8 *pass, struct samu *pwd,
}
if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
- TALLOC_FREE(pwd);
return False;
}
TALLOC_FREE(passwd);
@@ -4028,12 +4004,9 @@ static bool set_user_info_pw(uint8 *pass, struct samu *pwd,
/* update the SAMBA password */
if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
- TALLOC_FREE(pwd);
return False;
}
- TALLOC_FREE(pwd);
-
return True;
}
@@ -4052,11 +4025,18 @@ static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
return NT_STATUS_INVALID_PARAMETER;
}
+ if (id25->info.fields_present == 0) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (id25->info.fields_present & SAMR_FIELD_LAST_PWD_CHANGE) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
copy_id25_to_sam_passwd(pwd, id25);
/* write the change out */
if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
- TALLOC_FREE(pwd);
return status;
}
@@ -4075,9 +4055,6 @@ static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
}
}
- /* WARNING: No TALLOC_FREE(pwd), we are about to set the password
- * hereafter! */
-
return NT_STATUS_OK;
}
@@ -4162,20 +4139,20 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p,
acb_info = pdb_get_acct_ctrl(pwd);
if (acb_info & ACB_WSTRUST)
- has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
+ has_enough_rights = user_has_privileges(p->server_info->ptok,
&se_machine_account);
else if (acb_info & ACB_NORMAL)
- has_enough_rights = user_has_privileges(p->pipe_user.nt_user_token,
+ has_enough_rights = user_has_privileges(p->server_info->ptok,
&se_add_users);
else if (acb_info & (ACB_SVRTRUST|ACB_DOMTRUST)) {
if (lp_enable_privileges()) {
- has_enough_rights = nt_token_check_domain_rid(p->pipe_user.nt_user_token,
+ has_enough_rights = nt_token_check_domain_rid(p->server_info->ptok,
DOMAIN_GROUP_RID_ADMINS);
}
}
DEBUG(5, ("_samr_SetUserInfo: %s does%s possess sufficient rights\n",
- uidtoname(p->pipe_user.ut.uid),
+ uidtoname(p->server_info->utok.uid),
has_enough_rights ? "" : " not"));
/* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
@@ -4242,7 +4219,7 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p,
if (!set_user_info_pw(info->info24.password.data, pwd,
switch_value)) {
- status = NT_STATUS_ACCESS_DENIED;
+ status = NT_STATUS_WRONG_PASSWORD;
}
break;
@@ -4263,7 +4240,7 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p,
}
if (!set_user_info_pw(info->info25.password.data, pwd,
switch_value)) {
- status = NT_STATUS_ACCESS_DENIED;
+ status = NT_STATUS_WRONG_PASSWORD;
}
break;
@@ -4279,7 +4256,7 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p,
if (!set_user_info_pw(info->info26.password.data, pwd,
switch_value)) {
- status = NT_STATUS_ACCESS_DENIED;
+ status = NT_STATUS_WRONG_PASSWORD;
}
break;
@@ -4289,6 +4266,8 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p,
done:
+ TALLOC_FREE(pwd);
+
if (has_enough_rights) {
unbecome_root();
}
@@ -4553,7 +4532,7 @@ NTSTATUS _samr_AddAliasMember(pipes_struct *p,
DEBUG(10, ("sid is %s\n", sid_string_dbg(&alias_sid)));
se_priv_copy( &se_rights, &se_add_users );
- can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+ can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
/******** BEGIN SeAddUsers BLOCK *********/
@@ -4603,7 +4582,7 @@ NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
sid_string_dbg(&alias_sid)));
se_priv_copy( &se_rights, &se_add_users );
- can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+ can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
/******** BEGIN SeAddUsers BLOCK *********/
@@ -4658,7 +4637,7 @@ NTSTATUS _samr_AddGroupMember(pipes_struct *p,
}
se_priv_copy( &se_rights, &se_add_users );
- can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+ can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
/******** BEGIN SeAddUsers BLOCK *********/
@@ -4716,7 +4695,7 @@ NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
}
se_priv_copy( &se_rights, &se_add_users );
- can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+ can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
/******** BEGIN SeAddUsers BLOCK *********/
@@ -4787,9 +4766,9 @@ NTSTATUS _samr_DeleteUser(pipes_struct *p,
/* For machine accounts it's the SeMachineAccountPrivilege that counts. */
if ( acb_info & ACB_WSTRUST ) {
- can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account );
+ can_add_accounts = user_has_privileges( p->server_info->ptok, &se_machine_account );
} else {
- can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
+ can_add_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
}
/******** BEGIN SeAddUsers BLOCK *********/
@@ -4861,7 +4840,7 @@ NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
}
se_priv_copy( &se_rights, &se_add_users );
- can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+ can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
/******** BEGIN SeAddUsers BLOCK *********/
@@ -4936,7 +4915,7 @@ NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
DEBUG(10, ("lookup on Local SID\n"));
se_priv_copy( &se_rights, &se_add_users );
- can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+ can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
/******** BEGIN SeAddUsers BLOCK *********/
@@ -5005,7 +4984,7 @@ NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
}
se_priv_copy( &se_rights, &se_add_users );
- can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+ can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
/******** BEGIN SeAddUsers BLOCK *********/
@@ -5079,7 +5058,7 @@ NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
name = r->in.alias_name->string;
se_priv_copy( &se_rights, &se_add_users );
- can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+ can_add_accounts = user_has_privileges( p->server_info->ptok, &se_rights );
result = can_create(p->mem_ctx, name);
if (!NT_STATUS_IS_OK(result)) {
@@ -5291,7 +5270,7 @@ NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
return NT_STATUS_INVALID_INFO_CLASS;
}
- can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
+ can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
/******** BEGIN SeAddUsers BLOCK *********/
@@ -5393,7 +5372,7 @@ NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
return NT_STATUS_INVALID_INFO_CLASS;
}
- can_mod_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
+ can_mod_accounts = user_has_privileges( p->server_info->ptok, &se_add_users );
/******** BEGIN SeAddUsers BLOCK *********/
@@ -5481,14 +5460,14 @@ NTSTATUS _samr_OpenGroup(pipes_struct *p,
return status;
/*check if access can be granted as requested by client. */
- map_max_allowed_access(p->pipe_user.nt_user_token, &des_access);
+ map_max_allowed_access(p->server_info->ptok, &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);
se_priv_copy( &se_rights, &se_add_users );
- status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
+ status = access_check_samr_object(psd, p->server_info->ptok,
&se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
&acc_granted, "_samr_OpenGroup");
@@ -5842,16 +5821,6 @@ NTSTATUS _samr_Shutdown(pipes_struct *p,
/****************************************************************
****************************************************************/
-NTSTATUS _samr_CreateUser(pipes_struct *p,
- struct samr_CreateUser *r)
-{
- p->rng_fault_state = true;
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-/****************************************************************
-****************************************************************/
-
NTSTATUS _samr_SetMemberAttributesOfGroup(pipes_struct *p,
struct samr_SetMemberAttributesOfGroup *r)
{
@@ -5892,16 +5861,6 @@ NTSTATUS _samr_TestPrivateFunctionsUser(pipes_struct *p,
/****************************************************************
****************************************************************/
-NTSTATUS _samr_QueryUserInfo2(pipes_struct *p,
- struct samr_QueryUserInfo2 *r)
-{
- p->rng_fault_state = true;
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-/****************************************************************
-****************************************************************/
-
NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p,
struct samr_AddMultipleMembersToAlias *r)
{
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 577f7f1ded..744de67db4 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -388,7 +388,8 @@ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
return WERR_BADFID;
}
- return delete_printer_hook(p->mem_ctx, p->pipe_user.nt_user_token, Printer->sharename );
+ return delete_printer_hook(p->mem_ctx, p->server_info->ptok,
+ Printer->sharename );
}
/****************************************************************************
@@ -1656,13 +1657,13 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
/* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
and not a printer admin, then fail */
- if ((p->pipe_user.ut.uid != 0) &&
- !user_has_privileges(p->pipe_user.nt_user_token,
+ if ((p->server_info->utok.uid != 0) &&
+ !user_has_privileges(p->server_info->ptok,
&se_printop ) &&
!token_contains_name_in_list(
- uidtoname(p->pipe_user.ut.uid),
+ uidtoname(p->server_info->utok.uid),
NULL, NULL,
- p->pipe_user.nt_user_token,
+ p->server_info->ptok,
lp_printer_admin(snum))) {
close_printer_handle(p, handle);
return WERR_ACCESS_DENIED;
@@ -1715,8 +1716,8 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
return WERR_ACCESS_DENIED;
}
- if (!user_ok_token(uidtoname(p->pipe_user.ut.uid), NULL,
- p->pipe_user.nt_user_token, snum) ||
+ if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
+ p->server_info->ptok, snum) ||
!print_access_check(p->server_info, snum,
printer_default->access_required)) {
DEBUG(3, ("access DENIED for printer open\n"));
@@ -2018,11 +2019,11 @@ WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER
/* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
and not a printer admin, then fail */
- if ( (p->pipe_user.ut.uid != 0)
- && !user_has_privileges(p->pipe_user.nt_user_token, &se_printop )
+ if ( (p->server_info->utok.uid != 0)
+ && !user_has_privileges(p->server_info->ptok, &se_printop )
&& !token_contains_name_in_list(
- uidtoname(p->pipe_user.ut.uid), NULL,
- NULL, p->pipe_user.nt_user_token,
+ uidtoname(p->server_info->utok.uid), NULL,
+ NULL, p->server_info->ptok,
lp_printer_admin(-1)) )
{
return WERR_ACCESS_DENIED;
@@ -2070,7 +2071,8 @@ WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER
/* if we get to here, we now have 2 driver info structures to remove */
/* remove the Win2k driver first*/
- status_win2k = delete_printer_driver(info_win2k.info_3, &p->pipe_user, 3, False );
+ status_win2k = delete_printer_driver(
+ p, info_win2k.info_3, 3, False );
free_a_printer_driver( info_win2k, 3 );
/* this should not have failed---if it did, report to client */
@@ -2082,7 +2084,7 @@ WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER
}
}
- status = delete_printer_driver(info.info_3, &p->pipe_user, version, False);
+ status = delete_printer_driver(p, info.info_3, version, False);
/* if at least one of the deletes succeeded return OK */
@@ -2115,11 +2117,11 @@ WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIV
/* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
and not a printer admin, then fail */
- if ( (p->pipe_user.ut.uid != 0)
- && !user_has_privileges(p->pipe_user.nt_user_token, &se_printop )
+ if ( (p->server_info->utok.uid != 0)
+ && !user_has_privileges(p->server_info->ptok, &se_printop )
&& !token_contains_name_in_list(
- uidtoname(p->pipe_user.ut.uid), NULL, NULL,
- p->pipe_user.nt_user_token, lp_printer_admin(-1)) )
+ uidtoname(p->server_info->utok.uid), NULL, NULL,
+ p->server_info->ptok, lp_printer_admin(-1)) )
{
return WERR_ACCESS_DENIED;
}
@@ -2205,7 +2207,8 @@ WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIV
/* if we get to here, we now have 2 driver info structures to remove */
/* remove the Win2k driver first*/
- status_win2k = delete_printer_driver(info_win2k.info_3, &p->pipe_user, 3, delete_files);
+ status_win2k = delete_printer_driver(
+ p, info_win2k.info_3, 3, delete_files);
free_a_printer_driver( info_win2k, 3 );
/* this should not have failed---if it did, report to client */
@@ -2215,7 +2218,7 @@ WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIV
}
}
- status = delete_printer_driver(info.info_3, &p->pipe_user, version, delete_files);
+ status = delete_printer_driver(p, info.info_3, version, delete_files);
if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
status = WERR_OK;
@@ -6388,7 +6391,8 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
{
/* add_printer_hook() will call reload_services() */
- if ( !add_printer_hook(p->mem_ctx, p->pipe_user.nt_user_token, printer) ) {
+ if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
+ printer) ) {
result = WERR_ACCESS_DENIED;
goto done;
}
@@ -7482,11 +7486,11 @@ WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines )
/* if no hook then just fill in the default port */
if ( !*cmd ) {
- if (!(qlines = SMB_MALLOC_ARRAY( char*, 2 ))) {
+ if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
return WERR_NOMEM;
}
- if (!(qlines[0] = SMB_STRDUP( SAMBA_PRINTER_PORT_NAME ))) {
- SAFE_FREE(qlines);
+ if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
+ TALLOC_FREE(qlines);
return WERR_NOMEM;
}
qlines[1] = NULL;
@@ -7728,7 +7732,8 @@ static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_
trying to add a printer like this --jerry */
if (*lp_addprinter_cmd() ) {
- if ( !add_printer_hook(p->mem_ctx, p->pipe_user.nt_user_token, printer) ) {
+ if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
+ printer) ) {
free_a_printer(&printer,2);
return WERR_ACCESS_DENIED;
}
@@ -7855,12 +7860,13 @@ WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u,
}
DEBUG(5,("Cleaning driver's information\n"));
- err = clean_up_driver_struct(driver, level, &p->pipe_user);
+ err = clean_up_driver_struct(p, driver, level);
if (!W_ERROR_IS_OK(err))
goto done;
DEBUG(5,("Moving driver to final destination\n"));
- if( !W_ERROR_IS_OK(err = move_driver_to_download_area(driver, level, &p->pipe_user, &err)) ) {
+ if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, driver, level,
+ &err)) ) {
goto done;
}
@@ -9935,10 +9941,10 @@ WERROR _spoolss_xcvdataport(pipes_struct *p, SPOOL_Q_XCVDATAPORT *q_u, SPOOL_R_X
switch ( Printer->printer_type ) {
case SPLHND_PORTMON_TCP:
- return process_xcvtcp_command( p->pipe_user.nt_user_token, command,
+ return process_xcvtcp_command( p->server_info->ptok, command,
&q_u->indata, &r_u->outdata, &r_u->needed );
case SPLHND_PORTMON_LOCAL:
- return process_xcvlocal_command( p->pipe_user.nt_user_token, command,
+ return process_xcvlocal_command( p->server_info->ptok, command,
&q_u->indata, &r_u->outdata, &r_u->needed );
}
diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c
index 9d9e9af59b..bf3669022d 100644
--- a/source3/rpc_server/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srv_srvsvc_nt.c
@@ -262,7 +262,7 @@ static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *
remark = talloc_sub_advanced(
p->mem_ctx, lp_servicename(snum),
get_current_username(), lp_pathname(snum),
- p->pipe_user.ut.uid, get_current_username(),
+ p->server_info->utok.uid, get_current_username(),
"", remark);
}
@@ -289,7 +289,7 @@ static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *
remark = talloc_sub_advanced(
p->mem_ctx, lp_servicename(snum),
get_current_username(), lp_pathname(snum),
- p->pipe_user.ut.uid, get_current_username(),
+ p->server_info->utok.uid, get_current_username(),
"", remark);
}
path = talloc_asprintf(p->mem_ctx,
@@ -355,7 +355,7 @@ static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo5
remark = talloc_sub_advanced(
p->mem_ctx, lp_servicename(snum),
get_current_username(), lp_pathname(snum),
- p->pipe_user.ut.uid, get_current_username(),
+ p->server_info->utok.uid, get_current_username(),
"", remark);
}
@@ -383,7 +383,7 @@ static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo5
remark = talloc_sub_advanced(
p->mem_ctx, lp_servicename(snum),
get_current_username(), lp_pathname(snum),
- p->pipe_user.ut.uid, get_current_username(),
+ p->server_info->utok.uid, get_current_username(),
"", remark);
}
path = talloc_asprintf(ctx, "C:%s", lp_pathname(snum));
@@ -422,7 +422,7 @@ static void init_srv_share_info_1004(pipes_struct *p, struct srvsvc_NetShareInfo
remark = talloc_sub_advanced(
p->mem_ctx, lp_servicename(snum),
get_current_username(), lp_pathname(snum),
- p->pipe_user.ut.uid, get_current_username(),
+ p->server_info->utok.uid, get_current_username(),
"", remark);
}
@@ -1225,7 +1225,6 @@ WERROR _srvsvc_NetSessDel(pipes_struct *p,
struct srvsvc_NetSessDel *r)
{
struct sessionid *session_list;
- struct current_user user;
int num_sessions, snum;
const char *username;
const char *machine;
@@ -1246,12 +1245,11 @@ WERROR _srvsvc_NetSessDel(pipes_struct *p,
werr = WERR_ACCESS_DENIED;
- get_current_user(&user, p);
-
/* fail out now if you are not root or not a domain admin */
- if ((user.ut.uid != sec_initial_uid()) &&
- ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
+ if ((p->server_info->utok.uid != sec_initial_uid()) &&
+ ( ! nt_token_check_domain_rid(p->server_info->ptok,
+ DOMAIN_GROUP_RID_ADMINS))) {
goto done;
}
@@ -1263,7 +1261,7 @@ WERROR _srvsvc_NetSessDel(pipes_struct *p,
NTSTATUS ntstat;
- if (user.ut.uid != sec_initial_uid()) {
+ if (p->server_info->utok.uid != sec_initial_uid()) {
not_root = True;
become_root();
}
@@ -1466,7 +1464,6 @@ char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
WERROR _srvsvc_NetShareSetInfo(pipes_struct *p,
struct srvsvc_NetShareSetInfo *r)
{
- struct current_user user;
char *command = NULL;
char *share_name = NULL;
char *comment = NULL;
@@ -1510,13 +1507,11 @@ WERROR _srvsvc_NetShareSetInfo(pipes_struct *p,
if (lp_print_ok(snum))
return WERR_ACCESS_DENIED;
- get_current_user(&user,p);
-
- is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
+ is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
/* fail out now if you are not root and not a disk op */
- if ( user.ut.uid != sec_initial_uid() && !is_disk_op )
+ if ( p->server_info->utok.uid != sec_initial_uid() && !is_disk_op )
return WERR_ACCESS_DENIED;
switch (r->in.level) {
@@ -1683,7 +1678,6 @@ WERROR _srvsvc_NetShareSetInfo(pipes_struct *p,
WERROR _srvsvc_NetShareAdd(pipes_struct *p,
struct srvsvc_NetShareAdd *r)
{
- struct current_user user;
char *command = NULL;
char *share_name = NULL;
char *comment = NULL;
@@ -1704,11 +1698,9 @@ WERROR _srvsvc_NetShareAdd(pipes_struct *p,
*r->out.parm_error = 0;
}
- get_current_user(&user,p);
+ is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
- is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
-
- if (user.ut.uid != sec_initial_uid() && !is_disk_op )
+ if (p->server_info->utok.uid != sec_initial_uid() && !is_disk_op )
return WERR_ACCESS_DENIED;
if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
@@ -1868,7 +1860,6 @@ WERROR _srvsvc_NetShareAdd(pipes_struct *p,
WERROR _srvsvc_NetShareDel(pipes_struct *p,
struct srvsvc_NetShareDel *r)
{
- struct current_user user;
char *command = NULL;
char *share_name = NULL;
int ret;
@@ -1901,11 +1892,9 @@ WERROR _srvsvc_NetShareDel(pipes_struct *p,
if (lp_print_ok(snum))
return WERR_ACCESS_DENIED;
- get_current_user(&user,p);
-
- is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
+ is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
- if (user.ut.uid != sec_initial_uid() && !is_disk_op )
+ if (p->server_info->utok.uid != sec_initial_uid() && !is_disk_op )
return WERR_ACCESS_DENIED;
if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
@@ -2050,7 +2039,8 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
}
nt_status = create_conn_struct(talloc_tos(), &conn, snum,
- lp_pathname(snum), &oldcwd);
+ lp_pathname(snum), p->server_info,
+ &oldcwd);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(10, ("create_conn_struct failed: %s\n",
nt_errstr(nt_status)));
@@ -2058,8 +2048,6 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
goto error_exit;
}
- conn->server_info = p->server_info;
-
nt_status = create_file(
conn, /* conn */
NULL, /* req */
@@ -2165,7 +2153,8 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
}
nt_status = create_conn_struct(talloc_tos(), &conn, snum,
- lp_pathname(snum), &oldcwd);
+ lp_pathname(snum), p->server_info,
+ &oldcwd);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(10, ("create_conn_struct failed: %s\n",
nt_errstr(nt_status)));
@@ -2173,8 +2162,6 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
goto error_exit;
}
- conn->server_info = p->server_info;
-
nt_status = create_file(
conn, /* conn */
NULL, /* req */
@@ -2411,17 +2398,14 @@ static void enum_file_close_fn( const struct share_mode_entry *e,
WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r)
{
- struct current_user user;
SE_PRIV se_diskop = SE_DISK_OPERATOR;
bool is_disk_op;
DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
- get_current_user(&user,p);
-
- is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
+ is_disk_op = user_has_privileges( p->server_info->ptok, &se_diskop );
- if (user.ut.uid != sec_initial_uid() && !is_disk_op) {
+ if (p->server_info->utok.uid != sec_initial_uid() && !is_disk_op) {
return WERR_ACCESS_DENIED;
}
diff --git a/source3/rpc_server/srv_svcctl_nt.c b/source3/rpc_server/srv_svcctl_nt.c
index cb6657400f..6692160ba2 100644
--- a/source3/rpc_server/srv_svcctl_nt.c
+++ b/source3/rpc_server/srv_svcctl_nt.c
@@ -272,7 +272,8 @@ WERROR _svcctl_OpenSCManagerW(pipes_struct *p,
return WERR_NOMEM;
se_map_generic( &r->in.access_mask, &scm_generic_map );
- status = svcctl_access_check( sec_desc, p->pipe_user.nt_user_token, r->in.access_mask, &access_granted );
+ status = svcctl_access_check( sec_desc, p->server_info->ptok,
+ r->in.access_mask, &access_granted );
if ( !NT_STATUS_IS_OK(status) )
return ntstatus_to_werror( status );
@@ -309,7 +310,8 @@ WERROR _svcctl_OpenServiceW(pipes_struct *p,
return WERR_NOMEM;
se_map_generic( &r->in.access_mask, &svc_generic_map );
- status = svcctl_access_check( sec_desc, p->pipe_user.nt_user_token, r->in.access_mask, &access_granted );
+ status = svcctl_access_check( sec_desc, p->server_info->ptok,
+ r->in.access_mask, &access_granted );
if ( !NT_STATUS_IS_OK(status) )
return ntstatus_to_werror( status );
@@ -347,7 +349,8 @@ WERROR _svcctl_GetServiceDisplayNameW(pipes_struct *p,
service = r->in.service_name;
- display_name = svcctl_lookup_dispname(p->mem_ctx, service, p->pipe_user.nt_user_token );
+ display_name = svcctl_lookup_dispname(p->mem_ctx, service,
+ p->server_info->ptok);
if (!display_name) {
display_name = "";
}
@@ -424,7 +427,7 @@ WERROR _svcctl_enum_services_status(pipes_struct *p, SVCCTL_Q_ENUM_SERVICES_STAT
size_t buffer_size = 0;
WERROR result = WERR_OK;
SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle );
- NT_USER_TOKEN *token = p->pipe_user.nt_user_token;
+ NT_USER_TOKEN *token = p->server_info->ptok;
/* perform access checks */
@@ -517,11 +520,9 @@ WERROR _svcctl_ControlService(pipes_struct *p,
return info->ops->service_status( info->name,
r->out.service_status );
+ default:
+ return WERR_ACCESS_DENIED;
}
-
- /* default control action */
-
- return WERR_ACCESS_DENIED;
}
/********************************************************************
@@ -682,7 +683,8 @@ WERROR _svcctl_QueryServiceConfigW(pipes_struct *p,
*r->out.bytes_needed = r->in.buf_size;
- wresult = fill_svc_config( p->mem_ctx, info->name, r->out.query, p->pipe_user.nt_user_token );
+ wresult = fill_svc_config( p->mem_ctx, info->name, r->out.query,
+ p->server_info->ptok);
if ( !W_ERROR_IS_OK(wresult) )
return wresult;
@@ -690,7 +692,7 @@ WERROR _svcctl_QueryServiceConfigW(pipes_struct *p,
*r->out.bytes_needed = (buffer_size > r->in.buf_size) ? buffer_size : r->in.buf_size;
if (buffer_size > r->in.buf_size ) {
- TALLOC_FREE(r->out.query);
+ ZERO_STRUCTP(r->out.query);
return WERR_INSUFFICIENT_BUFFER;
}
@@ -725,7 +727,8 @@ WERROR _svcctl_query_service_config2( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CO
SERVICE_DESCRIPTION desc_buf;
const char *description;
- description = svcctl_lookup_description(p->mem_ctx, info->name, p->pipe_user.nt_user_token );
+ description = svcctl_lookup_description(
+ p->mem_ctx, info->name, p->server_info->ptok);
ZERO_STRUCTP( &desc_buf );
@@ -905,7 +908,8 @@ WERROR _svcctl_SetServiceObjectSecurity(pipes_struct *p,
/* store the new SD */
- if ( !svcctl_set_secdesc( p->mem_ctx, info->name, sec_desc, p->pipe_user.nt_user_token ) )
+ if ( !svcctl_set_secdesc( p->mem_ctx, info->name, sec_desc,
+ p->server_info->ptok) )
return WERR_ACCESS_DENIED;
return WERR_OK;
diff --git a/source3/rpc_server/srv_winreg_nt.c b/source3/rpc_server/srv_winreg_nt.c
index 7e842ed54d..1131033b04 100644
--- a/source3/rpc_server/srv_winreg_nt.c
+++ b/source3/rpc_server/srv_winreg_nt.c
@@ -70,7 +70,7 @@ static WERROR open_registry_key( pipes_struct *p, POLICY_HND *hnd,
if (parent == NULL) {
result = reg_openhive(NULL, subkeyname, access_desired,
- p->pipe_user.nt_user_token, &key);
+ p->server_info->ptok, &key);
}
else {
result = reg_openkey(NULL, parent, subkeyname, access_desired,
@@ -556,7 +556,8 @@ WERROR _winreg_InitiateSystemShutdownEx(pipes_struct *p, struct winreg_InitiateS
return WERR_NOMEM;
}
- can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
+ can_shutdown = user_has_privileges( p->server_info->ptok,
+ &se_remote_shutdown );
/* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
Take the error return from the script and provide it as the Windows return code. */
@@ -594,7 +595,8 @@ WERROR _winreg_AbortSystemShutdown(pipes_struct *p, struct winreg_AbortSystemShu
if (!*abort_shutdown_script)
return WERR_ACCESS_DENIED;
- can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_remote_shutdown );
+ can_shutdown = user_has_privileges( p->server_info->ptok,
+ &se_remote_shutdown );
/********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
@@ -682,7 +684,7 @@ WERROR _winreg_RestoreKey(pipes_struct *p, struct winreg_RestoreKey *r)
/* user must posses SeRestorePrivilege for this this proceed */
- if ( !user_has_privileges( p->pipe_user.nt_user_token, &se_restore ) )
+ if ( !user_has_privileges( p->server_info->ptok, &se_restore ) )
return WERR_ACCESS_DENIED;
DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
diff --git a/source3/rpc_server/srv_wkssvc_nt.c b/source3/rpc_server/srv_wkssvc_nt.c
index 0a54b0dd3f..7071b55e7c 100644
--- a/source3/rpc_server/srv_wkssvc_nt.c
+++ b/source3/rpc_server/srv_wkssvc_nt.c
@@ -293,7 +293,7 @@ WERROR _wkssvc_NetrJoinDomain2(pipes_struct *p,
char *admin_domain = NULL;
char *admin_account = NULL;
WERROR werr;
- struct nt_user_token *token = p->pipe_user.nt_user_token;
+ struct nt_user_token *token = p->server_info->ptok;
if (!r->in.domain_name) {
return WERR_INVALID_PARAM;
@@ -368,7 +368,7 @@ WERROR _wkssvc_NetrUnjoinDomain2(pipes_struct *p,
char *admin_domain = NULL;
char *admin_account = NULL;
WERROR werr;
- struct nt_user_token *token = p->pipe_user.nt_user_token;
+ struct nt_user_token *token = p->server_info->ptok;
if (!r->in.account || !r->in.encrypted_password) {
return WERR_INVALID_PARAM;
diff --git a/source3/rpcclient/cmd_netlogon.c b/source3/rpcclient/cmd_netlogon.c
index 9e3f35545c..9955d2d3fa 100644
--- a/source3/rpcclient/cmd_netlogon.c
+++ b/source3/rpcclient/cmd_netlogon.c
@@ -1040,6 +1040,72 @@ static WERROR cmd_netlogon_getdcsitecoverage(struct rpc_pipe_client *cli,
return werr;
}
+static NTSTATUS cmd_netlogon_database_redo(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ const char **argv)
+{
+ NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
+ const char *server_name = cli->desthost;
+ uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
+ struct netr_Authenticator clnt_creds, srv_cred;
+ struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
+ unsigned char trust_passwd_hash[16];
+ uint32_t sec_channel_type = 0;
+ struct netr_ChangeLogEntry e;
+ uint32_t rid = 500;
+
+ if (argc > 2) {
+ fprintf(stderr, "Usage: %s <user rid>\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ if (argc == 2) {
+ sscanf(argv[1], "%d", &rid);
+ }
+
+ if (!secrets_fetch_trust_account_password(lp_workgroup(),
+ trust_passwd_hash,
+ NULL, &sec_channel_type)) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ status = rpccli_netlogon_setup_creds(cli,
+ server_name, /* server name */
+ lp_workgroup(), /* domain */
+ global_myname(), /* client name */
+ global_myname(), /* machine account name */
+ trust_passwd_hash,
+ sec_channel_type,
+ &neg_flags);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ netlogon_creds_client_step(cli->dc, &clnt_creds);
+
+ ZERO_STRUCT(e);
+
+ e.object_rid = rid;
+ e.db_index = SAM_DATABASE_DOMAIN;
+ e.delta_type = NETR_DELTA_USER;
+
+ status = rpccli_netr_DatabaseRedo(cli, mem_ctx,
+ server_name,
+ global_myname(),
+ &clnt_creds,
+ &srv_cred,
+ e,
+ 0, /* is calculated automatically */
+ &delta_enum_array);
+
+ if (!netlogon_creds_client_check(cli->dc, &srv_cred.cred)) {
+ DEBUG(0,("credentials chain check failed\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return status;
+}
/* List of commands exported by this module */
@@ -1067,6 +1133,7 @@ struct cmd_set netlogon_commands[] = {
{ "netrenumtrusteddomains", RPC_RTYPE_WERROR, NULL, cmd_netlogon_enumtrusteddomains, &ndr_table_netlogon.syntax_id, NULL, "Enumerate trusted domains", "" },
{ "netrenumtrusteddomainsex", RPC_RTYPE_WERROR, NULL, cmd_netlogon_enumtrusteddomainsex, &ndr_table_netlogon.syntax_id, NULL, "Enumerate trusted domains", "" },
{ "getdcsitecoverage", RPC_RTYPE_WERROR, NULL, cmd_netlogon_getdcsitecoverage, &ndr_table_netlogon.syntax_id, NULL, "Get the Site-Coverage from a DC", "" },
+ { "database_redo", RPC_RTYPE_NTSTATUS, cmd_netlogon_database_redo, NULL, &ndr_table_netlogon.syntax_id, NULL, "Replicate single object from a DC", "" },
{ NULL }
};
diff --git a/source3/rpcclient/cmd_ntsvcs.c b/source3/rpcclient/cmd_ntsvcs.c
index 377a8a2a00..eb620d06b2 100644
--- a/source3/rpcclient/cmd_ntsvcs.c
+++ b/source3/rpcclient/cmd_ntsvcs.c
@@ -75,44 +75,6 @@ static WERROR cmd_ntsvcs_validate_dev_inst(struct rpc_pipe_client *cli,
return werr;
}
-static WERROR cmd_ntsvcs_get_device_list_size(struct rpc_pipe_client *cli,
- TALLOC_CTX *mem_ctx,
- int argc,
- const char **argv)
-{
- NTSTATUS status;
- WERROR werr;
- const char *devicename = NULL;
- uint32_t flags = 0;
- uint32_t size = 0;
-
- if (argc < 2 || argc > 4) {
- printf("usage: %s [devicename] <flags>\n", argv[0]);
- return WERR_OK;
- }
-
- devicename = argv[1];
-
- if (argc >= 3) {
- flags = atoi(argv[2]);
- }
-
- status = rpccli_PNP_GetDeviceListSize(cli, mem_ctx,
- devicename,
- &size,
- flags,
- &werr);
- if (!NT_STATUS_IS_OK(status)) {
- return ntstatus_to_werror(status);
- }
-
- if (W_ERROR_IS_OK(werr)) {
- printf("size: %d\n", size);
- }
-
- return werr;
-}
-
static WERROR cmd_ntsvcs_hw_prof_flags(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
int argc,
@@ -121,8 +83,8 @@ static WERROR cmd_ntsvcs_hw_prof_flags(struct rpc_pipe_client *cli,
NTSTATUS status;
WERROR werr;
const char *devicepath = NULL;
- uint32_t unk3 = 0;
- uint16_t unk4 = 0;
+ uint32_t profile_flags = 0;
+ uint16_t veto_type = 0;
const char *unk5 = NULL;
const char *unk5a = NULL;
@@ -137,8 +99,8 @@ static WERROR cmd_ntsvcs_hw_prof_flags(struct rpc_pipe_client *cli,
0,
devicepath,
0,
- &unk3,
- &unk4,
+ &profile_flags,
+ &veto_type,
unk5,
&unk5a,
0,
@@ -160,15 +122,15 @@ static WERROR cmd_ntsvcs_get_hw_prof_info(struct rpc_pipe_client *cli,
WERROR werr;
uint32_t idx = 0;
struct PNP_HwProfInfo info;
- uint32_t unknown1 = 0, unknown2 = 0;
+ uint32_t size = 0, flags = 0;
ZERO_STRUCT(info);
status = rpccli_PNP_GetHwProfInfo(cli, mem_ctx,
idx,
&info,
- unknown1,
- unknown2,
+ size,
+ flags,
&werr);
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
@@ -186,27 +148,35 @@ static WERROR cmd_ntsvcs_get_dev_reg_prop(struct rpc_pipe_client *cli,
WERROR werr;
const char *devicepath = NULL;
uint32_t property = DEV_REGPROP_DESC;
- uint32_t unknown1 = 0;
- uint8_t buffer;
+ uint32_t reg_data_type = REG_NONE;
+ uint8_t *buffer;
uint32_t buffer_size = 0;
- uint32_t unknown2 = 0;
- uint32_t unknown3 = 0;
+ uint32_t needed = 0;
+ uint32_t flags = 0;
if (argc < 2) {
- printf("usage: %s [devicepath]\n", argv[0]);
+ printf("usage: %s [devicepath] [buffersize]\n", argv[0]);
return WERR_OK;
}
devicepath = argv[1];
+ if (argc >= 3) {
+ buffer_size = atoi(argv[2]);
+ needed = buffer_size;
+ }
+
+ buffer = talloc_array(mem_ctx, uint8_t, buffer_size);
+ W_ERROR_HAVE_NO_MEMORY(buffer);
+
status = rpccli_PNP_GetDeviceRegProp(cli, mem_ctx,
devicepath,
property,
- &unknown1,
- &buffer,
+ &reg_data_type,
+ buffer,
&buffer_size,
- &unknown2,
- unknown3,
+ &needed,
+ flags,
&werr);
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
@@ -215,15 +185,98 @@ static WERROR cmd_ntsvcs_get_dev_reg_prop(struct rpc_pipe_client *cli,
return werr;
}
+static WERROR cmd_ntsvcs_get_dev_list_size(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
+{
+ NTSTATUS status;
+ WERROR werr;
+ uint32_t size = 0;
+ uint32_t flags = 0;
+ const char *filter = NULL;
+
+ if (argc > 3) {
+ printf("usage: %s [filter] [flags]\n", argv[0]);
+ return WERR_OK;
+ }
+
+ if (argc >= 2) {
+ filter = argv[1];
+ }
+
+ if (argc >= 3) {
+ flags = atoi(argv[2]);
+ }
+
+ status = rpccli_PNP_GetDeviceListSize(cli, mem_ctx,
+ filter,
+ &size,
+ flags,
+ &werr);
+ if (!NT_STATUS_IS_OK(status)) {
+ return ntstatus_to_werror(status);
+ }
+
+ printf("size: %d\n", size);
+
+ return werr;
+}
+
+static WERROR cmd_ntsvcs_get_dev_list(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv)
+{
+ NTSTATUS status;
+ WERROR werr;
+ const char *filter = NULL;
+ uint16_t *buffer = NULL;
+ uint32_t length = 0;
+ uint32_t flags = 0;
+
+ if (argc > 3) {
+ printf("usage: %s [length] [filter]\n", argv[0]);
+ return WERR_OK;
+ }
+
+ if (argc >= 2) {
+ length = atoi(argv[1]);
+ }
+
+ if (argc >= 3) {
+ filter = argv[2];
+ }
+
+ buffer = talloc(mem_ctx, uint16_t);
+ if (!buffer) {
+ return WERR_NOMEM;
+ }
+
+ status = rpccli_PNP_GetDeviceList(cli, mem_ctx,
+ filter,
+ buffer,
+ &length,
+ flags,
+ &werr);
+ if (!NT_STATUS_IS_OK(status)) {
+ return ntstatus_to_werror(status);
+ }
+
+ printf("devlist needs size: %d\n", length);
+
+ return werr;
+}
struct cmd_set ntsvcs_commands[] = {
{ "NTSVCS" },
{ "ntsvcs_getversion", RPC_RTYPE_WERROR, NULL, cmd_ntsvcs_get_version, &ndr_table_ntsvcs.syntax_id, NULL, "Query NTSVCS version", "" },
{ "ntsvcs_validatedevinst", RPC_RTYPE_WERROR, NULL, cmd_ntsvcs_validate_dev_inst, &ndr_table_ntsvcs.syntax_id, NULL, "Query NTSVCS device instance", "" },
- { "ntsvcs_getdevlistsize", RPC_RTYPE_WERROR, NULL, cmd_ntsvcs_get_device_list_size, &ndr_table_ntsvcs.syntax_id, NULL, "Query NTSVCS get device list", "" },
{ "ntsvcs_hwprofflags", RPC_RTYPE_WERROR, NULL, cmd_ntsvcs_hw_prof_flags, &ndr_table_ntsvcs.syntax_id, NULL, "Query NTSVCS HW prof flags", "" },
{ "ntsvcs_hwprofinfo", RPC_RTYPE_WERROR, NULL, cmd_ntsvcs_get_hw_prof_info, &ndr_table_ntsvcs.syntax_id, NULL, "Query NTSVCS HW prof info", "" },
{ "ntsvcs_getdevregprop", RPC_RTYPE_WERROR, NULL, cmd_ntsvcs_get_dev_reg_prop, &ndr_table_ntsvcs.syntax_id, NULL, "Query NTSVCS device registry property", "" },
+ { "ntsvcs_getdevlistsize", RPC_RTYPE_WERROR, NULL, cmd_ntsvcs_get_dev_list_size, &ndr_table_ntsvcs.syntax_id, NULL, "Query NTSVCS device list size", "" },
+ { "ntsvcs_getdevlist", RPC_RTYPE_WERROR, NULL, cmd_ntsvcs_get_dev_list, &ndr_table_ntsvcs.syntax_id, NULL, "Query NTSVCS device list", "" },
{ NULL }
};
diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c
index 3494e9123a..eaf5adbfa5 100644
--- a/source3/rpcclient/cmd_samr.c
+++ b/source3/rpcclient/cmd_samr.c
@@ -161,7 +161,7 @@ static void display_sam_dom_info_2(struct samr_DomGeneralInformation *general)
printf("Force Logoff:\t%d\n",
(int)nt_time_to_unix_abs(&general->force_logoff_time));
- printf("Unknown 2:\t0x%x\n", general->unknown2);
+ printf("Domain Server State:\t0x%x\n", general->domain_server_state);
printf("Server Role:\t%s\n", server_role_str(general->role));
printf("Unknown 3:\t0x%x\n", general->unknown3);
}
@@ -201,7 +201,7 @@ static void display_sam_dom_info_8(struct samr_DomInfo8 *info8)
static void display_sam_dom_info_9(struct samr_DomInfo9 *info9)
{
- printf("unknown:\t%d (0x%08x)\n", info9->unknown, info9->unknown);
+ printf("Domain Server State:\t0x%x\n", info9->domain_server_state);
}
static void display_sam_dom_info_12(struct samr_DomInfo12 *info12)
diff --git a/source3/samba4.m4 b/source3/samba4.m4
index b99deb8870..9ef3d71fd0 100644
--- a/source3/samba4.m4
+++ b/source3/samba4.m4
@@ -47,7 +47,7 @@ SMB_INCLUDE_MK(lib/zlib.mk)
AC_CONFIG_FILES(../source4/lib/registry/registry.pc)
AC_CONFIG_FILES(../source4/librpc/dcerpc.pc)
AC_CONFIG_FILES(../librpc/ndr.pc)
-AC_CONFIG_FILES(../source4/lib/torture/torture.pc)
+AC_CONFIG_FILES(../lib/torture/torture.pc)
AC_CONFIG_FILES(../source4/auth/gensec/gensec.pc)
AC_CONFIG_FILES(../source4/param/samba-hostconfig.pc)
AC_CONFIG_FILES(../source4/librpc/dcerpc_samr.pc)
@@ -131,6 +131,7 @@ builddir="$builddir/../source4"
oldsrcdir="$srcdir"
srcdir="$srcdir/../source4"
AC_SUBST(srcdir)
+AC_SUBST(builddir)
SMB_WRITE_PERLVARS(../source4/build/smb_build/config.pm)
builddir="$oldbuilddir"
srcdir="$oldsrcdir"
diff --git a/source3/samba4.mk b/source3/samba4.mk
index 1743431aa4..032a3d9c35 100644
--- a/source3/samba4.mk
+++ b/source3/samba4.mk
@@ -88,7 +88,7 @@ libutilsrcdir := $(samba4srcdir)/../lib/util
libtdrsrcdir := $(samba4srcdir)/lib/tdr
libdbwrapsrcdir := $(samba4srcdir)/lib/dbwrap
libcryptosrcdir := $(samba4srcdir)/../lib/crypto
-libtorturesrcdir := $(samba4srcdir)/lib/torture
+libtorturesrcdir := ../lib/torture
libcompressionsrcdir := $(samba4srcdir)/../lib/compression
libgencachesrcdir := $(samba4srcdir)/lib
paramsrcdir := $(samba4srcdir)/param
diff --git a/source3/script/installmo.sh b/source3/script/installmo.sh
new file mode 100644
index 0000000000..9c4ab1eefe
--- /dev/null
+++ b/source3/script/installmo.sh
@@ -0,0 +1,87 @@
+#!/bin/sh
+
+DESTDIR=$1
+LOCALEDIR=`echo $2 | sed 's/\/\//\//g'`
+SRCDIR=$3/
+MSGFMT=msgfmt
+
+case $0 in
+ *uninstall*)
+ if test ! -d "$DESTDIR/$LOCALEDIR"; then
+ echo "Directory $DESTDIR/$LOCALEDIR doesn't exist!"
+ echo "Do a \"make installmo\" or \"make install\" first."
+ exit 1
+ fi
+ mode='uninstall'
+ ;;
+ *)
+ mode='install'
+ ;;
+esac
+
+for dir in $SRCDIR/locale/*; do
+ MODULE=`basename $dir`
+ for f in $SRCDIR/locale/$MODULE/*.po; do
+ BASE=`basename $f`
+ LANGUAGE=`echo $BASE | sed 's/\.po//g'`
+ if test "$LANGUAGE" = '*'; then
+ echo "No .po file exists!"
+ exit 0
+ fi
+ FNAME="$DESTDIR/$LOCALEDIR/$LANGUAGE/LC_MESSAGES/$MODULE.mo"
+ if test ! -d "$DESTDIR/$LOCALEDIR/$LANGUAGE/LC_MESSAGES/"; then
+ mkdir -p "$DESTDIR/$LOCALEDIR/$LANGUAGE/LC_MESSAGES/"
+ fi
+ if test "$mode" = 'install'; then
+ echo "Installing $f as $FNAME"
+ touch "$FNAME"
+ $MSGFMT "$f" -f -o "$FNAME"
+ if test ! -f "$FNAME"; then
+ echo "Cannot install $FNAME. Does $USER have privileges?"
+ exit 1
+ fi
+ chmod 0644 "$FNAME"
+ elif test "$mode" = 'uninstall'; then
+ echo "removing $FNAME"
+ rm -f "$FNAME"
+ if test -f "$FNAME"; then
+ echo "Cannot remove $FNAME. Does $USER have privileges?"
+ exit 1
+ fi
+ else
+ echo "Unknown mode $mode. script called as $0."
+ exit 1
+ fi
+ done
+ if test "$mode" = 'install'; then
+ cat << EOF
+==============================================================
+MO files for $MODULE are installed.
+==============================================================
+EOF
+ else
+ cat << EOF
+==============================================================
+MO files for $MODULE are removed.
+==============================================================
+EOF
+ fi
+done
+
+if test "$mode" = 'install'; then
+ cat << EOF
+==============================================================
+All MO files for Samba are installed. You can use "make uninstall"
+or "make uninstallmo" to remove them.
+==============================================================
+EOF
+else
+ cat << EOF
+==============================================================
+All MO files for Samba are removed. you can use "make install"
+or "make installmo" to install them.
+==============================================================
+EOF
+fi
+
+exit 0
diff --git a/source3/script/tests/selftest.sh b/source3/script/tests/selftest.sh
index 0894b2507d..3b65aaa760 100755
--- a/source3/script/tests/selftest.sh
+++ b/source3/script/tests/selftest.sh
@@ -1,7 +1,7 @@
#!/bin/sh
-if [ $# != 3 ]; then
- echo "$0 <directory> <all | quick> <smbtorture4>"
+if [ $# != 3 -a $# != 4 ]; then
+ echo "$0 <directory> <all | quick> <smbtorture4> [<shrdir>]"
exit 1
fi
@@ -38,7 +38,6 @@ PASSWORD=test
SRCDIR="`dirname $0`/../.."
BINDIR="`pwd`/bin"
SCRIPTDIR=$SRCDIR/script/tests
-SHRDIR=$PREFIX_ABS/tmp
LIBDIR=$PREFIX_ABS/lib
PIDDIR=$PREFIX_ABS/pid
CONFFILE=$LIBDIR/client.conf
@@ -113,8 +112,23 @@ mkdir -p $PRIVATEDIR $LIBDIR $PIDDIR $LOCKDIR $LOGDIR
mkdir -p $SOCKET_WRAPPER_DIR
mkdir -p $WINBINDD_SOCKET_DIR
chmod 755 $WINBINDD_SOCKET_DIR
-mkdir -p $PREFIX_ABS/tmp
-chmod 777 $PREFIX_ABS/tmp
+
+##
+## Create an alternate shrdir if one was specified.
+##
+if [ $# = 4 ]; then
+ ALT_SHRDIR=`echo $4 | sed s+//+/+`
+ mkdir -p $ALT_SHRDIR || exit $?
+ OLD_PWD=`pwd`
+ cd $ALT_SHRDIR || exit $?
+ SHRDIR=`pwd`
+ cd $OLD_PWD
+ /bin/rm -rf $SHRDIR/*
+else
+ SHRDIR=$PREFIX_ABS/tmp
+ mkdir -p $SHRDIR
+fi
+chmod 777 $SHRDIR
##
## Create the common config include file with the basic settings
@@ -184,14 +198,14 @@ cat >$SERVERCONFFILE<<EOF
# min receivefile size = 4000
[tmp]
- path = $PREFIX_ABS/tmp
+ path = $SHRDIR
read only = no
smbd:sharedelay = 100000
smbd:writetimeupdatedelay = 500000
map hidden = yes
map system = yes
create mask = 755
- vfs objects = $BINDIR/xattr_tdb.so $BINDIR/streams_xattr.so
+ vfs objects = $BINDIR/xattr_tdb.so $BINDIR/streams_depot.so
[hideunread]
copy = tmp
hide unreadable = yes
@@ -262,7 +276,7 @@ export SOCKET_WRAPPER_DEFAULT_IFACE
TORTURE4_OPTIONS="$SAMBA4CONFIGURATION"
TORTURE4_OPTIONS="$TORTURE4_OPTIONS --maximum-runtime=$TORTURE_MAXTIME"
TORTURE4_OPTIONS="$TORTURE4_OPTIONS --target=samba3"
-TORTURE4_OPTIONS="$TORTURE4_OPTIONS --option=torture:localdir=$PREFIX_ABS/tmp"
+TORTURE4_OPTIONS="$TORTURE4_OPTIONS --option=torture:localdir=$SHRDIR"
export TORTURE4_OPTIONS
if [ x"$RUN_FROM_BUILD_FARM" = x"yes" ];then
diff --git a/source3/script/uninstallmo.sh b/source3/script/uninstallmo.sh
new file mode 100644
index 0000000000..5b4475f5c2
--- /dev/null
+++ b/source3/script/uninstallmo.sh
@@ -0,0 +1 @@
+installmo.sh
diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c
index fd553c3fc4..8beed0744c 100644
--- a/source3/smbd/aio.c
+++ b/source3/smbd/aio.c
@@ -506,7 +506,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
ERROR_BOTH(map_nt_error_from_unix(ret), ERRHRD, ERRdiskfull);
srv_set_message(outbuf,0,0,true);
} else {
- bool write_through = BITSETW(aio_ex->req->inbuf+smb_vwv7,0);
+ bool write_through = BITSETW(aio_ex->req->vwv+7,0);
NTSTATUS status;
SSVAL(outbuf,smb_vwv2,nwritten);
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index 555033b7df..2237a89ace 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -505,7 +505,6 @@ static bool process_trans2(blocking_lock_record *blr)
/* We finally got the lock, return success. */
- SCVAL(blr->req->inbuf, smb_com, SMBtrans2);
SSVAL(params,0,0);
/* Fake up max_data_bytes here - we know it fits. */
send_trans2_replies(blr->fsp->conn, blr->req, params, 2, NULL, 0, 0xffff);
@@ -666,86 +665,18 @@ static void process_blocking_lock_queue(void)
*/
for (blr = blocking_lock_queue; blr; blr = next) {
- connection_struct *conn = NULL;
- uint16 vuid;
- files_struct *fsp = NULL;
next = blr->next;
/*
- * Ensure we don't have any old chain_fsp values
- * sitting around....
- */
- chain_size = 0;
- fsp = blr->fsp;
-
- conn = conn_find(blr->req->tid);
- vuid = (lp_security() == SEC_SHARE)
- ? UID_FIELD_INVALID : blr->req->vuid;
-
- DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n",
- fsp->fnum, fsp->fsp_name ));
-
- if(!change_to_user(conn,vuid)) {
- struct byte_range_lock *br_lck = brl_get_locks(talloc_tos(), fsp);
-
- /*
- * Remove the entry and return an error to the client.
- */
-
- if (br_lck) {
- brl_lock_cancel(br_lck,
- blr->lock_pid,
- procid_self(),
- blr->offset,
- blr->count,
- blr->lock_flav);
- TALLOC_FREE(br_lck);
- }
-
- DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n",
- vuid ));
- blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED);
- DLIST_REMOVE(blocking_lock_queue, blr);
- TALLOC_FREE(blr);
- recalc_timeout = True;
- continue;
- }
-
- if(!set_current_service(conn,SVAL(blr->req->inbuf,smb_flg),True)) {
- struct byte_range_lock *br_lck = brl_get_locks(talloc_tos(), fsp);
-
- /*
- * Remove the entry and return an error to the client.
- */
-
- if (br_lck) {
- brl_lock_cancel(br_lck,
- blr->lock_pid,
- procid_self(),
- blr->offset,
- blr->count,
- blr->lock_flav);
- TALLOC_FREE(br_lck);
- }
-
- DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) ));
- blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED);
- DLIST_REMOVE(blocking_lock_queue, blr);
- TALLOC_FREE(blr);
- recalc_timeout = True;
- change_to_root_user();
- continue;
- }
-
- /*
* Go through the remaining locks and try and obtain them.
* The call returns True if all locks were obtained successfully
* and False if we still need to wait.
*/
if(blocking_lock_record_process(blr)) {
- struct byte_range_lock *br_lck = brl_get_locks(talloc_tos(), fsp);
+ struct byte_range_lock *br_lck = brl_get_locks(
+ talloc_tos(), blr->fsp);
if (br_lck) {
brl_lock_cancel(br_lck,
@@ -760,19 +691,17 @@ static void process_blocking_lock_queue(void)
DLIST_REMOVE(blocking_lock_queue, blr);
TALLOC_FREE(blr);
recalc_timeout = True;
- change_to_root_user();
continue;
}
- change_to_root_user();
-
/*
* We couldn't get the locks for this record on the list.
* If the time has expired, return a lock error.
*/
if (!timeval_is_zero(&blr->expire_time) && timeval_compare(&blr->expire_time, &tv_curr) <= 0) {
- struct byte_range_lock *br_lck = brl_get_locks(talloc_tos(), fsp);
+ struct byte_range_lock *br_lck = brl_get_locks(
+ talloc_tos(), blr->fsp);
/*
* Lock expired - throw away all previously
@@ -780,8 +709,10 @@ static void process_blocking_lock_queue(void)
*/
if (br_lck) {
- DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n",
- fsp->fnum, fsp->fsp_name ));
+ DEBUG(5,("process_blocking_lock_queue: "
+ "pending lock fnum = %d for file %s "
+ "timed out.\n", blr->fsp->fnum,
+ blr->fsp->fsp_name ));
brl_lock_cancel(br_lck,
blr->lock_pid,
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index d4c531ab19..ce918ab6a3 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -106,8 +106,7 @@ static void check_magic(struct files_struct *fsp)
static NTSTATUS close_filestruct(files_struct *fsp)
{
NTSTATUS status = NT_STATUS_OK;
- connection_struct *conn = fsp->conn;
-
+
if (fsp->fh->fd != -1) {
if(flush_write_cache(fsp, CLOSE_FLUSH) == -1) {
status = map_nt_error_from_unix(errno);
@@ -115,9 +114,8 @@ static NTSTATUS close_filestruct(files_struct *fsp)
delete_write_cache(fsp);
}
- conn->num_files_open--;
return status;
-}
+}
/****************************************************************************
If any deferred opens are waiting on this close, notify them.
@@ -583,7 +581,7 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
conn->server_info->unix_name,fsp->fsp_name,
- conn->num_files_open,
+ conn->num_files_open - 1,
nt_errstr(status) ));
file_free(req, fsp);
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 784b36d9bd..954cd5a4d2 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -30,6 +30,17 @@ static int set_sparse_flag(const SMB_STRUCT_STAT * const sbuf)
return 0;
}
+static int set_link_read_only_flag(const SMB_STRUCT_STAT *const sbuf)
+{
+#ifdef S_ISLNK
+#if LINKS_READ_ONLY
+ if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
+ return aRONLY;
+#endif
+#endif
+ return 0;
+}
+
/****************************************************************************
Change a dos mode to a unix mode.
Base permission for files:
@@ -159,13 +170,7 @@ static uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_
result = aDIR | (result & aRONLY);
result |= set_sparse_flag(sbuf);
-
-#ifdef S_ISLNK
-#if LINKS_READ_ONLY
- if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
- result |= aRONLY;
-#endif
-#endif
+ result |= set_link_read_only_flag(sbuf);
DEBUG(8,("dos_mode_from_sbuf returning "));
@@ -343,6 +348,113 @@ uint32 dos_mode_msdfs(connection_struct *conn, const char *path,SMB_STRUCT_STAT
return(result);
}
+#ifdef HAVE_STAT_DOS_FLAGS
+/****************************************************************************
+ Convert dos attributes (FILE_ATTRIBUTE_*) to dos stat flags (UF_*)
+****************************************************************************/
+
+static int dos_attributes_to_stat_dos_flags(uint32_t dosmode)
+{
+ uint32_t dos_stat_flags = 0;
+
+ if (dosmode & aARCH)
+ dos_stat_flags |= UF_DOS_ARCHIVE;
+ if (dosmode & aHIDDEN)
+ dos_stat_flags |= UF_DOS_HIDDEN;
+ if (dosmode & aRONLY)
+ dos_stat_flags |= UF_DOS_RO;
+ if (dosmode & aSYSTEM)
+ dos_stat_flags |= UF_DOS_SYSTEM;
+ if (dosmode & FILE_ATTRIBUTE_NONINDEXED)
+ dos_stat_flags |= UF_DOS_NOINDEX;
+
+ return dos_stat_flags;
+}
+
+/****************************************************************************
+ Gets DOS attributes, accessed via st_flags in the stat struct.
+****************************************************************************/
+
+static bool get_stat_dos_flags(connection_struct *conn,
+ const char *fname,
+ const SMB_STRUCT_STAT *sbuf,
+ uint32_t *dosmode)
+{
+ SMB_ASSERT(sbuf && VALID_STAT(*sbuf));
+ SMB_ASSERT(dosmode);
+
+ if (!lp_store_dos_attributes(SNUM(conn))) {
+ return false;
+ }
+
+ DEBUG(5, ("Getting stat dos attributes for %s.\n", fname));
+
+ if (sbuf->st_flags & UF_DOS_ARCHIVE)
+ *dosmode |= aARCH;
+ if (sbuf->st_flags & UF_DOS_HIDDEN)
+ *dosmode |= aHIDDEN;
+ if (sbuf->st_flags & UF_DOS_RO)
+ *dosmode |= aRONLY;
+ if (sbuf->st_flags & UF_DOS_SYSTEM)
+ *dosmode |= aSYSTEM;
+ if (sbuf->st_flags & UF_DOS_NOINDEX)
+ *dosmode |= FILE_ATTRIBUTE_NONINDEXED;
+ if (S_ISDIR(sbuf->st_mode))
+ *dosmode |= aDIR;
+
+ *dosmode |= set_sparse_flag(sbuf);
+ *dosmode |= set_link_read_only_flag(sbuf);
+
+ return true;
+}
+
+/****************************************************************************
+ Sets DOS attributes, stored in st_flags of the inode.
+****************************************************************************/
+
+static bool set_stat_dos_flags(connection_struct *conn,
+ const char *fname,
+ SMB_STRUCT_STAT *sbuf,
+ uint32_t dosmode,
+ bool *attributes_changed)
+{
+ uint32_t new_flags = 0;
+ int error = 0;
+
+ SMB_ASSERT(sbuf && VALID_STAT(*sbuf));
+ SMB_ASSERT(attributes_changed);
+
+ *attributes_changed = false;
+
+ if (!lp_store_dos_attributes(SNUM(conn))) {
+ return false;
+ }
+
+ DEBUG(5, ("Setting stat dos attributes for %s.\n", fname));
+
+ new_flags = (sbuf->st_flags & ~UF_DOS_FLAGS) |
+ dos_attributes_to_stat_dos_flags(dosmode);
+
+ /* Return early if no flags changed. */
+ if (new_flags == sbuf->st_flags)
+ return true;
+
+ DEBUG(5, ("Setting stat dos attributes=0x%x, prev=0x%x\n", new_flags,
+ sbuf->st_flags));
+
+ /* Set new flags with chflags. */
+ error = SMB_VFS_CHFLAGS(conn, fname, new_flags);
+ if (error) {
+ DEBUG(0, ("Failed setting new stat dos attributes (0x%x) on "
+ "file %s! errno=%d\n", new_flags, fname, errno));
+ return false;
+ }
+
+ *attributes_changed = true;
+ return true;
+}
+#endif /* HAVE_STAT_DOS_FLAGS */
+
/****************************************************************************
Change a unix mode to a dos mode.
****************************************************************************/
@@ -350,7 +462,7 @@ uint32 dos_mode_msdfs(connection_struct *conn, const char *path,SMB_STRUCT_STAT
uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf)
{
uint32 result = 0;
- bool offline;
+ bool offline, used_stat_dos_flags = false;
DEBUG(8,("dos_mode: %s\n", path));
@@ -373,11 +485,16 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf)
}
}
- /* Get the DOS attributes from an EA by preference. */
- if (get_ea_dos_attribute(conn, path, sbuf, &result)) {
- result |= set_sparse_flag(sbuf);
- } else {
- result |= dos_mode_from_sbuf(conn, path, sbuf);
+#ifdef HAVE_STAT_DOS_FLAGS
+ used_stat_dos_flags = get_stat_dos_flags(conn, path, sbuf, &result);
+#endif
+ if (!used_stat_dos_flags) {
+ /* Get the DOS attributes from an EA by preference. */
+ if (get_ea_dos_attribute(conn, path, sbuf, &result)) {
+ result |= set_sparse_flag(sbuf);
+ } else {
+ result |= dos_mode_from_sbuf(conn, path, sbuf);
+ }
}
@@ -468,6 +585,23 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
return(0);
}
+#ifdef HAVE_STAT_DOS_FLAGS
+ {
+ bool attributes_changed;
+
+ if (set_stat_dos_flags(conn, fname, st, dosmode,
+ &attributes_changed))
+ {
+ if (!newfile && attributes_changed) {
+ notify_fname(conn, NOTIFY_ACTION_MODIFIED,
+ FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
+ }
+ st->st_mode = unixmode;
+ return 0;
+ }
+ }
+#endif
+
/* Store the DOS attributes in an EA by preference. */
if (set_ea_dos_attribute(conn, fname, st, dosmode)) {
if (!newfile) {
diff --git a/source3/smbd/fake_file.c b/source3/smbd/fake_file.c
index 58b09604c4..7feedcc9f9 100644
--- a/source3/smbd/fake_file.c
+++ b/source3/smbd/fake_file.c
@@ -141,7 +141,6 @@ NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn,
return NT_STATUS_NO_MEMORY;
}
- conn->num_files_open++;
*result = fsp;
return NT_STATUS_OK;
}
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 562f1e8d94..392264bfc0 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -194,25 +194,39 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
return result;
}
+ if (!(name = talloc_strdup(ctx, orig_path))) {
+ DEBUG(0, ("talloc_strdup failed\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /*
+ * Large directory fix normalization. If we're case sensitive, and
+ * the case preserving parameters are set to "no", normalize the case of
+ * the incoming filename from the client WHETHER IT EXISTS OR NOT !
+ * This is in conflict with the current (3.0.20) man page, but is
+ * what people expect from the "large directory howto". I'll update
+ * the man page. Thanks to jht@samba.org for finding this. JRA.
+ */
+
+ if (conn->case_sensitive && !conn->case_preserve &&
+ !conn->short_case_preserve) {
+ strnorm(name, lp_defaultcase(SNUM(conn)));
+ }
+
/*
* Ensure saved_last_component is valid even if file exists.
*/
if(pp_saved_last_component) {
- end = strrchr_m(orig_path, '/');
+ end = strrchr_m(name, '/');
if (end) {
*pp_saved_last_component = talloc_strdup(ctx, end + 1);
} else {
*pp_saved_last_component = talloc_strdup(ctx,
- orig_path);
+ name);
}
}
- if (!(name = talloc_strdup(ctx, orig_path))) {
- DEBUG(0, ("talloc_strdup failed\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
if (!lp_posix_pathnames()) {
stream = strchr_m(name, ':');
@@ -227,20 +241,6 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
}
}
- /*
- * Large directory fix normalization. If we're case sensitive, and
- * the case preserving parameters are set to "no", normalize the case of
- * the incoming filename from the client WHETHER IT EXISTS OR NOT !
- * This is in conflict with the current (3.0.20) man page, but is
- * what people expect from the "large directory howto". I'll update
- * the man page. Thanks to jht@samba.org for finding this. JRA.
- */
-
- if (conn->case_sensitive && !conn->case_preserve &&
- !conn->short_case_preserve) {
- strnorm(name, lp_defaultcase(SNUM(conn)));
- }
-
start = name;
/* If we're providing case insentive semantics or
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index d3bfce7499..1a3a997e59 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -129,6 +129,8 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn,
ZERO_STRUCT(fsp_fi_cache);
+ conn->num_files_open++;
+
*result = fsp;
return NT_STATUS_OK;
}
@@ -420,9 +422,7 @@ void file_free(struct smb_request *req, files_struct *fsp)
DEBUG(5,("freed files structure %d (%d used)\n",
fsp->fnum, files_used));
- /* this is paranoia, just in case someone tries to reuse the
- information */
- ZERO_STRUCTP(fsp);
+ fsp->conn->num_files_open--;
if ((req != NULL) && (fsp == req->chain_fsp)) {
req->chain_fsp = NULL;
@@ -438,6 +438,10 @@ void file_free(struct smb_request *req, files_struct *fsp)
vfs_remove_fsp_extension(fsp->vfs_extension->owner, fsp);
}
+ /* this is paranoia, just in case someone tries to reuse the
+ information */
+ ZERO_STRUCTP(fsp);
+
SAFE_FREE(fsp);
}
@@ -484,46 +488,34 @@ files_struct *file_fsp(struct smb_request *req, uint16 fid)
Duplicate the file handle part for a DOS or FCB open.
****************************************************************************/
-NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *fsp,
+void dup_file_fsp(struct smb_request *req, files_struct *from,
uint32 access_mask, uint32 share_access,
- uint32 create_options, files_struct **result)
+ uint32 create_options, files_struct *to)
{
- NTSTATUS status;
- files_struct *dup_fsp;
-
- status = file_new(NULL, fsp->conn, &dup_fsp);
-
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- SAFE_FREE(dup_fsp->fh);
-
- dup_fsp->fh = fsp->fh;
- dup_fsp->fh->ref_count++;
-
- dup_fsp->file_id = fsp->file_id;
- dup_fsp->initial_allocation_size = fsp->initial_allocation_size;
- dup_fsp->mode = fsp->mode;
- dup_fsp->file_pid = fsp->file_pid;
- dup_fsp->vuid = fsp->vuid;
- dup_fsp->open_time = fsp->open_time;
- dup_fsp->access_mask = access_mask;
- dup_fsp->share_access = share_access;
- dup_fsp->oplock_type = fsp->oplock_type;
- dup_fsp->can_lock = fsp->can_lock;
- dup_fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
- if (!CAN_WRITE(fsp->conn)) {
- dup_fsp->can_write = False;
+ SAFE_FREE(to->fh);
+
+ to->fh = from->fh;
+ to->fh->ref_count++;
+
+ to->file_id = from->file_id;
+ to->initial_allocation_size = from->initial_allocation_size;
+ to->mode = from->mode;
+ to->file_pid = from->file_pid;
+ to->vuid = from->vuid;
+ to->open_time = from->open_time;
+ to->access_mask = access_mask;
+ to->share_access = share_access;
+ to->oplock_type = from->oplock_type;
+ to->can_lock = from->can_lock;
+ to->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
+ if (!CAN_WRITE(from->conn)) {
+ to->can_write = False;
} else {
- dup_fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ? True : False;
+ to->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ? True : False;
}
- dup_fsp->print_file = fsp->print_file;
- dup_fsp->modified = fsp->modified;
- dup_fsp->is_directory = fsp->is_directory;
- dup_fsp->aio_write_behind = fsp->aio_write_behind;
- string_set(&dup_fsp->fsp_name,fsp->fsp_name);
-
- *result = dup_fsp;
- return NT_STATUS_OK;
+ to->print_file = from->print_file;
+ 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);
}
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index b9460e5211..649ead4682 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -91,7 +91,6 @@ void send_trans_reply(connection_struct *conn,
int tot_data_sent = 0;
int tot_param_sent = 0;
int align;
- char *outbuf;
int ldata = rdata ? rdata_len : 0;
int lparam = rparam ? rparam_len : 0;
@@ -104,38 +103,43 @@ void send_trans_reply(connection_struct *conn,
align = ((this_lparam)%4);
- if (!create_outbuf(talloc_tos(), (char *)req->inbuf, &outbuf,
- 10, 1+align+this_ldata+this_lparam)) {
- smb_panic("could not allocate outbuf");
- }
+ reply_outbuf(req, 10, 1+align+this_ldata+this_lparam);
+
+ /*
+ * We might have SMBtranss in req which was transferred to the outbuf,
+ * fix that.
+ */
+ SCVAL(req->outbuf, smb_com, SMBtrans);
- copy_trans_params_and_data(outbuf, align,
+ copy_trans_params_and_data((char *)req->outbuf, align,
rparam, tot_param_sent, this_lparam,
rdata, tot_data_sent, this_ldata);
- SSVAL(outbuf,smb_vwv0,lparam);
- SSVAL(outbuf,smb_vwv1,ldata);
- SSVAL(outbuf,smb_vwv3,this_lparam);
- SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf)+1,outbuf));
- SSVAL(outbuf,smb_vwv5,0);
- SSVAL(outbuf,smb_vwv6,this_ldata);
- SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+1+this_lparam+align,
- outbuf));
- SSVAL(outbuf,smb_vwv8,0);
- SSVAL(outbuf,smb_vwv9,0);
+ SSVAL(req->outbuf,smb_vwv0,lparam);
+ SSVAL(req->outbuf,smb_vwv1,ldata);
+ SSVAL(req->outbuf,smb_vwv3,this_lparam);
+ SSVAL(req->outbuf,smb_vwv4,
+ smb_offset(smb_buf(req->outbuf)+1, req->outbuf));
+ SSVAL(req->outbuf,smb_vwv5,0);
+ SSVAL(req->outbuf,smb_vwv6,this_ldata);
+ SSVAL(req->outbuf,smb_vwv7,
+ smb_offset(smb_buf(req->outbuf)+1+this_lparam+align,
+ req->outbuf));
+ SSVAL(req->outbuf,smb_vwv8,0);
+ SSVAL(req->outbuf,smb_vwv9,0);
if (buffer_too_large) {
- error_packet_set((char *)outbuf, ERRDOS, ERRmoredata,
+ error_packet_set((char *)req->outbuf, ERRDOS, ERRmoredata,
STATUS_BUFFER_OVERFLOW, __LINE__, __FILE__);
}
- show_msg(outbuf);
- if (!srv_send_smb(smbd_server_fd(), (char *)outbuf,
+ show_msg((char *)req->outbuf);
+ if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
IS_CONN_ENCRYPTED(conn))) {
exit_server_cleanly("send_trans_reply: srv_send_smb failed.");
}
- TALLOC_FREE(outbuf);
+ TALLOC_FREE(req->outbuf);
tot_data_sent = this_ldata;
tot_param_sent = this_lparam;
@@ -155,39 +159,45 @@ void send_trans_reply(connection_struct *conn,
align = (this_lparam%4);
- if (!create_outbuf(talloc_tos(), (char *)req->inbuf, &outbuf,
- 10, 1+align+this_ldata+this_lparam)) {
- smb_panic("could not allocate outbuf");
- }
+ reply_outbuf(req, 10, 1+align+this_ldata+this_lparam);
+
+ /*
+ * We might have SMBtranss in req which was transferred to the
+ * outbuf, fix that.
+ */
+ SCVAL(req->outbuf, smb_com, SMBtrans);
- copy_trans_params_and_data(outbuf, align,
+ copy_trans_params_and_data((char *)req->outbuf, align,
rparam, tot_param_sent, this_lparam,
rdata, tot_data_sent, this_ldata);
- SSVAL(outbuf,smb_vwv3,this_lparam);
- SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf)+1,outbuf));
- SSVAL(outbuf,smb_vwv5,tot_param_sent);
- SSVAL(outbuf,smb_vwv6,this_ldata);
- SSVAL(outbuf,smb_vwv7,
- smb_offset(smb_buf(outbuf)+1+this_lparam+align, outbuf));
- SSVAL(outbuf,smb_vwv8,tot_data_sent);
- SSVAL(outbuf,smb_vwv9,0);
+ SSVAL(req->outbuf,smb_vwv3,this_lparam);
+ SSVAL(req->outbuf,smb_vwv4,
+ smb_offset(smb_buf(req->outbuf)+1,req->outbuf));
+ SSVAL(req->outbuf,smb_vwv5,tot_param_sent);
+ SSVAL(req->outbuf,smb_vwv6,this_ldata);
+ SSVAL(req->outbuf,smb_vwv7,
+ smb_offset(smb_buf(req->outbuf)+1+this_lparam+align,
+ req->outbuf));
+ SSVAL(req->outbuf,smb_vwv8,tot_data_sent);
+ SSVAL(req->outbuf,smb_vwv9,0);
if (buffer_too_large) {
- error_packet_set(outbuf, ERRDOS, ERRmoredata,
+ error_packet_set((char *)req->outbuf,
+ ERRDOS, ERRmoredata,
STATUS_BUFFER_OVERFLOW,
__LINE__, __FILE__);
}
- show_msg(outbuf);
- if (!srv_send_smb(smbd_server_fd(), outbuf,
+ show_msg((char *)req->outbuf);
+ if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
IS_CONN_ENCRYPTED(conn)))
exit_server_cleanly("send_trans_reply: srv_send_smb "
"failed.");
tot_data_sent += this_ldata;
tot_param_sent += this_lparam;
- TALLOC_FREE(outbuf);
+ TALLOC_FREE(req->outbuf);
}
}
@@ -493,8 +503,6 @@ void reply_trans(struct smb_request *req)
unsigned int pscnt;
struct trans_state *state;
NTSTATUS result;
- unsigned int size;
- unsigned int av_size;
START_PROFILE(SMBtrans);
@@ -504,8 +512,6 @@ void reply_trans(struct smb_request *req)
return;
}
- size = smb_len(req->inbuf) + 4;
- av_size = smb_len(req->inbuf);
dsoff = SVAL(req->vwv+12, 0);
dscnt = SVAL(req->vwv+11, 0);
psoff = SVAL(req->vwv+10, 0);
@@ -551,6 +557,12 @@ void reply_trans(struct smb_request *req)
goto bad_param;
if (state->total_data) {
+
+ if (trans_oob(state->total_data, 0, dscnt)
+ || trans_oob(smb_len(req->inbuf), dsoff, dscnt)) {
+ goto bad_param;
+ }
+
/* Can't use talloc here, the core routines do realloc on the
* params and data. Out of paranoia, 100 bytes too many. */
state->data = (char *)SMB_MALLOC(state->total_data+100);
@@ -565,21 +577,16 @@ void reply_trans(struct smb_request *req)
/* null-terminate the slack space */
memset(&state->data[state->total_data], 0, 100);
- if (dscnt > state->total_data ||
- dsoff+dscnt < dsoff) {
- goto bad_param;
- }
-
- if (dsoff > av_size ||
- dscnt > av_size ||
- dsoff+dscnt > av_size) {
- goto bad_param;
- }
-
memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
}
if (state->total_param) {
+
+ if (trans_oob(state->total_param, 0, pscnt)
+ || trans_oob(smb_len(req->inbuf), psoff, pscnt)) {
+ goto bad_param;
+ }
+
/* Can't use talloc here, the core routines do realloc on the
* params and data. Out of paranoia, 100 bytes too many */
state->param = (char *)SMB_MALLOC(state->total_param+100);
@@ -595,17 +602,6 @@ void reply_trans(struct smb_request *req)
/* null-terminate the slack space */
memset(&state->param[state->total_param], 0, 100);
- if (pscnt > state->total_param ||
- psoff+pscnt < psoff) {
- goto bad_param;
- }
-
- if (psoff > av_size ||
- pscnt > av_size ||
- psoff+pscnt > av_size) {
- goto bad_param;
- }
-
memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
}
@@ -614,6 +610,19 @@ void reply_trans(struct smb_request *req)
if (state->setup_count) {
unsigned int i;
+
+ /*
+ * No overflow possible here, state->setup_count is an
+ * unsigned int, being filled by a single byte from
+ * CVAL(req->vwv+13, 0) above. The cast in the comparison
+ * below is not necessary, it's here to clarify things. The
+ * validity of req->vwv and req->wct has been checked in
+ * init_smb_request already.
+ */
+ if (state->setup_count + 14 > (unsigned int)req->wct) {
+ goto bad_param;
+ }
+
if((state->setup = TALLOC_ARRAY(
state, uint16, state->setup_count)) == NULL) {
DEBUG(0,("reply_trans: setup malloc fail for %u "
@@ -626,17 +635,10 @@ void reply_trans(struct smb_request *req)
END_PROFILE(SMBtrans);
return;
}
- if (req->inbuf+smb_vwv14+(state->setup_count*SIZEOFWORD) >
- req->inbuf + size)
- goto bad_param;
- if ((smb_vwv14+(state->setup_count*SIZEOFWORD) < smb_vwv14) ||
- (smb_vwv14+(state->setup_count*SIZEOFWORD) <
- (state->setup_count*SIZEOFWORD)))
- goto bad_param;
- for (i=0;i<state->setup_count;i++)
- state->setup[i] = SVAL(req->inbuf,
- smb_vwv14+i*SIZEOFWORD);
+ for (i=0;i<state->setup_count;i++) {
+ state->setup[i] = SVAL(req->vwv + 14 + i, 0);
+ }
}
state->received_param = pscnt;
@@ -682,7 +684,6 @@ void reply_transs(struct smb_request *req)
connection_struct *conn = req->conn;
unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
struct trans_state *state;
- unsigned int av_size;
START_PROFILE(SMBtranss);
@@ -715,8 +716,6 @@ void reply_transs(struct smb_request *req)
if (SVAL(req->vwv+1, 0) < state->total_data)
state->total_data = SVAL(req->vwv+1, 0);
- av_size = smb_len(req->inbuf);
-
pcnt = SVAL(req->vwv+2, 0);
poff = SVAL(req->vwv+3, 0);
pdisp = SVAL(req->vwv+4, 0);
@@ -733,41 +732,19 @@ void reply_transs(struct smb_request *req)
goto bad_param;
if (pcnt) {
- if (pdisp > state->total_param ||
- pcnt > state->total_param ||
- pdisp+pcnt > state->total_param ||
- pdisp+pcnt < pdisp) {
- goto bad_param;
- }
-
- if (poff > av_size ||
- pcnt > av_size ||
- poff+pcnt > av_size ||
- poff+pcnt < poff) {
+ if (trans_oob(state->total_param, pdisp, pcnt)
+ || trans_oob(smb_len(req->inbuf), poff, pcnt)) {
goto bad_param;
}
-
- memcpy(state->param+pdisp,smb_base(req->inbuf)+poff,
- pcnt);
+ memcpy(state->param+pdisp,smb_base(req->inbuf)+poff,pcnt);
}
if (dcnt) {
- if (ddisp > state->total_data ||
- dcnt > state->total_data ||
- ddisp+dcnt > state->total_data ||
- ddisp+dcnt < ddisp) {
+ if (trans_oob(state->total_data, ddisp, dcnt)
+ || trans_oob(smb_len(req->inbuf), doff, dcnt)) {
goto bad_param;
}
-
- if (ddisp > av_size ||
- dcnt > av_size ||
- ddisp+dcnt > av_size ||
- ddisp+dcnt < ddisp) {
- goto bad_param;
- }
-
- memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,
- dcnt);
+ memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,dcnt);
}
if ((state->received_param < state->total_param) ||
@@ -776,12 +753,6 @@ void reply_transs(struct smb_request *req)
return;
}
- /*
- * construct_reply_common will copy smb_com from inbuf to
- * outbuf. SMBtranss is wrong here.
- */
- SCVAL(req->inbuf,smb_com,SMBtrans);
-
handle_trans(conn, req, state);
DLIST_REMOVE(conn->pending_trans, state);
diff --git a/source3/smbd/map_username.c b/source3/smbd/map_username.c
index a8899dd538..f549f0c9f3 100644
--- a/source3/smbd/map_username.c
+++ b/source3/smbd/map_username.c
@@ -178,7 +178,7 @@ bool map_username(fstring user)
/* skip lines like 'user = ' */
- dosuserlist = str_list_make(talloc_tos(), dosname, NULL);
+ dosuserlist = str_list_make_v3(talloc_tos(), dosname, NULL);
if (!dosuserlist) {
DEBUG(0,("Bad username map entry. Unable to build user list. Ignoring.\n"));
continue;
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 32240ff0d5..d46be64262 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -219,6 +219,7 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
connection_struct **pconn,
int snum,
const char *path,
+ struct auth_serversupplied_info *server_info,
char **poldcwd)
{
connection_struct *conn;
@@ -254,6 +255,15 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
conn->params->service = snum;
+ if (server_info != NULL) {
+ conn->server_info = copy_serverinfo(conn, server_info);
+ if (conn->server_info == NULL) {
+ DEBUG(0, ("copy_serverinfo failed\n"));
+ TALLOC_FREE(conn);
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
set_conn_connectpath(conn, connpath);
if (!smbd_vfs_init(conn)) {
@@ -881,7 +891,7 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
}
status = create_conn_struct(ctx, &conn, snum, lp_pathname(snum),
- &oldpath);
+ NULL, &oldpath);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(pdp);
return status;
@@ -923,7 +933,6 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
static int setup_ver2_dfs_referral(const char *pathname,
char **ppdata,
struct junction_map *junction,
- int consumedcnt,
bool self_referral)
{
char* pdata = *ppdata;
@@ -988,7 +997,8 @@ static int setup_ver2_dfs_referral(const char *pathname,
memcpy(pdata+uni_reqpathoffset2,uni_requestedpath,requestedpathlen);
/* create the header */
- SSVAL(pdata,0,consumedcnt * 2); /* path consumed */
+ SSVAL(pdata,0,requestedpathlen - 2); /* UCS2 of path consumed minus
+ 2 byte null */
/* number of referral in this pkt */
SSVAL(pdata,2,junction->referral_count);
if(self_referral) {
@@ -1037,7 +1047,6 @@ static int setup_ver2_dfs_referral(const char *pathname,
static int setup_ver3_dfs_referral(const char *pathname,
char **ppdata,
struct junction_map *junction,
- int consumedcnt,
bool self_referral)
{
char *pdata = *ppdata;
@@ -1084,7 +1093,8 @@ static int setup_ver3_dfs_referral(const char *pathname,
*ppdata = pdata;
/* create the header */
- SSVAL(pdata,0,consumedcnt * 2); /* path consumed */
+ SSVAL(pdata,0,reqpathlen - 2); /* UCS2 of path consumed minus
+ 2 byte null */
SSVAL(pdata,2,junction->referral_count); /* number of referral */
if(self_referral) {
SIVAL(pdata,4,DFSREF_REFERRAL_SERVER | DFSREF_STORAGE_SERVER);
@@ -1224,11 +1234,11 @@ int setup_dfs_referral(connection_struct *orig_conn,
case 2:
reply_size = setup_ver2_dfs_referral(pathnamep,
ppdata, junction,
- consumedcnt, self_referral);
+ self_referral);
break;
case 3:
reply_size = setup_ver3_dfs_referral(pathnamep, ppdata,
- junction, consumedcnt, self_referral);
+ junction, self_referral);
break;
default:
DEBUG(0,("setup_dfs_referral: Invalid dfs referral "
@@ -1321,7 +1331,7 @@ static bool junction_to_local_path(const struct junction_map *jucn,
return False;
}
status = create_conn_struct(talloc_tos(), conn_out, snum,
- lp_pathname(snum), oldpath);
+ lp_pathname(snum), NULL, oldpath);
if (!NT_STATUS_IS_OK(status)) {
return False;
}
@@ -1455,7 +1465,7 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
*/
status = create_conn_struct(talloc_tos(), &conn, snum, connect_path,
- &cwd);
+ NULL, &cwd);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3, ("create_conn_struct failed: %s\n",
nt_errstr(status)));
@@ -1523,7 +1533,8 @@ static int form_junctions(TALLOC_CTX *ctx,
* Fake up a connection struct for the VFS layer.
*/
- status = create_conn_struct(ctx, &conn, snum, connect_path, &cwd);
+ status = create_conn_struct(ctx, &conn, snum, connect_path, NULL,
+ &cwd);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3, ("create_conn_struct failed: %s\n",
nt_errstr(status)));
diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
index b2d0f20f89..2d0811bc1c 100644
--- a/source3/smbd/notify.c
+++ b/source3/smbd/notify.c
@@ -24,7 +24,7 @@
struct notify_change_request {
struct notify_change_request *prev, *next;
struct files_struct *fsp; /* backpointer for cancel by mid */
- uint8 request_buf[smb_size];
+ struct smb_request *req;
uint32 filter;
uint32 max_param;
struct notify_mid_map *mid_map;
@@ -133,40 +133,33 @@ static bool notify_marshall_changes(int num_changes,
*****************************************************************************/
static void change_notify_reply_packet(connection_struct *conn,
- const uint8 *request_buf,
+ struct smb_request *req,
NTSTATUS error_code)
{
- char outbuf[smb_size+38];
+ reply_outbuf(req, 18, 0);
- memset(outbuf, '\0', sizeof(outbuf));
- construct_reply_common((char *)request_buf, outbuf);
-
- ERROR_NT(error_code);
-
- /*
- * Seems NT needs a transact command with an error code
- * in it. This is a longer packet than a simple error.
- */
- srv_set_message(outbuf,18,0,False);
+ if (!NT_STATUS_IS_OK(error_code)) {
+ error_packet_set((char *)req->outbuf, 0, 0, error_code,
+ __LINE__,__FILE__);
+ }
- show_msg(outbuf);
- if (!srv_send_smb(smbd_server_fd(),
- outbuf,
- IS_CONN_ENCRYPTED(conn)))
+ show_msg((char *)req->outbuf);
+ if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
+ req->encrypted)) {
exit_server_cleanly("change_notify_reply_packet: srv_send_smb "
"failed.");
+ }
+ TALLOC_FREE(req->outbuf);
}
void change_notify_reply(connection_struct *conn,
- const uint8 *request_buf, uint32 max_param,
+ struct smb_request *req, uint32 max_param,
struct notify_change_buf *notify_buf)
{
prs_struct ps;
- struct smb_request *req = NULL;
- uint8 tmp_request[smb_size];
if (notify_buf->num_changes == -1) {
- change_notify_reply_packet(conn, request_buf, NT_STATUS_OK);
+ change_notify_reply_packet(conn, req, NT_STATUS_OK);
notify_buf->num_changes = 0;
return;
}
@@ -179,32 +172,14 @@ void change_notify_reply(connection_struct *conn,
* We exceed what the client is willing to accept. Send
* nothing.
*/
- change_notify_reply_packet(conn, request_buf, NT_STATUS_OK);
- goto done;
- }
-
- if (!(req = talloc(talloc_tos(), struct smb_request))) {
- change_notify_reply_packet(conn, request_buf, NT_STATUS_NO_MEMORY);
+ change_notify_reply_packet(conn, req, NT_STATUS_OK);
goto done;
}
- memcpy(tmp_request, request_buf, smb_size);
-
- /*
- * We're only interested in the header fields here
- */
-
- smb_setlen((char *)tmp_request, smb_size);
- SCVAL(tmp_request, smb_wct, 0);
-
- init_smb_request(req, tmp_request,0, conn->encrypted_tid);
- req->inbuf = tmp_request;
-
send_nt_replies(conn, req, NT_STATUS_OK, prs_data_p(&ps),
prs_offset(&ps), NULL, 0);
done:
- TALLOC_FREE(req);
prs_mem_free(&ps);
TALLOC_FREE(notify_buf->changes);
@@ -252,7 +227,7 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32 filter,
return status;
}
-NTSTATUS change_notify_add_request(const struct smb_request *req,
+NTSTATUS change_notify_add_request(struct smb_request *req,
uint32 max_param,
uint32 filter, bool recursive,
struct files_struct *fsp)
@@ -263,16 +238,16 @@ NTSTATUS change_notify_add_request(const struct smb_request *req,
DEBUG(10, ("change_notify_add_request: Adding request for %s: "
"max_param = %d\n", fsp->fsp_name, (int)max_param));
- if (!(request = SMB_MALLOC_P(struct notify_change_request))
- || !(map = SMB_MALLOC_P(struct notify_mid_map))) {
- SAFE_FREE(request);
+ if (!(request = talloc(NULL, struct notify_change_request))
+ || !(map = talloc(request, struct notify_mid_map))) {
+ TALLOC_FREE(request);
return NT_STATUS_NO_MEMORY;
}
request->mid_map = map;
map->req = request;
- memcpy(request->request_buf, req->inbuf, sizeof(request->request_buf));
+ request->req = talloc_move(request, &req);
request->max_param = max_param;
request->filter = filter;
request->fsp = fsp;
@@ -281,11 +256,11 @@ NTSTATUS change_notify_add_request(const struct smb_request *req,
DLIST_ADD_END(fsp->notify->requests, request,
struct notify_change_request *);
- map->mid = SVAL(req->inbuf, smb_mid);
+ map->mid = request->req->mid;
DLIST_ADD(notify_changes_by_mid, map);
/* Push the MID of this packet on the signing queue. */
- srv_defer_sign_response(SVAL(req->inbuf,smb_mid));
+ srv_defer_sign_response(request->req->mid);
return NT_STATUS_OK;
}
@@ -315,9 +290,7 @@ static void change_notify_remove_request(struct notify_change_request *remove_re
DLIST_REMOVE(fsp->notify->requests, req);
DLIST_REMOVE(notify_changes_by_mid, req->mid_map);
- SAFE_FREE(req->mid_map);
- TALLOC_FREE(req->backend_data);
- SAFE_FREE(req);
+ TALLOC_FREE(req);
}
/****************************************************************************
@@ -338,8 +311,8 @@ void remove_pending_change_notify_requests_by_mid(uint16 mid)
return;
}
- change_notify_reply_packet(map->req->fsp->conn,
- map->req->request_buf, NT_STATUS_CANCELLED);
+ change_notify_reply_packet(map->req->fsp->conn, map->req->req,
+ NT_STATUS_CANCELLED);
change_notify_remove_request(map->req);
}
@@ -355,8 +328,8 @@ void remove_pending_change_notify_requests_by_fid(files_struct *fsp,
}
while (fsp->notify->requests != NULL) {
- change_notify_reply_packet(fsp->conn,
- fsp->notify->requests->request_buf, status);
+ change_notify_reply_packet(
+ fsp->conn, fsp->notify->requests->req, status);
change_notify_remove_request(fsp->notify->requests);
}
}
@@ -366,6 +339,9 @@ void notify_fname(connection_struct *conn, uint32 action, uint32 filter,
{
char *fullpath;
+ if (path[0] == '.' && path[1] == '/') {
+ path += 2;
+ }
if (asprintf(&fullpath, "%s/%s", conn->connectpath, path) == -1) {
DEBUG(0, ("asprintf failed\n"));
return;
@@ -450,7 +426,7 @@ static void notify_fsp(files_struct *fsp, uint32 action, const char *name)
*/
change_notify_reply(fsp->conn,
- fsp->notify->requests->request_buf,
+ fsp->notify->requests->req,
fsp->notify->requests->max_param,
fsp->notify);
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index f711b588c5..777073e6ba 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -120,6 +120,11 @@ void send_nt_replies(connection_struct *conn,
+ data_alignment_offset);
/*
+ * We might have had SMBnttranss in req->inbuf, fix that.
+ */
+ SCVAL(req->outbuf, smb_com, SMBnttrans);
+
+ /*
* Set total params and data to be sent.
*/
@@ -279,7 +284,7 @@ static void nt_open_pipe(char *fname, connection_struct *conn,
/* Strip \\ off the name. */
fname++;
- status = np_open(req, conn, fname, &fsp);
+ status = np_open(req, fname, &fsp);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
@@ -716,23 +721,22 @@ static NTSTATUS set_sd(files_struct *fsp, uint8 *data, uint32 sd_len,
return status;
}
- if (psd->owner_sid==0) {
+ if (psd->owner_sid == NULL) {
security_info_sent &= ~OWNER_SECURITY_INFORMATION;
}
- if (psd->group_sid==0) {
+ if (psd->group_sid == NULL) {
security_info_sent &= ~GROUP_SECURITY_INFORMATION;
}
- if (psd->sacl==0) {
- security_info_sent &= ~SACL_SECURITY_INFORMATION;
- }
- if (psd->dacl==0) {
- security_info_sent &= ~DACL_SECURITY_INFORMATION;
- }
/* Convert all the generic bits. */
security_acl_map_generic(psd->dacl, &file_generic_mapping);
security_acl_map_generic(psd->sacl, &file_generic_mapping);
+ if (DEBUGLEVEL >= 10) {
+ DEBUG(10,("set_sd for file %s\n", fsp->fsp_name ));
+ NDR_PRINT_DEBUG(security_descriptor, psd);
+ }
+
status = SMB_VFS_FSET_NT_ACL(fsp, security_info_sent, psd);
TALLOC_FREE(psd);
@@ -1440,7 +1444,8 @@ static void call_nt_transact_notify_change(connection_struct *conn,
* here.
*/
- change_notify_reply(fsp->conn, req->inbuf, max_param_count, fsp->notify);
+ change_notify_reply(fsp->conn, req, max_param_count,
+ fsp->notify);
/*
* change_notify_reply() above has independently sent its
@@ -1582,16 +1587,29 @@ static void call_nt_transact_query_security_desc(connection_struct *conn,
status = SMB_VFS_FGET_NT_ACL(
fsp, security_info_wanted, &psd);
}
-
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
return;
}
+ /* If the SACL/DACL is NULL, but was requested, we mark that it is
+ * present in the reply to match Windows behavior */
+ if (psd->sacl == NULL &&
+ security_info_wanted & SACL_SECURITY_INFORMATION)
+ psd->type |= SEC_DESC_SACL_PRESENT;
+ if (psd->dacl == NULL &&
+ security_info_wanted & DACL_SECURITY_INFORMATION)
+ psd->type |= SEC_DESC_DACL_PRESENT;
+
sd_size = ndr_size_security_descriptor(psd, 0);
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));
+ NDR_PRINT_DEBUG(security_descriptor, psd);
+ }
+
SIVAL(params,0,(uint32)sd_size);
if (max_data_count < sd_size) {
@@ -2519,8 +2537,6 @@ void reply_nttrans(struct smb_request *req)
uint16 function_code;
NTSTATUS result;
struct trans_state *state;
- uint32_t size;
- uint32_t av_size;
START_PROFILE(SMBnttrans);
@@ -2530,8 +2546,6 @@ void reply_nttrans(struct smb_request *req)
return;
}
- size = smb_len(req->inbuf) + 4;
- av_size = smb_len(req->inbuf);
pscnt = IVAL(req->vwv+9, 1);
psoff = IVAL(req->vwv+11, 1);
dscnt = IVAL(req->vwv+13, 1);
@@ -2608,6 +2622,12 @@ void reply_nttrans(struct smb_request *req)
goto bad_param;
if (state->total_data) {
+
+ if (trans_oob(state->total_data, 0, dscnt)
+ || trans_oob(smb_len(req->inbuf), dsoff, dscnt)) {
+ goto bad_param;
+ }
+
/* Can't use talloc here, the core routines do realloc on the
* params and data. */
if ((state->data = (char *)SMB_MALLOC(state->total_data)) == NULL) {
@@ -2619,21 +2639,16 @@ void reply_nttrans(struct smb_request *req)
return;
}
- if (dscnt > state->total_data ||
- dsoff+dscnt < dsoff) {
- goto bad_param;
- }
-
- if (dsoff > av_size ||
- dscnt > av_size ||
- dsoff+dscnt > av_size) {
- goto bad_param;
- }
-
memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
}
if (state->total_param) {
+
+ if (trans_oob(state->total_param, 0, pscnt)
+ || trans_oob(smb_len(req->inbuf), psoff, pscnt)) {
+ goto bad_param;
+ }
+
/* Can't use talloc here, the core routines do realloc on the
* params and data. */
if ((state->param = (char *)SMB_MALLOC(state->total_param)) == NULL) {
@@ -2646,17 +2661,6 @@ void reply_nttrans(struct smb_request *req)
return;
}
- if (pscnt > state->total_param ||
- psoff+pscnt < psoff) {
- goto bad_param;
- }
-
- if (psoff > av_size ||
- pscnt > av_size ||
- psoff+pscnt > av_size) {
- goto bad_param;
- }
-
memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
}
@@ -2666,6 +2670,19 @@ void reply_nttrans(struct smb_request *req)
if(state->setup_count > 0) {
DEBUG(10,("reply_nttrans: state->setup_count = %d\n",
state->setup_count));
+
+ /*
+ * No overflow possible here, state->setup_count is an
+ * unsigned int, being filled by a single byte from
+ * CVAL(req->vwv+13, 0) above. The cast in the comparison
+ * below is not necessary, it's here to clarify things. The
+ * validity of req->vwv and req->wct has been checked in
+ * init_smb_request already.
+ */
+ if ((state->setup_count/2) + 19 > (unsigned int)req->wct) {
+ goto bad_param;
+ }
+
state->setup = (uint16 *)TALLOC(state, state->setup_count);
if (state->setup == NULL) {
DEBUG(0,("reply_nttrans : Out of memory\n"));
@@ -2677,16 +2694,7 @@ void reply_nttrans(struct smb_request *req)
return;
}
- if ((smb_nt_SetupStart + state->setup_count < smb_nt_SetupStart) ||
- (smb_nt_SetupStart + state->setup_count < state->setup_count)) {
- goto bad_param;
- }
- if (smb_nt_SetupStart + state->setup_count > size) {
- goto bad_param;
- }
-
- memcpy( state->setup, &req->inbuf[smb_nt_SetupStart],
- state->setup_count);
+ memcpy(state->setup, req->vwv+19, state->setup_count);
dump_data(10, (uint8 *)state->setup, state->setup_count);
}
@@ -2729,8 +2737,6 @@ void reply_nttranss(struct smb_request *req)
connection_struct *conn = req->conn;
uint32_t pcnt,poff,dcnt,doff,pdisp,ddisp;
struct trans_state *state;
- uint32_t av_size;
- uint32_t size;
START_PROFILE(SMBnttranss);
@@ -2764,9 +2770,6 @@ void reply_nttranss(struct smb_request *req)
state->total_data = IVAL(req->vwv+3, 1);
}
- size = smb_len(req->inbuf) + 4;
- av_size = smb_len(req->inbuf);
-
pcnt = IVAL(req->vwv+5, 1);
poff = IVAL(req->vwv+7, 1);
pdisp = IVAL(req->vwv+9, 1);
@@ -2783,41 +2786,19 @@ void reply_nttranss(struct smb_request *req)
goto bad_param;
if (pcnt) {
- if (pdisp > state->total_param ||
- pcnt > state->total_param ||
- pdisp+pcnt > state->total_param ||
- pdisp+pcnt < pdisp) {
+ if (trans_oob(state->total_param, pdisp, pcnt)
+ || trans_oob(smb_len(req->inbuf), poff, pcnt)) {
goto bad_param;
}
-
- if (poff > av_size ||
- pcnt > av_size ||
- poff+pcnt > av_size ||
- poff+pcnt < poff) {
- goto bad_param;
- }
-
- memcpy(state->param+pdisp, smb_base(req->inbuf)+poff,
- pcnt);
+ memcpy(state->param+pdisp, smb_base(req->inbuf)+poff,pcnt);
}
if (dcnt) {
- if (ddisp > state->total_data ||
- dcnt > state->total_data ||
- ddisp+dcnt > state->total_data ||
- ddisp+dcnt < ddisp) {
+ if (trans_oob(state->total_data, ddisp, dcnt)
+ || trans_oob(smb_len(req->inbuf), doff, dcnt)) {
goto bad_param;
}
-
- if (ddisp > av_size ||
- dcnt > av_size ||
- ddisp+dcnt > av_size ||
- ddisp+dcnt < ddisp) {
- goto bad_param;
- }
-
- memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,
- dcnt);
+ memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,dcnt);
}
if ((state->received_param < state->total_param) ||
@@ -2826,12 +2807,6 @@ void reply_nttranss(struct smb_request *req)
return;
}
- /*
- * construct_reply_common will copy smb_com from inbuf to
- * outbuf. SMBnttranss is wrong here.
- */
- SCVAL(req->inbuf,smb_com,SMBnttrans);
-
handle_nttrans(conn, state, req);
DLIST_REMOVE(conn->pending_trans, state);
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 480352beda..f98415ee33 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -332,6 +332,7 @@ static NTSTATUS open_file(files_struct *fsp,
if ((open_access_mask & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
(!file_existed && (local_flags & O_CREAT)) ||
((local_flags & O_TRUNC) == O_TRUNC) ) {
+ const char *wild;
/*
* We can't actually truncate here as the file may be locked.
@@ -353,8 +354,17 @@ static NTSTATUS open_file(files_struct *fsp,
#endif
/* Don't create files with Microsoft wildcard characters. */
+ if (fsp->base_fsp) {
+ /*
+ * wildcard characters are allowed in stream names
+ * only test the basefilename
+ */
+ wild = fsp->base_fsp->fsp_name;
+ } else {
+ wild = path;
+ }
if ((local_flags & O_CREAT) && !file_existed &&
- ms_has_wild(path)) {
+ ms_has_wild(wild)) {
return NT_STATUS_OBJECT_NAME_INVALID;
}
@@ -462,7 +472,7 @@ static NTSTATUS open_file(files_struct *fsp,
conn->server_info->unix_name,
fsp->fsp_name,
BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
- conn->num_files_open + 1));
+ conn->num_files_open));
errno = 0;
return NT_STATUS_OK;
@@ -951,9 +961,10 @@ static bool open_match_attributes(connection_struct *conn,
Try and find a duplicated file handle.
****************************************************************************/
-static files_struct *fcb_or_dos_open(struct smb_request *req,
+static NTSTATUS fcb_or_dos_open(struct smb_request *req,
connection_struct *conn,
- const char *fname,
+ files_struct *fsp_to_dup_into,
+ const char *fname,
struct file_id id,
uint16 file_pid,
uint16 vuid,
@@ -962,7 +973,6 @@ static files_struct *fcb_or_dos_open(struct smb_request *req,
uint32 create_options)
{
files_struct *fsp;
- files_struct *dup_fsp;
DEBUG(5,("fcb_or_dos_open: attempting old open semantics for "
"file %s.\n", fname ));
@@ -991,23 +1001,21 @@ static files_struct *fcb_or_dos_open(struct smb_request *req,
}
if (!fsp) {
- return NULL;
+ return NT_STATUS_NOT_FOUND;
}
/* quite an insane set of semantics ... */
if (is_executable(fname) &&
(fsp->fh->private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS)) {
DEBUG(10,("fcb_or_dos_open: file fail due to is_executable.\n"));
- return NULL;
+ return NT_STATUS_INVALID_PARAMETER;
}
/* We need to duplicate this fsp. */
- if (!NT_STATUS_IS_OK(dup_file_fsp(req, fsp, access_mask, share_access,
- create_options, &dup_fsp))) {
- return NULL;
- }
+ dup_file_fsp(req, fsp, access_mask, share_access,
+ create_options, fsp_to_dup_into);
- return dup_fsp;
+ return NT_STATUS_OK;
}
/****************************************************************************
@@ -1249,10 +1257,10 @@ static NTSTATUS calculate_access_mask(connection_struct *conn,
}
/****************************************************************************
- Open a file with a share mode.
+ Open a file with a share mode. Passed in an already created files_struct *.
****************************************************************************/
-NTSTATUS open_file_ntcreate(connection_struct *conn,
+static NTSTATUS open_file_ntcreate_internal(connection_struct *conn,
struct smb_request *req,
const char *fname,
SMB_STRUCT_STAT *psbuf,
@@ -1264,7 +1272,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
int oplock_request, /* internal Samba oplock codes. */
/* Information (FILE_EXISTS etc.) */
int *pinfo,
- files_struct **result)
+ files_struct *fsp)
{
int flags=0;
int flags2=0;
@@ -1274,7 +1282,6 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
bool new_file_created = False;
struct file_id id;
NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
- files_struct *fsp = NULL;
mode_t new_unx_mode = (mode_t)0;
mode_t unx_mode = (mode_t)0;
int info;
@@ -1291,7 +1298,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
ZERO_STRUCT(id);
if (conn->printer) {
- /*
+ /*
* Printers are handled completely differently.
* Most of the passed parameters are ignored.
*/
@@ -1302,7 +1309,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n", fname));
- return print_fsp_open(req, conn, fname, req->vuid, result);
+ return print_fsp_open(req, conn, fname, req->vuid, fsp);
}
if (!parent_dirname_talloc(talloc_tos(), fname, &parent_dir,
@@ -1366,7 +1373,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
status = check_name(conn, fname);
if (!NT_STATUS_IS_OK(status)) {
return status;
- }
+ }
if (!posix_open) {
new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
@@ -1533,7 +1540,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
flags2 |= O_SYNC;
}
#endif /* O_SYNC */
-
+
if (posix_open && (access_mask & FILE_APPEND_DATA)) {
flags2 |= O_APPEND;
}
@@ -1560,11 +1567,6 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
return NT_STATUS_ACCESS_DENIED;
}
- status = file_new(req, conn, &fsp);
- if(!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
fsp->share_access = share_access;
fsp->fh->private_options = create_options;
@@ -1589,7 +1591,6 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
fname, &old_write_time);
if (lck == NULL) {
- file_free(req, fsp);
DEBUG(0, ("Could not get share mode lock\n"));
return NT_STATUS_SHARING_VIOLATION;
}
@@ -1600,7 +1601,6 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
oplock_request)) {
schedule_defer_open(lck, request_time, req);
TALLOC_FREE(lck);
- file_free(req, fsp);
return NT_STATUS_SHARING_VIOLATION;
}
@@ -1620,7 +1620,6 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
oplock_request)) {
schedule_defer_open(lck, request_time, req);
TALLOC_FREE(lck);
- file_free(req, fsp);
return NT_STATUS_SHARING_VIOLATION;
}
}
@@ -1628,7 +1627,6 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
if (NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) {
/* DELETE_PENDING is not deferred for a second */
TALLOC_FREE(lck);
- file_free(req, fsp);
return status;
}
@@ -1643,33 +1641,31 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
if (create_options &
(NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
- files_struct *fsp_dup;
-
if (req == NULL) {
DEBUG(0, ("DOS open without an SMB "
"request!\n"));
TALLOC_FREE(lck);
- file_free(req, fsp);
return NT_STATUS_INTERNAL_ERROR;
}
/* Use the client requested access mask here,
* not the one we open with. */
- fsp_dup = fcb_or_dos_open(req, conn, fname, id,
- req->smbpid,
- req->vuid,
- access_mask,
- share_access,
- create_options);
-
- if (fsp_dup) {
+ status = fcb_or_dos_open(req,
+ conn,
+ fsp,
+ fname,
+ id,
+ req->smbpid,
+ req->vuid,
+ access_mask,
+ share_access,
+ create_options);
+
+ if (NT_STATUS_IS_OK(status)) {
TALLOC_FREE(lck);
- file_free(req, fsp);
if (pinfo) {
*pinfo = FILE_WAS_OPENED;
}
- conn->num_files_open++;
- *result = fsp_dup;
return NT_STATUS_OK;
}
}
@@ -1697,7 +1693,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
can_access = False;
}
- /*
+ /*
* If we're returning a share violation, ensure we
* cope with the braindead 1 second delay.
*/
@@ -1750,7 +1746,6 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
} else {
status = NT_STATUS_ACCESS_DENIED;
}
- file_free(req, fsp);
return status;
}
@@ -1788,7 +1783,6 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
if (lck != NULL) {
TALLOC_FREE(lck);
}
- file_free(req, fsp);
return fsp_open;
}
@@ -1819,7 +1813,6 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
DEBUG(0, ("open_file_ntcreate: Could not get share "
"mode lock for %s\n", fname));
fd_close(fsp);
- file_free(req, fsp);
return NT_STATUS_SHARING_VIOLATION;
}
@@ -1830,7 +1823,6 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
schedule_defer_open(lck, request_time, req);
TALLOC_FREE(lck);
fd_close(fsp);
- file_free(req, fsp);
return NT_STATUS_SHARING_VIOLATION;
}
@@ -1849,7 +1841,6 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
schedule_defer_open(lck, request_time, req);
TALLOC_FREE(lck);
fd_close(fsp);
- file_free(req, fsp);
return NT_STATUS_SHARING_VIOLATION;
}
}
@@ -1858,7 +1849,6 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
struct deferred_open_record state;
fd_close(fsp);
- file_free(req, fsp);
state.delayed_for_oplocks = False;
state.id = id;
@@ -1900,7 +1890,6 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
TALLOC_FREE(lck);
fd_close(fsp);
- file_free(req, fsp);
return NT_STATUS_SHARING_VIOLATION;
}
@@ -1926,7 +1915,6 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
status = map_nt_error_from_unix(errno);
TALLOC_FREE(lck);
fd_close(fsp);
- file_free(req, fsp);
return status;
}
}
@@ -1958,7 +1946,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
*pinfo = info;
}
- /*
+ /*
* Setup the oplock info in both the shared memory and
* file structs.
*/
@@ -1990,14 +1978,13 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
del_share_mode(lck, fsp);
TALLOC_FREE(lck);
fd_close(fsp);
- file_free(req, fsp);
return status;
}
/* Note that here we set the *inital* delete on close flag,
not the regular one. The magic gets handled in close. */
fsp->initial_delete_on_close = True;
}
-
+
if (new_file_created) {
/* Files should be initially set as archive */
if (lp_map_archive(SNUM(conn)) ||
@@ -2066,10 +2053,57 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
}
TALLOC_FREE(lck);
- conn->num_files_open++;
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ Open a file with a share mode.
+****************************************************************************/
+
+NTSTATUS open_file_ntcreate(connection_struct *conn,
+ struct smb_request *req,
+ const char *fname,
+ SMB_STRUCT_STAT *psbuf,
+ uint32 access_mask, /* access bits (FILE_READ_DATA etc.) */
+ uint32 share_access, /* share constants (FILE_SHARE_READ etc) */
+ uint32 create_disposition, /* FILE_OPEN_IF etc. */
+ uint32 create_options, /* options such as delete on close. */
+ uint32 new_dos_attributes, /* attributes used for new file. */
+ int oplock_request, /* internal Samba oplock codes. */
+ /* Information (FILE_EXISTS etc.) */
+ int *pinfo,
+ files_struct **result)
+{
+ NTSTATUS status;
+ files_struct *fsp = NULL;
+
+ *result = NULL;
+
+ status = file_new(req, conn, &fsp);
+ if(!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = open_file_ntcreate_internal(conn,
+ req,
+ fname,
+ psbuf,
+ access_mask,
+ share_access,
+ create_disposition,
+ create_options,
+ new_dos_attributes,
+ oplock_request,
+ pinfo,
+ fsp);
+
+ if(!NT_STATUS_IS_OK(status)) {
+ file_free(req, fsp);
+ return status;
+ }
*result = fsp;
- return NT_STATUS_OK;
+ return status;
}
/****************************************************************************
@@ -2097,10 +2131,9 @@ NTSTATUS open_file_fchmod(struct smb_request *req, connection_struct *conn,
status = open_file(fsp, conn, NULL, NULL, NULL, fname, psbuf, O_WRONLY,
0, FILE_WRITE_DATA, FILE_WRITE_DATA);
- /*
+ /*
* This is not a user visible file open.
- * Don't set a share mode and don't increment
- * the conn->num_files_open.
+ * Don't set a share mode.
*/
if (!NT_STATUS_IS_OK(status)) {
@@ -2431,8 +2464,6 @@ NTSTATUS open_directory(connection_struct *conn,
*pinfo = info;
}
- conn->num_files_open++;
-
*result = fsp;
return NT_STATUS_OK;
}
@@ -2821,6 +2852,8 @@ NTSTATUS create_file_unixpath(connection_struct *conn,
"%s\n", base, nt_errstr(status)));
goto fail;
}
+ /* we don't need to low level fd */
+ fd_close(base_fsp);
}
/*
@@ -2857,13 +2890,52 @@ NTSTATUS create_file_unixpath(connection_struct *conn,
* Ordinary file case.
*/
- status = open_file_ntcreate(
- conn, req, fname, &sbuf, access_mask, share_access,
- create_disposition, create_options, file_attributes,
- oplock_request, &info, &fsp);
+ if (base_fsp) {
+ /*
+ * We're opening the stream element of a base_fsp
+ * we already opened. We need to initialize
+ * the fsp first, and set up the base_fsp pointer.
+ */
+ status = file_new(req, conn, &fsp);
+ if(!NT_STATUS_IS_OK(status)) {
+ goto fail;
+ }
+
+ fsp->base_fsp = base_fsp;
+
+ status = open_file_ntcreate_internal(conn,
+ req,
+ fname,
+ &sbuf,
+ access_mask,
+ share_access,
+ create_disposition,
+ create_options,
+ file_attributes,
+ oplock_request,
+ &info,
+ fsp);
+
+ if(!NT_STATUS_IS_OK(status)) {
+ file_free(req, fsp);
+ fsp = NULL;
+ }
+ } else {
+ status = open_file_ntcreate(
+ conn, req, fname, &sbuf, access_mask, share_access,
+ create_disposition, create_options, file_attributes,
+ oplock_request, &info, &fsp);
+ }
if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
+ /* A stream open never opens a directory */
+
+ if (base_fsp) {
+ status = NT_STATUS_FILE_IS_A_DIRECTORY;
+ goto fail;
+ }
+
/*
* Fail the open if it was explicitly a non-directory
* file.
@@ -2887,6 +2959,8 @@ NTSTATUS create_file_unixpath(connection_struct *conn,
goto fail;
}
+ fsp->base_fsp = base_fsp;
+
/*
* According to the MS documentation, the only time the security
* descriptor is applied to the opened file is iff we *created* the
@@ -2923,7 +2997,12 @@ NTSTATUS create_file_unixpath(connection_struct *conn,
security_acl_map_generic(sd->dacl, &file_generic_mapping);
security_acl_map_generic(sd->sacl, &file_generic_mapping);
- status = SMB_VFS_FSET_NT_ACL(fsp, sec_info_sent, sd);
+ if (sec_info_sent & (OWNER_SECURITY_INFORMATION|
+ GROUP_SECURITY_INFORMATION|
+ DACL_SECURITY_INFORMATION|
+ SACL_SECURITY_INFORMATION)) {
+ status = SMB_VFS_FSET_NT_ACL(fsp, sec_info_sent, sd);
+ }
fsp->access_mask = saved_access_mask;
@@ -2968,16 +3047,6 @@ NTSTATUS create_file_unixpath(connection_struct *conn,
DEBUG(10, ("create_file_unixpath: info=%d\n", info));
- /*
- * Set fsp->base_fsp late enough that we can't "goto fail" anymore. In
- * the fail: branch we call close_file(fsp, ERROR_CLOSE) which would
- * also close fsp->base_fsp which we have to also do explicitly in
- * this routine here, as not in all "goto fail:" we have the fsp set
- * up already to be initialized with the base_fsp.
- */
-
- fsp->base_fsp = base_fsp;
-
*result = fsp;
if (pinfo != NULL) {
*pinfo = info;
@@ -2996,6 +3065,13 @@ NTSTATUS create_file_unixpath(connection_struct *conn,
DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
if (fsp != NULL) {
+ if (base_fsp && fsp->base_fsp == base_fsp) {
+ /*
+ * The close_file below will close
+ * fsp->base_fsp.
+ */
+ base_fsp = NULL;
+ }
close_file(req, fsp, ERROR_CLOSE);
fsp = NULL;
}
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index 88e7b766be..84b40f28cc 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -576,7 +576,7 @@ static bool user_ok(const char *user, int snum)
TALLOC_FREE(valid);
if (ret && lp_onlyuser(snum)) {
- char **user_list = str_list_make(
+ char **user_list = str_list_make_v3(
talloc_tos(), lp_username(snum), NULL);
if (user_list &&
str_list_substitute(user_list, "%S",
diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c
index b52b1b02d0..261f12cb08 100644
--- a/source3/smbd/pipes.c
+++ b/source3/smbd/pipes.c
@@ -78,7 +78,7 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req)
}
#endif
- status = np_open(req, conn, fname, &fsp);
+ status = np_open(req, fname, &fsp);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index cccf3087f7..97fd3b2bbe 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -870,7 +870,7 @@ static void merge_aces( canon_ace **pp_list_head )
Check if we need to return NT4.x compatible ACL entries.
****************************************************************************/
-static bool nt4_compatible_acls(void)
+bool nt4_compatible_acls(void)
{
int compat = lp_acl_compatibility();
@@ -3211,6 +3211,9 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid)
return ret;
}
+#if 0
+/* Disable this - prevents ACL inheritance from the ACL editor. JRA. */
+
/****************************************************************************
Take care of parent ACL inheritance.
****************************************************************************/
@@ -3398,6 +3401,7 @@ NTSTATUS append_parent_acl(files_struct *fsp,
*pp_new_sd = psd;
return status;
}
+#endif
/****************************************************************************
Reply to set a security descriptor on an fsp. security_info_sent is the
@@ -3510,8 +3514,11 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
create_file_sids(&sbuf, &file_owner_sid, &file_grp_sid);
+#if 0
+ /* Disable this - prevents ACL inheritance from the ACL editor. JRA. */
+
/* See here: http://www.codeproject.com/KB/winsdk/accessctrl2.aspx
- * for details. JRA.
+ * for details and also the log trace in bug #4308. JRA.
*/
if ((security_info_sent & DACL_SECURITY_INFORMATION) &&
@@ -3527,6 +3534,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
}
psd = new_sd;
}
+#endif
acl_perms = unpack_canon_ace( fsp, &sbuf, &file_owner_sid, &file_grp_sid,
&file_ace_list, &dir_ace_list, security_info_sent, psd);
@@ -4301,7 +4309,7 @@ SEC_DESC *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname)
finfo.fh->fd = -1;
finfo.fsp_name = CONST_DISCARD(char *,fname);
- if (!NT_STATUS_IS_OK(posix_fget_nt_acl( &finfo, DACL_SECURITY_INFORMATION, &psd))) {
+ 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"));
conn_free_internal( conn );
return NULL;
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 7931fbebab..b3cd2f26c8 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -37,6 +37,8 @@ SIG_ATOMIC_T got_sig_term = 0;
extern bool global_machine_password_needs_changing;
extern int max_send;
+static void construct_reply_common(const char *inbuf, char *outbuf);
+
/* Accessor function for smb_read_error for smbd functions. */
/****************************************************************************
@@ -1590,7 +1592,7 @@ void remove_from_common_flags2(uint32 v)
common_flags2 &= ~v;
}
-void construct_reply_common(const char *inbuf, char *outbuf)
+static void construct_reply_common(const char *inbuf, char *outbuf)
{
srv_set_message(outbuf,0,0,false);
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 377ba4e530..11c713ab4a 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -52,11 +52,45 @@ static NTSTATUS check_path_syntax_internal(char *path,
const char *s = path;
NTSTATUS ret = NT_STATUS_OK;
bool start_of_name_component = True;
+ bool stream_started = false;
*p_last_component_contains_wcard = False;
while (*s) {
- if (IS_PATH_SEP(*s,posix_path)) {
+ if (stream_started) {
+ switch (*s) {
+ case '/':
+ case '\\':
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ case ':':
+ if (s[1] == '\0') {
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
+ if (strchr_m(&s[1], ':')) {
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
+ if (StrCaseCmp(s, ":$DATA") != 0) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ break;
+ }
+ }
+
+ if (!stream_started && *s == ':') {
+ if (*p_last_component_contains_wcard) {
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
+ /* stream names allow more characters than file names */
+ stream_started = true;
+ start_of_name_component = false;
+ posix_path = true;
+
+ if (s[1] == '\0') {
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
+ }
+
+ if (!stream_started && IS_PATH_SEP(*s,posix_path)) {
/*
* Safe to assume is not the second part of a mb char
* as this is handled below.
@@ -119,7 +153,7 @@ static NTSTATUS check_path_syntax_internal(char *path,
if (!(*s & 0x80)) {
if (!posix_path) {
- if (*s <= 0x1f) {
+ if (*s <= 0x1f || *s == '|') {
return NT_STATUS_OBJECT_NAME_INVALID;
}
switch (*s) {
@@ -2894,7 +2928,7 @@ void reply_lockread(struct smb_request *req)
return;
}
- if (!CHECK_READ(fsp,req->inbuf)) {
+ if (!CHECK_READ(fsp,req)) {
reply_doserror(req, ERRDOS, ERRbadaccess);
END_PROFILE(SMBlockread);
return;
@@ -3002,7 +3036,7 @@ void reply_read(struct smb_request *req)
return;
}
- if (!CHECK_READ(fsp,req->inbuf)) {
+ if (!CHECK_READ(fsp,req)) {
reply_doserror(req, ERRDOS, ERRbadaccess);
END_PROFILE(SMBread);
return;
@@ -3255,7 +3289,7 @@ void reply_read_and_X(struct smb_request *req)
return;
}
- if (!CHECK_READ(fsp,req->inbuf)) {
+ if (!CHECK_READ(fsp,req)) {
reply_doserror(req, ERRDOS,ERRbadaccess);
END_PROFILE(SMBreadX);
return;
@@ -4558,8 +4592,15 @@ void reply_printopen(struct smb_request *req)
return;
}
+ status = file_new(req, conn, &fsp);
+ if(!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ END_PROFILE(SMBsplopen);
+ return;
+ }
+
/* Open for exclusive use, write only. */
- status = print_fsp_open(req, conn, NULL, req->vuid, &fsp);
+ status = print_fsp_open(req, conn, NULL, req->vuid, fsp);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
@@ -4989,8 +5030,16 @@ NTSTATUS rmdir_internals(TALLOC_CTX *ctx,
}
}
- /* We only have veto files/directories. Recursive delete. */
+ /* We only have veto files/directories.
+ * Are we allowed to delete them ? */
+ if(!lp_recursive_veto_delete(SNUM(conn))) {
+ TALLOC_FREE(dir_hnd);
+ errno = ENOTEMPTY;
+ goto err;
+ }
+
+ /* Do a recursive delete. */
RewindDir(dir_hnd,&dirpos);
while ((dname = ReadDirName(dir_hnd,&dirpos))) {
char *fullname = NULL;
@@ -5016,9 +5065,8 @@ NTSTATUS rmdir_internals(TALLOC_CTX *ctx,
break;
}
if(st.st_mode & S_IFDIR) {
- if(lp_recursive_veto_delete(SNUM(conn))) {
- if(!recursive_rmdir(ctx, conn, fullname))
- break;
+ if(!recursive_rmdir(ctx, conn, fullname)) {
+ break;
}
if(SMB_VFS_RMDIR(conn,fullname) != 0) {
break;
@@ -5448,6 +5496,12 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
return NT_STATUS_OBJECT_NAME_COLLISION;
}
+ if(replace_if_exists && dst_exists) {
+ if (is_ntfs_stream_name(newname)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ }
+
if (dst_exists) {
struct file_id fileid = vfs_file_id_from_sbuf(conn, &sbuf1);
files_struct *dst_fsp = file_find_di_first(fileid);
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 7583da65a5..fff05a3aac 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -80,7 +80,7 @@ struct event_context *smbd_event_context(void)
{
static struct event_context *ctx;
- if (!ctx && !(ctx = event_context_init(NULL))) {
+ if (!ctx && !(ctx = event_context_init(talloc_autofree_context()))) {
smb_panic("Could not init smbd event context");
}
return ctx;
@@ -91,7 +91,7 @@ struct messaging_context *smbd_messaging_context(void)
static struct messaging_context *ctx;
if (ctx == NULL) {
- ctx = messaging_init(NULL, server_id_self(),
+ ctx = messaging_init(talloc_autofree_context(), server_id_self(),
smbd_event_context());
}
if (ctx == NULL) {
@@ -105,7 +105,7 @@ struct memcache *smbd_memcache(void)
static struct memcache *cache;
if (!cache
- && !(cache = memcache_init(NULL,
+ && !(cache = memcache_init(talloc_autofree_context(),
lp_max_stat_cache_size()*1024))) {
smb_panic("Could not init smbd memcache");
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 05197021a3..0dea615fb5 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -1123,38 +1123,6 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
return NULL;
}
-/***************************************************************************************
- Simple wrapper function for make_connection() to include a call to
- vfs_chdir()
- **************************************************************************************/
-
-connection_struct *make_connection_with_chdir(const char *service_in,
- DATA_BLOB password,
- const char *dev, uint16 vuid,
- NTSTATUS *status)
-{
- connection_struct *conn = NULL;
-
- conn = make_connection(service_in, password, dev, vuid, status);
-
- /*
- * make_connection() does not change the directory for us any more
- * so we have to do it as a separate step --jerry
- */
-
- if ( conn && vfs_ChDir(conn,conn->connectpath) != 0 ) {
- DEBUG(0,("make_connection_with_chdir: Can't change "
- "directory to %s for [print$] (%s)\n",
- conn->connectpath,strerror(errno)));
- yield_connection(conn, lp_servicename(SNUM(conn)));
- conn_free(conn);
- *status = NT_STATUS_UNSUCCESSFUL;
- return NULL;
- }
-
- return conn;
-}
-
/****************************************************************************
Make a connection to a service.
*
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index fde6cdc160..24a201013a 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -1171,7 +1171,7 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
const char *p2;
uint16 data_blob_len = SVAL(req->vwv+7, 0);
enum remote_arch_types ra_type = get_remote_arch();
- int vuid = SVAL(req->inbuf,smb_uid);
+ int vuid = req->vuid;
user_struct *vuser = NULL;
NTSTATUS status = NT_STATUS_OK;
uint16 smbpid = req->smbpid;
@@ -1203,7 +1203,7 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
file_save("negotiate.dat", blob1.data, blob1.length);
#endif
- p2 = (char *)req->inbuf + smb_vwv13 + data_blob_len;
+ p2 = (char *)req->buf + data_blob_len;
p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
STR_TERMINATE);
diff --git a/source3/smbd/share_access.c b/source3/smbd/share_access.c
index f5f79c86e5..9dbacc2998 100644
--- a/source3/smbd/share_access.c
+++ b/source3/smbd/share_access.c
@@ -252,9 +252,11 @@ bool user_ok_token(const char *username, const char *domain,
bool is_share_read_only_for_token(const char *username,
const char *domain,
- struct nt_user_token *token, int snum)
+ struct nt_user_token *token,
+ connection_struct *conn)
{
- bool result = lp_readonly(snum);
+ int snum = SNUM(conn);
+ bool result = conn->read_only;
if (lp_readlist(snum) != NULL) {
if (token_contains_name_in_list(username, domain,
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index d0e3a68e8a..7b051d389f 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -768,6 +768,12 @@ void send_trans2_replies(connection_struct *conn,
reply_outbuf(req, 10, total_sent_thistime + alignment_offset
+ data_alignment_offset);
+ /*
+ * We might have SMBtrans2s in req which was transferred to
+ * the outbuf, fix that.
+ */
+ SCVAL(req->outbuf, smb_com, SMBtrans2);
+
/* Set total params and data to be sent */
SSVAL(req->outbuf,smb_tprcnt,paramsize);
SSVAL(req->outbuf,smb_tdrcnt,datasize);
@@ -1129,7 +1135,7 @@ static uint32 unix_filetype(mode_t mode)
return UNIX_TYPE_SOCKET;
#endif
- DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode));
+ DEBUG(0,("unix_filetype: unknown filetype %u\n", (unsigned)mode));
return UNIX_TYPE_UNKNOWN;
}
@@ -3993,6 +3999,46 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
return;
}
+ if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
+ && is_ntfs_stream_name(fname)) {
+ char *base;
+ SMB_STRUCT_STAT bsbuf;
+
+ status = split_ntfs_stream_name(talloc_tos(), fname,
+ &base, NULL);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("create_file_unixpath: "
+ "split_ntfs_stream_name failed: %s\n",
+ nt_errstr(status)));
+ reply_nterror(req, status);
+ return;
+ }
+
+ SMB_ASSERT(!is_ntfs_stream_name(base)); /* paranoia.. */
+
+ if (INFO_LEVEL_IS_UNIX(info_level)) {
+ /* Always do lstat for UNIX calls. */
+ if (SMB_VFS_LSTAT(conn,base,&bsbuf)) {
+ DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",base,strerror(errno)));
+ reply_unixerror(req,ERRDOS,ERRbadpath);
+ return;
+ }
+ } else {
+ if (SMB_VFS_STAT(conn,base,&bsbuf) != 0) {
+ DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",base,strerror(errno)));
+ reply_unixerror(req,ERRDOS,ERRbadpath);
+ return;
+ }
+ }
+
+ fileid = vfs_file_id_from_sbuf(conn, &bsbuf);
+ 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,fname,&sbuf)) {
@@ -4911,7 +4957,11 @@ NTSTATUS smb_set_file_time(connection_struct *conn,
time_to_asc(convert_timespec_to_time_t(ts[1])) ));
if (fsp != NULL) {
- set_sticky_write_time_fsp(fsp, ts[1]);
+ if (fsp->base_fsp) {
+ set_sticky_write_time_fsp(fsp->base_fsp, ts[1]);
+ } else {
+ set_sticky_write_time_fsp(fsp, ts[1]);
+ }
} else {
set_sticky_write_time_path(conn, fname,
vfs_file_id_from_sbuf(conn, psbuf),
@@ -4921,6 +4971,10 @@ NTSTATUS smb_set_file_time(connection_struct *conn,
DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n"));
+ if (fsp && fsp->base_fsp) {
+ fname = fsp->base_fsp->fsp_name;
+ }
+
if(file_ntimes(conn, fname, ts)!=0) {
return map_nt_error_from_unix(errno);
}
@@ -5347,26 +5401,42 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
return NT_STATUS_NOT_SUPPORTED;
}
- /* Create the base directory. */
- base_name = talloc_strdup(ctx, fname);
- if (!base_name) {
- return NT_STATUS_NO_MEMORY;
- }
- p = strrchr_m(base_name, '/');
- if (p) {
- p[1] = '\0';
+ if (fsp && fsp->base_fsp) {
+ if (newname[0] != ':') {
+ return NT_STATUS_NOT_SUPPORTED;
+ }
+ base_name = talloc_asprintf(ctx, "%s%s",
+ fsp->base_fsp->fsp_name,
+ newname);
+ if (!base_name) {
+ return NT_STATUS_NO_MEMORY;
+ }
} else {
- base_name = talloc_strdup(ctx, "./");
+ if (is_ntfs_stream_name(newname)) {
+ return NT_STATUS_NOT_SUPPORTED;
+ }
+
+ /* Create the base directory. */
+ base_name = talloc_strdup(ctx, fname);
+ if (!base_name) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ p = strrchr_m(base_name, '/');
+ if (p) {
+ p[1] = '\0';
+ } else {
+ base_name = talloc_strdup(ctx, "./");
+ if (!base_name) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+ /* Append the new name. */
+ base_name = talloc_asprintf_append(base_name,
+ "%s",
+ newname);
if (!base_name) {
return NT_STATUS_NO_MEMORY;
}
- }
- /* Append the new name. */
- base_name = talloc_asprintf_append(base_name,
- "%s",
- newname);
- if (!base_name) {
- return NT_STATUS_NO_MEMORY;
}
if (fsp) {
@@ -7263,8 +7333,8 @@ static void call_trans2ioctl(connection_struct *conn,
return;
}
- if ((SVAL(req->inbuf,(smb_setup+4)) == LMCAT_SPL)
- && (SVAL(req->inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
+ if ((SVAL(req->vwv+16, 0) == LMCAT_SPL)
+ && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
*ppdata = (char *)SMB_REALLOC(*ppdata, 32);
if (*ppdata == NULL) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
@@ -7527,8 +7597,6 @@ void reply_trans2(struct smb_request *req)
unsigned int psoff;
unsigned int pscnt;
unsigned int tran_call;
- unsigned int size;
- unsigned int av_size;
struct trans_state *state;
NTSTATUS result;
@@ -7545,8 +7613,6 @@ void reply_trans2(struct smb_request *req)
psoff = SVAL(req->vwv+10, 0);
pscnt = SVAL(req->vwv+9, 0);
tran_call = SVAL(req->vwv+14, 0);
- size = smb_len(req->inbuf) + 4;
- av_size = smb_len(req->inbuf);
result = allow_new_trans(conn->pending_trans, req->mid);
if (!NT_STATUS_IS_OK(result)) {
@@ -7611,8 +7677,8 @@ void reply_trans2(struct smb_request *req)
*/
if ( (state->setup_count == 4)
&& (tran_call == TRANSACT2_IOCTL)
- && (SVAL(req->inbuf,(smb_setup+4)) == LMCAT_SPL)
- && (SVAL(req->inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
+ && (SVAL(req->vwv+16, 0) == LMCAT_SPL)
+ && (SVAL(req->vwv+17, 0) == LMFUNC_GETJOBID)) {
DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
} else {
DEBUG(2,("Invalid smb_sucnt in trans2 call(%u)\n",state->setup_count));
@@ -7628,6 +7694,12 @@ void reply_trans2(struct smb_request *req)
goto bad_param;
if (state->total_data) {
+
+ if (trans_oob(state->total_data, 0, dscnt)
+ || trans_oob(smb_len(req->inbuf), dsoff, dscnt)) {
+ goto bad_param;
+ }
+
/* Can't use talloc here, the core routines do realloc on the
* params and data. */
state->data = (char *)SMB_MALLOC(state->total_data);
@@ -7640,21 +7712,16 @@ void reply_trans2(struct smb_request *req)
return;
}
- if (dscnt > state->total_data ||
- dsoff+dscnt < dsoff) {
- goto bad_param;
- }
-
- if (dsoff > av_size ||
- dscnt > av_size ||
- dsoff+dscnt > av_size) {
- goto bad_param;
- }
-
memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
}
if (state->total_param) {
+
+ if (trans_oob(state->total_param, 0, pscnt)
+ || trans_oob(smb_len(req->inbuf), psoff, pscnt)) {
+ goto bad_param;
+ }
+
/* Can't use talloc here, the core routines do realloc on the
* params and data. */
state->param = (char *)SMB_MALLOC(state->total_param);
@@ -7668,17 +7735,6 @@ void reply_trans2(struct smb_request *req)
return;
}
- if (pscnt > state->total_param ||
- psoff+pscnt < psoff) {
- goto bad_param;
- }
-
- if (psoff > av_size ||
- pscnt > av_size ||
- psoff+pscnt > av_size) {
- goto bad_param;
- }
-
memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
}
@@ -7726,8 +7782,6 @@ void reply_transs2(struct smb_request *req)
connection_struct *conn = req->conn;
unsigned int pcnt,poff,dcnt,doff,pdisp,ddisp;
struct trans_state *state;
- unsigned int size;
- unsigned int av_size;
START_PROFILE(SMBtranss2);
@@ -7739,9 +7793,6 @@ void reply_transs2(struct smb_request *req)
return;
}
- size = smb_len(req->inbuf)+4;
- av_size = smb_len(req->inbuf);
-
for (state = conn->pending_trans; state != NULL;
state = state->next) {
if (state->mid == req->mid) {
@@ -7779,41 +7830,19 @@ void reply_transs2(struct smb_request *req)
goto bad_param;
if (pcnt) {
- if (pdisp > state->total_param ||
- pcnt > state->total_param ||
- pdisp+pcnt > state->total_param ||
- pdisp+pcnt < pdisp) {
- goto bad_param;
- }
-
- if (poff > av_size ||
- pcnt > av_size ||
- poff+pcnt > av_size ||
- poff+pcnt < poff) {
+ if (trans_oob(state->total_param, pdisp, pcnt)
+ || trans_oob(smb_len(req->inbuf), poff, pcnt)) {
goto bad_param;
}
-
- memcpy(state->param+pdisp,smb_base(req->inbuf)+poff,
- pcnt);
+ memcpy(state->param+pdisp,smb_base(req->inbuf)+poff,pcnt);
}
if (dcnt) {
- if (ddisp > state->total_data ||
- dcnt > state->total_data ||
- ddisp+dcnt > state->total_data ||
- ddisp+dcnt < ddisp) {
- goto bad_param;
- }
-
- if (ddisp > av_size ||
- dcnt > av_size ||
- ddisp+dcnt > av_size ||
- ddisp+dcnt < ddisp) {
+ if (trans_oob(state->total_data, ddisp, dcnt)
+ || trans_oob(smb_len(req->inbuf), doff, dcnt)) {
goto bad_param;
}
-
- memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,
- dcnt);
+ memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,dcnt);
}
if ((state->received_param < state->total_param) ||
@@ -7822,12 +7851,6 @@ void reply_transs2(struct smb_request *req)
return;
}
- /*
- * construct_reply_common will copy smb_com from inbuf to
- * outbuf. SMBtranss2 is wrong here.
- */
- SCVAL(req->inbuf,smb_com,SMBtrans2);
-
handle_trans2(conn, req, state);
DLIST_REMOVE(conn->pending_trans, state);
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 8998f6a371..ca7df264e2 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -32,7 +32,7 @@ bool change_to_guest(void)
if (!pass) {
/* Don't need to free() this as its stored in a static */
- pass = getpwnam_alloc(NULL, lp_guestaccount());
+ pass = getpwnam_alloc(talloc_autofree_context(), lp_guestaccount());
if (!pass)
return(False);
}
@@ -88,7 +88,8 @@ static bool check_user_ok(connection_struct *conn, uint16_t vuid,
readonly_share = is_share_read_only_for_token(
server_info->unix_name,
pdb_get_domain(server_info->sam_account),
- server_info->ptok, snum);
+ server_info->ptok,
+ conn);
if (!readonly_share &&
!share_access_check(server_info->ptok, lp_servicename(snum),
@@ -317,9 +318,9 @@ bool become_authenticated_pipe_user(pipes_struct *p)
if (!push_sec_ctx())
return False;
- set_sec_ctx(p->pipe_user.ut.uid, p->pipe_user.ut.gid,
- p->pipe_user.ut.ngroups, p->pipe_user.ut.groups,
- p->pipe_user.nt_user_token);
+ set_sec_ctx(p->server_info->utok.uid, p->server_info->utok.gid,
+ p->server_info->utok.ngroups, p->server_info->utok.groups,
+ p->server_info->ptok);
return True;
}
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 904fb5c262..603426b67c 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -5291,6 +5291,11 @@ static bool run_local_memcache(int dummy)
DATA_BLOB d1, d2, d3;
DATA_BLOB v1, v2, v3;
+ TALLOC_CTX *mem_ctx;
+ char *str1, *str2;
+ size_t size1, size2;
+ bool ret = false;
+
cache = memcache_init(NULL, 100);
if (cache == NULL) {
@@ -5342,7 +5347,33 @@ static bool run_local_memcache(int dummy)
}
TALLOC_FREE(cache);
- return true;
+
+ cache = memcache_init(NULL, 0);
+
+ mem_ctx = talloc_init("foo");
+
+ str1 = talloc_strdup(mem_ctx, "string1");
+ str2 = talloc_strdup(mem_ctx, "string2");
+
+ memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
+ data_blob_string_const("torture"), &str1);
+ size1 = talloc_total_size(cache);
+
+ memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
+ data_blob_string_const("torture"), &str2);
+ size2 = talloc_total_size(cache);
+
+ printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
+
+ if (size2 > size1) {
+ printf("memcache leaks memory!\n");
+ goto fail;
+ }
+
+ ret = true;
+ fail:
+ TALLOC_FREE(cache);
+ return ret;
}
static double create_procs(bool (*fn)(int), bool *result)
diff --git a/source3/utils/net.h b/source3/utils/net.h
index 5dc2b11d4e..2d72756def 100644
--- a/source3/utils/net.h
+++ b/source3/utils/net.h
@@ -70,6 +70,16 @@ struct net_context {
void *private_data;
};
+struct net_dc_info {
+ bool is_dc;
+ bool is_pdc;
+ bool is_ad;
+ bool is_mixed_mode;
+ const char *netbios_domain_name;
+ const char *dns_domain_name;
+ const char *forest_name;
+};
+
#define NET_TRANSPORT_LOCAL 0x01
#define NET_TRANSPORT_RAP 0x02
#define NET_TRANSPORT_RPC 0x04
diff --git a/source3/utils/net_proto.h b/source3/utils/net_proto.h
index ee4388f157..c058a0166f 100644
--- a/source3/utils/net_proto.h
+++ b/source3/utils/net_proto.h
@@ -359,6 +359,7 @@ NTSTATUS rpc_vampire_internals(struct net_context *c,
TALLOC_CTX *mem_ctx,
int argc,
const char **argv);
+int rpc_vampire_passdb(struct net_context *c, int argc, const char **argv);
int rpc_vampire_ldif(struct net_context *c, int argc, const char **argv);
NTSTATUS rpc_vampire_ldif_internals(struct net_context *c,
const DOM_SID *domain_sid,
@@ -473,6 +474,10 @@ void net_display_usage_from_functable(struct functable *table);
const char *net_share_type_str(int num_type);
+NTSTATUS net_scan_dc(struct net_context *c,
+ struct cli_state *cli,
+ struct net_dc_info *dc_info);
+
/* The following definitions come from utils/netlookup.c */
NTSTATUS net_lookup_name_from_sid(struct net_context *c,
diff --git a/source3/utils/net_rap.c b/source3/utils/net_rap.c
index 570e951aee..dd757abd1a 100644
--- a/source3/utils/net_rap.c
+++ b/source3/utils/net_rap.c
@@ -612,7 +612,7 @@ int net_rap_printq_usage(struct net_context *c, int argc, const char **argv)
d_printf(
"net rap printq [misc. options] [targets]\n"
"\tor\n"
- "net rap printq list [<queue_name>] [misc. options] [targets]\n"
+ "net rap printq info [<queue_name>] [misc. options] [targets]\n"
"\tlists the specified queue and jobs on the target server.\n"
"\tIf the queue name is not specified, all queues are listed.\n\n");
d_printf(
@@ -726,9 +726,10 @@ int net_rap_printq(struct net_context *c, int argc, const char **argv)
"info",
rap_printq_info,
NET_TRANSPORT_RAP,
- "Display info about print job",
- "net rap printq info\n"
- " Display info about print job"
+ "Display info about print queues and jobs",
+ "net rap printq info [queue]\n"
+ " Display info about print jobs in queue.\n"
+ " If queue is not specified, all queues are listed"
},
{
"delete",
diff --git a/source3/utils/net_registry.c b/source3/utils/net_registry.c
index 64a0d8ac40..e2f410b9ac 100644
--- a/source3/utils/net_registry.c
+++ b/source3/utils/net_registry.c
@@ -339,6 +339,10 @@ static int net_registry_setvalue(struct net_context *c, int argc,
value.type = REG_SZ;
value.v.sz.len = strlen(argv[3])+1;
value.v.sz.str = CONST_DISCARD(char *, argv[3]);
+ } else if (strequal(argv[2], "multi_sz")) {
+ value.type = REG_MULTI_SZ;
+ value.v.multi_sz.num_strings = argc - 3;
+ value.v.multi_sz.strings = (char **)(argv + 3);
} else {
d_fprintf(stderr, "type \"%s\" not implemented\n", argv[2]);
goto done;
diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c
index 10f2a324a3..3c8ce0326e 100644
--- a/source3/utils/net_rpc.c
+++ b/source3/utils/net_rpc.c
@@ -5253,7 +5253,7 @@ static NTSTATUS rpc_trustdom_add_internals(struct net_context *c,
0, 0, ACB_DOMTRUST, SAMR_FIELD_ACCT_FLAGS,
hours,
0, 0, 0, 0, 0, 0, 0,
- crypt_pwd.data, 24);
+ &crypt_pwd);
result = rpccli_samr_SetUserInfo2(pipe_hnd, mem_ctx,
&user_pol,
@@ -6370,6 +6370,14 @@ static int rpc_vampire(struct net_context *c, int argc, const char **argv)
"net rpc vampire keytab\n"
" Dump remote SAM database to Kerberos keytab file"
},
+ {
+ "passdb",
+ rpc_vampire_passdb,
+ NET_TRANSPORT_RPC,
+ "Dump remote SAM database to passdb",
+ "net rpc vampire passdb\n"
+ " Dump remote SAM database to passdb"
+ },
{NULL, NULL, 0, NULL, NULL}
};
diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c
index 2fe464a000..8070a6282b 100644
--- a/source3/utils/net_rpc_join.c
+++ b/source3/utils/net_rpc_join.c
@@ -339,7 +339,8 @@ int net_rpc_join_newstyle(struct net_context *c, int argc, const char **argv)
&cli->user_session_key,
&crypt_pwd);
- init_samr_user_info24(&set_info.info24, crypt_pwd.data, 24);
+ init_samr_user_info24(&set_info.info24, &crypt_pwd,
+ PASS_DONT_CHANGE_AT_NEXT_LOGON);
CHECK_RPC_ERR(rpccli_samr_SetUserInfo2(pipe_hnd, mem_ctx,
&user_pol,
diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c
index c0922efe6b..6b23db74cb 100644
--- a/source3/utils/net_rpc_samsync.c
+++ b/source3/utils/net_rpc_samsync.c
@@ -26,6 +26,81 @@
#include "includes.h"
#include "utils/net.h"
+static void parse_samsync_partial_replication_objects(TALLOC_CTX *mem_ctx,
+ int argc,
+ const char **argv,
+ bool *do_single_object_replication,
+ struct samsync_object **objects,
+ uint32_t *num_objects)
+{
+ int i;
+
+ if (argc > 0) {
+ *do_single_object_replication = true;
+ }
+
+ for (i=0; i<argc; i++) {
+
+ struct samsync_object o;
+
+ ZERO_STRUCT(o);
+
+ if (!StrnCaseCmp(argv[i], "user_rid=", strlen("user_rid="))) {
+ o.object_identifier.rid = get_int_param(argv[i]);
+ o.object_type = NETR_DELTA_USER;
+ o.database_id = SAM_DATABASE_DOMAIN;
+ }
+ if (!StrnCaseCmp(argv[i], "group_rid=", strlen("group_rid="))) {
+ o.object_identifier.rid = get_int_param(argv[i]);
+ o.object_type = NETR_DELTA_GROUP;
+ o.database_id = SAM_DATABASE_DOMAIN;
+ }
+ if (!StrnCaseCmp(argv[i], "group_member_rid=", strlen("group_member_rid="))) {
+ o.object_identifier.rid = get_int_param(argv[i]);
+ o.object_type = NETR_DELTA_GROUP_MEMBER;
+ o.database_id = SAM_DATABASE_DOMAIN;
+ }
+ if (!StrnCaseCmp(argv[i], "alias_rid=", strlen("alias_rid="))) {
+ o.object_identifier.rid = get_int_param(argv[i]);
+ o.object_type = NETR_DELTA_ALIAS;
+ o.database_id = SAM_DATABASE_BUILTIN;
+ }
+ if (!StrnCaseCmp(argv[i], "alias_member_rid=", strlen("alias_member_rid="))) {
+ o.object_identifier.rid = get_int_param(argv[i]);
+ o.object_type = NETR_DELTA_ALIAS_MEMBER;
+ o.database_id = SAM_DATABASE_BUILTIN;
+ }
+ if (!StrnCaseCmp(argv[i], "account_sid=", strlen("account_sid="))) {
+ const char *sid_str = get_string_param(argv[i]);
+ string_to_sid(&o.object_identifier.sid, sid_str);
+ o.object_type = NETR_DELTA_ACCOUNT;
+ o.database_id = SAM_DATABASE_PRIVS;
+ }
+ if (!StrnCaseCmp(argv[i], "policy_sid=", strlen("policy_sid="))) {
+ const char *sid_str = get_string_param(argv[i]);
+ string_to_sid(&o.object_identifier.sid, sid_str);
+ o.object_type = NETR_DELTA_POLICY;
+ o.database_id = SAM_DATABASE_PRIVS;
+ }
+ if (!StrnCaseCmp(argv[i], "trustdom_sid=", strlen("trustdom_sid="))) {
+ const char *sid_str = get_string_param(argv[i]);
+ string_to_sid(&o.object_identifier.sid, sid_str);
+ o.object_type = NETR_DELTA_TRUSTED_DOMAIN;
+ o.database_id = SAM_DATABASE_PRIVS;
+ }
+ if (!StrnCaseCmp(argv[i], "secret_name=", strlen("secret_name="))) {
+ o.object_identifier.name = get_string_param(argv[i]);
+ o.object_type = NETR_DELTA_SECRET;
+ o.database_id = SAM_DATABASE_PRIVS;
+ }
+
+ if (o.object_type > 0) {
+ ADD_TO_ARRAY(mem_ctx, struct samsync_object, o,
+ objects, num_objects);
+ }
+ }
+}
+
/* dump sam database via samsync rpc calls */
NTSTATUS rpc_samdump_internals(struct net_context *c,
const DOM_SID *domain_sid,
@@ -48,9 +123,17 @@ NTSTATUS rpc_samdump_internals(struct net_context *c,
ctx->mode = NET_SAMSYNC_MODE_DUMP;
ctx->cli = pipe_hnd;
- ctx->delta_fn = display_sam_entries;
+ ctx->ops = &libnet_samsync_display_ops;
ctx->domain_name = domain_name;
+ ctx->force_full_replication = c->opt_force_full_repl ? true : false;
+ ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
+
+ parse_samsync_partial_replication_objects(ctx, argc, argv,
+ &ctx->single_object_replication,
+ &ctx->objects,
+ &ctx->num_objects);
+
libnet_samsync(SAM_DATABASE_DOMAIN, ctx);
libnet_samsync(SAM_DATABASE_BUILTIN, ctx);
@@ -123,9 +206,17 @@ NTSTATUS rpc_vampire_internals(struct net_context *c,
ctx->mode = NET_SAMSYNC_MODE_FETCH_PASSDB;
ctx->cli = pipe_hnd;
- ctx->delta_fn = fetch_sam_entries;
+ ctx->ops = &libnet_samsync_passdb_ops;
ctx->domain_name = domain_name;
+ ctx->force_full_replication = c->opt_force_full_repl ? true : false;
+ ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
+
+ parse_samsync_partial_replication_objects(ctx, argc, argv,
+ &ctx->single_object_replication,
+ &ctx->objects,
+ &ctx->num_objects);
+
/* fetch domain */
result = libnet_samsync(SAM_DATABASE_DOMAIN, ctx);
@@ -157,6 +248,19 @@ NTSTATUS rpc_vampire_internals(struct net_context *c,
return result;
}
+int rpc_vampire_passdb(struct net_context *c, int argc, const char **argv)
+{
+ if (c->display_usage) {
+ d_printf("Usage:\n"
+ "net rpc vampire passdb\n"
+ " Dump remote SAM database to passdb\n");
+ return 0;
+ }
+
+ return run_rpc_command(c, NULL, &ndr_table_netlogon.syntax_id, 0,
+ rpc_vampire_internals, argc, argv);
+}
+
NTSTATUS rpc_vampire_ldif_internals(struct net_context *c,
const DOM_SID *domain_sid,
const char *domain_name,
@@ -179,12 +283,21 @@ NTSTATUS rpc_vampire_ldif_internals(struct net_context *c,
if (argc >= 1) {
ctx->output_filename = argv[0];
}
+ if (argc >= 2) {
+ parse_samsync_partial_replication_objects(ctx, argc-1, argv+1,
+ &ctx->single_object_replication,
+ &ctx->objects,
+ &ctx->num_objects);
+ }
ctx->mode = NET_SAMSYNC_MODE_FETCH_LDIF;
ctx->cli = pipe_hnd;
- ctx->delta_fn = fetch_sam_entries_ldif;
+ ctx->ops = &libnet_samsync_ldif_ops;
ctx->domain_name = domain_name;
+ ctx->force_full_replication = c->opt_force_full_repl ? true : false;
+ ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
+
/* fetch domain */
status = libnet_samsync(SAM_DATABASE_DOMAIN, ctx);
@@ -249,17 +362,29 @@ NTSTATUS rpc_vampire_keytab_internals(struct net_context *c,
return status;
}
- if (argc >= 1) {
+ if (argc < 1) {
+ /* the caller should ensure that a filename is provided */
+ return NT_STATUS_INVALID_PARAMETER;
+ } else {
ctx->output_filename = argv[0];
}
+ if (argc >= 2) {
+ parse_samsync_partial_replication_objects(ctx, argc-1, argv+1,
+ &ctx->single_object_replication,
+ &ctx->objects,
+ &ctx->num_objects);
+ }
ctx->mode = NET_SAMSYNC_MODE_FETCH_KEYTAB;
ctx->cli = pipe_hnd;
- ctx->delta_fn = fetch_sam_entries_keytab;
+ ctx->ops = &libnet_samsync_keytab_ops;
ctx->domain_name = domain_name;
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;
+
/* fetch domain */
status = libnet_samsync(SAM_DATABASE_DOMAIN, ctx);
@@ -299,9 +424,13 @@ static NTSTATUS rpc_vampire_keytab_ds_internals(struct net_context *c,
ctx->force_full_replication = c->opt_force_full_repl ? true : false;
ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
- if (argc >= 1) {
+ if (argc < 1) {
+ /* the caller should ensure that a filename is provided */
+ return NT_STATUS_INVALID_PARAMETER;
+ } else {
ctx->output_filename = argv[0];
}
+
if (argc >= 2) {
ctx->object_dns = &argv[1];
ctx->object_count = argc - 1;
@@ -341,22 +470,41 @@ static NTSTATUS rpc_vampire_keytab_ds_internals(struct net_context *c,
int rpc_vampire_keytab(struct net_context *c, int argc, const char **argv)
{
int ret = 0;
+ NTSTATUS status;
+ struct cli_state *cli = NULL;
+ struct net_dc_info dc_info;
- if (c->display_usage) {
+ if (c->display_usage || (argc < 1)) {
d_printf("Usage:\n"
- "net rpc vampire keytab\n"
+ "net rpc vampire keytab <keytabfile>\n"
" Dump remote SAM database to Kerberos keytab file\n");
return 0;
}
- ret = run_rpc_command(c, NULL, &ndr_table_drsuapi.syntax_id,
- NET_FLAGS_SEAL,
- rpc_vampire_keytab_ds_internals, argc, argv);
- if (ret == 0) {
- return 0;
+ status = net_make_ipc_connection(c, 0, &cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ return -1;
}
- return run_rpc_command(c, NULL, &ndr_table_netlogon.syntax_id, 0,
- rpc_vampire_keytab_internals,
- argc, argv);
+ status = net_scan_dc(c, cli, &dc_info);
+ if (!NT_STATUS_IS_OK(status)) {
+ return -1;
+ }
+
+ 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);
+ } else {
+ ret = run_rpc_command(c, cli, &ndr_table_drsuapi.syntax_id,
+ NET_FLAGS_SEAL,
+ rpc_vampire_keytab_ds_internals, argc, argv);
+ }
+
+ return ret;
}
diff --git a/source3/utils/net_sam.c b/source3/utils/net_sam.c
index ce132131f7..e8ebb60205 100644
--- a/source3/utils/net_sam.c
+++ b/source3/utils/net_sam.c
@@ -1735,7 +1735,7 @@ doma_done:
d_printf("Checking Guest's group.\n");
- pwd = getpwnam_alloc(NULL, lp_guestaccount());
+ pwd = getpwnam_alloc(talloc_autofree_context(), lp_guestaccount());
if (!pwd) {
d_fprintf(stderr, "Failed to find just created Guest account!\n"
" Is nss properly configured?!\n");
diff --git a/source3/utils/net_util.c b/source3/utils/net_util.c
index a9b2bbe621..590a916522 100644
--- a/source3/utils/net_util.c
+++ b/source3/utils/net_util.c
@@ -607,3 +607,41 @@ const char *net_share_type_str(int num_type)
default: return "Unknown";
}
}
+
+NTSTATUS net_scan_dc(struct net_context *c,
+ struct cli_state *cli,
+ struct net_dc_info *dc_info)
+{
+ TALLOC_CTX *mem_ctx = talloc_tos();
+ struct rpc_pipe_client *dssetup_pipe = NULL;
+ union dssetup_DsRoleInfo info;
+ NTSTATUS status;
+
+ ZERO_STRUCTP(dc_info);
+
+ status = cli_rpc_pipe_open_noauth(cli, &ndr_table_dssetup.syntax_id,
+ &dssetup_pipe);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = rpccli_dssetup_DsRoleGetPrimaryDomainInformation(dssetup_pipe, mem_ctx,
+ DS_ROLE_BASIC_INFORMATION,
+ &info,
+ NULL);
+ TALLOC_FREE(dssetup_pipe);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ dc_info->is_dc = (info.basic.role & (DS_ROLE_PRIMARY_DC|DS_ROLE_BACKUP_DC));
+ dc_info->is_pdc = (info.basic.role & DS_ROLE_PRIMARY_DC);
+ dc_info->is_ad = (info.basic.flags & DS_ROLE_PRIMARY_DS_RUNNING);
+ dc_info->is_mixed_mode = (info.basic.flags & DS_ROLE_PRIMARY_DS_MIXED_MODE);
+ dc_info->netbios_domain_name = talloc_strdup(mem_ctx, info.basic.domain);
+ dc_info->dns_domain_name = talloc_strdup(mem_ctx, info.basic.dns_domain);
+ dc_info->forest_name = talloc_strdup(mem_ctx, info.basic.forest);
+
+ return NT_STATUS_OK;
+}
diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c
index 0a76761cb2..8aa8e5e0f9 100644
--- a/source3/utils/ntlm_auth.c
+++ b/source3/utils/ntlm_auth.c
@@ -380,13 +380,25 @@ NTSTATUS contact_winbind_auth_crap(const char *username,
}
if (nt_response && nt_response->length) {
- memcpy(request.data.auth_crap.nt_resp,
- nt_response->data,
- MIN(nt_response->length, sizeof(request.data.auth_crap.nt_resp)));
+ if (nt_response->length > sizeof(request.data.auth_crap.nt_resp)) {
+ request.flags = request.flags | WBFLAG_BIG_NTLMV2_BLOB;
+ request.extra_len = nt_response->length;
+ request.extra_data.data = SMB_MALLOC_ARRAY(char, request.extra_len);
+ if (request.extra_data.data == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ memcpy(request.extra_data.data, nt_response->data,
+ nt_response->length);
+
+ } else {
+ memcpy(request.data.auth_crap.nt_resp,
+ nt_response->data, nt_response->length);
+ }
request.data.auth_crap.nt_resp_len = nt_response->length;
}
result = winbindd_request_response(WINBINDD_PAM_AUTH_CRAP, &request, &response);
+ SAFE_FREE(request.extra_data.data);
/* Display response */
@@ -535,7 +547,8 @@ static NTSTATUS winbind_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB
if (memcmp(user_sess_key, zeros, 16) != 0) {
*user_session_key = data_blob(user_sess_key, 16);
}
- ntlmssp_state->auth_context = talloc_strdup(ntlmssp_state->mem_ctx, unix_name);
+ ntlmssp_state->auth_context = talloc_strdup(ntlmssp_state,
+ unix_name);
SAFE_FREE(unix_name);
} else {
DEBUG(NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED) ? 0 : 3,
@@ -555,7 +568,7 @@ static NTSTATUS local_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *u
nt_lm_owf_gen (opt_password, nt_pw, lm_pw);
- nt_status = ntlm_password_check(ntlmssp_state->mem_ctx,
+ nt_status = ntlm_password_check(ntlmssp_state,
&ntlmssp_state->chal,
&ntlmssp_state->lm_resp,
&ntlmssp_state->nt_resp,
@@ -566,7 +579,7 @@ static NTSTATUS local_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *u
lm_pw, nt_pw, user_session_key, lm_session_key);
if (NT_STATUS_IS_OK(nt_status)) {
- ntlmssp_state->auth_context = talloc_asprintf(ntlmssp_state->mem_ctx,
+ ntlmssp_state->auth_context = talloc_asprintf(ntlmssp_state,
"%s%c%s", ntlmssp_state->domain,
*lp_winbind_separator(),
ntlmssp_state->user);
diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c
index fe99b6fc9e..50cbc43d6d 100644
--- a/source3/utils/pdbedit.c
+++ b/source3/utils/pdbedit.c
@@ -571,7 +571,7 @@ static int new_user (struct pdb_methods *in, const char *username,
get_global_sam_sid();
- if ( !(pwd = getpwnam_alloc( NULL, username )) ) {
+ if ( !(pwd = getpwnam_alloc(talloc_autofree_context(), username )) ) {
DEBUG(0,("Cannot locate Unix account for %s\n", username));
return -1;
}
@@ -675,7 +675,7 @@ static int new_machine (struct pdb_methods *in, const char *machine_in)
fstrcpy(machineaccount, machinename);
fstrcat(machineaccount, "$");
- if ( !(pwd = getpwnam_alloc( NULL, machineaccount )) ) {
+ if ( !(pwd = getpwnam_alloc(talloc_autofree_context(), machineaccount )) ) {
DEBUG(0,("Cannot locate Unix account for %s\n", machineaccount));
return -1;
}
diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c
index 600fe52f0d..d2652ad95a 100644
--- a/source3/utils/smbpasswd.c
+++ b/source3/utils/smbpasswd.c
@@ -337,7 +337,7 @@ static int process_root(int local_flags)
load_interfaces();
}
- if (!user_name[0] && (pwd = getpwuid_alloc(NULL, geteuid()))) {
+ if (!user_name[0] && (pwd = getpwuid_alloc(talloc_autofree_context(), geteuid()))) {
fstrcpy(user_name, pwd->pw_name);
TALLOC_FREE(pwd);
}
@@ -498,7 +498,7 @@ static int process_nonroot(int local_flags)
}
if (!user_name[0]) {
- pwd = getpwuid_alloc(NULL, getuid());
+ pwd = getpwuid_alloc(talloc_autofree_context(), getuid());
if (pwd) {
fstrcpy(user_name,pwd->pw_name);
TALLOC_FREE(pwd);
diff --git a/source3/utils/smbtree.c b/source3/utils/smbtree.c
index ce2de4d7fe..9fc02bac13 100644
--- a/source3/utils/smbtree.c
+++ b/source3/utils/smbtree.c
@@ -30,15 +30,15 @@ static enum tree_level level = LEV_SHARE;
/* Holds a list of workgroups or servers */
-struct name_list {
- struct name_list *prev, *next;
+struct smb_name_list {
+ struct smb_name_list *prev, *next;
char *name, *comment;
uint32 server_type;
};
-static struct name_list *workgroups, *servers, *shares;
+static struct smb_name_list *workgroups, *servers, *shares;
-static void free_name_list(struct name_list *list)
+static void free_name_list(struct smb_name_list *list)
{
while(list)
DLIST_REMOVE(list, list);
@@ -47,10 +47,10 @@ static void free_name_list(struct name_list *list)
static void add_name(const char *machine_name, uint32 server_type,
const char *comment, void *state)
{
- struct name_list **name_list = (struct name_list **)state;
- struct name_list *new_name;
+ struct smb_name_list **name_list = (struct smb_name_list **)state;
+ struct smb_name_list *new_name;
- new_name = SMB_MALLOC_P(struct name_list);
+ new_name = SMB_MALLOC_P(struct smb_name_list);
if (!new_name)
return;
@@ -222,7 +222,7 @@ static bool get_shares(char *server_name, struct user_auth_info *user_info)
static bool print_tree(struct user_auth_info *user_info)
{
- struct name_list *wg, *sv, *sh;
+ struct smb_name_list *wg, *sv, *sh;
/* List workgroups */
diff --git a/source3/web/cgi.c b/source3/web/cgi.c
index ce36bd9310..49e83717c3 100644
--- a/source3/web/cgi.c
+++ b/source3/web/cgi.c
@@ -314,7 +314,7 @@ static void cgi_web_auth(void)
exit(0);
}
- pwd = getpwnam_alloc(NULL, user);
+ pwd = getpwnam_alloc(talloc_autofree_context(), user);
if (!pwd) {
printf("%sCannot find user %s<br>%s\n", head, user, tail);
exit(0);
@@ -367,7 +367,7 @@ static bool cgi_handle_authorization(char *line)
* Try and get the user from the UNIX password file.
*/
- pass = getpwnam_alloc(NULL, user);
+ pass = getpwnam_alloc(talloc_autofree_context(), user);
/*
* Validate the password they have given.
diff --git a/source3/web/neg_lang.c b/source3/web/neg_lang.c
index 82411000cd..491ca9eedd 100644
--- a/source3/web/neg_lang.c
+++ b/source3/web/neg_lang.c
@@ -74,7 +74,7 @@ void web_set_lang(const char *lang_string)
int lang_num, i;
/* build the lang list */
- lang_list = str_list_make(talloc_tos(), lang_string, ", \t\r\n");
+ lang_list = str_list_make_v3(talloc_tos(), lang_string, ", \t\r\n");
if (!lang_list) return;
/* sort the list by priority */
diff --git a/source3/winbindd/idmap.c b/source3/winbindd/idmap.c
index cfc5597f42..aaba7e53ee 100644
--- a/source3/winbindd/idmap.c
+++ b/source3/winbindd/idmap.c
@@ -461,6 +461,9 @@ static struct idmap_domain *idmap_find_domain(const char *domname)
struct idmap_domain *result;
int i;
+ DEBUG(10, ("idmap_find_domain called for domain '%s'\n",
+ domname?domname:"NULL"));
+
/*
* Always init the default domain, we can't go without one
*/
@@ -725,6 +728,10 @@ NTSTATUS idmap_backends_unixid_to_sid(const char *domname, struct id_map *id)
struct idmap_domain *dom;
struct id_map *maps[2];
+ DEBUG(10, ("idmap_backend_unixid_to_sid: domain = '%s', xid = %d "
+ "(type %d)\n",
+ domname?domname:"NULL", id->xid.id, id->xid.type));
+
maps[0] = id;
maps[1] = NULL;
@@ -751,6 +758,9 @@ NTSTATUS idmap_backends_sid_to_unixid(const char *domain, struct id_map *id)
struct idmap_domain *dom;
struct id_map *maps[2];
+ DEBUG(10, ("idmap_backend_sid_to_unixid: domain = '%s', sid = [%s]\n",
+ domain?domain:"NULL", sid_string_dbg(id->sid)));
+
maps[0] = id;
maps[1] = NULL;
@@ -788,3 +798,20 @@ NTSTATUS idmap_set_mapping(const struct id_map *map)
return dom->methods->set_mapping(dom, map);
}
+
+NTSTATUS idmap_remove_mapping(const struct id_map *map)
+{
+ struct idmap_domain *dom;
+
+ dom = idmap_find_domain(NULL);
+ if (dom == NULL) {
+ DEBUG(3, ("no default domain, no place to write\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ if (dom->methods->remove_mapping == NULL) {
+ DEBUG(3, ("default domain not writable\n"));
+ return NT_STATUS_MEDIA_WRITE_PROTECTED;
+ }
+
+ return dom->methods->remove_mapping(dom, map);
+}
diff --git a/source3/winbindd/idmap_ad.c b/source3/winbindd/idmap_ad.c
index 60a2d8642a..b22e5af94a 100644
--- a/source3/winbindd/idmap_ad.c
+++ b/source3/winbindd/idmap_ad.c
@@ -9,6 +9,7 @@
* Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
* Copyright (C) Gerald (Jerry) Carter 2004-2007
* Copyright (C) Luke Howard 2001-2004
+ * Copyright (C) Michael Adam 2008
*
* 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
@@ -25,6 +26,7 @@
*/
#include "includes.h"
+#include "winbindd.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_IDMAP
@@ -43,31 +45,39 @@
struct idmap_ad_context {
uint32_t filter_low_id;
uint32_t filter_high_id;
+ ADS_STRUCT *ads;
+ struct posix_schema *ad_schema;
+ enum wb_posix_mapping ad_map_type; /* WB_POSIX_MAP_UNKNOWN */
};
NTSTATUS init_module(void);
-static ADS_STRUCT *ad_idmap_ads = NULL;
-static struct posix_schema *ad_schema = NULL;
-static enum wb_posix_mapping ad_map_type = WB_POSIX_MAP_UNKNOWN;
-
/************************************************************************
***********************************************************************/
-static ADS_STRUCT *ad_idmap_cached_connection_internal(void)
+static ADS_STATUS ad_idmap_cached_connection_internal(struct idmap_domain *dom)
{
ADS_STRUCT *ads;
ADS_STATUS status;
bool local = False;
fstring dc_name;
struct sockaddr_storage dc_ip;
+ struct idmap_ad_context *ctx;
+ char *ldap_server = NULL;
+ char *realm = NULL;
+ struct winbindd_domain *wb_dom;
+
+ DEBUG(10, ("ad_idmap_cached_connection: called for domain '%s'\n",
+ dom->name));
+
+ ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);
- if (ad_idmap_ads != NULL) {
+ if (ctx->ads != NULL) {
time_t expire;
time_t now = time(NULL);
- ads = ad_idmap_ads;
+ ads = ctx->ads;
expire = MIN(ads->auth.tgt_expire, ads->auth.tgs_expire);
@@ -76,15 +86,15 @@ static ADS_STRUCT *ad_idmap_cached_connection_internal(void)
(uint32)expire-(uint32)now, (uint32) expire, (uint32) now));
if ( ads->config.realm && (expire > time(NULL))) {
- return ads;
+ return ADS_SUCCESS;
} else {
/* we own this ADS_STRUCT so make sure it goes away */
DEBUG(7,("Deleting expired krb5 credential cache\n"));
ads->is_mine = True;
ads_destroy( &ads );
ads_kdestroy(WINBIND_CCACHE_NAME);
- ad_idmap_ads = NULL;
- TALLOC_FREE( ad_schema );
+ ctx->ads = NULL;
+ TALLOC_FREE( ctx->ad_schema );
}
}
@@ -93,9 +103,28 @@ static ADS_STRUCT *ad_idmap_cached_connection_internal(void)
setenv("KRB5CCNAME", WINBIND_CCACHE_NAME, 1);
}
- if ( (ads = ads_init(lp_realm(), lp_workgroup(), NULL)) == NULL ) {
+ /*
+ * At this point we only have the NetBIOS domain name.
+ * Check if we can get server nam and realm from SAF cache
+ * and the domain list.
+ */
+ ldap_server = saf_fetch(dom->name);
+ DEBUG(10, ("ldap_server from saf cache: '%s'\n", ldap_server?ldap_server:""));
+
+ wb_dom = find_domain_from_name_noinit(dom->name);
+ if (wb_dom == NULL) {
+ DEBUG(10, ("find_domain_from_name_noinit did not find domain '%s'\n",
+ dom->name));
+ realm = NULL;
+ } else {
+ DEBUG(10, ("find_domain_from_name_noinit found realm '%s' for "
+ " domain '%s'\n", wb_dom->alt_name, dom->name));
+ realm = wb_dom->alt_name;
+ }
+
+ if ( (ads = ads_init(realm, dom->name, ldap_server)) == NULL ) {
DEBUG(1,("ads_init failed\n"));
- return NULL;
+ return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
}
/* the machine acct password might have change - fetch it every time */
@@ -107,54 +136,57 @@ static ADS_STRUCT *ad_idmap_cached_connection_internal(void)
/* setup server affinity */
- get_dc_name( NULL, ads->auth.realm, dc_name, &dc_ip );
+ get_dc_name(dom->name, realm, dc_name, &dc_ip );
status = ads_connect(ads);
if (!ADS_ERR_OK(status)) {
DEBUG(1, ("ad_idmap_init: failed to connect to AD\n"));
ads_destroy(&ads);
- return NULL;
+ return status;
}
ads->is_mine = False;
- ad_idmap_ads = ads;
+ ctx->ads = ads;
- return ads;
+ return ADS_SUCCESS;
}
/************************************************************************
***********************************************************************/
-static ADS_STRUCT *ad_idmap_cached_connection(void)
+static ADS_STATUS ad_idmap_cached_connection(struct idmap_domain *dom)
{
- ADS_STRUCT *ads = ad_idmap_cached_connection_internal();
-
- if ( !ads )
- return NULL;
+ ADS_STATUS status;
+ struct idmap_ad_context * ctx;
+
+ status = ad_idmap_cached_connection_internal(dom);
+ if (!ADS_ERR_OK(status)) {
+ return status;
+ }
+
+ ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);
/* if we have a valid ADS_STRUCT and the schema model is
defined, then we can return here. */
- if ( ad_schema )
- return ads;
+ if ( ctx->ad_schema ) {
+ return ADS_SUCCESS;
+ }
/* Otherwise, set the schema model */
- if ( (ad_map_type == WB_POSIX_MAP_SFU) ||
- (ad_map_type == WB_POSIX_MAP_SFU20) ||
- (ad_map_type == WB_POSIX_MAP_RFC2307) )
+ if ( (ctx->ad_map_type == WB_POSIX_MAP_SFU) ||
+ (ctx->ad_map_type == WB_POSIX_MAP_SFU20) ||
+ (ctx->ad_map_type == WB_POSIX_MAP_RFC2307) )
{
- ADS_STATUS schema_status;
-
- schema_status = ads_check_posix_schema_mapping( NULL, ads, ad_map_type, &ad_schema);
- if ( !ADS_ERR_OK(schema_status) ) {
+ status = ads_check_posix_schema_mapping(NULL, ctx->ads, ctx->ad_map_type, &ctx->ad_schema);
+ if ( !ADS_ERR_OK(status) ) {
DEBUG(2,("ad_idmap_cached_connection: Failed to obtain schema details!\n"));
- return NULL;
}
}
- return ads;
+ return status;
}
/************************************************************************
@@ -190,17 +222,18 @@ static NTSTATUS idmap_ad_initialize(struct idmap_domain *dom,
}
}
+ /* default map type */
+ ctx->ad_map_type = WB_POSIX_MAP_RFC2307;
+
/* schema mode */
- if ( ad_map_type == WB_POSIX_MAP_UNKNOWN )
- ad_map_type = WB_POSIX_MAP_RFC2307;
schema_mode = lp_parm_const_string(-1, config_option, "schema_mode", NULL);
if ( schema_mode && schema_mode[0] ) {
if ( strequal(schema_mode, "sfu") )
- ad_map_type = WB_POSIX_MAP_SFU;
+ ctx->ad_map_type = WB_POSIX_MAP_SFU;
else if ( strequal(schema_mode, "sfu20" ) )
- ad_map_type = WB_POSIX_MAP_SFU20;
+ ctx->ad_map_type = WB_POSIX_MAP_SFU20;
else if ( strequal(schema_mode, "rfc2307" ) )
- ad_map_type = WB_POSIX_MAP_RFC2307;
+ ctx->ad_map_type = WB_POSIX_MAP_RFC2307;
else
DEBUG(0,("idmap_ad_initialize: Unknown schema_mode (%s)\n",
schema_mode));
@@ -256,7 +289,6 @@ static NTSTATUS idmap_ad_unixids_to_sids(struct idmap_domain *dom, struct id_map
TALLOC_CTX *memctx;
struct idmap_ad_context *ctx;
ADS_STATUS rc;
- ADS_STRUCT *ads;
const char *attrs[] = { "sAMAccountType",
"objectSid",
NULL, /* uidnumber */
@@ -284,14 +316,16 @@ static NTSTATUS idmap_ad_unixids_to_sids(struct idmap_domain *dom, struct id_map
return NT_STATUS_NO_MEMORY;
}
- if ( (ads = ad_idmap_cached_connection()) == NULL ) {
- DEBUG(1, ("ADS uninitialized\n"));
+ rc = ad_idmap_cached_connection(dom);
+ if (!ADS_ERR_OK(rc)) {
+ DEBUG(1, ("ADS uninitialized: %s\n", ads_errstr(rc)));
ret = NT_STATUS_UNSUCCESSFUL;
+ /* ret = ads_ntstatus(rc); */
goto done;
}
- attrs[2] = ad_schema->posix_uidnumber_attr;
- attrs[3] = ad_schema->posix_gidnumber_attr;
+ attrs[2] = ctx->ad_schema->posix_uidnumber_attr;
+ attrs[3] = ctx->ad_schema->posix_gidnumber_attr;
again:
bidx = idx;
@@ -308,7 +342,7 @@ again:
ATYPE_INTERDOMAIN_TRUST);
}
u_filter = talloc_asprintf_append_buffer(u_filter, "(%s=%lu)",
- ad_schema->posix_uidnumber_attr,
+ ctx->ad_schema->posix_uidnumber_attr,
(unsigned long)ids[idx]->xid.id);
CHECK_ALLOC_DONE(u_filter);
break;
@@ -322,7 +356,7 @@ again:
ATYPE_SECURITY_LOCAL_GROUP);
}
g_filter = talloc_asprintf_append_buffer(g_filter, "(%s=%lu)",
- ad_schema->posix_gidnumber_attr,
+ ctx->ad_schema->posix_gidnumber_attr,
(unsigned long)ids[idx]->xid.id);
CHECK_ALLOC_DONE(g_filter);
break;
@@ -348,14 +382,14 @@ again:
filter = talloc_asprintf_append_buffer(filter, ")");
CHECK_ALLOC_DONE(filter);
- rc = ads_search_retry(ads, &res, filter, attrs);
+ rc = ads_search_retry(ctx->ads, &res, filter, attrs);
if (!ADS_ERR_OK(rc)) {
DEBUG(1, ("ERROR: ads search returned: %s\n", ads_errstr(rc)));
ret = NT_STATUS_UNSUCCESSFUL;
goto done;
}
- if ( (count = ads_count_replies(ads, res)) == 0 ) {
+ if ( (count = ads_count_replies(ctx->ads, res)) == 0 ) {
DEBUG(10, ("No IDs found\n"));
}
@@ -368,9 +402,9 @@ again:
uint32_t atype;
if (i == 0) { /* first entry */
- entry = ads_first_entry(ads, entry);
+ entry = ads_first_entry(ctx->ads, entry);
} else { /* following ones */
- entry = ads_next_entry(ads, entry);
+ entry = ads_next_entry(ctx->ads, entry);
}
if ( !entry ) {
@@ -379,13 +413,13 @@ again:
}
/* first check if the SID is present */
- if (!ads_pull_sid(ads, entry, "objectSid", &sid)) {
+ if (!ads_pull_sid(ctx->ads, entry, "objectSid", &sid)) {
DEBUG(2, ("Could not retrieve SID from entry\n"));
continue;
}
/* get type */
- if (!ads_pull_uint32(ads, entry, "sAMAccountType", &atype)) {
+ if (!ads_pull_uint32(ctx->ads, entry, "sAMAccountType", &atype)) {
DEBUG(1, ("could not get SAM account type\n"));
continue;
}
@@ -405,9 +439,9 @@ again:
continue;
}
- if (!ads_pull_uint32(ads, entry, (type==ID_TYPE_UID) ?
- ad_schema->posix_uidnumber_attr :
- ad_schema->posix_gidnumber_attr,
+ if (!ads_pull_uint32(ctx->ads, entry, (type==ID_TYPE_UID) ?
+ ctx->ad_schema->posix_uidnumber_attr :
+ ctx->ad_schema->posix_gidnumber_attr,
&id))
{
DEBUG(1, ("Could not get unix ID\n"));
@@ -439,7 +473,7 @@ again:
}
if (res) {
- ads_msgfree(ads, res);
+ ads_msgfree(ctx->ads, res);
}
if (ids[idx]) { /* still some values to map */
@@ -468,7 +502,6 @@ static NTSTATUS idmap_ad_sids_to_unixids(struct idmap_domain *dom, struct id_map
TALLOC_CTX *memctx;
struct idmap_ad_context *ctx;
ADS_STATUS rc;
- ADS_STRUCT *ads;
const char *attrs[] = { "sAMAccountType",
"objectSid",
NULL, /* attr_uidnumber */
@@ -495,14 +528,22 @@ static NTSTATUS idmap_ad_sids_to_unixids(struct idmap_domain *dom, struct id_map
return NT_STATUS_NO_MEMORY;
}
- if ( (ads = ad_idmap_cached_connection()) == NULL ) {
- DEBUG(1, ("ADS uninitialized\n"));
+ rc = ad_idmap_cached_connection(dom);
+ if (!ADS_ERR_OK(rc)) {
+ DEBUG(1, ("ADS uninitialized: %s\n", ads_errstr(rc)));
+ ret = NT_STATUS_UNSUCCESSFUL;
+ /* ret = ads_ntstatus(rc); */
+ goto done;
+ }
+
+ if (ctx->ad_schema == NULL) {
+ DEBUG(0, ("haven't got ctx->ad_schema ! \n"));
ret = NT_STATUS_UNSUCCESSFUL;
goto done;
}
- attrs[2] = ad_schema->posix_uidnumber_attr;
- attrs[3] = ad_schema->posix_gidnumber_attr;
+ attrs[2] = ctx->ad_schema->posix_uidnumber_attr;
+ attrs[3] = ctx->ad_schema->posix_gidnumber_attr;
again:
filter = talloc_asprintf(memctx, "(&(|"
@@ -529,14 +570,14 @@ again:
CHECK_ALLOC_DONE(filter);
DEBUG(10, ("Filter: [%s]\n", filter));
- rc = ads_search_retry(ads, &res, filter, attrs);
+ rc = ads_search_retry(ctx->ads, &res, filter, attrs);
if (!ADS_ERR_OK(rc)) {
DEBUG(1, ("ERROR: ads search returned: %s\n", ads_errstr(rc)));
ret = NT_STATUS_UNSUCCESSFUL;
goto done;
}
- if ( (count = ads_count_replies(ads, res)) == 0 ) {
+ if ( (count = ads_count_replies(ctx->ads, res)) == 0 ) {
DEBUG(10, ("No IDs found\n"));
}
@@ -549,9 +590,9 @@ again:
uint32_t atype;
if (i == 0) { /* first entry */
- entry = ads_first_entry(ads, entry);
+ entry = ads_first_entry(ctx->ads, entry);
} else { /* following ones */
- entry = ads_next_entry(ads, entry);
+ entry = ads_next_entry(ctx->ads, entry);
}
if ( !entry ) {
@@ -560,7 +601,7 @@ again:
}
/* first check if the SID is present */
- if (!ads_pull_sid(ads, entry, "objectSid", &sid)) {
+ if (!ads_pull_sid(ctx->ads, entry, "objectSid", &sid)) {
DEBUG(2, ("Could not retrieve SID from entry\n"));
continue;
}
@@ -572,7 +613,7 @@ again:
}
/* get type */
- if (!ads_pull_uint32(ads, entry, "sAMAccountType", &atype)) {
+ if (!ads_pull_uint32(ctx->ads, entry, "sAMAccountType", &atype)) {
DEBUG(1, ("could not get SAM account type\n"));
continue;
}
@@ -592,9 +633,9 @@ again:
continue;
}
- if (!ads_pull_uint32(ads, entry, (type==ID_TYPE_UID) ?
- ad_schema->posix_uidnumber_attr :
- ad_schema->posix_gidnumber_attr,
+ if (!ads_pull_uint32(ctx->ads, entry, (type==ID_TYPE_UID) ?
+ ctx->ad_schema->posix_uidnumber_attr :
+ ctx->ad_schema->posix_gidnumber_attr,
&id))
{
DEBUG(1, ("Could not get unix ID\n"));
@@ -619,7 +660,7 @@ again:
}
if (res) {
- ads_msgfree(ads, res);
+ ads_msgfree(ctx->ads, res);
}
if (ids[idx]) { /* still some values to map */
@@ -644,16 +685,18 @@ done:
static NTSTATUS idmap_ad_close(struct idmap_domain *dom)
{
- ADS_STRUCT *ads = ad_idmap_ads;
+ struct idmap_ad_context * ctx;
+
+ ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);
- if (ads != NULL) {
+ if (ctx->ads != NULL) {
/* we own this ADS_STRUCT so make sure it goes away */
- ads->is_mine = True;
- ads_destroy( &ads );
- ad_idmap_ads = NULL;
+ ctx->ads->is_mine = True;
+ ads_destroy( &ctx->ads );
+ ctx->ads = NULL;
}
- TALLOC_FREE( ad_schema );
+ TALLOC_FREE( ctx->ad_schema );
return NT_STATUS_OK;
}
@@ -666,66 +709,107 @@ static NTSTATUS idmap_ad_close(struct idmap_domain *dom)
Initialize the {sfu,sfu20,rfc2307} state
***********************************************************************/
-static NTSTATUS nss_sfu_init( struct nss_domain_entry *e )
-{
- /* Sanity check if we have previously been called with a
- different schema model */
+static const char *wb_posix_map_unknown_string = "WB_POSIX_MAP_UNKNOWN";
+static const char *wb_posix_map_template_string = "WB_POSIX_MAP_TEMPLATE";
+static const char *wb_posix_map_sfu_string = "WB_POSIX_MAP_SFU";
+static const char *wb_posix_map_sfu20_string = "WB_POSIX_MAP_SFU20";
+static const char *wb_posix_map_rfc2307_string = "WB_POSIX_MAP_RFC2307";
+static const char *wb_posix_map_unixinfo_string = "WB_POSIX_MAP_UNIXINFO";
- if ( (ad_map_type != WB_POSIX_MAP_UNKNOWN) &&
- (ad_map_type != WB_POSIX_MAP_SFU) )
- {
- DEBUG(0,("nss_sfu_init: Posix Map type has already been set. "
- "Mixed schema models not supported!\n"));
- return NT_STATUS_NOT_SUPPORTED;
+static const char *ad_map_type_string(enum wb_posix_mapping map_type)
+{
+ switch (map_type) {
+ case WB_POSIX_MAP_TEMPLATE:
+ return wb_posix_map_template_string;
+ case WB_POSIX_MAP_SFU:
+ return wb_posix_map_sfu_string;
+ case WB_POSIX_MAP_SFU20:
+ return wb_posix_map_sfu20_string;
+ case WB_POSIX_MAP_RFC2307:
+ return wb_posix_map_rfc2307_string;
+ case WB_POSIX_MAP_UNIXINFO:
+ return wb_posix_map_unixinfo_string;
+ default:
+ return wb_posix_map_unknown_string;
}
-
- ad_map_type = WB_POSIX_MAP_SFU;
-
- return NT_STATUS_OK;
}
-static NTSTATUS nss_sfu20_init( struct nss_domain_entry *e )
+static NTSTATUS nss_ad_generic_init(struct nss_domain_entry *e,
+ enum wb_posix_mapping new_ad_map_type)
{
- /* Sanity check if we have previously been called with a
- different schema model */
+ struct idmap_domain *dom;
+ struct idmap_ad_context *ctx;
+
+ if (e->state != NULL) {
+ dom = talloc_get_type(e->state, struct idmap_domain);
+ } else {
+ dom = TALLOC_ZERO_P(e, struct idmap_domain);
+ if (dom == NULL) {
+ DEBUG(0, ("Out of memory!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+ e->state = dom;
+ }
+
+ if (e->domain != NULL) {
+ dom->name = talloc_strdup(dom, e->domain);
+ if (dom->name == NULL) {
+ DEBUG(0, ("Out of memory!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
- if ( (ad_map_type != WB_POSIX_MAP_UNKNOWN) &&
- (ad_map_type != WB_POSIX_MAP_SFU20) )
+ if (dom->private_data != NULL) {
+ ctx = talloc_get_type(dom->private_data,
+ struct idmap_ad_context);
+ } else {
+ ctx = TALLOC_ZERO_P(dom, struct idmap_ad_context);
+ if (ctx == NULL) {
+ DEBUG(0, ("Out of memory!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+ ctx->ad_map_type = WB_POSIX_MAP_RFC2307;
+ dom->private_data = ctx;
+ }
+
+ if ((ctx->ad_map_type != WB_POSIX_MAP_UNKNOWN) &&
+ (ctx->ad_map_type != new_ad_map_type))
{
- DEBUG(0,("nss_sfu20_init: Posix Map type has already been set. "
- "Mixed schema models not supported!\n"));
- return NT_STATUS_NOT_SUPPORTED;
+ DEBUG(2, ("nss_ad_generic_init: "
+ "Warning: overriding previously set posix map type "
+ "%s for domain %s with map type %s.\n",
+ ad_map_type_string(ctx->ad_map_type),
+ dom->name,
+ ad_map_type_string(new_ad_map_type)));
}
-
- ad_map_type = WB_POSIX_MAP_SFU20;
+
+ ctx->ad_map_type = new_ad_map_type;
return NT_STATUS_OK;
}
-static NTSTATUS nss_rfc2307_init( struct nss_domain_entry *e )
+static NTSTATUS nss_sfu_init( struct nss_domain_entry *e )
{
- /* Sanity check if we have previously been called with a
- different schema model */
-
- if ( (ad_map_type != WB_POSIX_MAP_UNKNOWN) &&
- (ad_map_type != WB_POSIX_MAP_RFC2307) )
- {
- DEBUG(0,("nss_rfc2307_init: Posix Map type has already been set. "
- "Mixed schema models not supported!\n"));
- return NT_STATUS_NOT_SUPPORTED;
- }
-
- ad_map_type = WB_POSIX_MAP_RFC2307;
+ return nss_ad_generic_init(e, WB_POSIX_MAP_SFU);
+}
- return NT_STATUS_OK;
+static NTSTATUS nss_sfu20_init( struct nss_domain_entry *e )
+{
+ return nss_ad_generic_init(e, WB_POSIX_MAP_SFU20);
+}
+
+static NTSTATUS nss_rfc2307_init( struct nss_domain_entry *e )
+{
+ return nss_ad_generic_init(e, WB_POSIX_MAP_RFC2307);
}
/************************************************************************
***********************************************************************/
+
static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e,
const DOM_SID *sid,
- TALLOC_CTX *ctx,
+ TALLOC_CTX *mem_ctx,
ADS_STRUCT *ads,
LDAPMessage *msg,
char **homedir,
@@ -733,7 +817,6 @@ static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e,
char **gecos,
uint32 *gid )
{
- ADS_STRUCT *ads_internal = NULL;
const char *attrs[] = {NULL, /* attr_homedir */
NULL, /* attr_shell */
NULL, /* attr_gecos */
@@ -744,18 +827,27 @@ static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e,
ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
char *sidstr = NULL;
+ struct idmap_domain *dom;
+ struct idmap_ad_context *ctx;
+
+ DEBUG(10, ("nss_ad_get_info called for sid [%s] in domain '%s'\n",
+ sid_string_dbg(sid), e->domain?e->domain:"NULL"));
/* Only do query if we are online */
if (idmap_is_offline()) {
return NT_STATUS_FILE_IS_OFFLINE;
}
- /* We are assuming that the internal ADS_STRUCT is for the
- same forest as the incoming *ads pointer */
+ dom = talloc_get_type(e->state, struct idmap_domain);
+ ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);
- ads_internal = ad_idmap_cached_connection();
+ ads_status = ad_idmap_cached_connection(dom);
+ if (!ADS_ERR_OK(ads_status)) {
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
- if ( !ads_internal || !ad_schema ) {
+ if (!ctx->ad_schema) {
+ DEBUG(10, ("nss_ad_get_info: no ad_schema configured!\n"));
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
@@ -766,12 +858,15 @@ static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e,
/* See if we can use the ADS connection struct swe were given */
if (ads) {
- *homedir = ads_pull_string( ads, ctx, msg, ad_schema->posix_homedir_attr );
- *shell = ads_pull_string( ads, ctx, msg, ad_schema->posix_shell_attr );
- *gecos = ads_pull_string( ads, ctx, msg, ad_schema->posix_gecos_attr );
+ DEBUG(10, ("nss_ad_get_info: using given ads connection and "
+ "LDAP message (%p)\n", msg));
+
+ *homedir = ads_pull_string( ads, mem_ctx, msg, ctx->ad_schema->posix_homedir_attr );
+ *shell = ads_pull_string( ads, mem_ctx, msg, ctx->ad_schema->posix_shell_attr );
+ *gecos = ads_pull_string( ads, mem_ctx, msg, ctx->ad_schema->posix_gecos_attr );
if (gid) {
- if ( !ads_pull_uint32(ads, msg, ad_schema->posix_gidnumber_attr, gid ) )
+ if ( !ads_pull_uint32(ads, msg, ctx->ad_schema->posix_gidnumber_attr, gid ) )
*gid = (uint32)-1;
}
@@ -781,13 +876,16 @@ static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e,
/* Have to do our own query */
- attrs[0] = ad_schema->posix_homedir_attr;
- attrs[1] = ad_schema->posix_shell_attr;
- attrs[2] = ad_schema->posix_gecos_attr;
- attrs[3] = ad_schema->posix_gidnumber_attr;
+ DEBUG(10, ("nss_ad_get_info: no ads connection given, doing our "
+ "own query\n"));
+
+ attrs[0] = ctx->ad_schema->posix_homedir_attr;
+ attrs[1] = ctx->ad_schema->posix_shell_attr;
+ attrs[2] = ctx->ad_schema->posix_gecos_attr;
+ attrs[3] = ctx->ad_schema->posix_gidnumber_attr;
sidstr = sid_binstring(sid);
- filter = talloc_asprintf(ctx, "(objectSid=%s)", sidstr);
+ filter = talloc_asprintf(mem_ctx, "(objectSid=%s)", sidstr);
SAFE_FREE(sidstr);
if (!filter) {
@@ -795,18 +893,18 @@ static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e,
goto done;
}
- ads_status = ads_search_retry(ads_internal, &msg_internal, filter, attrs);
+ ads_status = ads_search_retry(ctx->ads, &msg_internal, filter, attrs);
if (!ADS_ERR_OK(ads_status)) {
nt_status = ads_ntstatus(ads_status);
goto done;
}
- *homedir = ads_pull_string(ads_internal, ctx, msg_internal, ad_schema->posix_homedir_attr);
- *shell = ads_pull_string(ads_internal, ctx, msg_internal, ad_schema->posix_shell_attr);
- *gecos = ads_pull_string(ads_internal, ctx, msg_internal, ad_schema->posix_gecos_attr);
+ *homedir = ads_pull_string(ctx->ads, mem_ctx, msg_internal, ctx->ad_schema->posix_homedir_attr);
+ *shell = ads_pull_string(ctx->ads, mem_ctx, msg_internal, ctx->ad_schema->posix_shell_attr);
+ *gecos = ads_pull_string(ctx->ads, mem_ctx, msg_internal, ctx->ad_schema->posix_gecos_attr);
if (gid) {
- if (!ads_pull_uint32(ads_internal, msg_internal, ad_schema->posix_gidnumber_attr, gid))
+ if (!ads_pull_uint32(ctx->ads, msg_internal, ctx->ad_schema->posix_gidnumber_attr, gid))
*gid = (uint32)-1;
}
@@ -814,7 +912,7 @@ static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e,
done:
if (msg_internal) {
- ads_msgfree(ads_internal, msg_internal);
+ ads_msgfree(ctx->ads, msg_internal);
}
return nt_status;
@@ -824,21 +922,22 @@ done:
*********************************************************************/
static NTSTATUS nss_ad_map_to_alias(TALLOC_CTX *mem_ctx,
- const char *domain,
+ struct nss_domain_entry *e,
const char *name,
char **alias)
{
- ADS_STRUCT *ads_internal = NULL;
const char *attrs[] = {NULL, /* attr_uid */
NULL };
char *filter = NULL;
LDAPMessage *msg = NULL;
ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ struct idmap_domain *dom;
+ struct idmap_ad_context *ctx = NULL;
/* Check incoming parameters */
- if ( !domain || !name || !*alias) {
+ if ( !e || !e->domain || !name || !*alias) {
nt_status = NT_STATUS_INVALID_PARAMETER;
goto done;
}
@@ -850,14 +949,20 @@ static NTSTATUS nss_ad_map_to_alias(TALLOC_CTX *mem_ctx,
goto done;
}
- ads_internal = ad_idmap_cached_connection();
+ dom = talloc_get_type(e->state, struct idmap_domain);
+ ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);
+
+ ads_status = ad_idmap_cached_connection(dom);
+ if (!ADS_ERR_OK(ads_status)) {
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
- if (!ads_internal || !ad_schema) {
+ if (!ctx->ad_schema) {
nt_status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
goto done;
}
- attrs[0] = ad_schema->posix_uid_attr;
+ attrs[0] = ctx->ad_schema->posix_uid_attr;
filter = talloc_asprintf(mem_ctx,
"(sAMAccountName=%s)",
@@ -867,13 +972,13 @@ static NTSTATUS nss_ad_map_to_alias(TALLOC_CTX *mem_ctx,
goto done;
}
- ads_status = ads_search_retry(ads_internal, &msg, filter, attrs);
+ ads_status = ads_search_retry(ctx->ads, &msg, filter, attrs);
if (!ADS_ERR_OK(ads_status)) {
nt_status = ads_ntstatus(ads_status);
goto done;
}
- *alias = ads_pull_string(ads_internal, mem_ctx, msg, ad_schema->posix_uid_attr );
+ *alias = ads_pull_string(ctx->ads, mem_ctx, msg, ctx->ad_schema->posix_uid_attr);
if (!*alias) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -886,7 +991,7 @@ done:
talloc_destroy(filter);
}
if (msg) {
- ads_msgfree(ads_internal, msg);
+ ads_msgfree(ctx->ads, msg);
}
return nt_status;
@@ -896,11 +1001,10 @@ done:
*********************************************************************/
static NTSTATUS nss_ad_map_from_alias( TALLOC_CTX *mem_ctx,
- const char *domain,
+ struct nss_domain_entry *e,
const char *alias,
char **name )
{
- ADS_STRUCT *ads_internal = NULL;
const char *attrs[] = {"sAMAccountName",
NULL };
char *filter = NULL;
@@ -908,6 +1012,8 @@ static NTSTATUS nss_ad_map_from_alias( TALLOC_CTX *mem_ctx,
ADS_STATUS ads_status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
char *username;
+ struct idmap_domain *dom;
+ struct idmap_ad_context *ctx = NULL;
/* Check incoming parameters */
@@ -923,29 +1029,35 @@ static NTSTATUS nss_ad_map_from_alias( TALLOC_CTX *mem_ctx,
goto done;
}
- ads_internal = ad_idmap_cached_connection();
+ dom = talloc_get_type(e->state, struct idmap_domain);
+ ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);
+
+ ads_status = ad_idmap_cached_connection(dom);
+ if (!ADS_ERR_OK(ads_status)) {
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
- if (!ads_internal || !ad_schema) {
+ if (!ctx->ad_schema) {
nt_status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
goto done;
}
filter = talloc_asprintf(mem_ctx,
"(%s=%s)",
- ad_schema->posix_uid_attr,
+ ctx->ad_schema->posix_uid_attr,
alias);
if (!filter) {
nt_status = NT_STATUS_NO_MEMORY;
goto done;
}
- ads_status = ads_search_retry(ads_internal, &msg, filter, attrs);
+ ads_status = ads_search_retry(ctx->ads, &msg, filter, attrs);
if (!ADS_ERR_OK(ads_status)) {
nt_status = ads_ntstatus(ads_status);
goto done;
}
- username = ads_pull_string(ads_internal, mem_ctx, msg,
+ username = ads_pull_string(ctx->ads, mem_ctx, msg,
"sAMAccountName");
if (!username) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -966,7 +1078,7 @@ done:
talloc_destroy(filter);
}
if (msg) {
- ads_msgfree(ads_internal, msg);
+ ads_msgfree(ctx->ads, msg);
}
return nt_status;
diff --git a/source3/winbindd/idmap_adex/idmap_adex.c b/source3/winbindd/idmap_adex/idmap_adex.c
index 7596b1cbd8..7e186ca8a1 100644
--- a/source3/winbindd/idmap_adex/idmap_adex.c
+++ b/source3/winbindd/idmap_adex/idmap_adex.c
@@ -329,9 +329,9 @@ static NTSTATUS _nss_adex_get_info(struct
/**********************************************************************
*********************************************************************/
-static NTSTATUS _nss_adex_map_to_alias(TALLOC_CTX * mem_ctx, const char
- *domain, const char
- *name, char **alias)
+static NTSTATUS _nss_adex_map_to_alias(TALLOC_CTX * mem_ctx,
+ struct nss_domain_entry *e,
+ const char *name, char **alias)
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
struct likewise_cell *cell = NULL;
@@ -344,7 +344,7 @@ static NTSTATUS _nss_adex_map_to_alias(TALLOC_CTX * mem_ctx, const char
BAIL_ON_NTSTATUS_ERROR(nt_status);
}
- nt_status = cell->provider->map_to_alias(mem_ctx, domain,
+ nt_status = cell->provider->map_to_alias(mem_ctx, e->domain,
name, alias);
/* go ahead and allow the cache mgr to mark this in
@@ -360,9 +360,9 @@ done:
/**********************************************************************
*********************************************************************/
-static NTSTATUS _nss_adex_map_from_alias(TALLOC_CTX * mem_ctx, const char
- *domain, const char
- *alias, char **name)
+static NTSTATUS _nss_adex_map_from_alias(TALLOC_CTX * mem_ctx,
+ struct nss_domain_entry *e,
+ const char *alias, char **name)
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
struct likewise_cell *cell = NULL;
@@ -376,7 +376,7 @@ static NTSTATUS _nss_adex_map_from_alias(TALLOC_CTX * mem_ctx, const char
}
- nt_status = cell->provider->map_from_alias(mem_ctx, domain,
+ nt_status = cell->provider->map_from_alias(mem_ctx, e->domain,
alias, name);
/* go ahead and allow the cache mgr to mark this in
diff --git a/source3/winbindd/idmap_hash/idmap_hash.c b/source3/winbindd/idmap_hash/idmap_hash.c
index a050f99bc8..7dd94aede0 100644
--- a/source3/winbindd/idmap_hash/idmap_hash.c
+++ b/source3/winbindd/idmap_hash/idmap_hash.c
@@ -304,14 +304,14 @@ done:
*********************************************************************/
static NTSTATUS nss_hash_map_to_alias(TALLOC_CTX *mem_ctx,
- const char *domain,
+ struct nss_domain_entry *e,
const char *name,
char **alias)
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
const char *value;
- value = talloc_asprintf(mem_ctx, "%s\\%s", domain, name);
+ value = talloc_asprintf(mem_ctx, "%s\\%s", e->domain, name);
BAIL_ON_PTR_NT_ERROR(value, nt_status);
nt_status = mapfile_lookup_key(mem_ctx, value, alias);
@@ -325,7 +325,7 @@ done:
*********************************************************************/
static NTSTATUS nss_hash_map_from_alias(TALLOC_CTX *mem_ctx,
- const char *domain,
+ struct nss_domain_entry *e,
const char *alias,
char **name)
{
diff --git a/source3/winbindd/idmap_tdb.c b/source3/winbindd/idmap_tdb.c
index f9d3a9fbff..4c8cceb691 100644
--- a/source3/winbindd/idmap_tdb.c
+++ b/source3/winbindd/idmap_tdb.c
@@ -820,10 +820,11 @@ done:
}
/**********************************
- set a mapping.
+ set a mapping.
**********************************/
-static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_map *map)
+static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom,
+ const struct id_map *map)
{
struct idmap_tdb_context *ctx;
NTSTATUS ret;
@@ -839,17 +840,19 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_
data.dptr = NULL;
/* TODO: should we filter a set_mapping using low/high filters ? */
-
+
ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
switch (map->xid.type) {
case ID_TYPE_UID:
- kidstr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
+ kidstr = talloc_asprintf(ctx, "UID %lu",
+ (unsigned long)map->xid.id);
break;
-
+
case ID_TYPE_GID:
- kidstr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
+ kidstr = talloc_asprintf(ctx, "GID %lu",
+ (unsigned long)map->xid.id);
break;
default:
@@ -875,8 +878,13 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_
ksid = string_term_tdb_data(ksidstr);
/* *DELETE* previous mappings if any.
- * This is done both SID and [U|G]ID passed in */
-
+ * This is done for both the SID and [U|G]ID passed in */
+
+ /* NOTE: We should lock both the ksid and kid records here, before
+ * making modifications. However, because tdb_chainlock() is a
+ * blocking call we could create an unrecoverable deadlock, so for now
+ * we only lock the ksid record. */
+
/* Lock the record for this SID. */
if (tdb_chainlock(ctx->tdb, ksid) != 0) {
DEBUG(10,("Failed to lock record %s. Error %s\n",
@@ -886,7 +894,8 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_
data = tdb_fetch(ctx->tdb, ksid);
if (data.dptr) {
- DEBUG(10, ("Deleting existing mapping %s <-> %s\n", (const char *)data.dptr, ksidstr ));
+ DEBUG(10, ("Deleting existing mapping %s <-> %s\n",
+ (const char *)data.dptr, ksidstr ));
tdb_delete(ctx->tdb, data);
tdb_delete(ctx->tdb, ksid);
SAFE_FREE(data.dptr);
@@ -894,20 +903,23 @@ static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, const struct id_
data = tdb_fetch(ctx->tdb, kid);
if (data.dptr) {
- DEBUG(10,("Deleting existing mapping %s <-> %s\n", (const char *)data.dptr, kidstr ));
+ DEBUG(10,("Deleting existing mapping %s <-> %s\n",
+ (const char *)data.dptr, kidstr ));
tdb_delete(ctx->tdb, data);
tdb_delete(ctx->tdb, kid);
SAFE_FREE(data.dptr);
}
if (tdb_store(ctx->tdb, ksid, kid, TDB_INSERT) == -1) {
- DEBUG(0, ("Error storing SID -> ID: %s\n", tdb_errorstr(ctx->tdb)));
+ DEBUG(0, ("Error storing SID -> ID: %s\n",
+ tdb_errorstr(ctx->tdb)));
tdb_chainunlock(ctx->tdb, ksid);
ret = NT_STATUS_UNSUCCESSFUL;
goto done;
}
if (tdb_store(ctx->tdb, kid, ksid, TDB_INSERT) == -1) {
- DEBUG(0, ("Error stroing ID -> SID: %s\n", tdb_errorstr(ctx->tdb)));
+ DEBUG(0, ("Error storing ID -> SID: %s\n",
+ tdb_errorstr(ctx->tdb)));
/* try to remove the previous stored SID -> ID map */
tdb_delete(ctx->tdb, ksid);
tdb_chainunlock(ctx->tdb, ksid);
@@ -927,10 +939,11 @@ done:
}
/**********************************
- remove a mapping.
+ remove a mapping.
**********************************/
-static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom, const struct id_map *map)
+static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom,
+ const struct id_map *map)
{
struct idmap_tdb_context *ctx;
NTSTATUS ret;
@@ -946,17 +959,19 @@ static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom, const struct
data.dptr = NULL;
/* TODO: should we filter a remove_mapping using low/high filters ? */
-
+
ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
switch (map->xid.type) {
case ID_TYPE_UID:
- kidstr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
+ kidstr = talloc_asprintf(ctx, "UID %lu",
+ (unsigned long)map->xid.id);
break;
-
+
case ID_TYPE_GID:
- kidstr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
+ kidstr = talloc_asprintf(ctx, "GID %lu",
+ (unsigned long)map->xid.id);
break;
default:
@@ -981,6 +996,11 @@ static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom, const struct
ksid = string_term_tdb_data(ksidstr);
kid = string_term_tdb_data(kidstr);
+ /* NOTE: We should lock both the ksid and kid records here, before
+ * making modifications. However, because tdb_chainlock() is a
+ * blocking call we could create an unrecoverable deadlock, so for now
+ * we only lock the ksid record. */
+
/* Lock the record for this SID. */
if (tdb_chainlock(ctx->tdb, ksid) != 0) {
DEBUG(10,("Failed to lock record %s. Error %s\n",
@@ -1001,16 +1021,17 @@ static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom, const struct
if ((data.dsize != kid.dsize) ||
(memcmp(data.dptr, kid.dptr, data.dsize) != 0)) {
DEBUG(10,("Specified SID does not map to specified ID\n"));
- DEBUGADD(10,("Actual mapping is %s -> %s\n", ksidstr, (const char *)data.dptr));
+ DEBUGADD(10,("Actual mapping is %s -> %s\n", ksidstr,
+ (const char *)data.dptr));
tdb_chainunlock(ctx->tdb, ksid);
ret = NT_STATUS_NONE_MAPPED;
goto done;
}
-
+
DEBUG(10, ("Removing %s <-> %s map\n", ksidstr, kidstr));
/* Delete previous mappings. */
-
+
DEBUG(10, ("Deleting existing mapping %s -> %s\n", ksidstr, kidstr ));
tdb_delete(ctx->tdb, ksid);
diff --git a/source3/winbindd/idmap_util.c b/source3/winbindd/idmap_util.c
index 9f876618be..9abf425f3e 100644
--- a/source3/winbindd/idmap_util.c
+++ b/source3/winbindd/idmap_util.c
@@ -33,7 +33,8 @@ NTSTATUS idmap_uid_to_sid(const char *domname, DOM_SID *sid, uid_t uid)
struct id_map map;
bool expired;
- DEBUG(10,("uid = [%lu]\n", (unsigned long)uid));
+ DEBUG(10,("idmap_uid_to_sid: uid = [%lu], domain = '%s'\n",
+ (unsigned long)uid, domname?domname:"NULL"));
if (idmap_cache_find_uid2sid(uid, sid, &expired)) {
DEBUG(10, ("idmap_cache_find_uid2sid found %d%s\n", uid,
@@ -85,7 +86,8 @@ NTSTATUS idmap_gid_to_sid(const char *domname, DOM_SID *sid, gid_t gid)
struct id_map map;
bool expired;
- DEBUG(10,("gid = [%lu]\n", (unsigned long)gid));
+ DEBUG(10,("idmap_gid_to_si: gid = [%lu], domain = '%s'\n",
+ (unsigned long)gid, domname?domname:"NULL"));
if (idmap_cache_find_gid2sid(gid, sid, &expired)) {
DEBUG(10, ("idmap_cache_find_gid2sid found %d%s\n", gid,
@@ -137,7 +139,8 @@ NTSTATUS idmap_sid_to_uid(const char *dom_name, DOM_SID *sid, uid_t *uid)
struct id_map map;
bool expired;
- DEBUG(10,("idmap_sid_to_uid: sid = [%s]\n", sid_string_dbg(sid)));
+ DEBUG(10,("idmap_sid_to_uid: sid = [%s], domain = '%s'\n",
+ sid_string_dbg(sid), dom_name));
if (idmap_cache_find_sid2uid(sid, uid, &expired)) {
DEBUG(10, ("idmap_cache_find_sid2uid found %d%s\n",
@@ -209,7 +212,8 @@ NTSTATUS idmap_sid_to_gid(const char *domname, DOM_SID *sid, gid_t *gid)
struct id_map map;
bool expired;
- DEBUG(10,("idmap_sid_to_gid: sid = [%s]\n", sid_string_dbg(sid)));
+ DEBUG(10,("idmap_sid_to_gid: sid = [%s], domain = '%s'\n",
+ sid_string_dbg(sid), domname));
if (idmap_cache_find_sid2gid(sid, gid, &expired)) {
DEBUG(10, ("idmap_cache_find_sid2gid found %d%s\n",
diff --git a/source3/winbindd/nss_info.c b/source3/winbindd/nss_info.c
index 0e8cb60257..734c009602 100644
--- a/source3/winbindd/nss_info.c
+++ b/source3/winbindd/nss_info.c
@@ -1,19 +1,20 @@
-/*
+/*
Unix SMB/CIFS implementation.
Idmap NSS headers
Copyright (C) Gerald Carter 2006
+ Copyright (C) Michael Adam 2008
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
Library General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -22,6 +23,7 @@
#include "nss_info.h"
static struct nss_function_entry *backends = NULL;
+static struct nss_function_entry *default_backend = NULL;
static struct nss_domain_entry *nss_domain_list = NULL;
/**********************************************************************
@@ -48,14 +50,14 @@ static struct nss_function_entry *nss_get_backend(const char *name )
{
struct nss_function_entry *entry;
- if ((version != SMB_NSS_INFO_INTERFACE_VERSION)) {
+ if ((version != SMB_NSS_INFO_INTERFACE_VERSION)) {
DEBUG(0, ("smb_register_idmap_nss: Failed to register idmap_nss module.\n"
- "The module was compiled against SMB_NSS_INFO_INTERFACE_VERSION %d,\n"
- "current SMB_NSS_INFO_INTERFACE_VERSION is %d.\n"
- "Please recompile against the current version of samba!\n",
+ "The module was compiled against SMB_NSS_INFO_INTERFACE_VERSION %d,\n"
+ "current SMB_NSS_INFO_INTERFACE_VERSION is %d.\n"
+ "Please recompile against the current version of samba!\n",
version, SMB_NSS_INFO_INTERFACE_VERSION));
return NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
+ }
if (!name || !name[0] || !methods) {
DEBUG(0,("smb_register_idmap_nss: called with NULL pointer or empty name!\n"));
@@ -89,12 +91,12 @@ static bool parse_nss_parm( const char *config, char **backend, char **domain )
int len;
*backend = *domain = NULL;
-
+
if ( !config )
return False;
-
+
p = strchr( config, ':' );
-
+
/* if no : then the string must be the backend name only */
if ( !p ) {
@@ -107,13 +109,13 @@ static bool parse_nss_parm( const char *config, char **backend, char **domain )
if ( strlen(p+1) > 0 ) {
*domain = SMB_STRDUP( p+1 );
}
-
+
len = PTR_DIFF(p,config)+1;
if ( (q = SMB_MALLOC_ARRAY( char, len )) == NULL ) {
SAFE_FREE( *backend );
return False;
}
-
+
StrnCpy( q, config, len-1);
q[len-1] = '\0';
*backend = q;
@@ -121,8 +123,44 @@ static bool parse_nss_parm( const char *config, char **backend, char **domain )
return True;
}
+static NTSTATUS nss_domain_list_add_domain(const char *domain,
+ struct nss_function_entry *nss_backend)
+{
+ struct nss_domain_entry *nss_domain;
+
+ nss_domain = TALLOC_ZERO_P(nss_domain_list, struct nss_domain_entry);
+ if (!nss_domain) {
+ DEBUG(0, ("nss_domain_list_add_domain: talloc() failure!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ nss_domain->backend = nss_backend;
+ if (domain) {
+ nss_domain->domain = talloc_strdup(nss_domain, domain);
+ if (!nss_domain->domain) {
+ DEBUG(0, ("nss_domain_list_add_domain: talloc() "
+ "failure!\n"));
+ TALLOC_FREE(nss_domain);
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
+ nss_domain->init_status = nss_domain->backend->methods->init(nss_domain);
+ if (!NT_STATUS_IS_OK(nss_domain->init_status)) {
+ DEBUG(0, ("nss_init: Failed to init backend '%s' for domain "
+ "'%s'!\n", nss_backend->name, nss_domain->domain));
+ }
+
+ DLIST_ADD(nss_domain_list, nss_domain);
+
+ DEBUG(10, ("Added domain '%s' with backend '%s' to nss_domain_list.\n",
+ domain, nss_backend->name));
+
+ return NT_STATUS_OK;
+}
+
/********************************************************************
- Each nss backend must not store global state, but rather be able
+ Each nss backend must not store global state, but rather be able
to initialize the state on a per domain basis.
*******************************************************************/
@@ -133,18 +171,17 @@ static bool parse_nss_parm( const char *config, char **backend, char **domain )
int i;
char *backend, *domain;
struct nss_function_entry *nss_backend;
- struct nss_domain_entry *nss_domain;
/* check for previous successful initializations */
if ( NT_STATUS_IS_OK(nss_initialized) )
return NT_STATUS_OK;
-
+
/* The "template" backend should alqays be registered as it
is a static module */
if ( (nss_backend = nss_get_backend( "template" )) == NULL ) {
- static_init_nss_info;
+ static_init_nss_info;
}
/* Create the list of nss_domains (loading any shared plugins
@@ -152,12 +189,15 @@ static bool parse_nss_parm( const char *config, char **backend, char **domain )
for ( i=0; nss_list && nss_list[i]; i++ ) {
- if ( !parse_nss_parm(nss_list[i], &backend, &domain) ) {
+ if ( !parse_nss_parm(nss_list[i], &backend, &domain) ) {
DEBUG(0,("nss_init: failed to parse \"%s\"!\n",
nss_list[i]));
- continue;
+ continue;
}
+ DEBUG(10, ("parsed backend = '%s', domain = '%s'\n",
+ backend, domain));
+
/* validate the backend */
if ( (nss_backend = nss_get_backend( backend )) == NULL ) {
@@ -166,41 +206,34 @@ static bool parse_nss_parm( const char *config, char **backend, char **domain )
if ( !NT_STATUS_IS_OK(status) ) {
continue;
}
-
+
/* try again */
if ( (nss_backend = nss_get_backend( backend )) == NULL ) {
DEBUG(0,("nss_init: unregistered backend %s!. Skipping\n",
backend));
continue;
}
-
}
- /* fill in the nss_domain_entry and add it to the
- list of domains */
-
- nss_domain = TALLOC_ZERO_P( nss_domain_list, struct nss_domain_entry );
- if ( !nss_domain ) {
- DEBUG(0,("nss_init: talloc() failure!\n"));
- return NT_STATUS_NO_MEMORY;
+ /*
+ * The first config item of the list without an explicit domain
+ * is treated as the default nss info backend.
+ */
+ if ((domain == NULL) && (default_backend == NULL)) {
+ DEBUG(10, ("nss_init: using '%s' as default backend.\n",
+ backend));
+ default_backend = nss_backend;
}
-
- nss_domain->backend = nss_backend;
- nss_domain->domain = talloc_strdup( nss_domain, domain );
- /* Try to init and ave the result */
-
- nss_domain->init_status = nss_domain->backend->methods->init( nss_domain );
- DLIST_ADD( nss_domain_list, nss_domain );
- if ( !NT_STATUS_IS_OK(nss_domain->init_status) ) {
- DEBUG(0,("nss_init: Failed to init backend for %s domain!\n",
- nss_domain->domain));
+ status = nss_domain_list_add_domain(domain, nss_backend);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
/* cleanup */
SAFE_FREE( backend );
- SAFE_FREE( domain );
+ SAFE_FREE( domain );
}
if ( !nss_domain_list ) {
@@ -210,10 +243,9 @@ static bool parse_nss_parm( const char *config, char **backend, char **domain )
/* we shouild default to use template here */
}
-
-
+
nss_initialized = NT_STATUS_OK;
-
+
return NT_STATUS_OK;
}
@@ -222,7 +254,7 @@ static bool parse_nss_parm( const char *config, char **backend, char **domain )
static struct nss_domain_entry *find_nss_domain( const char *domain )
{
- NTSTATUS status;
+ NTSTATUS status;
struct nss_domain_entry *p;
status = nss_init( lp_winbind_nss_info() );
@@ -231,20 +263,30 @@ static struct nss_domain_entry *find_nss_domain( const char *domain )
nt_errstr(status)));
return NULL;
}
-
+
for ( p=nss_domain_list; p; p=p->next ) {
if ( strequal( p->domain, domain ) )
break;
}
-
- /* If we didn't find a match, then use the default nss info */
+
+ /* If we didn't find a match, then use the default nss backend */
if ( !p ) {
- if ( !nss_domain_list ) {
+ if (!default_backend) {
+ return NULL;
+ }
+
+ status = nss_domain_list_add_domain(domain, default_backend);
+ if (!NT_STATUS_IS_OK(status)) {
return NULL;
}
-
- p = nss_domain_list;
+
+ /*
+ * HACK ALERT:
+ * Here, we use the fact that the new domain was added at
+ * the beginning of the list...
+ */
+ p = nss_domain_list;
}
if ( !NT_STATUS_IS_OK( p->init_status ) ) {
@@ -266,15 +308,18 @@ static struct nss_domain_entry *find_nss_domain( const char *domain )
struct nss_domain_entry *p;
struct nss_info_methods *m;
+ DEBUG(10, ("nss_get_info called for sid [%s] in domain '%s'\n",
+ sid_string_dbg(user_sid), domain?domain:"NULL"));
+
if ( (p = find_nss_domain( domain )) == NULL ) {
DEBUG(4,("nss_get_info: Failed to find nss domain pointer for %s\n",
domain ));
return NT_STATUS_NOT_FOUND;
}
-
+
m = p->backend->methods;
- return m->get_nss_info( p, user_sid, ctx, ads, msg,
+ return m->get_nss_info( p, user_sid, ctx, ads, msg,
homedir, shell, gecos, p_gid );
}
@@ -295,7 +340,7 @@ static struct nss_domain_entry *find_nss_domain( const char *domain )
m = p->backend->methods;
- return m->map_to_alias( mem_ctx, domain, name, alias );
+ return m->map_to_alias(mem_ctx, p, name, alias);
}
@@ -316,7 +361,7 @@ static struct nss_domain_entry *find_nss_domain( const char *domain )
m = p->backend->methods;
- return m->map_from_alias( mem_ctx, domain, alias, name );
+ return m->map_from_alias( mem_ctx, p, alias, name );
}
/********************************************************************
diff --git a/source3/winbindd/nss_info_template.c b/source3/winbindd/nss_info_template.c
index d8f903ddd0..f44c73f3a6 100644
--- a/source3/winbindd/nss_info_template.c
+++ b/source3/winbindd/nss_info_template.c
@@ -62,7 +62,7 @@ static NTSTATUS nss_template_get_info( struct nss_domain_entry *e,
*********************************************************************/
static NTSTATUS nss_template_map_to_alias( TALLOC_CTX *mem_ctx,
- const char *domain,
+ struct nss_domain_entry *e,
const char *name,
char **alias )
{
@@ -73,7 +73,7 @@ static NTSTATUS nss_template_map_to_alias( TALLOC_CTX *mem_ctx,
*********************************************************************/
static NTSTATUS nss_template_map_from_alias( TALLOC_CTX *mem_ctx,
- const char *domain,
+ struct nss_domain_entry *e,
const char *alias,
char **name )
{
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index ce1a1fe52f..82af55800f 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -343,6 +343,7 @@ static struct winbindd_dispatch_table {
{ WINBINDD_ALLOCATE_UID, winbindd_allocate_uid, "ALLOCATE_UID" },
{ WINBINDD_ALLOCATE_GID, winbindd_allocate_gid, "ALLOCATE_GID" },
{ WINBINDD_SET_MAPPING, winbindd_set_mapping, "SET_MAPPING" },
+ { WINBINDD_REMOVE_MAPPING, winbindd_remove_mapping, "REMOVE_MAPPING" },
{ WINBINDD_SET_HWM, winbindd_set_hwm, "SET_HWMS" },
/* Miscellaneous */
@@ -367,7 +368,7 @@ static struct winbindd_dispatch_table {
{ WINBINDD_WINS_BYNAME, winbindd_wins_byname, "WINS_BYNAME" },
{ WINBINDD_WINS_BYIP, winbindd_wins_byip, "WINS_BYIP" },
-
+
/* End of list */
{ WINBINDD_NUM_CMDS, NULL, "NONE" }
diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c
index 1febddf110..5c7d491849 100644
--- a/source3/winbindd/winbindd_ads.c
+++ b/source3/winbindd/winbindd_ads.c
@@ -401,6 +401,47 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
return NT_STATUS_OK;
}
+/* convert a single name to a sid in a domain - use rpc methods */
+static NTSTATUS name_to_sid(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ enum winbindd_cmd orig_cmd,
+ const char *domain_name,
+ const char *name,
+ DOM_SID *sid,
+ enum lsa_SidType *type)
+{
+ return reconnect_methods.name_to_sid(domain, mem_ctx, orig_cmd,
+ domain_name, name,
+ sid, type);
+}
+
+/* convert a domain SID to a user or group name - use rpc methods */
+static NTSTATUS sid_to_name(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *sid,
+ char **domain_name,
+ char **name,
+ enum lsa_SidType *type)
+{
+ return reconnect_methods.sid_to_name(domain, mem_ctx, sid,
+ domain_name, name, type);
+}
+
+/* convert a list of rids to names - use rpc methods */
+static NTSTATUS rids_to_names(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *sid,
+ uint32 *rids,
+ size_t num_rids,
+ char **domain_name,
+ char ***names,
+ enum lsa_SidType **types)
+{
+ return reconnect_methods.rids_to_names(domain, mem_ctx, sid,
+ rids, num_rids,
+ domain_name, names, types);
+}
+
/* If you are looking for "dn_lookup": Yes, it used to be here!
* It has gone now since it was a major speed bottleneck in
* lookup_groupmem (its only use). It has been replaced by
@@ -641,9 +682,10 @@ done:
tokenGroups are not available. */
static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const char *user_dn,
+ const char *user_dn,
DOM_SID *primary_group,
- size_t *p_num_groups, DOM_SID **user_sids)
+ size_t *p_num_groups,
+ DOM_SID **user_sids)
{
ADS_STATUS rc;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
@@ -652,15 +694,15 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain,
size_t num_groups = 0;
DOM_SID *group_sids = NULL;
int i;
- char **strings;
- size_t num_strings = 0;
+ char **strings = NULL;
+ size_t num_strings = 0, num_sids = 0;
DEBUG(3,("ads: lookup_usergroups_memberof\n"));
if ( !winbindd_can_contact_domain( domain ) ) {
- DEBUG(10,("lookup_usergroups_memberof: No incoming trust for domain %s\n",
- domain->name));
+ DEBUG(10,("lookup_usergroups_memberof: No incoming trust for "
+ "domain %s\n", domain->name));
return NT_STATUS_OK;
}
@@ -668,19 +710,19 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain,
if (!ads) {
domain->last_status = NT_STATUS_SERVER_DISABLED;
- goto done;
+ return NT_STATUS_UNSUCCESSFUL;
}
- rc = ads_search_retry_extended_dn_ranged(ads, mem_ctx, user_dn, attrs,
- ADS_EXTENDED_DN_HEX_STRING,
+ rc = ads_search_retry_extended_dn_ranged(ads, mem_ctx, user_dn, attrs,
+ ADS_EXTENDED_DN_HEX_STRING,
&strings, &num_strings);
if (!ADS_ERR_OK(rc)) {
- DEBUG(1,("lookup_usergroups_memberof ads_search member=%s: %s\n",
- user_dn, ads_errstr(rc)));
+ DEBUG(1,("lookup_usergroups_memberof ads_search "
+ "member=%s: %s\n", user_dn, ads_errstr(rc)));
return ads_ntstatus(rc);
}
-
+
*user_sids = NULL;
num_groups = 0;
@@ -693,21 +735,26 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain,
group_sids = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, num_strings + 1);
if (!group_sids) {
- TALLOC_FREE(strings);
status = NT_STATUS_NO_MEMORY;
goto done;
}
for (i=0; i<num_strings; i++) {
-
- if (!ads_get_sid_from_extended_dn(mem_ctx, strings[i],
- ADS_EXTENDED_DN_HEX_STRING,
- &(group_sids)[i])) {
- TALLOC_FREE(group_sids);
- TALLOC_FREE(strings);
- status = NT_STATUS_NO_MEMORY;
- goto done;
+ rc = ads_get_sid_from_extended_dn(mem_ctx, strings[i],
+ ADS_EXTENDED_DN_HEX_STRING,
+ &(group_sids)[i]);
+ if (!ADS_ERR_OK(rc)) {
+ /* ignore members without SIDs */
+ if (NT_STATUS_EQUAL(ads_ntstatus(rc),
+ NT_STATUS_NOT_FOUND)) {
+ continue;
+ }
+ else {
+ status = ads_ntstatus(rc);
+ goto done;
+ }
}
+ num_sids++;
}
if (i == 0) {
@@ -716,7 +763,7 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain,
goto done;
}
- for (i=0; i<num_strings; i++) {
+ for (i=0; i<num_sids; i++) {
/* ignore Builtin groups from ADS - Guenther */
if (sid_check_is_in_builtin(&group_sids[i])) {
@@ -728,14 +775,17 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain,
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
-
+
}
*p_num_groups = num_groups;
status = (*user_sids != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
- DEBUG(3,("ads lookup_usergroups (memberof) succeeded for dn=%s\n", user_dn));
+ DEBUG(3,("ads lookup_usergroups (memberof) succeeded for dn=%s\n",
+ user_dn));
+
done:
+ TALLOC_FREE(strings);
TALLOC_FREE(group_sids);
return status;
@@ -894,13 +944,25 @@ done:
return status;
}
+/* Lookup aliases a user is member of - use rpc methods */
+static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ uint32 num_sids, const DOM_SID *sids,
+ uint32 *num_aliases, uint32 **alias_rids)
+{
+ return reconnect_methods.lookup_useraliases(domain, mem_ctx,
+ num_sids, sids,
+ num_aliases,
+ alias_rids);
+}
+
/*
find the members of a group, given a group rid and domain
*/
static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const DOM_SID *group_sid, uint32 *num_names,
- DOM_SID **sid_mem, char ***names,
+ const DOM_SID *group_sid, uint32 *num_names,
+ DOM_SID **sid_mem, char ***names,
uint32 **name_types)
{
ADS_STATUS rc;
@@ -921,7 +983,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
uint32 num_nocache = 0;
TALLOC_CTX *tmp_ctx = NULL;
- DEBUG(10,("ads: lookup_groupmem %s sid=%s\n", domain->name,
+ DEBUG(10,("ads: lookup_groupmem %s sid=%s\n", domain->name,
sid_string_dbg(group_sid)));
*num_names = 0;
@@ -935,12 +997,12 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
if ( !winbindd_can_contact_domain( domain ) ) {
DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n",
- domain->name));
+ domain->name));
return NT_STATUS_OK;
}
ads = ads_cached_connection(domain);
-
+
if (!ads) {
domain->last_status = NT_STATUS_SERVER_DISABLED;
goto done;
@@ -952,8 +1014,8 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
}
/* search for all members of the group */
- if (!(ldap_exp = talloc_asprintf(tmp_ctx, "(objectSid=%s)",
- sidbinstr)))
+ if (!(ldap_exp = talloc_asprintf(tmp_ctx, "(objectSid=%s)",
+ sidbinstr)))
{
SAFE_FREE(sidbinstr);
DEBUG(1, ("ads: lookup_groupmem: talloc_asprintf for ldap_exp failed!\n"));
@@ -966,21 +1028,21 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
args.val = ADS_EXTENDED_DN_HEX_STRING;
args.critical = True;
- rc = ads_ranged_search(ads, tmp_ctx, LDAP_SCOPE_SUBTREE, ads->config.bind_path,
+ rc = ads_ranged_search(ads, tmp_ctx, LDAP_SCOPE_SUBTREE, ads->config.bind_path,
ldap_exp, &args, "member", &members, &num_members);
if (!ADS_ERR_OK(rc)) {
DEBUG(0,("ads_ranged_search failed with: %s\n", ads_errstr(rc)));
status = NT_STATUS_UNSUCCESSFUL;
goto done;
- }
-
+ }
+
DEBUG(10, ("ads lookup_groupmem: got %d sids via extended dn call\n", (int)num_members));
-
+
/* Now that we have a list of sids, we need to get the
* lists of names and name_types belonging to these sids.
- * even though conceptually not quite clean, we use the
- * RPC call lsa_lookup_sids for this since it can handle a
+ * even though conceptually not quite clean, we use the
+ * RPC call lsa_lookup_sids for this since it can handle a
* list of sids. ldap calls can just resolve one sid at a time.
*
* At this stage, the sids are still hidden in the exetended dn
@@ -988,7 +1050,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
* stated above: In extracting the sids from the member strings,
* we try to resolve as many sids as possible from the
* cache. Only the rest is passed to the lsa_lookup_sids call. */
-
+
if (num_members) {
(*sid_mem) = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, num_members);
(*names) = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_members);
@@ -1015,11 +1077,23 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
char *name, *domain_name;
DOM_SID sid;
- if (!ads_get_sid_from_extended_dn(tmp_ctx, members[i], args.val, &sid)) {
- status = NT_STATUS_INVALID_PARAMETER;
- goto done;
+ rc = ads_get_sid_from_extended_dn(tmp_ctx, members[i], args.val,
+ &sid);
+ if (!ADS_ERR_OK(rc)) {
+ if (NT_STATUS_EQUAL(ads_ntstatus(rc),
+ NT_STATUS_NOT_FOUND)) {
+ /* Group members can be objects, like Exchange
+ * Public Folders, that don't have a SID. Skip
+ * them. */
+ continue;
+ }
+ else {
+ status = ads_ntstatus(rc);
+ goto done;
+ }
}
- if (lookup_cached_sid(mem_ctx, &sid, &domain_name, &name, &name_type)) {
+ if (lookup_cached_sid(mem_ctx, &sid, &domain_name, &name,
+ &name_type)) {
DEBUG(10,("ads: lookup_groupmem: got sid %s from "
"cache\n", sid_string_dbg(&sid)));
sid_copy(&(*sid_mem)[*num_names], &sid);
@@ -1052,23 +1126,46 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
goto done;
}
- status = rpccli_lsa_lookup_sids(cli, tmp_ctx,
+ status = rpccli_lsa_lookup_sids(cli, tmp_ctx,
&lsa_policy,
- num_nocache,
- sid_mem_nocache,
- &domains_nocache,
- &names_nocache,
+ num_nocache,
+ sid_mem_nocache,
+ &domains_nocache,
+ &names_nocache,
&name_types_nocache);
+ if (!(NT_STATUS_IS_OK(status) ||
+ NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED) ||
+ NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)))
+ {
+ DEBUG(1, ("lsa_lookupsids call failed with %s "
+ "- retrying...\n", nt_errstr(status)));
+
+ status = cm_connect_lsa(domain, tmp_ctx, &cli,
+ &lsa_policy);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ status = rpccli_lsa_lookup_sids(cli, tmp_ctx,
+ &lsa_policy,
+ num_nocache,
+ sid_mem_nocache,
+ &domains_nocache,
+ &names_nocache,
+ &name_types_nocache);
+ }
+
if (NT_STATUS_IS_OK(status) ||
- NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED))
+ NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED))
{
- /* Copy the entries over from the "_nocache" arrays
- * to the result arrays, skipping the gaps the
+ /* Copy the entries over from the "_nocache" arrays
+ * to the result arrays, skipping the gaps the
* lookup_sids call left. */
for (i=0; i < num_nocache; i++) {
- if (((names_nocache)[i] != NULL) &&
- ((name_types_nocache)[i] != SID_NAME_UNKNOWN))
+ if (((names_nocache)[i] != NULL) &&
+ ((name_types_nocache)[i] != SID_NAME_UNKNOWN))
{
sid_copy(&(*sid_mem)[*num_names],
&sid_mem_nocache[i]);
@@ -1150,6 +1247,22 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
return ads_ntstatus(rc);
}
+/* find the lockout policy of a domain - use rpc methods */
+static NTSTATUS lockout_policy(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ struct samr_DomInfo12 *policy)
+{
+ return reconnect_methods.lockout_policy(domain, mem_ctx, policy);
+}
+
+/* find the password policy of a domain - use rpc methods */
+static NTSTATUS password_policy(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ struct samr_DomInfo1 *policy)
+{
+ return reconnect_methods.password_policy(domain, mem_ctx, policy);
+}
+
/* get a list of trusted domains */
static NTSTATUS trusted_domains(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
@@ -1340,16 +1453,16 @@ struct winbindd_methods ads_methods = {
query_user_list,
enum_dom_groups,
enum_local_groups,
- msrpc_name_to_sid,
- msrpc_sid_to_name,
- msrpc_rids_to_names,
+ name_to_sid,
+ sid_to_name,
+ rids_to_names,
query_user,
lookup_usergroups,
- msrpc_lookup_useraliases,
+ lookup_useraliases,
lookup_groupmem,
sequence_number,
- msrpc_lockout_policy,
- msrpc_password_policy,
+ lockout_policy,
+ password_policy,
trusted_domains,
};
diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c
index 360e915bc4..2f4a6ffe56 100644
--- a/source3/winbindd/winbindd_cache.c
+++ b/source3/winbindd/winbindd_cache.c
@@ -4222,7 +4222,14 @@ do_query:
nt_status = nss_get_info( domain->name, user_sid, ctx, ads, msg,
homedir, shell, gecos, p_gid );
+ DEBUG(10, ("nss_get_info returned %s\n", nt_errstr(nt_status)));
+
if ( NT_STATUS_IS_OK(nt_status) ) {
+ DEBUG(10, ("result:\n\thomedir = '%s'\n", *homedir));
+ DEBUGADD(10, ("\tshell = '%s'\n", *shell));
+ DEBUGADD(10, ("\tgecos = '%s'\n", *gecos));
+ DEBUGADD(10, ("\tgid = '%u'\n", *p_gid));
+
wcache_save_user_pwinfo( domain, nt_status, user_sid,
*homedir, *shell, *gecos, *p_gid );
}
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
index 03d1e043bf..9153585c26 100644
--- a/source3/winbindd/winbindd_dual.c
+++ b/source3/winbindd/winbindd_dual.c
@@ -1279,6 +1279,7 @@ static bool fork_domain_child(struct winbindd_child *child)
}
if (child->domain && child->domain->primary &&
+ !lp_use_kerberos_keytab() &&
lp_server_role() == ROLE_DOMAIN_MEMBER) {
struct timeval next_change;
diff --git a/source3/winbindd/winbindd_group.c b/source3/winbindd/winbindd_group.c
index 8e56138bb5..3422fdba1c 100644
--- a/source3/winbindd/winbindd_group.c
+++ b/source3/winbindd/winbindd_group.c
@@ -585,7 +585,7 @@ static bool fill_grent_mem(struct winbindd_domain *domain,
}
/* Real work goes here. Create a list of group names to
- expand startign with the initial one. Pass that to
+ expand starting with the initial one. Pass that to
expand_groups() which returns a list of more group names
to expand. Do this up to the max search depth. */
@@ -922,7 +922,7 @@ static void getgrsid_lookupsid_recv( void *private_data, bool success,
nt_status = normalize_name_unmap(s->state->mem_ctx, raw_name,
&mapped_name);
- /* basiuc whitespace reversal */
+ /* basic whitespace reversal */
if (NT_STATUS_IS_OK(nt_status)) {
s->group_name = talloc_asprintf(s->state->mem_ctx,
"%s%c%s",
diff --git a/source3/winbindd/winbindd_idmap.c b/source3/winbindd/winbindd_idmap.c
index d8c67dc21c..94a8c78a85 100644
--- a/source3/winbindd/winbindd_idmap.c
+++ b/source3/winbindd/winbindd_idmap.c
@@ -111,6 +111,65 @@ enum winbindd_result winbindd_dual_set_mapping(struct winbindd_domain *domain,
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
}
+static void winbindd_remove_mapping_recv(TALLOC_CTX *mem_ctx, bool success,
+ struct winbindd_response *response,
+ void *c, void *private_data)
+{
+ void (*cont)(void *priv, bool succ) = (void (*)(void *, bool))c;
+
+ if (!success) {
+ DEBUG(5, ("Could not trigger idmap_remove_mapping\n"));
+ cont(private_data, False);
+ return;
+ }
+
+ if (response->result != WINBINDD_OK) {
+ DEBUG(5, ("idmap_remove_mapping returned an error\n"));
+ cont(private_data, False);
+ return;
+ }
+
+ cont(private_data, True);
+}
+
+void winbindd_remove_mapping_async(TALLOC_CTX *mem_ctx,
+ const struct id_map *map,
+ void (*cont)(void *private_data, bool success),
+ void *private_data)
+{
+ struct winbindd_request request;
+ ZERO_STRUCT(request);
+ request.cmd = WINBINDD_DUAL_REMOVE_MAPPING;
+ request.data.dual_idmapset.id = map->xid.id;
+ request.data.dual_idmapset.type = map->xid.type;
+ sid_to_fstring(request.data.dual_idmapset.sid, map->sid);
+
+ do_async(mem_ctx, idmap_child(), &request, winbindd_remove_mapping_recv,
+ (void *)cont, private_data);
+}
+
+enum winbindd_result winbindd_dual_remove_mapping(
+ struct winbindd_domain *domain,
+ struct winbindd_cli_state *state)
+{
+ struct id_map map;
+ DOM_SID sid;
+ NTSTATUS result;
+
+ DEBUG(3, ("[%5lu]: dual_idmapremove\n", (unsigned long)state->pid));
+
+ if (!string_to_sid(&sid, state->request.data.dual_idmapset.sid))
+ return WINBINDD_ERROR;
+
+ map.sid = &sid;
+ map.xid.id = state->request.data.dual_idmapset.id;
+ map.xid.type = state->request.data.dual_idmapset.type;
+ map.status = ID_MAPPED;
+
+ result = idmap_remove_mapping(&map);
+ return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
+}
+
static void winbindd_set_hwm_recv(TALLOC_CTX *mem_ctx, bool success,
struct winbindd_response *response,
void *c, void *private_data)
@@ -486,6 +545,10 @@ static const struct winbindd_child_dispatch_table idmap_dispatch_table[] = {
.struct_cmd = WINBINDD_DUAL_SET_MAPPING,
.struct_fn = winbindd_dual_set_mapping,
},{
+ .name = "DUAL_REMOVE_MAPPING",
+ .struct_cmd = WINBINDD_DUAL_REMOVE_MAPPING,
+ .struct_fn = winbindd_dual_remove_mapping,
+ },{
.name = "DUAL_SET_HWMS",
.struct_cmd = WINBINDD_DUAL_SET_HWM,
.struct_fn = winbindd_dual_set_hwm,
diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index 9ff3899661..597d48aad0 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -1854,17 +1854,28 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
if (state->request.data.auth_crap.lm_resp_len > sizeof(state->request.data.auth_crap.lm_resp)
|| state->request.data.auth_crap.nt_resp_len > sizeof(state->request.data.auth_crap.nt_resp)) {
- DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n",
- state->request.data.auth_crap.lm_resp_len,
- state->request.data.auth_crap.nt_resp_len));
- result = NT_STATUS_INVALID_PARAMETER;
- goto done;
+ if (!state->request.flags & WBFLAG_BIG_NTLMV2_BLOB ||
+ state->request.extra_len != state->request.data.auth_crap.nt_resp_len) {
+ DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n",
+ state->request.data.auth_crap.lm_resp_len,
+ state->request.data.auth_crap.nt_resp_len));
+ result = NT_STATUS_INVALID_PARAMETER;
+ goto done;
+ }
}
lm_resp = data_blob_talloc(state->mem_ctx, state->request.data.auth_crap.lm_resp,
state->request.data.auth_crap.lm_resp_len);
- nt_resp = data_blob_talloc(state->mem_ctx, state->request.data.auth_crap.nt_resp,
- state->request.data.auth_crap.nt_resp_len);
+
+ if (state->request.flags & WBFLAG_BIG_NTLMV2_BLOB) {
+ nt_resp = data_blob_talloc(state->mem_ctx,
+ state->request.extra_data.data,
+ state->request.data.auth_crap.nt_resp_len);
+ } else {
+ nt_resp = data_blob_talloc(state->mem_ctx,
+ state->request.data.auth_crap.nt_resp,
+ state->request.data.auth_crap.nt_resp_len);
+ }
/* what domain should we contact? */
@@ -2106,9 +2117,15 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact
got_info = true;
}
+ /* atm the pidl generated rpccli_samr_ChangePasswordUser3 function will
+ * return with NT_STATUS_BUFFER_TOO_SMALL for w2k dcs as w2k just
+ * returns with 4byte error code (NT_STATUS_NOT_SUPPORTED) which is too
+ * short to comply with the samr_ChangePasswordUser3 idl - gd */
+
/* only fallback when the chgpasswd_user3 call is not supported */
if ((NT_STATUS_EQUAL(result, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR))) ||
(NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED)) ||
+ (NT_STATUS_EQUAL(result, NT_STATUS_BUFFER_TOO_SMALL)) ||
(NT_STATUS_EQUAL(result, NT_STATUS_NOT_IMPLEMENTED))) {
DEBUG(10,("Password change with chgpasswd_user3 failed with: %s, retrying chgpasswd_user2\n",
diff --git a/source3/winbindd/winbindd_passdb.c b/source3/winbindd/winbindd_passdb.c
index 5677c01be1..101854ae94 100644
--- a/source3/winbindd/winbindd_passdb.c
+++ b/source3/winbindd/winbindd_passdb.c
@@ -267,6 +267,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
}
if ( !pdb_getsampwsid( user, user_sid ) ) {
+ TALLOC_FREE( user );
return NT_STATUS_NO_SUCH_USER;
}
@@ -638,13 +639,13 @@ static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
sid_type_lookup(lsa_names[i].type)));
continue;
}
- if (!((*names)[i] = talloc_strdup((*names),
+ if (!((*names)[num_mapped] = talloc_strdup((*names),
lsa_names[i].name))) {
TALLOC_FREE(tmp_ctx);
return NT_STATUS_NO_MEMORY;
}
- (*name_types)[i] = lsa_names[i].type;
+ (*name_types)[num_mapped] = lsa_names[i].type;
num_mapped += 1;
}
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index 65ad47dd03..9de385e3b3 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -353,6 +353,11 @@ void winbindd_set_mapping_async(TALLOC_CTX *mem_ctx, const struct id_map *map,
void *private_data);
enum winbindd_result winbindd_dual_set_mapping(struct winbindd_domain *domain,
struct winbindd_cli_state *state);
+void winbindd_remove_mapping_async(TALLOC_CTX *mem_ctx, const struct id_map *map,
+ void (*cont)(void *private_data, bool success),
+ void *private_data);
+enum winbindd_result winbindd_dual_remove_mapping(struct winbindd_domain *domain,
+ struct winbindd_cli_state *state);
void winbindd_set_hwm_async(TALLOC_CTX *mem_ctx, const struct unixid *xid,
void (*cont)(void *private_data, bool success),
void *private_data);
@@ -462,40 +467,6 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai
/* The following definitions come from winbindd/winbindd_reconnect.c */
-/* The following definitions come from winbindd/winbindd_rpc.c */
-
-NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- enum winbindd_cmd original_cmd,
- const char *domain_name,
- const char *name,
- DOM_SID *sid,
- enum lsa_SidType *type);
-NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
- char **domain_name,
- char **name,
- enum lsa_SidType *type);
-NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
- uint32 *rids,
- size_t num_rids,
- char **domain_name,
- char ***names,
- enum lsa_SidType **types);
-NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 num_sids, const DOM_SID *sids,
- uint32 *num_aliases, uint32 **alias_rids);
-NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- struct samr_DomInfo12 *lockout_policy);
-NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- struct samr_DomInfo1 *password_policy);
-
/* The following definitions come from winbindd/winbindd_sid.c */
void winbindd_lookupsid(struct winbindd_cli_state *state);
@@ -505,6 +476,7 @@ void winbindd_sid_to_uid(struct winbindd_cli_state *state);
void winbindd_sid_to_gid(struct winbindd_cli_state *state);
void winbindd_sids_to_unixids(struct winbindd_cli_state *state);
void winbindd_set_mapping(struct winbindd_cli_state *state);
+void winbindd_remove_mapping(struct winbindd_cli_state *state);
void winbindd_set_hwm(struct winbindd_cli_state *state);
void winbindd_uid_to_sid(struct winbindd_cli_state *state);
void winbindd_gid_to_sid(struct winbindd_cli_state *state);
diff --git a/source3/winbindd/winbindd_rpc.c b/source3/winbindd/winbindd_rpc.c
index d966e50159..0070bde2cc 100644
--- a/source3/winbindd/winbindd_rpc.c
+++ b/source3/winbindd/winbindd_rpc.c
@@ -265,13 +265,13 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
}
/* convert a single name to a sid in a domain */
-NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- enum winbindd_cmd original_cmd,
- const char *domain_name,
- const char *name,
- DOM_SID *sid,
- enum lsa_SidType *type)
+static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ enum winbindd_cmd original_cmd,
+ const char *domain_name,
+ const char *name,
+ DOM_SID *sid,
+ enum lsa_SidType *type)
{
NTSTATUS result;
DOM_SID *sids = NULL;
@@ -331,12 +331,12 @@ NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
/*
convert a domain SID to a user or group name
*/
-NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
- char **domain_name,
- char **name,
- enum lsa_SidType *type)
+static NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *sid,
+ char **domain_name,
+ char **name,
+ enum lsa_SidType *type)
{
char **domains;
char **names;
@@ -384,14 +384,14 @@ NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
return NT_STATUS_OK;
}
-NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
- uint32 *rids,
- size_t num_rids,
- char **domain_name,
- char ***names,
- enum lsa_SidType **types)
+static NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *sid,
+ uint32 *rids,
+ size_t num_rids,
+ char **domain_name,
+ char ***names,
+ enum lsa_SidType **types)
{
char **domains;
NTSTATUS result;
@@ -636,10 +636,13 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
return NT_STATUS_OK;
}
-NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 num_sids, const DOM_SID *sids,
- uint32 *num_aliases, uint32 **alias_rids)
+#define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
+
+static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ uint32 num_sids, const DOM_SID *sids,
+ uint32 *num_aliases,
+ uint32 **alias_rids)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
POLICY_HND dom_pol;
@@ -1102,9 +1105,9 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
}
/* find the lockout policy for a domain */
-NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- struct samr_DomInfo12 *lockout_policy)
+static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ struct samr_DomInfo12 *lockout_policy)
{
NTSTATUS result;
struct rpc_pipe_client *cli;
@@ -1143,9 +1146,9 @@ NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
}
/* find the password policy for a domain */
-NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- struct samr_DomInfo1 *password_policy)
+static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ struct samr_DomInfo1 *password_policy)
{
NTSTATUS result;
struct rpc_pipe_client *cli;
diff --git a/source3/winbindd/winbindd_sid.c b/source3/winbindd/winbindd_sid.c
index 274786fa63..641b18ebbd 100644
--- a/source3/winbindd/winbindd_sid.c
+++ b/source3/winbindd/winbindd_sid.c
@@ -370,7 +370,8 @@ void winbindd_sid_to_gid(struct winbindd_cli_state *state)
range from random SIDs. */
backend:
- winbindd_lookupsid_async( state->mem_ctx, &sid, sid2gid_lookupsid_recv, state );
+ winbindd_lookupsid_async( state->mem_ctx, &sid, sid2gid_lookupsid_recv,
+ state );
}
static void set_mapping_recv(void *private_data, bool success)
@@ -415,6 +416,48 @@ void winbindd_set_mapping(struct winbindd_cli_state *state)
set_mapping_recv, state);
}
+static void remove_mapping_recv(void *private_data, bool success)
+{
+ struct winbindd_cli_state *state =
+ talloc_get_type_abort(private_data, struct winbindd_cli_state);
+
+ if (!success) {
+ DEBUG(5, ("Could not remove sid mapping\n"));
+ request_error(state);
+ return;
+ }
+
+ request_ok(state);
+}
+
+void winbindd_remove_mapping(struct winbindd_cli_state *state)
+{
+ struct id_map map;
+ DOM_SID sid;
+
+ DEBUG(3, ("[%5lu]: remove id map\n", (unsigned long)state->pid));
+
+ if ( ! state->privileged) {
+ DEBUG(0, ("Only root is allowed to remove mappings!\n"));
+ request_error(state);
+ return;
+ }
+
+ if (!string_to_sid(&sid, state->request.data.dual_idmapset.sid)) {
+ DEBUG(1, ("Could not get convert sid %s from string\n",
+ state->request.data.sid));
+ request_error(state);
+ return;
+ }
+
+ map.sid = &sid;
+ map.xid.id = state->request.data.dual_idmapset.id;
+ map.xid.type = state->request.data.dual_idmapset.type;
+
+ winbindd_remove_mapping_async(state->mem_ctx, &map,
+ remove_mapping_recv, state);
+}
+
static void set_hwm_recv(void *private_data, bool success)
{
struct winbindd_cli_state *state =
diff --git a/source4/Makefile b/source4/Makefile
index be41d02a38..38eb0706c9 100644
--- a/source4/Makefile
+++ b/source4/Makefile
@@ -11,7 +11,7 @@ include mkconfig.mk
pidldir := $(srcdir)/../pidl
basedir = $(prefix)
-torturedir = $(libdir)/torture
+torturedir = ../lib/torture
swatdir = $(datadir)/swat
setupdir = $(datadir)/setup
ncalrpcdir = $(localstatedir)/ncalrpc
@@ -78,7 +78,7 @@ libutilsrcdir := ../lib/util
libtdrsrcdir := lib/tdr
libdbwrapsrcdir := lib/dbwrap
libcryptosrcdir := ../lib/crypto
-libtorturesrcdir := lib/torture
+libtorturesrcdir := ../lib/torture
smb_serversrcdir := smb_server
libcompressionsrcdir := ../lib/compression
libgencachesrcdir := lib
diff --git a/source4/auth/config.m4 b/source4/auth/config.m4
index 1338b775ec..a271a9f6fe 100644
--- a/source4/auth/config.m4
+++ b/source4/auth/config.m4
@@ -20,11 +20,15 @@ AC_CHECK_FUNCS(crypt16 getauthuid getpwanam)
AC_CHECK_HEADERS(sasl/sasl.h)
AC_CHECK_LIB_EXT(sasl2, SASL_LIBS, sasl_client_init)
-SMB_EXT_LIB(SASL, $SASL_LIBS)
if test x"$ac_cv_header_sasl_sasl_h" = x"yes" -a x"$ac_cv_lib_ext_sasl2_sasl_client_init" = x"yes";then
SMB_ENABLE(SASL,YES)
SMB_ENABLE(cyrus_sasl,YES)
+ SASL_CFLAGS="$CFLAGS"
+ SASL_CPPFLAGS="$CPPFLAGS"
+ SASL_LDFLAGS="$LDFLAGS"
else
SMB_ENABLE(cyrus_sasl,NO)
fi
+
+SMB_EXT_LIB(SASL, $SASL_LIBS, [${SASL_CFLAGS}], [${SASL_CPPFLAGS}], [${SASL_LDFLAGS}])
diff --git a/source4/build/m4/check_python.m4 b/source4/build/m4/check_python.m4
index 96f93a3d75..7e56af76f7 100644
--- a/source4/build/m4/check_python.m4
+++ b/source4/build/m4/check_python.m4
@@ -71,8 +71,19 @@ AC_DEFUN([AC_SAMBA_PYTHON_DEVEL],
if test x$PYTHON != x
then
- DISTUTILS_CFLAGS=`$PYTHON -c "from distutils import sysconfig; print '-I%s -I%s %s' % (sysconfig.get_python_inc(), sysconfig.get_python_inc(plat_specific=1), sysconfig.get_config_var('CFLAGS'))"`
- DISTUTILS_LDFLAGS=`$PYTHON -c "from distutils import sysconfig; print '%s %s -lpython%s -L%s' % (sysconfig.get_config_var('LIBS'), sysconfig.get_config_var('SYSLIBS'), sysconfig.get_config_var('VERSION'), sysconfig.get_config_var('LIBPL'))"`
+ DISTUTILS_CFLAGS=`$PYTHON -c "from distutils import sysconfig; \
+ print '-I%s -I%s %s' % ( \
+ sysconfig.get_python_inc(), \
+ sysconfig.get_python_inc(plat_specific=1), \
+ sysconfig.get_config_var('CFLAGS'))"`
+ DISTUTILS_LDFLAGS=`$PYTHON -c "from distutils import sysconfig; \
+ print '%s %s -lpython%s -L%s %s -L%s' % ( \
+ sysconfig.get_config_var('LIBS'), \
+ sysconfig.get_config_var('SYSLIBS'), \
+ sysconfig.get_config_var('VERSION'), \
+ sysconfig.get_config_var('LIBDIR'), \
+ sysconfig.get_config_var('LDFLAGS'), \
+ sysconfig.get_config_var('LIBPL'))"`
TRY_LINK_PYTHON($DISTUTILS_LDFLAGS, $DISTUTILS_CFLAGS)
fi
diff --git a/source4/build/m4/public.m4 b/source4/build/m4/public.m4
index d61e00b22e..5be4189e06 100644
--- a/source4/build/m4/public.m4
+++ b/source4/build/m4/public.m4
@@ -188,10 +188,17 @@ use strict;
use vars qw(%enabled %config);
-%config = (AC_FOREACH([AC_Var], m4_defn([_AC_SUBST_VARS]), [
- AC_Var => '$AC_Var',])
-);
+%config = (
+CEOF
+
+for ac_var in $ac_subst_vars
+do
+ eval ac_val=\$$ac_var
+ echo "$ac_var => '$ac_val'," >> $1
+done
+cat >>$1<<CEOF
+);
$SMB_INFO_ENABLES
1;
CEOF
diff --git a/source4/build/make/python.mk b/source4/build/make/python.mk
index e307ba74bb..67a3e86215 100644
--- a/source4/build/make/python.mk
+++ b/source4/build/make/python.mk
@@ -46,7 +46,7 @@ swig:: pythonmods
.SUFFIXES: _wrap.c .i .py
%_wrap.c %.py: %.i
- [ "$(SWIG)" == "no" ] || $(SWIG) -O -Wall -python -keyword -I../source4 $<
+ [ "$(SWIG)" = "no" ] || $(SWIG) -O -Wall -python -keyword -I../source4 $<
realdistclean::
@echo "Removing SWIG output files"
diff --git a/source4/configure.ac b/source4/configure.ac
index cf85b13225..a90ac9e668 100644
--- a/source4/configure.ac
+++ b/source4/configure.ac
@@ -37,7 +37,7 @@ AC_CONFIG_FILES(lib/registry/registry.pc)
AC_CONFIG_FILES(lib/events/events.pc)
AC_CONFIG_FILES(librpc/dcerpc.pc)
AC_CONFIG_FILES(../librpc/ndr.pc)
-AC_CONFIG_FILES(lib/torture/torture.pc)
+AC_CONFIG_FILES(../lib/torture/torture.pc)
AC_CONFIG_FILES(auth/gensec/gensec.pc)
AC_CONFIG_FILES(param/samba-hostconfig.pc)
AC_CONFIG_FILES(librpc/dcerpc_samr.pc)
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 69e456274c..2161286e08 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -657,6 +657,28 @@ uint32_t samdb_result_acct_flags(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ct
return acct_flags;
}
+struct lsa_BinaryString samdb_result_parameters(TALLOC_CTX *mem_ctx,
+ struct ldb_message *msg,
+ const char *attr)
+{
+ struct lsa_BinaryString s;
+ const struct ldb_val *val = ldb_msg_find_ldb_val(msg, attr);
+
+ ZERO_STRUCT(s);
+
+ if (!val) {
+ return s;
+ }
+
+ s.array = talloc_array(mem_ctx, uint16_t, val->length/2);
+ if (!s.array) {
+ return s;
+ }
+ s.length = s.size = val->length/2;
+ memcpy(s.array, val->data, val->length);
+
+ return s;
+}
/* Find an attribute, with a particular value */
@@ -897,6 +919,17 @@ int samdb_msg_add_logon_hours(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx,
}
/*
+ add a parameters element to a message
+*/
+int samdb_msg_add_parameters(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
+ const char *attr_name, struct lsa_BinaryString *parameters)
+{
+ struct ldb_val val;
+ val.length = parameters->length * 2;
+ val.data = (uint8_t *)parameters->array;
+ return ldb_msg_add_value(msg, attr_name, &val, NULL);
+}
+/*
add a general value element to a message
*/
int samdb_msg_add_value(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
diff --git a/source4/dsdb/config.mk b/source4/dsdb/config.mk
index 8bc8b6e000..bd188192a0 100644
--- a/source4/dsdb/config.mk
+++ b/source4/dsdb/config.mk
@@ -6,7 +6,7 @@ mkinclude samdb/ldb_modules/config.mk
# Start SUBSYSTEM SAMDB
[SUBSYSTEM::SAMDB]
PUBLIC_DEPENDENCIES = HEIMDAL_KRB5
-PRIVATE_DEPENDENCIES = LIBNDR NDR_MISC NDR_DRSUAPI NDR_DRSBLOBS NSS_WRAPPER \
+PRIVATE_DEPENDENCIES = LIBNDR NDR_DRSUAPI NDR_DRSBLOBS NSS_WRAPPER \
auth_system_session LDAP_ENCODE LIBCLI_AUTH LIBNDR \
SAMDB_SCHEMA LDB_WRAP SAMDB_COMMON
diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk
index 00e4f1af92..1387066256 100644
--- a/source4/dsdb/samdb/ldb_modules/config.mk
+++ b/source4/dsdb/samdb/ldb_modules/config.mk
@@ -2,7 +2,7 @@
# Start MODULE ldb_objectguid
[MODULE::ldb_objectguid]
SUBSYSTEM = LIBLDB
-PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBNDR NDR_MISC
+PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBNDR
INIT_FUNCTION = LDB_MODULE(objectguid)
# End MODULE ldb_objectguid
################################################
@@ -14,7 +14,7 @@ ldb_objectguid_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/objectguid.o
[MODULE::ldb_repl_meta_data]
SUBSYSTEM = LIBLDB
PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS \
- LIBNDR NDR_MISC NDR_DRSUAPI \
+ LIBNDR NDR_DRSUAPI \
NDR_DRSBLOBS LIBNDR
INIT_FUNCTION = LDB_MODULE(repl_meta_data)
# End MODULE ldb_repl_meta_data
@@ -75,7 +75,7 @@ ldb_pdc_fsmo_OBJ_FILES = \
# Start MODULE ldb_samldb
[MODULE::ldb_samldb]
SUBSYSTEM = LIBLDB
-PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LDAP_ENCODE NDR_MISC SAMDB
+PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LDAP_ENCODE SAMDB
INIT_FUNCTION = LDB_MODULE(samldb)
#
# End MODULE ldb_samldb
@@ -102,7 +102,7 @@ ldb_samba3sam_OBJ_FILES = \
[MODULE::ldb_simple_ldap_map]
SUBSYSTEM = LIBLDB
INIT_FUNCTION = LDB_MODULE(entryuuid),LDB_MODULE(nsuniqueid)
-PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBNDR NDR_MISC
+PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBNDR
ENABLE = YES
ALIASES = entryuuid nsuniqueid
# End MODULE ldb_entryuuid
diff --git a/source4/dsdb/samdb/ldb_modules/linked_attributes.c b/source4/dsdb/samdb/ldb_modules/linked_attributes.c
index dd199c0137..f16eb215a6 100644
--- a/source4/dsdb/samdb/ldb_modules/linked_attributes.c
+++ b/source4/dsdb/samdb/ldb_modules/linked_attributes.c
@@ -249,10 +249,14 @@ static int linked_attributes_add(struct ldb_module *module, struct ldb_request *
return ldb_next_request(module, req);
}
- /* start with the first one */
- return la_do_mod_request(ac);
+ /* start with the original request */
+ return la_down_req(ac);
}
+/* For a delete or rename, we need to find out what linked attributes
+ * are currently on this DN, and then deal with them. This is the
+ * callback to the base search */
+
static int la_mod_search_callback(struct ldb_request *req, struct ldb_reply *ares)
{
const struct dsdb_attribute *schema_attr;
@@ -349,8 +353,8 @@ static int la_mod_search_callback(struct ldb_request *req, struct ldb_reply *are
talloc_free(ares);
- /* All mods set up, start with the first one */
- ret = la_do_mod_request(ac);
+ /* Start with the original request */
+ ret = la_down_req(ac);
if (ret != LDB_SUCCESS) {
return ldb_module_done(ac->req, NULL, NULL, ret);
}
@@ -539,8 +543,8 @@ static int linked_attributes_modify(struct ldb_module *module, struct ldb_reques
} else {
if (ac->ops) {
- /* Jump directly to handling the modifies */
- ret = la_do_mod_request(ac);
+ /* Start with the original request */
+ ret = la_down_req(ac);
} else {
/* nothing to do for this module, proceed */
talloc_free(ac);
@@ -732,12 +736,8 @@ static int la_op_search_callback(struct ldb_request *req,
talloc_free(ares);
- if (ac->ops) {
- /* start the mod requests chain */
- ret = la_do_mod_request(ac);
- } else {
- ret = la_down_req(ac);
- }
+ /* start the mod requests chain */
+ ret = la_down_req(ac);
if (ret != LDB_SUCCESS) {
return ldb_module_done(ac->req, NULL, NULL, ret);
}
@@ -840,11 +840,13 @@ static int la_mod_callback(struct ldb_request *req, struct ldb_reply *ares)
talloc_free(os);
}
- /* as last op run the original request */
+ /* If we still have modifies in the queue, then run them */
if (ac->ops) {
ret = la_do_mod_request(ac);
} else {
- ret = la_down_req(ac);
+ /* Otherwise, we are done! */
+ ret = ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
}
if (ret != LDB_SUCCESS) {
@@ -898,6 +900,7 @@ static int la_down_req(struct la_context *ac)
return ldb_next_request(ac->module, down_req);
}
+/* Having done the original operation, then try to fix up all the linked attributes */
static int la_down_callback(struct ldb_request *req, struct ldb_reply *ares)
{
struct la_context *ac;
@@ -920,9 +923,13 @@ static int la_down_callback(struct ldb_request *req, struct ldb_reply *ares)
return ldb_module_done(ac->req, NULL, NULL,
LDB_ERR_OPERATIONS_ERROR);
}
-
- return ldb_module_done(ac->req, ares->controls,
- ares->response, ares->error);
+ /* If we have modfies to make, then run them */
+ if (ac->ops) {
+ return la_do_mod_request(ac);
+ } else {
+ return ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
+ }
}
_PUBLIC_ const struct ldb_module_ops ldb_linked_attributes_module_ops = {
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c
index 7d00851792..1d240a33fe 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass.c
@@ -414,10 +414,10 @@ static int objectclass_add(struct ldb_module *module, struct ldb_request *req)
return ldb_next_request(module, req);
}
- /* Need to object to this, but cn=rootdse doesn't have an objectClass... */
+ /* the objectClass must be specified on add */
if (ldb_msg_find_element(req->op.add.message,
"objectClass") == NULL) {
- return ldb_next_request(module, req);
+ return LDB_ERR_OBJECT_CLASS_VIOLATION;
}
ac = oc_init_context(module, req);
diff --git a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c
index 0266654811..df409a8ae3 100644
--- a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c
+++ b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c
@@ -38,6 +38,10 @@ static int generate_attributeTypes(struct ldb_context *ldb, struct ldb_message *
const struct dsdb_schema *schema);
static int generate_dITContentRules(struct ldb_context *ldb, struct ldb_message *msg,
const struct dsdb_schema *schema);
+static int generate_extendedAttributeInfo(struct ldb_context *ldb, struct ldb_message *msg,
+ const struct dsdb_schema *schema);
+static int generate_extendedClassInfo(struct ldb_context *ldb, struct ldb_message *msg,
+ const struct dsdb_schema *schema);
static const struct {
const char *attr;
@@ -54,6 +58,14 @@ static const struct {
{
.attr = "dITContentRules",
.fn = generate_dITContentRules
+ },
+ {
+ .attr = "extendedAttributeInfo",
+ .fn = generate_extendedAttributeInfo
+ },
+ {
+ .attr = "extendedClassInfo",
+ .fn = generate_extendedClassInfo
}
};
@@ -322,7 +334,51 @@ static int generate_dITContentRules(struct ldb_context *ldb, struct ldb_message
return LDB_SUCCESS;
}
+static int generate_extendedAttributeInfo(struct ldb_context *ldb,
+ struct ldb_message *msg,
+ const struct dsdb_schema *schema)
+{
+ const struct dsdb_attribute *attribute;
+ int ret;
+
+ for (attribute = schema->attributes; attribute; attribute = attribute->next) {
+ char *val = schema_attribute_to_extendedInfo(msg, attribute);
+ if (!val) {
+ ldb_oom(ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret = ldb_msg_add_string(msg, "extendedAttributeInfo", val);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+
+ return LDB_SUCCESS;
+}
+
+static int generate_extendedClassInfo(struct ldb_context *ldb,
+ struct ldb_message *msg,
+ const struct dsdb_schema *schema)
+{
+ const struct dsdb_class *sclass;
+ int ret;
+
+ for (sclass = schema->classes; sclass; sclass = sclass->next) {
+ char *val = schema_class_to_extendedInfo(msg, sclass);
+ if (!val) {
+ ldb_oom(ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ ret = ldb_msg_add_string(msg, "extendedClassInfo", val);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+
+ return LDB_SUCCESS;
+}
/* Add objectClasses, attributeTypes and dITContentRules from the
schema object (they are not stored in the database)
diff --git a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py
index 1fc531902d..fa1af2ad61 100644
--- a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py
+++ b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py
@@ -27,7 +27,7 @@ import ldb
from ldb import SCOPE_DEFAULT, SCOPE_BASE, SCOPE_SUBTREE
from samba import Ldb, substitute_var
from samba.tests import LdbTestCase, TestCaseInTempDir, cmdline_loadparm
-import samba.dcerpc.security
+import samba.dcerpc.dom_sid
import samba.security
import samba.ndr
@@ -50,7 +50,7 @@ class MapBaseTestCase(TestCaseInTempDir):
"@TO": "sambaDomainName=TESTS," + s3.basedn})
ldb.add({"dn": "@MODULES",
- "@LIST": "rootdse,paged_results,server_sort,extended_dn,asq,samldb,password_hash,operational,objectguid,rdn_name,samba3sam,partition"})
+ "@LIST": "rootdse,paged_results,server_sort,asq,samldb,password_hash,operational,objectguid,rdn_name,samba3sam,partition"})
ldb.add({"dn": "@PARTITION",
"partition": ["%s:%s" % (s4.basedn, s4.url),
@@ -116,7 +116,7 @@ class MapBaseTestCase(TestCaseInTempDir):
super(MapBaseTestCase, self).tearDown()
def assertSidEquals(self, text, ndr_sid):
- sid_obj1 = samba.ndr.ndr_unpack(samba.dcerpc.security.dom_sid,
+ sid_obj1 = samba.ndr.ndr_unpack(samba.dcerpc.dom_sid.dom_sid,
str(ndr_sid[0]))
sid_obj2 = samba.security.Sid(text)
# For now, this is the only way we can compare these since the
diff --git a/source4/dsdb/schema/schema.h b/source4/dsdb/schema/schema.h
index 68dc8197cb..e8fefb5246 100644
--- a/source4/dsdb/schema/schema.h
+++ b/source4/dsdb/schema/schema.h
@@ -72,8 +72,8 @@ struct dsdb_attribute {
struct ldb_val oMObjectClass;
bool isSingleValued;
- uint32_t rangeLower;
- uint32_t rangeUpper;
+ uint32_t *rangeLower;
+ uint32_t *rangeUpper;
bool extendedCharsAllowed;
uint32_t schemaFlagsEx;
diff --git a/source4/dsdb/schema/schema_description.c b/source4/dsdb/schema/schema_description.c
index c3c37b4653..9443c04bb0 100644
--- a/source4/dsdb/schema/schema_description.c
+++ b/source4/dsdb/schema/schema_description.c
@@ -20,6 +20,7 @@
*/
#include "includes.h"
#include "dsdb/samdb/samdb.h"
+#include "librpc/ndr/libndr.h"
#define IF_NULL_FAIL_RET(x) do { \
if (!x) { \
@@ -36,7 +37,12 @@ char *schema_attribute_description(TALLOC_CTX *mem_ctx,
const char *equality,
const char *substring,
const char *syntax,
- bool single_value, bool operational)
+ bool single_value, bool operational,
+ uint32_t *range_lower,
+ uint32_t *range_upper,
+ const char *property_guid,
+ const char *property_set_guid,
+ bool indexed, bool system_only)
{
char *schema_entry = talloc_asprintf(mem_ctx,
"(%s%s%s", seperator, oid, seperator);
@@ -55,11 +61,13 @@ char *schema_attribute_description(TALLOC_CTX *mem_ctx,
"SUBSTR %s%s", substring, seperator);
IF_NULL_FAIL_RET(schema_entry);
}
-
- schema_entry = talloc_asprintf_append(schema_entry,
- "SYNTAX %s%s", syntax, seperator);
- IF_NULL_FAIL_RET(schema_entry);
-
+
+ if (syntax) {
+ schema_entry = talloc_asprintf_append(schema_entry,
+ "SYNTAX %s%s", syntax, seperator);
+ IF_NULL_FAIL_RET(schema_entry);
+ }
+
if (single_value) {
schema_entry = talloc_asprintf_append(schema_entry,
"SINGLE-VALUE%s", seperator);
@@ -71,7 +79,47 @@ char *schema_attribute_description(TALLOC_CTX *mem_ctx,
"NO-USER-MODIFICATION%s", seperator);
IF_NULL_FAIL_RET(schema_entry);
}
-
+
+ if (range_lower) {
+ schema_entry = talloc_asprintf_append(schema_entry,
+ "RANGE-LOWER '%u'%s",
+ *range_lower, seperator);
+ IF_NULL_FAIL_RET(schema_entry);
+ }
+
+ if (range_upper) {
+ schema_entry = talloc_asprintf_append(schema_entry,
+ "RANGE-UPPER '%u'%s",
+ *range_upper, seperator);
+ IF_NULL_FAIL_RET(schema_entry);
+ }
+
+ if (property_guid) {
+ schema_entry = talloc_asprintf_append(schema_entry,
+ "PROPERTY-GUID '%s'%s",
+ property_guid, seperator);
+ IF_NULL_FAIL_RET(schema_entry);
+ }
+
+ if (property_set_guid) {
+ schema_entry = talloc_asprintf_append(schema_entry,
+ "PROPERTY-SET-GUID '%s'%s",
+ property_set_guid, seperator);
+ IF_NULL_FAIL_RET(schema_entry);
+ }
+
+ if (indexed) {
+ schema_entry = talloc_asprintf_append(schema_entry,
+ "INDEXED%s", seperator);
+ IF_NULL_FAIL_RET(schema_entry);
+ }
+
+ if (system_only) {
+ schema_entry = talloc_asprintf_append(schema_entry,
+ "SYSTEM-ONLY%s", seperator);
+ IF_NULL_FAIL_RET(schema_entry);
+ }
+
schema_entry = talloc_asprintf_append(schema_entry,
")");
return schema_entry;
@@ -80,14 +128,12 @@ char *schema_attribute_description(TALLOC_CTX *mem_ctx,
char *schema_attribute_to_description(TALLOC_CTX *mem_ctx, const struct dsdb_attribute *attribute)
{
char *schema_description;
- const struct dsdb_syntax *map = find_syntax_map_by_ad_oid(attribute->attributeSyntax_oid);
- const char *syntax = map ? map->ldap_oid : attribute->attributeSyntax_oid;
+ const char *syntax = attribute->syntax->ldap_oid;
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
if (!tmp_ctx) {
return NULL;
}
-
schema_description
= schema_attribute_description(mem_ctx,
TARGET_AD_SCHEMA_SUBENTRY,
@@ -96,6 +142,34 @@ char *schema_attribute_to_description(TALLOC_CTX *mem_ctx, const struct dsdb_att
attribute->lDAPDisplayName,
NULL, NULL, talloc_asprintf(tmp_ctx, "'%s'", syntax),
attribute->isSingleValued,
+ attribute->systemOnly,/* TODO: is this correct? */
+ NULL, NULL, NULL, NULL,
+ false, false);
+ talloc_free(tmp_ctx);
+ return schema_description;
+}
+
+char *schema_attribute_to_extendedInfo(TALLOC_CTX *mem_ctx, const struct dsdb_attribute *attribute)
+{
+ char *schema_description;
+ TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+ if (!tmp_ctx) {
+ return NULL;
+ }
+
+ schema_description
+ = schema_attribute_description(mem_ctx,
+ TARGET_AD_SCHEMA_SUBENTRY,
+ " ",
+ attribute->attributeID_oid,
+ attribute->lDAPDisplayName,
+ NULL, NULL, NULL,
+ false, false,
+ attribute->rangeLower,
+ attribute->rangeUpper,
+ GUID_hexstring(tmp_ctx, &attribute->schemaIDGUID),
+ GUID_hexstring(tmp_ctx, &attribute->attributeSecurityGUID),
+ (attribute->searchFlags & SEARCH_FLAG_ATTINDEX),
attribute->systemOnly);
talloc_free(tmp_ctx);
return schema_description;
@@ -142,7 +216,8 @@ char *schema_class_description(TALLOC_CTX *mem_ctx,
const char *subClassOf,
int objectClassCategory,
char **must,
- char **may)
+ char **may,
+ const char *schemaHexGUID)
{
char *schema_entry = talloc_asprintf(mem_ctx,
"(%s%s%s", seperator, oid, seperator);
@@ -225,7 +300,14 @@ char *schema_class_description(TALLOC_CTX *mem_ctx,
")%s", seperator);
IF_NULL_FAIL_RET(schema_entry);
}
-
+
+ if (schemaHexGUID) {
+ schema_entry = talloc_asprintf_append(schema_entry,
+ "CLASS-GUID '%s'%s",
+ schemaHexGUID, seperator);
+ IF_NULL_FAIL_RET(schema_entry);
+ }
+
schema_entry = talloc_asprintf_append(schema_entry,
")");
return schema_entry;
@@ -251,7 +333,8 @@ char *schema_class_to_description(TALLOC_CTX *mem_ctx, const struct dsdb_class *
dsdb_attribute_list(tmp_ctx,
class, DSDB_SCHEMA_ALL_MUST),
dsdb_attribute_list(tmp_ctx,
- class, DSDB_SCHEMA_ALL_MAY));
+ class, DSDB_SCHEMA_ALL_MAY),
+ NULL);
talloc_free(tmp_ctx);
return schema_description;
}
@@ -295,7 +378,38 @@ char *schema_class_to_dITContentRule(TALLOC_CTX *mem_ctx, const struct dsdb_clas
* ditContentRules
* per MS-ADTS
* 3.1.1.3.1.1.1 */
- -1, must_attr_list, may_attr_list);
+ -1, must_attr_list, may_attr_list,
+ NULL);
talloc_free(tmp_ctx);
return schema_description;
}
+
+char *schema_class_to_extendedInfo(TALLOC_CTX *mem_ctx, const struct dsdb_class *sclass)
+{
+ char *schema_description = NULL;
+ DATA_BLOB guid_blob;
+ char *guid_hex;
+ TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+ if (!tmp_ctx) {
+ return NULL;
+ }
+
+ schema_description
+ = schema_class_description(mem_ctx,
+ TARGET_AD_SCHEMA_SUBENTRY,
+ " ",
+ sclass->governsID_oid,
+ sclass->lDAPDisplayName,
+ NULL,
+ NULL, /* Must not specify a
+ * SUP (subclass) in
+ * ditContentRules
+ * per MS-ADTS
+ * 3.1.1.3.1.1.1 */
+ -1, NULL, NULL,
+ GUID_hexstring(tmp_ctx, &sclass->schemaIDGUID));
+ talloc_free(tmp_ctx);
+ return schema_description;
+}
+
+
diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c
index 6561e8ed88..763872cf2b 100644
--- a/source4/dsdb/schema/schema_init.c
+++ b/source4/dsdb/schema/schema_init.c
@@ -643,6 +643,24 @@ WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
(p)->elem = samdb_result_uint(msg, attr, 0);\
} while (0)
+#define GET_UINT32_PTR_LDB(msg, attr, p, elem) do { \
+ uint64_t _v = samdb_result_uint64(msg, attr, UINT64_MAX);\
+ if (_v == UINT64_MAX) { \
+ (p)->elem = NULL; \
+ } else if (_v > UINT32_MAX) { \
+ d_printf("%s: %s == 0x%llX\n", __location__, \
+ attr, (unsigned long long)_v); \
+ return WERR_INVALID_PARAM; \
+ } else { \
+ (p)->elem = talloc(mem_ctx, uint32_t); \
+ if (!(p)->elem) { \
+ d_printf("%s: talloc failed for %s\n", __location__, attr); \
+ return WERR_NOMEM; \
+ } \
+ *(p)->elem = (uint32_t)_v; \
+ } \
+} while (0)
+
#define GET_GUID_LDB(msg, attr, p, elem) do { \
(p)->elem = samdb_result_guid(msg, attr);\
} while (0)
@@ -707,8 +725,8 @@ WERROR dsdb_attribute_from_ldb(const struct dsdb_schema *schema,
GET_BLOB_LDB(msg, "oMObjectClass", mem_ctx, attr, oMObjectClass);
GET_BOOL_LDB(msg, "isSingleValued", attr, isSingleValued, true);
- GET_UINT32_LDB(msg, "rangeLower", attr, rangeLower);
- GET_UINT32_LDB(msg, "rangeUpper", attr, rangeUpper);
+ GET_UINT32_PTR_LDB(msg, "rangeLower", attr, rangeLower);
+ GET_UINT32_PTR_LDB(msg, "rangeUpper", attr, rangeUpper);
GET_BOOL_LDB(msg, "extendedCharsAllowed", attr, extendedCharsAllowed, false);
GET_UINT32_LDB(msg, "schemaFlagsEx", attr, schemaFlagsEx);
@@ -1260,6 +1278,23 @@ static struct drsuapi_DsReplicaAttribute *dsdb_find_object_attr_name(struct dsdb
} \
} while (0)
+#define GET_UINT32_PTR_DS(s, r, attr, p, elem) do { \
+ struct drsuapi_DsReplicaAttribute *_a; \
+ _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
+ if (_a && _a->value_ctr.num_values >= 1 \
+ && _a->value_ctr.values[0].blob \
+ && _a->value_ctr.values[0].blob->length == 4) { \
+ (p)->elem = talloc(mem_ctx, uint32_t); \
+ if (!(p)->elem) { \
+ d_printf("%s: talloc failed for %s\n", __location__, attr); \
+ return WERR_NOMEM; \
+ } \
+ *(p)->elem = IVAL(_a->value_ctr.values[0].blob->data,0);\
+ } else { \
+ (p)->elem = NULL; \
+ } \
+} while (0)
+
#define GET_GUID_DS(s, r, attr, mem_ctx, p, elem) do { \
struct drsuapi_DsReplicaAttribute *_a; \
_a = dsdb_find_object_attr_name(s, r, attr, NULL); \
@@ -1330,8 +1365,8 @@ WERROR dsdb_attribute_from_drsuapi(struct dsdb_schema *schema,
GET_BLOB_DS(schema, r, "oMObjectClass", mem_ctx, attr, oMObjectClass);
GET_BOOL_DS(schema, r, "isSingleValued", attr, isSingleValued, true);
- GET_UINT32_DS(schema, r, "rangeLower", attr, rangeLower);
- GET_UINT32_DS(schema, r, "rangeUpper", attr, rangeUpper);
+ GET_UINT32_PTR_DS(schema, r, "rangeLower", attr, rangeLower);
+ GET_UINT32_PTR_DS(schema, r, "rangeUpper", attr, rangeUpper);
GET_BOOL_DS(schema, r, "extendedCharsAllowed", attr, extendedCharsAllowed, false);
GET_UINT32_DS(schema, r, "schemaFlagsEx", attr, schemaFlagsEx);
diff --git a/source4/dsdb/schema/schema_syntax.c b/source4/dsdb/schema/schema_syntax.c
index e0e6b3fc77..7aed08605b 100644
--- a/source4/dsdb/schema/schema_syntax.c
+++ b/source4/dsdb/schema/schema_syntax.c
@@ -1278,9 +1278,9 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
.attributeSyntax_oid = "2.5.5.7",
.drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
.ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
- .equality = "distinguishedNameMatch",
+ .equality = "octetStringMatch",
.comment = "OctetString: Binary+DN",
- .ldb_syntax = LDB_SYNTAX_DN,
+ .ldb_syntax = LDB_SYNTAX_OCTET_STRING,
},{
/* not used in w2k3 schema */
.name = "Object(OR-Name)",
@@ -1322,9 +1322,6 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
.attributeSyntax_oid = "2.5.5.14",
.drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
.ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
- .equality = "distinguishedNameMatch",
- .comment = "OctetString: String+DN",
- .ldb_syntax = LDB_SYNTAX_DN,
},{
/* not used in w2k3 schema */
.name = "Object(DN-String)",
@@ -1334,6 +1331,8 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
.attributeSyntax_oid = "2.5.5.14",
.drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
.ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
+ .equality = "distinguishedNameMatch",
+ .comment = "OctetString: String+DN",
.ldb_syntax = LDB_SYNTAX_DN,
}
};
diff --git a/source4/headermap.txt b/source4/headermap.txt
index cb5a4fab4c..b6edaac414 100644
--- a/source4/headermap.txt
+++ b/source4/headermap.txt
@@ -43,6 +43,7 @@ librpc/gen_ndr/samr.h: gen_ndr/samr.h
librpc/gen_ndr/ndr_samr.h: gen_ndr/ndr_samr.h
librpc/gen_ndr/ndr_samr_c.h: gen_ndr/ndr_samr_c.h
librpc/gen_ndr/security.h: gen_ndr/security.h
+librpc/gen_ndr/dom_sid.h: gen_ndr/dom_sid.h
auth/credentials/credentials.h: credentials.h
auth/credentials/credentials_krb5.h: credentials/krb5.h
rpc_server/dcerpc_server.h: dcerpc_server.h
@@ -50,7 +51,7 @@ rpc_server/common/common.h: dcerpc_server/common.h
libcli/auth/credentials.h: domain_credentials.h
../lib/util/charset/charset.h: charset.h
libcli/ldap/ldap.h: ldap.h
-lib/torture/torture.h: torture.h
+../lib/torture/torture.h: torture.h
libcli/libcli.h: client.h
librpc/gen_ndr/nbt.h: gen_ndr/nbt.h
librpc/gen_ndr/ntp_signd.h: gen_ndr/ntp_signd.h
diff --git a/source4/ldap_server/ldap_backend.c b/source4/ldap_server/ldap_backend.c
index d0417107f1..2adff2a1df 100644
--- a/source4/ldap_server/ldap_backend.c
+++ b/source4/ldap_server/ldap_backend.c
@@ -29,17 +29,13 @@
#include "lib/ldb/include/ldb_errors.h"
#include "lib/ldb_wrap.h"
-#define VALID_DN_SYNTAX(dn,i) do {\
+#define VALID_DN_SYNTAX(dn) do {\
if (!(dn)) {\
return NT_STATUS_NO_MEMORY;\
} else if ( ! ldb_dn_validate(dn)) {\
result = LDAP_INVALID_DN_SYNTAX;\
errstr = "Invalid DN format";\
goto reply;\
- } else if (ldb_dn_get_comp_num(dn) < (i)) {\
- result = LDAP_INVALID_DN_SYNTAX;\
- errstr = "Invalid DN (" #i " components needed for '" #dn "')";\
- goto reply;\
}\
} while(0)
@@ -179,7 +175,7 @@ static NTSTATUS ldapsrv_SearchRequest(struct ldapsrv_call *call)
NT_STATUS_HAVE_NO_MEMORY(local_ctx);
basedn = ldb_dn_new(local_ctx, samdb, req->basedn);
- VALID_DN_SYNTAX(basedn, 0);
+ VALID_DN_SYNTAX(basedn);
DEBUG(10, ("SearchRequest: basedn: [%s]\n", req->basedn));
DEBUG(10, ("SearchRequest: filter: [%s]\n", ldb_filter_from_tree(call, req->tree)));
@@ -349,7 +345,7 @@ static NTSTATUS ldapsrv_ModifyRequest(struct ldapsrv_call *call)
NT_STATUS_HAVE_NO_MEMORY(local_ctx);
dn = ldb_dn_new(local_ctx, samdb, req->dn);
- VALID_DN_SYNTAX(dn, 0);
+ VALID_DN_SYNTAX(dn);
DEBUG(10, ("ModifyRequest: dn: [%s]\n", req->dn));
@@ -452,7 +448,7 @@ static NTSTATUS ldapsrv_AddRequest(struct ldapsrv_call *call)
NT_STATUS_HAVE_NO_MEMORY(local_ctx);
dn = ldb_dn_new(local_ctx, samdb, req->dn);
- VALID_DN_SYNTAX(dn,1);
+ VALID_DN_SYNTAX(dn);
DEBUG(10, ("AddRequest: dn: [%s]\n", req->dn));
@@ -542,7 +538,7 @@ static NTSTATUS ldapsrv_DelRequest(struct ldapsrv_call *call)
NT_STATUS_HAVE_NO_MEMORY(local_ctx);
dn = ldb_dn_new(local_ctx, samdb, req->dn);
- VALID_DN_SYNTAX(dn,1);
+ VALID_DN_SYNTAX(dn);
DEBUG(10, ("DelRequest: dn: [%s]\n", req->dn));
@@ -588,10 +584,10 @@ static NTSTATUS ldapsrv_ModifyDNRequest(struct ldapsrv_call *call)
NT_STATUS_HAVE_NO_MEMORY(local_ctx);
olddn = ldb_dn_new(local_ctx, samdb, req->dn);
- VALID_DN_SYNTAX(olddn, 2);
+ VALID_DN_SYNTAX(olddn);
newrdn = ldb_dn_new(local_ctx, samdb, req->newrdn);
- VALID_DN_SYNTAX(newrdn, 1);
+ VALID_DN_SYNTAX(newrdn);
DEBUG(10, ("ModifyDNRequest: olddn: [%s]\n", req->dn));
DEBUG(10, ("ModifyDNRequest: newrdn: [%s]\n", req->newrdn));
@@ -605,7 +601,7 @@ static NTSTATUS ldapsrv_ModifyDNRequest(struct ldapsrv_call *call)
if (req->newsuperior) {
parentdn = ldb_dn_new(local_ctx, samdb, req->newsuperior);
- VALID_DN_SYNTAX(parentdn, 0);
+ VALID_DN_SYNTAX(parentdn);
DEBUG(10, ("ModifyDNRequest: newsuperior: [%s]\n", req->newsuperior));
if (ldb_dn_get_comp_num(parentdn) < 1) {
@@ -672,7 +668,7 @@ static NTSTATUS ldapsrv_CompareRequest(struct ldapsrv_call *call)
NT_STATUS_HAVE_NO_MEMORY(local_ctx);
dn = ldb_dn_new(local_ctx, samdb, req->dn);
- VALID_DN_SYNTAX(dn, 1);
+ VALID_DN_SYNTAX(dn);
DEBUG(10, ("CompareRequest: dn: [%s]\n", req->dn));
filter = talloc_asprintf(local_ctx, "(%s=%*s)", req->attribute,
diff --git a/source4/lib/ldb-samba/config.mk b/source4/lib/ldb-samba/config.mk
index f84b44dfc7..ceacf277e4 100644
--- a/source4/lib/ldb-samba/config.mk
+++ b/source4/lib/ldb-samba/config.mk
@@ -2,7 +2,7 @@
# Start SUBSYSTEM LDBSAMBA
[SUBSYSTEM::LDBSAMBA]
PUBLIC_DEPENDENCIES = LIBLDB
-PRIVATE_DEPENDENCIES = LIBSECURITY SAMDB_SCHEMA LIBNDR NDR_MISC NDR_DRSBLOBS
+PRIVATE_DEPENDENCIES = LIBSECURITY SAMDB_SCHEMA LIBNDR NDR_DRSBLOBS
# End SUBSYSTEM LDBSAMBA
################################################
diff --git a/source4/lib/ldb/common/ldb_ldif.c b/source4/lib/ldb/common/ldb_ldif.c
index 538ff8feaa..69490e670b 100644
--- a/source4/lib/ldb/common/ldb_ldif.c
+++ b/source4/lib/ldb/common/ldb_ldif.c
@@ -328,8 +328,10 @@ int ldb_ldif_write(struct ldb_context *ldb,
for (j=0;j<msg->elements[i].num_values;j++) {
struct ldb_val v;
ret = a->syntax->ldif_write_fn(ldb, mem_ctx, &msg->elements[i].values[j], &v);
- CHECK_RET;
- if (ldb_should_b64_encode(&v)) {
+ if (ret != LDB_SUCCESS) {
+ v = msg->elements[i].values[j];
+ }
+ if (ret != LDB_SUCCESS || ldb_should_b64_encode(&v)) {
ret = fprintf_fn(private_data, "%s:: ",
msg->elements[i].name);
CHECK_RET;
diff --git a/source4/lib/ldb/ldb.i b/source4/lib/ldb/ldb.i
index 35d443e809..0f05c1fbab 100644
--- a/source4/lib/ldb/ldb.i
+++ b/source4/lib/ldb/ldb.i
@@ -217,7 +217,7 @@ typedef struct ldb_dn {
we do it this way... */
talloc_steal(NULL, ret);
- if (ret == NULL)
+ if (ret == NULL || !ldb_dn_validate(ret))
SWIG_exception(SWIG_ValueError,
"unable to parse dn string");
fail:
@@ -263,7 +263,6 @@ fail:
{
char *dn = ldb_dn_get_linearized($self), *ret;
asprintf(&ret, "Dn('%s')", dn);
- talloc_free(dn);
return ret;
}
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
index 34a4e03965..9e3ad80705 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
@@ -1076,12 +1076,14 @@ static void ltdb_callback(struct event_context *ev,
}
if (!ctx->callback_failed) {
+ /* Once we are done, we do not need timeout events */
+ talloc_free(ctx->timeout_event);
ltdb_request_done(ctx->req, ret);
}
}
static int ltdb_handle_request(struct ldb_module *module,
- struct ldb_request *req)
+ struct ldb_request *req)
{
struct event_context *ev;
struct ltdb_context *ac;
@@ -1115,10 +1117,9 @@ static int ltdb_handle_request(struct ldb_module *module,
return LDB_ERR_OPERATIONS_ERROR;
}
-
tv.tv_sec = req->starttime + req->timeout;
- te = event_add_timed(ev, ac, tv, ltdb_timeout, ac);
- if (NULL == te) {
+ ac->timeout_event = event_add_timed(ev, ac, tv, ltdb_timeout, ac);
+ if (NULL == ac->timeout_event) {
return LDB_ERR_OPERATIONS_ERROR;
}
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h
index 61e90bccc6..c78a8172c7 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h
@@ -50,6 +50,7 @@ struct ltdb_context {
struct ldb_dn *base;
enum ldb_scope scope;
const char * const *attrs;
+ struct timed_event *timeout_event;
};
/* special record types */
diff --git a/source4/lib/ldb/ldb_wrap.c b/source4/lib/ldb/ldb_wrap.c
index 194b562c30..4a34c1c998 100644
--- a/source4/lib/ldb/ldb_wrap.c
+++ b/source4/lib/ldb/ldb_wrap.c
@@ -2732,7 +2732,6 @@ SWIGINTERN char const *ldb_dn_canonical_ex_str(ldb_dn *self){
SWIGINTERN char *ldb_dn___repr__(ldb_dn *self){
char *dn = ldb_dn_get_linearized(self), *ret;
asprintf(&ret, "Dn('%s')", dn);
- talloc_free(dn);
return ret;
}
SWIGINTERN ldb_dn *ldb_dn___add__(ldb_dn *self,ldb_dn *other){
diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk
index 2e2b45abe9..9af61f9632 100644
--- a/source4/lib/registry/config.mk
+++ b/source4/lib/registry/config.mk
@@ -97,7 +97,7 @@ regtree_OBJ_FILES = $(libregistrysrcdir)/tools/regtree.o
MANPAGES += $(libregistrysrcdir)/man/regtree.1
[SUBSYSTEM::torture_registry]
-PRIVATE_DEPENDENCIES = registry
+PRIVATE_DEPENDENCIES = torture registry
torture_registry_OBJ_FILES = $(addprefix $(libregistrysrcdir)/tests/, generic.o hive.o diff.o registry.o)
diff --git a/source4/lib/wmi/config.mk b/source4/lib/wmi/config.mk
index 28f6c73dcd..3bb1690c7b 100644
--- a/source4/lib/wmi/config.mk
+++ b/source4/lib/wmi/config.mk
@@ -43,7 +43,7 @@ librpc/gen_ndr/dcom_p.c: idl
#######################
# Start LIBRARY swig_dcerpc
[PYTHON::pywmi]
-PUBLIC_DEPENDENCIES = LIBCLI_SMB NDR_MISC LIBSAMBA-UTIL LIBSAMBA-CONFIG WMI
+PUBLIC_DEPENDENCIES = LIBCLI_SMB LIBNDR LIBSAMBA-UTIL LIBSAMBA-CONFIG WMI
$(eval $(call python_py_module_template,wmi.py,$(wmisrcdir)/wmi.py))
diff --git a/source4/libcli/clideltree.c b/source4/libcli/clideltree.c
index 28563d918e..d947ac3547 100644
--- a/source4/libcli/clideltree.c
+++ b/source4/libcli/clideltree.c
@@ -97,7 +97,8 @@ int smbcli_deltree(struct smbcli_tree *tree, const char *dname)
}
if (NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_OBJECT_PATH_NOT_FOUND) ||
- NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_NO_SUCH_FILE)) {
+ NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_NO_SUCH_FILE) ||
+ NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_DOS(ERRDOS, ERRbadfile))) {
return 0;
}
if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c
index a12f7652a5..5e6a5faafa 100644
--- a/source4/libcli/ldap/ldap_bind.c
+++ b/source4/libcli/ldap/ldap_bind.c
@@ -286,7 +286,7 @@ _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn,
search = &sasl_mechs_msgs[0]->r.SearchResultEntry;
if (search->num_attributes != 1) {
- DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of attributes: %d\n",
+ DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of attributes: %d != 1\n",
search->num_attributes));
goto failed;
}
diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c
index 1a695432ee..7d779b0678 100644
--- a/source4/libcli/resolve/host.c
+++ b/source4/libcli/resolve/host.c
@@ -53,10 +53,15 @@ struct host_state {
*/
static int host_destructor(struct host_state *state)
{
+ int status;
+
+ kill(state->child, SIGTERM);
close(state->child_fd);
- if (state->child != (pid_t)-1) {
- kill(state->child, SIGTERM);
+ if (waitpid(state->child, &status, WNOHANG) == 0) {
+ kill(state->child, SIGKILL);
+ waitpid(state->child, &status, 0);
}
+
return 0;
}
@@ -90,16 +95,23 @@ static void pipe_handler(struct event_context *ev, struct fd_event *fde,
struct host_state *state = talloc_get_type(c->private_data, struct host_state);
char address[128];
int ret;
+ pid_t child = state->child;
+ int status;
/* if we get any event from the child then we know that we
won't need to kill it off */
- state->child = (pid_t)-1;
+ talloc_set_destructor(state, NULL);
/* yes, we don't care about EAGAIN or other niceities
here. They just can't happen with this parent/child
relationship, and even if they did then giving an error is
the right thing to do */
ret = read(state->child_fd, address, sizeof(address)-1);
+ close(state->child_fd);
+ if (waitpid(state->child, &status, WNOHANG) == 0) {
+ kill(state->child, SIGKILL);
+ waitpid(state->child, &status, 0);
+ }
if (ret <= 0) {
composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
return;
@@ -164,10 +176,6 @@ struct composite_context *resolve_name_host_send(TALLOC_CTX *mem_ctx,
return c;
}
- /* signal handling in posix really sucks - doing this in a library
- affects the whole app, but what else to do?? */
- signal(SIGCHLD, SIG_IGN);
-
state->child = fork();
if (state->child == (pid_t)-1) {
composite_error(c, map_nt_error_from_unix(errno));
diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk
index f2883d1ede..30b1f32935 100644
--- a/source4/libcli/security/config.mk
+++ b/source4/libcli/security/config.mk
@@ -1,5 +1,5 @@
[SUBSYSTEM::LIBSECURITY]
-PUBLIC_DEPENDENCIES = NDR_MISC LIBNDR
+PUBLIC_DEPENDENCIES = LIBNDR
LIBSECURITY_OBJ_FILES = $(addprefix $(libclisrcdir)/security/, \
security_token.o security_descriptor.o \
diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c
index e95f0228c1..e94ed36d39 100644
--- a/source4/libcli/util/nterr.c
+++ b/source4/libcli/util/nterr.c
@@ -548,6 +548,7 @@ static const nt_err_code_struct nt_errs[] =
{ "NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED", NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED },
{ "NT_STATUS_OBJECTID_NOT_FOUND", NT_STATUS_OBJECTID_NOT_FOUND },
{ "NT_STATUS_DOWNGRADE_DETECTED", NT_STATUS_DOWNGRADE_DETECTED },
+ { "NT_STATUS_DS_BUSY", NT_STATUS_DS_BUSY },
{ "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES },
{ "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED },
{ "STATUS_NOTIFY_CLEANUP", STATUS_NOTIFY_CLEANUP },
diff --git a/source4/libnet/groupinfo.c b/source4/libnet/groupinfo.c
index 1da6646702..5c94c34b1d 100644
--- a/source4/libnet/groupinfo.c
+++ b/source4/libnet/groupinfo.c
@@ -83,8 +83,8 @@ static void continue_groupinfo_lookup(struct rpc_request *req)
if (s->monitor_fn) {
msg.type = mon_SamrLookupName;
msg_lookup = talloc(s, struct msg_rpc_lookup_name);
- msg_lookup->rid = s->lookup.out.rids.ids;
- msg_lookup->count = s->lookup.out.rids.count;
+ msg_lookup->rid = s->lookup.out.rids->ids;
+ msg_lookup->count = s->lookup.out.rids->count;
msg.data = (void*)msg_lookup;
msg.data_size = sizeof(*msg_lookup);
@@ -94,7 +94,7 @@ static void continue_groupinfo_lookup(struct rpc_request *req)
/* have we actually got name resolved
- we're looking for only one at the moment */
- if (s->lookup.out.rids.count == 0) {
+ if (s->lookup.out.rids->count == 0) {
composite_error(c, NT_STATUS_NO_SUCH_USER);
}
@@ -103,7 +103,7 @@ static void continue_groupinfo_lookup(struct rpc_request *req)
/* prepare parameters for LookupNames */
s->opengroup.in.domain_handle = &s->domain_handle;
s->opengroup.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- s->opengroup.in.rid = s->lookup.out.rids.ids[0];
+ s->opengroup.in.rid = s->lookup.out.rids->ids[0];
s->opengroup.out.group_handle = &s->group_handle;
/* send request */
@@ -152,6 +152,8 @@ static void continue_groupinfo_opengroup(struct rpc_request *req)
/* prepare parameters for QueryGroupInfo call */
s->querygroupinfo.in.group_handle = &s->group_handle;
s->querygroupinfo.in.level = s->level;
+ s->querygroupinfo.out.info = talloc(s, union samr_GroupInfo *);
+ if (composite_nomem(s->querygroupinfo.out.info, c)) return;
/* queue rpc call, set event handling and new state */
querygroup_req = dcerpc_samr_QueryGroupInfo_send(s->pipe, c, &s->querygroupinfo);
@@ -185,7 +187,7 @@ static void continue_groupinfo_getgroup(struct rpc_request *req)
return;
}
- s->info = talloc_steal(s, s->querygroupinfo.out.info);
+ s->info = talloc_steal(s, *s->querygroupinfo.out.info);
/* issue a monitor message */
if (s->monitor_fn) {
@@ -301,7 +303,11 @@ struct composite_context *libnet_rpc_groupinfo_send(struct dcerpc_pipe *p,
s->lookup.in.names[0].string = talloc_strdup(s, io->in.groupname);
if (composite_nomem(s->lookup.in.names[0].string, c)) return c;
-
+ s->lookup.out.rids = talloc_zero(s, struct samr_Ids);
+ s->lookup.out.types = talloc_zero(s, struct samr_Ids);
+ if (composite_nomem(s->lookup.out.rids, c)) return c;
+ if (composite_nomem(s->lookup.out.types, c)) return c;
+
/* send request */
lookup_req = dcerpc_samr_LookupNames_send(p, c, &s->lookup);
if (composite_nomem(lookup_req, c)) return c;
diff --git a/source4/libnet/groupman.c b/source4/libnet/groupman.c
index 58d5742336..4dfb2d8aab 100644
--- a/source4/libnet/groupman.c
+++ b/source4/libnet/groupman.c
@@ -174,6 +174,10 @@ struct composite_context* libnet_rpc_groupdel_send(struct dcerpc_pipe *p,
s->lookupname.in.num_names = 1;
s->lookupname.in.names = talloc_zero(s, struct lsa_String);
s->lookupname.in.names->string = io->in.groupname;
+ s->lookupname.out.rids = talloc_zero(s, struct samr_Ids);
+ s->lookupname.out.types = talloc_zero(s, struct samr_Ids);
+ if (composite_nomem(s->lookupname.out.rids, c)) return c;
+ if (composite_nomem(s->lookupname.out.types, c)) return c;
/* send the request */
lookup_req = dcerpc_samr_LookupNames_send(p, c, &s->lookupname);
@@ -205,12 +209,12 @@ static void continue_groupdel_name_found(struct rpc_request *req)
/* what to do when there's no group account to delete
and what if there's more than one rid resolved */
- if (!s->lookupname.out.rids.count) {
+ if (!s->lookupname.out.rids->count) {
c->status = NT_STATUS_NO_SUCH_GROUP;
composite_error(c, c->status);
return;
- } else if (!s->lookupname.out.rids.count > 1) {
+ } else if (!s->lookupname.out.rids->count > 1) {
c->status = NT_STATUS_INVALID_ACCOUNT_NAME;
composite_error(c, c->status);
return;
@@ -218,7 +222,7 @@ static void continue_groupdel_name_found(struct rpc_request *req)
/* prepare the arguments for rpc call */
s->opengroup.in.domain_handle = &s->domain_handle;
- s->opengroup.in.rid = s->lookupname.out.rids.ids[0];
+ s->opengroup.in.rid = s->lookupname.out.rids->ids[0];
s->opengroup.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
s->opengroup.out.group_handle = &s->group_handle;
diff --git a/source4/libnet/libnet_domain.c b/source4/libnet/libnet_domain.c
index ccdfdaf134..eb6920d88e 100644
--- a/source4/libnet/libnet_domain.c
+++ b/source4/libnet/libnet_domain.c
@@ -40,6 +40,7 @@ struct domain_open_samr_state {
uint32_t access_mask;
struct policy_handle connect_handle;
struct policy_handle domain_handle;
+ struct dom_sid2 *domain_sid;
/* information about the progress */
void (*monitor_fn)(struct monitor_msg*);
@@ -159,6 +160,8 @@ static void continue_domain_open_connect(struct rpc_request *req)
/* prepare for samr_LookupDomain call */
r->in.connect_handle = &s->connect_handle;
r->in.domain_name = &s->domain_name;
+ r->out.sid = talloc(s, struct dom_sid2 *);
+ if (composite_nomem(r->out.sid, c)) return;
lookup_req = dcerpc_samr_LookupDomain_send(s->pipe, c, r);
if (composite_nomem(lookup_req, c)) return;
@@ -209,7 +212,7 @@ static void continue_domain_open_lookup(struct rpc_request *req)
/* prepare for samr_OpenDomain call */
r->in.connect_handle = &s->connect_handle;
r->in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- r->in.sid = s->lookup.out.sid;
+ r->in.sid = *s->lookup.out.sid;
r->out.domain_handle = &s->domain_handle;
opendom_req = dcerpc_samr_OpenDomain_send(s->pipe, c, r);
@@ -361,7 +364,7 @@ NTSTATUS libnet_DomainOpenSamr_recv(struct composite_context *c, struct libnet_c
libnet functions */
ctx->samr.connect_handle = s->connect_handle;
ctx->samr.handle = s->domain_handle;
- ctx->samr.sid = talloc_steal(ctx, s->lookup.out.sid);
+ ctx->samr.sid = talloc_steal(ctx, *s->lookup.out.sid);
ctx->samr.name = talloc_steal(ctx, s->domain_name.string);
ctx->samr.access_mask = s->access_mask;
}
@@ -998,6 +1001,10 @@ static void continue_samr_connect(struct rpc_request *req)
s->enumdom.in.resume_handle = &s->resume_handle;
s->enumdom.in.buf_size = s->buf_size;
s->enumdom.out.resume_handle = &s->resume_handle;
+ s->enumdom.out.num_entries = talloc(s, uint32_t);
+ if (composite_nomem(s->enumdom.out.num_entries, c)) return;
+ s->enumdom.out.sam = talloc(s, struct samr_SamArray *);
+ if (composite_nomem(s->enumdom.out.sam, c)) return;
enumdom_req = dcerpc_samr_EnumDomains_send(s->ctx->samr.pipe, c, &s->enumdom);
if (composite_nomem(enumdom_req, c)) return;
@@ -1113,16 +1120,16 @@ static struct domainlist* get_domain_list(TALLOC_CTX *mem_ctx, struct domain_lis
/* prepare domains array */
if (s->domains == NULL) {
s->domains = talloc_array(mem_ctx, struct domainlist,
- s->enumdom.out.num_entries);
+ *s->enumdom.out.num_entries);
} else {
s->domains = talloc_realloc(mem_ctx, s->domains, struct domainlist,
- s->count + s->enumdom.out.num_entries);
+ s->count + *s->enumdom.out.num_entries);
}
/* copy domain names returned from samr_EnumDomains call */
- for (i = s->count; i < s->count + s->enumdom.out.num_entries; i++)
+ for (i = s->count; i < s->count + *s->enumdom.out.num_entries; i++)
{
- struct lsa_String *domain_name = &s->enumdom.out.sam->entries[i - s->count].name;
+ struct lsa_String *domain_name = &(*s->enumdom.out.sam)->entries[i - s->count].name;
/* strdup name as a child of allocated array to make it follow the array
in case of talloc_steal or talloc_free */
@@ -1131,7 +1138,7 @@ static struct domainlist* get_domain_list(TALLOC_CTX *mem_ctx, struct domain_lis
}
/* number of entries returned (domains enumerated) */
- s->count += s->enumdom.out.num_entries;
+ s->count += *s->enumdom.out.num_entries;
return s->domains;
}
diff --git a/source4/libnet/libnet_group.c b/source4/libnet/libnet_group.c
index eded378511..af5fe4d5d3 100644
--- a/source4/libnet/libnet_group.c
+++ b/source4/libnet/libnet_group.c
@@ -518,6 +518,10 @@ static void continue_domain_queried(struct rpc_request *req)
s->group_list.in.max_size = s->page_size;
s->group_list.in.resume_handle = &s->resume_index;
s->group_list.out.resume_handle = &s->resume_index;
+ s->group_list.out.num_entries = talloc(s, uint32_t);
+ if (composite_nomem(s->group_list.out.num_entries, c)) return;
+ s->group_list.out.sam = talloc(s, struct samr_SamArray *);
+ if (composite_nomem(s->group_list.out.sam, c)) return;
/* send the request */
enum_req = dcerpc_samr_EnumDomainGroups_send(s->ctx->samr.pipe, c, &s->group_list);
@@ -549,6 +553,10 @@ static void continue_samr_domain_opened(struct composite_context *ctx)
s->group_list.in.max_size = s->page_size;
s->group_list.in.resume_handle = &s->resume_index;
s->group_list.out.resume_handle = &s->resume_index;
+ s->group_list.out.num_entries = talloc(s, uint32_t);
+ if (composite_nomem(s->group_list.out.num_entries, c)) return;
+ s->group_list.out.sam = talloc(s, struct samr_SamArray *);
+ if (composite_nomem(s->group_list.out.sam, c)) return;
/* send the request */
enum_req = dcerpc_samr_EnumDomainGroups_send(s->ctx->samr.pipe, c, &s->group_list);
@@ -587,15 +595,15 @@ static void continue_groups_enumerated(struct rpc_request *req)
/* get enumerated accounts counter and resume handle (the latter allows
making subsequent call to continue enumeration) */
s->resume_index = *s->group_list.out.resume_handle;
- s->count = s->group_list.out.num_entries;
+ s->count = *s->group_list.out.num_entries;
/* prepare returned group accounts array */
- s->groups = talloc_array(c, struct grouplist, s->group_list.out.sam->count);
+ s->groups = talloc_array(c, struct grouplist, (*s->group_list.out.sam)->count);
if (composite_nomem(s->groups, c)) return;
- for (i = 0; i < s->group_list.out.sam->count; i++) {
+ for (i = 0; i < (*s->group_list.out.sam)->count; i++) {
struct dom_sid *group_sid;
- struct samr_SamEntry *entry = &s->group_list.out.sam->entries[i];
+ struct samr_SamEntry *entry = &(*s->group_list.out.sam)->entries[i];
struct dom_sid *domain_sid = (*s->query_domain.out.info)->domain.sid;
/* construct group sid from returned rid and queried domain sid */
diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c
index 0ed5e8ae26..70fcb4a894 100644
--- a/source4/libnet/libnet_join.c
+++ b/source4/libnet/libnet_join.c
@@ -444,13 +444,16 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
struct samr_OpenDomain od;
struct policy_handle d_handle;
struct samr_LookupNames ln;
+ struct samr_Ids rids, types;
struct samr_OpenUser ou;
struct samr_CreateUser2 cu;
struct policy_handle *u_handle = NULL;
struct samr_QueryUserInfo qui;
+ union samr_UserInfo *uinfo;
struct samr_UserInfo21 u_info21;
union libnet_SetPassword r2;
struct samr_GetUserPwInfo pwp;
+ struct samr_PwInfo info;
struct lsa_String samr_account_name;
uint32_t acct_flags, old_acct_flags;
@@ -559,9 +562,11 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
if (!connect_with_info->out.domain_sid) {
struct lsa_String name;
struct samr_LookupDomain l;
+ struct dom_sid2 *sid = NULL;
name.string = connect_with_info->out.domain_name;
l.in.connect_handle = &p_handle;
l.in.domain_name = &name;
+ l.out.sid = &sid;
status = dcerpc_samr_LookupDomain(samr_pipe, tmp_ctx, &l);
if (!NT_STATUS_IS_OK(status)) {
@@ -571,7 +576,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
talloc_free(tmp_ctx);
return status;
}
- connect_with_info->out.domain_sid = l.out.sid;
+ connect_with_info->out.domain_sid = *l.out.sid;
}
/* prepare samr_OpenDomain */
@@ -611,6 +616,8 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
ln.in.domain_handle = &d_handle;
ln.in.num_names = 1;
ln.in.names = talloc_array(tmp_ctx, struct lsa_String, 1);
+ ln.out.rids = &rids;
+ ln.out.types = &types;
if (!ln.in.names) {
r->out.error_string = NULL;
talloc_free(tmp_ctx);
@@ -630,10 +637,10 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
}
/* check if we got one RID for the user */
- if (ln.out.rids.count != 1) {
+ if (ln.out.rids->count != 1) {
r->out.error_string = talloc_asprintf(mem_ctx,
"samr_LookupNames for [%s] returns %d RIDs",
- r->in.account_name, ln.out.rids.count);
+ r->in.account_name, ln.out.rids->count);
talloc_free(tmp_ctx);
return NT_STATUS_INVALID_PARAMETER;
}
@@ -642,7 +649,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
ZERO_STRUCTP(u_handle);
ou.in.domain_handle = &d_handle;
ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- ou.in.rid = ln.out.rids.ids[0];
+ ou.in.rid = ln.out.rids->ids[0];
rid = ou.in.rid;
ou.out.user_handle = u_handle;
@@ -694,6 +701,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
/* prepare samr_QueryUserInfo (get flags) */
qui.in.user_handle = u_handle;
qui.in.level = 16;
+ qui.out.info = &uinfo;
status = dcerpc_samr_QueryUserInfo(samr_pipe, tmp_ctx, &qui);
if (!NT_STATUS_IS_OK(status)) {
@@ -705,7 +713,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
return status;
}
- if (!qui.out.info) {
+ if (!uinfo) {
status = NT_STATUS_INVALID_PARAMETER;
r->out.error_string
= talloc_asprintf(mem_ctx,
@@ -715,7 +723,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
return status;
}
- old_acct_flags = (qui.out.info->info16.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST));
+ old_acct_flags = (uinfo->info16.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST));
/* Possibly bail if the account is of the wrong type */
if (old_acct_flags
!= r->in.acct_type) {
@@ -771,17 +779,18 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
return NT_STATUS_USER_EXISTS;
}
} else {
- acct_flags = qui.out.info->info16.acct_flags;
+ acct_flags = uinfo->info16.acct_flags;
}
acct_flags = (acct_flags & ~(ACB_DISABLED|ACB_PWNOTREQ));
/* Find out what password policy this user has */
pwp.in.user_handle = u_handle;
+ pwp.out.info = &info;
status = dcerpc_samr_GetUserPwInfo(samr_pipe, tmp_ctx, &pwp);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = pwp.out.info.min_password_length;
+ policy_min_pw_len = pwp.out.info->min_password_length;
}
/* Grab a password of that minimum length */
diff --git a/source4/libnet/libnet_passwd.c b/source4/libnet/libnet_passwd.c
index de2ed01abd..80de6134b5 100644
--- a/source4/libnet/libnet_passwd.c
+++ b/source4/libnet/libnet_passwd.c
@@ -50,6 +50,8 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT
struct samr_Password nt_verifier, lm_verifier;
uint8_t old_nt_hash[16], new_nt_hash[16];
uint8_t old_lm_hash[16], new_lm_hash[16];
+ struct samr_DomInfo1 *dominfo = NULL;
+ struct samr_ChangeReject *reject = NULL;
/* prepare connect to the SAMR pipe of the users domain PDC */
c.level = LIBNET_RPC_CONNECT_PDC;
@@ -92,6 +94,8 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT
pw3.in.lm_password = &lm_pass;
pw3.in.lm_verifier = &lm_verifier;
pw3.in.password3 = NULL;
+ pw3.out.dominfo = &dominfo;
+ pw3.out.reject = &reject;
/* 2. try samr_ChangePasswordUser3 */
status = dcerpc_samr_ChangePasswordUser3(c.out.dcerpc_pipe, mem_ctx, &pw3);
@@ -303,7 +307,7 @@ static NTSTATUS libnet_SetPassword_samr_handle_26(struct libnet_context *ctx, TA
/* prepare samr_SetUserInfo2 level 26 */
ZERO_STRUCT(u_info);
encode_pw_buffer(u_info.info26.password.data, r->samr_handle.in.newpassword, STR_UNICODE);
- u_info.info26.pw_len = strlen(r->samr_handle.in.newpassword);
+ u_info.info26.password_expired = 0;
status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key);
if (!NT_STATUS_IS_OK(status)) {
@@ -406,8 +410,7 @@ static NTSTATUS libnet_SetPassword_samr_handle_24(struct libnet_context *ctx, TA
/* prepare samr_SetUserInfo2 level 24 */
ZERO_STRUCT(u_info);
encode_pw_buffer(u_info.info24.password.data, r->samr_handle.in.newpassword, STR_UNICODE);
- /* w2k3 ignores this length */
- u_info.info24.pw_len = strlen_m(r->samr_handle.in.newpassword)*2;
+ u_info.info24.password_expired = 0;
status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key);
if (!NT_STATUS_IS_OK(status)) {
@@ -527,10 +530,12 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
struct samr_Connect sc;
struct policy_handle p_handle;
struct samr_LookupDomain ld;
+ struct dom_sid2 *sid = NULL;
struct lsa_String d_name;
struct samr_OpenDomain od;
struct policy_handle d_handle;
struct samr_LookupNames ln;
+ struct samr_Ids rids, types;
struct samr_OpenUser ou;
struct policy_handle u_handle;
union libnet_SetPassword r2;
@@ -568,6 +573,7 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
d_name.string = r->samr.in.domain_name;
ld.in.connect_handle = &p_handle;
ld.in.domain_name = &d_name;
+ ld.out.sid = &sid;
/* 3. do a samr_LookupDomain to get the domain sid */
status = dcerpc_samr_LookupDomain(c.out.dcerpc_pipe, mem_ctx, &ld);
@@ -582,7 +588,7 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
ZERO_STRUCT(d_handle);
od.in.connect_handle = &p_handle;
od.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- od.in.sid = ld.out.sid;
+ od.in.sid = *ld.out.sid;
od.out.domain_handle = &d_handle;
/* 4. do a samr_OpenDomain to get a domain handle */
@@ -598,6 +604,8 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
ln.in.domain_handle = &d_handle;
ln.in.num_names = 1;
ln.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
+ ln.out.rids = &rids;
+ ln.out.types = &types;
if (!ln.in.names) {
r->samr.out.error_string = "Out of Memory";
return NT_STATUS_NO_MEMORY;
@@ -614,10 +622,10 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
}
/* check if we got one RID for the user */
- if (ln.out.rids.count != 1) {
+ if (ln.out.rids->count != 1) {
r->samr.out.error_string = talloc_asprintf(mem_ctx,
"samr_LookupNames for [%s] returns %d RIDs",
- r->samr.in.account_name, ln.out.rids.count);
+ r->samr.in.account_name, ln.out.rids->count);
status = NT_STATUS_INVALID_PARAMETER;
goto disconnect;
}
@@ -626,7 +634,7 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
ZERO_STRUCT(u_handle);
ou.in.domain_handle = &d_handle;
ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- ou.in.rid = ln.out.rids.ids[0];
+ ou.in.rid = ln.out.rids->ids[0];
ou.out.user_handle = &u_handle;
/* 6. do a samr_OpenUser to get a user handle */
diff --git a/source4/libnet/libnet_samsync_ldb.c b/source4/libnet/libnet_samsync_ldb.c
index 8b7dd1f598..160b4b3e19 100644
--- a/source4/libnet/libnet_samsync_ldb.c
+++ b/source4/libnet/libnet_samsync_ldb.c
@@ -384,7 +384,11 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
}
ADD_OR_DEL(string, "comment", comment.string);
- ADD_OR_DEL(string, "userParameters", parameters.string);
+
+ if (samdb_msg_add_parameters(state->sam_ldb, mem_ctx, msg, "userParameters", &user->parameters) != 0) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
ADD_OR_DEL(uint, "countryCode", country_code);
ADD_OR_DEL(uint, "codePage", code_page);
diff --git a/source4/libnet/libnet_user.c b/source4/libnet/libnet_user.c
index c768319452..8606d0856e 100644
--- a/source4/libnet/libnet_user.c
+++ b/source4/libnet/libnet_user.c
@@ -1032,6 +1032,10 @@ static void continue_domain_queried(struct rpc_request *req)
s->user_list.in.resume_handle = &s->resume_index;
s->user_list.in.acct_flags = ACB_NORMAL;
s->user_list.out.resume_handle = &s->resume_index;
+ s->user_list.out.num_entries = talloc(s, uint32_t);
+ if (composite_nomem(s->user_list.out.num_entries, c)) return;
+ s->user_list.out.sam = talloc(s, struct samr_SamArray *);
+ if (composite_nomem(s->user_list.out.sam, c)) return;
/* send the request */
enum_req = dcerpc_samr_EnumDomainUsers_send(s->ctx->samr.pipe, c, &s->user_list);
@@ -1064,6 +1068,10 @@ static void continue_samr_domain_opened(struct composite_context *ctx)
s->user_list.in.resume_handle = &s->resume_index;
s->user_list.in.acct_flags = ACB_NORMAL;
s->user_list.out.resume_handle = &s->resume_index;
+ s->user_list.out.sam = talloc(s, struct samr_SamArray *);
+ if (composite_nomem(s->user_list.out.sam, c)) return;
+ s->user_list.out.num_entries = talloc(s, uint32_t);
+ if (composite_nomem(s->user_list.out.num_entries, c)) return;
/* send the request */
enum_req = dcerpc_samr_EnumDomainUsers_send(s->ctx->samr.pipe, c, &s->user_list);
@@ -1102,15 +1110,15 @@ static void continue_users_enumerated(struct rpc_request *req)
/* get enumerated accounts counter and resume handle (the latter allows
making subsequent call to continue enumeration) */
s->resume_index = *s->user_list.out.resume_handle;
- s->count = s->user_list.out.num_entries;
+ s->count = *s->user_list.out.num_entries;
/* prepare returned user accounts array */
- s->users = talloc_array(c, struct userlist, s->user_list.out.sam->count);
+ s->users = talloc_array(c, struct userlist, (*s->user_list.out.sam)->count);
if (composite_nomem(s->users, c)) return;
- for (i = 0; i < s->user_list.out.sam->count; i++) {
+ for (i = 0; i < (*s->user_list.out.sam)->count; i++) {
struct dom_sid *user_sid;
- struct samr_SamEntry *entry = &s->user_list.out.sam->entries[i];
+ struct samr_SamEntry *entry = &(*s->user_list.out.sam)->entries[i];
struct dom_sid *domain_sid = (*s->query_domain.out.info)->domain.sid;
/* construct user sid from returned rid and queried domain sid */
diff --git a/source4/libnet/userinfo.c b/source4/libnet/userinfo.c
index e8b6b090c7..710154d41e 100644
--- a/source4/libnet/userinfo.c
+++ b/source4/libnet/userinfo.c
@@ -82,8 +82,8 @@ static void continue_userinfo_lookup(struct rpc_request *req)
if (s->monitor_fn) {
msg.type = mon_SamrLookupName;
msg_lookup = talloc(s, struct msg_rpc_lookup_name);
- msg_lookup->rid = s->lookup.out.rids.ids;
- msg_lookup->count = s->lookup.out.rids.count;
+ msg_lookup->rid = s->lookup.out.rids->ids;
+ msg_lookup->count = s->lookup.out.rids->count;
msg.data = (void*)msg_lookup;
msg.data_size = sizeof(*msg_lookup);
@@ -93,7 +93,7 @@ static void continue_userinfo_lookup(struct rpc_request *req)
/* have we actually got name resolved
- we're looking for only one at the moment */
- if (s->lookup.out.rids.count == 0) {
+ if (s->lookup.out.rids->count == 0) {
composite_error(c, NT_STATUS_NO_SUCH_USER);
}
@@ -102,7 +102,7 @@ static void continue_userinfo_lookup(struct rpc_request *req)
/* prepare parameters for LookupNames */
s->openuser.in.domain_handle = &s->domain_handle;
s->openuser.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- s->openuser.in.rid = s->lookup.out.rids.ids[0];
+ s->openuser.in.rid = s->lookup.out.rids->ids[0];
s->openuser.out.user_handle = &s->user_handle;
/* send request */
@@ -151,6 +151,8 @@ static void continue_userinfo_openuser(struct rpc_request *req)
/* prepare parameters for QueryUserInfo call */
s->queryuserinfo.in.user_handle = &s->user_handle;
s->queryuserinfo.in.level = s->level;
+ s->queryuserinfo.out.info = talloc(s, union samr_UserInfo *);
+ if (composite_nomem(s->queryuserinfo.out.info, c)) return;
/* queue rpc call, set event handling and new state */
queryuser_req = dcerpc_samr_QueryUserInfo_send(s->pipe, c, &s->queryuserinfo);
@@ -184,7 +186,7 @@ static void continue_userinfo_getuser(struct rpc_request *req)
return;
}
- s->info = talloc_steal(s, s->queryuserinfo.out.info);
+ s->info = talloc_steal(s, *(s->queryuserinfo.out.info));
/* issue a monitor message */
if (s->monitor_fn) {
@@ -297,6 +299,10 @@ struct composite_context *libnet_rpc_userinfo_send(struct dcerpc_pipe *p,
s->lookup.in.num_names = 1;
s->lookup.in.names = talloc_array(s, struct lsa_String, 1);
if (composite_nomem(s->lookup.in.names, c)) return c;
+ s->lookup.out.rids = talloc_zero(s, struct samr_Ids);
+ s->lookup.out.types = talloc_zero(s, struct samr_Ids);
+ if (composite_nomem(s->lookup.out.rids, c)) return c;
+ if (composite_nomem(s->lookup.out.types, c)) return c;
s->lookup.in.names[0].string = talloc_strdup(s, io->in.username);
if (composite_nomem(s->lookup.in.names[0].string, c)) return c;
diff --git a/source4/libnet/userman.c b/source4/libnet/userman.c
index 398d9f2cb0..c638d8af32 100644
--- a/source4/libnet/userman.c
+++ b/source4/libnet/userman.c
@@ -236,12 +236,12 @@ static void continue_userdel_name_found(struct rpc_request *req)
/* what to do when there's no user account to delete
and what if there's more than one rid resolved */
- if (!s->lookupname.out.rids.count) {
+ if (!s->lookupname.out.rids->count) {
c->status = NT_STATUS_NO_SUCH_USER;
composite_error(c, c->status);
return;
- } else if (!s->lookupname.out.rids.count > 1) {
+ } else if (!s->lookupname.out.rids->count > 1) {
c->status = NT_STATUS_INVALID_ACCOUNT_NAME;
composite_error(c, c->status);
return;
@@ -251,8 +251,8 @@ static void continue_userdel_name_found(struct rpc_request *req)
if (s->monitor_fn) {
struct msg_rpc_lookup_name msg_lookup;
- msg_lookup.rid = s->lookupname.out.rids.ids;
- msg_lookup.count = s->lookupname.out.rids.count;
+ msg_lookup.rid = s->lookupname.out.rids->ids;
+ msg_lookup.count = s->lookupname.out.rids->count;
msg.type = mon_SamrLookupName;
msg.data = (void*)&msg_lookup;
@@ -262,7 +262,7 @@ static void continue_userdel_name_found(struct rpc_request *req)
/* prepare the arguments for rpc call */
s->openuser.in.domain_handle = &s->domain_handle;
- s->openuser.in.rid = s->lookupname.out.rids.ids[0];
+ s->openuser.in.rid = s->lookupname.out.rids->ids[0];
s->openuser.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
s->openuser.out.user_handle = &s->user_handle;
@@ -393,6 +393,10 @@ struct composite_context *libnet_rpc_userdel_send(struct dcerpc_pipe *p,
s->lookupname.in.num_names = 1;
s->lookupname.in.names = talloc_zero(s, struct lsa_String);
s->lookupname.in.names->string = io->in.username;
+ s->lookupname.out.rids = talloc_zero(s, struct samr_Ids);
+ s->lookupname.out.types = talloc_zero(s, struct samr_Ids);
+ if (composite_nomem(s->lookupname.out.rids, c)) return c;
+ if (composite_nomem(s->lookupname.out.types, c)) return c;
/* send the request */
lookup_req = dcerpc_samr_LookupNames_send(p, c, &s->lookupname);
@@ -500,12 +504,12 @@ static void continue_usermod_name_found(struct rpc_request *req)
/* what to do when there's no user account to delete
and what if there's more than one rid resolved */
- if (!s->lookupname.out.rids.count) {
+ if (!s->lookupname.out.rids->count) {
c->status = NT_STATUS_NO_SUCH_USER;
composite_error(c, c->status);
return;
- } else if (!s->lookupname.out.rids.count > 1) {
+ } else if (!s->lookupname.out.rids->count > 1) {
c->status = NT_STATUS_INVALID_ACCOUNT_NAME;
composite_error(c, c->status);
return;
@@ -515,8 +519,8 @@ static void continue_usermod_name_found(struct rpc_request *req)
if (s->monitor_fn) {
struct msg_rpc_lookup_name msg_lookup;
- msg_lookup.rid = s->lookupname.out.rids.ids;
- msg_lookup.count = s->lookupname.out.rids.count;
+ msg_lookup.rid = s->lookupname.out.rids->ids;
+ msg_lookup.count = s->lookupname.out.rids->count;
msg.type = mon_SamrLookupName;
msg.data = (void*)&msg_lookup;
@@ -526,7 +530,7 @@ static void continue_usermod_name_found(struct rpc_request *req)
/* prepare the next rpc call */
s->openuser.in.domain_handle = &s->domain_handle;
- s->openuser.in.rid = s->lookupname.out.rids.ids[0];
+ s->openuser.in.rid = s->lookupname.out.rids->ids[0];
s->openuser.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
s->openuser.out.user_handle = &s->user_handle;
@@ -679,6 +683,9 @@ static NTSTATUS usermod_change(struct composite_context *c,
if (!do_set) {
s->queryuser.in.user_handle = &s->user_handle;
s->queryuser.in.level = level;
+ s->queryuser.out.info = talloc(s, union samr_UserInfo *);
+ if (composite_nomem(s->queryuser.out.info, c)) return;
+
/* send query user info request to retrieve complete data of
a particular info level */
@@ -751,7 +758,7 @@ static void continue_usermod_user_queried(struct rpc_request *req)
/* get returned user data and make a change (potentially one
of many) */
- s->info = *s->queryuser.out.info;
+ s->info = *(*s->queryuser.out.info);
usermod_setfields(s, &level, i, true);
@@ -834,6 +841,10 @@ struct composite_context *libnet_rpc_usermod_send(struct dcerpc_pipe *p,
s->lookupname.in.num_names = 1;
s->lookupname.in.names = talloc_zero(s, struct lsa_String);
s->lookupname.in.names->string = io->in.username;
+ s->lookupname.out.rids = talloc_zero(s, struct samr_Ids);
+ s->lookupname.out.types = talloc_zero(s, struct samr_Ids);
+ if (composite_nomem(s->lookupname.out.rids, c)) return c;
+ if (composite_nomem(s->lookupname.out.types, c)) return c;
/* send the rpc request */
lookup_req = dcerpc_samr_LookupNames_send(p, c, &s->lookupname);
diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk
index b2b9f2e7a7..97da760832 100644
--- a/source4/librpc/config.mk
+++ b/source4/librpc/config.mk
@@ -8,7 +8,7 @@ dcerpcsrcdir = $(librpcsrcdir)/rpc
PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTALLOC LIBSAMBA-UTIL CHARSET \
LIBSAMBA-HOSTCONFIG
-LIBNDR_OBJ_FILES = $(addprefix $(ndrsrcdir)/, ndr_string.o) ../librpc/ndr/ndr_basic.o ../librpc/ndr/uuid.o ../librpc/ndr/ndr.o
+LIBNDR_OBJ_FILES = $(addprefix $(ndrsrcdir)/, ndr_string.o) ../librpc/ndr/ndr_basic.o ../librpc/ndr/uuid.o ../librpc/ndr/ndr.o $(gen_ndrsrcdir)/ndr_misc.o ../librpc/ndr/ndr_misc.o
PC_FILES += ../librpc/ndr.pc
LIBNDR_VERSION = 0.0.1
@@ -18,6 +18,7 @@ LIBNDR_SOVERSION = 0
################################################
PUBLIC_HEADERS += ../librpc/ndr/libndr.h
+PUBLIC_HEADERS += $(gen_ndrsrcdir)/misc.h $(gen_ndrsrcdir)/ndr_misc.h
#################################
# Start BINARY ndrdump
@@ -49,17 +50,26 @@ PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBNDR
NDR_COMPRESSION_OBJ_FILES = ../librpc/ndr/ndr_compression.o
[SUBSYSTEM::NDR_SECURITY]
-PUBLIC_DEPENDENCIES = NDR_MISC LIBSECURITY
+PUBLIC_DEPENDENCIES = LIBNDR LIBSECURITY
+
+NDR_SECURITY_OBJ_FILES = $(gen_ndrsrcdir)/ndr_security.o \
+ ../librpc/ndr/ndr_sec_helper.o \
+ $(gen_ndrsrcdir)/ndr_dom_sid.o \
+ $(ndrsrcdir)/ndr_dom_sid.o
-NDR_SECURITY_OBJ_FILES = $(gen_ndrsrcdir)/ndr_security.o $(ndrsrcdir)/ndr_sec_helper.o
+PUBLIC_HEADERS += $(addprefix $(gen_ndrsrcdir)/, security.h dom_sid.h)
-PUBLIC_HEADERS += $(gen_ndrsrcdir)/security.h
[SUBSYSTEM::NDR_AUDIOSRV]
PUBLIC_DEPENDENCIES = LIBNDR
NDR_AUDIOSRV_OBJ_FILES = $(gen_ndrsrcdir)/ndr_audiosrv.o
+[SUBSYSTEM::NDR_NAMED_PIPE_AUTH]
+PUBLIC_DEPENDENCIES = LIBNDR
+
+NDR_NAMED_PIPE_AUTH_OBJ_FILES = $(gen_ndrsrcdir)/ndr_named_pipe_auth.o
+
[SUBSYSTEM::NDR_DNSSERVER]
PUBLIC_DEPENDENCIES = LIBNDR
@@ -100,13 +110,6 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY
NDR_EFS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_efs.o
-[SUBSYSTEM::NDR_MISC]
-PUBLIC_DEPENDENCIES = LIBNDR
-
-NDR_MISC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_misc.o ../librpc/ndr/ndr_misc.o
-
-PUBLIC_HEADERS += $(gen_ndrsrcdir)/misc.h $(gen_ndrsrcdir)/ndr_misc.h
-
[SUBSYSTEM::NDR_ROT]
PUBLIC_DEPENDENCIES = LIBNDR NDR_ORPC
@@ -120,7 +123,7 @@ NDR_LSA_OBJ_FILES = $(gen_ndrsrcdir)/ndr_lsa.o
PUBLIC_HEADERS += $(gen_ndrsrcdir)/lsa.h
[SUBSYSTEM::NDR_DFS]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC
+PUBLIC_DEPENDENCIES = LIBNDR
NDR_DFS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_dfs.o
@@ -140,7 +143,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_COMPRESSION NDR_SECURITY NDR_SAMR ASN1_UTIL
NDR_DRSUAPI_OBJ_FILES = $(gen_ndrsrcdir)/ndr_drsuapi.o ../librpc/ndr/ndr_drsuapi.o
[SUBSYSTEM::NDR_DRSBLOBS]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC NDR_DRSUAPI
+PUBLIC_DEPENDENCIES = LIBNDR NDR_DRSUAPI
NDR_DRSBLOBS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_drsblobs.o ../librpc/ndr/ndr_drsblobs.o
@@ -160,14 +163,14 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY
NDR_UNIXINFO_OBJ_FILES = $(gen_ndrsrcdir)/ndr_unixinfo.o
[SUBSYSTEM::NDR_SAMR]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC NDR_LSA NDR_SECURITY
+PUBLIC_DEPENDENCIES = LIBNDR NDR_LSA NDR_SECURITY
NDR_SAMR_OBJ_FILES = $(gen_ndrsrcdir)/ndr_samr.o
PUBLIC_HEADERS += $(addprefix $(librpcsrcdir)/, gen_ndr/samr.h gen_ndr/ndr_samr.h gen_ndr/ndr_samr_c.h)
[SUBSYSTEM::NDR_NFS4ACL]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC NDR_SECURITY
+PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY
NDR_NFS4ACL_OBJ_FILES = $(gen_ndrsrcdir)/ndr_nfs4acl.o
@@ -183,7 +186,7 @@ NDR_SPOOLSS_BUF_OBJ_FILES = $(ndrsrcdir)/ndr_spoolss_buf.o
$(eval $(call proto_header_template,$(ndrsrcdir)/ndr_spoolss_buf.h,$(NDR_SPOOLSS_BUF_OBJ_FILES:.o=.c)))
[SUBSYSTEM::NDR_WKSSVC]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_SRVSVC NDR_MISC NDR_SECURITY
+PUBLIC_DEPENDENCIES = LIBNDR NDR_SRVSVC NDR_SECURITY
NDR_WKSSVC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_wkssvc.o
@@ -193,7 +196,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_SVCCTL NDR_SECURITY
NDR_SRVSVC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_srvsvc.o
[SUBSYSTEM::NDR_SVCCTL]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC
+PUBLIC_DEPENDENCIES = LIBNDR
NDR_SVCCTL_OBJ_FILES = $(gen_ndrsrcdir)/ndr_svcctl.o
@@ -212,7 +215,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_LSA
NDR_EVENTLOG_OBJ_FILES = $(gen_ndrsrcdir)/ndr_eventlog.o
[SUBSYSTEM::NDR_EPMAPPER]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC
+PUBLIC_DEPENDENCIES = LIBNDR
NDR_EPMAPPER_OBJ_FILES = $(gen_ndrsrcdir)/ndr_epmapper.o
@@ -222,7 +225,7 @@ PUBLIC_DEPENDENCIES = LIBNDR
NDR_DBGIDL_OBJ_FILES = $(gen_ndrsrcdir)/ndr_dbgidl.o
[SUBSYSTEM::NDR_DSSETUP]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC
+PUBLIC_DEPENDENCIES = LIBNDR
NDR_DSSETUP_OBJ_FILES = $(gen_ndrsrcdir)/ndr_dssetup.o
@@ -237,7 +240,7 @@ PUBLIC_DEPENDENCIES = LIBNDR
NDR_WINS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_wins.o
[SUBSYSTEM::NDR_WINREG]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_INITSHUTDOWN NDR_SECURITY NDR_MISC
+PUBLIC_DEPENDENCIES = LIBNDR NDR_INITSHUTDOWN NDR_SECURITY
NDR_WINREG_OBJ_FILES = $(gen_ndrsrcdir)/ndr_winreg.o
@@ -262,12 +265,12 @@ PUBLIC_DEPENDENCIES = LIBNDR
NDR_ORPC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_orpc.o ../librpc/ndr/ndr_orpc.o
[SUBSYSTEM::NDR_OXIDRESOLVER]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_ORPC NDR_MISC
+PUBLIC_DEPENDENCIES = LIBNDR NDR_ORPC
NDR_OXIDRESOLVER_OBJ_FILES = $(gen_ndrsrcdir)/ndr_oxidresolver.o
[SUBSYSTEM::NDR_REMACT]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_ORPC NDR_MISC
+PUBLIC_DEPENDENCIES = LIBNDR NDR_ORPC
NDR_REMACT_OBJ_FILES = $(gen_ndrsrcdir)/ndr_remact.o
@@ -299,7 +302,7 @@ NDR_NTSVCS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_ntsvcs.o
[SUBSYSTEM::NDR_NETLOGON]
PUBLIC_DEPENDENCIES = LIBNDR NDR_SAMR NDR_LSA NDR_SECURITY
-NDR_NETLOGON_OBJ_FILES = $(gen_ndrsrcdir)/ndr_netlogon.o
+NDR_NETLOGON_OBJ_FILES = $(gen_ndrsrcdir)/ndr_netlogon.o ../librpc/ndr/ndr_netlogon.o
PUBLIC_HEADERS += $(addprefix $(librpcsrcdir)/, gen_ndr/netlogon.h)
@@ -339,7 +342,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT
NDR_SCHANNEL_OBJ_FILES = $(gen_ndrsrcdir)/ndr_schannel.o
[SUBSYSTEM::NDR_NBT]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC NDR_NBT_BUF NDR_SVCCTL NDR_SECURITY NDR_SAMR LIBCLI_NDR_NETLOGON
+PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT_BUF NDR_SVCCTL NDR_SECURITY NDR_SAMR LIBCLI_NDR_NETLOGON
NDR_NBT_OBJ_FILES = $(gen_ndrsrcdir)/ndr_nbt.o
@@ -362,7 +365,7 @@ NDR_WINBIND_OBJ_FILES = $(gen_ndrsrcdir)/ndr_winbind.o
#PUBLIC_HEADERS += $(gen_ndrsrcdir)/winbind.h
$(librpcsrcdir)/idl-deps:
- $(PERL) $(librpcsrcdir)/idl-deps.pl $(filter-out ../librpc/idl/security.idl,$(wildcard $(librpcsrcdir)/idl/*.idl ../librpc/idl/*.idl)) >$@
+ $(PERL) $(librpcsrcdir)/idl-deps.pl $(wildcard $(librpcsrcdir)/idl/*.idl ../librpc/idl/*.idl) >$@
clean::
rm -f $(librpcsrcdir)/idl-deps
@@ -377,7 +380,7 @@ $(gen_ndrsrcdir)/tables.c: $(IDL_NDR_PARSE_H_FILES)
[SUBSYSTEM::NDR_TABLE]
PUBLIC_DEPENDENCIES = \
NDR_AUDIOSRV NDR_ECHO NDR_DCERPC \
- NDR_DSBACKUP NDR_EFS NDR_MISC NDR_LSA NDR_DFS NDR_DRSUAPI \
+ 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 \
@@ -386,7 +389,7 @@ PUBLIC_DEPENDENCIES = \
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_DCOM NDR_WMI
+ NDR_DCOM NDR_WMI NDR_NAMED_PIPE_AUTH
NDR_TABLE_OBJ_FILES = ../librpc/ndr/ndr_table.o $(gen_ndrsrcdir)/tables.o
@@ -588,7 +591,7 @@ PUBLIC_DEPENDENCIES = dcerpc NDR_KEYSVC
RPC_NDR_KEYSVC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_keysvc_c.o
[SUBSYSTEM::NDR_DCERPC]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC
+PUBLIC_DEPENDENCIES = LIBNDR
NDR_DCERPC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_dcerpc.o
@@ -626,7 +629,7 @@ PUBLIC_HEADERS += $(addprefix $(librpcsrcdir)/, rpc/dcerpc.h \
[PYTHON::python_dcerpc]
LIBRARY_REALNAME = samba/dcerpc/base.$(SHLIBEXT)
-PUBLIC_DEPENDENCIES = LIBCLI_SMB NDR_MISC LIBSAMBA-UTIL LIBSAMBA-HOSTCONFIG dcerpc_samr RPC_NDR_LSA DYNCONFIG swig_credentials param
+PUBLIC_DEPENDENCIES = LIBCLI_SMB LIBSAMBA-UTIL LIBSAMBA-HOSTCONFIG dcerpc_samr RPC_NDR_LSA DYNCONFIG swig_credentials param
python_dcerpc_OBJ_FILES = $(dcerpcsrcdir)/pyrpc.o
@@ -729,9 +732,15 @@ PRIVATE_DEPENDENCIES = RPC_NDR_DRSUAPI PYTALLOC param swig_credentials python_dc
python_drsuapi_OBJ_FILES = $(gen_ndrsrcdir)/py_drsuapi.o
+[PYTHON::python_dcerpc_dom_sid]
+LIBRARY_REALNAME = samba/dcerpc/dom_sid.$(SHLIBEXT)
+PRIVATE_DEPENDENCIES = PYTALLOC python_dcerpc_misc python_dcerpc
+
+python_dcerpc_dom_sid_OBJ_FILES = $(gen_ndrsrcdir)/py_dom_sid.o
+
[PYTHON::python_dcerpc_security]
LIBRARY_REALNAME = samba/dcerpc/security.$(SHLIBEXT)
-PRIVATE_DEPENDENCIES = PYTALLOC python_dcerpc_misc python_dcerpc
+PRIVATE_DEPENDENCIES = PYTALLOC python_dcerpc_misc python_dcerpc_dom_sid python_dcerpc
python_dcerpc_security_OBJ_FILES = $(gen_ndrsrcdir)/py_security.o
diff --git a/source4/librpc/idl/dom_sid.idl b/source4/librpc/idl/dom_sid.idl
new file mode 100644
index 0000000000..80df11dbfe
--- /dev/null
+++ b/source4/librpc/idl/dom_sid.idl
@@ -0,0 +1,42 @@
+/*
+ use the same structure for dom_sid2 as dom_sid. A dom_sid2 is really
+ just a dom sid, but with the sub_auths represented as a conformant
+ array. As with all in-structure conformant arrays, the array length
+ is placed before the start of the structure. That's what gives rise
+ to the extra num_auths elemenent. We don't want the Samba code to
+ have to bother with such esoteric NDR details, so its easier to just
+ define it as a dom_sid and use pidl magic to make it all work. It
+ just means you need to mark a sid as a "dom_sid2" in the IDL when you
+ know it is of the conformant array variety
+*/
+cpp_quote("#define dom_sid2 dom_sid")
+
+/* same struct as dom_sid but inside a 28 bytes fixed buffer in NDR */
+cpp_quote("#define dom_sid28 dom_sid")
+
+/* same struct as dom_sid but in a variable byte buffer, which is maybe empty in NDR */
+cpp_quote("#define dom_sid0 dom_sid")
+
+[
+ pointer_default(unique)
+]
+interface dom_sid
+{
+ /* a domain SID. Note that unlike Samba3 this contains a pointer,
+ so you can't copy them using assignment */
+ typedef [public,gensize,noprint,noejs,nosize] struct {
+ uint8 sid_rev_num; /**< SID revision number */
+ [range(0,15)] int8 num_auths; /**< Number of sub-authorities */
+ uint8 id_auth[6]; /**< Identifier Authority */
+ uint32 sub_auths[num_auths];
+ } dom_sid;
+
+ /* id used to identify a endpoint, possibly in a cluster */
+ typedef [public] struct {
+ hyper id;
+ uint32 id2;
+ uint32 node;
+ } server_id;
+
+}
+
diff --git a/source4/librpc/idl/samr.idl b/source4/librpc/idl/samr.idl
deleted file mode 100644
index 47882dfb84..0000000000
--- a/source4/librpc/idl/samr.idl
+++ /dev/null
@@ -1,1424 +0,0 @@
-#include "idl_types.h"
-
-/*
- samr interface definition
-*/
-import "misc.idl", "lsa.idl", "security.idl";
-
-/*
- Thanks to Todd Sabin for some information from his samr.idl in acltools
-*/
-
-[ uuid("12345778-1234-abcd-ef00-0123456789ac"),
- version(1.0),
- endpoint("ncacn_np:[\\pipe\\samr]","ncacn_ip_tcp:", "ncalrpc:"),
- pointer_default(unique)
-] interface samr
-{
- typedef bitmap security_secinfo security_secinfo;
-
- /* account control (acct_flags) bits */
- typedef [public,bitmap32bit] bitmap {
- ACB_DISABLED = 0x00000001, /* 1 = User account disabled */
- ACB_HOMDIRREQ = 0x00000002, /* 1 = Home directory required */
- ACB_PWNOTREQ = 0x00000004, /* 1 = User password not required */
- ACB_TEMPDUP = 0x00000008, /* 1 = Temporary duplicate account */
- ACB_NORMAL = 0x00000010, /* 1 = Normal user account */
- ACB_MNS = 0x00000020, /* 1 = MNS logon user account */
- ACB_DOMTRUST = 0x00000040, /* 1 = Interdomain trust account */
- ACB_WSTRUST = 0x00000080, /* 1 = Workstation trust account */
- ACB_SVRTRUST = 0x00000100, /* 1 = Server trust account */
- ACB_PWNOEXP = 0x00000200, /* 1 = User password does not expire */
- ACB_AUTOLOCK = 0x00000400, /* 1 = Account auto locked */
- ACB_ENC_TXT_PWD_ALLOWED = 0x00000800, /* 1 = Encryped text password is allowed */
- ACB_SMARTCARD_REQUIRED = 0x00001000, /* 1 = Smart Card required */
- ACB_TRUSTED_FOR_DELEGATION = 0x00002000, /* 1 = Trusted for Delegation */
- ACB_NOT_DELEGATED = 0x00004000, /* 1 = Not delegated */
- ACB_USE_DES_KEY_ONLY = 0x00008000, /* 1 = Use DES key only */
- ACB_DONT_REQUIRE_PREAUTH = 0x00010000, /* 1 = Preauth not required */
- ACB_PW_EXPIRED = 0x00020000, /* 1 = Password Expired */
- ACB_NO_AUTH_DATA_REQD = 0x00080000 /* 1 = No authorization data required */
- } samr_AcctFlags;
-
- typedef [bitmap32bit] bitmap {
- SAMR_ACCESS_CONNECT_TO_SERVER = 0x00000001,
- SAMR_ACCESS_SHUTDOWN_SERVER = 0x00000002,
- SAMR_ACCESS_INITIALIZE_SERVER = 0x00000004,
- SAMR_ACCESS_CREATE_DOMAIN = 0x00000008,
- SAMR_ACCESS_ENUM_DOMAINS = 0x00000010,
- SAMR_ACCESS_OPEN_DOMAIN = 0x00000020
- } samr_ConnectAccessMask;
-
- typedef [bitmap32bit] bitmap {
- SAMR_USER_ACCESS_GET_NAME_ETC = 0x00000001,
- SAMR_USER_ACCESS_GET_LOCALE = 0x00000002,
- SAMR_USER_ACCESS_SET_LOC_COM = 0x00000004,
- SAMR_USER_ACCESS_GET_LOGONINFO = 0x00000008,
- SAMR_USER_ACCESS_GET_ATTRIBUTES = 0x00000010,
- SAMR_USER_ACCESS_SET_ATTRIBUTES = 0x00000020,
- SAMR_USER_ACCESS_CHANGE_PASSWORD = 0x00000040,
- SAMR_USER_ACCESS_SET_PASSWORD = 0x00000080,
- SAMR_USER_ACCESS_GET_GROUPS = 0x00000100,
- SAMR_USER_ACCESS_GET_GROUP_MEMBERSHIP = 0x00000200,
- SAMR_USER_ACCESS_CHANGE_GROUP_MEMBERSHIP = 0x00000400
- } samr_UserAccessMask;
-
- typedef [bitmap32bit] bitmap {
- SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 = 0x00000001,
- SAMR_DOMAIN_ACCESS_SET_INFO_1 = 0x00000002,
- SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 = 0x00000004,
- SAMR_DOMAIN_ACCESS_SET_INFO_2 = 0x00000008,
- SAMR_DOMAIN_ACCESS_CREATE_USER = 0x00000010,
- SAMR_DOMAIN_ACCESS_CREATE_GROUP = 0x00000020,
- SAMR_DOMAIN_ACCESS_CREATE_ALIAS = 0x00000040,
- SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS = 0x00000080,
- SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS = 0x00000100,
- SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT = 0x00000200,
- SAMR_DOMAIN_ACCESS_SET_INFO_3 = 0x00000400
- } samr_DomainAccessMask;
-
- typedef [bitmap32bit] bitmap {
- SAMR_GROUP_ACCESS_LOOKUP_INFO = 0x00000001,
- SAMR_GROUP_ACCESS_SET_INFO = 0x00000002,
- SAMR_GROUP_ACCESS_ADD_MEMBER = 0x00000004,
- SAMR_GROUP_ACCESS_REMOVE_MEMBER = 0x00000008,
- SAMR_GROUP_ACCESS_GET_MEMBERS = 0x00000010
- } samr_GroupAccessMask;
-
- typedef [bitmap32bit] bitmap {
- SAMR_ALIAS_ACCESS_ADD_MEMBER = 0x00000001,
- SAMR_ALIAS_ACCESS_REMOVE_MEMBER = 0x00000002,
- SAMR_ALIAS_ACCESS_GET_MEMBERS = 0x00000004,
- SAMR_ALIAS_ACCESS_LOOKUP_INFO = 0x00000008,
- SAMR_ALIAS_ACCESS_SET_INFO = 0x00000010
- } samr_AliasAccessMask;
-
- /******************/
- /* Function: 0x00 */
- NTSTATUS samr_Connect (
- /* notice the lack of [string] */
- [in,unique] uint16 *system_name,
- [in] samr_ConnectAccessMask access_mask,
- [out,ref] policy_handle *connect_handle
- );
-
-
- /******************/
- /* Function: 0x01 */
- [public] NTSTATUS samr_Close (
- [in,out,ref] policy_handle *handle
- );
-
- /******************/
- /* Function: 0x02 */
-
- NTSTATUS samr_SetSecurity (
- [in,ref] policy_handle *handle,
- [in] security_secinfo sec_info,
- [in,ref] sec_desc_buf *sdbuf
- );
-
- /******************/
- /* Function: 0x03 */
-
- NTSTATUS samr_QuerySecurity (
- [in,ref] policy_handle *handle,
- [in] security_secinfo sec_info,
- [out,unique] sec_desc_buf *sdbuf
- );
-
- /******************/
- /* Function: 0x04 */
-
- /*
- shutdown the SAM - once you call this the SAM will be dead
- */
- NTSTATUS samr_Shutdown (
- [in,ref] policy_handle *connect_handle
- );
-
- /******************/
- /* Function: 0x05 */
- NTSTATUS samr_LookupDomain (
- [in,ref] policy_handle *connect_handle,
- [in,ref] lsa_String *domain_name,
- [out,unique] dom_sid2 *sid
- );
-
-
- /******************/
- /* Function: 0x06 */
-
- typedef struct {
- uint32 idx;
- lsa_String name;
- } samr_SamEntry;
-
- typedef struct {
- uint32 count;
- [size_is(count)] samr_SamEntry *entries;
- } samr_SamArray;
-
- NTSTATUS samr_EnumDomains (
- [in,ref] policy_handle *connect_handle,
- [in,out,ref] uint32 *resume_handle,
- [in] uint32 buf_size,
- [out,unique] samr_SamArray *sam,
- [out] uint32 num_entries
- );
-
-
- /************************/
- /* Function 0x07 */
- [public] NTSTATUS samr_OpenDomain(
- [in,ref] policy_handle *connect_handle,
- [in] samr_DomainAccessMask access_mask,
- [in,ref] dom_sid2 *sid,
- [out,ref] policy_handle *domain_handle
- );
-
- /************************/
- /* Function 0x08 */
- /* server roles */
- typedef [v1_enum] enum {
- SAMR_ROLE_STANDALONE = 0,
- SAMR_ROLE_DOMAIN_MEMBER = 1,
- SAMR_ROLE_DOMAIN_BDC = 2,
- SAMR_ROLE_DOMAIN_PDC = 3
- } samr_Role;
-
- /* password properties flags */
- typedef [public,bitmap32bit] bitmap {
- DOMAIN_PASSWORD_COMPLEX = 0x00000001,
- DOMAIN_PASSWORD_NO_ANON_CHANGE = 0x00000002,
- DOMAIN_PASSWORD_NO_CLEAR_CHANGE = 0x00000004,
- DOMAIN_PASSWORD_LOCKOUT_ADMINS = 0x00000008,
- DOMAIN_PASSWORD_STORE_CLEARTEXT = 0x00000010,
- DOMAIN_REFUSE_PASSWORD_CHANGE = 0x00000020
- } samr_PasswordProperties;
-
- typedef struct {
- uint16 min_password_length;
- uint16 password_history_length;
- samr_PasswordProperties password_properties;
- /* yes, these are signed. They are in negative 100ns */
- dlong max_password_age;
- dlong min_password_age;
- } samr_DomInfo1;
-
- typedef struct {
- NTTIME force_logoff_time;
- lsa_String oem_information; /* comment */
- lsa_String domain_name;
- lsa_String primary; /* PDC name if this is a BDC */
- udlong sequence_num;
- uint32 unknown2;
- samr_Role role;
- uint32 unknown3;
- uint32 num_users;
- uint32 num_groups;
- uint32 num_aliases;
- } samr_DomGeneralInformation;
-
- typedef struct {
- NTTIME force_logoff_time;
- } samr_DomInfo3;
-
- typedef struct {
- lsa_String oem_information; /* comment */
- } samr_DomOEMInformation;
-
- typedef struct {
- lsa_String domain_name;
- } samr_DomInfo5;
-
- typedef struct {
- lsa_String primary;
- } samr_DomInfo6;
-
- typedef struct {
- samr_Role role;
- } samr_DomInfo7;
-
- typedef struct {
- hyper sequence_num;
- NTTIME domain_create_time;
- } samr_DomInfo8;
-
- typedef struct {
- uint32 unknown; /* w2k3 returns 1 */
- } samr_DomInfo9;
-
- typedef struct {
- samr_DomGeneralInformation general;
- hyper lockout_duration;
- hyper lockout_window;
- uint16 lockout_threshold;
- } samr_DomGeneralInformation2;
-
- typedef struct {
- hyper lockout_duration;
- hyper lockout_window;
- uint16 lockout_threshold;
- } samr_DomInfo12;
-
- typedef struct {
- hyper sequence_num;
- NTTIME domain_create_time;
- uint32 unknown1;
- uint32 unknown2;
- } samr_DomInfo13;
-
- typedef [switch_type(uint16)] union {
- [case(1)] samr_DomInfo1 info1;
- [case(2)] samr_DomGeneralInformation general;
- [case(3)] samr_DomInfo3 info3;
- [case(4)] samr_DomOEMInformation oem;
- [case(5)] samr_DomInfo5 info5;
- [case(6)] samr_DomInfo6 info6;
- [case(7)] samr_DomInfo7 info7;
- [case(8)] samr_DomInfo8 info8;
- [case(9)] samr_DomInfo9 info9;
- [case(11)] samr_DomGeneralInformation2 general2;
- [case(12)] samr_DomInfo12 info12;
- [case(13)] samr_DomInfo13 info13;
- } samr_DomainInfo;
-
- NTSTATUS samr_QueryDomainInfo(
- [in,ref] policy_handle *domain_handle,
- [in] uint16 level,
- [out,switch_is(level),unique] samr_DomainInfo *info
- );
-
- /************************/
- /* Function 0x09 */
- /*
- only levels 1, 3, 4, 6, 7, 9, 12 are valid for this
- call in w2k3
- */
- NTSTATUS samr_SetDomainInfo(
- [in,ref] policy_handle *domain_handle,
- [in] uint16 level,
- [in,switch_is(level),ref] samr_DomainInfo *info
- );
-
-
- /************************/
- /* Function 0x0a */
- NTSTATUS samr_CreateDomainGroup(
- [in,ref] policy_handle *domain_handle,
- [in,ref] lsa_String *name,
- [in] samr_GroupAccessMask access_mask,
- [out,ref] policy_handle *group_handle,
- [out,ref] uint32 *rid
- );
-
-
- /************************/
- /* Function 0x0b */
- NTSTATUS samr_EnumDomainGroups(
- [in,ref] policy_handle *domain_handle,
- [in,out,ref] uint32 *resume_handle,
- [in] uint32 max_size,
- [out,unique] samr_SamArray *sam,
- [out] uint32 num_entries
- );
-
- /************************/
- /* Function 0x0c */
- NTSTATUS samr_CreateUser(
- [in,ref] policy_handle *domain_handle,
- [in,ref] lsa_String *account_name,
- [in] samr_UserAccessMask access_mask,
- [out,ref] policy_handle *user_handle,
- [out,ref] uint32 *rid
- );
-
- /************************/
- /* Function 0x0d */
-
-
- /* w2k3 treats max_size as max_users*54 and sets the
- resume_handle as the rid of the last user sent
- */
- const int SAMR_ENUM_USERS_MULTIPLIER = 54;
-
- NTSTATUS samr_EnumDomainUsers(
- [in,ref] policy_handle *domain_handle,
- [in,out,ref] uint32 *resume_handle,
- [in] samr_AcctFlags acct_flags,
- [in] uint32 max_size,
- [out,unique] samr_SamArray *sam,
- [out] uint32 num_entries
- );
-
- /************************/
- /* Function 0x0e */
- NTSTATUS samr_CreateDomAlias(
- [in,ref] policy_handle *domain_handle,
- [in,ref] lsa_String *alias_name,
- [in] samr_AliasAccessMask access_mask,
- [out,ref] policy_handle *alias_handle,
- [out,ref] uint32 *rid
- );
-
- /************************/
- /* Function 0x0f */
- NTSTATUS samr_EnumDomainAliases(
- [in,ref] policy_handle *domain_handle,
- [in,out,ref] uint32 *resume_handle,
- [in] samr_AcctFlags acct_flags,
- [out,unique] samr_SamArray *sam,
- [out] uint32 num_entries
- );
-
- /************************/
- /* Function 0x10 */
-
- typedef struct {
- [range(0,1024)] uint32 count;
- [size_is(count)] uint32 *ids;
- } samr_Ids;
-
- NTSTATUS samr_GetAliasMembership(
- [in,ref] policy_handle *domain_handle,
- [in,ref] lsa_SidArray *sids,
- [out,ref] samr_Ids *rids
- );
-
- /************************/
- /* Function 0x11 */
-
- [public] NTSTATUS samr_LookupNames(
- [in,ref] policy_handle *domain_handle,
- [in,range(0,1000)] uint32 num_names,
- [in,size_is(1000),length_is(num_names)] lsa_String names[],
- [out] samr_Ids rids,
- [out] samr_Ids types
- );
-
-
- /************************/
- /* Function 0x12 */
- NTSTATUS samr_LookupRids(
- [in,ref] policy_handle *domain_handle,
- [in,range(0,1000)] uint32 num_rids,
- [in,size_is(1000),length_is(num_rids)] uint32 rids[],
- [out] lsa_Strings names,
- [out] samr_Ids types
- );
-
- /************************/
- /* Function 0x13 */
- NTSTATUS samr_OpenGroup(
- [in,ref] policy_handle *domain_handle,
- [in] samr_GroupAccessMask access_mask,
- [in] uint32 rid,
- [out,ref] policy_handle *group_handle
- );
-
- /* Group attributes */
- typedef [public,bitmap32bit] bitmap {
- SE_GROUP_MANDATORY = 0x00000001,
- SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002,
- SE_GROUP_ENABLED = 0x00000004,
- SE_GROUP_OWNER = 0x00000008,
- SE_GROUP_USE_FOR_DENY_ONLY = 0x00000010,
- SE_GROUP_RESOURCE = 0x20000000,
- SE_GROUP_LOGON_ID = 0xC0000000
- } samr_GroupAttrs;
-
- /************************/
- /* Function 0x14 */
-
- typedef struct {
- lsa_String name;
- samr_GroupAttrs attributes;
- uint32 num_members;
- lsa_String description;
- } samr_GroupInfoAll;
-
- typedef struct {
- samr_GroupAttrs attributes;
- } samr_GroupInfoAttributes;
-
- typedef struct {
- lsa_String description;
- } samr_GroupInfoDescription;
-
- typedef enum {
- GROUPINFOALL = 1,
- GROUPINFONAME = 2,
- GROUPINFOATTRIBUTES = 3,
- GROUPINFODESCRIPTION = 4,
- GROUPINFOALL2 = 5
- } samr_GroupInfoEnum;
-
- typedef [switch_type(samr_GroupInfoEnum)] union {
- [case(GROUPINFOALL)] samr_GroupInfoAll all;
- [case(GROUPINFONAME)] lsa_String name;
- [case(GROUPINFOATTRIBUTES)] samr_GroupInfoAttributes attributes;
- [case(GROUPINFODESCRIPTION)] lsa_String description;
- [case(GROUPINFOALL2)] samr_GroupInfoAll all2;
- } samr_GroupInfo;
-
- NTSTATUS samr_QueryGroupInfo(
- [in,ref] policy_handle *group_handle,
- [in] samr_GroupInfoEnum level,
- [out,switch_is(level),unique] samr_GroupInfo *info
- );
-
- /************************/
- /* Function 0x15 */
- NTSTATUS samr_SetGroupInfo(
- [in,ref] policy_handle *group_handle,
- [in] samr_GroupInfoEnum level,
- [in,switch_is(level),ref] samr_GroupInfo *info
- );
-
- /************************/
- /* Function 0x16 */
- NTSTATUS samr_AddGroupMember(
- [in,ref] policy_handle *group_handle,
- [in] uint32 rid,
- [in] uint32 flags
- );
-
- /************************/
- /* Function 0x17 */
- NTSTATUS samr_DeleteDomainGroup(
- [in,out,ref] policy_handle *group_handle
- );
-
- /************************/
- /* Function 0x18 */
- NTSTATUS samr_DeleteGroupMember(
- [in,ref] policy_handle *group_handle,
- [in] uint32 rid
- );
-
-
- /************************/
- /* Function 0x19 */
- typedef struct {
- uint32 count;
- [size_is(count)] uint32 *rids;
- [size_is(count)] uint32 *types;
- } samr_RidTypeArray;
-
- NTSTATUS samr_QueryGroupMember(
- [in,ref] policy_handle *group_handle,
- [out,unique] samr_RidTypeArray *rids
- );
-
-
- /************************/
- /* Function 0x1a */
-
- /*
- win2003 seems to accept any data at all for the two integers
- below, and doesn't seem to do anything with them that I can
- see. Weird. I really expected the first integer to be a rid
- and the second to be the attributes for that rid member.
- */
- NTSTATUS samr_SetMemberAttributesOfGroup(
- [in,ref] policy_handle *group_handle,
- [in] uint32 unknown1,
- [in] uint32 unknown2
- );
-
-
- /************************/
- /* Function 0x1b */
- NTSTATUS samr_OpenAlias (
- [in,ref] policy_handle *domain_handle,
- [in] samr_AliasAccessMask access_mask,
- [in] uint32 rid,
- [out,ref] policy_handle *alias_handle
- );
-
-
- /************************/
- /* Function 0x1c */
-
- typedef struct {
- lsa_String name;
- uint32 num_members;
- lsa_String description;
- } samr_AliasInfoAll;
-
- typedef enum {
- ALIASINFOALL = 1,
- ALIASINFONAME = 2,
- ALIASINFODESCRIPTION = 3
- } samr_AliasInfoEnum;
-
- typedef [switch_type(samr_AliasInfoEnum)] union {
- [case(ALIASINFOALL)] samr_AliasInfoAll all;
- [case(ALIASINFONAME)] lsa_String name;
- [case(ALIASINFODESCRIPTION)] lsa_String description;
- } samr_AliasInfo;
-
- NTSTATUS samr_QueryAliasInfo(
- [in,ref] policy_handle *alias_handle,
- [in] samr_AliasInfoEnum level,
- [out,switch_is(level),unique] samr_AliasInfo *info
- );
-
- /************************/
- /* Function 0x1d */
- NTSTATUS samr_SetAliasInfo(
- [in,ref] policy_handle *alias_handle,
- [in] samr_AliasInfoEnum level,
- [in,switch_is(level),ref] samr_AliasInfo *info
- );
-
- /************************/
- /* Function 0x1e */
- NTSTATUS samr_DeleteDomAlias(
- [in,out,ref] policy_handle *alias_handle
- );
-
- /************************/
- /* Function 0x1f */
- NTSTATUS samr_AddAliasMember(
- [in,ref] policy_handle *alias_handle,
- [in,ref] dom_sid2 *sid
- );
-
- /************************/
- /* Function 0x20 */
- NTSTATUS samr_DeleteAliasMember(
- [in,ref] policy_handle *alias_handle,
- [in,ref] dom_sid2 *sid
- );
-
- /************************/
- /* Function 0x21 */
- NTSTATUS samr_GetMembersInAlias(
- [in,ref] policy_handle *alias_handle,
- [out,ref] lsa_SidArray *sids
- );
-
- /************************/
- /* Function 0x22 */
- [public] NTSTATUS samr_OpenUser(
- [in,ref] policy_handle *domain_handle,
- [in] samr_UserAccessMask access_mask,
- [in] uint32 rid,
- [out,ref] policy_handle *user_handle
- );
-
- /************************/
- /* Function 0x23 */
- NTSTATUS samr_DeleteUser(
- [in,out,ref] policy_handle *user_handle
- );
-
- /************************/
- /* Function 0x24 */
- typedef struct {
- lsa_String account_name;
- lsa_String full_name;
- uint32 primary_gid;
- lsa_String description;
- lsa_String comment;
- } samr_UserInfo1;
-
- typedef struct {
- lsa_String comment;
- lsa_String unknown; /* settable, but doesn't stick. probably obsolete */
- uint16 country_code;
- uint16 code_page;
- } samr_UserInfo2;
-
- /* this is also used in samr and netlogon */
- typedef [public, flag(NDR_PAHEX)] struct {
- uint16 units_per_week;
- [size_is(1260), length_is(units_per_week/8)] uint8 *bits;
- } samr_LogonHours;
-
- typedef struct {
- lsa_String account_name;
- lsa_String full_name;
- uint32 rid;
- uint32 primary_gid;
- lsa_String home_directory;
- lsa_String home_drive;
- lsa_String logon_script;
- lsa_String profile_path;
- lsa_String workstations;
- NTTIME last_logon;
- NTTIME last_logoff;
- NTTIME last_password_change;
- NTTIME allow_password_change;
- NTTIME force_password_change;
- samr_LogonHours logon_hours;
- uint16 bad_password_count;
- uint16 logon_count;
- samr_AcctFlags acct_flags;
- } samr_UserInfo3;
-
- typedef struct {
- samr_LogonHours logon_hours;
- } samr_UserInfo4;
-
- typedef struct {
- lsa_String account_name;
- lsa_String full_name;
- uint32 rid;
- uint32 primary_gid;
- lsa_String home_directory;
- lsa_String home_drive;
- lsa_String logon_script;
- lsa_String profile_path;
- lsa_String description;
- lsa_String workstations;
- NTTIME last_logon;
- NTTIME last_logoff;
- samr_LogonHours logon_hours;
- uint16 bad_password_count;
- uint16 logon_count;
- NTTIME last_password_change;
- NTTIME acct_expiry;
- samr_AcctFlags acct_flags;
- } samr_UserInfo5;
-
- typedef struct {
- lsa_String account_name;
- lsa_String full_name;
- } samr_UserInfo6;
-
- typedef struct {
- lsa_String account_name;
- } samr_UserInfo7;
-
- typedef struct {
- lsa_String full_name;
- } samr_UserInfo8;
-
- typedef struct {
- uint32 primary_gid;
- } samr_UserInfo9;
-
- typedef struct {
- lsa_String home_directory;
- lsa_String home_drive;
- } samr_UserInfo10;
-
- typedef struct {
- lsa_String logon_script;
- } samr_UserInfo11;
-
- typedef struct {
- lsa_String profile_path;
- } samr_UserInfo12;
-
- typedef struct {
- lsa_String description;
- } samr_UserInfo13;
-
- typedef struct {
- lsa_String workstations;
- } samr_UserInfo14;
-
- typedef struct {
- samr_AcctFlags acct_flags;
- } samr_UserInfo16;
-
- typedef struct {
- NTTIME acct_expiry;
- } samr_UserInfo17;
-
- typedef [public, flag(NDR_PAHEX)] struct {
- uint8 hash[16];
- } samr_Password;
-
- typedef struct {
- samr_Password lm_pwd;
- samr_Password nt_pwd;
- boolean8 lm_pwd_active;
- boolean8 nt_pwd_active;
- } samr_UserInfo18;
-
- typedef struct {
- lsa_String parameters;
- } samr_UserInfo20;
-
- /* this defines the bits used for fields_present in info21 */
- typedef [bitmap32bit] bitmap {
- SAMR_FIELD_ACCOUNT_NAME = 0x00000001,
- SAMR_FIELD_FULL_NAME = 0x00000002,
- SAMR_FIELD_RID = 0x00000004,
- SAMR_FIELD_PRIMARY_GID = 0x00000008,
- SAMR_FIELD_DESCRIPTION = 0x00000010,
- SAMR_FIELD_COMMENT = 0x00000020,
- SAMR_FIELD_HOME_DIRECTORY = 0x00000040,
- SAMR_FIELD_HOME_DRIVE = 0x00000080,
- SAMR_FIELD_LOGON_SCRIPT = 0x00000100,
- SAMR_FIELD_PROFILE_PATH = 0x00000200,
- SAMR_FIELD_WORKSTATIONS = 0x00000400,
- SAMR_FIELD_LAST_LOGON = 0x00000800,
- SAMR_FIELD_LAST_LOGOFF = 0x00001000,
- SAMR_FIELD_LOGON_HOURS = 0x00002000,
- SAMR_FIELD_BAD_PWD_COUNT = 0x00004000,
- SAMR_FIELD_NUM_LOGONS = 0x00008000,
- SAMR_FIELD_ALLOW_PWD_CHANGE = 0x00010000,
- SAMR_FIELD_FORCE_PWD_CHANGE = 0x00020000,
- SAMR_FIELD_LAST_PWD_CHANGE = 0x00040000,
- SAMR_FIELD_ACCT_EXPIRY = 0x00080000,
- SAMR_FIELD_ACCT_FLAGS = 0x00100000,
- SAMR_FIELD_PARAMETERS = 0x00200000,
- SAMR_FIELD_COUNTRY_CODE = 0x00400000,
- SAMR_FIELD_CODE_PAGE = 0x00800000,
- SAMR_FIELD_PASSWORD = 0x01000000, /* either of these */
- SAMR_FIELD_PASSWORD2 = 0x02000000, /* two bits seems to work */
- SAMR_FIELD_PRIVATE_DATA = 0x04000000,
- SAMR_FIELD_EXPIRED_FLAG = 0x08000000,
- SAMR_FIELD_SEC_DESC = 0x10000000,
- SAMR_FIELD_OWF_PWD = 0x20000000
- } samr_FieldsPresent;
-
- /* used for 'password_expired' in samr_UserInfo21 */
- const int PASS_MUST_CHANGE_AT_NEXT_LOGON = 0x01;
- const int PASS_DONT_CHANGE_AT_NEXT_LOGON = 0x00;
-
- typedef struct {
- NTTIME last_logon;
- NTTIME last_logoff;
- NTTIME last_password_change;
- NTTIME acct_expiry;
- NTTIME allow_password_change;
- NTTIME force_password_change;
- lsa_String account_name;
- lsa_String full_name;
- lsa_String home_directory;
- lsa_String home_drive;
- lsa_String logon_script;
- lsa_String profile_path;
- lsa_String description;
- lsa_String workstations;
- lsa_String comment;
- lsa_String parameters;
- lsa_String unknown1;
- lsa_String unknown2;
- lsa_String unknown3;
- uint32 buf_count;
- [size_is(buf_count)] uint8 *buffer;
- uint32 rid;
- uint32 primary_gid;
- samr_AcctFlags acct_flags;
- samr_FieldsPresent fields_present;
- samr_LogonHours logon_hours;
- uint16 bad_password_count;
- uint16 logon_count;
- uint16 country_code;
- uint16 code_page;
- uint8 nt_password_set;
- uint8 lm_password_set;
- uint8 password_expired;
- uint8 unknown4;
- } samr_UserInfo21;
-
- typedef [public, flag(NDR_PAHEX)] struct {
- uint8 data[516];
- } samr_CryptPassword;
-
- typedef struct {
- samr_UserInfo21 info;
- samr_CryptPassword password;
- } samr_UserInfo23;
-
- typedef struct {
- samr_CryptPassword password;
- uint8 pw_len;
- } samr_UserInfo24;
-
- typedef [flag(NDR_PAHEX)] struct {
- uint8 data[532];
- } samr_CryptPasswordEx;
-
- typedef struct {
- samr_UserInfo21 info;
- samr_CryptPasswordEx password;
- } samr_UserInfo25;
-
- typedef struct {
- samr_CryptPasswordEx password;
- uint8 pw_len;
- } samr_UserInfo26;
-
- typedef [switch_type(uint16)] union {
- [case(1)] samr_UserInfo1 info1;
- [case(2)] samr_UserInfo2 info2;
- [case(3)] samr_UserInfo3 info3;
- [case(4)] samr_UserInfo4 info4;
- [case(5)] samr_UserInfo5 info5;
- [case(6)] samr_UserInfo6 info6;
- [case(7)] samr_UserInfo7 info7;
- [case(8)] samr_UserInfo8 info8;
- [case(9)] samr_UserInfo9 info9;
- [case(10)] samr_UserInfo10 info10;
- [case(11)] samr_UserInfo11 info11;
- [case(12)] samr_UserInfo12 info12;
- [case(13)] samr_UserInfo13 info13;
- [case(14)] samr_UserInfo14 info14;
- [case(16)] samr_UserInfo16 info16;
- [case(17)] samr_UserInfo17 info17;
- [case(18)] samr_UserInfo18 info18;
- [case(20)] samr_UserInfo20 info20;
- [case(21)] samr_UserInfo21 info21;
- [case(23)] samr_UserInfo23 info23;
- [case(24)] samr_UserInfo24 info24;
- [case(25)] samr_UserInfo25 info25;
- [case(26)] samr_UserInfo26 info26;
- } samr_UserInfo;
-
- [public] NTSTATUS samr_QueryUserInfo(
- [in,ref] policy_handle *user_handle,
- [in] uint16 level,
- [out,unique,switch_is(level)] samr_UserInfo *info
- );
-
-
- /************************/
- /* Function 0x25 */
- [public] NTSTATUS samr_SetUserInfo(
- [in,ref] policy_handle *user_handle,
- [in] uint16 level,
- [in,ref,switch_is(level)] samr_UserInfo *info
- );
-
- /************************/
- /* Function 0x26 */
- /*
- this is a password change interface that doesn't give
- the server the plaintext password. Depricated.
- */
- NTSTATUS samr_ChangePasswordUser(
- [in,ref] policy_handle *user_handle,
- [in] boolean8 lm_present,
- [in,unique] samr_Password *old_lm_crypted,
- [in,unique] samr_Password *new_lm_crypted,
- [in] boolean8 nt_present,
- [in,unique] samr_Password *old_nt_crypted,
- [in,unique] samr_Password *new_nt_crypted,
- [in] boolean8 cross1_present,
- [in,unique] samr_Password *nt_cross,
- [in] boolean8 cross2_present,
- [in,unique] samr_Password *lm_cross
- );
-
- /************************/
- /* Function 0x27 */
-
- typedef [public] struct {
- uint32 rid;
- samr_GroupAttrs attributes;
- } samr_RidWithAttribute;
-
- typedef [public] struct {
- uint32 count;
- [size_is(count)] samr_RidWithAttribute *rids;
- } samr_RidWithAttributeArray;
-
- NTSTATUS samr_GetGroupsForUser(
- [in,ref] policy_handle *user_handle,
- [out,unique] samr_RidWithAttributeArray *rids
- );
-
- /************************/
- /* Function 0x28 */
-
- typedef struct {
- uint32 idx;
- uint32 rid;
- samr_AcctFlags acct_flags;
- lsa_String account_name;
- lsa_String description;
- lsa_String full_name;
- } samr_DispEntryGeneral;
-
- typedef struct {
- uint32 count;
- [size_is(count)] samr_DispEntryGeneral *entries;
- } samr_DispInfoGeneral;
-
- typedef struct {
- uint32 idx;
- uint32 rid;
- samr_AcctFlags acct_flags;
- lsa_String account_name;
- lsa_String description;
- } samr_DispEntryFull;
-
- typedef struct {
- uint32 count;
- [size_is(count)] samr_DispEntryFull *entries;
- } samr_DispInfoFull;
-
- typedef struct {
- uint32 idx;
- uint32 rid;
- samr_GroupAttrs acct_flags;
- lsa_String account_name;
- lsa_String description;
- } samr_DispEntryFullGroup;
-
- typedef struct {
- uint32 count;
- [size_is(count)] samr_DispEntryFullGroup *entries;
- } samr_DispInfoFullGroups;
-
- typedef struct {
- uint32 idx;
- lsa_AsciiStringLarge account_name;
- } samr_DispEntryAscii;
-
- typedef struct {
- uint32 count;
- [size_is(count)] samr_DispEntryAscii *entries;
- } samr_DispInfoAscii;
-
- typedef [switch_type(uint16)] union {
- [case(1)] samr_DispInfoGeneral info1;/* users */
- [case(2)] samr_DispInfoFull info2; /* trust accounts? */
- [case(3)] samr_DispInfoFullGroups info3; /* groups */
- [case(4)] samr_DispInfoAscii info4; /* users */
- [case(5)] samr_DispInfoAscii info5; /* groups */
- } samr_DispInfo;
-
- NTSTATUS samr_QueryDisplayInfo(
- [in,ref] policy_handle *domain_handle,
- [in] uint16 level,
- [in] uint32 start_idx,
- [in] uint32 max_entries,
- [in] uint32 buf_size,
- [out] uint32 total_size,
- [out] uint32 returned_size,
- [out,switch_is(level)] samr_DispInfo info
- );
-
-
- /************************/
- /* Function 0x29 */
-
- /*
- this seems to be an alphabetic search function. The returned index
- is the index for samr_QueryDisplayInfo needed to get names occurring
- after the specified name. The supplied name does not need to exist
- in the database (for example you can supply just a first letter for
- searching starting at that letter)
-
- The level corresponds to the samr_QueryDisplayInfo level
- */
- NTSTATUS samr_GetDisplayEnumerationIndex(
- [in,ref] policy_handle *domain_handle,
- [in] uint16 level,
- [in] lsa_String name,
- [out] uint32 idx
- );
-
-
-
- /************************/
- /* Function 0x2a */
-
- /*
- w2k3 returns NT_STATUS_NOT_IMPLEMENTED for this
- */
- NTSTATUS samr_TestPrivateFunctionsDomain(
- [in,ref] policy_handle *domain_handle
- );
-
-
- /************************/
- /* Function 0x2b */
-
- /*
- w2k3 returns NT_STATUS_NOT_IMPLEMENTED for this
- */
- NTSTATUS samr_TestPrivateFunctionsUser(
- [in,ref] policy_handle *user_handle
- );
-
-
- /************************/
- /* Function 0x2c */
-
- typedef struct {
- uint16 min_password_length;
- samr_PasswordProperties password_properties;
- } samr_PwInfo;
-
- [public] NTSTATUS samr_GetUserPwInfo(
- [in,ref] policy_handle *user_handle,
- [out] samr_PwInfo info
- );
-
- /************************/
- /* Function 0x2d */
- NTSTATUS samr_RemoveMemberFromForeignDomain(
- [in,ref] policy_handle *domain_handle,
- [in,ref] dom_sid2 *sid
- );
-
- /************************/
- /* Function 0x2e */
-
- /*
- how is this different from QueryDomainInfo ??
- */
- NTSTATUS samr_QueryDomainInfo2(
- [in,ref] policy_handle *domain_handle,
- [in] uint16 level,
- [out,unique,switch_is(level)] samr_DomainInfo *info
- );
-
- /************************/
- /* Function 0x2f */
-
- /*
- how is this different from QueryUserInfo ??
- */
- NTSTATUS samr_QueryUserInfo2(
- [in,ref] policy_handle *user_handle,
- [in] uint16 level,
- [out,unique,switch_is(level)] samr_UserInfo *info
- );
-
- /************************/
- /* Function 0x30 */
-
- /*
- how is this different from QueryDisplayInfo??
- */
- NTSTATUS samr_QueryDisplayInfo2(
- [in,ref] policy_handle *domain_handle,
- [in] uint16 level,
- [in] uint32 start_idx,
- [in] uint32 max_entries,
- [in] uint32 buf_size,
- [out] uint32 total_size,
- [out] uint32 returned_size,
- [out,switch_is(level)] samr_DispInfo info
- );
-
- /************************/
- /* Function 0x31 */
-
- /*
- how is this different from GetDisplayEnumerationIndex ??
- */
- NTSTATUS samr_GetDisplayEnumerationIndex2(
- [in,ref] policy_handle *domain_handle,
- [in] uint16 level,
- [in] lsa_String name,
- [out] uint32 idx
- );
-
-
- /************************/
- /* Function 0x32 */
- NTSTATUS samr_CreateUser2(
- [in,ref] policy_handle *domain_handle,
- [in,ref] lsa_String *account_name,
- [in] samr_AcctFlags acct_flags,
- [in] samr_UserAccessMask access_mask,
- [out,ref] policy_handle *user_handle,
- [out,ref] uint32 *access_granted,
- [out,ref] uint32 *rid
- );
-
-
- /************************/
- /* Function 0x33 */
-
- /*
- another duplicate. There must be a reason ....
- */
- NTSTATUS samr_QueryDisplayInfo3(
- [in,ref] policy_handle *domain_handle,
- [in] uint16 level,
- [in] uint32 start_idx,
- [in] uint32 max_entries,
- [in] uint32 buf_size,
- [out] uint32 total_size,
- [out] uint32 returned_size,
- [out,switch_is(level)] samr_DispInfo info
- );
-
- /************************/
- /* Function 0x34 */
- NTSTATUS samr_AddMultipleMembersToAlias(
- [in,ref] policy_handle *alias_handle,
- [in,ref] lsa_SidArray *sids
- );
-
- /************************/
- /* Function 0x35 */
- NTSTATUS samr_RemoveMultipleMembersFromAlias(
- [in,ref] policy_handle *alias_handle,
- [in,ref] lsa_SidArray *sids
- );
-
- /************************/
- /* Function 0x36 */
-
- NTSTATUS samr_OemChangePasswordUser2(
- [in,unique] lsa_AsciiString *server,
- [in,ref] lsa_AsciiString *account,
- [in,unique] samr_CryptPassword *password,
- [in,unique] samr_Password *hash
- );
-
- /************************/
- /* Function 0x37 */
- NTSTATUS samr_ChangePasswordUser2(
- [in,unique] lsa_String *server,
- [in,ref] lsa_String *account,
- [in,unique] samr_CryptPassword *nt_password,
- [in,unique] samr_Password *nt_verifier,
- [in] boolean8 lm_change,
- [in,unique] samr_CryptPassword *lm_password,
- [in,unique] samr_Password *lm_verifier
- );
-
- /************************/
- /* Function 0x38 */
- NTSTATUS samr_GetDomPwInfo(
- [in,unique] lsa_String *domain_name,
- [out] samr_PwInfo info
- );
-
- /************************/
- /* Function 0x39 */
- NTSTATUS samr_Connect2(
- [in,unique,string,charset(UTF16)] uint16 *system_name,
- [in] samr_ConnectAccessMask access_mask,
- [out,ref] policy_handle *connect_handle
- );
-
- /************************/
- /* Function 0x3a */
- /*
- seems to be an exact alias for samr_SetUserInfo()
- */
- [public] NTSTATUS samr_SetUserInfo2(
- [in,ref] policy_handle *user_handle,
- [in] uint16 level,
- [in,ref,switch_is(level)] samr_UserInfo *info
- );
-
- /************************/
- /* Function 0x3b */
- /*
- this one is mysterious. I have a few guesses, but nothing working yet
- */
- NTSTATUS samr_SetBootKeyInformation(
- [in,ref] policy_handle *connect_handle,
- [in] uint32 unknown1,
- [in] uint32 unknown2,
- [in] uint32 unknown3
- );
-
- /************************/
- /* Function 0x3c */
- NTSTATUS samr_GetBootKeyInformation(
- [in,ref] policy_handle *domain_handle,
- [out] uint32 unknown
- );
-
- /************************/
- /* Function 0x3d */
- NTSTATUS samr_Connect3(
- [in,unique,string,charset(UTF16)] uint16 *system_name,
- /* this unknown value seems to be completely ignored by w2k3 */
- [in] uint32 unknown,
- [in] samr_ConnectAccessMask access_mask,
- [out,ref] policy_handle *connect_handle
- );
-
- /************************/
- /* Function 0x3e */
-
- typedef enum {
- SAMR_CONNECT_PRE_W2K = 1,
- SAMR_CONNECT_W2K = 2,
- SAMR_CONNECT_AFTER_W2K = 3
- } samr_ConnectVersion;
-
- NTSTATUS samr_Connect4(
- [in,unique,string,charset(UTF16)] uint16 *system_name,
- [in] samr_ConnectVersion client_version,
- [in] samr_ConnectAccessMask access_mask,
- [out,ref] policy_handle *connect_handle
- );
-
- /************************/
- /* Function 0x3f */
-
- typedef enum samr_RejectReason samr_RejectReason;
-
- typedef struct {
- samr_RejectReason reason;
- uint32 unknown1;
- uint32 unknown2;
- } samr_ChangeReject;
-
- NTSTATUS samr_ChangePasswordUser3(
- [in,unique] lsa_String *server,
- [in,ref] lsa_String *account,
- [in,unique] samr_CryptPassword *nt_password,
- [in,unique] samr_Password *nt_verifier,
- [in] boolean8 lm_change,
- [in,unique] samr_CryptPassword *lm_password,
- [in,unique] samr_Password *lm_verifier,
- [in,unique] samr_CryptPassword *password3,
- [out,unique] samr_DomInfo1 *dominfo,
- [out,unique] samr_ChangeReject *reject
- );
-
- /************************/
- /* Function 0x40 */
-
- typedef struct {
- samr_ConnectVersion client_version; /* w2k3 gives 3 */
- uint32 unknown2; /* w2k3 gives 0 */
- } samr_ConnectInfo1;
-
- typedef union {
- [case(1)] samr_ConnectInfo1 info1;
- } samr_ConnectInfo;
-
- [public] NTSTATUS samr_Connect5(
- [in,unique,string,charset(UTF16)] uint16 *system_name,
- [in] samr_ConnectAccessMask access_mask,
- [in,out] uint32 level,
- [in,out,switch_is(level),ref] samr_ConnectInfo *info,
- [out,ref] policy_handle *connect_handle
- );
-
- /************************/
- /* Function 0x41 */
- NTSTATUS samr_RidToSid(
- [in,ref] policy_handle *domain_handle,
- [in] uint32 rid,
- [out,unique] dom_sid2 *sid
- );
-
-
- /************************/
- /* Function 0x42 */
-
- /*
- this should set the DSRM password for the server, which is used
- when booting into Directory Services Recovery Mode on a DC. Win2003
- gives me NT_STATUS_NOT_SUPPORTED
- */
-
- NTSTATUS samr_SetDsrmPassword(
- [in,unique] lsa_String *name,
- [in] uint32 unknown,
- [in,unique] samr_Password *hash
- );
-
-
- /************************/
- /* Function 0x43 */
- /************************/
- typedef [bitmap32bit] bitmap {
- SAMR_VALIDATE_FIELD_PASSWORD_LAST_SET = 0x00000001,
- SAMR_VALIDATE_FIELD_BAD_PASSWORD_TIME = 0x00000002,
- SAMR_VALIDATE_FIELD_LOCKOUT_TIME = 0x00000004,
- SAMR_VALIDATE_FIELD_BAD_PASSWORD_COUNT = 0x00000008,
- SAMR_VALIDATE_FIELD_PASSWORD_HISTORY_LENGTH = 0x00000010,
- SAMR_VALIDATE_FIELD_PASSWORD_HISTORY = 0x00000020
- } samr_ValidateFieldsPresent;
-
- typedef enum {
- NetValidateAuthentication = 1,
- NetValidatePasswordChange= 2,
- NetValidatePasswordReset = 3
- } samr_ValidatePasswordLevel;
-
- /* NetApi maps samr_ValidationStatus errors to WERRORs. Haven't
- * identified the mapping of
- * - NERR_PasswordFilterError
- * - NERR_PasswordExpired and
- * - NERR_PasswordCantChange
- * yet - Guenther
- */
-
- typedef enum {
- SAMR_VALIDATION_STATUS_SUCCESS = 0,
- SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE = 1,
- SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT = 2,
- 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_ValidationStatus;
-
- typedef struct {
- uint32 length;
- [size_is(length)] uint8 *data;
- } samr_ValidationBlob;
-
- typedef struct {
- samr_ValidateFieldsPresent fields_present;
- NTTIME_hyper last_password_change;
- NTTIME_hyper bad_password_time;
- NTTIME_hyper lockout_time;
- uint32 bad_pwd_count;
- uint32 pwd_history_len;
- [size_is(pwd_history_len)] samr_ValidationBlob *pwd_history;
- } samr_ValidatePasswordInfo;
-
- typedef struct {
- samr_ValidatePasswordInfo info;
- samr_ValidationStatus status;
- } samr_ValidatePasswordRepCtr;
-
- typedef [switch_type(uint16)] union {
- [case(1)] samr_ValidatePasswordRepCtr ctr1;
- [case(2)] samr_ValidatePasswordRepCtr ctr2;
- [case(3)] samr_ValidatePasswordRepCtr ctr3;
- } samr_ValidatePasswordRep;
-
- typedef struct {
- samr_ValidatePasswordInfo info;
- lsa_StringLarge password;
- lsa_StringLarge account;
- samr_ValidationBlob hash;
- boolean8 pwd_must_change_at_next_logon;
- boolean8 clear_lockout;
- } samr_ValidatePasswordReq3;
-
- typedef struct {
- samr_ValidatePasswordInfo info;
- lsa_StringLarge password;
- lsa_StringLarge account;
- samr_ValidationBlob hash;
- boolean8 password_matched;
- } samr_ValidatePasswordReq2;
-
- typedef struct {
- samr_ValidatePasswordInfo info;
- boolean8 password_matched;
- } samr_ValidatePasswordReq1;
-
- typedef [switch_type(uint16)] union {
- [case(1)] samr_ValidatePasswordReq1 req1;
- [case(2)] samr_ValidatePasswordReq2 req2;
- [case(3)] samr_ValidatePasswordReq3 req3;
- } samr_ValidatePasswordReq;
-
- NTSTATUS samr_ValidatePassword(
- [in] samr_ValidatePasswordLevel level,
- [in,switch_is(level)] samr_ValidatePasswordReq req,
- [out,unique,switch_is(level)] samr_ValidatePasswordRep *rep
- );
-}
diff --git a/source4/librpc/idl/security.idl b/source4/librpc/idl/security.idl
deleted file mode 100644
index 40aa698176..0000000000
--- a/source4/librpc/idl/security.idl
+++ /dev/null
@@ -1,410 +0,0 @@
-#include "idl_types.h"
-
-/*
- security IDL structures
-*/
-
-import "misc.idl";
-
-/*
- use the same structure for dom_sid2 as dom_sid. A dom_sid2 is really
- just a dom sid, but with the sub_auths represented as a conformant
- array. As with all in-structure conformant arrays, the array length
- is placed before the start of the structure. That's what gives rise
- to the extra num_auths elemenent. We don't want the Samba code to
- have to bother with such esoteric NDR details, so its easier to just
- define it as a dom_sid and use pidl magic to make it all work. It
- just means you need to mark a sid as a "dom_sid2" in the IDL when you
- know it is of the conformant array variety
-*/
-cpp_quote("#define dom_sid2 dom_sid")
-
-/* same struct as dom_sid but inside a 28 bytes fixed buffer in NDR */
-cpp_quote("#define dom_sid28 dom_sid")
-
-/* same struct as dom_sid but in a variable byte buffer, which is maybe empty in NDR */
-cpp_quote("#define dom_sid0 dom_sid")
-
-[
- pointer_default(unique)
-]
-interface security
-{
- /*
- access masks are divided up like this:
- 0xabccdddd
- where
- a = generic rights bits SEC_GENERIC_
- b = flags SEC_FLAG_
- c = standard rights bits SEC_STD_
- d = object type specific bits SEC_{FILE,DIR,REG,xxx}_
-
- common combinations of bits are prefixed with SEC_RIGHTS_
- */
- const int SEC_MASK_GENERIC = 0xF0000000;
- const int SEC_MASK_FLAGS = 0x0F000000;
- const int SEC_MASK_STANDARD = 0x00FF0000;
- const int SEC_MASK_SPECIFIC = 0x0000FFFF;
-
- /* generic bits */
- const int SEC_GENERIC_ALL = 0x10000000;
- const int SEC_GENERIC_EXECUTE = 0x20000000;
- const int SEC_GENERIC_WRITE = 0x40000000;
- const int SEC_GENERIC_READ = 0x80000000;
-
- /* flag bits */
- const int SEC_FLAG_SYSTEM_SECURITY = 0x01000000;
- const int SEC_FLAG_MAXIMUM_ALLOWED = 0x02000000;
-
- /* standard bits */
- const int SEC_STD_DELETE = 0x00010000;
- const int SEC_STD_READ_CONTROL = 0x00020000;
- const int SEC_STD_WRITE_DAC = 0x00040000;
- const int SEC_STD_WRITE_OWNER = 0x00080000;
- const int SEC_STD_SYNCHRONIZE = 0x00100000;
- const int SEC_STD_REQUIRED = 0x000F0000;
- const int SEC_STD_ALL = 0x001F0000;
-
- /* file specific bits */
- const int SEC_FILE_READ_DATA = 0x00000001;
- const int SEC_FILE_WRITE_DATA = 0x00000002;
- const int SEC_FILE_APPEND_DATA = 0x00000004;
- const int SEC_FILE_READ_EA = 0x00000008;
- const int SEC_FILE_WRITE_EA = 0x00000010;
- const int SEC_FILE_EXECUTE = 0x00000020;
- const int SEC_FILE_READ_ATTRIBUTE = 0x00000080;
- const int SEC_FILE_WRITE_ATTRIBUTE = 0x00000100;
- const int SEC_FILE_ALL = 0x000001ff;
-
- /* directory specific bits */
- const int SEC_DIR_LIST = 0x00000001;
- const int SEC_DIR_ADD_FILE = 0x00000002;
- const int SEC_DIR_ADD_SUBDIR = 0x00000004;
- const int SEC_DIR_READ_EA = 0x00000008;
- const int SEC_DIR_WRITE_EA = 0x00000010;
- const int SEC_DIR_TRAVERSE = 0x00000020;
- const int SEC_DIR_DELETE_CHILD = 0x00000040;
- const int SEC_DIR_READ_ATTRIBUTE = 0x00000080;
- const int SEC_DIR_WRITE_ATTRIBUTE = 0x00000100;
-
- /* registry entry specific bits */
- const int SEC_REG_QUERY_VALUE = 0x00000001;
- const int SEC_REG_SET_VALUE = 0x00000002;
- const int SEC_REG_CREATE_SUBKEY = 0x00000004;
- const int SEC_REG_ENUM_SUBKEYS = 0x00000008;
- const int SEC_REG_NOTIFY = 0x00000010;
- const int SEC_REG_CREATE_LINK = 0x00000020;
-
- /* ldap specific access bits */
- const int SEC_ADS_CREATE_CHILD = 0x00000001;
- const int SEC_ADS_DELETE_CHILD = 0x00000002;
- const int SEC_ADS_LIST = 0x00000004;
- const int SEC_ADS_SELF_WRITE = 0x00000008;
- const int SEC_ADS_READ_PROP = 0x00000010;
- const int SEC_ADS_WRITE_PROP = 0x00000020;
- const int SEC_ADS_DELETE_TREE = 0x00000040;
- const int SEC_ADS_LIST_OBJECT = 0x00000080;
- const int SEC_ADS_CONTROL_ACCESS = 0x00000100;
-
- /* invalid bits */
- const int SEC_MASK_INVALID = 0x0ce0fe00;
-
- /* generic->specific mappings for files */
- const int SEC_RIGHTS_FILE_READ = SEC_STD_READ_CONTROL |
- SEC_STD_SYNCHRONIZE |
- SEC_FILE_READ_DATA |
- SEC_FILE_READ_ATTRIBUTE |
- SEC_FILE_READ_EA;
-
- const int SEC_RIGHTS_FILE_WRITE = SEC_STD_READ_CONTROL |
- SEC_STD_SYNCHRONIZE |
- SEC_FILE_WRITE_DATA |
- SEC_FILE_WRITE_ATTRIBUTE |
- SEC_FILE_WRITE_EA |
- SEC_FILE_APPEND_DATA;
-
- const int SEC_RIGHTS_FILE_EXECUTE = SEC_STD_SYNCHRONIZE |
- SEC_STD_READ_CONTROL |
- SEC_FILE_READ_ATTRIBUTE |
- SEC_FILE_EXECUTE;
-
- const int SEC_RIGHTS_FILE_ALL = SEC_STD_ALL | SEC_FILE_ALL;
-
- /* generic->specific mappings for directories (same as files) */
- const int SEC_RIGHTS_DIR_READ = SEC_RIGHTS_FILE_READ;
- const int SEC_RIGHTS_DIR_WRITE = SEC_RIGHTS_FILE_WRITE;
- const int SEC_RIGHTS_DIR_EXECUTE = SEC_RIGHTS_FILE_EXECUTE;
- const int SEC_RIGHTS_DIR_ALL = SEC_RIGHTS_FILE_ALL;
-
-
- /***************************************************************/
- /* WELL KNOWN SIDS */
-
- /* a NULL sid */
- const string SID_NULL = "S-1-0-0";
-
- /* the world domain */
- const string NAME_WORLD = "WORLD";
-
- const string SID_WORLD_DOMAIN = "S-1-1";
- const string SID_WORLD = "S-1-1-0";
-
- /* SECURITY_CREATOR_SID_AUTHORITY */
- const string SID_CREATOR_OWNER_DOMAIN = "S-1-3";
- const string SID_CREATOR_OWNER = "S-1-3-0";
- const string SID_CREATOR_GROUP = "S-1-3-1";
- const string SID_OWNER_RIGHTS = "S-1-3-4";
-
- /* SECURITY_NT_AUTHORITY */
- const string NAME_NT_AUTHORITY = "NT AUTHORITY";
-
- const string SID_NT_AUTHORITY = "S-1-5";
- const string SID_NT_DIALUP = "S-1-5-1";
- const string SID_NT_NETWORK = "S-1-5-2";
- const string SID_NT_BATCH = "S-1-5-3";
- const string SID_NT_INTERACTIVE = "S-1-5-4";
- const string SID_NT_SERVICE = "S-1-5-6";
- const string SID_NT_ANONYMOUS = "S-1-5-7";
- const string SID_NT_PROXY = "S-1-5-8";
- const string SID_NT_ENTERPRISE_DCS = "S-1-5-9";
- const string SID_NT_SELF = "S-1-5-10";
- const string SID_NT_AUTHENTICATED_USERS = "S-1-5-11";
- const string SID_NT_RESTRICTED = "S-1-5-12";
- const string SID_NT_TERMINAL_SERVER_USERS = "S-1-5-13";
- const string SID_NT_REMOTE_INTERACTIVE = "S-1-5-14";
- const string SID_NT_THIS_ORGANISATION = "S-1-5-15";
- const string SID_NT_IUSR = "S-1-5-17";
- const string SID_NT_SYSTEM = "S-1-5-18";
- const string SID_NT_LOCAL_SERVICE = "S-1-5-19";
- const string SID_NT_NETWORK_SERVICE = "S-1-5-20";
- const string SID_NT_DIGEST_AUTHENTICATION = "S-1-5-64-21";
- const string SID_NT_NTLM_AUTHENTICATION = "S-1-5-64-10";
- const string SID_NT_SCHANNEL_AUTHENTICATION = "S-1-5-64-14";
- const string SID_NT_OTHER_ORGANISATION = "S-1-5-1000";
-
- /* SECURITY_BUILTIN_DOMAIN_RID */
- const string NAME_BUILTIN = "BUILTIN";
-
- const string SID_BUILTIN = "S-1-5-32";
- const string SID_BUILTIN_ADMINISTRATORS = "S-1-5-32-544";
- const string SID_BUILTIN_USERS = "S-1-5-32-545";
- const string SID_BUILTIN_GUESTS = "S-1-5-32-546";
- const string SID_BUILTIN_POWER_USERS = "S-1-5-32-547";
- const string SID_BUILTIN_ACCOUNT_OPERATORS = "S-1-5-32-548";
- const string SID_BUILTIN_SERVER_OPERATORS = "S-1-5-32-549";
- const string SID_BUILTIN_PRINT_OPERATORS = "S-1-5-32-550";
- const string SID_BUILTIN_BACKUP_OPERATORS = "S-1-5-32-551";
- const string SID_BUILTIN_REPLICATOR = "S-1-5-32-552";
- const string SID_BUILTIN_RAS_SERVERS = "S-1-5-32-553";
- const string SID_BUILTIN_PREW2K = "S-1-5-32-554";
-
- /* well-known domain RIDs */
- const int DOMAIN_RID_LOGON = 9;
- const int DOMAIN_RID_ADMINISTRATOR = 500;
- const int DOMAIN_RID_GUEST = 501;
- const int DOMAIN_RID_ADMINS = 512;
- const int DOMAIN_RID_USERS = 513;
- const int DOMAIN_RID_DOMAIN_MEMBERS = 515;
- const int DOMAIN_RID_DCS = 516;
- const int DOMAIN_RID_CERT_ADMINS = 517;
- const int DOMAIN_RID_SCHEMA_ADMINS = 518;
- const int DOMAIN_RID_ENTERPRISE_ADMINS = 519;
-
-
- /*
- privilege IDs. Please keep the IDs below 64. If we get more
- than 64 then we need to change security_token
- */
- typedef enum {
- SEC_PRIV_SECURITY = 1,
- SEC_PRIV_BACKUP = 2,
- SEC_PRIV_RESTORE = 3,
- SEC_PRIV_SYSTEMTIME = 4,
- SEC_PRIV_SHUTDOWN = 5,
- SEC_PRIV_REMOTE_SHUTDOWN = 6,
- SEC_PRIV_TAKE_OWNERSHIP = 7,
- SEC_PRIV_DEBUG = 8,
- SEC_PRIV_SYSTEM_ENVIRONMENT = 9,
- SEC_PRIV_SYSTEM_PROFILE = 10,
- SEC_PRIV_PROFILE_SINGLE_PROCESS = 11,
- SEC_PRIV_INCREASE_BASE_PRIORITY = 12,
- SEC_PRIV_LOAD_DRIVER = 13,
- SEC_PRIV_CREATE_PAGEFILE = 14,
- SEC_PRIV_INCREASE_QUOTA = 15,
- SEC_PRIV_CHANGE_NOTIFY = 16,
- SEC_PRIV_UNDOCK = 17,
- SEC_PRIV_MANAGE_VOLUME = 18,
- SEC_PRIV_IMPERSONATE = 19,
- SEC_PRIV_CREATE_GLOBAL = 20,
- SEC_PRIV_ENABLE_DELEGATION = 21,
- SEC_PRIV_INTERACTIVE_LOGON = 22,
- SEC_PRIV_NETWORK_LOGON = 23,
- SEC_PRIV_REMOTE_INTERACTIVE_LOGON = 24
- } sec_privilege;
-
-
- /* a domain SID. Note that unlike Samba3 this contains a pointer,
- so you can't copy them using assignment */
- typedef [public,gensize,noprint,noejs,nosize] struct {
- uint8 sid_rev_num; /**< SID revision number */
- [range(0,15)] int8 num_auths; /**< Number of sub-authorities */
- uint8 id_auth[6]; /**< Identifier Authority */
- uint32 sub_auths[num_auths];
- } dom_sid;
-
- /* id used to identify a endpoint, possibly in a cluster */
- typedef [public] struct {
- hyper id;
- uint32 id2;
- uint32 node;
- } server_id;
-
- typedef [bitmap8bit] bitmap {
- SEC_ACE_FLAG_OBJECT_INHERIT = 0x01,
- SEC_ACE_FLAG_CONTAINER_INHERIT = 0x02,
- SEC_ACE_FLAG_NO_PROPAGATE_INHERIT = 0x04,
- SEC_ACE_FLAG_INHERIT_ONLY = 0x08,
- SEC_ACE_FLAG_INHERITED_ACE = 0x10,
- SEC_ACE_FLAG_VALID_INHERIT = 0x0f,
- SEC_ACE_FLAG_SUCCESSFUL_ACCESS = 0x40,
- SEC_ACE_FLAG_FAILED_ACCESS = 0x80
- } security_ace_flags;
-
- typedef [enum8bit] enum {
- SEC_ACE_TYPE_ACCESS_ALLOWED = 0,
- SEC_ACE_TYPE_ACCESS_DENIED = 1,
- SEC_ACE_TYPE_SYSTEM_AUDIT = 2,
- SEC_ACE_TYPE_SYSTEM_ALARM = 3,
- SEC_ACE_TYPE_ALLOWED_COMPOUND = 4,
- SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT = 5,
- SEC_ACE_TYPE_ACCESS_DENIED_OBJECT = 6,
- SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT = 7,
- SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT = 8
- } security_ace_type;
-
- typedef [bitmap32bit] bitmap {
- SEC_ACE_OBJECT_TYPE_PRESENT = 0x00000001,
- SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT = 0x00000002
- } security_ace_object_flags;
-
- typedef [nodiscriminant] union {
- /* this is the 'schemaIDGUID' attribute of the attribute object in the schema naming context */
- [case(SEC_ACE_OBJECT_TYPE_PRESENT)] GUID type;
- [default];
- } security_ace_object_type;
-
- typedef [nodiscriminant] union {
- /* this is the 'schemaIDGUID' attribute of the objectclass object in the schema naming context
- * (of the parent container)
- */
- [case(SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT)] GUID inherited_type;
- [default];
- } security_ace_object_inherited_type;
-
- typedef struct {
- security_ace_object_flags flags;
- [switch_is(flags & SEC_ACE_OBJECT_TYPE_PRESENT)] security_ace_object_type type;
- [switch_is(flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT)] security_ace_object_inherited_type inherited_type;
- } security_ace_object;
-
- typedef [nodiscriminant] union {
- [case(SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT)] security_ace_object object;
- [case(SEC_ACE_TYPE_ACCESS_DENIED_OBJECT)] security_ace_object object;
- [case(SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT)] security_ace_object object;
- [case(SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT)] security_ace_object object;
- [default];
- } security_ace_object_ctr;
-
- typedef [public,gensize,nosize] struct {
- security_ace_type type; /* SEC_ACE_TYPE_* */
- security_ace_flags flags; /* SEC_ACE_FLAG_* */
- [value(ndr_size_security_ace(r,ndr->flags))] uint16 size;
- uint32 access_mask;
- [switch_is(type)] security_ace_object_ctr object;
- dom_sid trustee;
- } security_ace;
-
- typedef enum {
- SECURITY_ACL_REVISION_NT4 = 2,
- SECURITY_ACL_REVISION_ADS = 4
- } security_acl_revision;
-
- const uint NT4_ACL_REVISION = SECURITY_ACL_REVISION_NT4;
-
- typedef [public,gensize,nosize] struct {
- security_acl_revision revision;
- [value(ndr_size_security_acl(r,ndr->flags))] uint16 size;
- [range(0,1000)] uint32 num_aces;
- security_ace aces[num_aces];
- } security_acl;
-
- /* default revision for new ACLs */
- typedef [enum8bit] enum {
- SECURITY_DESCRIPTOR_REVISION_1 = 1
- } security_descriptor_revision;
-
- const int SD_REVISION = SECURITY_DESCRIPTOR_REVISION_1;
-
- /* security_descriptor->type bits */
- typedef [bitmap16bit] bitmap {
- SEC_DESC_OWNER_DEFAULTED = 0x0001,
- SEC_DESC_GROUP_DEFAULTED = 0x0002,
- SEC_DESC_DACL_PRESENT = 0x0004,
- SEC_DESC_DACL_DEFAULTED = 0x0008,
- SEC_DESC_SACL_PRESENT = 0x0010,
- SEC_DESC_SACL_DEFAULTED = 0x0020,
- SEC_DESC_DACL_TRUSTED = 0x0040,
- SEC_DESC_SERVER_SECURITY = 0x0080,
- SEC_DESC_DACL_AUTO_INHERIT_REQ = 0x0100,
- SEC_DESC_SACL_AUTO_INHERIT_REQ = 0x0200,
- SEC_DESC_DACL_AUTO_INHERITED = 0x0400,
- SEC_DESC_SACL_AUTO_INHERITED = 0x0800,
- SEC_DESC_DACL_PROTECTED = 0x1000,
- SEC_DESC_SACL_PROTECTED = 0x2000,
- SEC_DESC_RM_CONTROL_VALID = 0x4000,
- SEC_DESC_SELF_RELATIVE = 0x8000
- } security_descriptor_type;
-
- typedef [gensize,nosize,public,flag(NDR_LITTLE_ENDIAN)] struct {
- security_descriptor_revision revision;
- security_descriptor_type type; /* SEC_DESC_xxxx flags */
- [relative] dom_sid *owner_sid;
- [relative] dom_sid *group_sid;
- [relative] security_acl *sacl; /* system ACL */
- [relative] security_acl *dacl; /* user (discretionary) ACL */
- } security_descriptor;
-
- typedef [public] struct {
- [range(0,0x40000),value(ndr_size_security_descriptor(sd,ndr->flags))] uint32 sd_size;
- [subcontext(4)] security_descriptor *sd;
- } sec_desc_buf;
-
- typedef [public] struct {
- dom_sid *user_sid;
- dom_sid *group_sid;
- uint32 num_sids;
- [size_is(num_sids)] dom_sid *sids[*];
- udlong privilege_mask;
- } security_token;
-
- /* bits that determine which parts of a security descriptor
- are being queried/set */
- typedef [public,bitmap32bit] bitmap {
- SECINFO_OWNER = 0x00000001,
- SECINFO_GROUP = 0x00000002,
- SECINFO_DACL = 0x00000004,
- SECINFO_SACL = 0x00000008,
- SECINFO_UNPROTECTED_SACL = 0x10000000,
- SECINFO_UNPROTECTED_DACL = 0x20000000,
- SECINFO_PROTECTED_SACL = 0x40000000,
- SECINFO_PROTECTED_DACL = 0x80000000
- } security_secinfo;
-
- typedef [public,bitmap32bit] bitmap {
- KERB_ENCTYPE_DES_CBC_CRC = 0x00000001,
- KERB_ENCTYPE_DES_CBC_MD5 = 0x00000002,
- KERB_ENCTYPE_RC4_HMAC_MD5 = 0x00000004,
- KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96 = 0x00000008,
- KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96 = 0x00000010
- } kerb_EncTypes;
-}
diff --git a/source4/librpc/ndr/ndr_sec_helper.c b/source4/librpc/ndr/ndr_dom_sid.c
index 1256d7dd2d..b986231b4f 100644
--- a/source4/librpc/ndr/ndr_sec_helper.c
+++ b/source4/librpc/ndr/ndr_dom_sid.c
@@ -4,6 +4,7 @@
fast routines for getting the wire size of security objects
Copyright (C) Andrew Tridgell 2003
+ Copyright (C) Stefan Metzmacher 2006-2008
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
@@ -54,68 +55,6 @@ size_t ndr_size_dom_sid0(const struct dom_sid *sid, int flags)
}
/*
- return the wire size of a security_ace
-*/
-size_t ndr_size_security_ace(const struct security_ace *ace, int flags)
-{
- size_t ret;
-
- if (!ace) return 0;
-
- ret = 8 + ndr_size_dom_sid(&ace->trustee, flags);
-
- switch (ace->type) {
- case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
- case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
- case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT:
- case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT:
- ret += 4; /* uint32 bitmap ace->object.object.flags */
- if (ace->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT) {
- ret += 16; /* GUID ace->object.object.type.type */
- }
- if (ace->object.object.flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) {
- ret += 16; /* GUID ace->object.object.inherited_typeinherited_type */
- }
- break;
- default:
- break;
- }
-
- return ret;
-}
-
-/*
- return the wire size of a security_acl
-*/
-size_t ndr_size_security_acl(const struct security_acl *acl, int flags)
-{
- size_t ret;
- int i;
- if (!acl) return 0;
- ret = 8;
- for (i=0;i<acl->num_aces;i++) {
- ret += ndr_size_security_ace(&acl->aces[i], flags);
- }
- return ret;
-}
-
-/*
- return the wire size of a security descriptor
-*/
-size_t ndr_size_security_descriptor(const struct security_descriptor *sd, int flags)
-{
- size_t ret;
- if (!sd) return 0;
-
- ret = 20;
- ret += ndr_size_dom_sid(sd->owner_sid, flags);
- ret += ndr_size_dom_sid(sd->group_sid, flags);
- ret += ndr_size_security_acl(sd->dacl, flags);
- ret += ndr_size_security_acl(sd->sacl, flags);
- return ret;
-}
-
-/*
print a dom_sid
*/
void ndr_print_dom_sid(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
diff --git a/source4/main.mk b/source4/main.mk
index 278c38454d..0a72487f8a 100644
--- a/source4/main.mk
+++ b/source4/main.mk
@@ -23,7 +23,7 @@ mkinclude ../lib/util/config.mk
mkinclude lib/tdr/config.mk
mkinclude lib/dbwrap/config.mk
mkinclude ../lib/crypto/config.mk
-mkinclude lib/torture/config.mk
+mkinclude ../lib/torture/config.mk
mkinclude lib/basic.mk
mkinclude lib/com/config.mk
# WMI fails at the moment
diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c
index 1e13474b9e..f08de72a38 100644
--- a/source4/ntvfs/posix/pvfs_resolve.c
+++ b/source4/ntvfs/posix/pvfs_resolve.c
@@ -186,23 +186,49 @@ static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs,
/*
parse a alternate data stream name
*/
-static NTSTATUS parse_stream_name(struct pvfs_filename *name, const char *s)
+static NTSTATUS parse_stream_name(struct smb_iconv_convenience *ic,
+ struct pvfs_filename *name,
+ const char *s)
{
char *p;
+ if (s[1] == '\0') {
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
name->stream_name = talloc_strdup(name, s+1);
if (name->stream_name == NULL) {
return NT_STATUS_NO_MEMORY;
}
- p = strchr_m(name->stream_name, ':');
- if (p == NULL) {
- name->stream_id = pvfs_name_hash(name->stream_name,
- strlen(name->stream_name));
- return NT_STATUS_OK;
- }
- if (strcasecmp_m(p, ":$DATA") != 0) {
- return NT_STATUS_OBJECT_NAME_INVALID;
+
+ p = name->stream_name;
+
+ while (*p) {
+ size_t c_size;
+ codepoint_t c = next_codepoint_convenience(ic, p, &c_size);
+
+ switch (c) {
+ case '/':
+ case '\\':
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ case ':':
+ *p= 0;
+ p++;
+ if (*p == '\0') {
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
+ if (strcasecmp_m(p, "$DATA") != 0) {
+ if (strchr_m(p, ':')) {
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ c_size = 0;
+ p--;
+ break;
+ }
+
+ p += c_size;
}
- *p = 0;
+
if (strcmp(name->stream_name, "") == 0) {
/*
* we don't set stream_name to NULL, here
@@ -233,6 +259,7 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name,
uint_t flags, struct pvfs_filename *name)
{
char *ret, *p, *p_start;
+ struct smb_iconv_convenience *ic = NULL;
NTSTATUS status;
name->original_name = talloc_strdup(name, cifs_name);
@@ -263,15 +290,21 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name,
for legal characters */
p_start = p;
+ ic = lp_iconv_convenience(pvfs->ntvfs->ctx->lp_ctx);
while (*p) {
size_t c_size;
- codepoint_t c = next_codepoint_convenience(lp_iconv_convenience(pvfs->ntvfs->ctx->lp_ctx), p, &c_size);
+ codepoint_t c = next_codepoint_convenience(ic, p, &c_size);
+
+ if (c <= 0x1F) {
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
+
switch (c) {
case '\\':
if (name->has_wildcard) {
/* wildcards are only allowed in the last part
of a name */
- return NT_STATUS_ILLEGAL_CHARACTER;
+ return NT_STATUS_OBJECT_NAME_INVALID;
}
if (p > p_start && (p[1] == '\\' || p[1] == '\0')) {
/* see if it is definately a "\\" or
@@ -288,12 +321,12 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name,
break;
case ':':
if (!(flags & PVFS_RESOLVE_STREAMS)) {
- return NT_STATUS_ILLEGAL_CHARACTER;
+ return NT_STATUS_OBJECT_NAME_INVALID;
}
if (name->has_wildcard) {
- return NT_STATUS_ILLEGAL_CHARACTER;
+ return NT_STATUS_OBJECT_NAME_INVALID;
}
- status = parse_stream_name(name, p);
+ status = parse_stream_name(ic, name, p);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -311,7 +344,7 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name,
break;
case '/':
case '|':
- return NT_STATUS_ILLEGAL_CHARACTER;
+ return NT_STATUS_OBJECT_NAME_INVALID;
case '.':
/* see if it is definately a .. or
. component. If it is then fail here, and
diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c
index 6f3f6799e7..6e888e5259 100644
--- a/source4/rpc_server/dcerpc_server.c
+++ b/source4/rpc_server/dcerpc_server.c
@@ -251,8 +251,8 @@ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
return NT_STATUS_OK;
}
-static NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p,
- DATA_BLOB *session_key)
+NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p,
+ DATA_BLOB *session_key)
{
if (p->auth_state.session_info->session_key.length) {
*session_key = p->auth_state.session_info->session_key;
diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c
index b3118d772d..e1fb187c52 100644
--- a/source4/rpc_server/samr/dcesrv_samr.c
+++ b/source4/rpc_server/samr/dcesrv_samr.c
@@ -37,26 +37,28 @@
#include "../lib/util/util_ldb.h"
#include "param/param.h"
-/* these query macros make samr_Query[User|Group]Info a bit easier to read */
+/* these query macros make samr_Query[User|Group|Alias]Info a bit easier to read */
#define QUERY_STRING(msg, field, attr) \
- r->out.info->field.string = samdb_result_string(msg, attr, "");
+ info->field.string = samdb_result_string(msg, attr, "");
#define QUERY_UINT(msg, field, attr) \
- r->out.info->field = samdb_result_uint(msg, attr, 0);
+ info->field = samdb_result_uint(msg, attr, 0);
#define QUERY_RID(msg, field, attr) \
- r->out.info->field = samdb_result_rid_from_sid(mem_ctx, msg, attr, 0);
+ info->field = samdb_result_rid_from_sid(mem_ctx, msg, attr, 0);
#define QUERY_UINT64(msg, field, attr) \
- r->out.info->field = samdb_result_uint64(msg, attr, 0);
+ info->field = samdb_result_uint64(msg, attr, 0);
#define QUERY_APASSC(msg, field, attr) \
- r->out.info->field = samdb_result_allow_password_change(sam_ctx, mem_ctx, \
- a_state->domain_state->domain_dn, msg, attr);
+ info->field = samdb_result_allow_password_change(sam_ctx, mem_ctx, \
+ a_state->domain_state->domain_dn, msg, attr);
#define QUERY_FPASSC(msg, field, attr) \
- r->out.info->field = samdb_result_force_password_change(sam_ctx, mem_ctx, \
- a_state->domain_state->domain_dn, msg);
+ info->field = samdb_result_force_password_change(sam_ctx, mem_ctx, \
+ a_state->domain_state->domain_dn, msg);
#define QUERY_LHOURS(msg, field, attr) \
- r->out.info->field = samdb_result_logon_hours(mem_ctx, msg, attr);
+ info->field = samdb_result_logon_hours(mem_ctx, msg, attr);
#define QUERY_AFLAGS(msg, field, attr) \
- r->out.info->field = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, a_state->domain_state->domain_dn);
+ info->field = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, a_state->domain_state->domain_dn);
+#define QUERY_PARAMETERS(msg, field, attr) \
+ info->field = samdb_result_parameters(mem_ctx, msg, attr);
/* these are used to make the Set[User|Group]Info code easier to follow */
@@ -136,6 +138,16 @@
set_el->flags = LDB_FLAG_MOD_REPLACE; \
} while (0)
+#define SET_PARAMETERS(msg, field, attr) do { \
+ struct ldb_message_element *set_el; \
+ if (samdb_msg_add_parameters(sam_ctx, mem_ctx, msg, attr, &r->in.info->field) != 0) { \
+ return NT_STATUS_NO_MEMORY; \
+ } \
+ set_el = ldb_msg_find_element(msg, attr); \
+ set_el->flags = LDB_FLAG_MOD_REPLACE; \
+} while (0)
+
+
/*
samr_Connect
@@ -217,7 +229,7 @@ static NTSTATUS dcesrv_samr_QuerySecurity(struct dcesrv_call_state *dce_call, TA
struct dcesrv_handle *h;
struct sec_desc_buf *sd;
- r->out.sdbuf = NULL;
+ *r->out.sdbuf = NULL;
DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
@@ -228,7 +240,7 @@ static NTSTATUS dcesrv_samr_QuerySecurity(struct dcesrv_call_state *dce_call, TA
sd->sd = samdb_default_security_descriptor(mem_ctx);
- r->out.sdbuf = sd;
+ *r->out.sdbuf = sd;
return NT_STATUS_OK;
}
@@ -265,7 +277,7 @@ static NTSTATUS dcesrv_samr_LookupDomain(struct dcesrv_call_state *dce_call, TAL
int ret;
struct ldb_dn *partitions_basedn;
- r->out.sid = NULL;
+ *r->out.sid = NULL;
DCESRV_PULL_HANDLE(h, r->in.connect_handle, SAMR_HANDLE_CONNECT);
@@ -307,7 +319,7 @@ static NTSTATUS dcesrv_samr_LookupDomain(struct dcesrv_call_state *dce_call, TAL
return NT_STATUS_NO_SUCH_DOMAIN;
}
- r->out.sid = sid;
+ *r->out.sid = sid;
return NT_STATUS_OK;
}
@@ -332,8 +344,8 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL
struct ldb_dn *partitions_basedn;
*r->out.resume_handle = 0;
- r->out.sam = NULL;
- r->out.num_entries = 0;
+ *r->out.sam = NULL;
+ *r->out.num_entries = 0;
DCESRV_PULL_HANDLE(h, r->in.connect_handle, SAMR_HANDLE_CONNECT);
@@ -389,9 +401,9 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL
}
}
- r->out.sam = array;
- r->out.num_entries = i;
- array->count = r->out.num_entries;
+ *r->out.sam = array;
+ *r->out.num_entries = i;
+ array->count = *r->out.num_entries;
return NT_STATUS_OK;
}
@@ -692,7 +704,7 @@ static NTSTATUS dcesrv_samr_info_DomInfo9(struct samr_domain_state *state,
struct ldb_message **dom_msgs,
struct samr_DomInfo9 *info)
{
- info->unknown = 1;
+ info->domain_server_state = DOMAIN_SERVER_ENABLED;
return NT_STATUS_OK;
}
@@ -765,18 +777,19 @@ static NTSTATUS dcesrv_samr_QueryDomainInfo(struct dcesrv_call_state *dce_call,
{
struct dcesrv_handle *h;
struct samr_domain_state *d_state;
+ union samr_DomainInfo *info;
struct ldb_message **dom_msgs;
const char * const *attrs = NULL;
- r->out.info = NULL;
+ *r->out.info = NULL;
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
d_state = h->data;
- r->out.info = talloc(mem_ctx, union samr_DomainInfo);
- if (!r->out.info) {
+ info = talloc(mem_ctx, union samr_DomainInfo);
+ if (!info) {
return NT_STATUS_NO_MEMORY;
}
@@ -881,47 +894,49 @@ static NTSTATUS dcesrv_samr_QueryDomainInfo(struct dcesrv_call_state *dce_call,
}
}
- ZERO_STRUCTP(r->out.info);
+ *r->out.info = info;
+
+ ZERO_STRUCTP(info);
switch (r->in.level) {
case 1:
return dcesrv_samr_info_DomInfo1(d_state, mem_ctx, dom_msgs,
- &r->out.info->info1);
+ &info->info1);
case 2:
return dcesrv_samr_info_DomGeneralInformation(d_state, mem_ctx, dom_msgs,
- &r->out.info->general);
+ &info->general);
case 3:
return dcesrv_samr_info_DomInfo3(d_state, mem_ctx, dom_msgs,
- &r->out.info->info3);
+ &info->info3);
case 4:
return dcesrv_samr_info_DomOEMInformation(d_state, mem_ctx, dom_msgs,
- &r->out.info->oem);
+ &info->oem);
case 5:
return dcesrv_samr_info_DomInfo5(d_state, mem_ctx, dom_msgs,
- &r->out.info->info5);
+ &info->info5);
case 6:
return dcesrv_samr_info_DomInfo6(d_state, mem_ctx, dom_msgs,
- &r->out.info->info6);
+ &info->info6);
case 7:
return dcesrv_samr_info_DomInfo7(d_state, mem_ctx, dom_msgs,
- &r->out.info->info7);
+ &info->info7);
case 8:
return dcesrv_samr_info_DomInfo8(d_state, mem_ctx, dom_msgs,
- &r->out.info->info8);
+ &info->info8);
case 9:
return dcesrv_samr_info_DomInfo9(d_state, mem_ctx, dom_msgs,
- &r->out.info->info9);
+ &info->info9);
case 11:
return dcesrv_samr_info_DomGeneralInformation2(d_state, mem_ctx, dom_msgs,
- &r->out.info->general2);
+ &info->general2);
case 12:
return dcesrv_samr_info_DomInfo12(d_state, mem_ctx, dom_msgs,
- &r->out.info->info12);
+ &info->info12);
case 13:
return dcesrv_samr_info_DomInfo13(d_state, mem_ctx, dom_msgs,
- &r->out.info->info13);
+ &info->info13);
}
-
+
return NT_STATUS_INVALID_INFO_CLASS;
}
@@ -1135,10 +1150,11 @@ static NTSTATUS dcesrv_samr_EnumDomainGroups(struct dcesrv_call_state *dce_call,
int ldb_cnt, count, i, first;
struct samr_SamEntry *entries;
const char * const attrs[3] = { "objectSid", "sAMAccountName", NULL };
+ struct samr_SamArray *sam;
*r->out.resume_handle = 0;
- r->out.sam = NULL;
- r->out.num_entries = 0;
+ *r->out.sam = NULL;
+ *r->out.num_entries = 0;
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
@@ -1189,20 +1205,22 @@ static NTSTATUS dcesrv_samr_EnumDomainGroups(struct dcesrv_call_state *dce_call,
/* return the rest, limit by max_size. Note that we
use the w2k3 element size value of 54 */
- r->out.num_entries = count - first;
- r->out.num_entries = MIN(r->out.num_entries,
+ *r->out.num_entries = count - first;
+ *r->out.num_entries = MIN(*r->out.num_entries,
1+(r->in.max_size/SAMR_ENUM_USERS_MULTIPLIER));
- r->out.sam = talloc(mem_ctx, struct samr_SamArray);
- if (!r->out.sam) {
+ sam = talloc(mem_ctx, struct samr_SamArray);
+ if (!sam) {
return NT_STATUS_NO_MEMORY;
}
- r->out.sam->entries = entries+first;
- r->out.sam->count = r->out.num_entries;
+ sam->entries = entries+first;
+ sam->count = *r->out.num_entries;
+
+ *r->out.sam = sam;
- if (r->out.num_entries < count - first) {
- *r->out.resume_handle = entries[first+r->out.num_entries-1].idx;
+ if (*r->out.num_entries < count - first) {
+ *r->out.resume_handle = entries[first+*r->out.num_entries-1].idx;
return STATUS_MORE_ENTRIES;
}
@@ -1492,10 +1510,11 @@ static NTSTATUS dcesrv_samr_EnumDomainUsers(struct dcesrv_call_state *dce_call,
int ret, num_filtered_entries, i, first;
struct samr_SamEntry *entries;
const char * const attrs[] = { "objectSid", "sAMAccountName", "userAccountControl", NULL };
+ struct samr_SamArray *sam;
*r->out.resume_handle = 0;
- r->out.sam = NULL;
- r->out.num_entries = 0;
+ *r->out.sam = NULL;
+ *r->out.num_entries = 0;
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
@@ -1539,24 +1558,26 @@ static NTSTATUS dcesrv_samr_EnumDomainUsers(struct dcesrv_call_state *dce_call,
/* return the rest, limit by max_size. Note that we
use the w2k3 element size value of 54 */
- r->out.num_entries = num_filtered_entries - first;
- r->out.num_entries = MIN(r->out.num_entries,
+ *r->out.num_entries = num_filtered_entries - first;
+ *r->out.num_entries = MIN(*r->out.num_entries,
1+(r->in.max_size/SAMR_ENUM_USERS_MULTIPLIER));
- r->out.sam = talloc(mem_ctx, struct samr_SamArray);
- if (!r->out.sam) {
+ sam = talloc(mem_ctx, struct samr_SamArray);
+ if (!sam) {
return NT_STATUS_NO_MEMORY;
}
- r->out.sam->entries = entries+first;
- r->out.sam->count = r->out.num_entries;
+ sam->entries = entries+first;
+ sam->count = *r->out.num_entries;
+
+ *r->out.sam = sam;
if (first == num_filtered_entries) {
return NT_STATUS_OK;
}
- if (r->out.num_entries < num_filtered_entries - first) {
- *r->out.resume_handle = entries[first+r->out.num_entries-1].idx;
+ if (*r->out.num_entries < num_filtered_entries - first) {
+ *r->out.resume_handle = entries[first+*r->out.num_entries-1].idx;
return STATUS_MORE_ENTRIES;
}
@@ -1685,10 +1706,11 @@ static NTSTATUS dcesrv_samr_EnumDomainAliases(struct dcesrv_call_state *dce_call
int ldb_cnt, count, i, first;
struct samr_SamEntry *entries;
const char * const attrs[3] = { "objectSid", "sAMAccountName", NULL };
+ struct samr_SamArray *sam;
*r->out.resume_handle = 0;
- r->out.sam = NULL;
- r->out.num_entries = 0;
+ *r->out.sam = NULL;
+ *r->out.num_entries = 0;
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
@@ -1748,20 +1770,22 @@ static NTSTATUS dcesrv_samr_EnumDomainAliases(struct dcesrv_call_state *dce_call
return NT_STATUS_OK;
}
- r->out.num_entries = count - first;
- r->out.num_entries = MIN(r->out.num_entries, 1000);
+ *r->out.num_entries = count - first;
+ *r->out.num_entries = MIN(*r->out.num_entries, 1000);
- r->out.sam = talloc(mem_ctx, struct samr_SamArray);
- if (!r->out.sam) {
+ sam = talloc(mem_ctx, struct samr_SamArray);
+ if (!sam) {
return NT_STATUS_NO_MEMORY;
}
- r->out.sam->entries = entries+first;
- r->out.sam->count = r->out.num_entries;
+ sam->entries = entries+first;
+ sam->count = *r->out.num_entries;
+
+ *r->out.sam = sam;
- if (r->out.num_entries < count - first) {
+ if (*r->out.num_entries < count - first) {
*r->out.resume_handle =
- entries[first+r->out.num_entries-1].idx;
+ entries[first+*r->out.num_entries-1].idx;
return STATUS_MORE_ENTRIES;
}
@@ -1859,8 +1883,8 @@ static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALL
const char * const attrs[] = { "sAMAccountType", "objectSid", NULL };
int count;
- ZERO_STRUCT(r->out.rids);
- ZERO_STRUCT(r->out.types);
+ ZERO_STRUCTP(r->out.rids);
+ ZERO_STRUCTP(r->out.types);
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
@@ -1870,13 +1894,13 @@ static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALL
return NT_STATUS_OK;
}
- r->out.rids.ids = talloc_array(mem_ctx, uint32_t, r->in.num_names);
- r->out.types.ids = talloc_array(mem_ctx, uint32_t, r->in.num_names);
- if (!r->out.rids.ids || !r->out.types.ids) {
+ r->out.rids->ids = talloc_array(mem_ctx, uint32_t, r->in.num_names);
+ r->out.types->ids = talloc_array(mem_ctx, uint32_t, r->in.num_names);
+ if (!r->out.rids->ids || !r->out.types->ids) {
return NT_STATUS_NO_MEMORY;
}
- r->out.rids.count = r->in.num_names;
- r->out.types.count = r->in.num_names;
+ r->out.rids->count = r->in.num_names;
+ r->out.types->count = r->in.num_names;
num_mapped = 0;
@@ -1885,8 +1909,8 @@ static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALL
struct dom_sid *sid;
uint32_t atype, rtype;
- r->out.rids.ids[i] = 0;
- r->out.types.ids[i] = SID_NAME_UNKNOWN;
+ r->out.rids->ids[i] = 0;
+ r->out.types->ids[i] = SID_NAME_UNKNOWN;
count = gendb_search(d_state->sam_ctx, mem_ctx, d_state->domain_dn, &res, attrs,
"sAMAccountName=%s",
@@ -1915,8 +1939,8 @@ static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALL
continue;
}
- r->out.rids.ids[i] = sid->sub_auths[sid->num_auths-1];
- r->out.types.ids[i] = rtype;
+ r->out.rids->ids[i] = sid->sub_auths[sid->num_auths-1];
+ r->out.types->ids[i] = rtype;
num_mapped++;
}
@@ -1940,8 +1964,8 @@ static NTSTATUS dcesrv_samr_LookupRids(struct dcesrv_call_state *dce_call, TALLO
struct lsa_String *names;
uint32_t *ids;
- ZERO_STRUCT(r->out.names);
- ZERO_STRUCT(r->out.types);
+ ZERO_STRUCTP(r->out.names);
+ ZERO_STRUCTP(r->out.types);
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
@@ -2002,11 +2026,11 @@ static NTSTATUS dcesrv_samr_LookupRids(struct dcesrv_call_state *dce_call, TALLO
}
}
- r->out.names.names = names;
- r->out.names.count = r->in.num_rids;
+ r->out.names->names = names;
+ r->out.names->count = r->in.num_rids;
- r->out.types.ids = ids;
- r->out.types.count = r->in.num_rids;
+ r->out.types->ids = ids;
+ r->out.types->count = r->in.num_rids;
return status;
}
@@ -2103,8 +2127,9 @@ static NTSTATUS dcesrv_samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, T
const char * const attrs[4] = { "sAMAccountName", "description",
"numMembers", NULL };
int ret;
+ union samr_GroupInfo *info;
- r->out.info = NULL;
+ *r->out.info = NULL;
DCESRV_PULL_HANDLE(h, r->in.group_handle, SAMR_HANDLE_GROUP);
@@ -2127,17 +2152,16 @@ static NTSTATUS dcesrv_samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, T
msg = res->msgs[0];
/* allocate the info structure */
- r->out.info = talloc(mem_ctx, union samr_GroupInfo);
- if (r->out.info == NULL) {
+ info = talloc_zero(mem_ctx, union samr_GroupInfo);
+ if (info == NULL) {
return NT_STATUS_NO_MEMORY;
}
- ZERO_STRUCTP(r->out.info);
/* Fill in the level */
switch (r->in.level) {
case GROUPINFOALL:
QUERY_STRING(msg, all.name, "sAMAccountName");
- r->out.info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
+ info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
QUERY_UINT (msg, all.num_members, "numMembers")
QUERY_STRING(msg, all.description, "description");
break;
@@ -2145,22 +2169,24 @@ static NTSTATUS dcesrv_samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, T
QUERY_STRING(msg, name, "sAMAccountName");
break;
case GROUPINFOATTRIBUTES:
- r->out.info->attributes.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
+ info->attributes.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
break;
case GROUPINFODESCRIPTION:
QUERY_STRING(msg, description, "description");
break;
case GROUPINFOALL2:
QUERY_STRING(msg, all2.name, "sAMAccountName");
- r->out.info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
+ info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
QUERY_UINT (msg, all2.num_members, "numMembers")
QUERY_STRING(msg, all2.description, "description");
break;
default:
- r->out.info = NULL;
+ talloc_free(info);
return NT_STATUS_INVALID_INFO_CLASS;
}
-
+
+ *r->out.info = info;
+
return NT_STATUS_OK;
}
@@ -2467,7 +2493,7 @@ static NTSTATUS dcesrv_samr_QueryGroupMember(struct dcesrv_call_state *dce_call,
}
}
- r->out.rids = array;
+ *r->out.rids = array;
return NT_STATUS_OK;
}
@@ -2574,8 +2600,9 @@ static NTSTATUS dcesrv_samr_QueryAliasInfo(struct dcesrv_call_state *dce_call, T
const char * const attrs[4] = { "sAMAccountName", "description",
"numMembers", NULL };
int ret;
+ union samr_AliasInfo *info;
- r->out.info = NULL;
+ *r->out.info = NULL;
DCESRV_PULL_HANDLE(h, r->in.alias_handle, SAMR_HANDLE_ALIAS);
@@ -2590,11 +2617,10 @@ static NTSTATUS dcesrv_samr_QueryAliasInfo(struct dcesrv_call_state *dce_call, T
msg = res[0];
/* allocate the info structure */
- r->out.info = talloc(mem_ctx, union samr_AliasInfo);
- if (r->out.info == NULL) {
+ info = talloc_zero(mem_ctx, union samr_AliasInfo);
+ if (info == NULL) {
return NT_STATUS_NO_MEMORY;
}
- ZERO_STRUCTP(r->out.info);
switch(r->in.level) {
case ALIASINFOALL:
@@ -2609,10 +2635,12 @@ static NTSTATUS dcesrv_samr_QueryAliasInfo(struct dcesrv_call_state *dce_call, T
QUERY_STRING(msg, description, "description");
break;
default:
- r->out.info = NULL;
+ talloc_free(info);
return NT_STATUS_INVALID_INFO_CLASS;
}
-
+
+ *r->out.info = info;
+
return NT_STATUS_OK;
}
@@ -2989,8 +3017,9 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA
struct ldb_context *sam_ctx;
const char * const *attrs = NULL;
+ union samr_UserInfo *info;
- r->out.info = NULL;
+ *r->out.info = NULL;
DCESRV_PULL_HANDLE(h, r->in.user_handle, SAMR_HANDLE_USER);
@@ -3175,11 +3204,10 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA
msg = res[0];
/* allocate the info structure */
- r->out.info = talloc(mem_ctx, union samr_UserInfo);
- if (r->out.info == NULL) {
+ info = talloc_zero(mem_ctx, union samr_UserInfo);
+ if (info == NULL) {
return NT_STATUS_NO_MEMORY;
}
- ZERO_STRUCTP(r->out.info);
/* fill in the reply */
switch (r->in.level) {
@@ -3290,7 +3318,7 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA
break;
case 20:
- QUERY_STRING(msg, info20.parameters, "userParameters");
+ QUERY_PARAMETERS(msg, info20.parameters, "userParameters");
break;
case 21:
@@ -3309,11 +3337,11 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA
QUERY_STRING(msg, info21.description, "description");
QUERY_STRING(msg, info21.workstations, "userWorkstations");
QUERY_STRING(msg, info21.comment, "comment");
- QUERY_STRING(msg, info21.parameters, "userParameters");
+ QUERY_PARAMETERS(msg, info21.parameters, "userParameters");
QUERY_RID (msg, info21.rid, "objectSid");
QUERY_UINT (msg, info21.primary_gid, "primaryGroupID");
QUERY_AFLAGS(msg, info21.acct_flags, "userAccountControl");
- r->out.info->info21.fields_present = 0x00FFFFFF;
+ info->info21.fields_present = 0x00FFFFFF;
QUERY_LHOURS(msg, info21.logon_hours, "logonHours");
QUERY_UINT (msg, info21.bad_password_count, "badPwdCount");
QUERY_UINT (msg, info21.logon_count, "logonCount");
@@ -3323,10 +3351,12 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA
default:
- r->out.info = NULL;
+ talloc_free(info);
return NT_STATUS_INVALID_INFO_CLASS;
}
-
+
+ *r->out.info = info;
+
return NT_STATUS_OK;
}
@@ -3416,7 +3446,7 @@ static NTSTATUS dcesrv_samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALL
break;
case 20:
- SET_STRING(msg, info20.parameters, "userParameters");
+ SET_PARAMETERS(msg, info20.parameters, "userParameters");
break;
case 21:
@@ -3446,7 +3476,7 @@ static NTSTATUS dcesrv_samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALL
IFSET(SAMR_FIELD_ACCT_FLAGS)
SET_AFLAGS(msg, info21.acct_flags, "userAccountControl");
IFSET(SAMR_FIELD_PARAMETERS)
- SET_STRING(msg, info21.parameters, "userParameters");
+ SET_PARAMETERS(msg, info21.parameters, "userParameters");
IFSET(SAMR_FIELD_COUNTRY_CODE)
SET_UINT (msg, info21.country_code, "countryCode");
IFSET(SAMR_FIELD_CODE_PAGE)
@@ -3477,7 +3507,7 @@ static NTSTATUS dcesrv_samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALL
IFSET(SAMR_FIELD_ACCT_FLAGS)
SET_AFLAGS(msg, info23.info.acct_flags, "userAccountControl");
IFSET(SAMR_FIELD_PARAMETERS)
- SET_STRING(msg, info23.info.parameters, "userParameters");
+ SET_PARAMETERS(msg, info23.info.parameters, "userParameters");
IFSET(SAMR_FIELD_COUNTRY_CODE)
SET_UINT (msg, info23.info.country_code, "countryCode");
IFSET(SAMR_FIELD_CODE_PAGE)
@@ -3533,7 +3563,7 @@ static NTSTATUS dcesrv_samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALL
IFSET(SAMR_FIELD_ACCT_FLAGS)
SET_AFLAGS(msg, info25.info.acct_flags, "userAccountControl");
IFSET(SAMR_FIELD_PARAMETERS)
- SET_STRING(msg, info25.info.parameters, "userParameters");
+ SET_PARAMETERS(msg, info25.info.parameters, "userParameters");
IFSET(SAMR_FIELD_COUNTRY_CODE)
SET_UINT (msg, info25.info.country_code, "countryCode");
IFSET(SAMR_FIELD_CODE_PAGE)
@@ -3650,7 +3680,7 @@ static NTSTATUS dcesrv_samr_GetGroupsForUser(struct dcesrv_call_state *dce_call,
}
}
- r->out.rids = array;
+ *r->out.rids = array;
return NT_STATUS_OK;
}
@@ -3808,65 +3838,65 @@ static NTSTATUS dcesrv_samr_QueryDisplayInfo(struct dcesrv_call_state *dce_call,
count += 1;
}
- r->out.total_size = count;
+ *r->out.total_size = count;
if (r->in.start_idx >= count) {
- r->out.returned_size = 0;
+ *r->out.returned_size = 0;
switch(r->in.level) {
case 1:
- r->out.info.info1.count = r->out.returned_size;
- r->out.info.info1.entries = NULL;
+ r->out.info->info1.count = *r->out.returned_size;
+ r->out.info->info1.entries = NULL;
break;
case 2:
- r->out.info.info2.count = r->out.returned_size;
- r->out.info.info2.entries = NULL;
+ r->out.info->info2.count = *r->out.returned_size;
+ r->out.info->info2.entries = NULL;
break;
case 3:
- r->out.info.info3.count = r->out.returned_size;
- r->out.info.info3.entries = NULL;
+ r->out.info->info3.count = *r->out.returned_size;
+ r->out.info->info3.entries = NULL;
break;
case 4:
- r->out.info.info4.count = r->out.returned_size;
- r->out.info.info4.entries = NULL;
+ r->out.info->info4.count = *r->out.returned_size;
+ r->out.info->info4.entries = NULL;
break;
case 5:
- r->out.info.info5.count = r->out.returned_size;
- r->out.info.info5.entries = NULL;
+ r->out.info->info5.count = *r->out.returned_size;
+ r->out.info->info5.entries = NULL;
break;
}
} else {
- r->out.returned_size = MIN(count - r->in.start_idx,
+ *r->out.returned_size = MIN(count - r->in.start_idx,
r->in.max_entries);
switch(r->in.level) {
case 1:
- r->out.info.info1.count = r->out.returned_size;
- r->out.info.info1.entries =
+ r->out.info->info1.count = *r->out.returned_size;
+ r->out.info->info1.entries =
&(entriesGeneral[r->in.start_idx]);
break;
case 2:
- r->out.info.info2.count = r->out.returned_size;
- r->out.info.info2.entries =
+ r->out.info->info2.count = *r->out.returned_size;
+ r->out.info->info2.entries =
&(entriesFull[r->in.start_idx]);
break;
case 3:
- r->out.info.info3.count = r->out.returned_size;
- r->out.info.info3.entries =
+ r->out.info->info3.count = *r->out.returned_size;
+ r->out.info->info3.entries =
&(entriesFullGroup[r->in.start_idx]);
break;
case 4:
- r->out.info.info4.count = r->out.returned_size;
- r->out.info.info4.entries =
+ r->out.info->info4.count = *r->out.returned_size;
+ r->out.info->info4.entries =
&(entriesAscii[r->in.start_idx]);
break;
case 5:
- r->out.info.info5.count = r->out.returned_size;
- r->out.info.info5.entries =
+ r->out.info->info5.count = *r->out.returned_size;
+ r->out.info->info5.entries =
&(entriesAscii[r->in.start_idx]);
break;
}
}
- return (r->out.returned_size < (count - r->in.start_idx)) ?
+ return (*r->out.returned_size < (count - r->in.start_idx)) ?
STATUS_MORE_ENTRIES : NT_STATUS_OK;
}
@@ -3910,18 +3940,18 @@ static NTSTATUS dcesrv_samr_GetUserPwInfo(struct dcesrv_call_state *dce_call, TA
struct dcesrv_handle *h;
struct samr_account_state *a_state;
- ZERO_STRUCT(r->out.info);
+ ZERO_STRUCTP(r->out.info);
DCESRV_PULL_HANDLE(h, r->in.user_handle, SAMR_HANDLE_USER);
a_state = h->data;
- r->out.info.min_password_length = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0,
- a_state->domain_state->domain_dn, "minPwdLength",
- NULL);
- r->out.info.password_properties = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0,
- a_state->account_dn,
- "pwdProperties", NULL);
+ r->out.info->min_password_length = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0,
+ a_state->domain_state->domain_dn, "minPwdLength",
+ NULL);
+ r->out.info->password_properties = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0,
+ a_state->account_dn,
+ "pwdProperties", NULL);
return NT_STATUS_OK;
}
@@ -4008,11 +4038,10 @@ static NTSTATUS dcesrv_samr_QueryDomainInfo2(struct dcesrv_call_state *dce_call,
ZERO_STRUCT(r1.out);
r1.in.domain_handle = r->in.domain_handle;
r1.in.level = r->in.level;
-
+ r1.out.info = r->out.info;
+
status = dcesrv_samr_QueryDomainInfo(dce_call, mem_ctx, &r1);
- r->out.info = r1.out.info;
-
return status;
}
@@ -4028,13 +4057,11 @@ static NTSTATUS dcesrv_samr_QueryUserInfo2(struct dcesrv_call_state *dce_call, T
struct samr_QueryUserInfo r1;
NTSTATUS status;
- ZERO_STRUCT(r1.out);
r1.in.user_handle = r->in.user_handle;
r1.in.level = r->in.level;
+ r1.out.info = r->out.info;
status = dcesrv_samr_QueryUserInfo(dce_call, mem_ctx, &r1);
-
- r->out.info = r1.out.info;
return status;
}
@@ -4054,14 +4081,12 @@ static NTSTATUS dcesrv_samr_QueryDisplayInfo2(struct dcesrv_call_state *dce_call
q.in.start_idx = r->in.start_idx;
q.in.max_entries = r->in.max_entries;
q.in.buf_size = r->in.buf_size;
- ZERO_STRUCT(q.out);
+ q.out.total_size = r->out.total_size;
+ q.out.returned_size = r->out.returned_size;
+ q.out.info = r->out.info;
result = dcesrv_samr_QueryDisplayInfo(dce_call, mem_ctx, &q);
- r->out.total_size = q.out.total_size;
- r->out.returned_size = q.out.returned_size;
- r->out.info = q.out.info;
-
return result;
}
@@ -4090,14 +4115,12 @@ static NTSTATUS dcesrv_samr_QueryDisplayInfo3(struct dcesrv_call_state *dce_call
q.in.start_idx = r->in.start_idx;
q.in.max_entries = r->in.max_entries;
q.in.buf_size = r->in.buf_size;
- ZERO_STRUCT(q.out);
+ q.out.total_size = r->out.total_size;
+ q.out.returned_size = r->out.returned_size;
+ q.out.info = r->out.info;
result = dcesrv_samr_QueryDisplayInfo(dce_call, mem_ctx, &q);
- r->out.total_size = q.out.total_size;
- r->out.returned_size = q.out.returned_size;
- r->out.info = q.out.info;
-
return result;
}
@@ -4138,7 +4161,7 @@ static NTSTATUS dcesrv_samr_GetDomPwInfo(struct dcesrv_call_state *dce_call, TAL
const char * const attrs[] = {"minPwdLength", "pwdProperties", NULL };
struct ldb_context *sam_ctx;
- ZERO_STRUCT(r->out.info);
+ ZERO_STRUCTP(r->out.info);
sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
if (sam_ctx == NULL) {
@@ -4156,8 +4179,8 @@ static NTSTATUS dcesrv_samr_GetDomPwInfo(struct dcesrv_call_state *dce_call, TAL
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- r->out.info.min_password_length = samdb_result_uint(msgs[0], "minPwdLength", 0);
- r->out.info.password_properties = samdb_result_uint(msgs[0], "pwdProperties", 1);
+ r->out.info->min_password_length = samdb_result_uint(msgs[0], "minPwdLength", 0);
+ r->out.info->password_properties = samdb_result_uint(msgs[0], "pwdProperties", 1);
talloc_free(msgs);
@@ -4267,9 +4290,9 @@ static NTSTATUS dcesrv_samr_Connect5(struct dcesrv_call_state *dce_call, TALLOC_
status = dcesrv_samr_Connect(dce_call, mem_ctx, &c);
- r->out.info->info1.client_version = SAMR_CONNECT_AFTER_W2K;
- r->out.info->info1.unknown2 = 0;
- r->out.level = r->in.level;
+ r->out.info_out->info1.client_version = SAMR_CONNECT_AFTER_W2K;
+ r->out.info_out->info1.unknown2 = 0;
+ *r->out.level_out = r->in.level_in;
return status;
}
@@ -4289,8 +4312,8 @@ static NTSTATUS dcesrv_samr_RidToSid(struct dcesrv_call_state *dce_call, TALLOC_
d_state = h->data;
/* form the users SID */
- r->out.sid = dom_sid_add_rid(mem_ctx, d_state->domain_sid, r->in.rid);
- if (!r->out.sid) {
+ *r->out.sid = dom_sid_add_rid(mem_ctx, d_state->domain_sid, r->in.rid);
+ if (!*r->out.sid) {
return NT_STATUS_NO_MEMORY;
}
diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c
index 1eb6a4f37c..ff8215a673 100644
--- a/source4/rpc_server/samr/samr_password.c
+++ b/source4/rpc_server/samr/samr_password.c
@@ -352,7 +352,8 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
uint8_t new_nt_hash[16], new_lm_hash[16];
struct samr_Password nt_verifier, lm_verifier;
- ZERO_STRUCT(r->out);
+ *r->out.dominfo = NULL;
+ *r->out.reject = NULL;
if (r->in.nt_password == NULL ||
r->in.nt_verifier == NULL) {
@@ -495,8 +496,8 @@ failed:
talloc_free(sam_ctx);
reject = talloc(mem_ctx, struct samr_ChangeReject);
- r->out.dominfo = dominfo;
- r->out.reject = reject;
+ *r->out.dominfo = dominfo;
+ *r->out.reject = reject;
if (reject == NULL) {
return status;
@@ -518,6 +519,8 @@ NTSTATUS dcesrv_samr_ChangePasswordUser2(struct dcesrv_call_state *dce_call, TAL
struct samr_ChangePasswordUser2 *r)
{
struct samr_ChangePasswordUser3 r2;
+ struct samr_DomInfo1 *dominfo = NULL;
+ struct samr_ChangeReject *reject = NULL;
r2.in.server = r->in.server;
r2.in.account = r->in.account;
@@ -527,6 +530,8 @@ NTSTATUS dcesrv_samr_ChangePasswordUser2(struct dcesrv_call_state *dce_call, TAL
r2.in.lm_password = r->in.lm_password;
r2.in.lm_verifier = r->in.lm_verifier;
r2.in.password3 = NULL;
+ r2.out.dominfo = &dominfo;
+ r2.out.reject = &reject;
return dcesrv_samr_ChangePasswordUser3(dce_call, mem_ctx, &r2);
}
diff --git a/source4/rpc_server/service_rpc.c b/source4/rpc_server/service_rpc.c
index f168614ad5..bb4d6bdaf2 100644
--- a/source4/rpc_server/service_rpc.c
+++ b/source4/rpc_server/service_rpc.c
@@ -27,6 +27,7 @@
#include "auth/gensec/gensec.h"
#include "../lib/util/dlinklist.h"
#include "rpc_server/dcerpc_server.h"
+#include "rpc_server/dcerpc_server_proto.h"
#include "lib/events/events.h"
#include "smbd/service_task.h"
#include "smbd/service_stream.h"
@@ -139,6 +140,10 @@ static void dcesrv_sock_accept(struct stream_connection *srv_conn)
dcesrv_conn->transport.get_my_addr = dcesrv_sock_get_my_addr;
dcesrv_conn->transport.get_peer_addr = dcesrv_sock_get_peer_addr;
+ if (dcesrv_sock->endpoint->ep_description->transport == NCACN_NP) {
+ dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
+ }
+
srv_conn->private = dcesrv_conn;
irpc_add_name(srv_conn->msg_ctx, "rpc_server");
@@ -287,12 +292,10 @@ static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
return status;
}
-
-/*
- add a socket address to the list of events, one event per dcerpc endpoint
-*/
-static NTSTATUS add_socket_rpc_pipe_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
- struct event_context *event_ctx, const struct model_ops *model_ops)
+static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
+ struct loadparm_context *lp_ctx,
+ struct dcesrv_endpoint *e,
+ struct event_context *event_ctx, const struct model_ops *model_ops)
{
struct dcesrv_socket_context *dcesrv_sock;
NTSTATUS status;
@@ -309,30 +312,16 @@ static NTSTATUS add_socket_rpc_pipe_iface(struct dcesrv_context *dce_ctx, struct
dcesrv_sock->endpoint = e;
dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
- status = NT_STATUS_OK;
-#if 0
-
- status = stream_setup_smb_pipe(event_ctx, model_ops, &dcesrv_stream_ops,
- e->ep_description->endpoint, dcesrv_sock);
+ status = stream_setup_named_pipe(event_ctx, lp_ctx,
+ model_ops, &dcesrv_stream_ops,
+ e->ep_description->endpoint, dcesrv_sock);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
+ DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
e->ep_description->endpoint, nt_errstr(status)));
+ return status;
}
-#endif
- return status;
-}
-
-static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
- struct loadparm_context *lp_ctx,
- struct dcesrv_endpoint *e,
- struct event_context *event_ctx, const struct model_ops *model_ops)
-{
- NTSTATUS status;
-
- status = add_socket_rpc_pipe_iface(dce_ctx, e, event_ctx, model_ops);
- NT_STATUS_NOT_OK_RETURN(status);
- return status;
+ return NT_STATUS_OK;
}
/*
diff --git a/source4/selftest/knownfail b/source4/selftest/knownfail
index f99db4fb1b..9649a1f644 100644
--- a/source4/selftest/knownfail
+++ b/source4/selftest/knownfail
@@ -35,6 +35,7 @@ rpc.netlogon.*.DsRAddressToSitenamesW
rpc.netlogon.*.DsRAddressToSitenamesExW
rpc.netlogon.*.GetPassword
rpc.netlogon.*.GetTrustPasswords
+rpc.netlogon.*.DatabaseRedo
base.charset.*.Testing partial surrogate
.*net.api.delshare.* # DelShare isn't implemented yet
rap.*netservergetinfo
diff --git a/source4/selftest/skip b/source4/selftest/skip
index e3e2d2d525..f1500ff315 100644
--- a/source4/selftest/skip
+++ b/source4/selftest/skip
@@ -23,6 +23,7 @@ base.scan.maxfid
raw.hold.oplock # Not a test, but a way to block other clients for a test
raw.ping.pong # Needs second server to test
rpc.samr_accessmask
+samba4.rpc.samr.passwords.pwdlastset # Not provided by Samba 4 yet
raw.scan.eamax
samba4.ntvfs.cifs.raw.qfileinfo.ipc
smb2.notify
@@ -49,6 +50,7 @@ rpc.initshutdown # Not provided by Samba 4
rpc.svcctl # Not provided by Samba 4
rpc.atsvc # Not provided by Samba 4
rpc.frsapi # Not provided by Samba 4
+rpc.ntsvcs # Not provided by Samba 4
^samba4.base.samba3.* # Samba3-specific test
^samba4.ntvfs.cifs.base.samba3.* # Samba3-specific test
^samba4.raw.samba3.* # Samba3-specific test
diff --git a/source4/setup/schema-map-fedora-ds-1.0 b/source4/setup/schema-map-fedora-ds-1.0
index e55ef0a9e7..74d9e2ac5a 100644
--- a/source4/setup/schema-map-fedora-ds-1.0
+++ b/source4/setup/schema-map-fedora-ds-1.0
@@ -23,9 +23,9 @@ aci
1.2.840.113556.1.4.906:1.3.6.1.4.1.1466.115.121.1.27
#This case insensitive string isn't available
1.2.840.113556.1.4.905:1.3.6.1.4.1.1466.115.121.1.15
-#This type of DN isn't in OpenLDAP
-1.2.840.113556.1.4.903:1.3.6.1.4.1.1466.115.121.1.12
#Treat Security Descriptors as binary
1.2.840.113556.1.4.907:1.3.6.1.4.1.1466.115.121.1.40
#NumbericString is not supported in Fedora DS 1.0, map to a directory string
1.3.6.1.4.1.1466.115.121.1.36:1.3.6.1.4.1.1466.115.121.1.15
+#Treat Object(DN-Binary) as a binary blob
+1.2.840.113556.1.4.903:1.3.6.1.4.1.1466.115.121.1.40
diff --git a/source4/setup/schema-map-openldap-2.3 b/source4/setup/schema-map-openldap-2.3
index 7de2e67b5e..bff1695c8f 100644
--- a/source4/setup/schema-map-openldap-2.3
+++ b/source4/setup/schema-map-openldap-2.3
@@ -35,10 +35,10 @@ modifyTimeStamp:samba4ModifyTimestamp
1.2.840.113556.1.4.906:1.3.6.1.4.1.1466.115.121.1.27
#This case insensitive string isn't available
1.2.840.113556.1.4.905:1.3.6.1.4.1.1466.115.121.1.44
-#This type of DN isn't in OpenLDAP
-1.2.840.113556.1.4.903:1.3.6.1.4.1.1466.115.121.1.12
#Treat Security Descriptors as binary
1.2.840.113556.1.4.907:1.3.6.1.4.1.1466.115.121.1.40
#Treat OIDs as case insensitive strings (as otherwise ldap class and
#attribute names, declared at OIDs fail
1.3.6.1.4.1.1466.115.121.1.38:1.3.6.1.4.1.1466.115.121.1.44
+#Treat Object(DN-Binary) as a binary blob
+1.2.840.113556.1.4.903:1.3.6.1.4.1.1466.115.121.1.40
diff --git a/source4/smbd/config.mk b/source4/smbd/config.mk
index b5babd4d69..63105d368c 100644
--- a/source4/smbd/config.mk
+++ b/source4/smbd/config.mk
@@ -2,11 +2,12 @@
[SUBSYSTEM::service]
PRIVATE_DEPENDENCIES = \
- MESSAGING samba-socket
+ MESSAGING samba-socket NDR_NAMED_PIPE_AUTH
service_OBJ_FILES = $(addprefix $(smbdsrcdir)/, \
service.o \
service_stream.o \
+ service_named_pipe.o \
service_task.o)
$(eval $(call proto_header_template,$(smbdsrcdir)/service_proto.h,$(service_OBJ_FILES:.o=.c)))
diff --git a/source4/smbd/service_named_pipe.c b/source4/smbd/service_named_pipe.c
new file mode 100644
index 0000000000..b2b102c01f
--- /dev/null
+++ b/source4/smbd/service_named_pipe.c
@@ -0,0 +1,366 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ helper functions for NAMED PIPE servers
+
+ Copyright (C) Stefan (metze) Metzmacher 2008
+
+ 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 "lib/socket/socket.h"
+#include "smbd/service.h"
+#include "param/param.h"
+#include "auth/session.h"
+#include "lib/stream/packet.h"
+#include "librpc/gen_ndr/ndr_named_pipe_auth.h"
+#include "system/passwd.h"
+
+struct named_pipe_socket {
+ const char *pipe_name;
+ const char *pipe_path;
+ const struct stream_server_ops *ops;
+ void *private_data;
+};
+
+struct named_pipe_connection {
+ struct stream_connection *connection;
+ struct packet_context *packet;
+ const struct named_pipe_socket *pipe_sock;
+ NTSTATUS status;
+};
+
+static void named_pipe_handover_connection(void *private_data)
+{
+ struct named_pipe_connection *pipe_conn = talloc_get_type(
+ private_data, struct named_pipe_connection);
+ struct stream_connection *conn = pipe_conn->connection;
+
+ EVENT_FD_NOT_WRITEABLE(conn->event.fde);
+
+ if (!NT_STATUS_IS_OK(pipe_conn->status)) {
+ stream_terminate_connection(conn, nt_errstr(pipe_conn->status));
+ return;
+ }
+
+ /*
+ * remove the named_pipe layer together with its packet layer
+ */
+ conn->ops = pipe_conn->pipe_sock->ops;
+ conn->private = pipe_conn->pipe_sock->private_data;
+ talloc_free(pipe_conn);
+
+ /* we're now ready to start receiving events on this stream */
+ EVENT_FD_READABLE(conn->event.fde);
+
+ /*
+ * hand over to the real pipe implementation,
+ * now that we have setup the transport session_info
+ */
+ conn->ops->accept_connection(conn);
+
+ DEBUG(10,("named_pipe_handover_connection[%s]: succeeded\n",
+ conn->ops->name));
+}
+
+static NTSTATUS named_pipe_recv_auth_request(void *private_data,
+ DATA_BLOB req_blob)
+{
+ struct named_pipe_connection *pipe_conn = talloc_get_type(
+ private_data, struct named_pipe_connection);
+ struct stream_connection *conn = pipe_conn->connection;
+ enum ndr_err_code ndr_err;
+ struct named_pipe_auth_req req;
+ union netr_Validation val;
+ struct auth_serversupplied_info *server_info;
+ struct named_pipe_auth_rep rep;
+ DATA_BLOB rep_blob;
+ NTSTATUS status;
+
+ /*
+ * make sure nothing happens on the socket untill the
+ * real implemenation takes over
+ */
+ packet_recv_disable(pipe_conn->packet);
+
+ /*
+ * TODO: check it's a root (uid == 0) pipe
+ */
+
+ ZERO_STRUCT(rep);
+ rep.level = 0;
+ rep.status = NT_STATUS_INTERNAL_ERROR;
+
+ DEBUG(10,("named_pipe_auth: req_blob.length[%u]\n",
+ (unsigned int)req_blob.length));
+ dump_data(10, req_blob.data, req_blob.length);
+
+ /* parse the passed credentials */
+ ndr_err = ndr_pull_struct_blob_all(
+ &req_blob,
+ pipe_conn,
+ lp_iconv_convenience(conn->lp_ctx),
+ &req,
+ (ndr_pull_flags_fn_t)ndr_pull_named_pipe_auth_req);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ rep.status = ndr_map_error2ntstatus(ndr_err);
+ DEBUG(2, ("Could not unmarshall named_pipe_auth_req: %s\n",
+ nt_errstr(rep.status)));
+ goto reply;
+ }
+
+ if (strcmp(NAMED_PIPE_AUTH_MAGIC, req.magic) != 0) {
+ DEBUG(2, ("named_pipe_auth_req: invalid magic '%s' != %s\n",
+ req.magic, NAMED_PIPE_AUTH_MAGIC));
+ rep.status = NT_STATUS_INVALID_PARAMETER;
+ goto reply;
+ }
+
+ switch (req.level) {
+ case 0:
+ /*
+ * anon connection, we don't create a session info
+ * and leave it NULL
+ */
+ rep.level = 0;
+ rep.status = NT_STATUS_OK;
+ break;
+ case 1:
+ val.sam3 = &req.info.info1;
+
+ rep.level = 1;
+ rep.status = make_server_info_netlogon_validation(pipe_conn,
+ "TODO",
+ 3, &val,
+ &server_info);
+ if (!NT_STATUS_IS_OK(rep.status)) {
+ DEBUG(2, ("make_server_info_netlogon_validation returned "
+ "%s\n", nt_errstr(rep.status)));
+ goto reply;
+ }
+
+ /* setup the session_info on the connection */
+ rep.status = auth_generate_session_info(conn,
+ conn->event.ctx,
+ conn->lp_ctx,
+ server_info,
+ &conn->session_info);
+ if (!NT_STATUS_IS_OK(rep.status)) {
+ DEBUG(2, ("auth_generate_session_info failed: %s\n",
+ nt_errstr(rep.status)));
+ goto reply;
+ }
+
+ break;
+ default:
+ DEBUG(2, ("named_pipe_auth_req: unknown level %u\n",
+ req.level));
+ rep.level = 0;
+ rep.status = NT_STATUS_INVALID_LEVEL;
+ goto reply;
+ }
+
+reply:
+ /* create the output */
+ ndr_err = ndr_push_struct_blob(&rep_blob, pipe_conn,
+ lp_iconv_convenience(conn->lp_ctx),
+ &rep,
+ (ndr_push_flags_fn_t)ndr_push_named_pipe_auth_rep);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ status = ndr_map_error2ntstatus(ndr_err);
+ DEBUG(2, ("Could not marshall named_pipe_auth_rep: %s\n",
+ nt_errstr(status)));
+ return status;
+ }
+
+ pipe_conn->status = rep.status;
+
+ DEBUG(10,("named_pipe_auth reply[%u]\n", rep_blob.length));
+ dump_data(10, rep_blob.data, rep_blob.length);
+ status = packet_send_callback(pipe_conn->packet, rep_blob,
+ named_pipe_handover_connection,
+ pipe_conn);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("packet_send_callback returned %s\n",
+ nt_errstr(status)));
+ return status;
+ }
+
+ return NT_STATUS_OK;
+}
+
+/*
+ called when a pipe socket becomes readable
+*/
+static void named_pipe_recv(struct stream_connection *conn, uint16_t flags)
+{
+ struct named_pipe_connection *pipe_conn = talloc_get_type(
+ conn->private, struct named_pipe_connection);
+
+ DEBUG(10,("named_pipe_recv\n"));
+
+ packet_recv(pipe_conn->packet);
+}
+
+/*
+ called when a pipe socket becomes writable
+*/
+static void named_pipe_send(struct stream_connection *conn, uint16_t flags)
+{
+ struct named_pipe_connection *pipe_conn = talloc_get_type(
+ conn->private, struct named_pipe_connection);
+
+ packet_queue_run(pipe_conn->packet);
+}
+
+/*
+ handle socket recv errors
+*/
+static void named_pipe_recv_error(void *private_data, NTSTATUS status)
+{
+ struct named_pipe_connection *pipe_conn = talloc_get_type(
+ private_data, struct named_pipe_connection);
+
+ stream_terminate_connection(pipe_conn->connection, nt_errstr(status));
+}
+
+static NTSTATUS named_pipe_full_request(void *private, DATA_BLOB blob, size_t *size)
+{
+ if (blob.length < 8) {
+ return STATUS_MORE_ENTRIES;
+ }
+
+ if (memcmp(NAMED_PIPE_AUTH_MAGIC, &blob.data[4], 4) != 0) {
+ DEBUG(0,("named_pipe_full_request: wrong protocol\n"));
+ *size = blob.length;
+ /* the error will be handled in named_pipe_recv_auth_request */
+ return NT_STATUS_OK;
+ }
+
+ *size = 4 + RIVAL(blob.data, 0);
+ if (*size > blob.length) {
+ return STATUS_MORE_ENTRIES;
+ }
+
+ return NT_STATUS_OK;
+}
+
+static void named_pipe_accept(struct stream_connection *conn)
+{
+ struct named_pipe_socket *pipe_sock = talloc_get_type(
+ conn->private, struct named_pipe_socket);
+ struct named_pipe_connection *pipe_conn;
+
+ DEBUG(5,("named_pipe_accept\n"));
+
+ pipe_conn = talloc_zero(conn, struct named_pipe_connection);
+ if (!pipe_conn) {
+ stream_terminate_connection(conn, "out of memory");
+ return;
+ }
+
+ pipe_conn->packet = packet_init(pipe_conn);
+ if (!pipe_conn->packet) {
+ stream_terminate_connection(conn, "out of memory");
+ return;
+ }
+ packet_set_private(pipe_conn->packet, pipe_conn);
+ packet_set_socket(pipe_conn->packet, conn->socket);
+ packet_set_callback(pipe_conn->packet, named_pipe_recv_auth_request);
+ packet_set_full_request(pipe_conn->packet, named_pipe_full_request);
+ packet_set_error_handler(pipe_conn->packet, named_pipe_recv_error);
+ packet_set_event_context(pipe_conn->packet, conn->event.ctx);
+ packet_set_fde(pipe_conn->packet, conn->event.fde);
+ packet_set_serialise(pipe_conn->packet);
+ packet_set_initial_read(pipe_conn->packet, 8);
+
+ pipe_conn->pipe_sock = pipe_sock;
+
+ pipe_conn->connection = conn;
+ conn->private = pipe_conn;
+}
+
+static const struct stream_server_ops named_pipe_stream_ops = {
+ .name = "named_pipe",
+ .accept_connection = named_pipe_accept,
+ .recv_handler = named_pipe_recv,
+ .send_handler = named_pipe_send,
+};
+
+NTSTATUS stream_setup_named_pipe(struct event_context *event_context,
+ struct loadparm_context *lp_ctx,
+ const struct model_ops *model_ops,
+ const struct stream_server_ops *stream_ops,
+ const char *pipe_name,
+ void *private_data)
+{
+ char *dirname;
+ struct named_pipe_socket *pipe_sock;
+ NTSTATUS status = NT_STATUS_NO_MEMORY;;
+
+ pipe_sock = talloc(event_context, struct named_pipe_socket);
+ if (pipe_sock == NULL) {
+ goto fail;
+ }
+
+ /* remember the details about the pipe */
+ pipe_sock->pipe_name = talloc_strdup(pipe_sock, pipe_name);
+ if (pipe_sock->pipe_name == NULL) {
+ goto fail;
+ }
+
+ dirname = talloc_asprintf(pipe_sock, "%s/np", lp_ncalrpc_dir(lp_ctx));
+ if (dirname == NULL) {
+ goto fail;
+ }
+
+ if (!directory_create_or_exist(dirname, geteuid(), 0700)) {
+ status = map_nt_error_from_unix(errno);
+ goto fail;
+ }
+
+ if (strncmp(pipe_name, "\\pipe\\", 6) == 0) {
+ pipe_name += 6;
+ }
+
+ pipe_sock->pipe_path = talloc_asprintf(pipe_sock, "%s/%s", dirname,
+ pipe_name);
+ if (pipe_sock->pipe_path == NULL) {
+ goto fail;
+ }
+
+ talloc_free(dirname);
+
+ pipe_sock->ops = stream_ops;
+ pipe_sock->private_data = talloc_reference(pipe_sock, private_data);
+
+ status = stream_setup_socket(event_context,
+ lp_ctx,
+ model_ops,
+ &named_pipe_stream_ops,
+ "unix",
+ pipe_sock->pipe_path,
+ NULL,
+ NULL,
+ pipe_sock);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto fail;
+ }
+ return NT_STATUS_OK;
+
+ fail:
+ talloc_free(pipe_sock);
+ return status;
+}
diff --git a/source4/torture/config.mk b/source4/torture/config.mk
index 8b12f36f95..4b4664f101 100644
--- a/source4/torture/config.mk
+++ b/source4/torture/config.mk
@@ -1,6 +1,6 @@
[SUBSYSTEM::TORTURE_UTIL]
PRIVATE_DEPENDENCIES = LIBCLI_RAW
-PUBLIC_DEPENDENCIES = POPT_CREDENTIALS
+PUBLIC_DEPENDENCIES = torture POPT_CREDENTIALS
TORTURE_UTIL_OBJ_FILES = $(addprefix $(torturesrcdir)/, util_smb.o)
@@ -89,6 +89,7 @@ mkinclude smb2/config.mk
mkinclude winbind/config.mk
[SUBSYSTEM::TORTURE_NDR]
+PRIVATE_DEPENDENCIES = torture
TORTURE_NDR_OBJ_FILES = $(addprefix $(torturesrcdir)/ndr/, ndr.o winreg.o atsvc.o lsa.o epmap.o dfs.o netlogon.o drsuapi.o spoolss.o samr.o)
@@ -105,7 +106,7 @@ PRIVATE_DEPENDENCIES = \
RPC_NDR_NETLOGON dcerpc_atsvc dcerpc_mgmt RPC_NDR_DRSUAPI \
RPC_NDR_LSA RPC_NDR_EPMAPPER RPC_NDR_DFS RPC_NDR_FRSAPI RPC_NDR_SPOOLSS \
RPC_NDR_SRVSVC RPC_NDR_WKSSVC RPC_NDR_ROT RPC_NDR_DSSETUP \
- RPC_NDR_REMACT RPC_NDR_OXIDRESOLVER WB_HELPER LIBSAMBA-NET \
+ RPC_NDR_REMACT RPC_NDR_OXIDRESOLVER RPC_NDR_NTSVCS WB_HELPER LIBSAMBA-NET \
LIBCLI_AUTH POPT_CREDENTIALS TORTURE_LDAP TORTURE_UTIL TORTURE_RAP \
dcerpc_server service process_model ntvfs SERVICE_SMB
@@ -116,7 +117,7 @@ torture_rpc_OBJ_FILES = $(addprefix $(torturesrcdir)/rpc/, \
eventlog.o epmapper.o winreg.o initshutdown.o oxidresolve.o remact.o mgmt.o \
scanner.o autoidl.o countcalls.o testjoin.o schannel.o netlogon.o remote_pac.o samlogon.o \
samsync.o bind.o dssetup.o alter_context.o bench.o samba3rpc.o rpc.o async_bind.o \
- handles.o frsapi.o object_uuid.o)
+ handles.o frsapi.o object_uuid.o ntsvcs.o)
$(eval $(call proto_header_template,$(torturesrcdir)/rpc/proto.h,$(torture_rpc_OBJ_FILES:.o=.c)))
@@ -139,7 +140,7 @@ $(eval $(call proto_header_template,$(torturesrcdir)/rap/proto.h,$(TORTURE_RAP_O
SUBSYSTEM = smbtorture
PRIVATE_DEPENDENCIES = \
LIBCLI_SMB gensec auth KERBEROS \
- POPT_CREDENTIALS SMBPASSWD
+ POPT_CREDENTIALS SMBPASSWD torture
# End SUBSYSTEM TORTURE_AUTH
#################################
@@ -181,7 +182,7 @@ $(eval $(call proto_header_template,$(torturesrcdir)/unix/proto.h,$(TORTURE_UNIX
SUBSYSTEM = smbtorture
INIT_FUNCTION = torture_ldap_init
PRIVATE_DEPENDENCIES = \
- LIBCLI_LDAP LIBCLI_CLDAP SAMDB POPT_CREDENTIALS
+ LIBCLI_LDAP LIBCLI_CLDAP SAMDB POPT_CREDENTIALS torture
# End SUBSYSTEM TORTURE_LDAP
#################################
diff --git a/source4/torture/libnet/libnet_domain.c b/source4/torture/libnet/libnet_domain.c
index 7d5be368c2..3c28d1a019 100644
--- a/source4/torture/libnet/libnet_domain.c
+++ b/source4/torture/libnet/libnet_domain.c
@@ -35,12 +35,13 @@
static bool test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle *handle, struct lsa_String *domname,
- uint32_t *access_mask, struct dom_sid **sid)
+ uint32_t *access_mask, struct dom_sid **sid_p)
{
NTSTATUS status;
struct policy_handle h, domain_handle;
struct samr_Connect r1;
struct samr_LookupDomain r2;
+ struct dom_sid2 *sid = NULL;
struct samr_OpenDomain r3;
printf("connecting\n");
@@ -59,6 +60,7 @@ static bool test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r2.in.connect_handle = &h;
r2.in.domain_name = domname;
+ r2.out.sid = &sid;
printf("domain lookup on %s\n", domname->string);
@@ -70,7 +72,7 @@ static bool test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r3.in.connect_handle = &h;
r3.in.access_mask = *access_mask;
- r3.in.sid = *sid = r2.out.sid;
+ r3.in.sid = *sid_p = *r2.out.sid;
r3.out.domain_handle = &domain_handle;
printf("opening domain\n");
diff --git a/source4/torture/libnet/libnet_group.c b/source4/torture/libnet/libnet_group.c
index 12b8167a86..9c9ecfd525 100644
--- a/source4/torture/libnet/libnet_group.c
+++ b/source4/torture/libnet/libnet_group.c
@@ -42,12 +42,15 @@ static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct lsa_String names[2];
uint32_t rid;
struct policy_handle group_handle;
+ struct samr_Ids rids, types;
names[0].string = groupname;
r1.in.domain_handle = domain_handle;
r1.in.num_names = 1;
r1.in.names = names;
+ r1.out.rids = &rids;
+ r1.out.types = &types;
printf("group account lookup '%s'\n", groupname);
@@ -57,7 +60,7 @@ static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return false;
}
- rid = r1.out.rids.ids[0];
+ rid = r1.out.rids->ids[0];
r2.in.domain_handle = domain_handle;
r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
@@ -139,6 +142,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle h, domain_handle;
struct samr_Connect r1;
struct samr_LookupDomain r2;
+ struct dom_sid2 *sid = NULL;
struct samr_OpenDomain r3;
printf("connecting\n");
@@ -155,6 +159,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r2.in.connect_handle = &h;
r2.in.domain_name = domname;
+ r2.out.sid = &sid;
printf("domain lookup on %s\n", domname->string);
@@ -166,7 +171,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r3.in.connect_handle = &h;
r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- r3.in.sid = r2.out.sid;
+ r3.in.sid = *r2.out.sid;
r3.out.domain_handle = &domain_handle;
printf("opening domain\n");
diff --git a/source4/torture/libnet/libnet_user.c b/source4/torture/libnet/libnet_user.c
index 6d3e682976..18007dccad 100644
--- a/source4/torture/libnet/libnet_user.c
+++ b/source4/torture/libnet/libnet_user.c
@@ -40,12 +40,15 @@ static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct lsa_String names[2];
uint32_t rid;
struct policy_handle user_handle;
+ struct samr_Ids rids, types;
names[0].string = username;
r1.in.domain_handle = domain_handle;
r1.in.num_names = 1;
r1.in.names = names;
+ r1.out.rids = &rids;
+ r1.out.types = &types;
printf("user account lookup '%s'\n", username);
@@ -55,7 +58,7 @@ static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return false;
}
- rid = r1.out.rids.ids[0];
+ rid = r1.out.rids->ids[0];
r2.in.domain_handle = domain_handle;
r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
@@ -92,6 +95,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle h, domain_handle;
struct samr_Connect r1;
struct samr_LookupDomain r2;
+ struct dom_sid2 *sid = NULL;
struct samr_OpenDomain r3;
printf("connecting\n");
@@ -108,6 +112,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r2.in.connect_handle = &h;
r2.in.domain_name = domname;
+ r2.out.sid = &sid;
printf("domain lookup on %s\n", domname->string);
@@ -119,7 +124,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r3.in.connect_handle = &h;
r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- r3.in.sid = r2.out.sid;
+ r3.in.sid = *r2.out.sid;
r3.out.domain_handle = &domain_handle;
printf("opening domain\n");
diff --git a/source4/torture/libnet/utils.c b/source4/torture/libnet/utils.c
index 54c5f2c29c..942540c80e 100644
--- a/source4/torture/libnet/utils.c
+++ b/source4/torture/libnet/utils.c
@@ -32,12 +32,13 @@
bool test_opendomain(struct torture_context *tctx,
struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle *handle, struct lsa_String *domname,
- struct dom_sid2 *sid)
+ struct dom_sid2 *sid_p)
{
NTSTATUS status;
struct policy_handle h, domain_handle;
struct samr_Connect r1;
struct samr_LookupDomain r2;
+ struct dom_sid2 *sid = NULL;
struct samr_OpenDomain r3;
torture_comment(tctx, "connecting\n");
@@ -51,6 +52,7 @@ bool test_opendomain(struct torture_context *tctx,
r2.in.connect_handle = &h;
r2.in.domain_name = domname;
+ r2.out.sid = &sid;
torture_comment(tctx, "domain lookup on %s\n", domname->string);
@@ -59,7 +61,7 @@ bool test_opendomain(struct torture_context *tctx,
r3.in.connect_handle = &h;
r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- r3.in.sid = r2.out.sid;
+ r3.in.sid = *r2.out.sid;
r3.out.domain_handle = &domain_handle;
torture_comment(tctx, "opening domain\n");
@@ -68,7 +70,7 @@ bool test_opendomain(struct torture_context *tctx,
torture_assert_ntstatus_ok(tctx, status, "OpenDomain failed");
*handle = domain_handle;
- *sid = *r2.out.sid;
+ *sid_p = **r2.out.sid;
return true;
}
@@ -84,19 +86,22 @@ bool test_user_cleanup(struct torture_context *tctx, struct dcerpc_pipe *p,
struct lsa_String names[2];
uint32_t rid;
struct policy_handle user_handle;
+ struct samr_Ids rids, types;
names[0].string = name;
r1.in.domain_handle = domain_handle;
r1.in.num_names = 1;
r1.in.names = names;
+ r1.out.rids = &rids;
+ r1.out.types = &types;
torture_comment(tctx, "user account lookup '%s'\n", name);
status = dcerpc_samr_LookupNames(p, mem_ctx, &r1);
torture_assert_ntstatus_ok(tctx, status, "LookupNames failed");
- rid = r1.out.rids.ids[0];
+ rid = r1.out.rids->ids[0];
r2.in.domain_handle = domain_handle;
r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
@@ -174,12 +179,15 @@ bool test_group_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct lsa_String names[2];
uint32_t rid;
struct policy_handle group_handle;
+ struct samr_Ids rids, types;
names[0].string = name;
r1.in.domain_handle = domain_handle;
r1.in.num_names = 1;
r1.in.names = names;
+ r1.out.rids = &rids;
+ r1.out.types = &types;
printf("group account lookup '%s'\n", name);
@@ -189,7 +197,7 @@ bool test_group_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return false;
}
- rid = r1.out.rids.ids[0];
+ rid = r1.out.rids->ids[0];
r2.in.domain_handle = domain_handle;
r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
diff --git a/source4/torture/raw/acls.c b/source4/torture/raw/acls.c
index 862b96ac17..48dec6e561 100644
--- a/source4/torture/raw/acls.c
+++ b/source4/torture/raw/acls.c
@@ -1410,7 +1410,9 @@ static bool test_inheritance(struct torture_context *tctx,
if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT)) {
if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def)) {
- printf("Expected default sd at %d - got:\n", i);
+ printf("Expected default sd:\n");
+ NDR_PRINT_DEBUG(security_descriptor, sd_def);
+ printf("at %d - got:\n", i);
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
}
goto check_dir;
@@ -1455,7 +1457,9 @@ static bool test_inheritance(struct torture_context *tctx,
(!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT) ||
(test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT))) {
if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def)) {
- printf("Expected default sd for dir at %d - got:\n", i);
+ printf("Expected default sd for dir at %d:\n", i);
+ NDR_PRINT_DEBUG(security_descriptor, sd_def);
+ printf("got:\n");
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
}
continue;
@@ -1469,7 +1473,7 @@ static bool test_inheritance(struct torture_context *tctx,
!dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
sd_orig->owner_sid) ||
q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
- printf("Bad sd in child dir at %d (parent 0x%x)\n",
+ printf("(CI & NP) Bad sd in child dir at %d (parent 0x%x)\n",
i, test_flags[i].parent_flags);
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
ret = false;
@@ -1487,7 +1491,7 @@ static bool test_inheritance(struct torture_context *tctx,
q.query_secdesc.out.sd->dacl->aces[0].flags != 0 ||
q.query_secdesc.out.sd->dacl->aces[1].flags !=
(test_flags[i].dir_flags | SEC_ACE_FLAG_INHERIT_ONLY)) {
- printf("Bad sd in child dir at %d (parent 0x%x)\n",
+ printf("(CI) Bad sd in child dir at %d (parent 0x%x)\n",
i, test_flags[i].parent_flags);
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
ret = false;
@@ -1500,8 +1504,8 @@ static bool test_inheritance(struct torture_context *tctx,
!dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
creator_owner) ||
q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
- printf("Bad sd in child dir at %d (parent 0x%x)\n",
- i, test_flags[i].parent_flags);
+ printf("(0) Bad sd in child dir at %d (parent 0x%x)\n",
+ i, test_flags[i].parent_flags);
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
ret = false;
continue;
diff --git a/source4/torture/raw/chkpath.c b/source4/torture/raw/chkpath.c
index 68ef8e226d..b66839b997 100644
--- a/source4/torture/raw/chkpath.c
+++ b/source4/torture/raw/chkpath.c
@@ -18,6 +18,7 @@
*/
#include "includes.h"
+#include "system/locale.h"
#include "torture/torture.h"
#include "libcli/raw/libcliraw.h"
#include "libcli/raw/raw_proto.h"
@@ -267,6 +268,85 @@ done:
return ret;
}
+static bool test_chkpath_names(struct smbcli_state *cli, struct torture_context *tctx)
+{
+ union smb_chkpath io;
+ union smb_fileinfo finfo;
+ NTSTATUS status;
+ bool ret = true;
+ uint8_t i;
+
+ /*
+ * we don't test characters >= 0x80 yet,
+ * as somehow our client libraries can't do that
+ */
+ for (i=0x01; i <= 0x7F; i++) {
+ /*
+ * it's important that we test the last character
+ * because of the error code with ':' 0x3A
+ * and servers without stream support
+ */
+ char *path = talloc_asprintf(tctx, "%s\\File0x%02X%c",
+ BASEDIR, i, i);
+ NTSTATUS expected;
+ NTSTATUS expected_dos1;
+ NTSTATUS expected_dos2;
+
+ expected = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ expected_dos1 = NT_STATUS_DOS(ERRDOS,ERRbadpath);
+ expected_dos2 = NT_STATUS_DOS(ERRDOS,ERRbadfile);
+
+ switch (i) {
+ case '"':/*0x22*/
+ case '*':/*0x2A*/
+ case '/':/*0x2F*/
+ case ':':/*0x3A*/
+ case '<':/*0x3C*/
+ case '>':/*0x3E*/
+ case '?':/*0x3F*/
+ case '|':/*0x7C*/
+ if (i == '/' &&
+ torture_setting_bool(tctx, "samba3", true)) {
+ /* samba 3 handles '/' as '\\' */
+ break;
+ }
+ expected = NT_STATUS_OBJECT_NAME_INVALID;
+ expected_dos1 = NT_STATUS_DOS(ERRDOS,ERRbadpath);
+ expected_dos2 = NT_STATUS_DOS(ERRDOS,ERRinvalidname);
+ break;
+ default:
+ if (i <= 0x1F) {
+ expected = NT_STATUS_OBJECT_NAME_INVALID;
+ expected_dos1 = NT_STATUS_DOS(ERRDOS,ERRbadpath);
+ expected_dos2 = NT_STATUS_DOS(ERRDOS,ERRinvalidname);
+ }
+ break;
+ }
+
+ printf("Checking File0x%02X%c%s expected[%s|%s|%s]\n",
+ i, isprint(i)?(char)i:' ',
+ isprint(i)?"":"(not printable)",
+ nt_errstr(expected),
+ nt_errstr(expected_dos1),
+ nt_errstr(expected_dos2));
+
+ io.chkpath.in.path = path;
+ status = smb_raw_chkpath(cli->tree, &io);
+ CHECK_STATUS(status, expected, expected_dos1);
+
+ ZERO_STRUCT(finfo);
+ finfo.generic.level = RAW_FILEINFO_NAME_INFO;
+ finfo.generic.in.file.path = path;
+ status = smb_raw_pathinfo(cli->tree, cli, &finfo);
+ CHECK_STATUS(status, expected, expected_dos2);
+
+ talloc_free(path);
+ }
+
+done:
+ return ret;
+}
+
/*
basic testing of chkpath calls
*/
@@ -303,6 +383,7 @@ bool torture_raw_chkpath(struct torture_context *torture,
}
ret &= test_chkpath(cli, torture);
+ ret &= test_chkpath_names(cli, torture);
done:
diff --git a/source4/torture/raw/streams.c b/source4/torture/raw/streams.c
index 8b2d327653..501da2335e 100644
--- a/source4/torture/raw/streams.c
+++ b/source4/torture/raw/streams.c
@@ -20,6 +20,7 @@
*/
#include "includes.h"
+#include "system/locale.h"
#include "torture/torture.h"
#include "libcli/raw/libcliraw.h"
#include "system/filesys.h"
@@ -43,6 +44,34 @@
ret = false; \
}} while (0)
+#define CHECK_NTTIME(v, correct) do { \
+ if ((v) != (correct)) { \
+ printf("(%s) Incorrect value %s=%llu - should be %llu\n", \
+ __location__, #v, (unsigned long long)v, \
+ (unsigned long long)correct); \
+ ret = false; \
+ }} while (0)
+
+#define CHECK_STR(v, correct) do { \
+ bool ok; \
+ if ((v) && !(correct)) { \
+ ok = false; \
+ } else if (!(v) && (correct)) { \
+ ok = false; \
+ } else if (!(v) && !(correct)) { \
+ ok = true; \
+ } else if (strcmp((v), (correct)) == 0) { \
+ ok = true; \
+ } else { \
+ ok = false; \
+ } \
+ if (!ok) { \
+ printf("(%s) Incorrect value %s='%s' - should be '%s'\n", \
+ __location__, #v, (v)?(v):"NULL", \
+ (correct)?(correct):"NULL"); \
+ ret = false; \
+ }} while (0)
+
/*
check that a stream has the right contents
*/
@@ -236,11 +265,7 @@ static bool test_stream_dir(struct torture_context *tctx,
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = basedir_data;
status = smb_raw_open(cli->tree, mem_ctx, &io);
- if (torture_setting_bool(tctx, "samba3", false)) {
- CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
- } else {
- CHECK_STATUS(status, NT_STATUS_FILE_IS_A_DIRECTORY);
- }
+ CHECK_STATUS(status, NT_STATUS_FILE_IS_A_DIRECTORY);
printf("(%s) list the streams on the basedir\n", __location__);
ret &= check_stream_list(cli, BASEDIR, 0, NULL);
@@ -565,16 +590,12 @@ static bool test_stream_delete(struct torture_context *tctx,
status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
CHECK_STATUS(status, NT_STATUS_DELETE_PENDING);
- if (!torture_setting_bool(tctx, "samba3", false)) {
-
- /*
- * S3 doesn't do this yet
- */
-
- finfo.generic.in.file.path = sname1;
- status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
- CHECK_STATUS(status, NT_STATUS_DELETE_PENDING);
- }
+ /*
+ * older S3 doesn't do this
+ */
+ finfo.generic.in.file.path = sname1;
+ status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
+ CHECK_STATUS(status, NT_STATUS_DELETE_PENDING);
/*
* fd-based qfileinfo on the stream still works, the stream does not
@@ -587,7 +608,9 @@ static bool test_stream_delete(struct torture_context *tctx,
status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
CHECK_STATUS(status, NT_STATUS_OK);
+ /* w2k and w2k3 return 0 and w2k8 returns 1
CHECK_VALUE(finfo.all_info.out.delete_pending, 0);
+ */
smbcli_close(cli->tree, fnum);
@@ -620,6 +643,378 @@ done:
return ret;
}
+/*
+ test stream names
+*/
+static bool test_stream_names(struct torture_context *tctx,
+ struct smbcli_state *cli,
+ TALLOC_CTX *mem_ctx)
+{
+ NTSTATUS status;
+ union smb_open io;
+ union smb_fileinfo finfo;
+ union smb_fileinfo stinfo;
+ union smb_setfileinfo sinfo;
+ const char *fname = BASEDIR "\\stream_names.txt";
+ const char *sname1, *sname1b, *sname1c, *sname1d;
+ const char *sname2, *snamew, *snamew2;
+ const char *snamer1, *snamer2;
+ bool ret = true;
+ int fnum1 = -1;
+ int fnum2 = -1;
+ int fnum3 = -1;
+ int i;
+ const char *four[4] = {
+ "::$DATA",
+ ":\x05Stream\n One:$DATA",
+ ":MStream Two:$DATA",
+ ":?Stream*:$DATA"
+ };
+ const char *five1[5] = {
+ "::$DATA",
+ ":\x05Stream\n One:$DATA",
+ ":BeforeRename:$DATA",
+ ":MStream Two:$DATA",
+ ":?Stream*:$DATA"
+ };
+ const char *five2[5] = {
+ "::$DATA",
+ ":\x05Stream\n One:$DATA",
+ ":AfterRename:$DATA",
+ ":MStream Two:$DATA",
+ ":?Stream*:$DATA"
+ };
+
+ sname1 = talloc_asprintf(mem_ctx, "%s:%s", fname, "\x05Stream\n One");
+ sname1b = talloc_asprintf(mem_ctx, "%s:", sname1);
+ sname1c = talloc_asprintf(mem_ctx, "%s:$FOO", sname1);
+ sname1d = talloc_asprintf(mem_ctx, "%s:?D*a", sname1);
+ sname2 = talloc_asprintf(mem_ctx, "%s:%s:$DaTa", fname, "MStream Two");
+ snamew = talloc_asprintf(mem_ctx, "%s:%s:$DATA", fname, "?Stream*");
+ snamew2 = talloc_asprintf(mem_ctx, "%s\\stream*:%s:$DATA", BASEDIR, "?Stream*");
+ snamer1 = talloc_asprintf(mem_ctx, "%s:%s:$DATA", fname, "BeforeRename");
+ snamer2 = talloc_asprintf(mem_ctx, "%s:%s:$DATA", fname, "AfterRename");
+
+ printf("(%s) testing stream names\n", __location__);
+ io.generic.level = RAW_OPEN_NTCREATEX;
+ io.ntcreatex.in.root_fid = 0;
+ io.ntcreatex.in.flags = 0;
+ io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
+ io.ntcreatex.in.create_options = 0;
+ io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
+ io.ntcreatex.in.share_access = 0;
+ io.ntcreatex.in.alloc_size = 0;
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
+ io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
+ io.ntcreatex.in.security_flags = 0;
+ io.ntcreatex.in.fname = sname1;
+
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ fnum1 = io.ntcreatex.out.file.fnum;
+
+ /*
+ * A different stream does not give a sharing violation
+ */
+
+ io.ntcreatex.in.fname = sname2;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ fnum2 = io.ntcreatex.out.file.fnum;
+
+ /*
+ * ... whereas the same stream does with unchanged access/share_access
+ * flags
+ */
+
+ io.ntcreatex.in.fname = sname1;
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_SUPERSEDE;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
+
+ io.ntcreatex.in.fname = sname1b;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
+
+ io.ntcreatex.in.fname = sname1c;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
+ /* w2k returns INVALID_PARAMETER */
+ CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
+ } else {
+ CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
+ }
+
+ io.ntcreatex.in.fname = sname1d;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
+ /* w2k returns INVALID_PARAMETER */
+ CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
+ } else {
+ CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
+ }
+
+ io.ntcreatex.in.fname = sname2;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
+
+ io.ntcreatex.in.fname = snamew;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ fnum3 = io.ntcreatex.out.file.fnum;
+
+ io.ntcreatex.in.fname = snamew2;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
+
+ ret &= check_stream_list(cli, fname, 4, four);
+
+ smbcli_close(cli->tree, fnum1);
+ smbcli_close(cli->tree, fnum2);
+ smbcli_close(cli->tree, fnum3);
+
+ if (torture_setting_bool(tctx, "samba4", true)) {
+ goto done;
+ }
+
+ finfo.generic.level = RAW_FILEINFO_ALL_INFO;
+ finfo.generic.in.file.path = fname;
+ status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ ret &= check_stream_list(cli, fname, 4, four);
+
+ for (i=0; i < 4; i++) {
+ NTTIME write_time;
+ uint64_t stream_size;
+ char *path = talloc_asprintf(tctx, "%s%s",
+ fname, four[i]);
+
+ char *rpath = talloc_strdup(path, path);
+ char *p = strrchr(rpath, ':');
+ /* eat :$DATA */
+ *p = 0;
+ p--;
+ if (*p == ':') {
+ /* eat ::$DATA */
+ *p = 0;
+ }
+ printf("(%s): i[%u][%s]\n", __location__, i, path);
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
+ io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE |
+ SEC_FILE_WRITE_ATTRIBUTE |
+ SEC_RIGHTS_FILE_ALL;
+ io.ntcreatex.in.fname = path;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ fnum1 = io.ntcreatex.out.file.fnum;
+
+ finfo.generic.level = RAW_FILEINFO_ALL_INFO;
+ finfo.generic.in.file.path = fname;
+ status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ stinfo.generic.level = RAW_FILEINFO_ALL_INFO;
+ stinfo.generic.in.file.fnum = fnum1;
+ status = smb_raw_fileinfo(cli->tree, mem_ctx, &stinfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ if (!torture_setting_bool(tctx, "samba3", false)) {
+ CHECK_NTTIME(stinfo.all_info.out.create_time,
+ finfo.all_info.out.create_time);
+ CHECK_NTTIME(stinfo.all_info.out.access_time,
+ finfo.all_info.out.access_time);
+ CHECK_NTTIME(stinfo.all_info.out.write_time,
+ finfo.all_info.out.write_time);
+ CHECK_NTTIME(stinfo.all_info.out.change_time,
+ finfo.all_info.out.change_time);
+ }
+ CHECK_VALUE(stinfo.all_info.out.attrib,
+ finfo.all_info.out.attrib);
+ CHECK_VALUE(stinfo.all_info.out.size,
+ finfo.all_info.out.size);
+ CHECK_VALUE(stinfo.all_info.out.delete_pending,
+ finfo.all_info.out.delete_pending);
+ CHECK_VALUE(stinfo.all_info.out.directory,
+ finfo.all_info.out.directory);
+ CHECK_VALUE(stinfo.all_info.out.ea_size,
+ finfo.all_info.out.ea_size);
+
+ stinfo.generic.level = RAW_FILEINFO_NAME_INFO;
+ stinfo.generic.in.file.fnum = fnum1;
+ status = smb_raw_fileinfo(cli->tree, mem_ctx, &stinfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ if (!torture_setting_bool(tctx, "samba3", false)) {
+ CHECK_STR(rpath, stinfo.name_info.out.fname.s);
+ }
+
+ write_time = finfo.all_info.out.write_time;
+ write_time += i*1000000;
+ write_time /= 1000000;
+ write_time *= 1000000;
+
+ ZERO_STRUCT(sinfo);
+ sinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO;
+ sinfo.basic_info.in.file.fnum = fnum1;
+ sinfo.basic_info.in.write_time = write_time;
+ sinfo.basic_info.in.attrib = stinfo.all_info.out.attrib;
+ status = smb_raw_setfileinfo(cli->tree, &sinfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ stream_size = i*8192;
+
+ ZERO_STRUCT(sinfo);
+ sinfo.end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFO;
+ sinfo.end_of_file_info.in.file.fnum = fnum1;
+ sinfo.end_of_file_info.in.size = stream_size;
+ status = smb_raw_setfileinfo(cli->tree, &sinfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ stinfo.generic.level = RAW_FILEINFO_ALL_INFO;
+ stinfo.generic.in.file.fnum = fnum1;
+ status = smb_raw_fileinfo(cli->tree, mem_ctx, &stinfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ if (!torture_setting_bool(tctx, "samba3", false)) {
+ CHECK_NTTIME(stinfo.all_info.out.write_time,
+ write_time);
+ CHECK_VALUE(stinfo.all_info.out.attrib,
+ finfo.all_info.out.attrib);
+ }
+ CHECK_VALUE(stinfo.all_info.out.size,
+ stream_size);
+ CHECK_VALUE(stinfo.all_info.out.delete_pending,
+ finfo.all_info.out.delete_pending);
+ CHECK_VALUE(stinfo.all_info.out.directory,
+ finfo.all_info.out.directory);
+ CHECK_VALUE(stinfo.all_info.out.ea_size,
+ finfo.all_info.out.ea_size);
+
+ ret &= check_stream_list(cli, fname, 4, four);
+
+ smbcli_close(cli->tree, fnum1);
+ talloc_free(path);
+ }
+
+ printf("(%s): testing stream renames\n", __location__);
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
+ io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE |
+ SEC_FILE_WRITE_ATTRIBUTE |
+ SEC_RIGHTS_FILE_ALL;
+ io.ntcreatex.in.fname = snamer1;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ fnum1 = io.ntcreatex.out.file.fnum;
+
+ ret &= check_stream_list(cli, fname, 5, five1);
+
+ ZERO_STRUCT(sinfo);
+ sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
+ sinfo.rename_information.in.file.fnum = fnum1;
+ sinfo.rename_information.in.overwrite = true;
+ sinfo.rename_information.in.root_fid = 0;
+ sinfo.rename_information.in.new_name = ":AfterRename:$DATA";
+ status = smb_raw_setfileinfo(cli->tree, &sinfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ ret &= check_stream_list(cli, fname, 5, five2);
+
+ ZERO_STRUCT(sinfo);
+ sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
+ sinfo.rename_information.in.file.fnum = fnum1;
+ sinfo.rename_information.in.overwrite = false;
+ sinfo.rename_information.in.root_fid = 0;
+ sinfo.rename_information.in.new_name = ":MStream Two:$DATA";
+ status = smb_raw_setfileinfo(cli->tree, &sinfo);
+ CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
+
+ ret &= check_stream_list(cli, fname, 5, five2);
+
+ ZERO_STRUCT(sinfo);
+ sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
+ sinfo.rename_information.in.file.fnum = fnum1;
+ sinfo.rename_information.in.overwrite = true;
+ sinfo.rename_information.in.root_fid = 0;
+ sinfo.rename_information.in.new_name = ":MStream Two:$DATA";
+ status = smb_raw_setfileinfo(cli->tree, &sinfo);
+ CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
+
+ ret &= check_stream_list(cli, fname, 5, five2);
+
+ /* TODO: we need to test more rename combinations */
+
+done:
+ if (fnum1 != -1) smbcli_close(cli->tree, fnum1);
+ if (fnum2 != -1) smbcli_close(cli->tree, fnum2);
+ if (fnum3 != -1) smbcli_close(cli->tree, fnum3);
+ status = smbcli_unlink(cli->tree, fname);
+ return ret;
+}
+
+/*
+ test stream names
+*/
+static bool test_stream_names2(struct torture_context *tctx,
+ struct smbcli_state *cli,
+ TALLOC_CTX *mem_ctx)
+{
+ NTSTATUS status;
+ union smb_open io;
+ const char *fname = BASEDIR "\\stream_names2.txt";
+ bool ret = true;
+ int fnum1 = -1;
+ uint8_t i;
+
+ printf("(%s) testing stream names\n", __location__);
+ io.generic.level = RAW_OPEN_NTCREATEX;
+ io.ntcreatex.in.root_fid = 0;
+ io.ntcreatex.in.flags = 0;
+ io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
+ io.ntcreatex.in.create_options = 0;
+ io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
+ io.ntcreatex.in.share_access = 0;
+ io.ntcreatex.in.alloc_size = 0;
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
+ io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
+ io.ntcreatex.in.security_flags = 0;
+ io.ntcreatex.in.fname = fname;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ fnum1 = io.ntcreatex.out.file.fnum;
+
+ for (i=0x01; i < 0x7F; i++) {
+ char *path = talloc_asprintf(tctx, "%s:Stream%c0x%02X:$DATA",
+ fname, i, i);
+ NTSTATUS expected;
+
+ switch (i) {
+ case '/':/*0x2F*/
+ case ':':/*0x3A*/
+ case '\\':/*0x5C*/
+ expected = NT_STATUS_OBJECT_NAME_INVALID;
+ break;
+ default:
+ expected = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ break;
+ }
+
+ printf("(%s) %s:Stream%c0x%02X:$DATA%s => expected[%s]\n",
+ __location__, fname, isprint(i)?(char)i:' ', i,
+ isprint(i)?"":" (not printable)",
+ nt_errstr(expected));
+
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
+ io.ntcreatex.in.fname = path;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, expected);
+
+ talloc_free(path);
+ }
+
+done:
+ if (fnum1 != -1) smbcli_close(cli->tree, fnum1);
+ status = smbcli_unlink(cli->tree, fname);
+ return ret;
+}
+
/*
basic testing of streams calls
*/
@@ -638,6 +1033,10 @@ bool torture_raw_streams(struct torture_context *torture,
smb_raw_exit(cli->session);
ret &= test_stream_sharemodes(torture, cli, torture);
smb_raw_exit(cli->session);
+ ret &= test_stream_names(torture, cli, torture);
+ smb_raw_exit(cli->session);
+ ret &= test_stream_names2(torture, cli, torture);
+ smb_raw_exit(cli->session);
if (!torture_setting_bool(torture, "samba4", false)) {
ret &= test_stream_delete(torture, cli, torture);
}
diff --git a/source4/torture/rpc/eventlog.c b/source4/torture/rpc/eventlog.c
index d5665ad07d..e89cdd3ea9 100644
--- a/source4/torture/rpc/eventlog.c
+++ b/source4/torture/rpc/eventlog.c
@@ -46,12 +46,12 @@ static bool get_policy_handle(struct torture_context *tctx,
unknown0.unknown1 = 0x0001;
r.in.unknown0 = &unknown0;
- init_lsa_String(r.in.logname, "dns server");
- init_lsa_String(r.in.servername, NULL);
+ init_lsa_String(&logname, "dns server");
+ init_lsa_String(&servername, NULL);
r.in.logname = &logname;
r.in.servername = &servername;
- r.in.unknown2 = 0x00000001;
- r.in.unknown3 = 0x00000001;
+ r.in.major_version = 0x00000001;
+ r.in.minor_version = 0x00000001;
r.out.handle = handle;
torture_assert_ntstatus_ok(tctx,
diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c
index 96cab0bf02..953f9d126d 100644
--- a/source4/torture/rpc/netlogon.c
+++ b/source4/torture/rpc/netlogon.c
@@ -32,8 +32,10 @@
#include "../lib/crypto/crypto.h"
#include "libcli/auth/libcli_auth.h"
#include "librpc/gen_ndr/ndr_netlogon_c.h"
+#include "librpc/gen_ndr/ndr_netlogon.h"
#include "librpc/gen_ndr/ndr_lsa_c.h"
#include "param/param.h"
+#include "libcli/security/security.h"
#define TEST_MACHINE_NAME "torturetest"
@@ -831,6 +833,538 @@ static bool test_DatabaseDeltas(struct torture_context *tctx,
return true;
}
+static bool test_DatabaseRedo(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct cli_credentials *machine_credentials)
+{
+ NTSTATUS status;
+ struct netr_DatabaseRedo r;
+ struct creds_CredentialState *creds;
+ struct netr_Authenticator credential;
+ struct netr_Authenticator return_authenticator;
+ struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
+ struct netr_ChangeLogEntry e;
+ struct dom_sid null_sid, *sid;
+ int i,d;
+
+ ZERO_STRUCT(null_sid);
+
+ sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
+
+ {
+
+ struct {
+ uint32_t rid;
+ uint16_t flags;
+ uint8_t db_index;
+ uint8_t delta_type;
+ struct dom_sid sid;
+ const char *name;
+ NTSTATUS expected_error;
+ uint32_t expected_num_results;
+ uint8_t expected_delta_type_1;
+ uint8_t expected_delta_type_2;
+ const char *comment;
+ } changes[] = {
+
+ /* SAM_DATABASE_DOMAIN */
+
+ {
+ .rid = 0,
+ .flags = 0,
+ .db_index = SAM_DATABASE_DOMAIN,
+ .delta_type = NETR_DELTA_MODIFY_COUNT,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
+ .expected_num_results = 0,
+ .comment = "NETR_DELTA_MODIFY_COUNT"
+ },
+ {
+ .rid = 0,
+ .flags = 0,
+ .db_index = SAM_DATABASE_DOMAIN,
+ .delta_type = 0,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DOMAIN,
+ .comment = "NULL DELTA"
+ },
+ {
+ .rid = 0,
+ .flags = 0,
+ .db_index = SAM_DATABASE_DOMAIN,
+ .delta_type = NETR_DELTA_DOMAIN,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DOMAIN,
+ .comment = "NETR_DELTA_DOMAIN"
+ },
+ {
+ .rid = DOMAIN_RID_ADMINISTRATOR,
+ .flags = 0,
+ .db_index = SAM_DATABASE_DOMAIN,
+ .delta_type = NETR_DELTA_USER,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_USER,
+ .comment = "NETR_DELTA_USER by rid 500"
+ },
+ {
+ .rid = DOMAIN_RID_GUEST,
+ .flags = 0,
+ .db_index = SAM_DATABASE_DOMAIN,
+ .delta_type = NETR_DELTA_USER,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_USER,
+ .comment = "NETR_DELTA_USER by rid 501"
+ },
+ {
+ .rid = 0,
+ .flags = NETR_CHANGELOG_SID_INCLUDED,
+ .db_index = SAM_DATABASE_DOMAIN,
+ .delta_type = NETR_DELTA_USER,
+ .sid = *sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
+ .comment = "NETR_DELTA_USER by sid and flags"
+ },
+ {
+ .rid = 0,
+ .flags = NETR_CHANGELOG_SID_INCLUDED,
+ .db_index = SAM_DATABASE_DOMAIN,
+ .delta_type = NETR_DELTA_USER,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
+ .comment = "NETR_DELTA_USER by null_sid and flags"
+ },
+ {
+ .rid = 0,
+ .flags = NETR_CHANGELOG_NAME_INCLUDED,
+ .db_index = SAM_DATABASE_DOMAIN,
+ .delta_type = NETR_DELTA_USER,
+ .sid = null_sid,
+ .name = "administrator",
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
+ .comment = "NETR_DELTA_USER by name 'administrator'"
+ },
+ {
+ .rid = DOMAIN_RID_ADMINS,
+ .flags = 0,
+ .db_index = SAM_DATABASE_DOMAIN,
+ .delta_type = NETR_DELTA_GROUP,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 2,
+ .expected_delta_type_1 = NETR_DELTA_GROUP,
+ .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
+ .comment = "NETR_DELTA_GROUP by rid 512"
+ },
+ {
+ .rid = DOMAIN_RID_ADMINS,
+ .flags = 0,
+ .db_index = SAM_DATABASE_DOMAIN,
+ .delta_type = NETR_DELTA_GROUP_MEMBER,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 2,
+ .expected_delta_type_1 = NETR_DELTA_GROUP,
+ .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
+ .comment = "NETR_DELTA_GROUP_MEMBER by rid 512"
+ },
+
+
+ /* SAM_DATABASE_BUILTIN */
+
+ {
+ .rid = 0,
+ .flags = 0,
+ .db_index = SAM_DATABASE_BUILTIN,
+ .delta_type = NETR_DELTA_MODIFY_COUNT,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
+ .expected_num_results = 0,
+ .comment = "NETR_DELTA_MODIFY_COUNT"
+ },
+ {
+ .rid = 0,
+ .flags = 0,
+ .db_index = SAM_DATABASE_BUILTIN,
+ .delta_type = NETR_DELTA_DOMAIN,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DOMAIN,
+ .comment = "NETR_DELTA_DOMAIN"
+ },
+ {
+ .rid = DOMAIN_RID_ADMINISTRATOR,
+ .flags = 0,
+ .db_index = SAM_DATABASE_BUILTIN,
+ .delta_type = NETR_DELTA_USER,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
+ .comment = "NETR_DELTA_USER by rid 500"
+ },
+ {
+ .rid = 0,
+ .flags = 0,
+ .db_index = SAM_DATABASE_BUILTIN,
+ .delta_type = NETR_DELTA_USER,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
+ .comment = "NETR_DELTA_USER"
+ },
+ {
+ .rid = 544,
+ .flags = 0,
+ .db_index = SAM_DATABASE_BUILTIN,
+ .delta_type = NETR_DELTA_ALIAS,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 2,
+ .expected_delta_type_1 = NETR_DELTA_ALIAS,
+ .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
+ .comment = "NETR_DELTA_ALIAS by rid 544"
+ },
+ {
+ .rid = 544,
+ .flags = 0,
+ .db_index = SAM_DATABASE_BUILTIN,
+ .delta_type = NETR_DELTA_ALIAS_MEMBER,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 2,
+ .expected_delta_type_1 = NETR_DELTA_ALIAS,
+ .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
+ .comment = "NETR_DELTA_ALIAS_MEMBER by rid 544"
+ },
+ {
+ .rid = 544,
+ .flags = 0,
+ .db_index = SAM_DATABASE_BUILTIN,
+ .delta_type = 0,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DOMAIN,
+ .comment = "NULL DELTA by rid 544"
+ },
+ {
+ .rid = 544,
+ .flags = NETR_CHANGELOG_SID_INCLUDED,
+ .db_index = SAM_DATABASE_BUILTIN,
+ .delta_type = 0,
+ .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DOMAIN,
+ .comment = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
+ },
+ {
+ .rid = 544,
+ .flags = NETR_CHANGELOG_SID_INCLUDED,
+ .db_index = SAM_DATABASE_BUILTIN,
+ .delta_type = NETR_DELTA_ALIAS,
+ .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 2,
+ .expected_delta_type_1 = NETR_DELTA_ALIAS,
+ .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
+ .comment = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
+ },
+ {
+ .rid = 0,
+ .flags = NETR_CHANGELOG_SID_INCLUDED,
+ .db_index = SAM_DATABASE_BUILTIN,
+ .delta_type = NETR_DELTA_ALIAS,
+ .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DELETE_ALIAS,
+ .comment = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
+ },
+
+ /* SAM_DATABASE_PRIVS */
+
+ {
+ .rid = 0,
+ .flags = 0,
+ .db_index = SAM_DATABASE_PRIVS,
+ .delta_type = 0,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_ACCESS_DENIED,
+ .expected_num_results = 0,
+ .comment = "NULL DELTA"
+ },
+ {
+ .rid = 0,
+ .flags = 0,
+ .db_index = SAM_DATABASE_PRIVS,
+ .delta_type = NETR_DELTA_MODIFY_COUNT,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
+ .expected_num_results = 0,
+ .comment = "NETR_DELTA_MODIFY_COUNT"
+ },
+ {
+ .rid = 0,
+ .flags = 0,
+ .db_index = SAM_DATABASE_PRIVS,
+ .delta_type = NETR_DELTA_POLICY,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_POLICY,
+ .comment = "NETR_DELTA_POLICY"
+ },
+ {
+ .rid = 0,
+ .flags = NETR_CHANGELOG_SID_INCLUDED,
+ .db_index = SAM_DATABASE_PRIVS,
+ .delta_type = NETR_DELTA_POLICY,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_POLICY,
+ .comment = "NETR_DELTA_POLICY by null sid and flags"
+ },
+ {
+ .rid = 0,
+ .flags = NETR_CHANGELOG_SID_INCLUDED,
+ .db_index = SAM_DATABASE_PRIVS,
+ .delta_type = NETR_DELTA_POLICY,
+ .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_POLICY,
+ .comment = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
+ },
+ {
+ .rid = DOMAIN_RID_ADMINISTRATOR,
+ .flags = 0,
+ .db_index = SAM_DATABASE_PRIVS,
+ .delta_type = NETR_DELTA_ACCOUNT,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
+ .expected_num_results = 0,
+ .comment = "NETR_DELTA_ACCOUNT by rid 500"
+ },
+ {
+ .rid = 0,
+ .flags = NETR_CHANGELOG_SID_INCLUDED,
+ .db_index = SAM_DATABASE_PRIVS,
+ .delta_type = NETR_DELTA_ACCOUNT,
+ .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
+ .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
+ },
+ {
+ .rid = 0,
+ .flags = NETR_CHANGELOG_SID_INCLUDED |
+ NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
+ .db_index = SAM_DATABASE_PRIVS,
+ .delta_type = NETR_DELTA_ACCOUNT,
+ .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
+ .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
+ },
+ {
+ .rid = 0,
+ .flags = NETR_CHANGELOG_SID_INCLUDED |
+ NETR_CHANGELOG_NAME_INCLUDED,
+ .db_index = SAM_DATABASE_PRIVS,
+ .delta_type = NETR_DELTA_ACCOUNT,
+ .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
+ .name = NULL,
+ .expected_error = NT_STATUS_INVALID_PARAMETER,
+ .expected_num_results = 0,
+ .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
+ },
+ {
+ .rid = DOMAIN_RID_ADMINISTRATOR,
+ .flags = NETR_CHANGELOG_SID_INCLUDED,
+ .db_index = SAM_DATABASE_PRIVS,
+ .delta_type = NETR_DELTA_ACCOUNT,
+ .sid = *sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DELETE_ACCOUNT,
+ .comment = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
+ },
+ {
+ .rid = 0,
+ .flags = NETR_CHANGELOG_NAME_INCLUDED,
+ .db_index = SAM_DATABASE_PRIVS,
+ .delta_type = NETR_DELTA_SECRET,
+ .sid = null_sid,
+ .name = "IsurelydontexistIhope",
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DELETE_SECRET,
+ .comment = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
+ },
+ {
+ .rid = 0,
+ .flags = NETR_CHANGELOG_NAME_INCLUDED,
+ .db_index = SAM_DATABASE_PRIVS,
+ .delta_type = NETR_DELTA_SECRET,
+ .sid = null_sid,
+ .name = "G$BCKUPKEY_P",
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_SECRET,
+ .comment = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
+ }
+ };
+
+ ZERO_STRUCT(return_authenticator);
+
+ r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
+ r.in.computername = TEST_MACHINE_NAME;
+ r.in.return_authenticator = &return_authenticator;
+ r.out.return_authenticator = &return_authenticator;
+ r.out.delta_enum_array = &delta_enum_array;
+
+ for (d=0; d<3; d++) {
+
+ const char *database;
+
+ switch (d) {
+ case 0:
+ database = "SAM";
+ break;
+ case 1:
+ database = "BUILTIN";
+ break;
+ case 2:
+ database = "LSA";
+ break;
+ default:
+ break;
+ }
+
+ torture_comment(tctx, "Testing DatabaseRedo\n");
+
+ if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
+ return false;
+ }
+
+ for (i=0;i<ARRAY_SIZE(changes);i++) {
+
+ if (d != changes[i].db_index) {
+ continue;
+ }
+
+ creds_client_authenticator(creds, &credential);
+
+ r.in.credential = &credential;
+
+ e.serial_number1 = 0;
+ e.serial_number2 = 0;
+ e.object_rid = changes[i].rid;
+ e.flags = changes[i].flags;
+ e.db_index = changes[i].db_index;
+ e.delta_type = changes[i].delta_type;
+
+ switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
+ case NETR_CHANGELOG_SID_INCLUDED:
+ e.object.object_sid = changes[i].sid;
+ break;
+ case NETR_CHANGELOG_NAME_INCLUDED:
+ e.object.object_name = changes[i].name;
+ break;
+ default:
+ break;
+ }
+
+ r.in.change_log_entry = e;
+
+ torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
+ database, changes[i].comment);
+
+ status = dcerpc_netr_DatabaseRedo(p, tctx, &r);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
+ return true;
+ }
+
+ torture_assert_ntstatus_equal(tctx, status, changes[i].expected_error, changes[i].comment);
+ if (delta_enum_array) {
+ torture_assert_int_equal(tctx,
+ delta_enum_array->num_deltas,
+ changes[i].expected_num_results,
+ changes[i].comment);
+ if (delta_enum_array->num_deltas > 0) {
+ torture_assert_int_equal(tctx,
+ delta_enum_array->delta_enum[0].delta_type,
+ changes[i].expected_delta_type_1,
+ changes[i].comment);
+ }
+ if (delta_enum_array->num_deltas > 1) {
+ torture_assert_int_equal(tctx,
+ delta_enum_array->delta_enum[1].delta_type,
+ changes[i].expected_delta_type_2,
+ changes[i].comment);
+ }
+ }
+
+ if (!creds_client_check(creds, &return_authenticator.cred)) {
+ torture_comment(tctx, "Credential chaining failed\n");
+ if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
+ return false;
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+}
/*
try a netlogon AccountDeltas
@@ -1761,6 +2295,7 @@ struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
+ torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
diff --git a/source4/torture/rpc/ntsvcs.c b/source4/torture/rpc/ntsvcs.c
new file mode 100644
index 0000000000..5453102039
--- /dev/null
+++ b/source4/torture/rpc/ntsvcs.c
@@ -0,0 +1,169 @@
+/*
+ Unix SMB/CIFS implementation.
+ test suite for rpc ntsvcs operations
+
+ Copyright (C) Guenther Deschner 2008
+
+ 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "lib/torture/torture.h"
+#include "torture/rpc/rpc.h"
+#include "librpc/gen_ndr/ndr_ntsvcs_c.h"
+#include "torture/util.h"
+#include "param/param.h"
+
+static bool test_PNP_GetVersion(struct torture_context *tctx,
+ struct dcerpc_pipe *p)
+{
+ NTSTATUS status;
+ struct PNP_GetVersion r;
+ uint16_t version = 0;
+
+ r.out.version = &version;
+
+ status = dcerpc_PNP_GetVersion(p, tctx, &r);
+
+ torture_assert_ntstatus_ok(tctx, status, "PNP_GetVersion");
+ torture_assert_werr_ok(tctx, r.out.result, "PNP_GetVersion");
+ torture_assert_int_equal(tctx, version, 0x400, "invalid version");
+
+ return true;
+}
+
+static bool test_PNP_GetDeviceListSize(struct torture_context *tctx,
+ struct dcerpc_pipe *p)
+{
+ NTSTATUS status;
+ struct PNP_GetDeviceListSize r;
+ uint32_t size = 0;
+
+ r.in.devicename = NULL;
+ r.in.flags = 0;
+ r.out.size = &size;
+
+ status = dcerpc_PNP_GetDeviceListSize(p, tctx, &r);
+
+ torture_assert_ntstatus_ok(tctx, status, "PNP_GetDeviceListSize");
+ torture_assert_werr_ok(tctx, r.out.result, "PNP_GetDeviceListSize");
+
+ return true;
+}
+
+static bool test_PNP_GetDeviceList(struct torture_context *tctx,
+ struct dcerpc_pipe *p)
+{
+ NTSTATUS status;
+ struct PNP_GetDeviceList r;
+ uint16_t *buffer = NULL;
+ uint32_t length = 0;
+
+ buffer = talloc_array(tctx, uint16_t, 0);
+
+ r.in.filter = NULL;
+ r.in.flags = 0;
+ r.in.length = &length;
+ r.out.length = &length;
+ r.out.buffer = buffer;
+
+ status = dcerpc_PNP_GetDeviceList(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "PNP_GetDeviceList");
+
+ if (W_ERROR_EQUAL(r.out.result, WERR_CM_BUFFER_SMALL)) {
+ struct PNP_GetDeviceListSize s;
+
+ s.in.devicename = NULL;
+ s.in.flags = 0;
+ s.out.size = &length;
+
+ status = dcerpc_PNP_GetDeviceListSize(p, tctx, &s);
+
+ torture_assert_ntstatus_ok(tctx, status, "PNP_GetDeviceListSize");
+ torture_assert_werr_ok(tctx, s.out.result, "PNP_GetDeviceListSize");
+ }
+
+ buffer = talloc_array(tctx, uint16_t, length);
+
+ r.in.length = &length;
+ r.out.length = &length;
+ r.out.buffer = buffer;
+
+ status = dcerpc_PNP_GetDeviceList(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "PNP_GetDeviceList");
+ torture_assert_werr_ok(tctx, r.out.result, "PNP_GetDeviceList");
+
+ return true;
+}
+
+static bool test_PNP_GetDeviceRegProp(struct torture_context *tctx,
+ struct dcerpc_pipe *p)
+{
+ NTSTATUS status;
+ struct PNP_GetDeviceRegProp r;
+
+ enum winreg_Type reg_data_type = REG_NONE;
+ uint32_t buffer_size = 0;
+ uint32_t needed = 0;
+ uint8_t *buffer;
+
+ buffer = talloc(tctx, uint8_t);
+
+ r.in.devicepath = "ACPI\\ACPI0003\\1";
+ r.in.property = DEV_REGPROP_DESC;
+ r.in.flags = 0;
+ r.in.reg_data_type = &reg_data_type;
+ r.in.buffer_size = &buffer_size;
+ r.in.needed = &needed;
+ r.out.buffer = buffer;
+ r.out.reg_data_type = &reg_data_type;
+ r.out.buffer_size = &buffer_size;
+ r.out.needed = &needed;
+
+ status = dcerpc_PNP_GetDeviceRegProp(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "PNP_GetDeviceRegProp");
+
+ if (W_ERROR_EQUAL(r.out.result, WERR_CM_BUFFER_SMALL)) {
+
+ buffer = talloc_array(tctx, uint8_t, needed);
+ r.in.buffer_size = &needed;
+
+ status = dcerpc_PNP_GetDeviceRegProp(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "PNP_GetDeviceRegProp");
+ }
+
+ return true;
+}
+
+struct torture_suite *torture_rpc_ntsvcs(TALLOC_CTX *mem_ctx)
+{
+ struct torture_rpc_tcase *tcase;
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "NTSVCS");
+ struct torture_test *test;
+
+ tcase = torture_suite_add_rpc_iface_tcase(suite, "ntsvcs",
+ &ndr_table_ntsvcs);
+
+ test = torture_rpc_tcase_add_test(tcase, "PNP_GetDeviceRegProp",
+ test_PNP_GetDeviceRegProp);
+ test = torture_rpc_tcase_add_test(tcase, "PNP_GetDeviceList",
+ test_PNP_GetDeviceList);
+ test = torture_rpc_tcase_add_test(tcase, "PNP_GetDeviceListSize",
+ test_PNP_GetDeviceListSize);
+ test = torture_rpc_tcase_add_test(tcase, "PNP_GetVersion",
+ test_PNP_GetVersion);
+
+ return suite;
+}
diff --git a/source4/torture/rpc/rpc.c b/source4/torture/rpc/rpc.c
index 2fcf700c36..7f6b06d000 100644
--- a/source4/torture/rpc/rpc.c
+++ b/source4/torture/rpc/rpc.c
@@ -395,6 +395,7 @@ NTSTATUS torture_rpc_init(void)
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);
+ torture_suite_add_simple_test(suite, "SAMR-PASSWORDS-PWDLASTSET", torture_rpc_samr_passwords_pwdlastset);
torture_suite_add_suite(suite, torture_rpc_netlogon(suite));
torture_suite_add_suite(suite, torture_rpc_remote_pac(suite));
torture_suite_add_simple_test(suite, "SAMLOGON", torture_rpc_samlogon);
@@ -438,6 +439,7 @@ NTSTATUS torture_rpc_init(void)
torture_suite_add_simple_test(suite, "DSSYNC", torture_rpc_dssync);
torture_suite_add_simple_test(suite, "BENCH-RPC", torture_bench_rpc);
torture_suite_add_simple_test(suite, "ASYNCBIND", torture_async_bind);
+ torture_suite_add_suite(suite, torture_rpc_ntsvcs(suite));
suite->description = talloc_strdup(suite, "DCE/RPC protocol and interface tests");
diff --git a/source4/torture/rpc/rpc.h b/source4/torture/rpc/rpc.h
index 29b1ebee54..9fd64f18b5 100644
--- a/source4/torture/rpc/rpc.h
+++ b/source4/torture/rpc/rpc.h
@@ -21,14 +21,13 @@
#ifndef __TORTURE_RPC_H__
#define __TORTURE_RPC_H__
-#include "torture/torture.h"
+#include "lib/torture/torture.h"
#include "auth/credentials/credentials.h"
#include "torture/rpc/drsuapi.h"
#include "libnet/libnet_join.h"
#include "librpc/rpc/dcerpc.h"
#include "libcli/raw/libcliraw.h"
#include "torture/rpc/proto.h"
-#include "torture/torture.h"
struct torture_rpc_tcase {
struct torture_tcase tcase;
diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c
index c2b849127f..f1e7e5a367 100644
--- a/source4/torture/rpc/samba3rpc.c
+++ b/source4/torture/rpc/samba3rpc.c
@@ -355,7 +355,7 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
char **domain,
struct dcerpc_pipe **result_pipe,
struct policy_handle **result_handle,
- struct dom_sid **sid)
+ struct dom_sid **sid_p)
{
struct dcerpc_pipe *samr_pipe;
NTSTATUS status;
@@ -365,7 +365,10 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
struct samr_Connect2 conn;
struct samr_EnumDomains enumdom;
uint32_t resume_handle = 0;
+ uint32_t num_entries = 0;
+ struct samr_SamArray *sam = NULL;
struct samr_LookupDomain l;
+ struct dom_sid2 *sid = NULL;
int dom_idx;
struct lsa_String domain_name;
struct lsa_String user_name;
@@ -423,6 +426,8 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
enumdom.in.resume_handle = &resume_handle;
enumdom.in.buf_size = (uint32_t)-1;
enumdom.out.resume_handle = &resume_handle;
+ enumdom.out.num_entries = &num_entries;
+ enumdom.out.sam = &sam;
status = dcerpc_samr_EnumDomains(samr_pipe, mem_ctx, &enumdom);
if (!NT_STATUS_IS_OK(status)) {
@@ -430,20 +435,21 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
goto fail;
}
- if (enumdom.out.num_entries != 2) {
+ if (*enumdom.out.num_entries != 2) {
d_printf("samr_EnumDomains returned %d entries, expected 2\n",
- enumdom.out.num_entries);
+ *enumdom.out.num_entries);
status = NT_STATUS_UNSUCCESSFUL;
goto fail;
}
- dom_idx = strequal(enumdom.out.sam->entries[0].name.string,
+ dom_idx = strequal(sam->entries[0].name.string,
"builtin") ? 1:0;
l.in.connect_handle = &conn_handle;
- domain_name.string = enumdom.out.sam->entries[dom_idx].name.string;
+ domain_name.string = sam->entries[dom_idx].name.string;
*domain = talloc_strdup(mem_ctx, domain_name.string);
l.in.domain_name = &domain_name;
+ l.out.sid = &sid;
status = dcerpc_samr_LookupDomain(samr_pipe, mem_ctx, &l);
if (!NT_STATUS_IS_OK(status)) {
@@ -453,7 +459,7 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
o.in.connect_handle = &conn_handle;
o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- o.in.sid = l.out.sid;
+ o.in.sid = *l.out.sid;
o.out.domain_handle = &domain_handle;
status = dcerpc_samr_OpenDomain(samr_pipe, mem_ctx, &o);
@@ -477,10 +483,13 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
struct samr_LookupNames ln;
struct samr_OpenUser ou;
+ struct samr_Ids rids, types;
ln.in.domain_handle = &domain_handle;
ln.in.num_names = 1;
ln.in.names = &user_name;
+ ln.out.rids = &rids;
+ ln.out.types = &types;
status = dcerpc_samr_LookupNames(samr_pipe, mem_ctx, &ln);
if (!NT_STATUS_IS_OK(status)) {
@@ -491,7 +500,7 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
ou.in.domain_handle = &domain_handle;
ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- user_rid = ou.in.rid = ln.out.rids.ids[0];
+ user_rid = ou.in.rid = ln.out.rids->ids[0];
ou.out.user_handle = user_handle;
status = dcerpc_samr_OpenUser(samr_pipe, mem_ctx, &ou);
@@ -509,8 +518,8 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
*result_pipe = samr_pipe;
*result_handle = user_handle;
- if (sid != NULL) {
- *sid = dom_sid_add_rid(mem_ctx, l.out.sid, user_rid);
+ if (sid_p != NULL) {
+ *sid_p = dom_sid_add_rid(mem_ctx, *l.out.sid, user_rid);
}
return NT_STATUS_OK;
@@ -555,6 +564,7 @@ static bool create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli,
struct samr_SetUserInfo sui;
struct samr_QueryUserInfo qui;
union samr_UserInfo u_info;
+ union samr_UserInfo *info;
DATA_BLOB session_key;
@@ -597,6 +607,7 @@ static bool create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli,
qui.in.user_handle = wks_handle;
qui.in.level = 21;
+ qui.out.info = &info;
status = dcerpc_samr_QueryUserInfo(samr_pipe, tmp_ctx, &qui);
if (!NT_STATUS_IS_OK(status)) {
@@ -604,14 +615,14 @@ static bool create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli,
goto done;
}
- qui.out.info->info21.allow_password_change = 0;
- qui.out.info->info21.force_password_change = 0;
- qui.out.info->info21.account_name.string = NULL;
- qui.out.info->info21.rid = 0;
- qui.out.info->info21.acct_expiry = 0;
- qui.out.info->info21.fields_present = 0x81827fa; /* copy usrmgr.exe */
+ info->info21.allow_password_change = 0;
+ info->info21.force_password_change = 0;
+ info->info21.account_name.string = NULL;
+ info->info21.rid = 0;
+ info->info21.acct_expiry = 0;
+ info->info21.fields_present = 0x81827fa; /* copy usrmgr.exe */
- u_info.info21 = qui.out.info->info21;
+ u_info.info21 = info->info21;
sui.in.user_handle = wks_handle;
sui.in.info = &u_info;
sui.in.level = 21;
@@ -721,9 +732,11 @@ static bool join3(struct smbcli_state *cli,
{
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
q.in.user_handle = wks_handle;
q.in.level = 21;
+ q.out.info = &info;
status = dcerpc_samr_QueryUserInfo(samr_pipe, mem_ctx, &q);
if (!NT_STATUS_IS_OK(status)) {
@@ -732,7 +745,7 @@ static bool join3(struct smbcli_state *cli,
goto done;
}
- last_password_change = q.out.info->info21.last_password_change;
+ last_password_change = info->info21.last_password_change;
}
cli_credentials_set_domain(wks_creds, dom_name, CRED_SPECIFIED);
@@ -755,6 +768,10 @@ static bool join3(struct smbcli_state *cli,
i21->acct_flags = ACB_WSTRUST;
i21->fields_present = SAMR_FIELD_FULL_NAME |
SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_PASSWORD;
+ /* this would break the test result expectations
+ i21->fields_present |= SAMR_FIELD_EXPIRED_FLAG;
+ i21->password_expired = 1;
+ */
encode_pw_buffer(u_info.info25.password.data,
cli_credentials_get_password(wks_creds),
@@ -795,8 +812,8 @@ static bool join3(struct smbcli_state *cli,
encode_pw_buffer(u_info.info24.password.data,
cli_credentials_get_password(wks_creds),
STR_UNICODE);
- u_info.info24.pw_len =
- strlen_m(cli_credentials_get_password(wks_creds))*2;
+ /* just to make this test pass */
+ u_info.info24.password_expired = 1;
status = dcerpc_fetch_session_key(samr_pipe, &session_key);
if (!NT_STATUS_IS_OK(status)) {
@@ -830,9 +847,11 @@ static bool join3(struct smbcli_state *cli,
{
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
q.in.user_handle = wks_handle;
q.in.level = 21;
+ q.out.info = &info;
status = dcerpc_samr_QueryUserInfo(samr_pipe, mem_ctx, &q);
if (!NT_STATUS_IS_OK(status)) {
@@ -843,7 +862,7 @@ static bool join3(struct smbcli_state *cli,
if (use_level25) {
if (last_password_change
- == q.out.info->info21.last_password_change) {
+ == info->info21.last_password_change) {
d_printf("(%s) last_password_change unchanged "
"during join, level25 must change "
"it\n", __location__);
@@ -852,7 +871,7 @@ static bool join3(struct smbcli_state *cli,
}
else {
if (last_password_change
- != q.out.info->info21.last_password_change) {
+ != info->info21.last_password_change) {
d_printf("(%s) last_password_change changed "
"during join, level24 doesn't "
"change it\n", __location__);
diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c
index 23c288bfcc..01ff01674c 100644
--- a/source4/torture/rpc/samr.c
+++ b/source4/torture/rpc/samr.c
@@ -29,6 +29,8 @@
#include "libcli/security/security.h"
#include "torture/rpc/rpc.h"
+#include <unistd.h>
+
#define TEST_ACCOUNT_NAME "samrtorturetest"
#define TEST_ALIASNAME "samrtorturetestalias"
#define TEST_GROUPNAME "samrtorturetestgroup"
@@ -37,6 +39,7 @@
enum torture_samr_choice {
TORTURE_SAMR_PASSWORDS,
+ TORTURE_SAMR_PASSWORDS_PWDLASTSET,
TORTURE_SAMR_USER_ATTRIBUTES,
TORTURE_SAMR_OTHER
};
@@ -59,6 +62,13 @@ static void init_lsa_String(struct lsa_String *string, const char *s)
string->string = s;
}
+static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
+{
+ string->length = length;
+ string->size = length;
+ string->array = (uint16_t *)discard_const(s);
+}
+
bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
struct policy_handle *handle)
{
@@ -131,18 +141,20 @@ static bool test_QuerySecurity(struct dcerpc_pipe *p,
NTSTATUS status;
struct samr_QuerySecurity r;
struct samr_SetSecurity s;
+ struct sec_desc_buf *sdbuf = NULL;
r.in.handle = handle;
r.in.sec_info = 7;
+ r.out.sdbuf = &sdbuf;
status = dcerpc_samr_QuerySecurity(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
- torture_assert(tctx, r.out.sdbuf != NULL, "sdbuf is NULL");
+ torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
s.in.handle = handle;
s.in.sec_info = 7;
- s.in.sdbuf = r.out.sdbuf;
+ s.in.sdbuf = sdbuf;
if (torture_setting_bool(tctx, "samba4", false)) {
torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
@@ -168,6 +180,7 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
struct samr_QueryUserInfo q;
struct samr_QueryUserInfo q0;
union samr_UserInfo u;
+ union samr_UserInfo *info;
bool ret = true;
const char *test_account_name;
@@ -184,7 +197,7 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
s2.in.info = &u;
q.in.user_handle = handle;
- q.out.info = &u;
+ q.out.info = &info;
q0 = q;
#define TESTCALL(call, r) \
@@ -204,6 +217,14 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
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", \
@@ -218,7 +239,7 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
TESTCALL(QueryUserInfo, q) \
s.in.level = lvl1; \
s2.in.level = lvl1; \
- u = *q.out.info; \
+ u = *info; \
if (lvl1 == 21) { \
ZERO_STRUCT(u.info21); \
u.info21.fields_present = fpval; \
@@ -228,21 +249,45 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
TESTCALL(SetUserInfo2, s2) \
init_lsa_String(&u.info ## lvl1.field1, ""); \
TESTCALL(QueryUserInfo, q); \
- u = *q.out.info; \
+ u = *info; \
STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
q.in.level = lvl2; \
TESTCALL(QueryUserInfo, q) \
- u = *q.out.info; \
+ u = *info; \
STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
} while (0)
+#define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
+ torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
+ q.in.level = lvl1; \
+ TESTCALL(QueryUserInfo, q) \
+ s.in.level = lvl1; \
+ s2.in.level = lvl1; \
+ u = *info; \
+ if (lvl1 == 21) { \
+ ZERO_STRUCT(u.info21); \
+ u.info21.fields_present = fpval; \
+ } \
+ init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
+ TESTCALL(SetUserInfo, s) \
+ TESTCALL(SetUserInfo2, s2) \
+ init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
+ TESTCALL(QueryUserInfo, q); \
+ u = *info; \
+ MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
+ q.in.level = lvl2; \
+ TESTCALL(QueryUserInfo, q) \
+ u = *info; \
+ MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
+ } while (0)
+
#define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
q.in.level = lvl1; \
TESTCALL(QueryUserInfo, q) \
s.in.level = lvl1; \
s2.in.level = lvl1; \
- u = *q.out.info; \
+ u = *info; \
if (lvl1 == 21) { \
uint8_t *bits = u.info21.logon_hours.bits; \
ZERO_STRUCT(u.info21); \
@@ -257,11 +302,11 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
TESTCALL(SetUserInfo2, s2) \
u.info ## lvl1.field1 = 0; \
TESTCALL(QueryUserInfo, q); \
- u = *q.out.info; \
+ u = *info; \
INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
q.in.level = lvl2; \
TESTCALL(QueryUserInfo, q) \
- u = *q.out.info; \
+ u = *info; \
INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
} while (0)
@@ -359,10 +404,10 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
SAMR_FIELD_WORKSTATIONS);
- TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
- TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
+ TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
+ TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
SAMR_FIELD_PARAMETERS);
- TEST_USERINFO_STRING(21, parameters, 20, parameters, "xx21-20 parameters",
+ TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
SAMR_FIELD_PARAMETERS);
TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
@@ -466,12 +511,19 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
/*
generate a random password for password change tests
*/
-static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
+static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
{
size_t len = MAX(8, min_len) + (random() % 6);
char *s = generate_random_str(mem_ctx, len);
+ return s;
+}
+
+static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
+{
+ char *s = samr_rand_pass_silent(mem_ctx, min_len);
printf("Generated password '%s'\n", s);
return s;
+
}
/*
@@ -512,12 +564,14 @@ static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx
DATA_BLOB session_key;
char *newpass;
struct samr_GetUserPwInfo pwp;
+ struct samr_PwInfo info;
int policy_min_pw_len = 0;
pwp.in.user_handle = handle;
+ pwp.out.info = &info;
status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = pwp.out.info.min_password_length;
+ policy_min_pw_len = pwp.out.info->min_password_length;
}
newpass = samr_rand_pass(tctx, policy_min_pw_len);
@@ -526,8 +580,7 @@ static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx
s.in.level = 24;
encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
- /* w2k3 ignores this length */
- u.info24.pw_len = strlen_m(newpass) * 2;
+ u.info24.password_expired = 0;
status = dcerpc_fetch_session_key(p, &session_key);
if (!NT_STATUS_IS_OK(status)) {
@@ -564,12 +617,14 @@ static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *t
DATA_BLOB session_key;
char *newpass;
struct samr_GetUserPwInfo pwp;
+ struct samr_PwInfo info;
int policy_min_pw_len = 0;
pwp.in.user_handle = handle;
+ pwp.out.info = &info;
status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = pwp.out.info.min_password_length;
+ policy_min_pw_len = pwp.out.info->min_password_length;
}
newpass = samr_rand_pass(tctx, policy_min_pw_len);
@@ -643,12 +698,14 @@ static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tc
char *newpass;
struct MD5Context ctx;
struct samr_GetUserPwInfo pwp;
+ struct samr_PwInfo info;
int policy_min_pw_len = 0;
pwp.in.user_handle = handle;
+ pwp.out.info = &info;
status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = pwp.out.info.min_password_length;
+ policy_min_pw_len = pwp.out.info->min_password_length;
}
if (makeshort && policy_min_pw_len) {
newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
@@ -661,7 +718,7 @@ static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tc
s.in.level = 26;
encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
- u.info26.pw_len = strlen(newpass);
+ u.info26.password_expired = 0;
status = dcerpc_fetch_session_key(p, &session_key);
if (!NT_STATUS_IS_OK(status)) {
@@ -725,12 +782,14 @@ static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *t
uint8_t confounder[16];
char *newpass;
struct samr_GetUserPwInfo pwp;
+ struct samr_PwInfo info;
int policy_min_pw_len = 0;
pwp.in.user_handle = handle;
+ pwp.out.info = &info;
status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = pwp.out.info.min_password_length;
+ policy_min_pw_len = pwp.out.info->min_password_length;
}
newpass = samr_rand_pass(tctx, policy_min_pw_len);
@@ -790,12 +849,161 @@ static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *t
return ret;
}
+static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
+ struct torture_context *tctx,
+ struct policy_handle *handle,
+ uint16_t level,
+ uint32_t fields_present,
+ char **password, uint8_t password_expired,
+ bool use_setinfo2, NTSTATUS expected_error)
+{
+ NTSTATUS status;
+ struct samr_SetUserInfo s;
+ struct samr_SetUserInfo2 s2;
+ union samr_UserInfo u;
+ bool ret = true;
+ DATA_BLOB session_key;
+ DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
+ struct MD5Context ctx;
+ uint8_t confounder[16];
+ char *newpass;
+ struct samr_GetUserPwInfo pwp;
+ struct samr_PwInfo info;
+ int policy_min_pw_len = 0;
+ const char *comment = NULL;
+
+ pwp.in.user_handle = handle;
+ pwp.out.info = &info;
+
+ status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
+ if (NT_STATUS_IS_OK(status)) {
+ policy_min_pw_len = pwp.out.info->min_password_length;
+ }
+ newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
+
+ if (use_setinfo2) {
+ s2.in.user_handle = handle;
+ s2.in.info = &u;
+ s2.in.level = level;
+ } else {
+ s.in.user_handle = handle;
+ s.in.info = &u;
+ s.in.level = level;
+ }
+
+ if (fields_present & SAMR_FIELD_COMMENT) {
+ comment = talloc_asprintf(tctx, "comment: %d\n", time(NULL));
+ }
+
+ ZERO_STRUCT(u);
+
+ switch (level) {
+ case 21:
+ u.info21.fields_present = fields_present;
+ u.info21.password_expired = password_expired;
+ u.info21.comment.string = comment;
+
+ break;
+ case 23:
+ u.info23.info.fields_present = fields_present;
+ u.info23.info.password_expired = password_expired;
+ u.info23.info.comment.string = comment;
+
+ encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
+
+ break;
+ case 24:
+ u.info24.password_expired = password_expired;
+
+ encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
+
+ break;
+ case 25:
+ u.info25.info.fields_present = fields_present;
+ u.info25.info.password_expired = password_expired;
+ u.info25.info.comment.string = comment;
+
+ encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
+
+ break;
+ case 26:
+ u.info26.password_expired = password_expired;
+
+ encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
+
+ break;
+ }
+
+ status = dcerpc_fetch_session_key(p, &session_key);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("SetUserInfo level %u - no session key - %s\n",
+ s.in.level, nt_errstr(status));
+ return false;
+ }
+
+ generate_random_buffer((uint8_t *)confounder, 16);
+
+ MD5Init(&ctx);
+ MD5Update(&ctx, confounder, 16);
+ MD5Update(&ctx, session_key.data, session_key.length);
+ MD5Final(confounded_session_key.data, &ctx);
+
+ switch (level) {
+ case 23:
+ arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
+ break;
+ case 24:
+ arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
+ break;
+ case 25:
+ arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
+ memcpy(&u.info25.password.data[516], confounder, 16);
+ break;
+ case 26:
+ arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
+ memcpy(&u.info26.password.data[516], confounder, 16);
+ break;
+ }
+
+ if (use_setinfo2) {
+ status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
+ } else {
+ status = dcerpc_samr_SetUserInfo(p, tctx, &s);
+ }
+
+ if (!NT_STATUS_IS_OK(expected_error)) {
+ if (use_setinfo2) {
+ torture_assert_ntstatus_equal(tctx,
+ s2.out.result,
+ expected_error, "SetUserInfo2 failed");
+ } else {
+ torture_assert_ntstatus_equal(tctx,
+ s.out.result,
+ expected_error, "SetUserInfo failed");
+ }
+ return true;
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("SetUserInfo%s level %u failed - %s\n",
+ use_setinfo2 ? "2":"", level, nt_errstr(status));
+ ret = false;
+ } else {
+ if (level != 21) {
+ *password = newpass;
+ }
+ }
+
+ return ret;
+}
+
static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
struct policy_handle *handle)
{
NTSTATUS status;
struct samr_SetAliasInfo r;
struct samr_QueryAliasInfo q;
+ union samr_AliasInfo *info;
uint16_t levels[] = {2, 3};
int i;
bool ret = true;
@@ -826,6 +1034,7 @@ static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tct
q.in.alias_handle = handle;
q.in.level = levels[i];
+ q.out.info = &info;
status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
if (!NT_STATUS_IS_OK(status)) {
@@ -842,11 +1051,13 @@ static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context
struct policy_handle *user_handle)
{
struct samr_GetGroupsForUser r;
+ struct samr_RidWithAttributeArray *rids = NULL;
NTSTATUS status;
torture_comment(tctx, "testing GetGroupsForUser\n");
r.in.user_handle = user_handle;
+ r.out.rids = &rids;
status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
@@ -860,8 +1071,11 @@ static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tct
{
NTSTATUS status;
struct samr_GetDomPwInfo r;
+ struct samr_PwInfo info;
r.in.domain_name = domain_name;
+ r.out.info = &info;
+
torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
@@ -893,10 +1107,12 @@ static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tc
{
NTSTATUS status;
struct samr_GetUserPwInfo r;
+ struct samr_PwInfo info;
torture_comment(tctx, "Testing GetUserPwInfo\n");
r.in.user_handle = handle;
+ r.out.info = &info;
status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
@@ -911,15 +1127,18 @@ static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *t
NTSTATUS status;
struct samr_LookupNames n;
struct lsa_String sname[2];
+ struct samr_Ids rids, types;
init_lsa_String(&sname[0], name);
n.in.domain_handle = domain_handle;
n.in.num_names = 1;
n.in.names = sname;
+ n.out.rids = &rids;
+ n.out.types = &types;
status = dcerpc_samr_LookupNames(p, tctx, &n);
if (NT_STATUS_IS_OK(status)) {
- *rid = n.out.rids.ids[0];
+ *rid = n.out.rids->ids[0];
} else {
return status;
}
@@ -1071,6 +1290,7 @@ static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_contex
char *newpass;
struct samr_GetUserPwInfo pwp;
+ struct samr_PwInfo info;
int policy_min_pw_len = 0;
status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
@@ -1078,10 +1298,11 @@ static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_contex
return false;
}
pwp.in.user_handle = &user_handle;
+ pwp.out.info = &info;
status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = pwp.out.info.min_password_length;
+ policy_min_pw_len = pwp.out.info->min_password_length;
}
newpass = samr_rand_pass(tctx, policy_min_pw_len);
@@ -1346,12 +1567,14 @@ static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_co
uint8_t old_lm_hash[16], new_lm_hash[16];
struct samr_GetDomPwInfo dom_pw_info;
+ struct samr_PwInfo info;
int policy_min_pw_len = 0;
struct lsa_String domain_name;
domain_name.string = "";
dom_pw_info.in.domain_name = &domain_name;
+ dom_pw_info.out.info = &info;
torture_comment(tctx, "Testing OemChangePasswordUser2\n");
@@ -1362,7 +1585,7 @@ static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_co
status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = dom_pw_info.out.info.min_password_length;
+ policy_min_pw_len = dom_pw_info.out.info->min_password_length;
}
newpass = samr_rand_pass(tctx, policy_min_pw_len);
@@ -1515,11 +1738,13 @@ static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_conte
uint8_t old_lm_hash[16], new_lm_hash[16];
struct samr_GetDomPwInfo dom_pw_info;
+ struct samr_PwInfo info;
struct lsa_String domain_name;
domain_name.string = "";
dom_pw_info.in.domain_name = &domain_name;
+ dom_pw_info.out.info = &info;
torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
@@ -1531,7 +1756,7 @@ static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_conte
int policy_min_pw_len = 0;
status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = dom_pw_info.out.info.min_password_length;
+ policy_min_pw_len = dom_pw_info.out.info->min_password_length;
}
newpass = samr_rand_pass(tctx, policy_min_pw_len);
@@ -1594,6 +1819,8 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct
uint8_t old_nt_hash[16], new_nt_hash[16];
uint8_t old_lm_hash[16], new_lm_hash[16];
NTTIME t;
+ struct samr_DomInfo1 *dominfo = NULL;
+ struct samr_ChangeReject *reject = NULL;
torture_comment(tctx, "Testing ChangePasswordUser3\n");
@@ -1641,6 +1868,8 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct
r.in.lm_password = &lm_pass;
r.in.lm_verifier = &lm_verifier;
r.in.password3 = NULL;
+ r.out.dominfo = &dominfo;
+ r.out.reject = &reject;
status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
@@ -1670,6 +1899,8 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct
r.in.lm_password = &lm_pass;
r.in.lm_verifier = &lm_verifier;
r.in.password3 = NULL;
+ r.out.dominfo = &dominfo;
+ r.out.reject = &reject;
status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
@@ -1712,21 +1943,23 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct
r.in.lm_password = &lm_pass;
r.in.lm_verifier = &lm_verifier;
r.in.password3 = NULL;
+ r.out.dominfo = &dominfo;
+ r.out.reject = &reject;
unix_to_nt_time(&t, time(NULL));
status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
- && r.out.dominfo
- && r.out.reject
+ && dominfo
+ && reject
&& handle_reject_reason
- && (!null_nttime(last_password_change) || !r.out.dominfo->min_password_age)) {
- if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
+ && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
+ if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
- if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) {
+ if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
- SAMR_REJECT_OTHER, r.out.reject->reason);
+ SAMR_REJECT_OTHER, reject->reason);
return false;
}
}
@@ -1740,54 +1973,54 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct
Guenther */
- if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
- (last_password_change + r.out.dominfo->min_password_age > t)) {
+ if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
+ (last_password_change + dominfo->min_password_age > t)) {
- if (r.out.reject->reason != SAMR_REJECT_OTHER) {
+ if (reject->reason != SAMR_REJECT_OTHER) {
printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
- SAMR_REJECT_OTHER, r.out.reject->reason);
+ SAMR_REJECT_OTHER, reject->reason);
return false;
}
- } else if ((r.out.dominfo->min_password_length > 0) &&
- (strlen(newpass) < r.out.dominfo->min_password_length)) {
+ } else if ((dominfo->min_password_length > 0) &&
+ (strlen(newpass) < dominfo->min_password_length)) {
- if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) {
+ if (reject->reason != SAMR_REJECT_TOO_SHORT) {
printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
- SAMR_REJECT_TOO_SHORT, r.out.reject->reason);
+ SAMR_REJECT_TOO_SHORT, reject->reason);
return false;
}
- } else if ((r.out.dominfo->password_history_length > 0) &&
+ } else if ((dominfo->password_history_length > 0) &&
strequal(oldpass, newpass)) {
- if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) {
+ if (reject->reason != SAMR_REJECT_IN_HISTORY) {
printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
- SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
+ SAMR_REJECT_IN_HISTORY, reject->reason);
return false;
}
- } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
+ } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
- if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
+ if (reject->reason != SAMR_REJECT_COMPLEXITY) {
printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
- SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
+ SAMR_REJECT_COMPLEXITY, reject->reason);
return false;
}
}
- if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
+ if (reject->reason == SAMR_REJECT_TOO_SHORT) {
/* retry with adjusted size */
return test_ChangePasswordUser3(p, tctx, account_string,
- r.out.dominfo->min_password_length,
+ dominfo->min_password_length,
password, NULL, 0, false);
}
} else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
- if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
+ if (reject && reject->reason != SAMR_REJECT_OTHER) {
printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
- SAMR_REJECT_OTHER, r.out.reject->reason);
+ SAMR_REJECT_OTHER, reject->reason);
return false;
}
/* Perhaps the server has a 'min password age' set? */
@@ -1823,6 +2056,8 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex
char *oldpass;
uint8_t old_nt_hash[16], new_nt_hash[16];
NTTIME t;
+ struct samr_DomInfo1 *dominfo = NULL;
+ struct samr_ChangeReject *reject = NULL;
new_random_pass = samr_very_rand_pass(tctx, 128);
@@ -1889,15 +2124,17 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex
r.in.lm_password = NULL;
r.in.lm_verifier = NULL;
r.in.password3 = NULL;
+ r.out.dominfo = &dominfo;
+ r.out.reject = &reject;
unix_to_nt_time(&t, time(NULL));
status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
- if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
+ if (reject && reject->reason != SAMR_REJECT_OTHER) {
printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
- SAMR_REJECT_OTHER, r.out.reject->reason);
+ SAMR_REJECT_OTHER, reject->reason);
return false;
}
/* Perhaps the server has a 'min password age' set? */
@@ -1925,15 +2162,17 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex
r.in.lm_password = NULL;
r.in.lm_verifier = NULL;
r.in.password3 = NULL;
+ r.out.dominfo = &dominfo;
+ r.out.reject = &reject;
unix_to_nt_time(&t, time(NULL));
status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
- if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
+ if (reject && reject->reason != SAMR_REJECT_OTHER) {
printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
- SAMR_REJECT_OTHER, r.out.reject->reason);
+ SAMR_REJECT_OTHER, reject->reason);
return false;
}
/* Perhaps the server has a 'min password age' set? */
@@ -2051,6 +2290,486 @@ static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_
return true;
}
+static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
+ struct torture_context *tctx,
+ struct policy_handle *handle,
+ bool use_info2,
+ NTTIME *pwdlastset)
+{
+ NTSTATUS status;
+ uint16_t levels[] = { /* 3, */ 5, 21 };
+ int i;
+ NTTIME pwdlastset3 = 0;
+ NTTIME pwdlastset5 = 0;
+ NTTIME pwdlastset21 = 0;
+
+ torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
+ use_info2 ? "2":"");
+
+ for (i=0; i<ARRAY_SIZE(levels); i++) {
+
+ struct samr_QueryUserInfo r;
+ struct samr_QueryUserInfo2 r2;
+ union samr_UserInfo *info;
+
+ if (use_info2) {
+ r2.in.user_handle = handle;
+ r2.in.level = levels[i];
+ r2.out.info = &info;
+ status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
+
+ } else {
+ r.in.user_handle = handle;
+ r.in.level = levels[i];
+ r.out.info = &info;
+ status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
+ }
+
+ if (!NT_STATUS_IS_OK(status) &&
+ !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
+ printf("QueryUserInfo%s level %u failed - %s\n",
+ use_info2 ? "2":"", levels[i], nt_errstr(status));
+ return false;
+ }
+
+ switch (levels[i]) {
+ case 3:
+ pwdlastset3 = info->info3.last_password_change;
+ break;
+ case 5:
+ pwdlastset5 = info->info5.last_password_change;
+ break;
+ case 21:
+ pwdlastset21 = info->info21.last_password_change;
+ break;
+ default:
+ return false;
+ }
+ }
+ /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
+ "pwdlastset mixup"); */
+ torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
+ "pwdlastset mixup");
+
+ *pwdlastset = pwdlastset21;
+
+ torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
+
+ return true;
+}
+
+static bool test_SetPassword_level(struct dcerpc_pipe *p,
+ struct torture_context *tctx,
+ struct policy_handle *handle,
+ uint16_t level,
+ uint32_t fields_present,
+ uint8_t password_expired,
+ NTSTATUS expected_error,
+ bool use_setinfo2,
+ char **password,
+ bool use_queryinfo2,
+ NTTIME *pwdlastset)
+{
+ const char *fields = NULL;
+ bool ret = true;
+
+ switch (level) {
+ case 21:
+ case 23:
+ case 25:
+ fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
+ fields_present);
+ break;
+ default:
+ break;
+ }
+
+ torture_comment(tctx, "Testing SetUserInfo%s level %d call "
+ "(password_expired: %d) %s\n",
+ use_setinfo2 ? "2":"", level, password_expired,
+ fields ? fields : "");
+
+ switch (level) {
+ case 21:
+ case 23:
+ case 24:
+ case 25:
+ case 26:
+ if (!test_SetUserPass_level_ex(p, tctx, handle, level,
+ fields_present,
+ password,
+ password_expired,
+ use_setinfo2,
+ expected_error)) {
+ ret = false;
+ }
+ break;
+ default:
+ return false;
+ }
+
+ if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
+ use_queryinfo2,
+ pwdlastset)) {
+ ret = false;
+ }
+
+ return ret;
+}
+
+static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
+ struct torture_context *tctx,
+ uint32_t acct_flags,
+ struct policy_handle *handle,
+ char **password)
+{
+ int i, s = 0, q = 0;
+ bool ret = true;
+ int delay = 500000;
+ bool set_levels[] = { false, true };
+ bool query_levels[] = { false, true };
+
+ struct {
+ uint16_t level;
+ uint8_t password_expired_nonzero;
+ uint32_t fields_present;
+ bool query_info2;
+ bool set_info2;
+ NTSTATUS set_error;
+ } pwd_tests[] = {
+
+ /* level 21 */
+ {
+ .level = 21,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_EXPIRED_FLAG
+ },{
+ .level = 21,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_LAST_PWD_CHANGE,
+ .set_error = NT_STATUS_ACCESS_DENIED
+ },{
+ .level = 21,
+ .password_expired_nonzero = 1,
+ .fields_present = 0,
+ .set_error = NT_STATUS_INVALID_PARAMETER
+ },{
+ .level = 21,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_COMMENT,
+
+#if 0
+ /* FIXME */
+ },{
+ .level = 21,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_PASSWORD |
+ SAMR_FIELD_PASSWORD2 |
+ SAMR_FIELD_LAST_PWD_CHANGE,
+ .query_info2 = false,
+ .set_error = NT_STATUS_ACCESS_DENIED
+#endif
+
+ /* level 23 */
+ },{
+ .level = 23,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_EXPIRED_FLAG
+ },{
+ .level = 23,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_LAST_PWD_CHANGE,
+ .set_error = NT_STATUS_ACCESS_DENIED
+ },{
+ .level = 23,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_LAST_PWD_CHANGE |
+ SAMR_FIELD_PASSWORD |
+ SAMR_FIELD_PASSWORD2,
+ .set_error = NT_STATUS_ACCESS_DENIED
+ },{
+ .level = 23,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_LAST_PWD_CHANGE |
+ SAMR_FIELD_PASSWORD |
+ SAMR_FIELD_PASSWORD2 |
+ SAMR_FIELD_EXPIRED_FLAG,
+ .set_error = NT_STATUS_ACCESS_DENIED
+ },{
+ .level = 23,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_PASSWORD |
+ SAMR_FIELD_PASSWORD2 |
+ SAMR_FIELD_EXPIRED_FLAG
+ },{
+ .level = 23,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_PASSWORD |
+ SAMR_FIELD_PASSWORD2,
+ },{
+ .level = 23,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_COMMENT,
+ },{
+ .level = 23,
+ .password_expired_nonzero = 1,
+ .fields_present = 0,
+ .set_error = NT_STATUS_INVALID_PARAMETER
+ },{
+
+ /* level 24 */
+
+ .level = 24,
+ .password_expired_nonzero = 1
+ },{
+ .level = 24,
+ .password_expired_nonzero = 24
+ },{
+
+ /* level 25 */
+
+ .level = 25,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_LAST_PWD_CHANGE,
+ .set_error = NT_STATUS_ACCESS_DENIED
+ },{
+ .level = 25,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_EXPIRED_FLAG,
+ },{
+ .level = 25,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_PASSWORD |
+ SAMR_FIELD_PASSWORD2 |
+ SAMR_FIELD_EXPIRED_FLAG
+ },{
+ .level = 25,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_PASSWORD |
+ SAMR_FIELD_PASSWORD2,
+ },{
+ .level = 25,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_COMMENT,
+ },{
+
+ /* level 26 */
+
+ .level = 26,
+ .password_expired_nonzero = 1
+ },{
+ .level = 26,
+ .password_expired_nonzero = 24
+ }
+ };
+
+ if (torture_setting_bool(tctx, "samba3", false)) {
+ delay = 1000000;
+ printf("Samba3 has second granularity, setting delay to: %d\n",
+ delay);
+ }
+
+ /* set to 1 to enable testing for all possible opcode
+ (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
+ combinations */
+#if 0
+#define TEST_SET_LEVELS 1
+#define TEST_QUERY_LEVELS 1
+#endif
+ for (i=0; i<ARRAY_SIZE(pwd_tests); i++) {
+#ifdef TEST_SET_LEVELS
+ for (s=0; s<ARRAY_SIZE(set_levels); s++) {
+#endif
+#ifdef TEST_QUERY_LEVELS
+ for (q=0; q<ARRAY_SIZE(query_levels); q++) {
+#endif
+ NTTIME pwdlastset_old = 0;
+ NTTIME pwdlastset_new = 0;
+
+ torture_comment(tctx, "------------------------------\n"
+ "Testing pwdLastSet attribute for flags: 0x%08x "
+ "(s: %d (l: %d), q: %d)\n",
+ acct_flags, s, pwd_tests[i].level, q);
+
+ /* set #1 */
+
+ /* set a password and force password change (pwdlastset 0) by
+ * setting the password expired flag to a non-0 value */
+
+ if (!test_SetPassword_level(p, tctx, handle,
+ pwd_tests[i].level,
+ pwd_tests[i].fields_present,
+ pwd_tests[i].password_expired_nonzero,
+ pwd_tests[i].set_error,
+ set_levels[s],
+ password,
+ query_levels[q],
+ &pwdlastset_old)) {
+ ret = false;
+ }
+
+ if (!NT_STATUS_IS_OK(pwd_tests[i].set_error)) {
+ /* skipping on expected failure */
+ continue;
+ }
+
+ /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
+ * set without the SAMR_FIELD_EXPIRED_FLAG */
+
+ switch (pwd_tests[i].level) {
+ case 21:
+ case 23:
+ case 25:
+ if ((pwdlastset_new != 0) &&
+ !(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG)) {
+ torture_comment(tctx, "not considering a non-0 "
+ "pwdLastSet as a an error as the "
+ "SAMR_FIELD_EXPIRED_FLAG has not "
+ "been set\n");
+ break;
+ }
+ default:
+ if (pwdlastset_new != 0) {
+ torture_warning(tctx, "pwdLastSet test failed: "
+ "expected pwdLastSet 0 but got %lld\n",
+ pwdlastset_old);
+ ret = false;
+ }
+ break;
+ }
+
+ usleep(delay);
+
+ /* set #2 */
+
+ /* set a password, pwdlastset needs to get updated (increased
+ * value), password_expired value used here is 0 */
+
+ if (!test_SetPassword_level(p, tctx, handle, pwd_tests[i].level,
+ pwd_tests[i].fields_present,
+ 0,
+ pwd_tests[i].set_error,
+ set_levels[s],
+ password,
+ query_levels[q],
+ &pwdlastset_new)) {
+
+ ret = false;
+ }
+
+ /* when a password has been changed, pwdlastset must not be 0 afterwards
+ * and must be larger then the old value */
+
+ switch (pwd_tests[i].level) {
+ case 21:
+ case 23:
+ case 25:
+
+ /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
+ * password has been changed, old and new pwdlastset
+ * need to be the same value */
+
+ if (!(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG) &&
+ !((pwd_tests[i].fields_present & SAMR_FIELD_PASSWORD) ||
+ (pwd_tests[i].fields_present & SAMR_FIELD_PASSWORD2)))
+ {
+ torture_assert_int_equal(tctx, pwdlastset_old,
+ pwdlastset_new, "pwdlastset must be equal");
+ break;
+ }
+ default:
+ if (pwdlastset_old >= pwdlastset_new) {
+ torture_warning(tctx, "pwdLastSet test failed: "
+ "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
+ pwdlastset_old, pwdlastset_new);
+ ret = false;
+ }
+ if (pwdlastset_new == 0) {
+ torture_warning(tctx, "pwdLastSet test failed: "
+ "expected non-0 pwdlastset, got: %lld\n",
+ pwdlastset_new);
+ ret = false;
+ }
+ }
+
+ pwdlastset_old = pwdlastset_new;
+
+ usleep(delay);
+
+ /* set #3 */
+
+ /* set a password and force password change (pwdlastset 0) by
+ * setting the password expired flag to a non-0 value */
+
+ if (!test_SetPassword_level(p, tctx, handle, pwd_tests[i].level,
+ pwd_tests[i].fields_present,
+ pwd_tests[i].password_expired_nonzero,
+ pwd_tests[i].set_error,
+ set_levels[s],
+ password,
+ query_levels[q],
+ &pwdlastset_new)) {
+ ret = false;
+ }
+
+ /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
+ * set without the SAMR_FIELD_EXPIRED_FLAG */
+
+ switch (pwd_tests[i].level) {
+ case 21:
+ case 23:
+ case 25:
+ if ((pwdlastset_new != 0) &&
+ !(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG)) {
+ torture_comment(tctx, "not considering a non-0 "
+ "pwdLastSet as a an error as the "
+ "SAMR_FIELD_EXPIRED_FLAG has not "
+ "been set\n");
+ break;
+ }
+
+ /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
+ * password has been changed, old and new pwdlastset
+ * need to be the same value */
+
+ if (!(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG) &&
+ !((pwd_tests[i].fields_present & SAMR_FIELD_PASSWORD) ||
+ (pwd_tests[i].fields_present & SAMR_FIELD_PASSWORD2)))
+ {
+ torture_assert_int_equal(tctx, pwdlastset_old,
+ pwdlastset_new, "pwdlastset must be equal");
+ break;
+ }
+ default:
+
+ if (pwdlastset_old == pwdlastset_new) {
+ torture_warning(tctx, "pwdLastSet test failed: "
+ "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
+ pwdlastset_old, pwdlastset_new);
+ ret = false;
+ }
+
+ if (pwdlastset_new != 0) {
+ torture_warning(tctx, "pwdLastSet test failed: "
+ "expected pwdLastSet 0, got %lld\n",
+ pwdlastset_old);
+ ret = false;
+ }
+ break;
+ }
+#ifdef TEST_QUERY_LEVELS
+ }
+#endif
+#ifdef TEST_SET_LEVELS
+ }
+#endif
+ }
+
+#undef TEST_SET_LEVELS
+#undef TEST_QUERY_LEVELS
+
+ return ret;
+}
static bool test_user_ops(struct dcerpc_pipe *p,
struct torture_context *tctx,
@@ -2061,6 +2780,7 @@ static bool test_user_ops(struct dcerpc_pipe *p,
{
char *password = NULL;
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
NTSTATUS status;
bool ret = true;
@@ -2143,7 +2863,7 @@ static bool test_user_ops(struct dcerpc_pipe *p,
ret = false;
}
}
-
+
for (i = 0; password_fields[i]; i++) {
if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
ret = false;
@@ -2176,6 +2896,7 @@ static bool test_user_ops(struct dcerpc_pipe *p,
q.in.user_handle = user_handle;
q.in.level = 5;
+ q.out.info = &info;
status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
if (!NT_STATUS_IS_OK(status)) {
@@ -2184,20 +2905,37 @@ static bool test_user_ops(struct dcerpc_pipe *p,
ret = false;
} else {
uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
- if ((q.out.info->info5.acct_flags) != expected_flags) {
+ if ((info->info5.acct_flags) != expected_flags) {
printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
- q.out.info->info5.acct_flags,
+ info->info5.acct_flags,
expected_flags);
ret = false;
}
- if (q.out.info->info5.rid != rid) {
+ if (info->info5.rid != rid) {
printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
- q.out.info->info5.rid, rid);
+ info->info5.rid, rid);
}
}
break;
+
+ case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
+
+ /* test last password change timestamp behaviour */
+ if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
+ user_handle, &password)) {
+ ret = false;
+ }
+
+ if (ret == true) {
+ torture_comment(tctx, "pwdLastSet test succeeded\n");
+ } else {
+ torture_warning(tctx, "pwdLastSet test failed\n");
+ }
+
+ break;
+
case TORTURE_SAMR_OTHER:
/* We just need the account to exist */
break;
@@ -2481,6 +3219,7 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
/* set samr_SetDomainInfo level 1 with min_length 5 */
{
struct samr_QueryDomainInfo r;
+ union samr_DomainInfo *info = NULL;
struct samr_SetDomainInfo s;
uint16_t len_old, len;
uint32_t pwd_prop_old;
@@ -2491,6 +3230,7 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.domain_handle = domain_handle;
r.in.level = 1;
+ r.out.info = &info;
printf("testing samr_QueryDomainInfo level 1\n");
status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
@@ -2500,7 +3240,7 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
s.in.domain_handle = domain_handle;
s.in.level = 1;
- s.in.info = r.out.info;
+ s.in.info = info;
/* remember the old min length, so we can reset it */
len_old = s.in.info->info1.min_password_length;
@@ -2540,13 +3280,17 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
NTSTATUS status;
struct samr_OpenUser r;
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
struct samr_LookupNames n;
struct policy_handle user_handle;
+ struct samr_Ids rids, types;
n.in.domain_handle = domain_handle;
n.in.num_names = 1;
n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
n.in.names[0].string = acct_name;
+ n.out.rids = &rids;
+ n.out.types = &types;
status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
if (!NT_STATUS_IS_OK(status)) {
@@ -2556,17 +3300,18 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.domain_handle = domain_handle;
r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- r.in.rid = n.out.rids.ids[0];
+ r.in.rid = n.out.rids->ids[0];
r.out.user_handle = &user_handle;
status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
+ printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
return false;
}
q.in.user_handle = &user_handle;
q.in.level = 5;
+ q.out.info = &info;
status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
if (!NT_STATUS_IS_OK(status)) {
@@ -2577,7 +3322,7 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
printf("calling test_ChangePasswordUser3 with too early password change\n");
if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
- q.out.info->info5.last_password_change, true)) {
+ info->info5.last_password_change, true)) {
ret = false;
}
}
@@ -2607,6 +3352,7 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
NTSTATUS status;
struct samr_CreateUser r;
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
struct samr_DeleteUser d;
uint32_t rid;
@@ -2654,6 +3400,7 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
} else {
q.in.user_handle = &user_handle;
q.in.level = 16;
+ q.out.info = &info;
status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
if (!NT_STATUS_IS_OK(status)) {
@@ -2661,9 +3408,9 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
q.in.level, nt_errstr(status));
ret = false;
} else {
- if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
+ if ((info->info16.acct_flags & acct_flags) != acct_flags) {
printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
- q.out.info->info16.acct_flags,
+ info->info16.acct_flags,
acct_flags);
ret = false;
}
@@ -2705,6 +3452,7 @@ static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx
NTSTATUS status;
struct samr_CreateUser2 r;
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
struct samr_DeleteUser d;
struct policy_handle user_handle;
uint32_t rid;
@@ -2783,6 +3531,7 @@ static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx
if (NT_STATUS_IS_OK(status)) {
q.in.user_handle = &user_handle;
q.in.level = 5;
+ q.out.info = &info;
status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
if (!NT_STATUS_IS_OK(status)) {
@@ -2794,31 +3543,31 @@ static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx
if (acct_flags == ACB_NORMAL) {
expected_flags |= ACB_PW_EXPIRED;
}
- if ((q.out.info->info5.acct_flags) != expected_flags) {
+ if ((info->info5.acct_flags) != expected_flags) {
printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
- q.out.info->info5.acct_flags,
+ info->info5.acct_flags,
expected_flags);
ret = false;
}
switch (acct_flags) {
case ACB_SVRTRUST:
- if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
+ if (info->info5.primary_gid != DOMAIN_RID_DCS) {
printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
- DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
+ DOMAIN_RID_DCS, info->info5.primary_gid);
ret = false;
}
break;
case ACB_WSTRUST:
- if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
+ if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
- DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
+ DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
ret = false;
}
break;
case ACB_NORMAL:
- if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
+ if (info->info5.primary_gid != DOMAIN_RID_USERS) {
printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
- DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
+ DOMAIN_RID_USERS, info->info5.primary_gid);
ret = false;
}
break;
@@ -2852,6 +3601,7 @@ static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
{
NTSTATUS status;
struct samr_QueryAliasInfo r;
+ union samr_AliasInfo *info;
uint16_t levels[] = {1, 2, 3};
int i;
bool ret = true;
@@ -2861,6 +3611,7 @@ static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.alias_handle = handle;
r.in.level = levels[i];
+ r.out.info = &info;
status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -2878,6 +3629,7 @@ static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
{
NTSTATUS status;
struct samr_QueryGroupInfo r;
+ union samr_GroupInfo *info;
uint16_t levels[] = {1, 2, 3, 4, 5};
int i;
bool ret = true;
@@ -2887,6 +3639,7 @@ static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.group_handle = handle;
r.in.level = levels[i];
+ r.out.info = &info;
status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -2904,11 +3657,13 @@ static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
{
NTSTATUS status;
struct samr_QueryGroupMember r;
+ struct samr_RidTypeArray *rids = NULL;
bool ret = true;
printf("Testing QueryGroupMember\n");
r.in.group_handle = handle;
+ r.out.rids = &rids;
status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -2925,6 +3680,7 @@ static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
{
NTSTATUS status;
struct samr_QueryGroupInfo r;
+ union samr_GroupInfo *info;
struct samr_SetGroupInfo s;
uint16_t levels[] = {1, 2, 3, 4};
uint16_t set_ok[] = {0, 1, 1, 1};
@@ -2936,6 +3692,7 @@ static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.group_handle = handle;
r.in.level = levels[i];
+ r.out.info = &info;
status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -2948,7 +3705,7 @@ static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
s.in.group_handle = handle;
s.in.level = levels[i];
- s.in.info = r.out.info;
+ s.in.info = *r.out.info;
#if 0
/* disabled this, as it changes the name only from the point of view of samr,
@@ -2990,6 +3747,7 @@ static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
{
NTSTATUS status;
struct samr_QueryUserInfo r;
+ union samr_UserInfo *info;
uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 16, 17, 20, 21};
int i;
@@ -3000,6 +3758,7 @@ static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.user_handle = handle;
r.in.level = levels[i];
+ r.out.info = &info;
status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -3017,6 +3776,7 @@ static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
{
NTSTATUS status;
struct samr_QueryUserInfo2 r;
+ union samr_UserInfo *info;
uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 16, 17, 20, 21};
int i;
@@ -3027,6 +3787,7 @@ static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.user_handle = handle;
r.in.level = levels[i];
+ r.out.info = &info;
status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -3174,6 +3935,7 @@ static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
NTSTATUS status;
struct samr_OpenUser r;
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
struct policy_handle user_handle;
bool ret = true;
@@ -3192,6 +3954,7 @@ static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
q.in.user_handle = &user_handle;
q.in.level = 16;
+ q.out.info = &info;
status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
if (!NT_STATUS_IS_OK(status)) {
@@ -3199,9 +3962,9 @@ static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
nt_errstr(status));
ret = false;
} else {
- if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
+ if ((acct_flag_mask & info->info16.acct_flags) == 0) {
printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
- acct_flag_mask, q.out.info->info16.acct_flags, rid);
+ acct_flag_mask, info->info16.acct_flags, rid);
ret = false;
}
}
@@ -3223,6 +3986,11 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *
bool ret = true;
struct samr_LookupNames n;
struct samr_LookupRids lr ;
+ struct lsa_Strings names;
+ struct samr_Ids rids, types;
+ struct samr_SamArray *sam = NULL;
+ uint32_t num_entries = 0;
+
uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
@@ -3236,6 +4004,8 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *
r.in.acct_flags = mask = masks[mask_idx];
r.in.max_size = (uint32_t)-1;
r.out.resume_handle = &resume_handle;
+ r.out.num_entries = &num_entries;
+ r.out.sam = &sam;
status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
@@ -3244,18 +4014,18 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *
return false;
}
- torture_assert(tctx, r.out.sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
+ torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
- if (r.out.sam->count == 0) {
+ if (sam->count == 0) {
continue;
}
- for (i=0;i<r.out.sam->count;i++) {
+ for (i=0;i<sam->count;i++) {
if (mask) {
- if (!check_mask(p, tctx, handle, r.out.sam->entries[i].idx, mask)) {
+ if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
ret = false;
}
- } else if (!test_OpenUser(p, tctx, handle, r.out.sam->entries[i].idx)) {
+ } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
ret = false;
}
}
@@ -3263,10 +4033,12 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *
printf("Testing LookupNames\n");
n.in.domain_handle = handle;
- n.in.num_names = r.out.sam->count;
- n.in.names = talloc_array(tctx, struct lsa_String, r.out.sam->count);
- for (i=0;i<r.out.sam->count;i++) {
- n.in.names[i].string = r.out.sam->entries[i].name.string;
+ n.in.num_names = sam->count;
+ n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
+ n.out.rids = &rids;
+ n.out.types = &types;
+ for (i=0;i<sam->count;i++) {
+ n.in.names[i].string = sam->entries[i].name.string;
}
status = dcerpc_samr_LookupNames(p, tctx, &n);
if (!NT_STATUS_IS_OK(status)) {
@@ -3277,10 +4049,12 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *
printf("Testing LookupRids\n");
lr.in.domain_handle = handle;
- lr.in.num_rids = r.out.sam->count;
- lr.in.rids = talloc_array(tctx, uint32_t, r.out.sam->count);
- for (i=0;i<r.out.sam->count;i++) {
- lr.in.rids[i] = r.out.sam->entries[i].idx;
+ lr.in.num_rids = sam->count;
+ lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
+ lr.out.names = &names;
+ lr.out.types = &types;
+ for (i=0;i<sam->count;i++) {
+ lr.in.rids[i] = sam->entries[i].idx;
}
status = dcerpc_samr_LookupRids(p, tctx, &lr);
torture_assert_ntstatus_ok(tctx, status, "LookupRids");
@@ -3337,6 +4111,8 @@ static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
NTSTATUS status;
struct samr_EnumDomainGroups r;
uint32_t resume_handle=0;
+ struct samr_SamArray *sam = NULL;
+ uint32_t num_entries = 0;
int i;
bool ret = true;
@@ -3346,6 +4122,8 @@ static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.resume_handle = &resume_handle;
r.in.max_size = (uint32_t)-1;
r.out.resume_handle = &resume_handle;
+ r.out.num_entries = &num_entries;
+ r.out.sam = &sam;
status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -3353,12 +4131,12 @@ static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return false;
}
- if (!r.out.sam) {
+ if (!sam) {
return false;
}
- for (i=0;i<r.out.sam->count;i++) {
- if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
+ for (i=0;i<sam->count;i++) {
+ if (!test_OpenGroup(p, mem_ctx, handle, sam->entries[i].idx)) {
ret = false;
}
}
@@ -3372,6 +4150,8 @@ static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
NTSTATUS status;
struct samr_EnumDomainAliases r;
uint32_t resume_handle=0;
+ struct samr_SamArray *sam = NULL;
+ uint32_t num_entries = 0;
int i;
bool ret = true;
@@ -3379,7 +4159,9 @@ static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.domain_handle = handle;
r.in.resume_handle = &resume_handle;
- r.in.acct_flags = (uint32_t)-1;
+ r.in.max_size = (uint32_t)-1;
+ r.out.sam = &sam;
+ r.out.num_entries = &num_entries;
r.out.resume_handle = &resume_handle;
status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
@@ -3388,12 +4170,12 @@ static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return false;
}
- if (!r.out.sam) {
+ if (!sam) {
return false;
}
- for (i=0;i<r.out.sam->count;i++) {
- if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
+ for (i=0;i<sam->count;i++) {
+ if (!test_OpenAlias(p, mem_ctx, handle, sam->entries[i].idx)) {
ret = false;
}
}
@@ -3409,14 +4191,19 @@ static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *m
bool ret = true;
uint16_t levels[] = {1, 2, 3, 4, 5};
uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
+ struct lsa_String name;
+ uint32_t idx = 0;
int i;
for (i=0;i<ARRAY_SIZE(levels);i++) {
printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
+ init_lsa_String(&name, TEST_ACCOUNT_NAME);
+
r.in.domain_handle = handle;
r.in.level = levels[i];
- init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
+ r.in.name = &name;
+ r.out.idx = &idx;
status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
@@ -3428,7 +4215,7 @@ static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *m
ret = false;
}
- init_lsa_String(&r.in.name, "zzzzzzzz");
+ init_lsa_String(&name, "zzzzzzzz");
status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
@@ -3450,14 +4237,19 @@ static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *
bool ret = true;
uint16_t levels[] = {1, 2, 3, 4, 5};
uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
+ struct lsa_String name;
+ uint32_t idx = 0;
int i;
for (i=0;i<ARRAY_SIZE(levels);i++) {
printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
+ init_lsa_String(&name, TEST_ACCOUNT_NAME);
+
r.in.domain_handle = handle;
r.in.level = levels[i];
- init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
+ r.in.name = &name;
+ r.out.idx = &idx;
status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
if (ok_lvl[i] &&
@@ -3468,7 +4260,7 @@ static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *
ret = false;
}
- init_lsa_String(&r.in.name, "zzzzzzzz");
+ init_lsa_String(&name, "zzzzzzzz");
status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
@@ -3502,6 +4294,7 @@ static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct
{
struct samr_OpenUser r;
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
struct policy_handle user_handle;
int i, ret = true;
NTSTATUS status;
@@ -3510,16 +4303,16 @@ static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct
for (i = 0; ; i++) {
switch (querydisplayinfo->in.level) {
case 1:
- if (i >= querydisplayinfo->out.info.info1.count) {
+ if (i >= querydisplayinfo->out.info->info1.count) {
return ret;
}
- r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid;
+ r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
break;
case 2:
- if (i >= querydisplayinfo->out.info.info2.count) {
+ if (i >= querydisplayinfo->out.info->info2.count) {
return ret;
}
- r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid;
+ r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
break;
case 3:
/* Groups */
@@ -3543,6 +4336,7 @@ static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct
q.in.user_handle = &user_handle;
q.in.level = 21;
+ q.out.info = &info;
status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
if (!NT_STATUS_IS_OK(status)) {
printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
@@ -3551,41 +4345,41 @@ static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct
switch (querydisplayinfo->in.level) {
case 1:
- if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
+ if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
*seen_testuser = true;
}
- STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name,
- q.out.info->info21.full_name, q.out.info->info21.account_name);
- STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name,
- q.out.info->info21.account_name, q.out.info->info21.account_name);
- STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description,
- q.out.info->info21.description, q.out.info->info21.account_name);
- INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid,
- q.out.info->info21.rid, q.out.info->info21.account_name);
- INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags,
- q.out.info->info21.acct_flags, q.out.info->info21.account_name);
+ STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
+ info->info21.full_name, info->info21.account_name);
+ STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
+ info->info21.account_name, info->info21.account_name);
+ STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
+ info->info21.description, info->info21.account_name);
+ INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
+ info->info21.rid, info->info21.account_name);
+ INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
+ info->info21.acct_flags, info->info21.account_name);
break;
case 2:
- STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name,
- q.out.info->info21.account_name, q.out.info->info21.account_name);
- STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description,
- q.out.info->info21.description, q.out.info->info21.account_name);
- INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid,
- q.out.info->info21.rid, q.out.info->info21.account_name);
- INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL),
- q.out.info->info21.acct_flags, q.out.info->info21.account_name);
+ STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
+ info->info21.account_name, info->info21.account_name);
+ STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
+ info->info21.description, info->info21.account_name);
+ INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
+ info->info21.rid, info->info21.account_name);
+ INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
+ info->info21.acct_flags, info->info21.account_name);
- if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) {
+ if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
- q.out.info->info21.account_name.string);
+ info->info21.account_name.string);
}
- if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
+ if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
- q.out.info->info21.account_name.string,
- querydisplayinfo->out.info.info2.entries[i].acct_flags,
- q.out.info->info21.acct_flags);
+ info->info21.account_name.string,
+ querydisplayinfo->out.info->info2.entries[i].acct_flags,
+ info->info21.acct_flags);
return false;
}
@@ -3605,10 +4399,15 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
NTSTATUS status;
struct samr_QueryDisplayInfo r;
struct samr_QueryDomainInfo dom_info;
+ union samr_DomainInfo *info = NULL;
bool ret = true;
uint16_t levels[] = {1, 2, 3, 4, 5};
int i;
bool seen_testuser = false;
+ uint32_t total_size;
+ uint32_t returned_size;
+ union samr_DispInfo disp_info;
+
for (i=0;i<ARRAY_SIZE(levels);i++) {
printf("Testing QueryDisplayInfo level %u\n", levels[i]);
@@ -3620,6 +4419,9 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.level = levels[i];
r.in.max_entries = 2;
r.in.buf_size = (uint32_t)-1;
+ r.out.total_size = &total_size;
+ r.out.returned_size = &returned_size;
+ r.out.info = &disp_info;
status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
@@ -3632,27 +4434,29 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
ret = false;
}
- r.in.start_idx += r.out.info.info1.count;
+ r.in.start_idx += r.out.info->info1.count;
break;
case 2:
if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
ret = false;
}
- r.in.start_idx += r.out.info.info2.count;
+ r.in.start_idx += r.out.info->info2.count;
break;
case 3:
- r.in.start_idx += r.out.info.info3.count;
+ r.in.start_idx += r.out.info->info3.count;
break;
case 4:
- r.in.start_idx += r.out.info.info4.count;
+ r.in.start_idx += r.out.info->info4.count;
break;
case 5:
- r.in.start_idx += r.out.info.info5.count;
+ r.in.start_idx += r.out.info->info5.count;
break;
}
}
dom_info.in.domain_handle = handle;
dom_info.in.level = 2;
+ dom_info.out.info = &info;
+
/* Check number of users returned is correct */
status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
if (!NT_STATUS_IS_OK(status)) {
@@ -3664,17 +4468,17 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
switch (r.in.level) {
case 1:
case 4:
- if (dom_info.out.info->general.num_users < r.in.start_idx) {
+ if (info->general.num_users < r.in.start_idx) {
printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
- r.in.start_idx, dom_info.out.info->general.num_groups,
- dom_info.out.info->general.domain_name.string);
+ r.in.start_idx, info->general.num_groups,
+ info->general.domain_name.string);
ret = false;
}
if (!seen_testuser) {
struct policy_handle user_handle;
if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
- dom_info.out.info->general.domain_name.string);
+ info->general.domain_name.string);
ret = false;
test_samr_handle_Close(p, mem_ctx, &user_handle);
}
@@ -3682,10 +4486,10 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
break;
case 3:
case 5:
- if (dom_info.out.info->general.num_groups != r.in.start_idx) {
+ if (info->general.num_groups != r.in.start_idx) {
printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
- r.in.start_idx, dom_info.out.info->general.num_groups,
- dom_info.out.info->general.domain_name.string);
+ r.in.start_idx, info->general.num_groups,
+ info->general.domain_name.string);
ret = false;
}
@@ -3705,6 +4509,9 @@ static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
bool ret = true;
uint16_t levels[] = {1, 2, 3, 4, 5};
int i;
+ uint32_t total_size;
+ uint32_t returned_size;
+ union samr_DispInfo info;
for (i=0;i<ARRAY_SIZE(levels);i++) {
printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
@@ -3714,6 +4521,9 @@ static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.start_idx = 0;
r.in.max_entries = 1000;
r.in.buf_size = (uint32_t)-1;
+ r.out.total_size = &total_size;
+ r.out.returned_size = &returned_size;
+ r.out.info = &info;
status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -3734,6 +4544,9 @@ static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context
bool ret = true;
uint16_t levels[] = {1, 2, 3, 4, 5};
int i;
+ uint32_t total_size;
+ uint32_t returned_size;
+ union samr_DispInfo info;
for (i=0;i<ARRAY_SIZE(levels);i++) {
torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
@@ -3743,6 +4556,9 @@ static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context
r.in.start_idx = 0;
r.in.max_entries = 1000;
r.in.buf_size = (uint32_t)-1;
+ r.out.total_size = &total_size;
+ r.out.returned_size = &returned_size;
+ r.out.info = &info;
status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -3762,6 +4578,9 @@ static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *me
NTSTATUS status;
struct samr_QueryDisplayInfo r;
bool ret = true;
+ uint32_t total_size;
+ uint32_t returned_size;
+ union samr_DispInfo info;
printf("Testing QueryDisplayInfo continuation\n");
@@ -3770,14 +4589,17 @@ static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *me
r.in.start_idx = 0;
r.in.max_entries = 1;
r.in.buf_size = (uint32_t)-1;
+ r.out.total_size = &total_size;
+ r.out.returned_size = &returned_size;
+ r.out.info = &info;
do {
status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
- if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
- if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
+ if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
+ if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
printf("expected idx %d but got %d\n",
r.in.start_idx + 1,
- r.out.info.info1.entries[0].idx);
+ r.out.info->info1.entries[0].idx);
break;
}
}
@@ -3791,7 +4613,7 @@ static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *me
r.in.start_idx++;
} while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
NT_STATUS_IS_OK(status)) &&
- r.out.returned_size != 0);
+ *r.out.returned_size != 0);
return ret;
}
@@ -3801,6 +4623,7 @@ static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *
{
NTSTATUS status;
struct samr_QueryDomainInfo r;
+ union samr_DomainInfo *info = NULL;
struct samr_SetDomainInfo s;
uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
@@ -3827,6 +4650,7 @@ static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *
r.in.domain_handle = handle;
r.in.level = levels[i];
+ r.out.info = &info;
status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -3838,40 +4662,40 @@ static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *
switch (levels[i]) {
case 2:
- if (strcmp(r.out.info->general.oem_information.string, domain_comment) != 0) {
+ if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
- levels[i], r.out.info->general.oem_information.string, domain_comment);
+ levels[i], info->general.oem_information.string, domain_comment);
ret = false;
}
- if (!r.out.info->general.primary.string) {
+ if (!info->general.primary.string) {
printf("QueryDomainInfo level %u returned no PDC name\n",
levels[i]);
ret = false;
- } else if (r.out.info->general.role == SAMR_ROLE_DOMAIN_PDC) {
- if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->general.primary.string) != 0) {
+ } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
+ if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
- levels[i], r.out.info->general.primary.string, dcerpc_server_name(p));
+ levels[i], info->general.primary.string, dcerpc_server_name(p));
}
}
break;
case 4:
- if (strcmp(r.out.info->oem.oem_information.string, domain_comment) != 0) {
+ if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
- levels[i], r.out.info->oem.oem_information.string, domain_comment);
+ levels[i], info->oem.oem_information.string, domain_comment);
ret = false;
}
break;
case 6:
- if (!r.out.info->info6.primary.string) {
+ if (!info->info6.primary.string) {
printf("QueryDomainInfo level %u returned no PDC name\n",
levels[i]);
ret = false;
}
break;
case 11:
- if (strcmp(r.out.info->general2.general.oem_information.string, domain_comment) != 0) {
+ if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
- levels[i], r.out.info->general2.general.oem_information.string, domain_comment);
+ levels[i], info->general2.general.oem_information.string, domain_comment);
ret = false;
}
break;
@@ -3881,7 +4705,7 @@ static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *
s.in.domain_handle = handle;
s.in.level = levels[i];
- s.in.info = r.out.info;
+ s.in.info = info;
status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
if (set_ok[i]) {
@@ -3918,6 +4742,7 @@ static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context
{
NTSTATUS status;
struct samr_QueryDomainInfo2 r;
+ union samr_DomainInfo *info = NULL;
uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
int i;
bool ret = true;
@@ -3927,6 +4752,7 @@ static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context
r.in.domain_handle = handle;
r.in.level = levels[i];
+ r.out.info = &info;
status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -3949,8 +4775,13 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
struct samr_QueryDisplayInfo q2;
NTSTATUS status;
uint32_t resume_handle=0;
+ struct samr_SamArray *sam = NULL;
+ uint32_t num_entries = 0;
int i;
bool ret = true;
+ uint32_t total_size;
+ uint32_t returned_size;
+ union samr_DispInfo info;
int num_names = 0;
const char **names = NULL;
@@ -3961,6 +4792,8 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
q1.in.resume_handle = &resume_handle;
q1.in.max_size = 5;
q1.out.resume_handle = &resume_handle;
+ q1.out.num_entries = &num_entries;
+ q1.out.sam = &sam;
status = STATUS_MORE_ENTRIES;
while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
@@ -3970,22 +4803,25 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
break;
- for (i=0; i<q1.out.num_entries; i++) {
+ for (i=0; i<*q1.out.num_entries; i++) {
add_string_to_array(tctx,
- q1.out.sam->entries[i].name.string,
+ sam->entries[i].name.string,
&names, &num_names);
}
}
torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
- torture_assert(tctx, q1.out.sam, "EnumDomainGroups failed to return q1.out.sam");
+ torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
q2.in.domain_handle = handle;
q2.in.level = 5;
q2.in.start_idx = 0;
q2.in.max_entries = 5;
q2.in.buf_size = (uint32_t)-1;
+ q2.out.total_size = &total_size;
+ q2.out.returned_size = &returned_size;
+ q2.out.info = &info;
status = STATUS_MORE_ENTRIES;
while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
@@ -3995,9 +4831,9 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
break;
- for (i=0; i<q2.out.info.info5.count; i++) {
+ for (i=0; i<q2.out.info->info5.count; i++) {
int j;
- const char *name = q2.out.info.info5.entries[i].account_name.string;
+ const char *name = q2.out.info->info5.entries[i].account_name.string;
bool found = false;
for (j=0; j<num_names; j++) {
if (names[j] == NULL)
@@ -4015,7 +4851,7 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
ret = false;
}
}
- q2.in.start_idx += q2.out.info.info5.count;
+ q2.in.start_idx += q2.out.info->info5.count;
}
if (!NT_STATUS_IS_OK(status)) {
@@ -4076,7 +4912,7 @@ static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
struct samr_RidToSid r;
NTSTATUS status;
bool ret = true;
- struct dom_sid *calc_sid;
+ struct dom_sid *calc_sid, *out_sid;
int rids[] = { 0, 42, 512, 10200 };
int i;
@@ -4086,6 +4922,7 @@ static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
calc_sid = dom_sid_dup(tctx, domain_sid);
r.in.domain_handle = domain_handle;
r.in.rid = rids[i];
+ r.out.sid = &out_sid;
status = dcerpc_samr_RidToSid(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -4094,9 +4931,9 @@ static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
} else {
calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
- if (!dom_sid_equal(calc_sid, r.out.sid)) {
+ if (!dom_sid_equal(calc_sid, out_sid)) {
printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
- dom_sid_string(tctx, r.out.sid),
+ dom_sid_string(tctx, out_sid),
dom_sid_string(tctx, calc_sid));
ret = false;
}
@@ -4112,10 +4949,12 @@ static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_con
struct samr_GetBootKeyInformation r;
NTSTATUS status;
bool ret = true;
+ uint32_t unknown = 0;
torture_comment(tctx, "Testing GetBootKeyInformation\n");
r.in.domain_handle = domain_handle;
+ r.out.unknown = &unknown;
status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -4134,6 +4973,7 @@ static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *t
struct samr_AddGroupMember r;
struct samr_DeleteGroupMember d;
struct samr_QueryGroupMember q;
+ struct samr_RidTypeArray *rids = NULL;
struct samr_SetMemberAttributesOfGroup s;
uint32_t rid;
@@ -4173,6 +5013,7 @@ static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *t
}
q.in.group_handle = group_handle;
+ q.out.rids = &rids;
status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
@@ -4312,6 +5153,7 @@ static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
switch (which_ops) {
case TORTURE_SAMR_USER_ATTRIBUTES:
case TORTURE_SAMR_PASSWORDS:
+ case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
/* This test needs 'complex' users to validate */
@@ -4388,6 +5230,7 @@ static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tct
{
NTSTATUS status;
struct samr_LookupDomain r;
+ struct dom_sid2 *sid = NULL;
struct lsa_String n1;
struct lsa_String n2;
bool ret = true;
@@ -4397,6 +5240,7 @@ static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tct
/* check for correct error codes */
r.in.connect_handle = handle;
r.in.domain_name = &n2;
+ r.out.sid = &sid;
n2.string = NULL;
status = dcerpc_samr_LookupDomain(p, tctx, &r);
@@ -4419,7 +5263,7 @@ static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tct
ret = false;
}
- if (!test_OpenDomain(p, tctx, handle, r.out.sid, which_ops)) {
+ if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops)) {
ret = false;
}
@@ -4433,6 +5277,8 @@ static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx
NTSTATUS status;
struct samr_EnumDomains r;
uint32_t resume_handle = 0;
+ uint32_t num_entries = 0;
+ struct samr_SamArray *sam = NULL;
int i;
bool ret = true;
@@ -4440,17 +5286,19 @@ static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx
r.in.resume_handle = &resume_handle;
r.in.buf_size = (uint32_t)-1;
r.out.resume_handle = &resume_handle;
+ r.out.num_entries = &num_entries;
+ r.out.sam = &sam;
status = dcerpc_samr_EnumDomains(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
- if (!r.out.sam) {
+ if (!*r.out.sam) {
return false;
}
- for (i=0;i<r.out.sam->count;i++) {
+ for (i=0;i<sam->count;i++) {
if (!test_LookupDomain(p, tctx, handle,
- r.out.sam->entries[i].name.string, which_ops)) {
+ sam->entries[i].name.string, which_ops)) {
ret = false;
}
}
@@ -4473,6 +5321,7 @@ static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
struct samr_Connect5 r5;
union samr_ConnectInfo info;
struct policy_handle h;
+ uint32_t level_out = 0;
bool ret = true, got_handle = false;
torture_comment(tctx, "testing samr_Connect\n");
@@ -4553,9 +5402,10 @@ static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
r5.in.system_name = "";
r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- r5.in.level = 1;
- r5.in.info = &info;
- r5.out.info = &info;
+ r5.in.level_in = 1;
+ r5.out.level_out = &level_out;
+ r5.in.info_in = &info;
+ r5.out.info_out = &info;
r5.out.connect_handle = &h;
status = dcerpc_samr_Connect5(p, tctx, &r5);
@@ -4651,3 +5501,25 @@ bool torture_rpc_samr_passwords(struct torture_context *torture)
return ret;
}
+bool torture_rpc_samr_passwords_pwdlastset(struct torture_context *torture)
+{
+ NTSTATUS status;
+ struct dcerpc_pipe *p;
+ bool ret = true;
+ struct policy_handle handle;
+
+ status = torture_rpc_connection(torture, &p, &ndr_table_samr);
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+
+ ret &= test_Connect(p, torture, &handle);
+
+ ret &= test_EnumDomains(p, torture, &handle,
+ TORTURE_SAMR_PASSWORDS_PWDLASTSET);
+
+ ret &= test_samr_handle_Close(p, torture, &handle);
+
+ return ret;
+}
+
diff --git a/source4/torture/rpc/samr_accessmask.c b/source4/torture/rpc/samr_accessmask.c
index bfff8c9267..9a8e442019 100644
--- a/source4/torture/rpc/samr_accessmask.c
+++ b/source4/torture/rpc/samr_accessmask.c
@@ -52,13 +52,15 @@ static NTSTATUS torture_samr_Connect5(struct torture_context *tctx,
NTSTATUS status;
struct samr_Connect5 r5;
union samr_ConnectInfo info;
+ uint32_t level_out = 0;
info.info1.client_version = 0;
info.info1.unknown2 = 0;
r5.in.system_name = "";
- r5.in.level = 1;
- r5.in.info = &info;
- r5.out.info = &info;
+ r5.in.level_in = 1;
+ r5.in.info_in = &info;
+ r5.out.info_out = &info;
+ r5.out.level_out = &level_out;
r5.out.connect_handle = h;
r5.in.access_mask = mask;
@@ -147,6 +149,8 @@ static bool test_samr_accessmask_EnumDomains(struct torture_context *tctx,
int i;
uint32_t mask;
uint32_t resume_handle = 0;
+ struct samr_SamArray *sam = NULL;
+ uint32_t num_entries = 0;
printf("testing which bits in Connect5 accessmask allows us to EnumDomains\n");
mask = 1;
@@ -170,6 +174,8 @@ static bool test_samr_accessmask_EnumDomains(struct torture_context *tctx,
ed.in.resume_handle = &resume_handle;
ed.in.buf_size = (uint32_t)-1;
ed.out.resume_handle = &resume_handle;
+ ed.out.num_entries = &num_entries;
+ ed.out.sam = &sam;
status = dcerpc_samr_EnumDomains(p, tctx, &ed);
if (!NT_STATUS_IS_OK(status)) {
@@ -195,6 +201,8 @@ static bool test_samr_accessmask_EnumDomains(struct torture_context *tctx,
ed.in.resume_handle = &resume_handle;
ed.in.buf_size = (uint32_t)-1;
ed.out.resume_handle = &resume_handle;
+ ed.out.num_entries = &num_entries;
+ ed.out.sam = &sam;
status = dcerpc_samr_EnumDomains(p, tctx, &ed);
if(!NT_STATUS_EQUAL(NT_STATUS_ACCESS_DENIED, status)) {
@@ -236,7 +244,7 @@ static bool test_samr_connect_user_acl(struct torture_context *tctx,
struct samr_SetSecurity ss;
struct security_ace ace;
struct security_descriptor *sd;
- struct sec_desc_buf sdb;
+ struct sec_desc_buf sdb, *sdbuf = NULL;
bool ret = true;
int sd_size;
struct dcerpc_pipe *test_p;
@@ -255,6 +263,7 @@ static bool test_samr_connect_user_acl(struct torture_context *tctx,
/* get the current ACL for the SAMR policy handle */
qs.in.handle = &ch;
qs.in.sec_info = SECINFO_DACL;
+ qs.out.sdbuf = &sdbuf;
status = dcerpc_samr_QuerySecurity(p, tctx, &qs);
if (!NT_STATUS_IS_OK(status)) {
printf("QuerySecurity failed - %s\n", nt_errstr(status));
@@ -262,13 +271,13 @@ static bool test_samr_connect_user_acl(struct torture_context *tctx,
}
/* how big is the security descriptor? */
- sd_size = qs.out.sdbuf->sd_size;
+ sd_size = sdbuf->sd_size;
/* add an ACE to the security descriptor to deny the user the
* 'connect to server' right
*/
- sd = qs.out.sdbuf->sd;
+ sd = sdbuf->sd;
ace.type = SEC_ACE_TYPE_ACCESS_DENIED;
ace.flags = 0;
ace.access_mask = SAMR_ACCESS_CONNECT_TO_SERVER;
@@ -314,7 +323,7 @@ static bool test_samr_connect_user_acl(struct torture_context *tctx,
printf("QuerySecurity failed - %s\n", nt_errstr(status));
ret = false;
}
- if (sd_size != qs.out.sdbuf->sd_size) {
+ if (sd_size != sdbuf->sd_size) {
printf("security descriptor changed\n");
ret = false;
}
@@ -387,6 +396,7 @@ static bool test_samr_accessmask_LookupDomain(struct torture_context *tctx,
{
NTSTATUS status;
struct samr_LookupDomain ld;
+ struct dom_sid2 *sid = NULL;
struct policy_handle ch;
struct lsa_String dn;
int i;
@@ -412,6 +422,7 @@ static bool test_samr_accessmask_LookupDomain(struct torture_context *tctx,
ld.in.connect_handle = &ch;
ld.in.domain_name = &dn;
+ ld.out.sid = &sid;
dn.string = lp_workgroup(tctx->lp_ctx);
status = dcerpc_samr_LookupDomain(p, tctx, &ld);
@@ -471,6 +482,7 @@ static bool test_samr_accessmask_OpenDomain(struct torture_context *tctx,
{
NTSTATUS status;
struct samr_LookupDomain ld;
+ struct dom_sid2 *sid = NULL;
struct samr_OpenDomain od;
struct policy_handle ch;
struct policy_handle dh;
@@ -488,6 +500,7 @@ static bool test_samr_accessmask_OpenDomain(struct torture_context *tctx,
ld.in.connect_handle = &ch;
ld.in.domain_name = &dn;
+ ld.out.sid = &sid;
dn.string = lp_workgroup(tctx->lp_ctx);
status = dcerpc_samr_LookupDomain(p, tctx, &ld);
if (!NT_STATUS_IS_OK(status)) {
@@ -517,7 +530,7 @@ static bool test_samr_accessmask_OpenDomain(struct torture_context *tctx,
od.in.connect_handle = &ch;
od.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- od.in.sid = ld.out.sid;
+ od.in.sid = *ld.out.sid;
od.out.domain_handle = &dh;
status = dcerpc_samr_OpenDomain(p, tctx, &od);
diff --git a/source4/torture/rpc/samsync.c b/source4/torture/rpc/samsync.c
index 12ddc934c9..a3fc6f740f 100644
--- a/source4/torture/rpc/samsync.c
+++ b/source4/torture/rpc/samsync.c
@@ -151,17 +151,19 @@ struct samsync_trusted_domain {
static struct policy_handle *samsync_open_domain(TALLOC_CTX *mem_ctx,
struct samsync_state *samsync_state,
const char *domain,
- struct dom_sid **sid)
+ struct dom_sid **sid_p)
{
struct lsa_String name;
struct samr_OpenDomain o;
struct samr_LookupDomain l;
+ struct dom_sid2 *sid = NULL;
struct policy_handle *domain_handle = talloc(mem_ctx, struct policy_handle);
NTSTATUS nt_status;
name.string = domain;
l.in.connect_handle = samsync_state->connect_handle;
l.in.domain_name = &name;
+ l.out.sid = &sid;
nt_status = dcerpc_samr_LookupDomain(samsync_state->p_samr, mem_ctx, &l);
if (!NT_STATUS_IS_OK(nt_status)) {
@@ -171,11 +173,11 @@ static struct policy_handle *samsync_open_domain(TALLOC_CTX *mem_ctx,
o.in.connect_handle = samsync_state->connect_handle;
o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- o.in.sid = l.out.sid;
+ o.in.sid = *l.out.sid;
o.out.domain_handle = domain_handle;
if (sid) {
- *sid = l.out.sid;
+ *sid_p = *l.out.sid;
}
nt_status = dcerpc_samr_OpenDomain(samsync_state->p_samr, mem_ctx, &o);
@@ -192,10 +194,12 @@ static struct sec_desc_buf *samsync_query_samr_sec_desc(TALLOC_CTX *mem_ctx,
struct policy_handle *handle)
{
struct samr_QuerySecurity r;
+ struct sec_desc_buf *sdbuf = NULL;
NTSTATUS status;
r.in.handle = handle;
r.in.sec_info = 0x7;
+ r.out.sdbuf = &sdbuf;
status = dcerpc_samr_QuerySecurity(samsync_state->p_samr, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -203,7 +207,7 @@ static struct sec_desc_buf *samsync_query_samr_sec_desc(TALLOC_CTX *mem_ctx,
return NULL;
}
- return r.out.sdbuf;
+ return sdbuf;
}
static struct sec_desc_buf *samsync_query_lsa_sec_desc(TALLOC_CTX *mem_ctx,
@@ -260,6 +264,15 @@ static struct sec_desc_buf *samsync_query_lsa_sec_desc(TALLOC_CTX *mem_ctx,
} \
} while (0)
+#define TEST_BINARY_STRING_EQUAL(s1, s2) do {\
+ if (!((!s1.array || s1.array[0]=='\0') && (!s2.array || s2.array[0]=='\0')) \
+ && memcmp(s1.array, s2.array, s1.length * 2) != 0) {\
+ printf("%s: string mismatch: " #s1 ":%s != " #s2 ": %s\n", \
+ __location__, (const char *)s1.array, (const char *)s2.array);\
+ ret = false;\
+ } \
+} while (0)
+
#define TEST_SID_EQUAL(s1, s2) do {\
if (!dom_sid_equal(s1, s2)) {\
printf("%s: dom_sid mismatch: " #s1 ":%s != " #s2 ": %s\n", \
@@ -294,6 +307,7 @@ static bool samsync_handle_domain(TALLOC_CTX *mem_ctx, struct samsync_state *sam
struct netr_DELTA_DOMAIN *domain = delta->delta_union.domain;
struct dom_sid *dom_sid;
struct samr_QueryDomainInfo q[14]; /* q[0] will be unused simple for clarity */
+ union samr_DomainInfo *info[14];
uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
NTSTATUS nt_status;
int i;
@@ -341,8 +355,10 @@ static bool samsync_handle_domain(TALLOC_CTX *mem_ctx, struct samsync_state *sam
(long long)samsync_state->seq_num[database_id]);
for (i=0;i<ARRAY_SIZE(levels);i++) {
+
q[levels[i]].in.domain_handle = samsync_state->domain_handle[database_id];
q[levels[i]].in.level = levels[i];
+ q[levels[i]].out.info = &info[levels[i]];
nt_status = dcerpc_samr_QueryDomainInfo(samsync_state->p_samr, mem_ctx, &q[levels[i]]);
@@ -353,23 +369,23 @@ static bool samsync_handle_domain(TALLOC_CTX *mem_ctx, struct samsync_state *sam
}
}
- TEST_STRING_EQUAL(q[5].out.info->info5.domain_name, domain->domain_name);
+ TEST_STRING_EQUAL(info[5]->info5.domain_name, domain->domain_name);
- TEST_STRING_EQUAL(q[2].out.info->general.oem_information, domain->oem_information);
- TEST_STRING_EQUAL(q[4].out.info->oem.oem_information, domain->oem_information);
- TEST_TIME_EQUAL(q[2].out.info->general.force_logoff_time, domain->force_logoff_time);
- TEST_TIME_EQUAL(q[3].out.info->info3.force_logoff_time, domain->force_logoff_time);
+ TEST_STRING_EQUAL(info[2]->general.oem_information, domain->oem_information);
+ TEST_STRING_EQUAL(info[4]->oem.oem_information, domain->oem_information);
+ TEST_TIME_EQUAL(info[2]->general.force_logoff_time, domain->force_logoff_time);
+ TEST_TIME_EQUAL(info[3]->info3.force_logoff_time, domain->force_logoff_time);
- TEST_TIME_EQUAL(q[1].out.info->info1.min_password_length, domain->min_password_length);
- TEST_TIME_EQUAL(q[1].out.info->info1.password_history_length, domain->password_history_length);
- TEST_TIME_EQUAL(q[1].out.info->info1.max_password_age, domain->max_password_age);
- TEST_TIME_EQUAL(q[1].out.info->info1.min_password_age, domain->min_password_age);
+ TEST_TIME_EQUAL(info[1]->info1.min_password_length, domain->min_password_length);
+ TEST_TIME_EQUAL(info[1]->info1.password_history_length, domain->password_history_length);
+ TEST_TIME_EQUAL(info[1]->info1.max_password_age, domain->max_password_age);
+ TEST_TIME_EQUAL(info[1]->info1.min_password_age, domain->min_password_age);
- TEST_UINT64_EQUAL(q[8].out.info->info8.sequence_num,
+ TEST_UINT64_EQUAL(info[8]->info8.sequence_num,
domain->sequence_num);
- TEST_TIME_EQUAL(q[8].out.info->info8.domain_create_time,
+ TEST_TIME_EQUAL(info[8]->info8.domain_create_time,
domain->domain_create_time);
- TEST_TIME_EQUAL(q[13].out.info->info13.domain_create_time,
+ TEST_TIME_EQUAL(info[13]->info13.domain_create_time,
domain->domain_create_time);
TEST_SEC_DESC_EQUAL(domain->sdbuf, samr, samsync_state->domain_handle[database_id]);
@@ -425,9 +441,12 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct
struct samr_OpenUser r;
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
struct policy_handle user_handle;
struct samr_GetGroupsForUser getgroups;
+ struct samr_RidWithAttributeArray *rids;
+
if (!samsync_state->domain_name || !samsync_state->domain_handle[database_id]) {
printf("SamSync needs domain information before the users\n");
return false;
@@ -446,6 +465,7 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct
q.in.user_handle = &user_handle;
q.in.level = 21;
+ q.out.info = &info;
TEST_SEC_DESC_EQUAL(user->sdbuf, samr, &user_handle);
@@ -457,6 +477,7 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct
}
getgroups.in.user_handle = &user_handle;
+ getgroups.out.rids = &rids;
nt_status = dcerpc_samr_GetGroupsForUser(samsync_state->p_samr, mem_ctx, &getgroups);
if (!NT_STATUS_IS_OK(nt_status)) {
@@ -480,67 +501,67 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct
return false;
}
- TEST_STRING_EQUAL(q.out.info->info21.account_name, user->account_name);
- TEST_STRING_EQUAL(q.out.info->info21.full_name, user->full_name);
- TEST_INT_EQUAL(q.out.info->info21.rid, user->rid);
- TEST_INT_EQUAL(q.out.info->info21.primary_gid, user->primary_gid);
- TEST_STRING_EQUAL(q.out.info->info21.home_directory, user->home_directory);
- TEST_STRING_EQUAL(q.out.info->info21.home_drive, user->home_drive);
- TEST_STRING_EQUAL(q.out.info->info21.logon_script, user->logon_script);
- TEST_STRING_EQUAL(q.out.info->info21.description, user->description);
- TEST_STRING_EQUAL(q.out.info->info21.workstations, user->workstations);
+ TEST_STRING_EQUAL(info->info21.account_name, user->account_name);
+ TEST_STRING_EQUAL(info->info21.full_name, user->full_name);
+ TEST_INT_EQUAL(info->info21.rid, user->rid);
+ TEST_INT_EQUAL(info->info21.primary_gid, user->primary_gid);
+ TEST_STRING_EQUAL(info->info21.home_directory, user->home_directory);
+ TEST_STRING_EQUAL(info->info21.home_drive, user->home_drive);
+ TEST_STRING_EQUAL(info->info21.logon_script, user->logon_script);
+ TEST_STRING_EQUAL(info->info21.description, user->description);
+ TEST_STRING_EQUAL(info->info21.workstations, user->workstations);
- TEST_TIME_EQUAL(q.out.info->info21.last_logon, user->last_logon);
- TEST_TIME_EQUAL(q.out.info->info21.last_logoff, user->last_logoff);
+ TEST_TIME_EQUAL(info->info21.last_logon, user->last_logon);
+ TEST_TIME_EQUAL(info->info21.last_logoff, user->last_logoff);
- TEST_INT_EQUAL(q.out.info->info21.logon_hours.units_per_week,
+ TEST_INT_EQUAL(info->info21.logon_hours.units_per_week,
user->logon_hours.units_per_week);
if (ret) {
- if (memcmp(q.out.info->info21.logon_hours.bits, user->logon_hours.bits,
- q.out.info->info21.logon_hours.units_per_week/8) != 0) {
+ if (memcmp(info->info21.logon_hours.bits, user->logon_hours.bits,
+ info->info21.logon_hours.units_per_week/8) != 0) {
printf("Logon hours mismatch\n");
ret = false;
}
}
- TEST_INT_EQUAL(q.out.info->info21.bad_password_count,
+ TEST_INT_EQUAL(info->info21.bad_password_count,
user->bad_password_count);
- TEST_INT_EQUAL(q.out.info->info21.logon_count,
+ TEST_INT_EQUAL(info->info21.logon_count,
user->logon_count);
- TEST_TIME_EQUAL(q.out.info->info21.last_password_change,
+ TEST_TIME_EQUAL(info->info21.last_password_change,
user->last_password_change);
- TEST_TIME_EQUAL(q.out.info->info21.acct_expiry,
+ TEST_TIME_EQUAL(info->info21.acct_expiry,
user->acct_expiry);
- TEST_INT_EQUAL((q.out.info->info21.acct_flags & ~ACB_PW_EXPIRED), user->acct_flags);
+ TEST_INT_EQUAL((info->info21.acct_flags & ~ACB_PW_EXPIRED), user->acct_flags);
if (user->acct_flags & ACB_PWNOEXP) {
- if (q.out.info->info21.acct_flags & ACB_PW_EXPIRED) {
+ if (info->info21.acct_flags & ACB_PW_EXPIRED) {
printf("ACB flags mismatch: both expired and no expiry!\n");
ret = false;
}
- if (q.out.info->info21.force_password_change != (NTTIME)0x7FFFFFFFFFFFFFFFULL) {
+ if (info->info21.force_password_change != (NTTIME)0x7FFFFFFFFFFFFFFFULL) {
printf("ACB flags mismatch: no password expiry, but force password change 0x%016llx (%lld) != 0x%016llx (%lld)\n",
- (unsigned long long)q.out.info->info21.force_password_change,
- (unsigned long long)q.out.info->info21.force_password_change,
+ (unsigned long long)info->info21.force_password_change,
+ (unsigned long long)info->info21.force_password_change,
(unsigned long long)0x7FFFFFFFFFFFFFFFULL, (unsigned long long)0x7FFFFFFFFFFFFFFFULL
);
ret = false;
}
}
- TEST_INT_EQUAL(q.out.info->info21.nt_password_set, user->nt_password_present);
- TEST_INT_EQUAL(q.out.info->info21.lm_password_set, user->lm_password_present);
- TEST_INT_EQUAL(q.out.info->info21.password_expired, user->password_expired);
+ TEST_INT_EQUAL(info->info21.nt_password_set, user->nt_password_present);
+ TEST_INT_EQUAL(info->info21.lm_password_set, user->lm_password_present);
+ TEST_INT_EQUAL(info->info21.password_expired, user->password_expired);
- TEST_STRING_EQUAL(q.out.info->info21.comment, user->comment);
- TEST_STRING_EQUAL(q.out.info->info21.parameters, user->parameters);
+ TEST_STRING_EQUAL(info->info21.comment, user->comment);
+ TEST_BINARY_STRING_EQUAL(info->info21.parameters, user->parameters);
- TEST_INT_EQUAL(q.out.info->info21.country_code, user->country_code);
- TEST_INT_EQUAL(q.out.info->info21.code_page, user->code_page);
+ TEST_INT_EQUAL(info->info21.country_code, user->country_code);
+ TEST_INT_EQUAL(info->info21.code_page, user->code_page);
- TEST_STRING_EQUAL(q.out.info->info21.profile_path, user->profile_path);
+ TEST_STRING_EQUAL(info->info21.profile_path, user->profile_path);
if (user->lm_password_present) {
sam_rid_crypt(rid, user->lmpassword.hash, lm_hash.hash, 0);
@@ -619,7 +640,7 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct
return true;
}
} else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_PASSWORD_EXPIRED)) {
- if (q.out.info->info21.acct_flags & ACB_PW_EXPIRED) {
+ if (info->info21.acct_flags & ACB_PW_EXPIRED) {
return true;
}
} else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD)) {
@@ -654,7 +675,7 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct
TEST_TIME_EQUAL(user->last_logon, info3->base.last_logon);
TEST_TIME_EQUAL(user->acct_expiry, info3->base.acct_expiry);
TEST_TIME_EQUAL(user->last_password_change, info3->base.last_password_change);
- TEST_TIME_EQUAL(q.out.info->info21.force_password_change, info3->base.force_password_change);
+ TEST_TIME_EQUAL(info->info21.force_password_change, info3->base.force_password_change);
/* Does the concept of a logoff time ever really
* exist? (not in any sensible way, according to the
@@ -667,28 +688,28 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct
TEST_TIME_EQUAL(user->last_logoff, info3->base.last_logoff);
}
- TEST_INT_EQUAL(getgroups.out.rids->count, info3->base.groups.count);
- if (getgroups.out.rids->count == info3->base.groups.count) {
+ TEST_INT_EQUAL(rids->count, info3->base.groups.count);
+ if (rids->count == info3->base.groups.count) {
int i, j;
- int count = getgroups.out.rids->count;
- bool *matched = talloc_zero_array(mem_ctx, bool, getgroups.out.rids->count);
+ int count = rids->count;
+ bool *matched = talloc_zero_array(mem_ctx, bool, rids->count);
for (i = 0; i < count; i++) {
for (j = 0; j < count; j++) {
- if ((getgroups.out.rids->rids[i].rid ==
+ if ((rids->rids[i].rid ==
info3->base.groups.rids[j].rid)
- && (getgroups.out.rids->rids[i].attributes ==
+ && (rids->rids[i].attributes ==
info3->base.groups.rids[j].attributes)) {
matched[i] = true;
}
}
}
- for (i = 0; i < getgroups.out.rids->count; i++) {
+ for (i = 0; i < rids->count; i++) {
if (matched[i] == false) {
ret = false;
printf("Could not find group RID %u found in getgroups in NETLOGON reply\n",
- getgroups.out.rids->rids[i].rid);
+ rids->rids[i].rid);
}
}
}
@@ -711,6 +732,7 @@ static bool samsync_handle_alias(TALLOC_CTX *mem_ctx, struct samsync_state *sams
struct samr_OpenAlias r;
struct samr_QueryAliasInfo q;
+ union samr_AliasInfo *info;
struct policy_handle alias_handle;
if (!samsync_state->domain_name || !samsync_state->domain_handle[database_id]) {
@@ -731,6 +753,7 @@ static bool samsync_handle_alias(TALLOC_CTX *mem_ctx, struct samsync_state *sams
q.in.alias_handle = &alias_handle;
q.in.level = 1;
+ q.out.info = &info;
TEST_SEC_DESC_EQUAL(alias->sdbuf, samr, &alias_handle);
@@ -745,8 +768,8 @@ static bool samsync_handle_alias(TALLOC_CTX *mem_ctx, struct samsync_state *sams
return false;
}
- TEST_STRING_EQUAL(q.out.info->all.name, alias->alias_name);
- TEST_STRING_EQUAL(q.out.info->all.description, alias->description);
+ TEST_STRING_EQUAL(info->all.name, alias->alias_name);
+ TEST_STRING_EQUAL(info->all.description, alias->description);
return ret;
}
@@ -760,6 +783,7 @@ static bool samsync_handle_group(TALLOC_CTX *mem_ctx, struct samsync_state *sams
struct samr_OpenGroup r;
struct samr_QueryGroupInfo q;
+ union samr_GroupInfo *info;
struct policy_handle group_handle;
if (!samsync_state->domain_name || !samsync_state->domain_handle[database_id]) {
@@ -780,6 +804,7 @@ static bool samsync_handle_group(TALLOC_CTX *mem_ctx, struct samsync_state *sams
q.in.group_handle = &group_handle;
q.in.level = 1;
+ q.out.info = &info;
TEST_SEC_DESC_EQUAL(group->sdbuf, samr, &group_handle);
@@ -794,9 +819,9 @@ static bool samsync_handle_group(TALLOC_CTX *mem_ctx, struct samsync_state *sams
return false;
}
- TEST_STRING_EQUAL(q.out.info->all.name, group->group_name);
- TEST_INT_EQUAL(q.out.info->all.attributes, group->attributes);
- TEST_STRING_EQUAL(q.out.info->all.description, group->description);
+ TEST_STRING_EQUAL(info->all.name, group->group_name);
+ TEST_INT_EQUAL(info->all.attributes, group->attributes);
+ TEST_STRING_EQUAL(info->all.description, group->description);
return ret;
}
diff --git a/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c
index ca1655729b..451990a71b 100644
--- a/source4/torture/rpc/schannel.c
+++ b/source4/torture/rpc/schannel.c
@@ -128,6 +128,7 @@ static bool test_samr_ops(struct torture_context *tctx,
{
NTSTATUS status;
struct samr_GetDomPwInfo r;
+ struct samr_PwInfo info;
struct samr_Connect connect;
struct samr_OpenDomain opendom;
int i;
@@ -137,6 +138,7 @@ static bool test_samr_ops(struct torture_context *tctx,
name.string = lp_workgroup(tctx->lp_ctx);
r.in.domain_name = &name;
+ r.out.info = &info;
connect.in.system_name = 0;
connect.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
diff --git a/source4/torture/rpc/svcctl.c b/source4/torture/rpc/svcctl.c
index c9006baaf5..8d8f43a0cf 100644
--- a/source4/torture/rpc/svcctl.c
+++ b/source4/torture/rpc/svcctl.c
@@ -1,19 +1,19 @@
-/*
+/*
Unix SMB/CIFS implementation.
test suite for srvsvc rpc operations
Copyright (C) Jelmer Vernooij 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/>.
*/
@@ -26,28 +26,141 @@
static bool test_OpenSCManager(struct dcerpc_pipe *p, struct torture_context *tctx, struct policy_handle *h)
{
struct svcctl_OpenSCManagerW r;
-
+
r.in.MachineName = NULL;
r.in.DatabaseName = NULL;
r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
r.out.handle = h;
-
- torture_assert_ntstatus_ok(tctx,
- dcerpc_svcctl_OpenSCManagerW(p, tctx, &r),
- "OpenSCManager failed!");
-
+
+ torture_assert_ntstatus_ok(tctx,
+ dcerpc_svcctl_OpenSCManagerW(p, tctx, &r),
+ "OpenSCManager failed!");
+
return true;
}
static bool test_CloseServiceHandle(struct dcerpc_pipe *p, struct torture_context *tctx, struct policy_handle *h)
{
- struct svcctl_CloseServiceHandle r;
+ struct svcctl_CloseServiceHandle r;
r.in.handle = h;
r.out.handle = h;
- torture_assert_ntstatus_ok(tctx,
- dcerpc_svcctl_CloseServiceHandle(p, tctx, &r),
- "CloseServiceHandle failed");
+ torture_assert_ntstatus_ok(tctx,
+ dcerpc_svcctl_CloseServiceHandle(p, tctx, &r),
+ "CloseServiceHandle failed");
+
+ return true;
+}
+
+static bool test_OpenService(struct dcerpc_pipe *p, struct torture_context *tctx,
+ struct policy_handle *h, const char *name, struct policy_handle *s)
+{
+ struct svcctl_OpenServiceW r;
+
+ r.in.scmanager_handle = h;
+ r.in.ServiceName = name;
+ r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+ r.out.handle = s;
+
+ torture_assert_ntstatus_ok(tctx,
+ dcerpc_svcctl_OpenServiceW(p, tctx, &r),
+ "OpenServiceW failed!");
+ torture_assert_werr_ok(tctx, r.out.result, "OpenServiceW failed!");
+
+ return true;
+
+}
+
+static bool test_QueryServiceStatusEx(struct torture_context *tctx, struct dcerpc_pipe *p)
+{
+ struct svcctl_QueryServiceStatusEx r;
+ struct policy_handle h, s;
+ NTSTATUS status;
+
+ uint32_t info_level = 0;
+ uint8_t *buffer;
+ uint32_t buf_size = 0;
+ uint32_t bytes_needed = 0;
+
+ if (!test_OpenSCManager(p, tctx, &h))
+ return false;
+
+ if (!test_OpenService(p, tctx, &h, "Netlogon", &s))
+ return false;
+
+ buffer = talloc(tctx, uint8_t);
+
+ r.in.handle = &s;
+ r.in.info_level = info_level;
+ r.in.buf_size = buf_size;
+ r.out.buffer = buffer;
+ r.out.bytes_needed = &bytes_needed;
+
+ status = dcerpc_svcctl_QueryServiceStatusEx(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "QueryServiceStatusEx failed!");
+
+ if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+ r.in.buf_size = bytes_needed;
+ buffer = talloc_array(tctx, uint8_t, bytes_needed);
+ r.out.buffer = buffer;
+
+ status = dcerpc_svcctl_QueryServiceStatusEx(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "QueryServiceStatusEx failed!");
+ torture_assert_werr_ok(tctx, r.out.result, "QueryServiceStatusEx failed!");
+ }
+
+ if (!test_CloseServiceHandle(p, tctx, &s))
+ return false;
+
+ if (!test_CloseServiceHandle(p, tctx, &h))
+ return false;
+
+ return true;
+}
+
+static bool test_QueryServiceConfig2W(struct torture_context *tctx, struct dcerpc_pipe *p)
+{
+ struct svcctl_QueryServiceConfig2W r;
+ struct policy_handle h, s;
+ NTSTATUS status;
+
+ uint32_t info_level = 1;
+ uint8_t *buffer;
+ uint32_t buf_size = 0;
+ uint32_t bytes_needed = 0;
+
+ if (!test_OpenSCManager(p, tctx, &h))
+ return false;
+
+ if (!test_OpenService(p, tctx, &h, "Netlogon", &s))
+ return false;
+
+ buffer = talloc(tctx, uint8_t);
+
+ r.in.handle = &s;
+ r.in.info_level = info_level;
+ r.in.buf_size = buf_size;
+ r.out.buffer = buffer;
+ r.out.bytes_needed = &bytes_needed;
+
+ status = dcerpc_svcctl_QueryServiceConfig2W(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfig2W failed!");
+
+ if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+ r.in.buf_size = bytes_needed;
+ buffer = talloc_array(tctx, uint8_t, bytes_needed);
+ r.out.buffer = buffer;
+
+ status = dcerpc_svcctl_QueryServiceConfig2W(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfig2W failed!");
+ torture_assert_werr_ok(tctx, r.out.result, "QueryServiceConfig2W failed!");
+ }
+
+ if (!test_CloseServiceHandle(p, tctx, &s))
+ return false;
+
+ if (!test_CloseServiceHandle(p, tctx, &h))
+ return false;
return true;
}
@@ -59,7 +172,9 @@ static bool test_EnumServicesStatus(struct torture_context *tctx, struct dcerpc_
int i;
NTSTATUS status;
uint32_t resume_handle = 0;
- struct ENUM_SERVICE_STATUS *service = NULL;
+ struct ENUM_SERVICE_STATUS *service = NULL;
+ uint32_t bytes_needed = 0;
+ uint32_t services_returned = 0;
if (!test_OpenSCManager(p, tctx, &h))
return false;
@@ -71,17 +186,17 @@ static bool test_EnumServicesStatus(struct torture_context *tctx, struct dcerpc_
r.in.resume_handle = &resume_handle;
r.out.service = NULL;
r.out.resume_handle = &resume_handle;
- r.out.services_returned = 0;
- r.out.bytes_needed = 0;
+ r.out.services_returned = &services_returned;
+ r.out.bytes_needed = &bytes_needed;
status = dcerpc_svcctl_EnumServicesStatusW(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status, "EnumServicesStatus failed!");
if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
- r.in.buf_size = *r.out.bytes_needed;
- r.out.service = talloc_array(tctx, uint8_t, *r.out.bytes_needed);
-
+ r.in.buf_size = bytes_needed;
+ r.out.service = talloc_array(tctx, uint8_t, bytes_needed);
+
status = dcerpc_svcctl_EnumServicesStatusW(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status, "EnumServicesStatus failed!");
@@ -90,17 +205,17 @@ static bool test_EnumServicesStatus(struct torture_context *tctx, struct dcerpc_
service = (struct ENUM_SERVICE_STATUS *)r.out.service;
}
- for(i = 0; i < *r.out.services_returned; i++) {
+ for(i = 0; i < services_returned; i++) {
printf("Type: %d, State: %d\n", service[i].status.type, service[i].status.state);
}
-
+
if (!test_CloseServiceHandle(p, tctx, &h))
return false;
return true;
}
-static bool test_SCManager(struct torture_context *tctx,
+static bool test_SCManager(struct torture_context *tctx,
struct dcerpc_pipe *p)
{
struct policy_handle h;
@@ -119,13 +234,16 @@ struct torture_suite *torture_rpc_svcctl(TALLOC_CTX *mem_ctx)
struct torture_suite *suite = torture_suite_create(mem_ctx, "SVCCTL");
struct torture_rpc_tcase *tcase;
- tcase = torture_suite_add_rpc_iface_tcase(suite, "svcctl",
- &ndr_table_svcctl);
-
- torture_rpc_tcase_add_test(tcase, "SCManager",
- test_SCManager);
- torture_rpc_tcase_add_test(tcase, "EnumServicesStatus",
- test_EnumServicesStatus);
+ tcase = torture_suite_add_rpc_iface_tcase(suite, "svcctl", &ndr_table_svcctl);
+
+ torture_rpc_tcase_add_test(tcase, "SCManager",
+ test_SCManager);
+ torture_rpc_tcase_add_test(tcase, "EnumServicesStatus",
+ test_EnumServicesStatus);
+ torture_rpc_tcase_add_test(tcase, "QueryServiceStatusEx",
+ test_QueryServiceStatusEx);
+ torture_rpc_tcase_add_test(tcase, "QueryServiceConfig2W",
+ test_QueryServiceConfig2W);
return suite;
}
diff --git a/source4/torture/rpc/testjoin.c b/source4/torture/rpc/testjoin.c
index 3408a1924c..c93358015c 100644
--- a/source4/torture/rpc/testjoin.c
+++ b/source4/torture/rpc/testjoin.c
@@ -59,6 +59,7 @@ static NTSTATUS DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle user_handle;
uint32_t rid;
struct samr_LookupNames n;
+ struct samr_Ids rids, types;
struct lsa_String sname;
struct samr_OpenUser r;
@@ -67,10 +68,12 @@ static NTSTATUS DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
n.in.domain_handle = handle;
n.in.num_names = 1;
n.in.names = &sname;
+ n.out.rids = &rids;
+ n.out.types = &types;
status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
if (NT_STATUS_IS_OK(status)) {
- rid = n.out.rids.ids[0];
+ rid = n.out.rids->ids[0];
} else {
return status;
}
@@ -113,7 +116,9 @@ struct test_join *torture_create_testuser(struct torture_context *torture,
struct samr_CreateUser2 r;
struct samr_OpenDomain o;
struct samr_LookupDomain l;
+ struct dom_sid2 *sid = NULL;
struct samr_GetUserPwInfo pwp;
+ struct samr_PwInfo info;
struct samr_SetUserInfo s;
union samr_UserInfo u;
struct policy_handle handle;
@@ -172,6 +177,7 @@ struct test_join *torture_create_testuser(struct torture_context *torture,
name.string = domain;
l.in.connect_handle = &handle;
l.in.domain_name = &name;
+ l.out.sid = &sid;
status = dcerpc_samr_LookupDomain(join->p, join, &l);
if (!NT_STATUS_IS_OK(status)) {
@@ -179,14 +185,14 @@ struct test_join *torture_create_testuser(struct torture_context *torture,
goto failed;
}
- talloc_steal(join, l.out.sid);
- join->dom_sid = l.out.sid;
+ talloc_steal(join, *l.out.sid);
+ join->dom_sid = *l.out.sid;
join->dom_netbios_name = talloc_strdup(join, domain);
if (!join->dom_netbios_name) goto failed;
o.in.connect_handle = &handle;
o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- o.in.sid = l.out.sid;
+ o.in.sid = *l.out.sid;
o.out.domain_handle = &domain_handle;
status = dcerpc_samr_OpenDomain(join->p, join, &o);
@@ -224,10 +230,11 @@ again:
join->user_sid = dom_sid_add_rid(join, join->dom_sid, rid);
pwp.in.user_handle = &join->user_handle;
+ pwp.out.info = &info;
status = dcerpc_samr_GetUserPwInfo(join->p, join, &pwp);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = pwp.out.info.min_password_length;
+ policy_min_pw_len = pwp.out.info->min_password_length;
}
random_pw = generate_random_str(join, MAX(8, policy_min_pw_len));
@@ -240,7 +247,7 @@ again:
s.in.level = 24;
encode_pw_buffer(u.info24.password.data, random_pw, STR_UNICODE);
- u.info24.pw_len = strlen(random_pw);
+ u.info24.password_expired = 0;
status = dcerpc_fetch_session_key(join->p, &session_key);
if (!NT_STATUS_IS_OK(status)) {
diff --git a/source4/torture/smb2/config.mk b/source4/torture/smb2/config.mk
index 9785303629..3a1ac5e06c 100644
--- a/source4/torture/smb2/config.mk
+++ b/source4/torture/smb2/config.mk
@@ -5,7 +5,7 @@
SUBSYSTEM = smbtorture
INIT_FUNCTION = torture_smb2_init
PRIVATE_DEPENDENCIES = \
- LIBCLI_SMB2 POPT_CREDENTIALS
+ LIBCLI_SMB2 POPT_CREDENTIALS torture
# End SUBSYSTEM TORTURE_SMB2
#################################
diff --git a/source4/torture/smbtorture.h b/source4/torture/smbtorture.h
index 3b5a573d83..c1363fd4c1 100644
--- a/source4/torture/smbtorture.h
+++ b/source4/torture/smbtorture.h
@@ -21,7 +21,7 @@
#ifndef __SMBTORTURE_H__
#define __SMBTORTURE_H__
-#include "torture/torture.h"
+#include "../lib/torture/torture.h"
struct smbcli_state;
diff --git a/source4/torture/util.h b/source4/torture/util.h
index f36d54233d..3609cca7d9 100644
--- a/source4/torture/util.h
+++ b/source4/torture/util.h
@@ -20,7 +20,7 @@
#ifndef _TORTURE_UTIL_H_
#define _TORTURE_UTIL_H_
-#include "torture/torture.h"
+#include "lib/torture/torture.h"
struct smbcli_state;
struct smbcli_tree;
diff --git a/source4/torture/winbind/config.mk b/source4/torture/winbind/config.mk
index 15bc51daba..9648a7472b 100644
--- a/source4/torture/winbind/config.mk
+++ b/source4/torture/winbind/config.mk
@@ -5,7 +5,7 @@
SUBSYSTEM = smbtorture
INIT_FUNCTION = torture_winbind_init
PRIVATE_DEPENDENCIES = \
- LIBWINBIND-CLIENT
+ LIBWINBIND-CLIENT torture
# End SUBSYSTEM TORTURE_WINBIND
#################################
diff --git a/source4/utils/ad2oLschema.c b/source4/utils/ad2oLschema.c
index c579112b45..2e3139d9c7 100644
--- a/source4/utils/ad2oLschema.c
+++ b/source4/utils/ad2oLschema.c
@@ -226,7 +226,6 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch
const char *equality = NULL, *substring = NULL;
bool single_value = attribute->isSingleValued;
- const struct dsdb_syntax *map = find_syntax_map_by_ad_syntax(attribute->oMSyntax);
char *schema_entry = NULL;
int j;
@@ -244,11 +243,11 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch
}
}
- if (map) {
+ if (attribute->syntax) {
/* We might have been asked to remap this oid,
* due to a conflict, or lack of
* implementation */
- syntax = map->ldap_oid;
+ syntax = attribute->syntax->ldap_oid;
/* We might have been asked to remap this oid, due to a conflict */
for (j=0; syntax && oid_map && oid_map[j].old_oid; j++) {
if (strcasecmp(syntax, oid_map[j].old_oid) == 0) {
@@ -257,8 +256,8 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch
}
}
- equality = map->equality;
- substring = map->substring;
+ equality = attribute->syntax->equality;
+ substring = attribute->syntax->substring;
}
/* We might have been asked to remap this name, due to a conflict */
@@ -278,7 +277,10 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch
substring,
syntax,
single_value,
- false);
+ false,
+ NULL, NULL,
+ NULL, NULL,
+ false, false);
if (schema_entry == NULL) {
ret.failures++;
@@ -366,7 +368,8 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch
subClassOf,
objectClassCategory,
must,
- may);
+ may,
+ NULL);
if (schema_entry == NULL) {
ret.failures++;
return ret;
diff --git a/source4/utils/net/config.mk b/source4/utils/net/config.mk
index 93b51e1e28..b2f0fcf6b1 100644
--- a/source4/utils/net/config.mk
+++ b/source4/utils/net/config.mk
@@ -16,6 +16,7 @@ PRIVATE_DEPENDENCIES = \
net_OBJ_FILES = $(addprefix $(utilssrcdir)/net/, \
net.o \
+ net_machinepw.o \
net_password.o \
net_time.o \
net_join.o \
diff --git a/source4/utils/net/net.c b/source4/utils/net/net.c
index 81584e4398..4d1b202ccb 100644
--- a/source4/utils/net/net.c
+++ b/source4/utils/net/net.c
@@ -107,6 +107,8 @@ static const struct net_functable net_functable[] = {
{"vampire", "join and syncronise an AD domain onto the local server\n", net_vampire, net_vampire_usage},
{"samsync", "synchronise into the local ldb the sam of an NT4 domain\n", net_samsync_ldb, net_samsync_ldb_usage},
{"user", "manage user accounts\n", net_user, net_user_usage},
+ {"machinepw", "Get a machine password out of our SAM", net_machinepw,
+ net_machinepw_usage},
{NULL, NULL, NULL, NULL}
};
diff --git a/source4/utils/net/net_machinepw.c b/source4/utils/net/net_machinepw.c
new file mode 100644
index 0000000000..710d889c19
--- /dev/null
+++ b/source4/utils/net/net_machinepw.c
@@ -0,0 +1,91 @@
+/*
+ Samba Unix/Linux SMB client library
+ Distributed SMB/CIFS Server Management Utility
+
+ Copyright (C) 2008 Volker Lendecke
+
+ 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 "utils/net/net.h"
+#include "libnet/libnet.h"
+#include "libcli/security/security.h"
+#include "param/secrets.h"
+#include "param/param.h"
+#include "lib/events/events.h"
+#include "lib/util/util_ldb.h"
+
+int net_machinepw_usage(struct net_context *ctx, int argc, const char **argv)
+{
+ d_printf("net machinepw <accountname>\n");
+ return -1;
+}
+
+int net_machinepw(struct net_context *ctx, int argc, const char **argv)
+{
+ struct ldb_context *secrets;
+ TALLOC_CTX *mem_ctx;
+ struct event_context *ev;
+ struct ldb_message **msgs;
+ int num_records;
+ const char *attrs[] = { "secret", NULL };
+ const char *secret;
+
+ if (argc != 1) {
+ net_machinepw_usage(ctx, argc, argv);
+ return -1;
+ }
+
+ mem_ctx = talloc_new(ctx);
+ if (mem_ctx == NULL) {
+ d_fprintf(stderr, "talloc_new failed\n");
+ return -1;
+ }
+
+ ev = event_context_init(mem_ctx);
+ if (ev == NULL) {
+ d_fprintf(stderr, "event_context_init failed\n");
+ goto fail;
+ }
+
+ secrets = secrets_db_connect(mem_ctx, ev, ctx->lp_ctx);
+ if (secrets == NULL) {
+ d_fprintf(stderr, "secrets_db_connect failed\n");
+ goto fail;
+ }
+
+ num_records = gendb_search(secrets, mem_ctx, NULL, &msgs, attrs,
+ "(&(objectclass=primaryDomain)"
+ "(samaccountname=%s))", argv[0]);
+ if (num_records != 1) {
+ d_fprintf(stderr, "gendb_search returned %d records, "
+ "expected 1\n", num_records);
+ goto fail;
+ }
+
+ secret = ldb_msg_find_attr_as_string(msgs[0], "secret", NULL);
+ if (secret == NULL) {
+ d_fprintf(stderr, "machine account contains no secret\n");
+ goto fail;
+ }
+
+ printf("%s\n", secret);
+ talloc_free(mem_ctx);
+ return 0;
+
+ fail:
+ talloc_free(mem_ctx);
+ return -1;
+}
diff --git a/source4/winbind/wb_async_helpers.c b/source4/winbind/wb_async_helpers.c
index 48a2a4d882..a50a0fe473 100644
--- a/source4/winbind/wb_async_helpers.c
+++ b/source4/winbind/wb_async_helpers.c
@@ -325,6 +325,8 @@ struct samr_getuserdomgroups_state {
int num_rids;
uint32_t *rids;
+ struct samr_RidWithAttributeArray *rid_array;
+
struct policy_handle *user_handle;
struct samr_OpenUser o;
struct samr_GetGroupsForUser g;
@@ -386,6 +388,7 @@ static void samr_usergroups_recv_open(struct rpc_request *req)
if (!composite_is_ok(state->ctx)) return;
state->g.in.user_handle = state->user_handle;
+ state->g.out.rids = &state->rid_array;
req = dcerpc_samr_GetGroupsForUser_send(state->samr_pipe, state,
&state->g);
@@ -438,7 +441,7 @@ NTSTATUS wb_samr_userdomgroups_recv(struct composite_context *ctx,
NTSTATUS status = composite_wait(ctx);
if (!NT_STATUS_IS_OK(status)) goto done;
- *num_rids = state->g.out.rids->count;
+ *num_rids = state->rid_array->count;
*rids = talloc_array(mem_ctx, uint32_t, *num_rids);
if (*rids == NULL) {
status = NT_STATUS_NO_MEMORY;
@@ -446,7 +449,7 @@ NTSTATUS wb_samr_userdomgroups_recv(struct composite_context *ctx,
}
for (i=0; i<*num_rids; i++) {
- (*rids)[i] = state->g.out.rids->rids[i].rid;
+ (*rids)[i] = state->rid_array->rids[i].rid;
}
done: