summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoras200622 <none@none>2008-01-05 20:52:22 -0800
committeras200622 <none@none>2008-01-05 20:52:22 -0800
commitdc20a3024900c47dd2ee44b9707e6df38f7d62a5 (patch)
treee0957e6b6d6b5c0117800046c765b78d69f80ce1
parentbda89588bd7667394a834e8a9a34612cce2ae9c3 (diff)
downloadillumos-gate-dc20a3024900c47dd2ee44b9707e6df38f7d62a5.tar.gz
6560095 SNAS shows SIDs for Built-in Groups members instead of name
6582153 SMB signing and sealing (redirector) 6582192 Remove SMB config cache 6582210 Consistent Logging Strategy 6582214 Unified error reporting strategy 6593360 Confusing log message: [ID 334764 user.error] Ads is not enable 6597854 The shares are not accessible if doing Run \\ip-addr 6610587 RPC-WINREG test has failed on smbtorture. 6610650 Workgroup: authentication problem when client's LM level > 2 6611277 Should not be able to join domain when Snas ipc-mode=anon and W2K DC IPC=No access without anonymous 6613675 Creating a file with DOS readonly bit set requires special handling 6626113 libshare_smb leaks file descriptor on unload 6626119 libshare_smb leaks file descriptor on door call failure 6626126 libsmb configuration leaks memory 6629314 smbd logging forgets newlines, creating a mess 6629954 smb local group support should be re-enabled 6630424 libshare having trouble starting smb/server 6631739 rdr_ipcmode does change to "Fallback,anon". 6631985 SMB daemon doesn't locate a new ADS server if ads_site property has been modified. 6631987 SMB daemon reads /etc/resolv.conf once when it starts up. 6633202 smbfs client caused CIFS server panic 6635175 lint error reported when building smbsrv module when either mars or ceres lint was used 6636763 Get core if using sharemgr set-share -r with nonexistent share 6640934 libshare tries to enable smb service if any filesystem is shared over smb 6641051 The CIFS server needs to use the VFS nbmand mechanism for system-wide share reservations 6642047 Changes to SMF properties of the CIFS service - PSARC/2007/686 6642302 Do not add null when marshalling non-null-terminated NDR strings 6642368 Cross protocol byte range locking is needed --HG-- rename : usr/src/lib/smbsrv/libmlsvc/common/mlsvc_handle.c => deleted_files/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_handle.c rename : usr/src/lib/smbsrv/libsmb/common/smb_group_door_encdec.c => deleted_files/usr/src/lib/smbsrv/libsmb/common/smb_group_door_encdec.c rename : usr/src/lib/smbsrv/libsmb/common/smb_group_xdr.c => deleted_files/usr/src/lib/smbsrv/libsmb/common/smb_group_xdr.c rename : usr/src/lib/smbsrv/libmlrpc/common/mlrpc_client.c => usr/src/lib/smbsrv/libmlrpc/common/ndr_client.c rename : usr/src/lib/smbsrv/libmlrpc/common/mlrpc_heap.c => usr/src/lib/smbsrv/libmlrpc/common/ndr_heap.c rename : usr/src/lib/smbsrv/libmlrpc/common/mlrpc_encdec.c => usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c rename : usr/src/lib/smbsrv/libmlrpc/common/mlndo.c => usr/src/lib/smbsrv/libmlrpc/common/ndr_ops.c rename : usr/src/lib/smbsrv/libmlrpc/common/mlndr.c => usr/src/lib/smbsrv/libmlrpc/common/ndr_process.c rename : usr/src/lib/smbsrv/libmlrpc/common/mlrpc_server.c => usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c rename : usr/src/lib/smbsrv/libmlrpc/common/mlrpc_svc.c => usr/src/lib/smbsrv/libmlrpc/common/ndr_svc.c
-rw-r--r--deleted_files/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_handle.c (renamed from usr/src/lib/smbsrv/libmlsvc/common/mlsvc_handle.c)0
-rw-r--r--deleted_files/usr/src/lib/smbsrv/libsmb/common/smb_group_door_encdec.c (renamed from usr/src/lib/smbsrv/libsmb/common/smb_group_door_encdec.c)0
-rw-r--r--deleted_files/usr/src/lib/smbsrv/libsmb/common/smb_group_xdr.c (renamed from usr/src/lib/smbsrv/libsmb/common/smb_group_xdr.c)0
-rw-r--r--usr/src/cmd/dfs.cmds/sharemgr/commands.c28
-rw-r--r--usr/src/cmd/mdb/common/modules/smbsrv/smbsrv.c3
-rwxr-xr-xusr/src/cmd/smbsrv/dtrace/msrpc.d46
-rwxr-xr-xusr/src/cmd/smbsrv/dtrace/stype.d16
-rw-r--r--usr/src/cmd/smbsrv/smbadm/smbadm.c377
-rw-r--r--usr/src/cmd/smbsrv/smbd/server.xml24
-rw-r--r--usr/src/cmd/smbsrv/smbd/smbd_door_ops.c616
-rw-r--r--usr/src/cmd/smbsrv/smbd/smbd_door_server.c40
-rw-r--r--usr/src/cmd/smbsrv/smbd/smbd_join.c47
-rw-r--r--usr/src/cmd/smbsrv/smbd/smbd_main.c62
-rwxr-xr-xusr/src/cmd/smbsrv/smbd/smbd_mlsvc_doorsvc.c20
-rw-r--r--usr/src/cmd/smbsrv/smbd/smbd_nicmon.c8
-rw-r--r--usr/src/lib/Makefile4
-rw-r--r--usr/src/lib/libshare/common/libshare.c11
-rw-r--r--usr/src/lib/libshare/common/libshare.h4
-rw-r--r--usr/src/lib/libshare/smb/libshare_smb.c447
-rw-r--r--usr/src/lib/libshare/smb/smb_share_doorclnt.c808
-rw-r--r--usr/src/lib/libsqlite/Makefile.com11
-rw-r--r--usr/src/lib/libsqlite/i386/Makefile4
-rw-r--r--usr/src/lib/libsqlite/sparc/Makefile4
-rw-r--r--usr/src/lib/smbsrv/libmlrpc/Makefile.com16
-rw-r--r--usr/src/lib/smbsrv/libmlrpc/common/mapfile-vers5
-rw-r--r--usr/src/lib/smbsrv/libmlrpc/common/ndr_client.c (renamed from usr/src/lib/smbsrv/libmlrpc/common/mlrpc_client.c)0
-rw-r--r--usr/src/lib/smbsrv/libmlrpc/common/ndr_heap.c (renamed from usr/src/lib/smbsrv/libmlrpc/common/mlrpc_heap.c)0
-rw-r--r--usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c (renamed from usr/src/lib/smbsrv/libmlrpc/common/mlrpc_encdec.c)0
-rw-r--r--usr/src/lib/smbsrv/libmlrpc/common/ndr_ops.c (renamed from usr/src/lib/smbsrv/libmlrpc/common/mlndo.c)0
-rw-r--r--usr/src/lib/smbsrv/libmlrpc/common/ndr_process.c (renamed from usr/src/lib/smbsrv/libmlrpc/common/mlndr.c)9
-rw-r--r--usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c (renamed from usr/src/lib/smbsrv/libmlrpc/common/mlrpc_server.c)18
-rw-r--r--usr/src/lib/smbsrv/libmlrpc/common/ndr_svc.c (renamed from usr/src/lib/smbsrv/libmlrpc/common/mlrpc_svc.c)184
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/Makefile.com3
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h167
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/lmshare.c51
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/lsalib.c604
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/lsar_lookup.c139
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers34
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c6
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mlsvc_dssetup.c6
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c50
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mlsvc_logr.c82
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mlsvc_lsa.c506
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mlsvc_sam.c804
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mlsvc_srvsvc.c31
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mlsvc_svcctl.c135
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c426
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mlsvc_winreg.c189
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mlsvc_wkssvc.c10
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c18
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c27
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/samlib.c123
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/samr_lookup.c4
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/samr_open.c9
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/secdb.c99
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/smb_autohome.c15
-rw-r--r--usr/src/lib/smbsrv/libsmb/Makefile.com7
-rw-r--r--usr/src/lib/smbsrv/libsmb/amd64/Makefile2
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/libsmb.h333
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/mapfile-vers86
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_api_door_calls.c743
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_auth.c138
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_cfg.c838
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_domain.c22
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_door_client.c96
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_idmap.c60
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_info.c336
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c2319
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_privilege.c44
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_pwdutil.c12
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_scfutil.c377
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_util.c34
-rw-r--r--usr/src/lib/smbsrv/libsmb/i386/Makefile3
-rw-r--r--usr/src/lib/smbsrv/libsmb/sparc/Makefile3
-rw-r--r--usr/src/lib/smbsrv/libsmb/sparcv9/Makefile2
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/libsmbns.h16
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/mapfile-vers10
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c235
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c32
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c85
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.h3
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.c82
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_cache.c8
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_name.c25
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_netlogon.c47
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_nicconfig.c56
-rw-r--r--usr/src/lib/smbsrv/libsmbrdr/common/libsmbrdr.h8
-rw-r--r--usr/src/lib/smbsrv/libsmbrdr/common/mapfile-vers9
-rw-r--r--usr/src/lib/smbsrv/libsmbrdr/common/smbrdr.h24
-rw-r--r--usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_ipc_util.c15
-rw-r--r--usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_lib.c124
-rw-r--r--usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_logon.c129
-rw-r--r--usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_netbios.c23
-rw-r--r--usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_netuse.c76
-rw-r--r--usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_read_andx.c38
-rw-r--r--usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_rpcpipe.c65
-rw-r--r--usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_session.c297
-rw-r--r--usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_transact.c23
-rw-r--r--usr/src/pkgdefs/SUNWsmbsu/prototype_com6
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_check_directory.c11
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_close.c12
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_common_open.c396
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_common_search.c24
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_common_transact.c92
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_common_tree.c32
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_create.c16
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_create_directory.c14
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_delete.c187
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_delete_directory.c10
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_dispatch.c241
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_find.c12
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_find_unique.c6
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_flush.c4
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_fsops.c365
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_lock_byte_range.c6
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_lock_svc.c251
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_locking_andx.c35
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_logoff_andx.c5
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_negotiate.c12
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_node.c257
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_nt_create_andx.c13
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c11
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_nt_transact_ioctl.c6
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_nt_transact_notify_change.c28
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_nt_transact_security.c37
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_ofile.c26
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_open_andx.c22
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_path_name_reduction.c6
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_query_information.c6
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_query_information2.c8
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_query_information_disk.c4
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_read.c25
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_rename.c110
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_rpc.c20
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_sd.c6
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_search.c11
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_seek.c36
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_session_setup_andx.c10
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_set_information.c8
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_set_information2.c10
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_trans2_create_directory.c14
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_trans2_find.c326
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_trans2_query_file_info.c11
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_trans2_query_fs_information.c10
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_trans2_query_path_info.c10
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_trans2_set_file_information.c12
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_trans2_set_information.c8
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_trans2_set_path_information.c11
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_tree_disconnect.c7
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_unlock_byte_range.c8
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_vops.c477
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_write.c76
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_write_raw.c15
-rw-r--r--usr/src/uts/common/smbsrv/cifs.h19
-rw-r--r--usr/src/uts/common/smbsrv/lmshare.h3
-rw-r--r--usr/src/uts/common/smbsrv/lmshare_door.h29
-rw-r--r--usr/src/uts/common/smbsrv/lsalib.h37
-rw-r--r--usr/src/uts/common/smbsrv/mlrpc.h54
-rw-r--r--usr/src/uts/common/smbsrv/mlsvc.h17
-rw-r--r--usr/src/uts/common/smbsrv/mlsvc_util.h101
-rw-r--r--usr/src/uts/common/smbsrv/ndl/rpcpdu.ndl48
-rw-r--r--usr/src/uts/common/smbsrv/ndl/winreg.ndl202
-rw-r--r--usr/src/uts/common/smbsrv/samlib.h4
-rw-r--r--usr/src/uts/common/smbsrv/smb_door_svc.h18
-rw-r--r--usr/src/uts/common/smbsrv/smb_fsops.h14
-rw-r--r--usr/src/uts/common/smbsrv/smb_kproto.h49
-rw-r--r--usr/src/uts/common/smbsrv/smb_privilege.h5
-rw-r--r--usr/src/uts/common/smbsrv/smb_vops.h110
-rw-r--r--usr/src/uts/common/smbsrv/smbinfo.h24
-rw-r--r--usr/src/uts/common/smbsrv/smbvar.h12
170 files changed, 8473 insertions, 8890 deletions
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_handle.c b/deleted_files/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_handle.c
index a13b7346f5..a13b7346f5 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_handle.c
+++ b/deleted_files/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_handle.c
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_group_door_encdec.c b/deleted_files/usr/src/lib/smbsrv/libsmb/common/smb_group_door_encdec.c
index 0b29764926..0b29764926 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_group_door_encdec.c
+++ b/deleted_files/usr/src/lib/smbsrv/libsmb/common/smb_group_door_encdec.c
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_group_xdr.c b/deleted_files/usr/src/lib/smbsrv/libsmb/common/smb_group_xdr.c
index 723a6471f9..723a6471f9 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_group_xdr.c
+++ b/deleted_files/usr/src/lib/smbsrv/libsmb/common/smb_group_xdr.c
diff --git a/usr/src/cmd/dfs.cmds/sharemgr/commands.c b/usr/src/cmd/dfs.cmds/sharemgr/commands.c
index 3ba5cc892b..f6e0f24d3f 100644
--- a/usr/src/cmd/dfs.cmds/sharemgr/commands.c
+++ b/usr/src/cmd/dfs.cmds/sharemgr/commands.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -2973,7 +2973,7 @@ sa_set_share(sa_handle_t handle, int flags, int argc, char *argv[])
int c;
int ret = SA_OK;
sa_group_t group, sharegroup;
- sa_share_t share;
+ sa_share_t share = NULL;
sa_resource_t resource = NULL;
char *sharepath = NULL;
char *description = NULL;
@@ -3107,9 +3107,10 @@ sa_set_share(sa_handle_t handle, int flags, int argc, char *argv[])
share = sa_find_share(handle, sharepath);
} else if (rsrcname != NULL) {
resource = sa_find_resource(handle, rsrc);
- if (resource != NULL) {
+ if (resource != NULL)
share = sa_get_resource_parent(resource);
- }
+ else
+ ret = SA_NO_SUCH_RESOURCE;
}
if (share != NULL) {
sharegroup = sa_get_parent_group(share);
@@ -3191,9 +3192,22 @@ sa_set_share(sa_handle_t handle, int flags, int argc, char *argv[])
break;
}
} else {
- (void) printf(gettext("Share path \"%s\" not found\n"),
- sharepath);
- ret = SA_NO_SUCH_PATH;
+ switch (ret) {
+ case SA_NO_SUCH_RESOURCE:
+ (void) printf(gettext("Resource \"%s\" not found\n"),
+ rsrcname);
+ break;
+ default:
+ if (sharepath != NULL) {
+ (void) printf(
+ gettext("Share path \"%s\" not found\n"),
+ sharepath);
+ ret = SA_NO_SUCH_PATH;
+ } else {
+ (void) printf(gettext("Set failed: %s\n"),
+ sa_errorstr(ret));
+ }
+ }
}
return (ret);
diff --git a/usr/src/cmd/mdb/common/modules/smbsrv/smbsrv.c b/usr/src/cmd/mdb/common/modules/smbsrv/smbsrv.c
index d8cca22f4f..77a6095bbf 100644
--- a/usr/src/cmd/mdb/common/modules/smbsrv/smbsrv.c
+++ b/usr/src/cmd/mdb/common/modules/smbsrv/smbsrv.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -203,7 +203,6 @@ smb_information(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
mdb_printf("%sAnnounce Quota\n",
(smb_info.si.skc_announce_quota) ? "" : "Do Not ");
mdb_printf("Security Mode %d\n", smb_info.si.skc_secmode);
- mdb_printf("LM Level %d\n", smb_info.si.skc_lmlevel);
mdb_printf("Domain %s\n", smb_info.si.skc_resource_domain);
mdb_printf("Hostname %s\n", smb_info.si.skc_hostname);
mdb_printf("Comment %s\n", smb_info.si.skc_system_comment);
diff --git a/usr/src/cmd/smbsrv/dtrace/msrpc.d b/usr/src/cmd/smbsrv/dtrace/msrpc.d
index abf6497980..ce352a7588 100755
--- a/usr/src/cmd/smbsrv/dtrace/msrpc.d
+++ b/usr/src/cmd/smbsrv/dtrace/msrpc.d
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -85,6 +85,18 @@
* trace:entry MO 02 .. sec_addr.port_spec[11] put 1@37 = 0 {00}
*/
+BEGIN
+{
+ printf("MSRPC Trace Started");
+ printf("\n\n");
+}
+
+END
+{
+ printf("MSRPC Trace Ended");
+ printf("\n\n");
+}
+
/*
* SmbSessionSetupX, SmbLogoffX
* SmbTreeConnect, SmbTreeDisconnect
@@ -97,16 +109,24 @@ smb_com_session_setup_andx:entry,
smb_com_logoff_andx:entry,
smb_tree_connect:return,
smb_tree_disconnect:entry,
-smb_tree_disconnect:return
+smb_tree_disconnect:return,
+smb_winpipe_open:entry,
+smb_winpipe_call:entry,
+smb_winpipe_upcall:entry,
+door_ki_upcall:entry
{
}
smb_com_session_setup_andx:return,
smb_session*:return,
smb_user*:return,
-smb_tree*:return
+smb_tree*:return,
+smb_winpipe_open:return,
+smb_winpipe_call:return,
+smb_winpipe_upcall:return,
+door_ki_upcall:return
{
- printf("rc=%d", arg1);
+ printf("rc=0x%08x", arg1);
}
sdt:smbsrv::smb-sessionsetup-clntinfo
@@ -131,22 +151,12 @@ smb_com_logoff_andx:return
/*
* Raise error functions (no return).
*/
-smbsr_raise_error:entry
-{
- printf("class=%d code=%d", arg1, arg2);
-}
-
-smbsr_raise_cifs_error:entry
+smbsr_error:entry
{
printf("status=0x%08x class=%d, code=%d", arg1, arg2, arg3);
}
-smbsr_raise_nt_error:entry
-{
- printf("error=0x%08x", arg1);
-}
-
-smbsr_raise_errno:entry
+smbsr_errno:entry
{
printf("errno=%d", arg1);
}
@@ -356,7 +366,7 @@ pid$target::smbrdr_*:return
{
}
-pid$target::mlsvc_tree_connect:entry
+pid$target::smbrdr_tree_connect:entry
{
printf("%s %s %s",
copyinstr(arg0),
@@ -377,7 +387,7 @@ pid$target::mlsvc_close_pipe:entry
{
}
-pid$target::mlsvc_tree_connect:return,
+pid$target::smbrdr_tree_connect:return,
pid$target::mlsvc_open_pipe:return,
pid$target::mlsvc_close_pipe:return
{
diff --git a/usr/src/cmd/smbsrv/dtrace/stype.d b/usr/src/cmd/smbsrv/dtrace/stype.d
index 19fef52dbe..53968091bb 100755
--- a/usr/src/cmd/smbsrv/dtrace/stype.d
+++ b/usr/src/cmd/smbsrv/dtrace/stype.d
@@ -22,7 +22,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -60,22 +60,12 @@ smb_com_logoff_andx:return
/*
* Raise error functions (no return).
*/
-smbsr_raise_error:entry
-{
- printf("class=%d code=%d", arg1, arg2);
-}
-
-smbsr_raise_cifs_error:entry
+smbsr_error:entry
{
printf("status=0x%08x class=%d, code=%d", arg1, arg2, arg3);
}
-smbsr_raise_nt_error:entry
-{
- printf("error=0x%08x", arg1);
-}
-
-smbsr_raise_errno:entry
+smbsr_errno:entry
{
printf("errno=%d", arg1);
}
diff --git a/usr/src/cmd/smbsrv/smbadm/smbadm.c b/usr/src/cmd/smbsrv/smbadm/smbadm.c
index 17cb3b8300..adeac3cb6a 100644
--- a/usr/src/cmd/smbsrv/smbadm/smbadm.c
+++ b/usr/src/cmd/smbsrv/smbadm/smbadm.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -41,7 +41,6 @@
#include <libgen.h>
#include <smbsrv/libsmb.h>
-#include <smbsrv/libmlsvc.h>
typedef enum {
HELP_ADD_MEMBER,
@@ -403,9 +402,7 @@ smbadm_list(int argc, char **argv)
return (1);
}
- (void) printf(gettext("%s name: %s\n"),
- modename, resource_domain);
-
+ (void) printf(gettext("%s name: %s\n"), modename, resource_domain);
return (0);
}
@@ -420,7 +417,7 @@ smbadm_group_create(int argc, char **argv)
char *gname = NULL;
char *desc = NULL;
char option;
- uint32_t status;
+ int status;
while ((option = getopt(argc, argv, "d:")) != -1) {
switch (option) {
@@ -441,19 +438,19 @@ smbadm_group_create(int argc, char **argv)
if (getgrnam(gname) == NULL) {
(void) fprintf(stderr,
- gettext("failed to get the Solaris group\n"));
+ gettext("failed to get the Solaris group '%s'\n"), gname);
(void) fprintf(stderr,
- gettext("use 'groupadd' to add the Solaris group\n"));
+ gettext("use 'groupadd' to add '%s'\n"), gname);
return (1);
}
- status = smb_group_add(gname, desc);
- if (status != NT_STATUS_SUCCESS) {
+ status = smb_lgrp_add(gname, desc);
+ if (status != SMB_LGRP_SUCCESS) {
(void) fprintf(stderr,
gettext("failed to create the group (%s)\n"),
- xlate_nt_status(status));
+ smb_lgrp_strerror(status));
} else {
- (void) printf(gettext("Successfully created group '%s'\n"),
+ (void) printf(gettext("'%s' created.\n"),
gname);
}
@@ -466,38 +463,21 @@ smbadm_group_create(int argc, char **argv)
* Dump group members details.
*/
static void
-smbadm_group_dump_members(char *gname)
+smbadm_group_dump_members(smb_gsid_t *members, int num)
{
- ntgrp_member_list_t *members = NULL;
- int mem_cnt = 0;
- int offset = 0;
- uint32_t status;
+ char sidstr[NT_SID_FMTBUF_SIZE];
int i;
- status = smb_group_member_count(gname, &mem_cnt);
- if (mem_cnt < 0) {
- (void) fprintf(stderr,
- gettext("failed to get the group members (%s)\n"),
- xlate_nt_status(status));
- }
-
- if (mem_cnt == 0) {
+ if (num == 0) {
(void) printf(gettext("\tNo members\n"));
return;
}
(void) printf(gettext("\tMembers:\n"));
- while (smb_group_member_list(gname, offset, &members) == 0) {
- if (members == NULL)
- break;
-
- for (i = 0; i < members->cnt; i++)
- (void) printf(gettext("\t\t%s\n"), members->members[i]);
-
- offset += members->cnt;
- smb_group_free_memberlist(members, 0);
- if (offset >= mem_cnt)
- break;
+ for (i = 0; i < num; i++) {
+ (void) smb_lookup_sid(members[i].gs_sid, sidstr,
+ sizeof (sidstr));
+ (void) printf(gettext("\t\t%s\n"), sidstr);
}
}
@@ -507,39 +487,34 @@ smbadm_group_dump_members(char *gname)
* Dump group privilege details.
*/
static void
-smbadm_group_dump_privs(char *gname, ntpriv_list_t *privs)
+smbadm_group_dump_privs(smb_privset_t *privs)
{
- int privcnt = 0;
- uint32_t privval;
- char *name = NULL;
+ smb_privinfo_t *pinfo;
+ char *pstatus;
int i;
(void) printf(gettext("\tPrivileges: \n"));
- for (i = 0; i < privs->cnt; i++) {
- name = privs->privs[i]->name;
- if (name == NULL)
+ for (i = 0; i < privs->priv_cnt; i++) {
+ pinfo = smb_priv_getbyvalue(privs->priv[i].luid.lo_part);
+ if ((pinfo == NULL) || (pinfo->flags & PF_PRESENTABLE) == 0)
continue;
- if (smb_group_priv_get(gname, privs->privs[i]->id,
- &privval) != 0) {
- continue;
- }
-
- if (privval == SE_PRIVILEGE_ENABLED) {
- (void) printf(gettext("\t\t%s: On\n"), name);
- } else if (privval == SE_PRIVILEGE_DISABLED) {
- (void) printf(gettext("\t\t%s: Off\n"), name);
- } else {
- (void) printf(gettext("\t\t%s: %d\n"),
- name, privval);
+ switch (privs->priv[i].attrs) {
+ case SE_PRIVILEGE_ENABLED:
+ pstatus = "On";
+ break;
+ case SE_PRIVILEGE_DISABLED:
+ pstatus = "Off";
+ break;
+ default:
+ pstatus = "Unknown";
+ break;
}
-
- name = NULL;
- privcnt++;
+ (void) printf(gettext("\t\t%s: %s\n"), pinfo->name, pstatus);
}
- if (privcnt == 0)
+ if (privs->priv_cnt == 0)
(void) printf(gettext("\t\tNo privileges\n"));
}
@@ -548,41 +523,21 @@ smbadm_group_dump_privs(char *gname, ntpriv_list_t *privs)
*
* Dump group details.
*/
-static int
-smbadm_group_dump(ntgrp_list_t *list, boolean_t show_mem, boolean_t show_privs)
+static void
+smbadm_group_dump(smb_group_t *grp, boolean_t show_mem, boolean_t show_privs)
{
- ntpriv_list_t *privs = NULL;
- char *gname;
- uint32_t status;
- int i;
+ char sidstr[NT_SID_FMTBUF_SIZE];
- if (show_privs) {
- if ((status = smb_group_priv_list(&privs)) != 0) {
- (void) fprintf(stderr,
- gettext("failed to get privileges (%s)\n"),
- xlate_nt_status(status));
- return (1);
- }
- }
+ (void) printf(gettext("%s (%s)\n"), grp->sg_name, grp->sg_cmnt);
- for (i = 0; i < list->cnt; i++) {
- gname = list->groups[i].name;
+ nt_sid_format2(grp->sg_id.gs_sid, sidstr);
+ (void) printf(gettext("\tSID: %s\n"), sidstr);
- (void) printf(gettext("%s (%s)\n"), gname,
- list->groups[i].desc);
- (void) printf(gettext("\tType: %s, Attr: %X\n"),
- list->groups[i].type, list->groups[i].attr);
- (void) printf(gettext("\tSID: %s\n"),
- list->groups[i].sid);
-
- if (show_privs)
- smbadm_group_dump_privs(gname, privs);
-
- if (show_mem)
- smbadm_group_dump_members(list->groups[i].name);
- }
+ if (show_privs)
+ smbadm_group_dump_privs(grp->sg_privs);
- return (0);
+ if (show_mem)
+ smbadm_group_dump_members(grp->sg_members, grp->sg_nmembers);
}
/*
@@ -593,14 +548,12 @@ static int
smbadm_group_show(int argc, char **argv)
{
char *gname = NULL;
- int cnt = 0;
- int offset = 0;
boolean_t show_privs;
boolean_t show_members;
char option;
- uint32_t status;
- ntgrp_list_t *list = NULL;
- int ret = 0;
+ int status;
+ smb_group_t grp;
+ smb_giter_t gi;
show_privs = show_members = B_FALSE;
@@ -622,47 +575,44 @@ smbadm_group_show(int argc, char **argv)
if (optind >= argc || gname == NULL || *gname == '\0')
gname = "*";
- status = smb_group_count(&cnt);
- if ((status != NT_STATUS_SUCCESS) || (cnt < 0)) {
- (void) fprintf(stderr,
- gettext("failed to get the number of group(s) (%s)\n"),
- xlate_nt_status(status));
- return (1);
- }
-
- while ((offset < cnt)) {
- status = smb_group_list(offset, &list, gname, 0);
- if (status != NT_STATUS_SUCCESS) {
+ if (strcmp(gname, "*")) {
+ status = smb_lgrp_getbyname(gname, &grp);
+ if (status == SMB_LGRP_SUCCESS) {
+ smbadm_group_dump(&grp, show_members, show_privs);
+ smb_lgrp_free(&grp);
+ } else {
(void) fprintf(stderr,
- gettext("failed to get the group(s) (%s)\n"),
- xlate_nt_status(status));
- return (1);
+ gettext("failed to find '%s' (%s)\n"),
+ gname, smb_lgrp_strerror(status));
}
+ return (status);
+ }
- if ((list == NULL) || (list->cnt <= 0))
- break;
-
- ret = smbadm_group_dump(list, show_members, show_privs);
- if (ret)
- break;
+ status = smb_lgrp_iteropen(&gi);
+ if (status != SMB_LGRP_SUCCESS) {
+ (void) fprintf(stderr,
+ gettext("failed to list groups (%s)\n"),
+ smb_lgrp_strerror(status));
+ return (status);
+ }
- offset += list->cnt;
- smb_group_free_list(list, 0);
- list = NULL;
+ while (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS) {
+ smbadm_group_dump(&grp, show_members, show_privs);
+ smb_lgrp_free(&grp);
}
+ smb_lgrp_iterclose(&gi);
- return (ret);
+ return (0);
}
/*
* smbadm_group_delete
- *
*/
static int
smbadm_group_delete(int argc, char **argv)
{
- uint32_t status;
char *gname = NULL;
+ int status;
gname = argv[optind];
if (optind >= argc || gname == NULL || *gname == '\0') {
@@ -670,13 +620,13 @@ smbadm_group_delete(int argc, char **argv)
smbadm_usage(B_FALSE);
}
- status = smb_group_delete(gname);
- if (status != NT_STATUS_SUCCESS) {
+ status = smb_lgrp_delete(gname);
+ if (status != SMB_LGRP_SUCCESS) {
(void) fprintf(stderr,
gettext("failed to delete the group (%s)\n"),
- xlate_nt_status(status));
+ smb_lgrp_strerror(status));
} else {
- (void) printf(gettext("Successfully deleted group '%s'\n"),
+ (void) printf(gettext("'%s' deleted.\n"),
gname);
}
@@ -685,14 +635,13 @@ smbadm_group_delete(int argc, char **argv)
/*
* smbadm_group_rename
- *
*/
static int
smbadm_group_rename(int argc, char **argv)
{
char *gname = NULL;
char *ngname = NULL;
- uint32_t status;
+ int status;
gname = argv[optind];
if (optind++ >= argc || gname == NULL || *gname == '\0') {
@@ -706,22 +655,26 @@ smbadm_group_rename(int argc, char **argv)
smbadm_usage(B_FALSE);
}
- if (getgrnam(gname) == NULL) {
+ if (getgrnam(ngname) == NULL) {
(void) fprintf(stderr,
- gettext("failed to get the Solaris group\n"));
+ gettext("failed to get the Solaris group '%s'\n"), ngname);
(void) fprintf(stderr,
- gettext("use 'groupadd' to add the Solaris group\n"));
+ gettext("use 'groupadd' to add '%s'\n"), ngname);
return (1);
}
- status = smb_group_modify(gname, ngname, NULL);
- if (status != NT_STATUS_SUCCESS) {
- (void) fprintf(stderr,
- gettext("failed to modify the group (%s)\n"),
- xlate_nt_status(status));
+ status = smb_lgrp_rename(gname, ngname);
+ if (status != SMB_LGRP_SUCCESS) {
+ if (status == SMB_LGRP_EXISTS)
+ (void) fprintf(stderr,
+ gettext("failed to rename '%s' (%s already "
+ "exists)\n"), gname, ngname);
+ else
+ (void) fprintf(stderr,
+ gettext("failed to rename '%s' (%s)\n"), gname,
+ smb_lgrp_strerror(status));
} else {
- (void) printf(gettext("Successfully modified "
- "group '%s'\n"), gname);
+ (void) printf(gettext("'%s' renamed to '%s'\n"), gname, ngname);
}
return (status);
@@ -755,14 +708,8 @@ smbadm_group_setprop(int argc, char **argv)
smbadm_usage(B_FALSE);
}
- ret = smbadm_prop_parse(optarg, &props[pcnt++]);
- if (ret) {
- if (ret == 1)
- exit(1);
-
- if (ret == 2)
- smbadm_usage(B_FALSE);
- }
+ if (smbadm_prop_parse(optarg, &props[pcnt++]) != 0)
+ smbadm_usage(B_FALSE);
break;
default:
@@ -821,14 +768,8 @@ smbadm_group_getprop(int argc, char **argv)
smbadm_usage(B_FALSE);
}
- ret = smbadm_prop_parse(optarg, &props[pcnt++]);
- if (ret) {
- if (ret == 1)
- exit(1);
-
- if (ret == 2)
- smbadm_usage(B_FALSE);
- }
+ if (smbadm_prop_parse(optarg, &props[pcnt++]) != 0)
+ smbadm_usage(B_FALSE);
break;
default:
@@ -873,7 +814,8 @@ smbadm_group_addmember(int argc, char **argv)
char *gname = NULL;
char **mname;
char option;
- uint32_t status;
+ smb_gsid_t msid;
+ int status;
int mcnt = 0;
int ret = 0;
int i;
@@ -916,16 +858,25 @@ smbadm_group_addmember(int argc, char **argv)
if (mname[i] == NULL)
continue;
- status = smb_group_member_add(gname, mname[i]);
- if (status != NT_STATUS_SUCCESS) {
+ if (smb_lookup_name(mname[i], &msid) != NT_STATUS_SUCCESS) {
+ (void) fprintf(stderr,
+ gettext("failed to add %s "
+ "(could not obtain the SID)\n"),
+ mname[i]);
+ continue;
+ }
+
+ status = smb_lgrp_add_member(gname, msid.gs_sid, msid.gs_type);
+ free(msid.gs_sid);
+ if (status != SMB_LGRP_SUCCESS) {
(void) fprintf(stderr,
gettext("failed to add %s (%s)\n"),
- mname[i], xlate_nt_status(status));
+ mname[i], smb_lgrp_strerror(status));
ret = 1;
- }
- else
- (void) printf(gettext("Successfully added %s to %s\n"),
+ } else {
+ (void) printf(gettext("'%s' is now a member of '%s'\n"),
mname[i], gname);
+ }
}
free(mname);
@@ -941,7 +892,8 @@ smbadm_group_delmember(int argc, char **argv)
char *gname = NULL;
char **mname;
char option;
- uint32_t status;
+ smb_gsid_t msid;
+ int status;
int mcnt = 0;
int ret = 0;
int i;
@@ -983,15 +935,24 @@ smbadm_group_delmember(int argc, char **argv)
if (mname[i] == NULL)
continue;
- status = smb_group_member_remove(gname, mname[i]);
- if (status != NT_STATUS_SUCCESS) {
+ if (smb_lookup_name(mname[i], &msid) != NT_STATUS_SUCCESS) {
+ (void) fprintf(stderr,
+ gettext("failed to remove %s "
+ "(could not obtain the SID)\n"),
+ mname[i]);
+ continue;
+ }
+
+ status = smb_lgrp_del_member(gname, msid.gs_sid, msid.gs_type);
+ free(msid.gs_sid);
+ if (status != SMB_LGRP_SUCCESS) {
(void) fprintf(stderr,
gettext("failed to remove %s (%s)\n"),
- mname[i], xlate_nt_status(status));
+ mname[i], smb_lgrp_strerror(status));
ret = 1;
} else {
(void) printf(
- gettext("Successfully removed %s from %s\n"),
+ gettext("'%s' has been removed from %s\n"),
mname[i], gname);
}
}
@@ -1045,6 +1006,7 @@ smbadm_user_enable(int argc, char **argv)
int
main(int argc, char **argv)
{
+ int ret;
int i;
(void) malloc(0); /* satisfy libumem dependency */
@@ -1087,7 +1049,24 @@ main(int argc, char **argv)
smbadm_usage(B_TRUE);
}
- return (curcmd->func(argc - 1, &argv[1]));
+ if (smb_idmap_start() != 0) {
+ (void) fprintf(stderr,
+ gettext("failed to contact idmap service"));
+ return (1);
+ }
+
+ if ((ret = smb_lgrp_start()) != SMB_LGRP_SUCCESS) {
+ (void) fprintf(stderr,
+ gettext("failed to initialize (%s)"),
+ smb_lgrp_strerror(ret));
+ smb_idmap_stop();
+ return (1);
+ }
+
+ ret = curcmd->func(argc - 1, &argv[1]);
+ smb_lgrp_stop();
+ smb_idmap_stop();
+ return (ret);
}
}
@@ -1167,13 +1146,13 @@ smbadm_prop_gethandle(char *pname)
static int
smbadm_setprop_desc(char *gname, smbadm_prop_t *prop)
{
- uint32_t status;
+ int status;
- status = smb_group_modify(gname, gname, prop->p_value);
- if (status != NT_STATUS_SUCCESS) {
+ status = smb_lgrp_setcmnt(gname, prop->p_value);
+ if (status != SMB_LGRP_SUCCESS) {
(void) fprintf(stderr,
gettext("failed to modify the group description (%s)\n"),
- xlate_nt_status(status));
+ smb_lgrp_strerror(status));
return (1);
}
@@ -1186,50 +1165,44 @@ smbadm_setprop_desc(char *gname, smbadm_prop_t *prop)
static int
smbadm_getprop_desc(char *gname, smbadm_prop_t *prop)
{
- uint32_t status;
- ntgrp_list_t *list = NULL;
+ char *cmnt = NULL;
+ int status;
- status = smb_group_list(0, &list, gname, 0);
- if (status != NT_STATUS_SUCCESS) {
+ status = smb_lgrp_getcmnt(gname, &cmnt);
+ if (status != SMB_LGRP_SUCCESS) {
(void) fprintf(stderr,
- gettext("failed to get the %s (%s)\n"),
- prop->p_name, xlate_nt_status(status));
- return (1);
- }
-
- if ((list == NULL) || (list->cnt <= 0)) {
- (void) fprintf(stderr, gettext("%s: no such group\n"), gname);
+ gettext("failed to get the group description (%s)\n"),
+ smb_lgrp_strerror(status));
return (1);
}
- (void) printf(gettext("\t%s: %s\n"), prop->p_name,
- list->groups[0].desc);
- smb_group_free_list(list, 0);
+ (void) printf(gettext("\t%s: %s\n"), prop->p_name, cmnt);
+ free(cmnt);
return (0);
}
static int
-smbadm_group_setpriv(char *gname, uint32_t priv_id, smbadm_prop_t *prop)
+smbadm_group_setpriv(char *gname, uint8_t priv_id, smbadm_prop_t *prop)
{
- uint32_t priv_attr;
- uint32_t status;
+ boolean_t enable;
+ int status;
int ret;
if (strcasecmp(prop->p_value, "on") == 0) {
(void) printf(gettext("Enabling %s privilege "), prop->p_name);
- priv_attr = SE_PRIVILEGE_ENABLED;
+ enable = B_TRUE;
} else {
(void) printf(gettext("Disabling %s privilege "), prop->p_name);
- priv_attr = SE_PRIVILEGE_DISABLED;
+ enable = B_FALSE;
}
- status = smb_group_priv_set(gname, priv_id, priv_attr);
-
- if (status == NT_STATUS_SUCCESS) {
+ status = smb_lgrp_setpriv(gname, priv_id, enable);
+ if (status == SMB_LGRP_SUCCESS) {
(void) printf(gettext("succeeded\n"));
ret = 0;
} else {
- (void) printf(gettext("failed: %s\n"), xlate_nt_status(status));
+ (void) printf(gettext("failed: %s\n"),
+ smb_lgrp_strerror(status));
ret = 1;
}
@@ -1237,24 +1210,20 @@ smbadm_group_setpriv(char *gname, uint32_t priv_id, smbadm_prop_t *prop)
}
static int
-smbadm_group_getpriv(char *gname, uint32_t priv_id, smbadm_prop_t *prop)
+smbadm_group_getpriv(char *gname, uint8_t priv_id, smbadm_prop_t *prop)
{
- uint32_t priv_attr;
- uint32_t status;
+ boolean_t enable;
+ int status;
- status = smb_group_priv_get(gname, priv_id, &priv_attr);
- if (status != NT_STATUS_SUCCESS) {
+ status = smb_lgrp_getpriv(gname, priv_id, &enable);
+ if (status != SMB_LGRP_SUCCESS) {
(void) fprintf(stderr, gettext("failed to get %s (%s)\n"),
- prop->p_name, xlate_nt_status(status));
+ prop->p_name, smb_lgrp_strerror(status));
return (1);
}
- if (priv_attr == SE_PRIVILEGE_ENABLED)
- (void) printf(gettext("\t%s: %s\n"), prop->p_name, "On");
- else if (priv_attr == SE_PRIVILEGE_DISABLED)
- (void) printf(gettext("\t%s: %s\n"), prop->p_name, "Off");
- else
- (void) printf(gettext("\t%s: %s\n"), prop->p_name, "Unknown");
+ (void) printf(gettext("\t%s: %s\n"), prop->p_name,
+ (enable) ? "On" : "Off");
return (0);
}
diff --git a/usr/src/cmd/smbsrv/smbd/server.xml b/usr/src/cmd/smbsrv/smbd/server.xml
index 879ca260a8..99b6b7c033 100644
--- a/usr/src/cmd/smbsrv/smbd/server.xml
+++ b/usr/src/cmd/smbsrv/smbd/server.xml
@@ -21,7 +21,7 @@
CDDL HEADER END
- Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ Copyright 2008 Sun Microsystems, Inc. All rights reserved.
Use is subject to license terms.
ident "%Z%%M% %I% %E% SMI"
@@ -124,10 +124,6 @@
value='solaris.smf.read.smb' />
<propval name='value_authorization' type='astring'
value='solaris.smf.value.smb' />
- <propval name='rdr_ipcuser' type='astring' value='' />
- <propval name='rdr_ipcpasswd' type='astring' value='' />
- <propval name='ads_user' type='astring' value='' />
- <propval name='ads_passwd' type='astring' value='' />
<propval name='machine_passwd' type='astring' value='' />
</property_group>
@@ -136,8 +132,6 @@
<stability value='Evolving' />
<propval name='value_authorization' type='astring'
value='solaris.smf.value.smb' />
- <propval name='rdr_ipcmode' type='astring'
- value='auth' override='true'/>
<propval name='oplock_enable' type='boolean'
value='false' override='true'/>
<propval name='oplock_timeout' type='integer'
@@ -160,8 +154,6 @@
value='' override='true'/>
<propval name='srvsvc_sharesetinfo_enable' type='boolean'
value='false' override='true'/>
- <propval name='logr_enable' type='boolean'
- value='false' override='true'/>
<propval name='mlrpc_keep_alive_interval' type='integer'
value='30' override='true'/>
<propval name='max_bufsize' type='integer'
@@ -196,24 +188,10 @@
value='' override='true'/>
<propval name='lmauth_level' type='integer'
value='4' override='true'/>
- <propval name='msdcs_disable' type='boolean'
- value='false' override='true'/>
- <propval name='ads_enable' type='boolean'
- value='false' override='true'/>
- <propval name='ads_domain' type='astring'
- value='' override='true'/>
<propval name='ads_site' type='astring'
value='' override='true'/>
- <propval name='ads_user_container' type='astring'
- value='cn=Users' override='true'/>
- <propval name='ads_ip_lookup' type='boolean'
- value='false' override='true'/>
<propval name='ddns_enable' type='boolean'
value='false' override='true'/>
- <propval name='ddns_retry_cnt' type='integer'
- value='3' override='true'/>
- <propval name='ddns_retry_sec' type='integer'
- value='2' override='true'/>
</property_group>
<!-- 6. Identify faults to be ignored. -->
diff --git a/usr/src/cmd/smbsrv/smbd/smbd_door_ops.c b/usr/src/cmd/smbsrv/smbd/smbd_door_ops.c
index 5b1634a719..72b27a581e 100644
--- a/usr/src/cmd/smbsrv/smbd/smbd_door_ops.c
+++ b/usr/src/cmd/smbsrv/smbd/smbd_door_ops.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -32,6 +32,7 @@
#include <synch.h>
#include <strings.h>
#include <smbsrv/smb_common_door.h>
+#include <smbsrv/mlsvc_util.h>
#include <smbsrv/libmlsvc.h>
#include "smbd.h"
@@ -50,33 +51,9 @@ static char *smb_dop_user_auth_logoff(char *argp, size_t arg_size,
static char *smb_dop_user_list(char *argp, size_t arg_size,
door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err);
-static char *smb_dop_group_add(char *argp, size_t arg_size,
+static char *smb_dop_lookup_sid(char *argp, size_t arg_size,
door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err);
-static char *smb_dop_group_delete(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err);
-static char *smb_dop_group_member_add(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err);
-static char *smb_dop_group_member_remove(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err);
-static char *smb_dop_group_count(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err);
-static char *smb_dop_group_cachesize(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err);
-static char *smb_dop_group_modify(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err);
-static char *smb_dop_group_priv_num(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err);
-static char *smb_dop_group_priv_list(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err);
-static char *smb_dop_group_priv_get(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err);
-static char *smb_dop_group_priv_set(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err);
-static char *smb_dop_group_list(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err);
-static char *smb_dop_group_member_list(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err);
-static char *smb_dop_group_member_count(char *argp, size_t arg_size,
+static char *smb_dop_lookup_name(char *argp, size_t arg_size,
door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err);
/* SMB daemon's door operation table */
@@ -87,20 +64,8 @@ smb_dr_op_t smb_doorsrv_optab[] =
smb_dop_user_nonauth_logon,
smb_dop_user_auth_logoff,
smb_dop_user_list,
- smb_dop_group_add,
- smb_dop_group_delete,
- smb_dop_group_member_add,
- smb_dop_group_member_remove,
- smb_dop_group_count,
- smb_dop_group_cachesize,
- smb_dop_group_modify,
- smb_dop_group_priv_num,
- smb_dop_group_priv_list,
- smb_dop_group_priv_get,
- smb_dop_group_priv_set,
- smb_dop_group_list,
- smb_dop_group_member_list,
- smb_dop_group_member_count
+ smb_dop_lookup_sid,
+ smb_dop_lookup_name,
};
/*ARGSUSED*/
@@ -330,587 +295,86 @@ smb_dop_user_list(char *argp, size_t arg_size,
return (rbuf);
}
-/* NT Group door operations start from here */
-/*ARGSUSED*/
-static char *
-smb_dop_group_add(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err)
-{
- char *rbuf = NULL;
- ntgrp_dr_arg_t *args;
- uint32_t ntstatus = NT_STATUS_UNSUCCESSFUL;
-
- *err = SMB_DR_OP_SUCCESS;
- *rbufsize = 0;
-
- /* Decode */
- if ((args = (ntgrp_dr_arg_t *)malloc(sizeof (ntgrp_dr_arg_t))) == 0) {
- syslog(LOG_ERR,
- "smb_dop_group_add: cannot allocate memory");
- *err = SMB_DR_OP_ERR;
- return (NULL);
- }
- bzero(args, sizeof (ntgrp_dr_arg_t));
- if (smb_dr_decode_common(argp, arg_size,
- xdr_ntgrp_dr_arg_t, args) != 0) {
- free(args);
- *err = SMB_DR_OP_ERR_DECODE;
- return (NULL);
- }
-
- ntstatus = nt_group_add(args->gname, args->desc);
-
- /* Encode the result and return */
- if ((rbuf = smb_dr_encode_common(SMB_DR_OP_SUCCESS, &ntstatus,
- xdr_uint32_t, rbufsize)) == NULL) {
- *err = SMB_DR_OP_ERR_ENCODE;
- *rbufsize = 0;
- }
-
- free(args);
- return (rbuf);
-}
-
-/*ARGSUSED*/
-static char *
-smb_dop_group_delete(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err)
-{
- char *gname = NULL;
- char *rbuf = NULL;
- uint32_t ntstatus = NT_STATUS_UNSUCCESSFUL;
-
- *err = SMB_DR_OP_SUCCESS;
- *rbufsize = 0;
-
- /* Decode */
- if ((gname = smb_dr_decode_string(argp, arg_size)) == 0) {
- *err = SMB_DR_OP_ERR_DECODE;
- return (NULL);
- }
-
- ntstatus = nt_group_delete(gname);
-
- /* Encode the result and return */
- if ((rbuf = smb_dr_encode_common(SMB_DR_OP_SUCCESS, &ntstatus,
- xdr_uint32_t, rbufsize)) == NULL) {
- *err = SMB_DR_OP_ERR_ENCODE;
- *rbufsize = 0;
- }
- return (rbuf);
-}
-
-/*ARGSUSED*/
-static char *
-smb_dop_group_member_add(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err)
-{
- char *rbuf = NULL;
- ntgrp_dr_arg_t *args;
- nt_group_t *grp = NULL;
- uint32_t ntstatus = NT_STATUS_UNSUCCESSFUL;
-
- *err = SMB_DR_OP_SUCCESS;
- *rbufsize = 0;
-
- /* Decode */
- if ((args = (ntgrp_dr_arg_t *)malloc(sizeof (ntgrp_dr_arg_t))) == 0) {
- syslog(LOG_ERR,
- "smb_dop_group_member_add: cannot allocate memory");
- *err = SMB_DR_OP_ERR;
- return (NULL);
- }
- bzero(args, sizeof (ntgrp_dr_arg_t));
- if (smb_dr_decode_common(argp, arg_size,
- xdr_ntgrp_dr_arg_t, args) != 0) {
- free(args);
- *err = SMB_DR_OP_ERR_DECODE;
- return (NULL);
- }
-
- grp = nt_group_getinfo(args->gname, RWLOCK_WRITER);
- if (grp) {
- ntstatus = nt_group_add_member_byname(args->gname,
- args->member);
- } else {
- ntstatus = NT_STATUS_NO_SUCH_GROUP;
- }
- nt_group_putinfo(grp);
-
- /* Encode the result and return */
- if ((rbuf = smb_dr_encode_common(SMB_DR_OP_SUCCESS, &ntstatus,
- xdr_uint32_t, rbufsize)) == NULL) {
- *err = SMB_DR_OP_ERR_ENCODE;
- *rbufsize = 0;
- }
- free(args);
- return (rbuf);
-}
-
-/*ARGSUSED*/
-static char *
-smb_dop_group_member_remove(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err)
-{
- char *rbuf = NULL;
- ntgrp_dr_arg_t *args;
- nt_group_t *grp = NULL;
- uint32_t ntstatus = NT_STATUS_UNSUCCESSFUL;
-
- *err = SMB_DR_OP_SUCCESS;
- *rbufsize = 0;
-
- /* Decode */
- if ((args = (ntgrp_dr_arg_t *)malloc(sizeof (ntgrp_dr_arg_t))) == 0) {
- syslog(LOG_ERR,
- "smb_dop_group_member_add: cannot allocate memory");
- *err = SMB_DR_OP_ERR;
- return (NULL);
- }
- bzero(args, sizeof (ntgrp_dr_arg_t));
- if (smb_dr_decode_common(argp, arg_size,
- xdr_ntgrp_dr_arg_t, args) != 0) {
- free(args);
- *err = SMB_DR_OP_ERR_DECODE;
- return (NULL);
- }
-
- grp = nt_group_getinfo(args->gname, RWLOCK_WRITER);
- if (grp) {
- ntstatus = nt_group_del_member_byname(grp, args->member);
- } else {
- ntstatus = NT_STATUS_NO_SUCH_GROUP;
- }
- nt_group_putinfo(grp);
-
- /* Encode the result and return */
- if ((rbuf = smb_dr_encode_common(SMB_DR_OP_SUCCESS, &ntstatus,
- xdr_uint32_t, rbufsize)) == NULL) {
- *err = SMB_DR_OP_ERR_ENCODE;
- *rbufsize = 0;
- }
-
- free(args);
- return (rbuf);
-}
-
-/*ARGSUSED*/
-static char *
-smb_dop_group_count(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err)
-{
- char *rbuf = NULL;
- int num = 0;
-
- *err = SMB_DR_OP_SUCCESS;
- *rbufsize = 0;
-
- num = nt_group_num_groups();
-
- /* Encode the result and return */
- if ((rbuf = smb_dr_encode_common(SMB_DR_OP_SUCCESS, &num,
- xdr_uint32_t, rbufsize)) == NULL) {
- *err = SMB_DR_OP_ERR_ENCODE;
- *rbufsize = 0;
- }
- return (rbuf);
-}
-
-/*ARGSUSED*/
-static char *
-smb_dop_group_cachesize(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err)
-{
- char *rbuf = NULL;
- int num = 0;
-
- *err = SMB_DR_OP_SUCCESS;
- *rbufsize = 0;
-
- num = nt_group_cache_size();
-
- /* Encode the result and return */
- if ((rbuf = smb_dr_encode_common(SMB_DR_OP_SUCCESS, &num,
- xdr_uint32_t, rbufsize)) == NULL) {
- *err = SMB_DR_OP_ERR_ENCODE;
- *rbufsize = 0;
- }
- return (rbuf);
-}
-
/*ARGSUSED*/
static char *
-smb_dop_group_modify(char *argp, size_t arg_size,
+smb_dop_lookup_name(char *argp, size_t arg_size,
door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err)
{
char *rbuf = NULL;
- ntgrp_dr_arg_t *args;
- nt_group_t *grp = NULL;
- uint32_t ntstatus = NT_STATUS_UNSUCCESSFUL;
+ char *name = NULL;
+ uint32_t status;
+ nt_sid_t *sid;
+ uint16_t sid_type;
+ char strsid[NT_SID_FMTBUF_SIZE];
+ char strres[NT_SID_FMTBUF_SIZE];
*err = SMB_DR_OP_SUCCESS;
*rbufsize = 0;
/* Decode */
- if ((args = (ntgrp_dr_arg_t *)malloc(sizeof (ntgrp_dr_arg_t))) == 0) {
- syslog(LOG_ERR,
- "smb_dop_group_modify: cannot allocate memory");
- *err = SMB_DR_OP_ERR;
- return (NULL);
- }
- bzero(args, sizeof (ntgrp_dr_arg_t));
- if (smb_dr_decode_common(argp, arg_size,
- xdr_ntgrp_dr_arg_t, args) != 0) {
- free(args);
- *err = SMB_DR_OP_ERR_DECODE;
- return (NULL);
- }
-
- grp = nt_group_getinfo(args->gname, RWLOCK_WRITER);
- if (grp) {
- if (!args->desc)
- args->desc = grp->comment;
- ntstatus = nt_group_modify(args->gname,
- args->newgname, args->desc);
- } else {
- ntstatus = NT_STATUS_NO_SUCH_GROUP;
- }
- nt_group_putinfo(grp);
-
- /* Encode the result and return */
- if ((rbuf = smb_dr_encode_common(SMB_DR_OP_SUCCESS, &ntstatus,
- xdr_uint32_t, rbufsize)) == NULL) {
- *err = SMB_DR_OP_ERR_ENCODE;
- *rbufsize = 0;
- }
- free(args);
- return (rbuf);
-}
-
-/*ARGSUSED*/
-static char *
-smb_dop_group_priv_num(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err)
-{
- char *rbuf = NULL;
- int num = 0;
-
- *err = SMB_DR_OP_SUCCESS;
- *rbufsize = 0;
-
- num = smb_priv_presentable_num();
-
- /* Encode the result and return */
- if ((rbuf = smb_dr_encode_common(SMB_DR_OP_SUCCESS, &num,
- xdr_uint32_t, rbufsize)) == NULL) {
- *err = SMB_DR_OP_ERR_ENCODE;
- *rbufsize = 0;
- }
-
- return (rbuf);
-}
-
-/*ARGSUSED*/
-static char *
-smb_dop_group_priv_list(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err)
-{
- char *rbuf = NULL;
- int num = 0, i, len = 0;
- uint32_t *ids = NULL;
- smb_privinfo_t *priv = NULL;
- ntpriv_list_t *list;
-
- *err = SMB_DR_OP_SUCCESS;
- *rbufsize = 0;
-
- num = smb_priv_presentable_num();
- if (num > 0) {
- len = sizeof (int) + (num * sizeof (privs_t *));
- if ((ids = malloc(num * sizeof (uint32_t))) == 0) {
- syslog(LOG_ERR, "smb_dop_group_priv_list:"
- "cannot allocate memory");
- *err = SMB_DR_OP_ERR;
- return (NULL);
- }
-
- if ((list = (ntpriv_list_t *)malloc(len)) == 0) {
- syslog(LOG_ERR, "smb_dop_group_priv_list:"
- "cannot allocate memory");
- *err = SMB_DR_OP_ERR;
- free(ids);
- return (NULL);
- }
-
- list->cnt = num;
- (void) smb_priv_presentable_ids(ids, num);
- for (i = 0; i < num; i++) {
- if ((list->privs[i] = malloc(sizeof (ntpriv_t))) == 0) {
- *err = SMB_DR_OP_ERR;
- free(ids);
- smb_group_free_privlist(list, 1);
- return (NULL);
- }
- bzero(list->privs[i], sizeof (ntpriv_t));
- priv = smb_priv_getbyvalue(ids[i]);
- list->privs[i]->id = priv->id;
- list->privs[i]->name = strdup(priv->name);
- }
- free(ids);
- }
-
- if ((rbuf = smb_dr_encode_grp_privlist(SMB_DR_OP_SUCCESS, list,
- rbufsize)) == NULL) {
- *err = SMB_DR_OP_ERR_ENCODE;
- *rbufsize = 0;
- }
-
- smb_group_free_privlist(list, 1);
-
- return (rbuf);
-}
-
-/*ARGSUSED*/
-static char *
-smb_dop_group_priv_get(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err)
-{
- char *rbuf = NULL;
- ntgrp_dr_arg_t *args;
- uint32_t priv_attr;
- nt_group_t *grp;
- uint32_t retval;
-
- *err = SMB_DR_OP_SUCCESS;
- *rbufsize = 0;
-
- /* Decode */
- if ((args = (ntgrp_dr_arg_t *)malloc(sizeof (ntgrp_dr_arg_t))) == 0) {
- syslog(LOG_ERR,
- "smb_dop_group_priv_get: cannot allocate memory");
- *err = SMB_DR_OP_ERR;
- return (NULL);
- }
- bzero(args, sizeof (ntgrp_dr_arg_t));
- if (smb_dr_decode_common(argp, arg_size,
- xdr_ntgrp_dr_arg_t, args) != 0) {
- free(args);
- *err = SMB_DR_OP_ERR_DECODE;
- return (NULL);
- }
-
- grp = nt_group_getinfo(args->gname, RWLOCK_READER);
- if (grp) {
- priv_attr = nt_group_getpriv(grp, args->privid);
- retval = priv_attr;
- } else {
- retval = NT_STATUS_NO_SUCH_GROUP;
- *err = SMB_DR_OP_ERR;
- }
- nt_group_putinfo(grp);
-
- /* Encode the result and return */
- if ((rbuf = smb_dr_encode_common(SMB_DR_OP_SUCCESS, &retval,
- xdr_uint32_t, rbufsize)) == NULL) {
- *err = SMB_DR_OP_ERR_ENCODE;
- *rbufsize = 0;
- }
- free(args);
- return (rbuf);
-}
-
-/*ARGSUSED*/
-static char *
-smb_dop_group_priv_set(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err)
-{
- char *rbuf = NULL;
- ntgrp_dr_arg_t *args;
- uint32_t ntstatus = NT_STATUS_UNSUCCESSFUL;
- nt_group_t *grp;
-
- *err = SMB_DR_OP_SUCCESS;
- *rbufsize = 0;
-
- /* Decode */
- if ((args = (ntgrp_dr_arg_t *)malloc(sizeof (ntgrp_dr_arg_t))) == 0) {
- syslog(LOG_ERR,
- "smb_dop_group_priv_set: cannot allocate memory");
- *err = SMB_DR_OP_ERR;
- return (NULL);
- }
- bzero(args, sizeof (ntgrp_dr_arg_t));
- if (smb_dr_decode_common(argp, arg_size,
- xdr_ntgrp_dr_arg_t, args) != 0) {
- free(args);
+ if ((name = smb_dr_decode_string(argp, arg_size)) == 0) {
*err = SMB_DR_OP_ERR_DECODE;
return (NULL);
}
- grp = nt_group_getinfo(args->gname, RWLOCK_WRITER);
- if (grp) {
- ntstatus = nt_group_setpriv(grp,
- args->privid, args->priv_attr);
- } else {
- ntstatus = NT_STATUS_NO_SUCH_GROUP;
- *err = SMB_DR_OP_ERR;
+ *strres = '\0';
+ sid_type = SidTypeUnknown;
+ status = mlsvc_lookup_name(name, &sid, &sid_type);
+ xdr_free(xdr_string, (char *)&name);
+ if (status == NT_STATUS_SUCCESS) {
+ /* pack the SID and its type in a string */
+ nt_sid_format2(sid, strsid);
+ (void) snprintf(strres, sizeof (strres), "%d-%s",
+ sid_type, strsid);
+ free(sid);
}
- nt_group_putinfo(grp);
/* Encode the result and return */
- if ((rbuf = smb_dr_encode_common(SMB_DR_OP_SUCCESS, &ntstatus,
- xdr_uint32_t, rbufsize)) == NULL) {
- *err = SMB_DR_OP_ERR_ENCODE;
- *rbufsize = 0;
- }
-
- free(args);
- return (rbuf);
-}
-
-/*ARGSUSED*/
-static char *
-smb_dop_group_list(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err)
-{
- char *rbuf = NULL, *scope = NULL;
- ntgrp_dr_arg_t *args;
- ntgrp_list_t list;
-
- *err = SMB_DR_OP_SUCCESS;
- *rbufsize = 0;
-
- /* Decode */
- if ((args = (ntgrp_dr_arg_t *)malloc(sizeof (ntgrp_dr_arg_t))) == 0) {
- syslog(LOG_ERR,
- "smb_dop_group_list: cannot allocate memory");
- *err = SMB_DR_OP_ERR;
- return (NULL);
- }
- bzero(args, sizeof (ntgrp_dr_arg_t));
- if (smb_dr_decode_common(argp, arg_size,
- xdr_ntgrp_dr_arg_t, args) != 0) {
- free(args);
- *err = SMB_DR_OP_ERR_DECODE;
- return (NULL);
- }
-
- bzero(&list, sizeof (ntgrp_list_t));
- scope = args->scope;
- if (scope == NULL)
- scope = "*";
- nt_group_list(args->offset, scope, &list);
-
- /* Encode the result and return */
- if ((rbuf = smb_dr_encode_grp_list(SMB_DR_OP_SUCCESS, &list,
+ if ((rbuf = smb_dr_encode_string(SMB_DR_OP_SUCCESS, strres,
rbufsize)) == NULL) {
*err = SMB_DR_OP_ERR_ENCODE;
*rbufsize = 0;
}
- smb_group_free_list(&list, 1);
- free(args);
return (rbuf);
}
/*ARGSUSED*/
static char *
-smb_dop_group_member_list(char *argp, size_t arg_size,
+smb_dop_lookup_sid(char *argp, size_t arg_size,
door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err)
{
char *rbuf = NULL;
- ntgrp_dr_arg_t *args;
- nt_group_t *grp = NULL;
- ntgrp_member_list_t members;
+ char *name = NULL;
+ uint32_t status;
+ nt_sid_t *sid;
+ char *strsid;
*err = SMB_DR_OP_SUCCESS;
*rbufsize = 0;
/* Decode */
- if ((args = (ntgrp_dr_arg_t *)malloc(sizeof (ntgrp_dr_arg_t))) == 0) {
- syslog(LOG_ERR,
- "smb_group_dr_listmember: cannot allocate memory");
- *err = SMB_DR_OP_ERR;
- return (NULL);
- }
- bzero(args, sizeof (ntgrp_dr_arg_t));
- if (smb_dr_decode_common(argp, arg_size,
- xdr_ntgrp_dr_arg_t, args) != 0) {
- free(args);
+ if ((strsid = smb_dr_decode_string(argp, arg_size)) == 0) {
*err = SMB_DR_OP_ERR_DECODE;
return (NULL);
}
- bzero(&members, sizeof (ntgrp_member_list_t));
- bzero(&members.members, SMB_GROUP_PER_LIST * sizeof (members_list));
- if ((!args->gname) || (strlen(args->gname) == 0)) {
- free(args);
- *err = SMB_DR_OP_ERR;
- return (NULL);
- }
- grp = nt_group_getinfo(args->gname, RWLOCK_READER);
- if (grp) {
- (void) nt_group_member_list(args->offset, grp, &members);
- }
- nt_group_putinfo(grp);
+ sid = nt_sid_strtosid(strsid);
+ status = mlsvc_lookup_sid(sid, &name);
+ free(sid);
+ if (status != NT_STATUS_SUCCESS)
+ name = strsid;
/* Encode the result and return */
- if ((rbuf = smb_dr_encode_grp_memberlist(SMB_DR_OP_SUCCESS, &members,
+ if ((rbuf = smb_dr_encode_string(SMB_DR_OP_SUCCESS, name,
rbufsize)) == NULL) {
*err = SMB_DR_OP_ERR_ENCODE;
*rbufsize = 0;
}
- smb_group_free_memberlist(&members, 1);
- free(args);
- return (rbuf);
-}
-
-/*ARGSUSED*/
-static char *
-smb_dop_group_member_count(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err)
-{
- char *rbuf = NULL, *gname = NULL;
- ntgrp_dr_arg_t *enc_args;
- nt_group_t *grp = NULL;
- int num = 0;
- uint32_t ntstatus = NT_STATUS_UNSUCCESSFUL;
-
- *err = SMB_DR_OP_SUCCESS;
- *rbufsize = 0;
-
- /* Decode */
- if ((gname = smb_dr_decode_string(argp, arg_size)) == 0) {
- *err = SMB_DR_OP_ERR_DECODE;
- return (NULL);
- }
-
- grp = nt_group_getinfo(gname, RWLOCK_READER);
- if (grp) {
- num = nt_group_num_members(grp);
- ntstatus = NT_STATUS_SUCCESS;
- } else {
- ntstatus = NT_STATUS_NO_SUCH_GROUP;
- }
- nt_group_putinfo(grp);
+ if (status == NT_STATUS_SUCCESS)
+ free(name);
- /* Encode the result and return */
- if ((enc_args = (ntgrp_dr_arg_t *)
- malloc(sizeof (ntgrp_dr_arg_t))) == 0) {
- syslog(LOG_ERR,
- "smb_dop_group_member_count: cannot allocate memory");
- *err = SMB_DR_OP_ERR;
- return (NULL);
- }
- bzero(enc_args, sizeof (ntgrp_dr_arg_t));
- enc_args->count = num;
- enc_args->ntstatus = ntstatus;
- if ((rbuf = smb_dr_encode_common(SMB_DR_OP_SUCCESS, enc_args,
- xdr_ntgrp_dr_arg_t, rbufsize)) == NULL) {
- *err = SMB_DR_OP_ERR_ENCODE;
- *rbufsize = 0;
- }
- free(enc_args);
+ xdr_free(xdr_string, (char *)&strsid);
return (rbuf);
}
diff --git a/usr/src/cmd/smbsrv/smbd/smbd_door_server.c b/usr/src/cmd/smbsrv/smbd/smbd_door_server.c
index ebdc051b79..e70b7f124f 100644
--- a/usr/src/cmd/smbsrv/smbd/smbd_door_server.c
+++ b/usr/src/cmd/smbsrv/smbd/smbd_door_server.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -33,7 +33,6 @@
#include <errno.h>
#include <syslog.h>
#include <unistd.h>
-#include <varargs.h>
#include <stdio.h>
#include <synch.h>
#include <string.h>
@@ -179,25 +178,17 @@ smb_srv_door(void *cookie, char *ptr, size_t size, door_desc_t *dp,
switch (req_type) {
case SMBD_DOOR_PARAM_GET: {
smb_cfg_id_t id;
- char *value = NULL;
- char *empty = "";
+ char value[MAX_VALUE_BUFLEN];
id = smb_dr_get_uint32(dec_ctx);
dec_status = smb_dr_decode_finish(dec_ctx);
- if (dec_status != 0) {
+ if (dec_status != 0)
goto decode_error;
- }
- smb_config_rdlock();
- value = smb_config_getstr(id);
+ (void) smb_config_getstr(id, value, sizeof (value));
smb_dr_put_int32(enc_ctx, SMBD_DOOR_SRV_SUCCESS);
-
- if (value)
- smb_dr_put_string(enc_ctx, value);
- else
- smb_dr_put_string(enc_ctx, empty);
- smb_config_unlock();
+ smb_dr_put_string(enc_ctx, value);
break;
}
@@ -214,13 +205,10 @@ smb_srv_door(void *cookie, char *ptr, size_t size, door_desc_t *dp,
goto decode_error;
}
- smb_config_wrlock();
- if (smb_config_set(id, value) == 0) {
+ if (smb_config_setstr(id, value) == SMBD_SMF_OK)
smb_dr_put_int32(enc_ctx, SMBD_DOOR_SRV_SUCCESS);
- } else {
+ else
smb_dr_put_int32(enc_ctx, SMBD_DOOR_SRV_ERROR);
- }
- smb_config_unlock();
smb_dr_free_string(value);
break;
}
@@ -262,20 +250,6 @@ smb_srv_door(void *cookie, char *ptr, size_t size, door_desc_t *dp,
smb_dr_put_int32(enc_ctx, rc);
break;
- case SMBD_DOOR_ADS_DOMAIN_CHANGED:
- domain = smb_dr_get_string(dec_ctx);
- dec_status = smb_dr_decode_finish(dec_ctx);
- if (dec_status != 0) {
- smb_dr_free_string(domain);
- goto decode_error;
- }
-
- rc = ads_domain_change_notify_handler(domain);
- smb_dr_put_int32(enc_ctx, SMBD_DOOR_SRV_SUCCESS);
- smb_dr_put_int32(enc_ctx, rc);
- smb_dr_free_string(domain);
- break;
-
default:
goto decode_error;
}
diff --git a/usr/src/cmd/smbsrv/smbd/smbd_join.c b/usr/src/cmd/smbsrv/smbd/smbd_join.c
index 90e4059abd..5e7d76396b 100644
--- a/usr/src/cmd/smbsrv/smbd/smbd_join.c
+++ b/usr/src/cmd/smbsrv/smbd/smbd_join.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -109,12 +109,20 @@ smbd_join(smb_joininfo_t *info)
unsigned char passwd_hash[SMBAUTH_HASH_SZ];
char plain_passwd[PASS_LEN + 1];
char plain_user[PASS_LEN + 1];
+ char nbt_domain[SMB_PI_MAX_DOMAIN];
+ char fqdn[MAXHOSTNAMELEN];
if (info->mode == SMB_SECMODE_WORKGRP) {
- smb_config_wrlock();
+ if (smb_config_get_secmode() == SMB_SECMODE_DOMAIN) {
+ if (ads_domain_change_cleanup("") != 0) {
+ syslog(LOG_ERR, "smbd: unable to remove the"
+ " old keys from the Kerberos keytab. "
+ "Please remove the old keys for your "
+ "host principal.");
+ }
+ }
(void) smb_config_set_secmode(info->mode);
- (void) smb_config_set(SMB_CI_DOMAIN_NAME, info->domain_name);
- smb_config_unlock();
+ (void) smb_config_setstr(SMB_CI_DOMAIN_NAME, info->domain_name);
return (NT_STATUS_SUCCESS);
}
@@ -124,10 +132,25 @@ smbd_join(smb_joininfo_t *info)
* will ensure that we don't attempt a NETLOGON_SAMLOGON
* when attempting to find the PDC.
*/
- smb_set_domain_member(0);
+ (void) smb_config_setbool(SMB_CI_DOMAIN_MEMB, B_FALSE);
+
+ (void) strlcpy(plain_user, info->domain_username, sizeof (plain_user));
+ (void) strlcpy(plain_passwd, info->domain_passwd,
+ sizeof (plain_passwd));
+ (void) smb_resolve_netbiosname(info->domain_name, nbt_domain,
+ sizeof (nbt_domain));
- (void) strcpy(plain_user, info->domain_username);
- (void) strcpy(plain_passwd, info->domain_passwd);
+ if (smb_resolve_fqdn(info->domain_name, fqdn, sizeof (fqdn)) != 1) {
+ syslog(LOG_ERR, "smbd: fully-qualified domain name is unknown");
+ return (NT_STATUS_INVALID_PARAMETER);
+ }
+
+ if (ads_domain_change_cleanup(fqdn)) {
+ syslog(LOG_ERR, "smbd: unable to remove the old keys from the"
+ " Kerberos keytab. Please remove the old keys for your "
+ "host principal.");
+ return (NT_STATUS_INTERNAL_ERROR);
+ }
if (smb_auth_ntlm_hash(plain_passwd, passwd_hash) != SMBAUTH_SUCCESS) {
status = NT_STATUS_INTERNAL_ERROR;
@@ -138,7 +161,7 @@ smbd_join(smb_joininfo_t *info)
smbrdr_ipc_set(plain_user, passwd_hash);
- if (locate_resource_pdc(info->domain_name)) {
+ if (locate_resource_pdc(nbt_domain)) {
if ((pi = smb_getdomaininfo(0)) == 0) {
status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
syslog(LOG_ERR, "smbd: could not get domain controller"
@@ -155,11 +178,9 @@ smbd_join(smb_joininfo_t *info)
plain_user, plain_passwd);
if (status == NT_STATUS_SUCCESS) {
- smb_config_wrlock();
(void) smb_config_set_secmode(SMB_SECMODE_DOMAIN);
- (void) smb_config_set(SMB_CI_DOMAIN_NAME,
+ (void) smb_config_setstr(SMB_CI_DOMAIN_NAME,
info->domain_name);
- smb_config_unlock();
smbrdr_ipc_commit();
return (status);
}
@@ -296,8 +317,8 @@ smb_netlogon_dc_browser(void *arg)
SMB_PI_MAX_DOMAIN);
smb_setdomaininfo(NULL, NULL, 0);
- if (msdcs_lookup_ads() == 0) {
- if (smb_is_domain_member())
+ if (msdcs_lookup_ads(resource_domain) == 0) {
+ if (smb_config_getbool(SMB_CI_DOMAIN_MEMB))
protocol = NETLOGON_PROTO_SAMLOGON;
else
protocol = NETLOGON_PROTO_NETLOGON;
diff --git a/usr/src/cmd/smbsrv/smbd/smbd_main.c b/usr/src/cmd/smbsrv/smbd/smbd_main.c
index d174aeb18e..ca10cabb19 100644
--- a/usr/src/cmd/smbsrv/smbd/smbd_main.c
+++ b/usr/src/cmd/smbsrv/smbd/smbd_main.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -333,7 +333,6 @@ smbd_service_init(void)
int door_id;
int rc;
- int ddns_enabled;
uint32_t mode;
char resource_domain[SMB_PI_MAX_DOMAIN];
int i;
@@ -364,35 +363,28 @@ smbd_service_init(void)
return (1);
}
- /*
- * Need to load the configuration data prior to getting the
- * interface information.
- */
- if (smb_config_load() != 0) {
- smbd_report("failed to load configuration data");
+ (void) smb_nicmon_start();
+ if (dns_msgid_init() != 0) {
+ smbd_report("DNS message id initialization failed");
return (1);
}
- smb_resolver_init();
- (void) smb_nicmon_start();
-
smbrdr_init();
- smb_netbios_start();
+ if (smb_netbios_start() != 0)
+ smbd_report("NetBIOS services failed to start");
+ else
+ smbd_report("NetBIOS services started");
+
if (smb_netlogon_init() != 0) {
smbd_report("netlogon initialization failed");
return (1);
}
- smb_config_rdlock();
- resource_domain[0] = '\0';
- (void) strlcpy(resource_domain,
- smb_config_getstr(SMB_CI_DOMAIN_NAME), SMB_PI_MAX_DOMAIN);
+ (void) smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN);
(void) utf8_strupr(resource_domain);
- smb_config_unlock();
-
- mode = smb_get_security_mode();
+ mode = smb_config_get_secmode();
if (mode == SMB_SECMODE_DOMAIN)
(void) locate_resource_pdc(resource_domain);
@@ -403,21 +395,14 @@ smbd_service_init(void)
}
if ((rc = nt_domain_init(resource_domain, mode)) != 0) {
- if (rc == SMB_DOMAIN_NOMACHINE_SID)
- smbd_report("No Security Identifier (SID) has been "
- "generated for this system.\n"
- "Check idmap service configuration.");
-
- if (rc == SMB_DOMAIN_NODOMAIN_SID) {
- /* Get the domain sid from domain controller */
- if ((rc = lsa_query_primary_domain_info()) != 0)
- smbd_report("Failed to get the Security "
- "Identifier (SID) of domain %s",
- resource_domain);
- }
- return (rc);
+ if (rc == SMB_DOMAIN_NOMACHINE_SID) {
+ smbd_report(
+ "no machine SID: check idmap configuration");
+ return (rc);
+ }
}
+ ads_init();
if ((rc = mlsvc_init()) != 0) {
smbd_report("msrpc initialization failed");
return (rc);
@@ -436,12 +421,8 @@ smbd_service_init(void)
return (rc);
/* Call dyndns update - Just in case its configured to refresh DNS */
- smb_config_rdlock();
- ddns_enabled = smb_config_getyorn(SMB_CI_DYNDNS_ENABLE);
- smb_config_unlock();
- if (ddns_enabled) {
+ if (smb_config_getbool(SMB_CI_DYNDNS_ENABLE))
(void) dyndns_update();
- }
if ((rc = smbd_kernel_bind()) != 0)
smbd_report("kernel bind error: %s", strerror(errno));
@@ -457,6 +438,7 @@ smbd_service_init(void)
smbd_report("winpipe ioctl: %s", strerror(errno));
}
+ (void) smb_lgrp_start();
return (lmshare_start());
}
@@ -484,8 +466,8 @@ smbd_service_fini(void)
smb_lmshrd_srv_stop();
lmshare_stop();
smb_nicmon_stop();
- smb_resolver_close();
smb_idmap_stop();
+ smb_lgrp_stop();
smbd_remove_ccache();
}
@@ -551,7 +533,7 @@ smbd_refresh_monitor(void *arg)
* We've been woken up by a refresh event so go do
* what is necessary.
*/
- (void) smb_config_load();
+ ads_refresh();
smb_nic_build_info();
(void) smb_netbios_name_reconfig();
(void) smb_browser_config();
@@ -705,7 +687,7 @@ smbd_setup_options(int argc, char *argv[])
if ((grp = getgrnam("sys")) != NULL)
smbd.s_gid = grp->gr_gid;
- smbd.s_fg = smb_get_fg_flag();
+ smbd.s_fg = smb_config_get_fg_flag();
while ((c = getopt(argc, argv, ":f")) != -1) {
switch (c) {
diff --git a/usr/src/cmd/smbsrv/smbd/smbd_mlsvc_doorsvc.c b/usr/src/cmd/smbsrv/smbd/smbd_mlsvc_doorsvc.c
index 3ce7927215..986cef687c 100755
--- a/usr/src/cmd/smbsrv/smbd/smbd_mlsvc_doorsvc.c
+++ b/usr/src/cmd/smbsrv/smbd/smbd_mlsvc_doorsvc.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -209,8 +209,6 @@ smb_winpipe_request(void *cookie, char *argp, size_t arg_size,
inpipe = context->inpipe;
(void) strcpy(inpipe->sp_pipename, tmp_pipe.sp_pipename);
- inpipe->sp_datalen = tmp_pipe.sp_datalen;
- bcopy(bufp, inpipe->sp_data, inpipe->sp_datalen);
outpipe = context->outpipe;
(void) strcpy(outpipe->sp_pipename, "OUTPIPE");
@@ -227,7 +225,7 @@ smb_winpipe_request(void *cookie, char *argp, size_t arg_size,
if (context == NULL)
goto zero_exit;
- context->inpipe->sp_datalen = context->inlen;
+ inpipe->sp_datalen = context->inlen;
context->inlen = 0;
context->outcookie = 0;
@@ -235,6 +233,9 @@ smb_winpipe_request(void *cookie, char *argp, size_t arg_size,
}
if (mdhin.md_call_type == SMB_RPC_TRANSACT) {
+ bcopy(bufp, inpipe->sp_data, tmp_pipe.sp_datalen);
+ inpipe->sp_datalen = tmp_pipe.sp_datalen;
+
context = mlrpc_process(inpipe->sp_pipeid, user_ctx);
if (context == NULL)
goto zero_exit;
@@ -246,13 +247,14 @@ smb_winpipe_request(void *cookie, char *argp, size_t arg_size,
}
if (mdhin.md_call_type == SMB_RPC_WRITE) {
- bcopy(inpipe->sp_data, context->inpipe->sp_data +
- context->inlen, inpipe->sp_datalen);
/*
- * if we get another RPC_WRITE then we need to append
+ * Append write data to the stream.
*/
- context->inlen += inpipe->sp_datalen;
- context->inpipe->sp_datalen = context->inlen;
+ bcopy(bufp, inpipe->sp_data + context->inlen,
+ tmp_pipe.sp_datalen);
+ inpipe->sp_datalen += tmp_pipe.sp_datalen;
+ context->inlen += tmp_pipe.sp_datalen;
+
goto zero_exit;
}
diff --git a/usr/src/cmd/smbsrv/smbd/smbd_nicmon.c b/usr/src/cmd/smbsrv/smbd/smbd_nicmon.c
index e13f7c457d..148f4800d1 100644
--- a/usr/src/cmd/smbsrv/smbd/smbd_nicmon.c
+++ b/usr/src/cmd/smbsrv/smbd/smbd_nicmon.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -179,11 +179,9 @@ smb_setup_eventpipe(int *read_pipe, int *write_pipe)
static void
smb_process_nic_change()
{
- int ddns_enabled;
+ boolean_t ddns_enabled;
- smb_config_rdlock();
- ddns_enabled = smb_config_getyorn(SMB_CI_DYNDNS_ENABLE);
- smb_config_unlock();
+ ddns_enabled = smb_config_getbool(SMB_CI_DYNDNS_ENABLE);
/* Clear rev zone before creating if list */
if (ddns_enabled) {
diff --git a/usr/src/lib/Makefile b/usr/src/lib/Makefile
index 0aec8857f3..02d7c65ca7 100644
--- a/usr/src/lib/Makefile
+++ b/usr/src/lib/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -553,7 +553,7 @@ libshare: libscf libzfs libuuid libfsmgt libsecdb
libexacct/demo: libexacct libproject libsocket libnsl
libtsalarm: libpcp
smbsrv: libsocket libnsl libmd libxnet libpthread librt \
- libshare libidmap pkcs11
+ libshare libidmap pkcs11 libsqlite
libvscan: libscf
#
diff --git a/usr/src/lib/libshare/common/libshare.c b/usr/src/lib/libshare/common/libshare.c
index 5716ef931c..74bb0af7e9 100644
--- a/usr/src/lib/libshare/common/libshare.c
+++ b/usr/src/lib/libshare/common/libshare.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -217,15 +217,6 @@ sa_errorstr(int err)
case SA_PATH_IS_PARENTDIR:
ret = dgettext(TEXT_DOMAIN, "path is parent of a share");
break;
- case SA_KRB_KEYTAB_ERR:
- ret = dgettext(TEXT_DOMAIN, "unable to remove the old keys"
- " from the Kerberos keytab. Please manually remove"
- " the old keys for your host principal prior to setting"
- " the ads_domain property");
- break;
- case SA_NO_SERVICE:
- ret = dgettext(TEXT_DOMAIN, "service is not running");
- break;
default:
(void) snprintf(errstr, sizeof (errstr),
dgettext(TEXT_DOMAIN, "unknown %d"), err);
diff --git a/usr/src/lib/libshare/common/libshare.h b/usr/src/lib/libshare/common/libshare.h
index af6e2db2f8..b45b747d9a 100644
--- a/usr/src/lib/libshare/common/libshare.h
+++ b/usr/src/lib/libshare/common/libshare.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -85,8 +85,6 @@ typedef void *sa_handle_t; /* opaque handle to access core functions */
#define SA_MULTIPLE_ERROR 26 /* multiple protocols reported error */
#define SA_PATH_IS_SUBDIR 27 /* check_path found path is subdir */
#define SA_PATH_IS_PARENTDIR 28 /* check_path found path is parent */
-#define SA_KRB_KEYTAB_ERR 29 /* fail to delete old keytab entries */
-#define SA_NO_SERVICE 30 /* service isn't running */
/* API Initialization */
#define SA_INIT_SHARE_API 0x0001 /* init share specific interface */
diff --git a/usr/src/lib/libshare/smb/libshare_smb.c b/usr/src/lib/libshare/smb/libshare_smb.c
index 9aa98e9a37..0a3ed7535b 100644
--- a/usr/src/lib/libshare/smb/libshare_smb.c
+++ b/usr/src/lib/libshare/smb/libshare_smb.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -77,18 +77,21 @@ static int string_length_check_validator(int, char *);
static int true_false_validator(int, char *);
static int ip_address_validator_empty_ok(int, char *);
static int ip_address_csv_list_validator_empty_ok(int, char *);
-static int ipc_mode_validator(int, char *);
static int path_validator(int, char *);
static int smb_enable_resource(sa_resource_t);
static int smb_disable_resource(sa_resource_t);
static uint64_t smb_share_features(void);
static int smb_list_transient(sa_handle_t);
-static int smb_domain_change_event(char *new_domain);
+
+extern void lmshrd_door_close(void);
/* size of basic format allocation */
#define OPT_CHUNK 1024
+/* size of string for types - big enough to hold "dependency" */
+#define SCFTYPE_LEN 32
+
/*
* Indexes of entries in smb_proto_options table.
* Changes to smb_proto_options table may require
@@ -245,6 +248,50 @@ smb_isonline(void)
}
/*
+ * smb_isdisabled()
+ *
+ * Determine if the SMF service instance is in the disabled state or
+ * not. A number of operations depend on this state.
+ */
+static boolean_t
+smb_isdisabled(void)
+{
+ char *str;
+ boolean_t ret = B_FALSE;
+
+ if ((str = smf_get_state(SMBD_DEFAULT_INSTANCE_FMRI)) != NULL) {
+ ret = (strcmp(str, SCF_STATE_STRING_DISABLED) == 0);
+ free(str);
+ }
+ return (ret);
+}
+
+/*
+ * smb_isautoenable()
+ *
+ * Determine if the SMF service instance auto_enabled set or not. A
+ * number of operations depend on this state. The property not being
+ * set or being set to true means autoenable. Only being set to false
+ * is not autoenabled.
+ */
+static boolean_t
+smb_isautoenable(void)
+{
+ boolean_t ret = B_TRUE;
+ scf_simple_prop_t *prop;
+ uint8_t *retstr;
+
+ prop = scf_simple_prop_get(NULL, SMBD_DEFAULT_INSTANCE_FMRI,
+ "application", "auto_enable");
+ if (prop != NULL) {
+ retstr = scf_simple_prop_next_boolean(prop);
+ ret = *retstr != 0;
+ scf_simple_prop_free(prop);
+ }
+ return (ret);
+}
+
+/*
* smb_enable_share tells the implementation that it is to enable the share.
* This entails converting the path and options into the appropriate ioctl
* calls. It is assumed that all error checking of paths, etc. were
@@ -273,7 +320,12 @@ smb_enable_share(sa_share_t share)
if (path == NULL)
return (SA_NO_SUCH_PATH);
+ /*
+ * If administratively disabled, don't try to start anything.
+ */
online = smb_isonline();
+ if (!online && !smb_isautoenable() && smb_isdisabled())
+ goto done;
iszfs = sa_path_is_zfs(path);
@@ -374,11 +426,28 @@ smb_enable_resource(sa_resource_t resource)
sa_optionset_t opts;
sa_share_t share;
lmshare_info_t si;
- int ret;
+ int ret = SA_OK;
+ int err;
+ boolean_t isonline;
share = sa_get_resource_parent(resource);
if (share == NULL)
return (SA_NO_SUCH_PATH);
+
+ /*
+ * If administratively disabled, don't try to start anything.
+ */
+ isonline = smb_isonline();
+ if (!isonline && !smb_isautoenable() && smb_isdisabled())
+ goto done;
+
+ if (!isonline)
+ ret = smb_enable_service();
+ if (!smb_isonline()) {
+ ret = SA_OK;
+ goto done;
+ }
+
path = sa_get_share_attr(share, "path");
if (path == NULL)
return (SA_SYSTEM_ERR);
@@ -388,21 +457,25 @@ smb_enable_resource(sa_resource_t resource)
return (SA_NO_SUCH_RESOURCE);
}
- ret = smb_enable_service();
-
- if (!smb_isonline()) {
- ret = SA_OK;
- goto done;
- }
-
opts = sa_get_derived_optionset(resource, SMB_PROTOCOL_NAME, 1);
smb_build_lmshare_info(rname, path, opts, &si);
sa_free_attr_string(path);
sa_free_attr_string(rname);
sa_free_derived_optionset(opts);
- if (lmshrd_add(&si) != NERR_Success)
+
+ /*
+ * Attempt to add the share. Any error that occurs if it was
+ * online is an error but don't count NERR_DuplicateName if
+ * smb/server had to be brought online since bringing the
+ * service up will enable the share that was just added prior
+ * to the attempt to enable.
+ */
+
+ err = lmshrd_add(&si);
+ if (err == NERR_Success || !(!isonline && err == NERR_DuplicateName))
+ (void) sa_update_sharetab(share, "smb");
+ else
return (SA_NOT_SHARED);
- (void) sa_update_sharetab(share, "smb");
done:
return (ret);
@@ -670,85 +743,44 @@ smb_validate_property(sa_property_t property, sa_optionset_t parent)
*/
struct smb_proto_option_defs {
- char *name; /* display name -- remove protocol identifier */
int smb_index;
int32_t minval;
int32_t maxval; /* In case of length of string this should be max */
int (*validator)(int, char *);
int32_t refresh;
} smb_proto_options[] = {
- { SMB_CD_SYS_CMNT,
- SMB_CI_SYS_CMNT, 0, MAX_VALUE_BUFLEN,
- string_length_check_validator, SMB_REFRESH_REFRESH},
- { SMB_CD_MAX_WORKERS,
- SMB_CI_MAX_WORKERS, 64, 1024, range_check_validator,
- SMB_REFRESH_REFRESH},
- { SMB_CD_NBSCOPE,
- SMB_CI_NBSCOPE, 0, MAX_VALUE_BUFLEN,
- string_length_check_validator, SMB_REFRESH_REFRESH},
- { SMB_CD_RDR_IPCMODE,
- SMB_CI_RDR_IPCMODE, 0, 0, ipc_mode_validator, SMB_REFRESH_REFRESH},
- { SMB_CD_LM_LEVEL,
- SMB_CI_LM_LEVEL, 2, 5, range_check_validator, SMB_REFRESH_REFRESH},
- { SMB_CD_KEEPALIVE,
- SMB_CI_KEEPALIVE, 20, 5400, range_check_validator_zero_ok,
- SMB_REFRESH_REFRESH},
- { SMB_CD_WINS_SRV1,
- SMB_CI_WINS_SRV1, 0, MAX_VALUE_BUFLEN,
- ip_address_validator_empty_ok, SMB_REFRESH_REFRESH},
- { SMB_CD_WINS_SRV2,
- SMB_CI_WINS_SRV2, 0, MAX_VALUE_BUFLEN,
- ip_address_validator_empty_ok, SMB_REFRESH_REFRESH},
- { SMB_CD_WINS_EXCL,
- SMB_CI_WINS_EXCL, 0, MAX_VALUE_BUFLEN,
- ip_address_csv_list_validator_empty_ok, SMB_REFRESH_REFRESH},
- { SMB_CD_SIGNING_ENABLE,
- SMB_CI_SIGNING_ENABLE, 0, 0, true_false_validator,
- SMB_REFRESH_REFRESH},
- { SMB_CD_SIGNING_REQD,
- SMB_CI_SIGNING_REQD, 0, 0, true_false_validator,
- SMB_REFRESH_REFRESH},
- { SMB_CD_RESTRICT_ANON,
- SMB_CI_RESTRICT_ANON, 0, 0, true_false_validator,
- SMB_REFRESH_REFRESH},
- { SMB_CD_DOMAIN_SRV,
- SMB_CI_DOMAIN_SRV, 0, MAX_VALUE_BUFLEN,
- ip_address_validator_empty_ok, SMB_REFRESH_REFRESH},
- { SMB_CD_ADS_ENABLE,
- SMB_CI_ADS_ENABLE, 0, 0, true_false_validator, SMB_REFRESH_REFRESH},
- { SMB_CD_ADS_USER,
- SMB_CI_ADS_USER, 0, MAX_VALUE_BUFLEN,
- string_length_check_validator, SMB_REFRESH_REFRESH},
- { SMB_CD_ADS_USER_CONTAINER,
- SMB_CI_ADS_USER_CONTAINER, 0, MAX_VALUE_BUFLEN,
- string_length_check_validator, SMB_REFRESH_REFRESH},
- { SMB_CD_ADS_DOMAIN,
- SMB_CI_ADS_DOMAIN, 0, MAX_VALUE_BUFLEN,
- string_length_check_validator, SMB_REFRESH_REFRESH},
- { SMB_CD_ADS_PASSWD,
- SMB_CI_ADS_PASSWD, 0, MAX_VALUE_BUFLEN,
- string_length_check_validator, SMB_REFRESH_REFRESH},
- { SMB_CD_ADS_IPLOOKUP,
- SMB_CI_ADS_IPLOOKUP, 0, 0, true_false_validator,
- SMB_REFRESH_REFRESH},
- { SMB_CD_ADS_SITE,
- SMB_CI_ADS_SITE, 0, MAX_VALUE_BUFLEN,
- string_length_check_validator, SMB_REFRESH_REFRESH},
- { SMB_CD_DYNDNS_ENABLE,
- SMB_CI_DYNDNS_ENABLE, 0, 0, true_false_validator,
- SMB_REFRESH_REFRESH},
- { SMB_CD_DYNDNS_RETRY_SEC,
- SMB_CI_DYNDNS_RETRY_SEC, 0, 20, range_check_validator,
- SMB_REFRESH_REFRESH},
- { SMB_CD_DYNDNS_RETRY_COUNT,
- SMB_CI_DYNDNS_RETRY_COUNT, 3, 5, range_check_validator,
- SMB_REFRESH_REFRESH},
- { SMB_CD_AUTOHOME_MAP,
- SMB_CI_AUTOHOME_MAP, 0, MAX_VALUE_BUFLEN,
- path_validator},
- {NULL, -1, 0, 0, NULL}
+ { SMB_CI_SYS_CMNT, 0, MAX_VALUE_BUFLEN,
+ string_length_check_validator, SMB_REFRESH_REFRESH },
+ { SMB_CI_MAX_WORKERS, 64, 1024, range_check_validator,
+ SMB_REFRESH_REFRESH },
+ { SMB_CI_NBSCOPE, 0, MAX_VALUE_BUFLEN,
+ string_length_check_validator, 0 },
+ { SMB_CI_LM_LEVEL, 2, 5, range_check_validator, 0 },
+ { SMB_CI_KEEPALIVE, 20, 5400, range_check_validator_zero_ok,
+ SMB_REFRESH_REFRESH },
+ { SMB_CI_WINS_SRV1, 0, MAX_VALUE_BUFLEN,
+ ip_address_validator_empty_ok, SMB_REFRESH_REFRESH },
+ { SMB_CI_WINS_SRV2, 0, MAX_VALUE_BUFLEN,
+ ip_address_validator_empty_ok, SMB_REFRESH_REFRESH },
+ { SMB_CI_WINS_EXCL, 0, MAX_VALUE_BUFLEN,
+ ip_address_csv_list_validator_empty_ok, SMB_REFRESH_REFRESH },
+ { SMB_CI_SIGNING_ENABLE, 0, 0, true_false_validator,
+ SMB_REFRESH_REFRESH },
+ { SMB_CI_SIGNING_REQD, 0, 0, true_false_validator,
+ SMB_REFRESH_REFRESH },
+ { SMB_CI_RESTRICT_ANON, 0, 0, true_false_validator,
+ SMB_REFRESH_REFRESH },
+ { SMB_CI_DOMAIN_SRV, 0, MAX_VALUE_BUFLEN,
+ ip_address_validator_empty_ok, 0 },
+ { SMB_CI_ADS_SITE, 0, MAX_VALUE_BUFLEN,
+ string_length_check_validator, SMB_REFRESH_REFRESH },
+ { SMB_CI_DYNDNS_ENABLE, 0, 0, true_false_validator, 0 },
+ { SMB_CI_AUTOHOME_MAP, 0, MAX_VALUE_BUFLEN, path_validator, 0 },
};
+#define SMB_OPT_NUM \
+ (sizeof (smb_proto_options) / sizeof (smb_proto_options[0]))
+
/*
* Check the range of value as int range.
*/
@@ -884,22 +916,6 @@ ip_address_csv_list_validator_empty_ok(int index, char *value)
}
/*
- * Check IPC mode
- */
-/*ARGSUSED*/
-static int
-ipc_mode_validator(int index, char *value)
-{
- if (value == NULL)
- return (SA_BAD_VALUE);
- if (strcasecmp(value, "anon") == 0)
- return (SA_OK);
- if (strcasecmp(value, "auth") == 0)
- return (SA_OK);
- return (SA_BAD_VALUE);
-}
-
-/*
* Check path
*/
/*ARGSUSED*/
@@ -937,10 +953,14 @@ static int
findprotoopt(char *name)
{
int i;
- for (i = 0; smb_proto_options[i].name != NULL; i++) {
- if (strcasecmp(smb_proto_options[i].name, name) == 0)
+ char *sc_name;
+
+ for (i = 0; i < SMB_OPT_NUM; i++) {
+ sc_name = smb_config_getname(smb_proto_options[i].smb_index);
+ if (strcasecmp(sc_name, name) == 0)
return (i);
}
+
return (-1);
}
@@ -954,21 +974,22 @@ static int
smb_load_proto_properties()
{
sa_property_t prop;
+ char value[MAX_VALUE_BUFLEN];
+ char *name;
int index;
- char *value;
+ int rc;
protoset = sa_create_protocol_properties(SMB_PROTOCOL_NAME);
if (protoset == NULL)
return (SA_NO_MEMORY);
- if (smb_config_load() != 0)
- return (SA_CONFIG_ERR);
- for (index = 0; smb_proto_options[index].name != NULL; index++) {
- value = smb_config_getenv(smb_proto_options[index].smb_index);
- prop = sa_create_property(
- smb_proto_options[index].name, value != NULL ? value : "");
- if (value != NULL)
- free(value);
+ for (index = 0; index < SMB_OPT_NUM; index++) {
+ rc = smb_config_get(smb_proto_options[index].smb_index,
+ value, sizeof (value));
+ if (rc != SMBD_SMF_OK)
+ continue;
+ name = smb_config_getname(smb_proto_options[index].smb_index);
+ prop = sa_create_property(name, value);
if (prop != NULL)
(void) sa_add_protocol_property(protoset, prop);
}
@@ -1004,6 +1025,8 @@ smb_share_fini(void)
{
xmlFreeNode(protoset);
protoset = NULL;
+
+ (void) lmshrd_door_close();
}
/*
@@ -1019,6 +1042,140 @@ smb_get_proto_set(void)
}
/*
+ * smb_enable_dependencies()
+ *
+ * SMBD_DEFAULT_INSTANCE_FMRI may have some dependencies that aren't
+ * enabled. This will attempt to enable all of them.
+ */
+static void
+smb_enable_dependencies(const char *fmri)
+{
+ scf_handle_t *handle;
+ scf_service_t *service;
+ scf_instance_t *inst = NULL;
+ scf_iter_t *iter;
+ scf_property_t *prop;
+ scf_value_t *value;
+ scf_propertygroup_t *pg;
+ scf_scope_t *scope;
+ char type[SCFTYPE_LEN];
+ char *dependency;
+ char *servname;
+ int maxlen;
+
+ /*
+ * Get all required handles and storage.
+ */
+ handle = scf_handle_create(SCF_VERSION);
+ if (handle == NULL)
+ return;
+
+ if (scf_handle_bind(handle) != 0) {
+ scf_handle_destroy(handle);
+ return;
+ }
+
+ maxlen = scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH);
+ if (maxlen == (ssize_t)-1)
+ maxlen = MAXPATHLEN;
+
+ dependency = malloc(maxlen);
+
+ service = scf_service_create(handle);
+
+ iter = scf_iter_create(handle);
+
+ pg = scf_pg_create(handle);
+
+ prop = scf_property_create(handle);
+
+ value = scf_value_create(handle);
+
+ scope = scf_scope_create(handle);
+
+ if (service == NULL || iter == NULL || pg == NULL || prop == NULL ||
+ value == NULL || scope == NULL || dependency == NULL)
+ goto done;
+
+ /*
+ * We passed in the FMRI for the default instance but for
+ * some things we need the simple form so construct it. Since
+ * we reuse the storage that dependency points to, we need to
+ * use the servname early.
+ */
+ (void) snprintf(dependency, maxlen, "%s", fmri + sizeof ("svc:"));
+ servname = strrchr(dependency, ':');
+ if (servname == NULL)
+ goto done;
+ *servname = '\0';
+ servname = dependency;
+
+ /*
+ * Setup to iterate over the service property groups, only
+ * looking at those that are "dependency" types. The "entity"
+ * property will have the FMRI of the service we are dependent
+ * on.
+ */
+ if (scf_handle_get_scope(handle, SCF_SCOPE_LOCAL, scope) != 0)
+ goto done;
+
+ if (scf_scope_get_service(scope, servname, service) != 0)
+ goto done;
+
+ if (scf_iter_service_pgs(iter, service) != 0)
+ goto done;
+
+ while (scf_iter_next_pg(iter, pg) > 0) {
+ char *services[2];
+ /*
+ * Have a property group for the service. See if it is
+ * a dependency pg and only do operations on those.
+ */
+ if (scf_pg_get_type(pg, type, SCFTYPE_LEN) <= 0)
+ continue;
+
+ if (strncmp(type, SCF_GROUP_DEPENDENCY, SCFTYPE_LEN) != 0)
+ continue;
+ /*
+ * Have a dependency. Attempt to enable it.
+ */
+ if (scf_pg_get_property(pg, SCF_PROPERTY_ENTITIES, prop) != 0)
+ continue;
+
+ if (scf_property_get_value(prop, value) != 0)
+ continue;
+
+ services[1] = NULL;
+
+ if (scf_value_get_as_string(value, dependency, maxlen) > 0) {
+ services[0] = dependency;
+ _check_services(services);
+ }
+ }
+
+done:
+ if (dependency != NULL)
+ free(dependency);
+ if (value != NULL)
+ scf_value_destroy(value);
+ if (prop != NULL)
+ scf_property_destroy(prop);
+ if (pg != NULL)
+ scf_pg_destroy(pg);
+ if (iter != NULL)
+ scf_iter_destroy(iter);
+ if (scope != NULL)
+ scf_scope_destroy(scope);
+ if (inst != NULL)
+ scf_instance_destroy(inst);
+ if (service != NULL)
+ scf_service_destroy(service);
+
+ (void) scf_handle_unbind(handle);
+ scf_handle_destroy(handle);
+}
+
+/*
* How long to wait for service to come online
*/
#define WAIT_FOR_SERVICE 15
@@ -1032,21 +1189,25 @@ smb_enable_service(void)
{
int i;
int ret = SA_OK;
+ char *service[] = { SMBD_DEFAULT_INSTANCE_FMRI, NULL };
if (!smb_isonline()) {
- if (smf_enable_instance(SMBD_DEFAULT_INSTANCE_FMRI, 0) != 0) {
- (void) fprintf(stderr,
- dgettext(TEXT_DOMAIN,
- "%s failed to restart: %s\n"),
- SMBD_DEFAULT_INSTANCE_FMRI,
- scf_strerror(scf_error()));
- return (SA_CONFIG_ERR);
- }
+ /*
+ * Attempt to start the idmap, and other dependent
+ * services, first. If it fails, the SMB service will
+ * ultimately fail so we use that as the error. If we
+ * don't try to enable idmap, smb won't start the
+ * first time unless the admin has done it
+ * manually. The service could be administratively
+ * disabled so we won't always get started.
+ */
+ smb_enable_dependencies(SMBD_DEFAULT_INSTANCE_FMRI);
+ _check_services(service);
/* Wait for service to come online */
for (i = 0; i < WAIT_FOR_SERVICE; i++) {
if (smb_isonline()) {
- ret = SA_OK;
+ ret = SA_OK;
break;
} else {
ret = SA_BUSY;
@@ -1079,45 +1240,6 @@ smb_validate_proto_prop(int index, char *name, char *value)
}
/*
- * smb_domain_change_event
- *
- * This function is called whenever ads_domain is changed via sharectl.
- * It will make a door call to trigger the ADS domain change event.
- */
-static int
-smb_domain_change_event(char *new_domain)
-{
- char *orig_domain;
- int rc = SA_OK;
-
- orig_domain = smb_config_getenv(SMB_CI_ADS_DOMAIN);
- if (orig_domain == NULL)
- return (rc);
-
- if (strcasecmp(orig_domain, new_domain) == 0) {
- free(orig_domain);
- return (rc);
- }
-
- if (!smb_isonline()) {
- free(orig_domain);
- return (SA_NO_SERVICE);
- }
-
- /*
- * Clear the ADS_HOST_INFO cache
- * and remove old keys from the
- * Kerberos keytab.
- */
- if (smb_ads_domain_change_notify(orig_domain) != 0)
- rc = SA_KRB_KEYTAB_ERR;
-
- free(orig_domain);
- return (rc);
-}
-
-
-/*
* smb_set_proto_prop(prop)
*
* check that prop is valid.
@@ -1141,13 +1263,9 @@ smb_set_proto_prop(sa_property_t prop)
ret = smb_validate_proto_prop(index, name, value);
if (ret == SA_OK) {
opt = &smb_proto_options[index];
- if ((opt->smb_index == SMB_CI_ADS_DOMAIN) &&
- (ret = smb_domain_change_event(value))
- != SA_OK)
- goto cleanup;
/* Save to SMF */
- smb_config_setenv(opt->smb_index, value);
+ (void) smb_config_set(opt->smb_index, value);
/*
* Specialized refresh mechanisms can
* be flagged in the proto_options and
@@ -1162,7 +1280,6 @@ smb_set_proto_prop(sa_property_t prop)
}
}
-cleanup:
if (name != NULL)
sa_free_attr_string(name);
if (value != NULL)
diff --git a/usr/src/lib/libshare/smb/smb_share_doorclnt.c b/usr/src/lib/libshare/smb/smb_share_doorclnt.c
index 0ebf61b7a9..1a06278568 100644
--- a/usr/src/lib/libshare/smb/smb_share_doorclnt.c
+++ b/usr/src/lib/libshare/smb/smb_share_doorclnt.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -37,15 +37,20 @@
#include <errno.h>
#include <string.h>
#include <strings.h>
+#include <unistd.h>
+#include <thread.h>
+#include <synch.h>
#include <smbsrv/libsmb.h>
-
#include <smbsrv/lmshare.h>
#include <smbsrv/lmerr.h>
#include <smbsrv/lmshare_door.h>
#include <smbsrv/cifs.h>
-int lmshrd_fildes = -1;
+static int lmshrd_fildes = -1;
+static uint64_t lmshrd_door_ncall = 0;
+static mutex_t lmshrd_mutex;
+static cond_t lmshrd_cv;
char *lmshrd_desc[] = {
"",
@@ -72,116 +77,150 @@ char *lmshrd_desc[] = {
};
/*
- * Returns 0 on success. Otherwise, -1.
+ * Open the lmshrd door. This is a private call for use by
+ * lmshrd_door_enter() and must be called with lmshrd_mutex held.
+ *
+ * Returns the door fd on success. Otherwise, -1.
*/
static int
-lmshrd_door_open(int opcode)
+lmshrd_door_open(void)
+{
+ if (lmshrd_fildes == -1) {
+ if ((lmshrd_fildes = open(LMSHR_DOOR_NAME, O_RDONLY)) < 0)
+ lmshrd_fildes = -1;
+ else
+ lmshrd_door_ncall = 0;
+ }
+
+ return (lmshrd_fildes);
+}
+
+/*
+ * Close the lmshrd door.
+ */
+void
+lmshrd_door_close(void)
{
- int rc = 0;
+ (void) mutex_lock(&lmshrd_mutex);
- if (lmshrd_fildes == -1 &&
- (lmshrd_fildes = open(LMSHR_DOOR_NAME, O_RDONLY)) < 0) {
- syslog(LOG_DEBUG, "%s: open %s failed %s", lmshrd_desc[opcode],
- LMSHR_DOOR_NAME, strerror(errno));
- rc = -1;
+ if (lmshrd_fildes != -1) {
+ while (lmshrd_door_ncall > 0)
+ (void) cond_wait(&lmshrd_cv, &lmshrd_mutex);
+
+ if (lmshrd_fildes != -1) {
+ (void) close(lmshrd_fildes);
+ lmshrd_fildes = -1;
+ }
}
- return (rc);
+
+ (void) mutex_unlock(&lmshrd_mutex);
}
/*
- * Return 0 upon success. Otherwise, -1.
+ * Entry handler for lmshrd door calls.
*/
-static int
-lmshrd_door_check_srv_status(int opcode, smb_dr_ctx_t *dec_ctx)
+static door_arg_t *
+lmshrd_door_enter(void)
{
- int status = smb_dr_get_int32(dec_ctx);
- int err;
- int rc = -1;
+ door_arg_t *arg;
+ char *buf;
- switch (status) {
- case LMSHR_DOOR_SRV_SUCCESS:
- rc = 0;
- break;
+ (void) mutex_lock(&lmshrd_mutex);
- case LMSHR_DOOR_SRV_ERROR:
- err = smb_dr_get_uint32(dec_ctx);
- syslog(LOG_ERR, "%s: Encountered door server error %s",
- lmshrd_desc[opcode], strerror(err));
- break;
+ if (lmshrd_door_open() == -1) {
+ (void) mutex_unlock(&lmshrd_mutex);
+ return (NULL);
+ }
+
+ if ((arg = malloc(sizeof (door_arg_t) + LMSHR_DOOR_SIZE)) != NULL) {
+ buf = ((char *)arg) + sizeof (door_arg_t);
+ bzero(arg, sizeof (door_arg_t));
+ arg->data_ptr = buf;
+ arg->rbuf = buf;
+ arg->rsize = LMSHR_DOOR_SIZE;
- default:
- syslog(LOG_ERR, "%s: Unknown door server status",
- lmshrd_desc[opcode]);
+ ++lmshrd_door_ncall;
}
- if (rc != 0) {
- if ((err = smb_dr_decode_finish(dec_ctx)) != 0)
- syslog(LOG_ERR, "%s: Decode error %s",
- lmshrd_desc[opcode], strerror(err));
+ (void) mutex_unlock(&lmshrd_mutex);
+ return (arg);
+}
+
+/*
+ * Exit handler for lmshrd door calls.
+ */
+static void
+lmshrd_door_exit(door_arg_t *arg, char *errmsg)
+{
+ if (errmsg)
+ syslog(LOG_DEBUG, "lmshrd_door: %s", errmsg);
+
+ (void) mutex_lock(&lmshrd_mutex);
+ free(arg);
+ --lmshrd_door_ncall;
+ (void) cond_signal(&lmshrd_cv);
+ (void) mutex_unlock(&lmshrd_mutex);
+}
+
+/*
+ * Return 0 upon success. Otherwise, -1.
+ */
+static int
+lmshrd_door_check_status(smb_dr_ctx_t *dec_ctx)
+{
+ int status = smb_dr_get_int32(dec_ctx);
+
+ if (status != LMSHR_DOOR_SRV_SUCCESS) {
+ if (status == LMSHR_DOOR_SRV_ERROR)
+ (void) smb_dr_get_uint32(dec_ctx);
+ return (-1);
}
- return (rc);
+ return (0);
}
uint64_t
lmshrd_open_iterator(int mode)
{
- door_arg_t arg;
- char *buf;
- unsigned int used;
+ door_arg_t *arg;
smb_dr_ctx_t *dec_ctx;
smb_dr_ctx_t *enc_ctx;
- unsigned int status = 0;
uint64_t lmshr_iter = 0;
- int opcode = LMSHR_DOOR_OPEN_ITERATOR;
+ int rc;
- if (lmshrd_door_open(opcode) == -1)
+ if ((arg = lmshrd_door_enter()) == NULL)
return (lmshr_iter);
- buf = malloc(LMSHR_DOOR_SIZE);
- if (!buf)
- return (lmshr_iter);
-
- enc_ctx = smb_dr_encode_start(buf, LMSHR_DOOR_SIZE);
- smb_dr_put_uint32(enc_ctx, opcode);
+ enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
+ smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_OPEN_ITERATOR);
smb_dr_put_int32(enc_ctx, mode);
- if ((status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
- syslog(LOG_ERR, "%s: Encode error %s",
- lmshrd_desc[opcode], strerror(status));
- (void) free(buf);
+
+ rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
+ if (rc != 0) {
+ lmshrd_door_exit(arg, "encode error");
return (lmshr_iter);
}
- arg.data_ptr = buf;
- arg.data_size = used;
- arg.desc_ptr = NULL;
- arg.desc_num = 0;
- arg.rbuf = buf;
- arg.rsize = LMSHR_DOOR_SIZE;
-
- if (door_call(lmshrd_fildes, &arg) < 0) {
- syslog(LOG_DEBUG, "%s: Door call failed %s",
- lmshrd_desc[opcode], strerror(errno));
- (void) free(buf);
- lmshrd_fildes = -1;
+ if (door_call(lmshrd_fildes, arg) < 0) {
+ lmshrd_door_exit(arg, "door call error");
+ lmshrd_door_close();
return (lmshr_iter);
}
- dec_ctx = smb_dr_decode_start(arg.data_ptr, arg.data_size);
- if (lmshrd_door_check_srv_status(opcode, dec_ctx) != 0) {
- (void) free(buf);
+ dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
+ if (lmshrd_door_check_status(dec_ctx) != 0) {
+ (void) smb_dr_decode_finish(dec_ctx);
+ lmshrd_door_exit(arg, "decode error");
return (lmshr_iter);
}
lmshr_iter = smb_dr_get_lmshr_iterator(dec_ctx);
- if ((status = smb_dr_decode_finish(dec_ctx)) != 0) {
- syslog(LOG_ERR, "%s: Decode error %s",
- lmshrd_desc[opcode], strerror(status));
- (void) free(buf);
+ if (smb_dr_decode_finish(dec_ctx) != 0) {
+ lmshrd_door_exit(arg, "decode error");
return (lmshr_iter);
}
- (void) free(buf);
+ lmshrd_door_exit(arg, NULL);
return (lmshr_iter);
}
@@ -189,312 +228,221 @@ lmshrd_open_iterator(int mode)
DWORD
lmshrd_close_iterator(uint64_t iterator)
{
- door_arg_t arg;
- char *buf;
- unsigned int used;
+ door_arg_t *arg;
smb_dr_ctx_t *dec_ctx;
smb_dr_ctx_t *enc_ctx;
- unsigned int status = 0;
- int opcode = LMSHR_DOOR_CLOSE_ITERATOR;
-
- if (lmshrd_door_open(opcode) == -1)
- return (NERR_InternalError);
+ int rc;
- buf = malloc(LMSHR_DOOR_SIZE);
- if (!buf)
+ if ((arg = lmshrd_door_enter()) == NULL)
return (NERR_InternalError);
- enc_ctx = smb_dr_encode_start(buf, LMSHR_DOOR_SIZE);
- smb_dr_put_uint32(enc_ctx, opcode);
+ enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
+ smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_CLOSE_ITERATOR);
smb_dr_put_lmshr_iterator(enc_ctx, iterator);
- if ((status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
- syslog(LOG_ERR, "%s: Encode error %s",
- lmshrd_desc[opcode], strerror(status));
- (void) free(buf);
+
+ rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
+ if (rc != 0) {
+ lmshrd_door_exit(arg, "encode error");
return (NERR_InternalError);
}
- arg.data_ptr = buf;
- arg.data_size = used;
- arg.desc_ptr = NULL;
- arg.desc_num = 0;
- arg.rbuf = buf;
- arg.rsize = LMSHR_DOOR_SIZE;
-
- if (door_call(lmshrd_fildes, &arg) < 0) {
- syslog(LOG_DEBUG, "%s: Door call failed %s",
- lmshrd_desc[opcode], strerror(errno));
- (void) free(buf);
- lmshrd_fildes = -1;
+ if (door_call(lmshrd_fildes, arg) < 0) {
+ lmshrd_door_exit(arg, "door call error");
+ lmshrd_door_close();
return (NERR_InternalError);
}
- dec_ctx = smb_dr_decode_start(arg.data_ptr, arg.data_size);
- if (lmshrd_door_check_srv_status(opcode, dec_ctx) != 0) {
- (void) free(buf);
+ dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
+ if (lmshrd_door_check_status(dec_ctx) != 0) {
+ (void) smb_dr_decode_finish(dec_ctx);
+ lmshrd_door_exit(arg, "decode error");
return (NERR_InternalError);
}
- if ((status = smb_dr_decode_finish(dec_ctx)) != 0) {
- syslog(LOG_ERR, "%s: Decode error %s",
- lmshrd_desc[opcode], strerror(status));
- (void) free(buf);
+ if (smb_dr_decode_finish(dec_ctx) != 0) {
+ lmshrd_door_exit(arg, "decode error");
return (NERR_InternalError);
}
- (void) free(buf);
+ lmshrd_door_exit(arg, NULL);
return (NERR_Success);
}
DWORD
lmshrd_iterate(uint64_t iterator, lmshare_info_t *si)
{
- door_arg_t arg;
- char *buf;
- unsigned int used;
+ door_arg_t *arg;
smb_dr_ctx_t *dec_ctx;
smb_dr_ctx_t *enc_ctx;
- unsigned int status = 0;
- int opcode = LMSHR_DOOR_ITERATE;
+ int rc;
- if (lmshrd_door_open(opcode) == -1)
- return (NERR_InternalError);
-
- buf = malloc(LMSHR_DOOR_SIZE);
- if (!buf)
+ if ((arg = lmshrd_door_enter()) == NULL)
return (NERR_InternalError);
bzero(si, sizeof (lmshare_info_t));
- enc_ctx = smb_dr_encode_start(buf, LMSHR_DOOR_SIZE);
- smb_dr_put_uint32(enc_ctx, opcode);
+ enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
+ smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_ITERATE);
smb_dr_put_lmshr_iterator(enc_ctx, iterator);
- if ((status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
- syslog(LOG_ERR, "%s: Encode error %s",
- lmshrd_desc[opcode], strerror(status));
- (void) free(buf);
+
+ rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
+ if (rc != 0) {
+ lmshrd_door_exit(arg, "encode error");
return (NERR_InternalError);
}
- arg.data_ptr = buf;
- arg.data_size = used;
- arg.desc_ptr = NULL;
- arg.desc_num = 0;
- arg.rbuf = buf;
- arg.rsize = LMSHR_DOOR_SIZE;
-
- if (door_call(lmshrd_fildes, &arg) < 0) {
- syslog(LOG_DEBUG, "%s: Door call failed %s",
- lmshrd_desc[opcode], strerror(errno));
- (void) free(buf);
- lmshrd_fildes = -1;
+ if (door_call(lmshrd_fildes, arg) < 0) {
+ lmshrd_door_exit(arg, "door call error");
+ lmshrd_door_close();
return (NERR_InternalError);
}
- dec_ctx = smb_dr_decode_start(arg.data_ptr, arg.data_size);
- if (lmshrd_door_check_srv_status(opcode, dec_ctx) != 0) {
- (void) free(buf);
+ dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
+ if (lmshrd_door_check_status(dec_ctx) != 0) {
+ (void) smb_dr_decode_finish(dec_ctx);
+ lmshrd_door_exit(arg, "decode error");
return (NERR_InternalError);
}
smb_dr_get_lmshare(dec_ctx, si);
- if ((status = smb_dr_decode_finish(dec_ctx)) != 0) {
- syslog(LOG_ERR, "%s: Decode error %s",
- lmshrd_desc[opcode], strerror(status));
- (void) free(buf);
+ if (smb_dr_decode_finish(dec_ctx) != 0) {
+ lmshrd_door_exit(arg, "decode error");
return (NERR_InternalError);
}
- (void) free(buf);
+ lmshrd_door_exit(arg, NULL);
return (NERR_Success);
}
DWORD
lmshrd_list(int offset, lmshare_list_t *list)
{
- door_arg_t arg;
- char *buf;
- unsigned int used;
+ door_arg_t *arg;
smb_dr_ctx_t *dec_ctx;
smb_dr_ctx_t *enc_ctx;
- int status;
DWORD rc;
- int opcode = LMSHR_DOOR_LIST;
- if (lmshrd_door_open(opcode) == -1)
+ if ((arg = lmshrd_door_enter()) == NULL)
return (NERR_InternalError);
- buf = malloc(LMSHR_DOOR_SIZE);
-
- if (!buf)
- return (NERR_InternalError);
-
- enc_ctx = smb_dr_encode_start(buf, LMSHR_DOOR_SIZE);
- smb_dr_put_uint32(enc_ctx, opcode);
+ enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
+ smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_LIST);
smb_dr_put_int32(enc_ctx, offset);
- if ((status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
- syslog(LOG_ERR, "%s: Encode error %s",
- lmshrd_desc[opcode], strerror(status));
- (void) free(buf);
+ rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
+ if (rc != 0) {
+ lmshrd_door_exit(arg, "encode error");
return (NERR_InternalError);
}
- arg.data_ptr = buf;
- arg.data_size = used;
- arg.desc_ptr = NULL;
- arg.desc_num = 0;
- arg.rbuf = buf;
- arg.rsize = LMSHR_DOOR_SIZE;
-
- if (door_call(lmshrd_fildes, &arg) < 0) {
- syslog(LOG_DEBUG, "%s: Door call failed %s",
- lmshrd_desc[opcode], strerror(errno));
- (void) free(buf);
- lmshrd_fildes = -1;
+ if (door_call(lmshrd_fildes, arg) < 0) {
+ lmshrd_door_exit(arg, "door call error");
+ lmshrd_door_close();
return (NERR_InternalError);
}
- dec_ctx = smb_dr_decode_start(arg.data_ptr, arg.data_size);
- if (lmshrd_door_check_srv_status(opcode, dec_ctx) != 0) {
- (void) free(buf);
+ dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
+ if (lmshrd_door_check_status(dec_ctx) != 0) {
+ (void) smb_dr_decode_finish(dec_ctx);
+ lmshrd_door_exit(arg, "decode error");
return (NERR_InternalError);
}
rc = smb_dr_get_uint32(dec_ctx);
smb_dr_get_lmshr_list(dec_ctx, list);
- if ((status = smb_dr_decode_finish(dec_ctx)) != 0) {
- syslog(LOG_ERR, "%s: Decode error %s",
- lmshrd_desc[opcode], strerror(status));
- (void) free(buf);
+ if (smb_dr_decode_finish(dec_ctx) != 0) {
+ lmshrd_door_exit(arg, "decode error");
return (NERR_InternalError);
}
- (void) free(buf);
-
+ lmshrd_door_exit(arg, NULL);
return (rc);
}
int
lmshrd_num_shares(void)
{
- door_arg_t arg;
- char *buf;
- unsigned int used;
+ door_arg_t *arg;
smb_dr_ctx_t *dec_ctx;
smb_dr_ctx_t *enc_ctx;
- unsigned int status = 0;
DWORD num_shares;
- int opcode = LMSHR_DOOR_NUM_SHARES;
+ int rc;
- if (lmshrd_door_open(opcode) == -1)
+ if ((arg = lmshrd_door_enter()) == NULL)
return (-1);
- buf = malloc(LMSHR_DOOR_SIZE);
- if (!buf)
- return (-1);
-
- enc_ctx = smb_dr_encode_start(buf, LMSHR_DOOR_SIZE);
+ enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_NUM_SHARES);
- if ((status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
- syslog(LOG_ERR, "%s: Encode error %s",
- lmshrd_desc[opcode], strerror(status));
- (void) free(buf);
+
+ rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
+ if (rc != 0) {
+ lmshrd_door_exit(arg, "encode error");
return (-1);
}
- arg.data_ptr = buf;
- arg.data_size = used;
- arg.desc_ptr = NULL;
- arg.desc_num = 0;
- arg.rbuf = buf;
- arg.rsize = LMSHR_DOOR_SIZE;
-
- if (door_call(lmshrd_fildes, &arg) < 0) {
- syslog(LOG_DEBUG, "%s: Door call failed %s",
- lmshrd_desc[opcode], strerror(errno));
- (void) free(buf);
- lmshrd_fildes = -1;
+ if (door_call(lmshrd_fildes, arg) < 0) {
+ lmshrd_door_exit(arg, "door call error");
+ lmshrd_door_close();
return (-1);
}
- dec_ctx = smb_dr_decode_start(arg.data_ptr, arg.data_size);
- if (lmshrd_door_check_srv_status(opcode, dec_ctx) != 0) {
- (void) free(buf);
+ dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
+ if (lmshrd_door_check_status(dec_ctx) != 0) {
+ (void) smb_dr_decode_finish(dec_ctx);
+ lmshrd_door_exit(arg, "decode error");
return (-1);
}
num_shares = smb_dr_get_uint32(dec_ctx);
- if ((status = smb_dr_decode_finish(dec_ctx)) != 0) {
- syslog(LOG_ERR, "%s: Decode error %s",
- lmshrd_desc[opcode], strerror(status));
- (void) free(buf);
+ if (smb_dr_decode_finish(dec_ctx) != 0) {
+ lmshrd_door_exit(arg, "decode error");
return (-1);
}
- (void) free(buf);
+ lmshrd_door_exit(arg, NULL);
return (num_shares);
}
DWORD
lmshrd_delete(char *share_name)
{
- door_arg_t arg;
- char *buf;
- unsigned int used;
+ door_arg_t *arg;
smb_dr_ctx_t *dec_ctx;
smb_dr_ctx_t *enc_ctx;
- int status;
DWORD rc;
- int opcode = LMSHR_DOOR_DELETE;
-
- if (lmshrd_door_open(opcode) == -1)
- return (NERR_InternalError);
- buf = malloc(LMSHR_DOOR_SIZE);
- if (!buf)
+ if ((arg = lmshrd_door_enter()) == NULL)
return (NERR_InternalError);
- enc_ctx = smb_dr_encode_start(buf, LMSHR_DOOR_SIZE);
+ enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_DELETE);
smb_dr_put_string(enc_ctx, share_name);
- if ((status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
- syslog(LOG_ERR, "%s: Encode error %s",
- lmshrd_desc[opcode], strerror(status));
- (void) free(buf);
+ rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
+ if (rc != 0) {
+ lmshrd_door_exit(arg, "encode error");
return (NERR_InternalError);
}
- arg.data_ptr = buf;
- arg.data_size = used;
- arg.desc_ptr = NULL;
- arg.desc_num = 0;
- arg.rbuf = buf;
- arg.rsize = LMSHR_DOOR_SIZE;
-
- if (door_call(lmshrd_fildes, &arg) < 0) {
- syslog(LOG_DEBUG, "%s: Door call failed %s",
- lmshrd_desc[opcode], strerror(errno));
- (void) free(buf);
- lmshrd_fildes = -1;
+ if (door_call(lmshrd_fildes, arg) < 0) {
+ lmshrd_door_exit(arg, "door call error");
+ lmshrd_door_close();
return (NERR_InternalError);
}
- dec_ctx = smb_dr_decode_start(arg.data_ptr, arg.data_size);
- if (lmshrd_door_check_srv_status(opcode, dec_ctx) != 0) {
- (void) free(buf);
+ dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
+ if (lmshrd_door_check_status(dec_ctx) != 0) {
+ (void) smb_dr_decode_finish(dec_ctx);
+ lmshrd_door_exit(arg, "decode error");
return (NERR_InternalError);
}
rc = smb_dr_get_uint32(dec_ctx);
- if ((status = smb_dr_decode_finish(dec_ctx)) != 0) {
- syslog(LOG_ERR, "%s: Decode error %s",
- lmshrd_desc[opcode], strerror(status));
- (void) free(buf);
+ if (smb_dr_decode_finish(dec_ctx) != 0) {
+ lmshrd_door_exit(arg, "decode error");
return (NERR_InternalError);
}
- (void) free(buf);
+ lmshrd_door_exit(arg, NULL);
return (rc);
}
@@ -502,316 +450,223 @@ lmshrd_delete(char *share_name)
DWORD
lmshrd_rename(char *from, char *to)
{
- door_arg_t arg;
- char *buf;
- unsigned int used;
+ door_arg_t *arg;
smb_dr_ctx_t *dec_ctx;
smb_dr_ctx_t *enc_ctx;
- int status;
DWORD rc;
- int opcode = LMSHR_DOOR_RENAME;
-
- if (lmshrd_door_open(opcode) == -1)
- return (NERR_InternalError);
- buf = malloc(LMSHR_DOOR_SIZE);
- if (!buf)
+ if ((arg = lmshrd_door_enter()) == NULL)
return (NERR_InternalError);
- enc_ctx = smb_dr_encode_start(buf, LMSHR_DOOR_SIZE);
+ enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_RENAME);
smb_dr_put_string(enc_ctx, from);
smb_dr_put_string(enc_ctx, to);
- if ((status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
- syslog(LOG_ERR, "%s: Encode error %s",
- lmshrd_desc[opcode], strerror(status));
- (void) free(buf);
+ rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
+ if (rc != 0) {
+ lmshrd_door_exit(arg, "encode error");
return (NERR_InternalError);
}
- arg.data_ptr = buf;
- arg.data_size = used;
- arg.desc_ptr = NULL;
- arg.desc_num = 0;
- arg.rbuf = buf;
- arg.rsize = LMSHR_DOOR_SIZE;
-
- if (door_call(lmshrd_fildes, &arg) < 0) {
- syslog(LOG_DEBUG, "%s: Door call failed %s",
- lmshrd_desc[opcode], strerror(errno));
- (void) free(buf);
- lmshrd_fildes = -1;
+ if (door_call(lmshrd_fildes, arg) < 0) {
+ lmshrd_door_exit(arg, "door call error");
+ lmshrd_door_close();
return (NERR_InternalError);
}
- dec_ctx = smb_dr_decode_start(arg.data_ptr, arg.data_size);
- if (lmshrd_door_check_srv_status(opcode, dec_ctx) != 0) {
- (void) free(buf);
+ dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
+ if (lmshrd_door_check_status(dec_ctx) != 0) {
+ (void) smb_dr_decode_finish(dec_ctx);
+ lmshrd_door_exit(arg, "decode error");
return (NERR_InternalError);
}
rc = smb_dr_get_uint32(dec_ctx);
- if ((status = smb_dr_decode_finish(dec_ctx)) != 0) {
- syslog(LOG_ERR, "%s: Decode error %s",
- lmshrd_desc[opcode], strerror(status));
- (void) free(buf);
+ if (smb_dr_decode_finish(dec_ctx) != 0) {
+ lmshrd_door_exit(arg, "decode error");
return (NERR_InternalError);
}
- (void) free(buf);
+ lmshrd_door_exit(arg, NULL);
return (rc);
}
DWORD
lmshrd_getinfo(char *share_name, lmshare_info_t *si)
{
- door_arg_t arg;
- char *buf;
- unsigned int used;
+ door_arg_t *arg;
smb_dr_ctx_t *dec_ctx;
smb_dr_ctx_t *enc_ctx;
- int status;
DWORD rc;
- int opcode = LMSHR_DOOR_GETINFO;
-
- if (lmshrd_door_open(opcode) == -1)
- return (NERR_InternalError);
- buf = malloc(LMSHR_DOOR_SIZE);
- if (!buf)
+ if ((arg = lmshrd_door_enter()) == NULL)
return (NERR_InternalError);
- enc_ctx = smb_dr_encode_start(buf, LMSHR_DOOR_SIZE);
+ enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_GETINFO);
smb_dr_put_string(enc_ctx, share_name);
- if ((status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
- syslog(LOG_ERR, "%s: Encode error %s",
- lmshrd_desc[opcode], strerror(status));
- (void) free(buf);
+ rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
+ if (rc != 0) {
+ lmshrd_door_exit(arg, "encode error");
return (NERR_InternalError);
}
- arg.data_ptr = buf;
- arg.data_size = used;
- arg.desc_ptr = NULL;
- arg.desc_num = 0;
- arg.rbuf = buf;
- arg.rsize = LMSHR_DOOR_SIZE;
-
- if (door_call(lmshrd_fildes, &arg) < 0) {
- syslog(LOG_DEBUG, "%s: Door call failed %s",
- lmshrd_desc[opcode], strerror(errno));
- (void) free(buf);
- lmshrd_fildes = -1;
+ if (door_call(lmshrd_fildes, arg) < 0) {
+ lmshrd_door_exit(arg, "door call error");
+ lmshrd_door_close();
return (NERR_InternalError);
}
- dec_ctx = smb_dr_decode_start(arg.data_ptr, arg.data_size);
- if (lmshrd_door_check_srv_status(opcode, dec_ctx) != 0) {
- (void) free(buf);
+ dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
+ if (lmshrd_door_check_status(dec_ctx) != 0) {
+ (void) smb_dr_decode_finish(dec_ctx);
+ lmshrd_door_exit(arg, "decode error");
return (NERR_InternalError);
}
rc = smb_dr_get_uint32(dec_ctx);
smb_dr_get_lmshare(dec_ctx, si);
- if ((status = smb_dr_decode_finish(dec_ctx)) != 0) {
- syslog(LOG_ERR, "%s: Decode error %s",
- lmshrd_desc[opcode], strerror(status));
- (void) free(buf);
+ if (smb_dr_decode_finish(dec_ctx) != 0) {
+ lmshrd_door_exit(arg, "decode error");
return (NERR_InternalError);
}
- (void) free(buf);
+ lmshrd_door_exit(arg, NULL);
return (rc);
}
DWORD
lmshrd_add(lmshare_info_t *si)
{
- door_arg_t arg;
- char *buf;
- unsigned int used;
+ door_arg_t *arg;
smb_dr_ctx_t *dec_ctx;
smb_dr_ctx_t *enc_ctx;
- int status;
DWORD rc;
- int opcode = LMSHR_DOOR_ADD;
- if (lmshrd_door_open(opcode) == -1)
+ if ((arg = lmshrd_door_enter()) == NULL)
return (NERR_InternalError);
- buf = malloc(LMSHR_DOOR_SIZE);
- if (!buf)
- return (NERR_InternalError);
-
- enc_ctx = smb_dr_encode_start(buf, LMSHR_DOOR_SIZE);
- smb_dr_put_uint32(enc_ctx, opcode);
+ enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
+ smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_ADD);
smb_dr_put_lmshare(enc_ctx, si);
- if ((status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
- syslog(LOG_ERR, "%s: Encode error %s",
- lmshrd_desc[opcode], strerror(status));
- (void) free(buf);
+ rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
+ if (rc != 0) {
+ lmshrd_door_exit(arg, "encode error");
return (NERR_InternalError);
}
- arg.data_ptr = buf;
- arg.data_size = used;
- arg.desc_ptr = NULL;
- arg.desc_num = 0;
- arg.rbuf = buf;
- arg.rsize = LMSHR_DOOR_SIZE;
-
- if (door_call(lmshrd_fildes, &arg) < 0) {
- syslog(LOG_DEBUG, "%s: Door call failed %s",
- lmshrd_desc[opcode], strerror(errno));
- (void) free(buf);
- lmshrd_fildes = -1;
+ if (door_call(lmshrd_fildes, arg) < 0) {
+ lmshrd_door_exit(arg, "door call error");
+ lmshrd_door_close();
return (NERR_InternalError);
}
- dec_ctx = smb_dr_decode_start(arg.data_ptr, arg.data_size);
- if (lmshrd_door_check_srv_status(opcode, dec_ctx) != 0) {
- (void) free(buf);
+ dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
+ if (lmshrd_door_check_status(dec_ctx) != 0) {
+ (void) smb_dr_decode_finish(dec_ctx);
+ lmshrd_door_exit(arg, "decode error");
return (NERR_InternalError);
}
rc = smb_dr_get_uint32(dec_ctx);
smb_dr_get_lmshare(dec_ctx, si);
- if ((status = smb_dr_decode_finish(dec_ctx)) != 0) {
- syslog(LOG_ERR, "%s: Decode error %s",
- lmshrd_desc[opcode], strerror(status));
- (void) free(buf);
+ if (smb_dr_decode_finish(dec_ctx) != 0) {
+ lmshrd_door_exit(arg, "decode error");
return (NERR_InternalError);
}
- (void) free(buf);
+ lmshrd_door_exit(arg, NULL);
return (rc);
}
DWORD
lmshrd_setinfo(lmshare_info_t *si)
{
- door_arg_t arg;
- char *buf;
- unsigned int used;
+ door_arg_t *arg;
smb_dr_ctx_t *dec_ctx;
smb_dr_ctx_t *enc_ctx;
- int status;
DWORD rc;
- int opcode = LMSHR_DOOR_SETINFO;
-
- if (lmshrd_door_open(opcode) == -1)
- return (NERR_InternalError);
- buf = malloc(LMSHR_DOOR_SIZE);
- if (!buf)
+ if ((arg = lmshrd_door_enter()) == NULL)
return (NERR_InternalError);
- enc_ctx = smb_dr_encode_start(buf, LMSHR_DOOR_SIZE);
- smb_dr_put_uint32(enc_ctx, opcode);
+ enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
+ smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_SETINFO);
smb_dr_put_lmshare(enc_ctx, si);
- if ((status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
- syslog(LOG_ERR, "%s: Encode error %s",
- lmshrd_desc[opcode], strerror(status));
- (void) free(buf);
+ rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
+ if (rc != 0) {
+ lmshrd_door_exit(arg, "encode error");
return (NERR_InternalError);
}
- arg.data_ptr = buf;
- arg.data_size = used;
- arg.desc_ptr = NULL;
- arg.desc_num = 0;
- arg.rbuf = buf;
- arg.rsize = LMSHR_DOOR_SIZE;
-
- if (door_call(lmshrd_fildes, &arg) < 0) {
- syslog(LOG_DEBUG, "%s: Door call failed %s",
- lmshrd_desc[opcode], strerror(errno));
- (void) free(buf);
- lmshrd_fildes = -1;
+ if (door_call(lmshrd_fildes, arg) < 0) {
+ lmshrd_door_exit(arg, "door call error");
+ lmshrd_door_close();
return (NERR_InternalError);
}
- dec_ctx = smb_dr_decode_start(arg.data_ptr, arg.data_size);
- if (lmshrd_door_check_srv_status(opcode, dec_ctx) != 0) {
- (void) free(buf);
+ dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
+ if (lmshrd_door_check_status(dec_ctx) != 0) {
+ (void) smb_dr_decode_finish(dec_ctx);
+ lmshrd_door_exit(arg, "decode error");
return (NERR_InternalError);
}
rc = smb_dr_get_uint32(dec_ctx);
- if ((status = smb_dr_decode_finish(dec_ctx)) != 0) {
- syslog(LOG_ERR, "%s: Decode error %s",
- lmshrd_desc[opcode], strerror(status));
- (void) free(buf);
+ if (smb_dr_decode_finish(dec_ctx) != 0) {
+ lmshrd_door_exit(arg, "decode error");
return (NERR_InternalError);
}
- (void) free(buf);
+ lmshrd_door_exit(arg, NULL);
return (rc);
}
static int
lmshrd_check(char *share_name, int opcode)
{
- door_arg_t arg;
- char *buf;
- unsigned int used;
+ door_arg_t *arg;
smb_dr_ctx_t *dec_ctx;
smb_dr_ctx_t *enc_ctx;
- int status, rc;
+ int rc;
- if (lmshrd_door_open(opcode) == -1)
+ if ((arg = lmshrd_door_enter()) == NULL)
return (NERR_InternalError);
- buf = malloc(LMSHR_DOOR_SIZE);
- if (!buf)
- return (NERR_InternalError);
-
- enc_ctx = smb_dr_encode_start(buf, LMSHR_DOOR_SIZE);
+ enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
smb_dr_put_uint32(enc_ctx, opcode);
smb_dr_put_string(enc_ctx, share_name);
- if ((status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
- syslog(LOG_ERR, "%s: Encode error %s",
- lmshrd_desc[opcode], strerror(status));
- (void) free(buf);
+ rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
+ if (rc != 0) {
+ lmshrd_door_exit(arg, "encode error");
return (NERR_InternalError);
}
- arg.data_ptr = buf;
- arg.data_size = used;
- arg.desc_ptr = NULL;
- arg.desc_num = 0;
- arg.rbuf = buf;
- arg.rsize = LMSHR_DOOR_SIZE;
-
- if (door_call(lmshrd_fildes, &arg) < 0) {
- syslog(LOG_DEBUG, "%s: Door call failed %s",
- lmshrd_desc[opcode], strerror(errno));
- (void) free(buf);
- lmshrd_fildes = -1;
+ if (door_call(lmshrd_fildes, arg) < 0) {
+ lmshrd_door_exit(arg, "door call error");
+ lmshrd_door_close();
return (NERR_InternalError);
}
- dec_ctx = smb_dr_decode_start(arg.data_ptr, arg.data_size);
- if (lmshrd_door_check_srv_status(opcode, dec_ctx) != 0) {
- (void) free(buf);
+ dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
+ if (lmshrd_door_check_status(dec_ctx) != 0) {
+ (void) smb_dr_decode_finish(dec_ctx);
+ lmshrd_door_exit(arg, "decode error");
return (NERR_InternalError);
}
rc = smb_dr_get_int32(dec_ctx);
- if ((status = smb_dr_decode_finish(dec_ctx)) != 0) {
- syslog(LOG_ERR, "%s: Decode error %s",
- lmshrd_desc[opcode], strerror(status));
- (void) free(buf);
+ if (smb_dr_decode_finish(dec_ctx) != 0) {
+ lmshrd_door_exit(arg, "decode error");
return (NERR_InternalError);
}
- (void) free(buf);
+ lmshrd_door_exit(arg, NULL);
return (rc);
}
@@ -850,102 +705,3 @@ lmshrd_is_dir(char *path)
{
return (lmshrd_check(path, LMSHR_DOOR_IS_DIR));
}
-
-static char *
-lmshare_decode_type(unsigned int stype)
-{
- switch (stype) {
- case STYPE_DISKTREE:
- return ("Disk");
- case STYPE_PRINTQ:
- return ("Print Queue");
- case STYPE_DEVICE:
- return ("Device");
- case STYPE_IPC:
- return ("IPC");
- case STYPE_DFS:
- return ("DFS");
- case STYPE_SPECIAL:
- return ("Special");
- default:
- return ("Unknown");
- };
-}
-
-
-static void
-lmshare_loginfo(FILE *fp, lmshare_info_t *si)
-{
- if (!si) {
- return;
- }
-
- (void) fprintf(fp, "\n%s Information:\n", si->share_name);
- (void) fprintf(fp, "\tFolder: %s\n", si->directory);
- (void) fprintf(fp, "\tType: %s\n", lmshare_decode_type(si->stype));
- (void) fprintf(fp, "\tComment: %s\n", si->comment);
-
- (void) fprintf(fp, "\tStatus: %s\n",
- ((si->mode & LMSHRM_TRANS) ? "Transient" : "Permanent"));
-
- (void) fprintf(fp, "\tContainer: %s\n", si->container);
-}
-
-int
-lmshrd_dump_hash(char *logfname)
-{
- lmshare_info_t si;
- uint64_t it;
- FILE *fp;
-
- if ((logfname == 0) || (*logfname == 0))
- fp = stdout;
- else {
- fp = fopen(logfname, "w");
- if (fp == 0) {
- syslog(LOG_WARNING, "LmshareDump [%s]:"
- " cannot create logfile", logfname);
- syslog(LOG_WARNING, "LmshareDump:"
- " output will be written on screen");
- }
- }
-
- it = lmshrd_open_iterator(LMSHRM_PERM);
- if (it == NULL) {
- syslog(LOG_ERR, "LmshareDump: resource shortage");
- if (fp && fp != stdout) {
- (void) fclose(fp);
- }
- return (1);
- }
-
- if (lmshrd_iterate(it, &si) != NERR_Success) {
- syslog(LOG_ERR, "LmshareDump: Iterator iterate failed");
- if (fp && fp != stdout) {
- (void) fclose(fp);
- }
- return (1);
- }
- while (*si.share_name != 0) {
- lmshare_loginfo(fp, &si);
- if (lmshrd_iterate(it, &si) != NERR_Success) {
- syslog(LOG_ERR, "LmshareDump: Iterator iterate failed");
- if (fp && fp != stdout) {
- (void) fclose(fp);
- }
- return (1);
- }
- }
-
- if (lmshrd_close_iterator(it) != NERR_Success) {
- syslog(LOG_ERR, "LmshareDump: Iterator close failed");
- if (fp && fp != stdout) {
- (void) fclose(fp);
- }
- return (1);
- }
- if (fp && fp != stdout) {
- (void) fclose(fp);
- }
- return (0);
-}
diff --git a/usr/src/lib/libsqlite/Makefile.com b/usr/src/lib/libsqlite/Makefile.com
index 49b42f553b..5bf5ebd84c 100644
--- a/usr/src/lib/libsqlite/Makefile.com
+++ b/usr/src/lib/libsqlite/Makefile.com
@@ -1,5 +1,5 @@
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -48,7 +48,8 @@ include $(SRC)/lib/Makefile.lib
SRCDIR = ../src
TOOLDIR = ../tool
-LIBS = $(RELOC) $(LINTLIB)
+$(DYNLIB) := LDLIBS += -lc
+LIBS = $(RELOC) $(LINTLIB) $(DYNLIB)
$(LINTLIB) := SRCS = $(LINTSRC)
@@ -88,7 +89,7 @@ SRCS = \
MYCPPFLAGS = -D_REENTRANT -DTHREADSAFE=1 -DHAVE_USLEEP=1 -I. -I.. -I$(SRCDIR)
CPPFLAGS += $(MYCPPFLAGS)
-MAPFILE = ../mapfile-sqlite
+MAPFILES = ../mapfile-sqlite
# Header files used by all library source files.
#
@@ -198,11 +199,11 @@ $(OBJS) $(OBJS:%.o=%-native.o): $(HDR)
native: $(NATIVERELOC)
$(RELOC): objs .WAIT $(OBJS)
- $(LD) -r $(MAPFILE:%=-M%) -o $(RELOC) $(OBJS)
+ $(LD) -r $(MAPFILES:%=-M%) -o $(RELOC) $(OBJS)
$(CTFMERGE) -t -f -L VERSION -o $(RELOC) $(OBJS)
$(NATIVERELOC): objs .WAIT $(OBJS:%.o=%-native.o)
- $(LD) -r $(MAPFILE:%=-M%) -o $(NATIVERELOC) $(OBJS:%.o=%-native.o)
+ $(LD) -r $(MAPFILES:%=-M%) -o $(NATIVERELOC) $(OBJS:%.o=%-native.o)
opcodes.h: $(SRCDIR)/vdbe.c
@echo "Generating $@"; \
diff --git a/usr/src/lib/libsqlite/i386/Makefile b/usr/src/lib/libsqlite/i386/Makefile
index 1cdf2c61ae..743fead699 100644
--- a/usr/src/lib/libsqlite/i386/Makefile
+++ b/usr/src/lib/libsqlite/i386/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -27,6 +27,6 @@
include ../Makefile.com
-install: $(ROOTLIBDIR)/$(RELOC)
+install: $(ROOTLIBDIR)/$(RELOC) $(ROOTLIBS) $(ROOTLINKS)
$(ROOTLIBDIR)/$(RELOC): all
diff --git a/usr/src/lib/libsqlite/sparc/Makefile b/usr/src/lib/libsqlite/sparc/Makefile
index 1cdf2c61ae..743fead699 100644
--- a/usr/src/lib/libsqlite/sparc/Makefile
+++ b/usr/src/lib/libsqlite/sparc/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -27,6 +27,6 @@
include ../Makefile.com
-install: $(ROOTLIBDIR)/$(RELOC)
+install: $(ROOTLIBDIR)/$(RELOC) $(ROOTLIBS) $(ROOTLINKS)
$(ROOTLIBDIR)/$(RELOC): all
diff --git a/usr/src/lib/smbsrv/libmlrpc/Makefile.com b/usr/src/lib/smbsrv/libmlrpc/Makefile.com
index cc5ba2923f..d4776174cd 100644
--- a/usr/src/lib/smbsrv/libmlrpc/Makefile.com
+++ b/usr/src/lib/smbsrv/libmlrpc/Makefile.com
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -29,13 +29,13 @@ LIBRARY = libmlrpc.a
VERS = .1
OBJS_COMMON = \
- mlndo.o \
- mlndr.o \
- mlrpc_client.o \
- mlrpc_encdec.o \
- mlrpc_heap.o \
- mlrpc_server.o \
- mlrpc_svc.o
+ ndr_client.o \
+ ndr_heap.o \
+ ndr_marshal.o \
+ ndr_ops.o \
+ ndr_process.o \
+ ndr_server.o \
+ ndr_svc.o
NDLLIST = rpcpdu
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/mapfile-vers b/usr/src/lib/smbsrv/libmlrpc/common/mapfile-vers
index 2f8fea95f3..5166d7d3d9 100644
--- a/usr/src/lib/smbsrv/libmlrpc/common/mapfile-vers
+++ b/usr/src/lib/smbsrv/libmlrpc/common/mapfile-vers
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -48,6 +48,9 @@ SUNWprivate {
mlrpc_process;
mlrpc_register_service;
mlrpc_release;
+ ndr_hdalloc;
+ ndr_hdfree;
+ ndr_hdlookup;
ndr_mbstowcs;
ndr_mbtowc;
ndt__char;
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/mlrpc_client.c b/usr/src/lib/smbsrv/libmlrpc/common/ndr_client.c
index 0f58231251..0f58231251 100644
--- a/usr/src/lib/smbsrv/libmlrpc/common/mlrpc_client.c
+++ b/usr/src/lib/smbsrv/libmlrpc/common/ndr_client.c
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/mlrpc_heap.c b/usr/src/lib/smbsrv/libmlrpc/common/ndr_heap.c
index 97a16ea010..97a16ea010 100644
--- a/usr/src/lib/smbsrv/libmlrpc/common/mlrpc_heap.c
+++ b/usr/src/lib/smbsrv/libmlrpc/common/ndr_heap.c
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/mlrpc_encdec.c b/usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c
index 884683dfe4..884683dfe4 100644
--- a/usr/src/lib/smbsrv/libmlrpc/common/mlrpc_encdec.c
+++ b/usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/mlndo.c b/usr/src/lib/smbsrv/libmlrpc/common/ndr_ops.c
index c469223c4d..c469223c4d 100644
--- a/usr/src/lib/smbsrv/libmlrpc/common/mlndo.c
+++ b/usr/src/lib/smbsrv/libmlrpc/common/ndr_ops.c
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/mlndr.c b/usr/src/lib/smbsrv/libmlrpc/common/ndr_process.c
index e81225ede8..b64ada2955 100644
--- a/usr/src/lib/smbsrv/libmlrpc/common/mlndr.c
+++ b/usr/src/lib/smbsrv/libmlrpc/common/ndr_process.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -1321,9 +1321,9 @@ mlndr_outer_string(struct ndr_reference *outer_ref)
myref.inner_flags = NDR_F_NONE;
/*
- * Set up strlen_is so that we know what to
- * expect later (see mlndr_s_wchar).
+ * Set up size_is and strlen_is for mlndr_s_wchar.
*/
+ myref.size_is = size_is;
myref.strlen_is = length_is;
}
@@ -1933,6 +1933,9 @@ mlndr_s_wchar(struct ndr_reference *encl_ref)
if (count < 0) {
return (0);
} else if (count == 0) {
+ if (encl_ref->strlen_is != encl_ref->size_is)
+ break;
+
/*
* If the input char is 0, mbtowc
* returns 0 without setting wide_char.
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/mlrpc_server.c b/usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c
index 2f442937be..a1f203c09c 100644
--- a/usr/src/lib/smbsrv/libmlrpc/common/mlrpc_server.c
+++ b/usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -70,8 +70,8 @@ static void mlrpc_reply_fault(struct mlrpc_xaction *, unsigned long);
static int mlrpc_build_reply(struct mlrpc_xaction *);
/*
- * The is the RPC service server-side entry point. All MSRPC encoded
- * messages should be passed through here. We use the same context
+ * This is the RPC service server-side entry point. All MSRPC encoded
+ * messages should be passed through here. We use the same context
* structure as the client side but we don't need to set up the client
* side info.
*/
@@ -98,6 +98,7 @@ mlrpc_process(int fid, smb_dr_user_ctx_t *user_ctx)
return (NULL);
bzero(mxa, sizeof (struct mlrpc_xaction));
+ mxa->fid = fid;
mxa->context = context;
mxa->binding_list = context->binding;
@@ -177,6 +178,8 @@ mlrpc_lookup(int fid)
return (NULL);
}
+ bzero(available->inpipe, sizeof (smb_pipe_t));
+ bzero(available->outpipe, sizeof (smb_pipe_t));
available->fid = fid;
available->inpipe->sp_pipeid = fid;
available->outpipe->sp_pipeid = fid;
@@ -205,6 +208,7 @@ mlrpc_release(int fid)
context = &context_table[i];
if (context->fid == fid) {
+ ndr_hdclose(fid);
free(context->inpipe);
free(context->outpipe);
bzero(context, sizeof (struct mlsvc_rpc_context));
@@ -267,8 +271,8 @@ mlrpc_s_bind(struct mlrpc_xaction *mxa)
mlrpc_p_result_t *result;
unsigned p_cont_id;
struct mlrpc_binding *mbind;
- mlrpc_uuid_t *as_uuid;
- mlrpc_uuid_t *ts_uuid;
+ ndr_uuid_t *as_uuid;
+ ndr_uuid_t *ts_uuid;
char as_buf[64];
char ts_buf[64];
int as_vers;
@@ -414,8 +418,8 @@ mlrpc_s_alter_context(struct mlrpc_xaction *mxa)
struct mlrpc_binding *mbind;
struct mlrpc_service *msvc;
unsigned p_cont_id;
- mlrpc_uuid_t *as_uuid;
- mlrpc_uuid_t *ts_uuid;
+ ndr_uuid_t *as_uuid;
+ ndr_uuid_t *ts_uuid;
int as_vers;
int ts_vers;
mlrpc_port_any_t *sec_addr;
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/mlrpc_svc.c b/usr/src/lib/smbsrv/libmlrpc/common/ndr_svc.c
index 771e54b7e4..1c051b560e 100644
--- a/usr/src/lib/smbsrv/libmlrpc/common/mlrpc_svc.c
+++ b/usr/src/lib/smbsrv/libmlrpc/common/ndr_svc.c
@@ -19,26 +19,44 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
+#include <synch.h>
#include <stdio.h>
+#include <unistd.h>
#include <string.h>
#include <strings.h>
+#include <assert.h>
#include <smbsrv/libsmb.h>
#include <smbsrv/ndr.h>
#include <smbsrv/mlrpc.h>
+#include <smbsrv/ntsid.h>
+
+/*
+ * Global list of allocated handles. Handles are used in various
+ * server-side RPC functions: typically, issued when a service is
+ * opened and obsoleted when it is closed. Clients should treat
+ * handles as opaque data.
+ */
+static ndr_handle_t *ndr_handle_list;
+static mutex_t ndr_handle_lock;
+
+/*
+ * Table of registered services.
+ */
#define NDL_MAX_SERVICES 32
-static struct mlrpc_service *mlrpc_services[NDL_MAX_SERVICES];
+static mlrpc_service_t *mlrpc_services[NDL_MAX_SERVICES];
+
struct mlrpc_stub_table *
-mlrpc_find_stub_in_svc(struct mlrpc_service *msvc, int opnum)
+mlrpc_find_stub_in_svc(mlrpc_service_t *msvc, int opnum)
{
struct mlrpc_stub_table *ste;
@@ -50,10 +68,10 @@ mlrpc_find_stub_in_svc(struct mlrpc_service *msvc, int opnum)
return (NULL);
}
-struct mlrpc_service *
+mlrpc_service_t *
mlrpc_find_service_by_name(const char *name)
{
- struct mlrpc_service *msvc;
+ mlrpc_service_t *msvc;
int i;
for (i = 0; i < NDL_MAX_SERVICES; i++) {
@@ -70,11 +88,11 @@ mlrpc_find_service_by_name(const char *name)
return (NULL);
}
-struct mlrpc_service *
-mlrpc_find_service_by_uuids(mlrpc_uuid_t *as_uuid, int as_vers,
- mlrpc_uuid_t *ts_uuid, int ts_vers)
+mlrpc_service_t *
+mlrpc_find_service_by_uuids(ndr_uuid_t *as_uuid, int as_vers,
+ ndr_uuid_t *ts_uuid, int ts_vers)
{
- struct mlrpc_service *msvc;
+ mlrpc_service_t *msvc;
char abstract_syntax[128];
char transfer_syntax[128];
int i;
@@ -130,9 +148,9 @@ mlrpc_find_service_by_uuids(mlrpc_uuid_t *as_uuid, int as_vers,
* -3 Table overflow
*/
int
-mlrpc_register_service(struct mlrpc_service *msvc)
+mlrpc_register_service(mlrpc_service_t *msvc)
{
- struct mlrpc_service *p;
+ mlrpc_service_t *p;
int free_slot = -1;
int i;
@@ -158,7 +176,7 @@ mlrpc_register_service(struct mlrpc_service *msvc)
}
void
-mlrpc_unregister_service(struct mlrpc_service *msvc)
+mlrpc_unregister_service(mlrpc_service_t *msvc)
{
int i;
@@ -171,7 +189,7 @@ mlrpc_unregister_service(struct mlrpc_service *msvc)
int
mlrpc_list_services(char *buffer, int bufsize)
{
- struct mlrpc_service *msvc;
+ mlrpc_service_t *msvc;
smb_ctxbuf_t ctx;
int i;
@@ -187,8 +205,144 @@ mlrpc_list_services(char *buffer, int bufsize)
return (smb_ctxbuf_len(&ctx));
}
+/*
+ * Allocate a handle for use with the server-side RPC functions.
+ * The handle contains the machine SID and an incrementing counter,
+ * which should make each handle unique.
+ *
+ * An arbitrary caller context can be associated with the handle
+ * via data; it will not be dereferenced by the handle API.
+ *
+ * The uuid for the new handle is returned after it has been added
+ * to the global handle list.
+ */
+ndr_hdid_t *
+ndr_hdalloc(const ndr_xa_t *xa, const void *data)
+{
+ static ndr_hdid_t uuid;
+ ndr_handle_t *hd;
+ nt_sid_t *sid;
+
+ if ((hd = malloc(sizeof (ndr_handle_t))) == NULL)
+ return (NULL);
+
+ if (uuid.data[1] == 0) {
+ if ((sid = nt_domain_local_sid()) == NULL)
+ return (NULL);
+
+ uuid.data[0] = 0;
+ uuid.data[1] = 0;
+ uuid.data[2] = sid->SubAuthority[1];
+ uuid.data[3] = sid->SubAuthority[2];
+ uuid.data[4] = sid->SubAuthority[3];
+ }
+
+ ++uuid.data[1];
+
+ bcopy(&uuid, &hd->nh_id, sizeof (ndr_hdid_t));
+ hd->nh_fid = xa->fid;
+ hd->nh_svc = xa->binding->service;
+ hd->nh_data = (void *)data;
+
+ (void) mutex_lock(&ndr_handle_lock);
+ hd->nh_next = ndr_handle_list;
+ ndr_handle_list = hd;
+ (void) mutex_unlock(&ndr_handle_lock);
+
+ return (&hd->nh_id);
+}
+
+/*
+ * Remove a handle from the global list and free it.
+ */
+void
+ndr_hdfree(const ndr_xa_t *xa, const ndr_hdid_t *id)
+{
+ mlrpc_service_t *svc = xa->binding->service;
+ ndr_handle_t *hd;
+ ndr_handle_t **pphd;
+
+ assert(id);
+
+ (void) mutex_lock(&ndr_handle_lock);
+ pphd = &ndr_handle_list;
+
+ while (*pphd) {
+ hd = *pphd;
+
+ if (bcmp(&hd->nh_id, id, sizeof (ndr_hdid_t)) == 0) {
+ if (hd->nh_svc == svc) {
+ *pphd = hd->nh_next;
+ free(hd);
+ }
+ break;
+ }
+
+ pphd = &(*pphd)->nh_next;
+ }
+
+ (void) mutex_unlock(&ndr_handle_lock);
+}
+
+/*
+ * Lookup a handle by id. If the handle is in the list and it matches
+ * the specified service, a pointer to it is returned. Otherwise a null
+ * pointer is returned.
+ */
+ndr_handle_t *
+ndr_hdlookup(const ndr_xa_t *xa, const ndr_hdid_t *id)
+{
+ mlrpc_service_t *svc = xa->binding->service;
+ ndr_handle_t *hd;
+
+ assert(id);
+ (void) mutex_lock(&ndr_handle_lock);
+ hd = ndr_handle_list;
+
+ while (hd) {
+ if (bcmp(&hd->nh_id, id, sizeof (ndr_hdid_t)) == 0) {
+ if (hd->nh_svc != svc)
+ break;
+ (void) mutex_unlock(&ndr_handle_lock);
+ return (hd);
+ }
+
+ hd = hd->nh_next;
+ }
+
+ (void) mutex_unlock(&ndr_handle_lock);
+ return (NULL);
+}
+
+/*
+ * Called when a pipe is closed to release any associated handles.
+ */
+void
+ndr_hdclose(int fid)
+{
+ ndr_handle_t *hd;
+ ndr_handle_t **pphd;
+
+ (void) mutex_lock(&ndr_handle_lock);
+ pphd = &ndr_handle_list;
+
+ while (*pphd) {
+ hd = *pphd;
+
+ if (hd->nh_fid == fid) {
+ *pphd = hd->nh_next;
+ free(hd);
+ continue;
+ }
+
+ pphd = &(*pphd)->nh_next;
+ }
+
+ (void) mutex_unlock(&ndr_handle_lock);
+}
+
void
-mlrpc_uuid_to_str(mlrpc_uuid_t *uuid, char *str)
+mlrpc_uuid_to_str(ndr_uuid_t *uuid, char *str)
{
(void) sprintf(str, "%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x",
uuid->data1, uuid->data2, uuid->data3,
@@ -199,7 +353,7 @@ mlrpc_uuid_to_str(mlrpc_uuid_t *uuid, char *str)
}
int
-mlrpc_str_to_uuid(char *str, mlrpc_uuid_t *uuid)
+mlrpc_str_to_uuid(char *str, ndr_uuid_t *uuid)
{
char *p = str;
char *q;
diff --git a/usr/src/lib/smbsrv/libmlsvc/Makefile.com b/usr/src/lib/smbsrv/libmlsvc/Makefile.com
index 60f0c4f66d..0b32262027 100644
--- a/usr/src/lib/smbsrv/libmlsvc/Makefile.com
+++ b/usr/src/lib/smbsrv/libmlsvc/Makefile.com
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -34,7 +34,6 @@ OBJS_COMMON = \
lsar_open.o \
mlsvc_client.o \
mlsvc_dssetup.o \
- mlsvc_handle.o \
mlsvc_init.o \
mlsvc_logr.o \
mlsvc_lsa.o \
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h b/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h
index 71cc37af48..b77dde5340 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h
+++ b/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -41,7 +41,8 @@ extern "C" {
#endif
extern int mlsvc_init(void);
-extern int mlsvc_is_local_domain(const char *);
+extern uint32_t mlsvc_lookup_name(char *, nt_sid_t **, uint16_t *);
+extern uint32_t mlsvc_lookup_sid(nt_sid_t *, char **);
extern DWORD lsa_query_primary_domain_info(void);
extern DWORD lsa_query_account_domain_info(void);
extern DWORD lsa_enum_trusted_domains(void);
@@ -68,168 +69,6 @@ extern void smb_autohome_endent(void);
extern smb_autohome_t *smb_autohome_getent(const char *name);
extern smb_autohome_t *smb_autohome_lookup(const char *name);
-/*
- * Local groups
- */
-#define NT_GROUP_FMRI_PREFIX "network/smb/group"
-
-typedef enum {
- RWLOCK_NONE,
- RWLOCK_WRITER,
- RWLOCK_READER
-} krwmode_t;
-
-typedef struct nt_group_data {
- void *data;
- int size;
-} nt_group_data_t;
-
-/*
- * IMPORTANT NOTE:
- * If you change nt_group_member_t, nt_group_members_t, or nt_group_t
- * structures, you MIGHT have to change following functions accordingly:
- * nt_group_setfields
- * nt_group_init_size
- * nt_group_init
- */
-typedef struct nt_group_member {
- uint16_t info_size; /* size of the whole structure */
- uint16_t sid_name_use; /* type of the specified SID */
- char *account; /* Pointer to account name of member */
- nt_sid_t sid; /* Variable length */
-} nt_group_member_t;
-
-typedef struct nt_group_members {
- uint32_t size; /* in bytes */
- uint32_t count;
- nt_group_member_t list[ANY_SIZE_ARRAY];
-} nt_group_members_t;
-
-typedef struct nt_group {
- time_t age;
- nt_group_data_t info;
- /*
- * following fields point to a contigous block
- * of memory that is read and written from/to DB
- */
- uint32_t *attr;
- uint16_t *sid_name_use;
- char *name;
- char *comment;
- nt_sid_t *sid;
- smb_privset_t *privileges;
- nt_group_members_t *members;
-} nt_group_t;
-
-typedef struct nt_group_iterator {
- HT_ITERATOR *iterator;
- int iteration;
-} nt_group_iterator_t;
-
-extern int nt_group_num_groups(void);
-extern uint32_t nt_group_add(char *, char *);
-extern uint32_t nt_group_modify(char *, char *, char *);
-extern uint32_t nt_group_delete(char *);
-extern nt_group_t *nt_group_getinfo(char *, krwmode_t);
-extern void nt_group_putinfo(nt_group_t *);
-
-extern int nt_group_getpriv(nt_group_t *, uint32_t);
-extern uint32_t nt_group_setpriv(nt_group_t *, uint32_t, uint32_t);
-
-/* Member manipulation functions */
-extern int nt_group_is_member(nt_group_t *, nt_sid_t *);
-extern uint32_t nt_group_del_member(nt_group_t *, void *, int);
-extern uint32_t nt_group_add_member(nt_group_t *, nt_sid_t *, uint16_t, char *);
-extern int nt_group_num_members(nt_group_t *);
-
-extern void nt_group_ht_lock(krwmode_t);
-extern void nt_group_ht_unlock(void);
-
-extern nt_group_iterator_t *nt_group_open_iterator(void);
-extern void nt_group_close_iterator(nt_group_iterator_t *);
-extern nt_group_t *nt_group_iterate(nt_group_iterator_t *);
-
-extern int nt_group_cache_size(void);
-
-extern int nt_group_member_list(int offset, nt_group_t *grp,
- ntgrp_member_list_t *rmembers);
-extern void nt_group_list(int offset, char *pattern, ntgrp_list_t *list);
-
-extern uint32_t sam_init(void);
-
-extern uint32_t nt_group_add_member_byname(char *, char *);
-extern uint32_t nt_group_del_member_byname(nt_group_t *, char *);
-extern void nt_group_add_groupprivs(nt_group_t *, smb_privset_t *);
-
-extern uint32_t nt_groups_member_privs(nt_sid_t *, smb_privset_t *);
-extern int nt_groups_member_ngroups(nt_sid_t *);
-extern uint32_t nt_groups_member_groups(nt_sid_t *, smb_id_t *, int);
-extern nt_group_t *nt_groups_lookup_rid(uint32_t);
-extern int nt_groups_count(int);
-
-/*
- * source for account name size is MSDN
- */
-#define NT_GROUP_NAME_CHAR_MAX 32
-#define NT_GROUP_NAME_MAX (NT_GROUP_NAME_CHAR_MAX * 3 + 1)
-#define NT_GROUP_USER_NAME_MAX (NT_GROUP_NAME_CHAR_MAX * 3 + 1)
-#define NT_GROUP_MEMBER_NAME_MAX (NT_GROUP_NAME_CHAR_MAX * 3 + 1)
-#define NT_GROUP_COMMENT_MAX 256
-
-/*
- * flags for count operation
- */
-#define NT_GROUP_CNT_BUILTIN 1
-#define NT_GROUP_CNT_LOCAL 2
-#define NT_GROUP_CNT_ALL 3
-
-/*
- * flag to distinguish between add and modify
- * operations.
- */
-#define NT_GROUP_OP_CHANGE 1
-#define NT_GROUP_OP_SYNC 2
-
-/*
- * specify key type for deleting a member i.e.
- * whether it's member's name or member's SID.
- */
-#define NT_GROUP_KEY_SID 1
-#define NT_GROUP_KEY_NAME 2
-
-/* Macro for walking members */
-#define NEXT_MEMBER(m) (nt_group_member_t *)((char *)(m) + (m)->info_size)
-
-/*
- * When NT requests the security descriptor for a local file that
- * doesn't already have a one, we generate one on-the-fly. The SD
- * contains both user and group SIDs. The problem is that we need a
- * way to distinguish a user SID from a group SID when NT performs a
- * subsequent SID lookup to obtain the appropriate name to display.
- * The following macros are used to map to and from an external
- * representation so that we can tell the difference between UIDs
- * and GIDs. The local UID/GID is shifted left and the LSB is used
- * to distinguish the id type before it is inserted into the SID.
- * We can then use this type identifier during lookup operations.
- */
-#define SAM_MIN_RID 1000
-#define SAM_RT_ERROR -1
-#define SAM_RT_UNIX_UID 0
-#define SAM_RT_UNIX_GID 1
-#define SAM_RT_NT_UID 2
-#define SAM_RT_NT_GID 3
-#define SAM_RT_MASK 0x3
-#define SAM_RT_EVERYONE 4
-#define SAM_RT_UNKNOWN 5
-
-#define SAM_RID_TYPE(rid) ((rid) & SAM_RT_MASK)
-#define SAM_DECODE_RID(rid) (((rid) - SAM_MIN_RID) >> 2)
-#define SAM_ENCODE_RID(type, id) ((((id) << 2) | type) + SAM_MIN_RID)
-#define SAM_ENCODE_UXUID(id) SAM_ENCODE_RID(SAM_RT_UNIX_UID, id)
-#define SAM_ENCODE_UXGID(id) SAM_ENCODE_RID(SAM_RT_UNIX_GID, id)
-#define SAM_ENCODE_NTUID(id) SAM_ENCODE_RID(SAM_RT_NT_UID, id)
-#define SAM_ENCODE_NTGID(id) SAM_ENCODE_RID(SAM_RT_NT_GID, id)
-
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/lmshare.c b/usr/src/lib/smbsrv/libmlsvc/common/lmshare.c
index 5fb02b71f4..d131db4144 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/lmshare.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/lmshare.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -989,55 +989,6 @@ lmshare_setinfo(lmshare_info_t *si, int doshm)
return (res);
}
-/*
- * lmshare_decode_type
- *
- * Gets a SMB share type as an integer value and return
- * a string name for it.
- */
-static char *
-lmshare_decode_type(uint_t stype)
-{
- switch (stype) {
- case STYPE_DISKTREE:
- return ("Disk");
- case STYPE_PRINTQ:
- return ("Print Queue");
- case STYPE_DEVICE:
- return ("Device");
- case STYPE_IPC:
- return ("IPC");
- case STYPE_DFS:
- return ("DFS");
- case STYPE_SPECIAL:
- return ("Special");
- default:
- return ("Unknown");
- /* NOTREACHED */
- };
-}
-
-/*
- * lmshare_loginfo
- *
- * Decodes and writes the information of the given
- * share to the specified file.
- */
-void
-lmshare_loginfo(FILE *fp, lmshare_info_t *si)
-{
- (void) fprintf(fp, "\n%s Information:\n", si->share_name);
- (void) fprintf(fp, "\tFolder: %s\n", si->directory);
- (void) fprintf(fp, "\tType: %s\n",
- lmshare_decode_type((uint_t)si->stype));
- (void) fprintf(fp, "\tComment: %s\n", si->comment);
-
- (void) fprintf(fp, "\tStatus: %s\n",
- ((si->mode & LMSHRM_TRANS) ? "Transient" : "Permanent"));
-
- (void) fprintf(fp, "\tContainer: %s\n", si->container);
-}
-
DWORD
lmshare_list(int offset, lmshare_list_t *list)
{
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/lsalib.c b/usr/src/lib/smbsrv/libmlsvc/common/lsalib.c
index 8e2effc333..4873d508cc 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/lsalib.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/lsalib.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -32,6 +32,8 @@
#include <strings.h>
#include <unistd.h>
#include <netdb.h>
+#include <pwd.h>
+#include <grp.h>
#include <smbsrv/libsmb.h>
#include <smbsrv/libsmbns.h>
@@ -43,9 +45,111 @@
#include <smbsrv/ntsid.h>
#include <smbsrv/smb_token.h>
+/*
+ * Name Lookup modes
+ */
+#define MLSVC_LOOKUP_BUILTIN 1
+#define MLSVC_LOOKUP_LOCAL 2
+#define MLSVC_LOOKUP_DOMAIN 3
+#define MLSVC_LOOKUP_DOMLOC 4
+
+static int lsa_lookup_mode(const char *, const char *);
+static uint32_t lsa_lookup_name_builtin(char *, smb_userinfo_t *);
+static uint32_t lsa_lookup_name_local(char *, char *, uint16_t,
+ smb_userinfo_t *);
+static uint32_t lsa_lookup_name_lusr(char *, nt_sid_t **);
+static uint32_t lsa_lookup_name_lgrp(char *, nt_sid_t **);
+static uint32_t lsa_lookup_name_domain(char *, char *, char *,
+ smb_userinfo_t *);
+
+static uint32_t lsa_lookup_sid_builtin(nt_sid_t *, smb_userinfo_t *);
+static uint32_t lsa_lookup_sid_local(nt_sid_t *, smb_userinfo_t *);
+static uint32_t lsa_lookup_sid_domain(nt_sid_t *, smb_userinfo_t *);
+
static int lsa_list_accounts(mlsvc_handle_t *);
/*
+ * lsa_lookup_name
+ *
+ * Lookup the given account and returns the account information
+ * in 'ainfo'
+ *
+ * If the name is a domain account, it may refer to a user, group or
+ * alias. If it is a local account, its type should be specified
+ * in the sid_type parameter. In case the account type is unknown
+ * sid_type should be set to SidTypeUnknown.
+ *
+ * account argument could be either [domain\\]name or [domain/]name.
+ * If domain is not specified and service is in domain mode then it
+ * first does a domain lookup and then a local lookup.
+ */
+uint32_t
+lsa_lookup_name(char *server, char *account, uint16_t sid_type,
+ smb_userinfo_t *ainfo)
+{
+ nt_domain_t *dominfo;
+ int lookup_mode;
+ char *name;
+ char *domain;
+ uint32_t status = NT_STATUS_NONE_MAPPED;
+
+ (void) strsubst(account, '\\', '/');
+ name = strchr(account, '/');
+ if (name) {
+ /* domain is specified */
+ *name++ = '\0';
+ domain = account;
+ } else {
+ name = account;
+ domain = NULL;
+ }
+
+ lookup_mode = lsa_lookup_mode(domain, name);
+
+ switch (lookup_mode) {
+ case MLSVC_LOOKUP_BUILTIN:
+ return (lsa_lookup_name_builtin(name, ainfo));
+
+ case MLSVC_LOOKUP_LOCAL:
+ return (lsa_lookup_name_local(domain, name, sid_type, ainfo));
+
+ case MLSVC_LOOKUP_DOMAIN:
+ return (lsa_lookup_name_domain(server, domain, name, ainfo));
+
+ default:
+ /* lookup the name in domain */
+ dominfo = nt_domain_lookupbytype(NT_DOMAIN_PRIMARY);
+ if (dominfo == NULL)
+ return (NT_STATUS_INTERNAL_ERROR);
+ status = lsa_lookup_name_domain(server, dominfo->name, name,
+ ainfo);
+ if (status != NT_STATUS_NONE_MAPPED)
+ return (status);
+
+ mlsvc_release_user_info(ainfo);
+ /* lookup the name locally */
+ status = lsa_lookup_name_local(domain, name, sid_type, ainfo);
+ }
+
+ return (status);
+}
+
+uint32_t
+lsa_lookup_sid(nt_sid_t *sid, smb_userinfo_t *ainfo)
+{
+ if (!nt_sid_is_valid(sid))
+ return (NT_STATUS_INVALID_SID);
+
+ if (nt_sid_is_local(sid))
+ return (lsa_lookup_sid_local(sid, ainfo));
+
+ if (nt_builtin_lookup_sid(sid, NULL))
+ return (lsa_lookup_sid_builtin(sid, ainfo));
+
+ return (lsa_lookup_sid_domain(sid, ainfo));
+}
+
+/*
* lsa_query_primary_domain_info
*
* Obtains the primary domain SID and name from the specified server
@@ -138,174 +242,115 @@ lsa_enum_trusted_domains(void)
}
/*
- * lsa_test_lookup
- *
- * Test routine for lsa_lookup_name and lsa_lookup_sid.
- */
-void
-lsa_test_lookup(char *name)
-{
- smb_userinfo_t *user_info;
- nt_sid_t *sid;
- DWORD status;
- smb_ntdomain_t *di;
-
- if ((di = smb_getdomaininfo(0)) == 0)
- return;
-
- user_info = mlsvc_alloc_user_info();
-
- if (lsa_lookup_builtin_name(name, user_info) != 0) {
- status = lsa_lookup_name(di->server, di->domain, name,
- user_info);
-
- if (status == 0) {
- sid = nt_sid_splice(user_info->domain_sid,
- user_info->rid);
-
- (void) lsa_lookup_sid(sid, user_info);
- free(sid);
- }
- }
-
- mlsvc_free_user_info(user_info);
-}
-
-/*
- * lsa_lookup_builtin_name
+ * lsa_lookup_name_builtin
*
* lookup builtin account table to see if account_name is
* there. If it is there, set sid_name_use, domain_sid,
* domain_name, and rid fields of the passed user_info
- * structure and return 0. If lookup fails return 1.
+ * structure.
*/
-int
-lsa_lookup_builtin_name(char *account_name, smb_userinfo_t *user_info)
+static uint32_t
+lsa_lookup_name_builtin(char *account_name, smb_userinfo_t *user_info)
{
char *domain;
int res;
- user_info->domain_sid = nt_builtin_lookup_name(account_name,
+ user_info->user_sid = nt_builtin_lookup_name(account_name,
&user_info->sid_name_use);
- if (user_info->domain_sid == 0)
- return (1);
+ if (user_info->user_sid == NULL)
+ return (NT_STATUS_NONE_MAPPED);
+ user_info->domain_sid = nt_sid_dup(user_info->user_sid);
res = nt_sid_split(user_info->domain_sid, &user_info->rid);
if (res < 0)
- return (1);
+ return (NT_STATUS_INTERNAL_ERROR);
domain = nt_builtin_lookup_domain(account_name);
if (domain) {
user_info->domain_name = strdup(domain);
- return (0);
+ return (NT_STATUS_SUCCESS);
}
- return (1);
+ return (NT_STATUS_INTERNAL_ERROR);
}
/*
- * lsa_lookup_local_sam
+ * lsa_lookup_name_local
*
- * lookup for the given account name in the local SAM database.
- * Returns 0 on success. If lookup fails return 1.
- */
-int
-lsa_lookup_local_sam(char *domain, char *account_name,
- smb_userinfo_t *user_info)
-{
- nt_group_t *grp;
-
- if (*domain == '\0' || *account_name == '\0')
- return (1);
-
- grp = nt_group_getinfo(account_name, RWLOCK_READER);
- if (grp == 0)
- return (1);
-
- user_info->sid_name_use = *grp->sid_name_use;
- user_info->domain_sid = nt_sid_dup(grp->sid);
- nt_group_putinfo(grp);
-
- if (user_info->domain_sid == 0)
- return (1);
-
- (void) nt_sid_split(user_info->domain_sid, &user_info->rid);
- user_info->domain_name = strdup(domain);
-
- if (user_info->domain_name == 0) {
- free(user_info->domain_sid);
- user_info->domain_sid = 0;
- return (1);
- }
-
- return (0);
-}
-
-/*
- * lsa_lookup_local
+ * Obtains the infomation for the given local account name if it
+ * can be found. The type of account is specified by sid_type,
+ * which can be of user, group or unknown type. If the caller
+ * doesn't know whether the name is a user or group name then
+ * SidTypeUnknown should be passed, in which case this
+ * function first tries to find a user and then a group match.
*
- * if given account name has domain part, check to see if
- * it matches with host name or any of host's primary addresses.
- * if any match found first lookup in builtin accounts table and
- * then in local SAM table.
- *
- * if account name doesn't have domain part, first do local lookups
- * if nothing is found return 1. This means that caller function should
- * do domain lookup.
- * if any error happened return -1, if name is found return 0.
+ * CAVEAT: if there are both a user and a group account with
+ * the same name, user SID will always be returned.
*/
-int
-lsa_lookup_local(char *name, smb_userinfo_t *user_info)
+static uint32_t
+lsa_lookup_name_local(char *domain, char *name, uint16_t sid_type,
+ smb_userinfo_t *ainfo)
{
char hostname[MAXHOSTNAMELEN];
- int res = 0;
- int local_lookup = 0;
- char *tmp;
- net_cfg_t cfg;
- uint32_t addr;
-
- if (smb_gethostname(hostname, MAXHOSTNAMELEN, 1) != 0)
- return (-1);
-
- tmp = strchr(name, '\\');
- if (tmp != 0) {
- *tmp = 0;
- if (strcasecmp(name, hostname) == 0)
- local_lookup = 1;
-
- if (!local_lookup) {
- addr = inet_addr(name);
- if (smb_nic_get_byip(addr, &cfg) != NULL) {
- local_lookup = 1;
- }
- }
-
- if (!local_lookup) {
- /* do domain lookup */
- *tmp = '\\';
- return (1);
- }
-
- name = tmp + 1;
- local_lookup = 1;
+ nt_sid_t *sid;
+ uint32_t status;
+
+ switch (sid_type) {
+ case SidTypeUser:
+ status = lsa_lookup_name_lusr(name, &sid);
+ if (status != NT_STATUS_SUCCESS)
+ return (status);
+ break;
+
+ case SidTypeGroup:
+ case SidTypeAlias:
+ status = lsa_lookup_name_lgrp(name, &sid);
+ if (status != NT_STATUS_SUCCESS)
+ return (status);
+ break;
+
+ case SidTypeUnknown:
+ sid_type = SidTypeUser;
+ status = lsa_lookup_name_lusr(name, &sid);
+ if (status == NT_STATUS_SUCCESS)
+ break;
+
+ if (status == NT_STATUS_NONE_MAPPED)
+ return (status);
+
+ sid_type = SidTypeAlias;
+ status = lsa_lookup_name_lgrp(name, &sid);
+ if (status != NT_STATUS_SUCCESS)
+ return (status);
+ break;
+
+ default:
+ return (NT_STATUS_INVALID_PARAMETER);
}
- res = lsa_lookup_builtin_name(name, user_info);
- if (res != 0)
- res = lsa_lookup_local_sam(hostname, name, user_info);
-
- if (res == 0)
- return (0);
+ ainfo->sid_name_use = sid_type;
+ ainfo->user_sid = sid;
+ ainfo->domain_sid = nt_sid_dup(sid);
+ if (ainfo->domain_sid == NULL)
+ return (NT_STATUS_NO_MEMORY);
+
+ (void) nt_sid_split(ainfo->domain_sid, &ainfo->rid);
+ if ((domain == NULL) || (*domain == '\0')) {
+ (void) smb_getnetbiosname(hostname, sizeof (hostname));
+ ainfo->domain_name = strdup(hostname);
+ } else {
+ ainfo->domain_name = strdup(domain);
+ }
- if (local_lookup)
- return (-1);
+ if (ainfo->domain_name == NULL)
+ return (NT_STATUS_NO_MEMORY);
- return (1);
+ return (NT_STATUS_SUCCESS);
}
/*
- * lsa_lookup_name
+ * lsa_lookup_name_domain
*
* Lookup a name on the specified server (domain controller) and obtain
* the appropriate SID. The information is returned in the user_info
@@ -314,41 +359,16 @@ lsa_lookup_local(char *name, smb_userinfo_t *user_info)
* type of SID. If the name is the domain name, this function will be
* identical to lsa_domain_info. Otherwise the rid and name fields will
* also be valid. On failure sid_name_use will be set to SidTypeUnknown.
- *
- * On success 0 is returned. Otherwise a -ve error code.
- */
-int lsa_lookup_name(char *server, char *domain, char *account_name,
- smb_userinfo_t *user_info)
-{
- mlsvc_handle_t domain_handle;
- int rc;
- char *user = smbrdr_ipc_get_user();
-
- rc = lsar_open(server, domain, user, &domain_handle);
- if (rc != 0)
- return (-1);
-
- rc = lsar_lookup_names(&domain_handle, account_name, user_info);
-
- (void) lsar_close(&domain_handle);
- return (rc);
-}
-
-/*
- * lsa_lookup_name2
- *
- * Returns NT status codes.
*/
-DWORD lsa_lookup_name2(char *server, char *domain, char *account_name,
+static uint32_t
+lsa_lookup_name_domain(char *server, char *domain, char *account_name,
smb_userinfo_t *user_info)
{
mlsvc_handle_t domain_handle;
- DWORD status;
- int rc;
char *user = smbrdr_ipc_get_user();
+ uint32_t status;
- rc = lsar_open(server, domain, user, &domain_handle);
- if (rc != 0)
+ if (lsar_open(server, domain, user, &domain_handle) != 0)
return (NT_STATUS_INVALID_PARAMETER);
status = lsar_lookup_names2(&domain_handle, account_name, user_info);
@@ -357,76 +377,8 @@ DWORD lsa_lookup_name2(char *server, char *domain, char *account_name,
* Not a Windows 2000 domain controller:
* use the NT compatible call.
*/
- if (lsar_lookup_names(&domain_handle, account_name,
- user_info) != 0)
- status = NT_STATUS_NONE_MAPPED;
- else
- status = 0;
- }
-
- (void) lsar_close(&domain_handle);
- return (status);
-}
-
-/*
- * lsa_lookup_sid
- *
- * Lookup a SID on the specified server (domain controller) and obtain
- * the appropriate name. The information is returned in the user_info
- * structure. The caller is responsible for allocating and releasing
- * this structure. On success sid_name_use will be set to indicate the
- * type of SID. On failure sid_name_use will be set to SidTypeUnknown.
- *
- * On success 0 is returned. Otherwise a -ve error code.
- */
-int
-lsa_lookup_sid(nt_sid_t *sid, smb_userinfo_t *user_info)
-{
- mlsvc_handle_t domain_handle;
- int rc;
- char *user = smbrdr_ipc_get_user();
-
- rc = lsar_open(NULL, NULL, user, &domain_handle);
- if (rc != 0)
- return (-1);
-
- rc = lsar_lookup_sids(&domain_handle,
- (struct mslsa_sid *)sid, user_info);
-
- (void) lsar_close(&domain_handle);
- return (rc);
-}
-
-/*
- * lsa_lookup_sid2
- *
- * Returns NT status codes.
- */
-DWORD
-lsa_lookup_sid2(nt_sid_t *sid, smb_userinfo_t *user_info)
-{
- mlsvc_handle_t domain_handle;
- DWORD status;
- int rc;
- char *user = smbrdr_ipc_get_user();
-
- rc = lsar_open(NULL, NULL, user, &domain_handle);
- if (rc != 0)
- return (NT_STATUS_INVALID_PARAMETER);
-
- status = lsar_lookup_sids2(&domain_handle,
- (struct mslsa_sid *)sid, user_info);
-
- if (status == NT_STATUS_REVISION_MISMATCH) {
- /*
- * Not a Windows 2000 domain controller:
- * use the NT compatible call.
- */
- if (lsar_lookup_sids(&domain_handle, (struct mslsa_sid *)sid,
- user_info) != 0)
- status = NT_STATUS_NONE_MAPPED;
- else
- status = 0;
+ status = lsar_lookup_names(&domain_handle, account_name,
+ user_info);
}
(void) lsar_close(&domain_handle);
@@ -434,12 +386,12 @@ lsa_lookup_sid2(nt_sid_t *sid, smb_userinfo_t *user_info)
}
/*
- * lsa_test_lookup2
+ * lsa_test_lookup
*
- * Test routine for lsa_lookup_name2 and lsa_lookup_sid2.
+ * Test routine for lsa_lookup_name_domain and lsa_lookup_sid2.
*/
void
-lsa_test_lookup2(char *name)
+lsa_test_lookup(char *name)
{
smb_userinfo_t *user_info;
nt_sid_t *sid;
@@ -451,15 +403,15 @@ lsa_test_lookup2(char *name)
user_info = mlsvc_alloc_user_info();
- if (lsa_lookup_builtin_name(name, user_info) != 0) {
- status = lsa_lookup_name2(di->server, di->domain, name,
+ if (lsa_lookup_name_builtin(name, user_info) != 0) {
+ status = lsa_lookup_name_domain(di->server, di->domain, name,
user_info);
if (status == 0) {
sid = nt_sid_splice(user_info->domain_sid,
user_info->rid);
- (void) lsa_lookup_sid2(sid, user_info);
+ (void) lsa_lookup_sid_domain(sid, user_info);
free(sid);
}
}
@@ -627,3 +579,177 @@ lsa_list_accounts(mlsvc_handle_t *domain_handle)
mlsvc_free_user_info(user_info);
return (0);
}
+
+/*
+ * lsa_lookup_name_lusr
+ *
+ * Obtains the SID for the given local user name if it
+ * can be found. Upon successful return the allocated memory
+ * for the returned SID must be freed by the caller.
+ *
+ * Note that in domain mode this function might actually return
+ * a domain SID if local users are mapped to domain users.
+ */
+static uint32_t
+lsa_lookup_name_lusr(char *name, nt_sid_t **sid)
+{
+ struct passwd *pw;
+
+ if ((pw = getpwnam(name)) == NULL)
+ return (NT_STATUS_NO_SUCH_USER);
+
+ if (smb_idmap_getsid(pw->pw_uid, SMB_IDMAP_USER, sid) != IDMAP_SUCCESS)
+ return (NT_STATUS_NONE_MAPPED);
+
+ return (NT_STATUS_SUCCESS);
+}
+
+/*
+ * lsa_lookup_name_lgrp
+ *
+ * Obtains the SID for the given local group name if it
+ * can be found. Upon successful return the allocated memory
+ * for the returned SID must be freed by the caller.
+ *
+ * Note that in domain mode this function might actually return
+ * a domain SID if local groups are mapped to domain groups.
+ */
+static uint32_t
+lsa_lookup_name_lgrp(char *name, nt_sid_t **sid)
+{
+ struct group *gr;
+
+ if ((gr = getgrnam(name)) == NULL)
+ return (NT_STATUS_NO_SUCH_ALIAS);
+
+ if (smb_idmap_getsid(gr->gr_gid, SMB_IDMAP_GROUP, sid) != IDMAP_SUCCESS)
+ return (NT_STATUS_NONE_MAPPED);
+
+ return (NT_STATUS_SUCCESS);
+}
+
+static int
+lsa_lookup_mode(const char *domain, const char *name)
+{
+ int lookup_mode;
+
+ if (nt_builtin_lookup((char *)name))
+ return (MLSVC_LOOKUP_BUILTIN);
+
+ if (smb_config_get_secmode() == SMB_SECMODE_WORKGRP)
+ return (MLSVC_LOOKUP_LOCAL);
+
+ if ((domain == NULL) || (*domain == '\0'))
+ return (MLSVC_LOOKUP_DOMLOC);
+
+ if (mlsvc_is_local_domain(domain) == 1)
+ lookup_mode = MLSVC_LOOKUP_LOCAL;
+ else
+ lookup_mode = MLSVC_LOOKUP_DOMAIN;
+
+ return (lookup_mode);
+}
+
+static uint32_t
+lsa_lookup_sid_local(nt_sid_t *sid, smb_userinfo_t *ainfo)
+{
+ char hostname[MAXHOSTNAMELEN];
+ struct passwd *pw;
+ struct group *gr;
+ uid_t id;
+ int id_type;
+
+ id_type = SMB_IDMAP_UNKNOWN;
+ if (smb_idmap_getid(sid, &id, &id_type) != IDMAP_SUCCESS)
+ return (NT_STATUS_NONE_MAPPED);
+
+ switch (id_type) {
+ case SMB_IDMAP_USER:
+ ainfo->sid_name_use = SidTypeUser;
+ if ((pw = getpwuid(id)) == NULL)
+ return (NT_STATUS_NO_SUCH_USER);
+
+ ainfo->name = strdup(pw->pw_name);
+ break;
+
+ case SMB_IDMAP_GROUP:
+ ainfo->sid_name_use = SidTypeAlias;
+ if ((gr = getgrgid(id)) == NULL)
+ return (NT_STATUS_NO_SUCH_ALIAS);
+
+ ainfo->name = strdup(gr->gr_name);
+ break;
+
+ default:
+ return (NT_STATUS_NONE_MAPPED);
+ }
+
+ if (ainfo->name == NULL)
+ return (NT_STATUS_NO_MEMORY);
+
+ ainfo->domain_sid = nt_sid_dup(sid);
+ if (nt_sid_split(ainfo->domain_sid, &ainfo->rid) < 0)
+ return (NT_STATUS_INTERNAL_ERROR);
+ *hostname = '\0';
+ (void) smb_getnetbiosname(hostname, MAXHOSTNAMELEN);
+ if ((ainfo->domain_name = strdup(hostname)) == NULL)
+ return (NT_STATUS_NO_MEMORY);
+
+ return (NT_STATUS_SUCCESS);
+}
+
+static uint32_t
+lsa_lookup_sid_builtin(nt_sid_t *sid, smb_userinfo_t *ainfo)
+{
+ char *name;
+ WORD sid_name_use;
+
+ if ((name = nt_builtin_lookup_sid(sid, &sid_name_use)) == NULL)
+ return (NT_STATUS_NONE_MAPPED);
+
+ ainfo->sid_name_use = sid_name_use;
+ ainfo->name = strdup(name);
+ ainfo->domain_sid = nt_sid_dup(sid);
+
+ if (ainfo->name == NULL || ainfo->domain_sid == NULL)
+ return (NT_STATUS_NO_MEMORY);
+
+ if (sid_name_use != SidTypeDomain)
+ (void) nt_sid_split(ainfo->domain_sid, &ainfo->rid);
+
+ if ((name = nt_builtin_lookup_domain(ainfo->name)) != NULL)
+ ainfo->domain_name = strdup(name);
+ else
+ ainfo->domain_name = strdup("UNKNOWN");
+
+ if (ainfo->domain_name == NULL)
+ return (NT_STATUS_NO_MEMORY);
+
+ return (NT_STATUS_SUCCESS);
+}
+
+static uint32_t
+lsa_lookup_sid_domain(nt_sid_t *sid, smb_userinfo_t *ainfo)
+{
+ mlsvc_handle_t domain_handle;
+ char *user = smbrdr_ipc_get_user();
+ uint32_t status;
+
+ if (lsar_open(NULL, NULL, user, &domain_handle) != 0)
+ return (NT_STATUS_INVALID_PARAMETER);
+
+ status = lsar_lookup_sids2(&domain_handle,
+ (struct mslsa_sid *)sid, ainfo);
+
+ if (status == NT_STATUS_REVISION_MISMATCH) {
+ /*
+ * Not a Windows 2000 domain controller:
+ * use the NT compatible call.
+ */
+ status = lsar_lookup_sids(&domain_handle,
+ (struct mslsa_sid *)sid, ainfo);
+ }
+
+ (void) lsar_close(&domain_handle);
+ return (status);
+}
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/lsar_lookup.c b/usr/src/lib/smbsrv/libmlsvc/common/lsar_lookup.c
index 5216818cce..f8f21e08cc 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/lsar_lookup.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/lsar_lookup.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -175,15 +175,15 @@ lsar_query_info_policy(mlsvc_handle_t *lsa_handle, WORD infoClass)
* If the lookup fails, the status will typically be
* NT_STATUS_NONE_MAPPED.
*/
-int
+uint32_t
lsar_lookup_names(mlsvc_handle_t *lsa_handle, char *name,
smb_userinfo_t *user_info)
{
struct mlsvc_rpc_context *context;
mlrpc_heapref_t heap;
int opnum;
- int rc;
int index;
+ uint32_t status;
struct mslsa_LookupNames arg;
size_t length;
lookup_name_table_t name_table;
@@ -192,7 +192,7 @@ lsar_lookup_names(mlsvc_handle_t *lsa_handle, char *name,
char *p;
if (lsa_handle == NULL || name == NULL || user_info == NULL)
- return (-1);
+ return (NT_STATUS_INVALID_PARAMETER);
bzero(user_info, sizeof (smb_userinfo_t));
user_info->sid_name_use = SidTypeUnknown;
@@ -239,35 +239,39 @@ lsar_lookup_names(mlsvc_handle_t *lsa_handle, char *name,
name_table.name[0].str = (unsigned char *)name;
(void) mlsvc_rpc_init(&heap);
- rc = mlsvc_rpc_call(context, opnum, &arg, &heap);
- if (rc == 0) {
- if (arg.status != 0) {
- rc = -1;
- } else if (arg.mapped_count == 0) {
- rc = -1;
+ if (mlsvc_rpc_call(context, opnum, &arg, &heap) != 0) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ } else if (arg.status != 0) {
+ mlsvc_rpc_report_status(opnum, arg.status);
+ status = NT_SC_VALUE(arg.status);
+ } else if (arg.mapped_count == 0) {
+ user_info->sid_name_use = SidTypeInvalid;
+ status = NT_STATUS_NONE_MAPPED;
+ } else {
+ rid_entry = &arg.translated_sids.rids[0];
+ user_info->sid_name_use = rid_entry->sid_name_use;
+ user_info->rid = rid_entry->rid;
+ user_info->name = MEM_STRDUP("mlrpc", name);
+
+ if ((index = rid_entry->domain_index) == -1) {
+ user_info->domain_sid = 0;
+ user_info->domain_name = 0;
} else {
- rid_entry = &arg.translated_sids.rids[0];
- user_info->sid_name_use = rid_entry->sid_name_use;
- user_info->rid = rid_entry->rid;
- user_info->name = MEM_STRDUP("mlrpc", name);
-
- if ((index = rid_entry->domain_index) == -1) {
- user_info->domain_sid = 0;
- user_info->domain_name = 0;
- } else {
- domain_entry =
- &arg.domain_table->entries[index];
- user_info->domain_sid = nt_sid_dup(
- (nt_sid_t *)domain_entry->domain_sid);
- user_info->domain_name = MEM_STRDUP("mlrpc",
- (const char *)
- domain_entry->domain_name.str);
- }
+ domain_entry =
+ &arg.domain_table->entries[index];
+ user_info->domain_sid = nt_sid_dup(
+ (nt_sid_t *)domain_entry->domain_sid);
+ user_info->domain_name = MEM_STRDUP("mlrpc",
+ (const char *)
+ domain_entry->domain_name.str);
+ user_info->user_sid = nt_sid_splice(
+ user_info->domain_sid, user_info->rid);
}
+ status = NT_STATUS_SUCCESS;
}
mlsvc_rpc_free(context, &heap);
- return (rc);
+ return (status);
}
/*
@@ -279,7 +283,7 @@ lsar_lookup_names(mlsvc_handle_t *lsa_handle, char *name,
* level 2 but for now we want to restrict it to level 1 so that we
* don't crash the PDC when we get things wrong.
*/
-int
+uint32_t
lsar_lookup_sids(mlsvc_handle_t *lsa_handle, struct mslsa_sid *sid,
smb_userinfo_t *user_info)
{
@@ -290,11 +294,11 @@ lsar_lookup_sids(mlsvc_handle_t *lsa_handle, struct mslsa_sid *sid,
struct mlsvc_rpc_context *context;
mlrpc_heapref_t heap;
int opnum;
- int rc;
int index;
+ uint32_t status;
if (lsa_handle == NULL || sid == NULL || user_info == NULL)
- return (-1);
+ return (NT_STATUS_INVALID_PARAMETER);
context = lsa_handle->context;
opnum = LSARPC_OPNUM_LookupSids;
@@ -308,45 +312,48 @@ lsar_lookup_sids(mlsvc_handle_t *lsa_handle, struct mslsa_sid *sid,
arg.lup_sid_table.entries = &sid_entry;
(void) mlsvc_rpc_init(&heap);
- rc = mlsvc_rpc_call(context, opnum, &arg, &heap);
- if (rc == 0) {
- if (arg.mapped_count == 0) {
- user_info->sid_name_use = SidTypeInvalid;
- rc = 1;
- } else {
- name_entry = &arg.name_table.entries[0];
- user_info->sid_name_use = name_entry->sid_name_use;
+ if (mlsvc_rpc_call(context, opnum, &arg, &heap) != 0) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ } else if (arg.mapped_count == 0) {
+ user_info->sid_name_use = SidTypeInvalid;
+ status = NT_STATUS_NONE_MAPPED;
+ } else if (arg.status != 0) {
+ mlsvc_rpc_report_status(opnum, arg.status);
+ status = NT_SC_VALUE(arg.status);
+ } else {
+ name_entry = &arg.name_table.entries[0];
+ user_info->sid_name_use = name_entry->sid_name_use;
- if (user_info->sid_name_use == SidTypeUser ||
- user_info->sid_name_use == SidTypeGroup ||
- user_info->sid_name_use == SidTypeAlias) {
+ if (user_info->sid_name_use == SidTypeUser ||
+ user_info->sid_name_use == SidTypeGroup ||
+ user_info->sid_name_use == SidTypeAlias) {
- user_info->rid =
- sid->SubAuthority[sid->SubAuthCount - 1];
+ user_info->rid =
+ sid->SubAuthority[sid->SubAuthCount - 1];
- user_info->name = MEM_STRDUP("mlrpc",
- (const char *)name_entry->name.str);
- }
+ user_info->name = MEM_STRDUP("mlrpc",
+ (const char *)name_entry->name.str);
+ }
- if ((index = name_entry->domain_ix) == -1) {
- user_info->domain_sid = 0;
- user_info->domain_name = 0;
- } else {
- domain_entry =
- &arg.domain_table->entries[index];
+ if ((index = name_entry->domain_ix) == -1) {
+ user_info->domain_sid = 0;
+ user_info->domain_name = 0;
+ } else {
+ domain_entry =
+ &arg.domain_table->entries[index];
- user_info->domain_sid = nt_sid_dup(
- (nt_sid_t *)domain_entry->domain_sid);
+ user_info->domain_sid = nt_sid_dup(
+ (nt_sid_t *)domain_entry->domain_sid);
- user_info->domain_name = MEM_STRDUP("mlrpc",
- (const char *)
- domain_entry->domain_name.str);
- }
+ user_info->domain_name = MEM_STRDUP("mlrpc",
+ (const char *)
+ domain_entry->domain_name.str);
}
+ status = NT_STATUS_SUCCESS;
}
mlsvc_rpc_free(context, &heap);
- return (rc);
+ return (status);
}
/*
@@ -728,8 +735,6 @@ lsar_lookup_sids2(mlsvc_handle_t *lsa_handle, struct mslsa_sid *sid,
mlsvc_rpc_report_status(opnum, arg.status);
status = NT_SC_VALUE(arg.status);
} else {
- status = 0;
-
name_entry = &arg.name_table.entries[0];
user_info->sid_name_use = name_entry->sid_name_use;
@@ -757,6 +762,7 @@ lsar_lookup_sids2(mlsvc_handle_t *lsa_handle, struct mslsa_sid *sid,
user_info->domain_name = MEM_STRDUP("mlrpc",
(char const *)domain_entry->domain_name.str);
}
+ status = NT_STATUS_SUCCESS;
}
mlsvc_rpc_free(context, &heap);
@@ -780,7 +786,7 @@ lsar_lookup_sids2(mlsvc_handle_t *lsa_handle, struct mslsa_sid *sid,
*
* It should be okay to lookup DOMAIN\Administrator in this function.
*/
-DWORD
+uint32_t
lsar_lookup_names2(mlsvc_handle_t *lsa_handle, char *name,
smb_userinfo_t *user_info)
{
@@ -793,7 +799,7 @@ lsar_lookup_names2(mlsvc_handle_t *lsa_handle, char *name,
lookup_name_table_t name_table;
struct lsar_rid_entry2 *rid_entry;
struct mslsa_domain_entry *domain_entry;
- DWORD status;
+ uint32_t status;
if (lsa_handle == NULL || name == NULL || user_info == NULL)
return (NT_STATUS_INVALID_PARAMETER);
@@ -831,8 +837,6 @@ lsar_lookup_names2(mlsvc_handle_t *lsa_handle, char *name,
user_info->sid_name_use = SidTypeInvalid;
status = NT_STATUS_NONE_MAPPED;
} else {
- status = 0;
-
rid_entry = &arg.translated_sids.rids[0];
user_info->sid_name_use = rid_entry->sid_name_use;
user_info->rid = rid_entry->rid;
@@ -849,7 +853,10 @@ lsar_lookup_names2(mlsvc_handle_t *lsa_handle, char *name,
user_info->domain_name = MEM_STRDUP("mlrpc",
(char const *)domain_entry->domain_name.str);
+ user_info->user_sid = nt_sid_splice(
+ user_info->domain_sid, user_info->rid);
}
+ status = NT_STATUS_SUCCESS;
}
mlsvc_rpc_free(context, &heap);
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers b/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers
index a294b0ef2e..05608e27d6 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#
@@ -46,41 +46,13 @@ SUNWprivate {
lmshare_setinfo;
lmshare_start;
lmshare_stop;
- lsa_lookup_name2;
- lsa_lookup_sid2;
lsa_query_primary_domain_info;
lsa_query_account_domain_info;
lsa_enum_trusted_domains;
mlsvc_init;
- mlsvc_is_local_domain;
mlsvc_join;
- nt_group_add;
- nt_group_add_groupprivs;
- nt_group_add_member_byname;
- nt_group_cache_size;
- nt_group_close_iterator;
- nt_group_delete;
- nt_group_del_member_byname;
- nt_group_getinfo;
- nt_group_getpriv;
- nt_group_ht_lock;
- nt_group_ht_unlock;
- nt_group_is_member;
- nt_group_iterate;
- nt_group_modify;
- nt_group_num_groups;
- nt_group_num_members;
- nt_group_open_iterator;
- nt_group_putinfo;
- nt_groups_count;
- nt_group_setpriv;
- nt_groups_lookup_rid;
- nt_groups_member_groups;
- nt_groups_member_ngroups;
- nt_groups_member_privs;
- nt_group_list;
- nt_group_member_list;
- sam_init;
+ mlsvc_lookup_name;
+ mlsvc_lookup_sid;
smb_logon;
smb_token_destroy;
smb_build_lmshare_info;
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c
index de20a8c934..25acdec4f2 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -193,7 +193,7 @@ mlsvc_xa_exchange(struct mlrpc_client *mcli, struct mlrpc_xaction *mxa)
struct mlndr_stream *send_mlnds = &mxa->send_mlnds;
int rc;
- rc = smbrdr_rpc_transact(context->fid,
+ rc = smbrdr_transact(context->fid,
(char *)send_mlnds->pdu_base_offset, send_mlnds->pdu_size,
(char *)recv_mlnds->pdu_base_offset, recv_mlnds->pdu_max_size);
@@ -228,7 +228,7 @@ mlsvc_xa_read(struct mlrpc_client *mcli, struct mlrpc_xaction *mxa)
if ((len = (mlnds->pdu_max_size - mlnds->pdu_size)) < 0)
return (-1);
- rc = smbrdr_rpc_readx(context->fid,
+ rc = smbrdr_readx(context->fid,
(char *)mlnds->pdu_base_offset + mlnds->pdu_size, len);
if (rc < 0)
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_dssetup.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_dssetup.c
index a20304afa8..659b184919 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_dssetup.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_dssetup.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -103,7 +103,7 @@ dssetup_DsRoleGetPrimaryDomainInfo(void *arg, struct mlrpc_xaction *mxa)
}
di = smb_getdomaininfo(0);
- (void) smb_getdomainname(dns_domain, MAXHOSTNAMELEN);
+ (void) smb_getfqdomainname(dns_domain, MAXHOSTNAMELEN);
if (di == NULL) {
bzero(param,
@@ -122,7 +122,7 @@ dssetup_DsRoleGetPrimaryDomainInfo(void *arg, struct mlrpc_xaction *mxa)
(uint8_t *)MLRPC_HEAP_STRSAVE(mxa, dns_domain);
param->ru.info1.forest =
(uint8_t *)MLRPC_HEAP_STRSAVE(mxa, dns_domain);
- bzero(&param->ru.info1.domain_guid, sizeof (mlrpc_uuid_t));
+ bzero(&param->ru.info1.domain_guid, sizeof (ndr_uuid_t));
if (param->ru.info1.nt_domain == NULL ||
param->ru.info1.dns_domain == NULL ||
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c
index fc17554949..cd8ec7da36 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c
@@ -19,19 +19,15 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
-#include <stdio.h>
#include <unistd.h>
-
-#include <smbsrv/libsmb.h>
+#include <pthread.h>
#include <smbsrv/libmlsvc.h>
-#include <smbsrv/mlsvc_util.h>
-#include <smbsrv/lsalib.h>
void dssetup_initialize(void);
void srvsvc_initialize(void);
@@ -42,6 +38,12 @@ void netr_initialize(void);
void samr_initialize(void);
void svcctl_initialize(void);
void winreg_initialize(void);
+int srvsvc_gettime(unsigned long *);
+
+static void *mlsvc_keepalive(void *);
+
+static pthread_t mlsvc_keepalive_thr;
+#define MLSVC_KEEPALIVE_INTERVAL (10 * 60) /* 10 minutes */
/*
* All mlrpc initialization is invoked from here.
@@ -50,6 +52,9 @@ void winreg_initialize(void);
int
mlsvc_init(void)
{
+ pthread_attr_t tattr;
+ int rc;
+
srvsvc_initialize();
wkssvc_initialize();
lsarpc_initialize();
@@ -60,6 +65,35 @@ mlsvc_init(void)
winreg_initialize();
logr_initialize();
- (void) sam_init();
- return (0);
+ (void) lsa_query_primary_domain_info();
+
+ (void) pthread_attr_init(&tattr);
+ (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
+ rc = pthread_create(&mlsvc_keepalive_thr, &tattr,
+ mlsvc_keepalive, 0);
+ (void) pthread_attr_destroy(&tattr);
+ return (rc);
+}
+
+/*ARGSUSED*/
+static void *
+mlsvc_keepalive(void *arg)
+{
+ unsigned long t;
+ nt_domain_t *domain;
+
+ for (;;) {
+ (void) sleep(MLSVC_KEEPALIVE_INTERVAL);
+
+ if (smb_config_get_secmode() == SMB_SECMODE_DOMAIN) {
+ domain = nt_domain_lookupbytype(NT_DOMAIN_PRIMARY);
+ if (domain == NULL)
+ (void) lsa_query_primary_domain_info();
+ }
+
+ (void) srvsvc_gettime(&t);
+ }
+
+ /*NOTREACHED*/
+ return (NULL);
}
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_logr.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_logr.c
index 4a6c80613d..3070561173 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_logr.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_logr.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -195,7 +195,6 @@ typedef struct {
} read_data_t;
static char logr_sysname[SYS_NMLN];
-static char hostname[MAXHOSTNAMELEN];
static mts_wchar_t wcs_hostname[MAXHOSTNAMELEN];
static int hostname_len = 0;
static mts_wchar_t wcs_srcname[MAX_SRCNAME_LEN];
@@ -231,26 +230,25 @@ logr_initialize(void)
/*
* logr_s_EventLogClose
*
- * This is a request to close the LOGR interface specified by the
- * handle. Free the handle and its associated resources and zero out
- * the result handle for the client.
+ * This is a request to close the LOGR interface specified by handle.
+ * Free the handle and associated resources, and zero out the result
+ * handle for the client.
*/
-/*ARGSUSED*/
static int
logr_s_EventLogClose(void *arg, struct mlrpc_xaction *mxa)
{
struct logr_EventLogClose *param = arg;
- ms_handle_desc_t *desc;
- read_data_t *data;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
+ ndr_handle_t *hd;
- if ((desc = mlsvc_lookup_handle((ms_handle_t *)&param->handle)) == 0) {
+ if ((hd = ndr_hdlookup(mxa, id)) == NULL) {
+ bzero(&param->result_handle, sizeof (logr_handle_t));
param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
return (MLRPC_DRC_OK);
}
- data = (read_data_t *)(uintptr_t)(desc->discrim);
- free(data);
- (void) mlsvc_put_handle((ms_handle_t *)&param->handle);
+ free(hd->nh_data);
+ ndr_hdfree(mxa, id);
bzero(&param->result_handle, sizeof (logr_handle_t));
param->status = NT_STATUS_SUCCESS;
@@ -260,40 +258,16 @@ logr_s_EventLogClose(void *arg, struct mlrpc_xaction *mxa)
/*
* logr_s_EventLogOpen
*
- * This is a request to open the event log.
- *
- * Return a handle for use with subsequent event log requests.
+ * Open the event log. Not supported yet.
*/
/*ARGSUSED*/
static int
logr_s_EventLogOpen(void *arg, struct mlrpc_xaction *mxa)
{
struct logr_EventLogOpen *param = arg;
- ms_handle_t *handle;
- int log_enable = 0;
- int len;
- int rc;
- smb_config_rdlock();
- log_enable = smb_config_getyorn(SMB_CI_LOGR_ENABLE);
- smb_config_unlock();
-
- rc = smb_gethostname(hostname, MAXHOSTNAMELEN, 1);
-
- if (log_enable == 0 || rc != 0) {
- bzero(&param->handle, sizeof (logr_handle_t));
- param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
- return (MLRPC_DRC_OK);
- }
-
- handle = mlsvc_get_handle(MLSVC_IFSPEC_LOGR, LOGR_KEY, 0);
- bcopy(handle, &param->handle, sizeof (logr_handle_t));
-
- len = strlen(hostname) + 1;
- (void) mts_mbstowcs(wcs_hostname, hostname, len);
- hostname_len = len * sizeof (mts_wchar_t);
-
- param->status = NT_STATUS_SUCCESS;
+ bzero(&param->handle, sizeof (logr_handle_t));
+ param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
return (MLRPC_DRC_OK);
}
@@ -316,15 +290,15 @@ logr_get_snapshot(void)
* return number of log entries in the snapshot as result of RPC
* call.
*/
-/*ARGSUSED*/
static int
logr_s_EventLogQueryCount(void *arg, struct mlrpc_xaction *mxa)
{
struct logr_EventLogQueryCount *param = arg;
- ms_handle_desc_t *desc;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
+ ndr_handle_t *hd;
read_data_t *data;
- if ((desc = mlsvc_lookup_handle((ms_handle_t *)&param->handle)) == 0) {
+ if ((hd = ndr_hdlookup(mxa, id)) == NULL) {
param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
return (MLRPC_DRC_OK);
}
@@ -334,7 +308,7 @@ logr_s_EventLogQueryCount(void *arg, struct mlrpc_xaction *mxa)
return (MLRPC_DRC_OK);
}
- desc->discrim = (DWORD)(uintptr_t)data;
+ hd->nh_data = data;
param->rec_num = data->tot_recnum;
param->status = NT_STATUS_SUCCESS;
return (MLRPC_DRC_OK);
@@ -345,21 +319,20 @@ logr_s_EventLogQueryCount(void *arg, struct mlrpc_xaction *mxa)
*
* Return oldest record number in the snapshot as result of RPC call.
*/
-/*ARGSUSED*/
static int
logr_s_EventLogGetOldestRec(void *arg, struct mlrpc_xaction *mxa)
{
struct logr_EventLogGetOldestRec *param = arg;
- ms_handle_desc_t *desc;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
+ ndr_handle_t *hd;
read_data_t *data;
- desc = mlsvc_lookup_handle((ms_handle_t *)&param->handle);
- if (desc == NULL) {
+ if ((hd = ndr_hdlookup(mxa, id)) == NULL) {
param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
return (MLRPC_DRC_OK);
}
- data = (read_data_t *)(uintptr_t)desc->discrim;
+ data = (read_data_t *)hd->nh_data;
param->oldest_rec = data->log.ix - data->tot_recnum;
param->status = NT_STATUS_SUCCESS;
return (MLRPC_DRC_OK);
@@ -452,12 +425,12 @@ set_logrec(log_entry_t *le, DWORD recno, logr_record_t *rec)
* Reads a whole number of entries from system log. The function can
* read log entries in chronological or reverse chronological order.
*/
-/*ARGSUSED*/
static int
logr_s_EventLogRead(void *arg, struct mlrpc_xaction *mxa)
{
struct logr_EventLogRead *param = arg;
- ms_handle_desc_t *desc;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
+ ndr_handle_t *hd;
read_data_t *rdata;
log_entry_t *le;
DWORD ent_no, ent_num, ent_remain;
@@ -465,20 +438,19 @@ logr_s_EventLogRead(void *arg, struct mlrpc_xaction *mxa)
BYTE *buf;
int dir, ent_per_req;
- desc = mlsvc_lookup_handle((ms_handle_t *)&param->handle);
- if (desc == NULL) {
+ if ((hd = ndr_hdlookup(mxa, id)) == NULL) {
param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
return (MLRPC_DRC_OK);
}
- rdata = (read_data_t *)(uintptr_t)(desc->discrim);
- if (rdata == 0) {
+ rdata = (read_data_t *)hd->nh_data;
+ if (rdata == NULL) {
if ((rdata = logr_get_snapshot()) == NULL) {
param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
return (MLRPC_DRC_OK);
}
- desc->discrim = (DWORD)(uintptr_t)rdata;
+ hd->nh_data = rdata;
}
dir = (param->read_flags & EVENTLOG_FORWARDS_READ) ? FWD : REW;
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_lsa.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_lsa.c
index 4d770edbc1..0bc4206f3d 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_lsa.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_lsa.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -54,6 +54,9 @@ struct local_group_table {
char *name;
};
+static int lsarpc_key_domain;
+static int lsarpc_key_account;
+
static int lsarpc_call_stub(struct mlrpc_xaction *mxa);
static int lsarpc_s_CloseHandle(void *arg, struct mlrpc_xaction *);
@@ -78,14 +81,6 @@ static int lsarpc_s_PrimaryDomainInfo(struct mslsa_PrimaryDomainInfo *,
struct mlrpc_xaction *);
static int lsarpc_s_AccountDomainInfo(struct mslsa_AccountDomainInfo *,
struct mlrpc_xaction *);
-static int lsarpc_s_LookupNtSid(struct mlrpc_xaction *, nt_sid_t *,
- smb_userinfo_t *, struct mslsa_name_entry *, int);
-static int lsarpc_s_LookupLocalSid(struct mlrpc_xaction *, nt_sid_t *,
- smb_userinfo_t *, struct mslsa_name_entry *);
-static int lsarpc_s_LookupBuiltinSid(struct mlrpc_xaction *, nt_sid_t *,
- smb_userinfo_t *, struct mslsa_name_entry *);
-static int lsarpc_s_UnknownSid(struct mlrpc_xaction *, nt_sid_t *,
- smb_userinfo_t *, struct mslsa_name_entry *);
static int lsarpc_s_UpdateDomainTable(struct mlrpc_xaction *,
smb_userinfo_t *, struct mslsa_domain_table *, DWORD *);
@@ -177,22 +172,21 @@ lsarpc_call_stub(struct mlrpc_xaction *mxa)
* lsarpc_s_OpenDomainHandle opnum=0x06
*
* This is a request to open the LSA (OpenPolicy and OpenPolicy2).
- * The client is looking for an LSA domain handle. Handles appear to
- * be a 20 byte opaque object with the top 4 bytes all zero. As it is
- * opaque to the client, we can put anything we like in it. Real handles
- * do appear to contain a sequence number which is incremented when a
- * new handle is issued. However, we don't really care about that
- * (yet). Always return MLRPC_DRC_OK.
+ * The client is looking for an LSA domain handle.
*/
-/*ARGSUSED*/
static int
lsarpc_s_OpenDomainHandle(void *arg, struct mlrpc_xaction *mxa)
{
struct mslsa_OpenPolicy2 *param = arg;
+ ndr_hdid_t *id;
- bzero(&param->domain_handle, sizeof (mslsa_handle_t));
- (void) strcpy((char *)&param->domain_handle.hand2, "DomainHandle");
- param->status = 0;
+ if ((id = ndr_hdalloc(mxa, &lsarpc_key_domain)) != NULL) {
+ bcopy(id, &param->domain_handle, sizeof (mslsa_handle_t));
+ param->status = NT_STATUS_SUCCESS;
+ } else {
+ bzero(&param->domain_handle, sizeof (mslsa_handle_t));
+ param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
+ }
return (MLRPC_DRC_OK);
}
@@ -205,15 +199,16 @@ lsarpc_s_OpenDomainHandle(void *arg, struct mlrpc_xaction *mxa)
* MLRPC_DRC_OK. Setting the handle to zero appears to be standard
* behaviour and someone may rely on it, i.e. we do on the client side.
*/
-/*ARGSUSED*/
static int
lsarpc_s_CloseHandle(void *arg, struct mlrpc_xaction *mxa)
{
struct mslsa_CloseHandle *param = arg;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
- bzero(&param->result_handle, sizeof (param->result_handle));
- param->status = 0;
+ ndr_hdfree(mxa, id);
+ bzero(&param->result_handle, sizeof (param->result_handle));
+ param->status = NT_STATUS_SUCCESS;
return (MLRPC_DRC_OK);
}
@@ -307,23 +302,28 @@ lsarpc_s_EnumTrustedDomain(void *arg, struct mlrpc_xaction *mxa)
/*
* lsarpc_s_OpenAccount
*
- * This is a request to open an account handle. This function hasn't
- * been tested. It is just a template in case some server somewhere
- * makes this call. See lsarpc_s_OpenDomainHandle for more information.
+ * This is a request to open an account handle.
*/
-/*ARGSUSED*/
static int
lsarpc_s_OpenAccount(void *arg, struct mlrpc_xaction *mxa)
{
struct mslsa_OpenAccount *param = arg;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
+ ndr_handle_t *hd;
+
+ hd = ndr_hdlookup(mxa, id);
+ if ((hd == NULL) || (hd->nh_data != &lsarpc_key_domain)) {
+ bzero(&param, sizeof (struct mslsa_OpenAccount));
+ param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
+ return (MLRPC_DRC_OK);
+ }
- if (param->handle.hand1 != 0 ||
- strcmp("DomainHandle", (char *)&param->handle.hand2)) {
- param->status = NT_SC_ERROR(ERROR_NO_SUCH_DOMAIN);
+ if ((id = ndr_hdalloc(mxa, &lsarpc_key_account)) != NULL) {
+ bcopy(id, &param->account_handle, sizeof (mslsa_handle_t));
+ param->status = NT_STATUS_SUCCESS;
} else {
- (void) strcpy((char *)&param->account_handle.hand2,
- "AccountHandle");
- param->status = 0;
+ bzero(&param->account_handle, sizeof (mslsa_handle_t));
+ param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
}
return (MLRPC_DRC_OK);
@@ -584,7 +584,7 @@ lsarpc_s_PrimaryDomainInfo(struct mslsa_PrimaryDomainInfo *pd_info,
status = NT_STATUS_SUCCESS;
- security_mode = smb_get_security_mode();
+ security_mode = smb_config_get_secmode();
if (security_mode != SMB_SECMODE_DOMAIN) {
rc = smb_gethostname(domain_name, MLSVC_DOMAIN_NAME_MAX, 1);
@@ -686,8 +686,8 @@ lsarpc_s_LookupNames(void *arg, struct mlrpc_xaction *mxa)
smb_userinfo_t *user_info = 0;
struct mslsa_domain_table *domain_table;
struct mslsa_domain_entry *domain_entry;
- char *name = "";
DWORD status = NT_STATUS_SUCCESS;
+ char *account;
int rc = 0;
if (param->name_table->n_entry != 1)
@@ -704,20 +704,10 @@ lsarpc_s_LookupNames(void *arg, struct mlrpc_xaction *mxa)
goto name_lookup_failed;
}
- name = (char *)param->name_table->names->str;
-
- rc = lsa_lookup_local(name, user_info);
- if (rc < 0) {
- status = NT_STATUS_NO_SUCH_USER;
+ account = (char *)param->name_table->names->str;
+ status = lsa_lookup_name(NULL, account, SidTypeUnknown, user_info);
+ if (status != NT_STATUS_SUCCESS)
goto name_lookup_failed;
- }
-
- if (rc > 0) {
- if (lsa_lookup_name(0, 0, name, user_info) != 0) {
- status = NT_STATUS_NO_SUCH_USER;
- goto name_lookup_failed;
- }
- }
/*
* Set up the rid table.
@@ -780,6 +770,7 @@ lsarpc_s_LookupSids(void *arg, struct mlrpc_xaction *mxa)
struct mslsa_domain_table *domain_table;
struct mslsa_domain_entry *domain_entry;
struct mslsa_name_entry *names;
+ struct mslsa_name_entry *name;
smb_userinfo_t *user_info;
nt_sid_t *sid;
DWORD n_entry;
@@ -805,48 +796,28 @@ lsarpc_s_LookupSids(void *arg, struct mlrpc_xaction *mxa)
domain_table->n_entry = 0;
domain_table->max_n_entry = MLSVC_DOMAIN_MAX;
- for (i = 0; i < n_entry; ++i) {
+ name = names;
+ for (i = 0; i < n_entry; ++i, name++) {
bzero(&names[i], sizeof (struct mslsa_name_entry));
sid = (nt_sid_t *)param->lup_sid_table.entries[i].psid;
- if (nt_sid_is_local(sid)) {
- result = lsarpc_s_LookupLocalSid(mxa, sid, user_info,
- &names[i]);
- } else {
- result = lsarpc_s_LookupBuiltinSid(mxa, sid, user_info,
- &names[i]);
-
- if (result != 0)
- result = lsarpc_s_LookupNtSid(mxa, sid,
- user_info, &names[i], 1);
+ result = lsa_lookup_sid(sid, user_info);
+ if (result != NT_STATUS_SUCCESS)
+ goto lookup_sid_failed;
- if (result != 0) {
- result = lsarpc_s_UnknownSid(mxa, sid,
- user_info, &names[i]);
- }
- }
-
- if (result == -1) {
- mlsvc_free_user_info(user_info);
- param->domain_table = 0;
- param->name_table.n_entry = 0;
- param->name_table.entries = 0;
- param->mapped_count = 0;
- param->status = NT_SC_ERROR(NT_STATUS_INVALID_SID);
- return (MLRPC_DRC_OK);
+ if (!mlsvc_string_save((ms_string_t *)&name->name,
+ user_info->name, mxa)) {
+ result = NT_STATUS_NO_MEMORY;
+ goto lookup_sid_failed;
}
+ name->sid_name_use = user_info->sid_name_use;
result = lsarpc_s_UpdateDomainTable(mxa, user_info,
- domain_table, &names[i].domain_ix);
+ domain_table, &name->domain_ix);
if (result == -1) {
- mlsvc_free_user_info(user_info);
- param->domain_table = 0;
- param->name_table.n_entry = 0;
- param->name_table.entries = 0;
- param->mapped_count = 0;
- param->status = NT_SC_ERROR(NT_STATUS_INVALID_SID);
- return (MLRPC_DRC_OK);
+ result = NT_STATUS_INTERNAL_ERROR;
+ goto lookup_sid_failed;
}
mlsvc_release_user_info(user_info);
@@ -860,295 +831,16 @@ lsarpc_s_LookupSids(void *arg, struct mlrpc_xaction *mxa)
mlsvc_free_user_info(user_info);
return (MLRPC_DRC_OK);
-}
-
-/*
- * lsarpc_s_LookupLocalSid
- *
- * This function handles local domain SID lookup. If the SID matches the
- * local domain SID, we lookup the local files to map the RID to a name.
- * We attempt to handle both users and groups. When the SID was supplied
- * to the client, the ID type should have been encoded in the RID. We
- * decode the RID and lookup it up in either the passwd file or the
- * group file as appropriate.
- *
- * On success, 0 is returned. Otherwise -1 is returned.
- */
-static int
-lsarpc_s_LookupLocalSid(struct mlrpc_xaction *mxa, nt_sid_t *sid,
- smb_userinfo_t *user_info, struct mslsa_name_entry *name)
-{
- char buffer[MLSVC_DOMAIN_NAME_MAX];
- char namebuf[MLSVC_DOMAIN_NAME_MAX];
- nt_sid_t *lds;
- nt_sid_t *tmp_sid;
- nt_group_t *grp;
- struct passwd *pw;
- struct group *gr;
- DWORD rid;
- int unix_id;
-
- if (smb_gethostname(buffer, MLSVC_DOMAIN_NAME_MAX, 1) != 0)
- return (-1);
-
- /*
- * Only free tmp_sid in error paths. If it is assigned to the
- * user_info, it will be freed later when that structure is
- * released.
- */
- if ((tmp_sid = nt_sid_dup(sid)) == NULL)
- return (-1);
-
- rid = 0;
- lds = nt_domain_local_sid();
- user_info->sid_name_use = SidTypeInvalid;
-
- if (nt_sid_is_equal(lds, tmp_sid)) {
- user_info->sid_name_use = SidTypeDomain;
- user_info->name = strdup(buffer);
- } else {
- (void) nt_sid_split(tmp_sid, &rid);
-
- switch (SAM_RID_TYPE(rid)) {
- case SAM_RT_NT_UID:
- break;
-
- case SAM_RT_NT_GID:
- user_info->sid_name_use = SidTypeAlias;
- grp = nt_groups_lookup_rid(rid);
- if (grp)
- user_info->name = strdup(grp->name);
- else {
- (void) snprintf(namebuf, sizeof (namebuf),
- "%d (no name)", rid);
- user_info->name = strdup(namebuf);
- }
- break;
-
- case SAM_RT_UNIX_UID:
- /*
- * It is always possible that the rid will not
- * correspond to an entry in the local passwd or group
- * file. In this case we can return the RID with a
- * message to indicate the problem, which seems better
- * than returning an invalid SID error.
- */
- unix_id = SAM_DECODE_RID(rid);
- (void) snprintf(namebuf, sizeof (namebuf),
- "%d (no name)", unix_id);
- user_info->sid_name_use = SidTypeUser;
- pw = getpwuid(unix_id);
- user_info->name = (pw) ?
- strdup(pw->pw_name) : strdup(namebuf);
- break;
-
- case SAM_RT_UNIX_GID:
- unix_id = SAM_DECODE_RID(rid);
- (void) snprintf(namebuf, sizeof (namebuf),
- "%d (no name)", unix_id);
- user_info->sid_name_use = SidTypeAlias;
- gr = getgrgid(unix_id);
- user_info->name = (gr) ?
- strdup(gr->gr_name) : strdup(namebuf);
- break;
- }
- }
-
- if (user_info->sid_name_use == SidTypeInvalid) {
- free(tmp_sid);
- return (-1);
- }
- /*
- * Set up the rest of user_info.
- * Don't free tmp_sid after this.
- */
- user_info->rid = rid;
- user_info->domain_name = strdup(buffer);
- user_info->domain_sid = tmp_sid;
-
- bzero(name, sizeof (struct mslsa_name_entry));
- name->sid_name_use = user_info->sid_name_use;
-
- if (!mlsvc_string_save(
- (ms_string_t *)&name->name, user_info->name, mxa)) {
- return (-1);
- }
+lookup_sid_failed:
+ param->domain_table = 0;
+ param->name_table.n_entry = 0;
+ param->name_table.entries = 0;
+ param->mapped_count = 0;
+ param->status = NT_SC_ERROR(result);
- return (0);
-}
-
-/*
- * lsarpc_s_LookupNtSid
- *
- * This function handles NT domain SID lookup on the domain controller.
- * Most of the work is performed by lsa_lookup_sid. We just have to
- * update the name data for the response. It is assumed that any SID
- * passed to this function has already been checked and correctly
- * identified as an NT domain SID. It shouldn't break anything if you
- * get it wrong, the domain controller will just reject the SID.
- *
- * On success, 0 is returned. Otherwise -1 is returned.
- */
-static int
-lsarpc_s_LookupNtSid(struct mlrpc_xaction *mxa, nt_sid_t *sid,
- smb_userinfo_t *user_info, struct mslsa_name_entry *name, int version)
-{
- char *username;
- DWORD status;
-
- if (smb_getdomaininfo(0) == 0) {
- status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- return (-1);
- }
-
- if (version == 2)
- status = lsa_lookup_sid2(sid, user_info);
- else
- status = lsa_lookup_sid(sid, user_info);
-
- if (status != 0)
- return (-1);
-
- switch (user_info->sid_name_use) {
- case SidTypeDomain:
- if ((username = user_info->domain_name) == 0)
- user_info->sid_name_use = SidTypeUnknown;
- break;
-
- case SidTypeUser:
- case SidTypeGroup:
- case SidTypeAlias:
- case SidTypeDeletedAccount:
- case SidTypeWellKnownGroup:
- if ((username = user_info->name) == 0)
- user_info->sid_name_use = SidTypeUnknown;
- break;
-
- default:
- return (-1);
- }
-
- if (username == 0)
- username = "unknown";
- bzero(name, sizeof (struct mslsa_name_entry));
- name->sid_name_use = user_info->sid_name_use;
-
- if (!mlsvc_string_save((ms_string_t *)&name->name, username, mxa))
- return (-1);
-
- return (0);
-}
-
-/*
- * lsarpc_s_LookupBuiltinSid
- *
- * This function handles predefined local groups and aliases in the NT
- * AUTHORITY or BUILTIN domains, and some other miscellaneous bits. I
- * don't think NT cares about the domain field of well-known groups or
- * aliases but it seems sensible to set it up anyway. If we get a match,
- * set up the name in the response heap.
- *
- * On success, 0 is returned. Otherwise non-zero is returned. A non-zero
- * return value should not be automatically interpreted as an error. The
- * caller should attempt to resolve the SID through alternative means.
- */
-static int
-lsarpc_s_LookupBuiltinSid(struct mlrpc_xaction *mxa, nt_sid_t *sid,
- smb_userinfo_t *user_info, struct mslsa_name_entry *name)
-{
- char *np;
- WORD sid_name_use;
-
- if ((np = nt_builtin_lookup_sid(sid, &sid_name_use)) == NULL)
- return (1);
-
- user_info->sid_name_use = sid_name_use;
- user_info->name = strdup(np);
- user_info->domain_sid = nt_sid_dup(sid);
-
- if (user_info->name == NULL || user_info->domain_sid == NULL) {
- mlsvc_release_user_info(user_info);
- return (-1);
- }
-
- if (sid_name_use != SidTypeDomain && sid->SubAuthCount != 0)
- user_info->rid = sid->SubAuthority[sid->SubAuthCount - 1];
- else
- user_info->rid = 0;
-
- if ((np = nt_builtin_lookup_domain(user_info->name)) != NULL)
- user_info->domain_name = strdup(np);
- else
- user_info->domain_name = strdup("UNKNOWN");
-
- if (user_info->domain_name == NULL) {
- mlsvc_release_user_info(user_info);
- return (-1);
- }
-
- if (sid_name_use == SidTypeAlias &&
- user_info->domain_sid->SubAuthCount != 0) {
- --user_info->domain_sid->SubAuthCount;
- }
-
- bzero(name, sizeof (struct mslsa_name_entry));
- name->sid_name_use = sid_name_use;
-
- if (sid_name_use == SidTypeUnknown) {
- mlsvc_release_user_info(user_info);
- return (1);
- }
-
- if (!mlsvc_string_save(
- (ms_string_t *)&name->name, user_info->name, mxa)) {
- mlsvc_release_user_info(user_info);
- return (-1);
- }
-
- return (0);
-}
-
-/*
- * lsarpc_s_UnknownSid
- *
- * This function handles unknown SIDs. By the time this is called we
- * know that this is not a local SID and that the PDC has no idea to
- * whom this sid refers. It may be a remnant from a time when the
- * server was in another domain. All we can do is turn into the SID
- * into a string and return it in place of a user name.
- *
- * On success, 0 is returned. Otherwise -1 is returned.
- */
-static int
-lsarpc_s_UnknownSid(struct mlrpc_xaction *mxa, nt_sid_t *sid,
- smb_userinfo_t *user_info, struct mslsa_name_entry *name)
-{
- char domain_name[MLSVC_DOMAIN_NAME_MAX];
- char *sidbuf;
-
- if ((sidbuf = nt_sid_format(sid)) == NULL)
- return (-1);
-
- if (smb_gethostname(domain_name, MLSVC_DOMAIN_NAME_MAX, 1) != 0)
- return (-1);
-
- (void) utf8_strupr(domain_name);
- mlsvc_release_user_info(user_info);
- user_info->sid_name_use = SidTypeUnknown;
- user_info->name = sidbuf;
- user_info->domain_name = strdup(domain_name);
- user_info->domain_sid = nt_sid_dup(nt_domain_local_sid());
-
- bzero(name, sizeof (struct mslsa_name_entry));
- name->sid_name_use = user_info->sid_name_use;
-
- if (!mlsvc_string_save(
- (ms_string_t *)&name->name, user_info->name, mxa)) {
- return (-1);
- }
-
- return (0);
+ mlsvc_free_user_info(user_info);
+ return (MLRPC_DRC_OK);
}
/*
@@ -1223,6 +915,7 @@ lsarpc_s_LookupSids2(void *arg, struct mlrpc_xaction *mxa)
{
struct lsar_lookup_sids2 *param = arg;
struct lsar_name_entry2 *names;
+ struct lsar_name_entry2 *name;
struct mslsa_domain_table *domain_table;
struct mslsa_domain_entry *domain_entry;
smb_userinfo_t *user_info;
@@ -1250,51 +943,28 @@ lsarpc_s_LookupSids2(void *arg, struct mlrpc_xaction *mxa)
domain_table->n_entry = 0;
domain_table->max_n_entry = MLSVC_DOMAIN_MAX;
- for (i = 0; i < n_entry; ++i) {
- bzero(&names[i], sizeof (struct lsar_name_entry2));
+ name = names;
+ for (i = 0; i < n_entry; ++i, name++) {
+ bzero(name, sizeof (struct lsar_name_entry2));
sid = (nt_sid_t *)param->lup_sid_table.entries[i].psid;
- if (nt_sid_is_local(sid)) {
- result = lsarpc_s_LookupLocalSid(mxa, sid, user_info,
- (struct mslsa_name_entry *)&names[i]);
- } else {
- result = lsarpc_s_LookupBuiltinSid(mxa, sid, user_info,
- (struct mslsa_name_entry *)&names[i]);
-
- if (result != 0)
- result = lsarpc_s_LookupNtSid(mxa, sid,
- user_info,
- (struct mslsa_name_entry *)&names[i], 2);
-
- if (result != 0) {
- result = lsarpc_s_UnknownSid(mxa, sid,
- user_info,
- (struct mslsa_name_entry *)&names[i]);
- }
- }
+ result = lsa_lookup_sid(sid, user_info);
+ if (result != NT_STATUS_SUCCESS)
+ goto lookup_sid_failed;
- if (result == -1) {
- mlsvc_free_user_info(user_info);
- param->domain_table = 0;
- param->name_table.n_entry = 0;
- param->name_table.entries = 0;
- param->mapped_count = 0;
- param->status = NT_SC_ERROR(NT_STATUS_INVALID_SID);
- return (MLRPC_DRC_OK);
+ if (!mlsvc_string_save((ms_string_t *)&name->name,
+ user_info->name, mxa)) {
+ result = NT_STATUS_NO_MEMORY;
+ goto lookup_sid_failed;
}
+ name->sid_name_use = user_info->sid_name_use;
result = lsarpc_s_UpdateDomainTable(mxa, user_info,
- domain_table, &names[i].domain_ix);
+ domain_table, &name->domain_ix);
if (result == -1) {
- mlsvc_free_user_info(user_info);
- param->domain_table = 0;
- param->name_table.n_entry = 0;
- param->name_table.entries = 0;
- param->mapped_count = 0;
- param->status = NT_SC_ERROR(NT_STATUS_INVALID_SID);
-
- return (MLRPC_DRC_OK);
+ result = NT_STATUS_INTERNAL_ERROR;
+ goto lookup_sid_failed;
}
mlsvc_release_user_info(user_info);
@@ -1308,6 +978,16 @@ lsarpc_s_LookupSids2(void *arg, struct mlrpc_xaction *mxa)
mlsvc_free_user_info(user_info);
return (MLRPC_DRC_OK);
+
+lookup_sid_failed:
+ param->domain_table = 0;
+ param->name_table.n_entry = 0;
+ param->name_table.entries = 0;
+ param->mapped_count = 0;
+ param->status = NT_SC_ERROR(result);
+
+ mlsvc_free_user_info(user_info);
+ return (MLRPC_DRC_OK);
}
/*
@@ -1324,7 +1004,7 @@ lsarpc_s_LookupNames2(void *arg, struct mlrpc_xaction *mxa)
smb_userinfo_t *user_info = 0;
struct mslsa_domain_table *domain_table;
struct mslsa_domain_entry *domain_entry;
- char *name = "";
+ char *account;
DWORD status = NT_STATUS_SUCCESS;
int rc = 0;
@@ -1342,20 +1022,10 @@ lsarpc_s_LookupNames2(void *arg, struct mlrpc_xaction *mxa)
goto name_lookup2_failed;
}
- name = (char *)param->name_table->names->str;
-
- rc = lsa_lookup_local(name, user_info);
- if (rc < 0) {
- status = NT_STATUS_NONE_MAPPED;
+ account = (char *)param->name_table->names->str;
+ status = lsa_lookup_name(NULL, account, SidTypeUnknown, user_info);
+ if (status != NT_STATUS_SUCCESS)
goto name_lookup2_failed;
- }
-
- if (rc > 0) {
- if (lsa_lookup_name2(0, 0, name, user_info) != 0) {
- status = NT_STATUS_NONE_MAPPED;
- goto name_lookup2_failed;
- }
- }
/*
* Set up the rid table.
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_sam.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_sam.c
index 6d22e62127..3be04d2a50 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_sam.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_sam.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -47,28 +47,31 @@
#include <smbsrv/samlib.h>
/*
- * The keys associated with the various handles dispensed
- * by the SAMR server. These keys can be used to validate
- * client activity. These values are never passed over
- * the network so security shouldn't be an issue.
+ * The keys associated with the various handles dispensed by the SAMR
+ * server. These keys can be used to validate client activity.
+ * These values are never passed over the wire so security shouldn't
+ * be an issue.
*/
-#define SAMR_CONNECT_KEY "SamrConnect"
-#define SAMR_DOMAIN_KEY "SamrDomain"
-#define SAMR_USER_KEY "SamrUser"
-#define SAMR_GROUP_KEY "SamrGroup"
-#define SAMR_ALIAS_KEY "SamrAlias"
-
-/*
- * Domain discriminator values. Set the top bit to try
- * to distinguish these values from user and group ids.
- */
-#define SAMR_DATABASE_DOMAIN 0x80000001
-#define SAMR_LOCAL_DOMAIN 0x80000002
-#define SAMR_BUILTIN_DOMAIN 0x80000003
-#define SAMR_PRIMARY_DOMAIN 0x80000004
-
+typedef enum {
+ SAMR_KEY_NULL = 0,
+ SAMR_KEY_CONNECT,
+ SAMR_KEY_DOMAIN,
+ SAMR_KEY_USER,
+ SAMR_KEY_GROUP,
+ SAMR_KEY_ALIAS
+} samr_key_t;
+
+typedef struct samr_keydata {
+ samr_key_t kd_key;
+ nt_domain_type_t kd_type;
+ DWORD kd_rid;
+} samr_keydata_t;
+
+static ndr_hdid_t *samr_hdalloc(ndr_xa_t *, samr_key_t, nt_domain_type_t,
+ DWORD);
+static void samr_hdfree(ndr_xa_t *, ndr_hdid_t *);
+static ndr_handle_t *samr_hdlookup(ndr_xa_t *, ndr_hdid_t *, samr_key_t);
static int samr_call_stub(struct mlrpc_xaction *mxa);
-
static DWORD samr_s_enum_local_domains(struct samr_EnumLocalDomain *,
struct mlrpc_xaction *);
@@ -115,6 +118,60 @@ samr_call_stub(struct mlrpc_xaction *mxa)
}
/*
+ * Handle allocation wrapper to setup the local context.
+ */
+static ndr_hdid_t *
+samr_hdalloc(ndr_xa_t *mxa, samr_key_t key, nt_domain_type_t domain_type,
+ DWORD rid)
+{
+ samr_keydata_t *data;
+
+ if ((data = malloc(sizeof (samr_keydata_t))) == NULL)
+ return (NULL);
+
+ data->kd_key = key;
+ data->kd_type = domain_type;
+ data->kd_rid = rid;
+
+ return (ndr_hdalloc(mxa, data));
+}
+
+/*
+ * Handle deallocation wrapper to free the local context.
+ */
+static void
+samr_hdfree(ndr_xa_t *mxa, ndr_hdid_t *id)
+{
+ ndr_handle_t *hd;
+
+ if ((hd = ndr_hdlookup(mxa, id)) != NULL) {
+ free(hd->nh_data);
+ ndr_hdfree(mxa, id);
+ }
+}
+
+/*
+ * Handle lookup wrapper to validate the local context.
+ */
+static ndr_handle_t *
+samr_hdlookup(ndr_xa_t *mxa, ndr_hdid_t *id, samr_key_t key)
+{
+ ndr_handle_t *hd;
+ samr_keydata_t *data;
+
+ if ((hd = ndr_hdlookup(mxa, id)) == NULL)
+ return (NULL);
+
+ if ((data = (samr_keydata_t *)hd->nh_data) == NULL)
+ return (NULL);
+
+ if (data->kd_key != key)
+ return (NULL);
+
+ return (hd);
+}
+
+/*
* samr_s_ConnectAnon
*
* This is a request to connect to the local SAM database. We don't
@@ -124,44 +181,38 @@ samr_call_stub(struct mlrpc_xaction *mxa)
*
* Return a handle for use with subsequent SAM requests.
*/
-/*ARGSUSED*/
static int
samr_s_ConnectAnon(void *arg, struct mlrpc_xaction *mxa)
{
struct samr_ConnectAnon *param = arg;
- ms_handle_t *handle;
+ ndr_hdid_t *id;
- handle = mlsvc_get_handle(MLSVC_IFSPEC_SAMR, SAMR_CONNECT_KEY,
- SAMR_DATABASE_DOMAIN);
- bcopy(handle, &param->handle, sizeof (samr_handle_t));
+ id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, NT_DOMAIN_NULL, 0);
+ if (id) {
+ bcopy(id, &param->handle, sizeof (samr_handle_t));
+ param->status = 0;
+ } else {
+ bzero(&param->handle, sizeof (samr_handle_t));
+ param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
+ }
- param->status = 0;
return (MLRPC_DRC_OK);
}
/*
* samr_s_CloseHandle
*
- * This is a request to close the SAM interface specified by the handle.
+ * Close the SAM interface specified by the handle.
* Free the handle and zero out the result handle for the client.
- *
- * We could do some checking here but it probably doesn't matter.
*/
-/*ARGSUSED*/
static int
samr_s_CloseHandle(void *arg, struct mlrpc_xaction *mxa)
{
struct samr_CloseHandle *param = arg;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
-#ifdef SAMR_S_DEBUG
- if (mlsvc_lookup_handle((ms_handle_t *)&param->handle) == 0) {
- bzero(&param->result_handle, sizeof (samr_handle_t));
- param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
- return (MLRPC_DRC_OK);
- }
-#endif /* SAMR_S_DEBUG */
+ samr_hdfree(mxa, id);
- (void) mlsvc_put_handle((ms_handle_t *)&param->handle);
bzero(&param->result_handle, sizeof (samr_handle_t));
param->status = 0;
return (MLRPC_DRC_OK);
@@ -179,9 +230,8 @@ static int
samr_s_LookupDomain(void *arg, struct mlrpc_xaction *mxa)
{
struct samr_LookupDomain *param = arg;
- char resource_domain[MAXHOSTNAMELEN];
+ char resource_domain[SMB_PI_MAX_DOMAIN];
char *domain_name;
- char *p;
nt_sid_t *sid = NULL;
if ((domain_name = (char *)param->domain_name.str) == NULL) {
@@ -190,11 +240,7 @@ samr_s_LookupDomain(void *arg, struct mlrpc_xaction *mxa)
return (MLRPC_DRC_OK);
}
- smb_config_rdlock();
- p = smb_config_getstr(SMB_CI_DOMAIN_NAME);
- (void) strlcpy(resource_domain, p, MAXHOSTNAMELEN);
- smb_config_unlock();
-
+ (void) smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN);
if (mlsvc_is_local_domain(domain_name) == 1) {
sid = nt_sid_dup(nt_domain_local_sid());
} else if (strcasecmp(resource_domain, domain_name) == 0) {
@@ -237,12 +283,10 @@ static int
samr_s_EnumLocalDomains(void *arg, struct mlrpc_xaction *mxa)
{
struct samr_EnumLocalDomain *param = arg;
- ms_handle_t *handle;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
DWORD status;
- handle = (ms_handle_t *)&param->handle;
-
- if (mlsvc_validate_handle(handle, SAMR_CONNECT_KEY) == 0)
+ if (samr_hdlookup(mxa, id, SAMR_KEY_CONNECT) == NULL)
status = NT_STATUS_ACCESS_DENIED;
else
status = samr_s_enum_local_domains(param, mxa);
@@ -308,52 +352,42 @@ samr_s_enum_local_domains(struct samr_EnumLocalDomain *param,
* samr_s_OpenDomain
*
* This is a request to open a domain within the local SAM database.
- * The caller must supply a valid handle obtained via a successful
- * connect. We return a handle to be used to access objects within
- * this domain.
+ * The caller must supply a valid connect handle.
+ * We return a handle to be used to access objects within this domain.
*/
-/*ARGSUSED*/
static int
samr_s_OpenDomain(void *arg, struct mlrpc_xaction *mxa)
{
struct samr_OpenDomain *param = arg;
- ms_handle_t *handle = 0;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
nt_domain_t *domain;
- if (!mlsvc_validate_handle(
- (ms_handle_t *)&param->handle, SAMR_CONNECT_KEY)) {
+ if (samr_hdlookup(mxa, id, SAMR_KEY_CONNECT) == NULL) {
bzero(&param->domain_handle, sizeof (samr_handle_t));
param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
return (MLRPC_DRC_OK);
}
- domain = nt_domain_lookup_sid((nt_sid_t *)param->sid);
- if (domain == NULL) {
+ if ((domain = nt_domain_lookup_sid((nt_sid_t *)param->sid)) == NULL) {
bzero(&param->domain_handle, sizeof (samr_handle_t));
param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
return (MLRPC_DRC_OK);
}
- switch (domain->type) {
- case NT_DOMAIN_BUILTIN:
- handle = mlsvc_get_handle(MLSVC_IFSPEC_SAMR,
- SAMR_DOMAIN_KEY, SAMR_BUILTIN_DOMAIN);
-
- bcopy(handle, &param->domain_handle, sizeof (samr_handle_t));
- param->status = 0;
- break;
-
- case NT_DOMAIN_LOCAL:
- handle = mlsvc_get_handle(MLSVC_IFSPEC_SAMR,
- SAMR_DOMAIN_KEY, SAMR_LOCAL_DOMAIN);
+ if ((domain->type != NT_DOMAIN_BUILTIN) &&
+ (domain->type != NT_DOMAIN_LOCAL)) {
+ bzero(&param->domain_handle, sizeof (samr_handle_t));
+ param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
+ return (MLRPC_DRC_OK);
+ }
- bcopy(handle, &param->domain_handle, sizeof (samr_handle_t));
+ id = samr_hdalloc(mxa, SAMR_KEY_DOMAIN, domain->type, 0);
+ if (id) {
+ bcopy(id, &param->domain_handle, sizeof (samr_handle_t));
param->status = 0;
- break;
-
- default:
+ } else {
bzero(&param->domain_handle, sizeof (samr_handle_t));
- param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
+ param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
}
return (MLRPC_DRC_OK);
@@ -373,13 +407,38 @@ static int
samr_s_QueryDomainInfo(void *arg, struct mlrpc_xaction *mxa)
{
struct samr_QueryDomainInfo *param = arg;
- ms_handle_desc_t *desc;
- char *hostname;
- char *domain_str = "";
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->domain_handle;
+ ndr_handle_t *hd;
+ samr_keydata_t *data;
+ char *domain;
+ int alias_cnt;
int rc;
- desc = mlsvc_lookup_handle((ms_handle_t *)&param->domain_handle);
- if (desc == NULL || (strcmp(desc->key, SAMR_DOMAIN_KEY) != 0)) {
+ if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
+ bzero(param, sizeof (struct samr_QueryDomainInfo));
+ param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
+ return (MLRPC_DRC_OK);
+ }
+
+ data = (samr_keydata_t *)hd->nh_data;
+
+ switch (data->kd_type) {
+ case NT_DOMAIN_BUILTIN:
+ domain = "Builtin";
+ break;
+
+ case NT_DOMAIN_LOCAL:
+ domain = MLRPC_HEAP_MALLOC(mxa, MAXHOSTNAMELEN);
+ rc = smb_gethostname(domain, MAXHOSTNAMELEN, 1);
+
+ if (rc != 0 || domain == NULL) {
+ bzero(param, sizeof (struct samr_QueryDomainInfo));
+ param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
+ return (MLRPC_DRC_OK);
+ }
+ break;
+
+ default:
bzero(param, sizeof (struct samr_QueryDomainInfo));
param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
return (MLRPC_DRC_OK);
@@ -401,21 +460,13 @@ samr_s_QueryDomainInfo(void *arg, struct mlrpc_xaction *mxa)
break;
case SAMR_QUERY_DOMAIN_INFO_2:
- if (desc->discrim == SAMR_LOCAL_DOMAIN) {
- hostname = MLRPC_HEAP_MALLOC(mxa, MAXHOSTNAMELEN);
- rc = smb_gethostname(hostname, MAXHOSTNAMELEN, 1);
- if (rc != 0 || hostname == NULL) {
- bzero(param,
- sizeof (struct samr_QueryDomainInfo));
- param->status =
- NT_SC_ERROR(NT_STATUS_NO_MEMORY);
- return (MLRPC_DRC_OK);
- }
-
- domain_str = hostname;
- } else {
- if (desc->discrim == SAMR_BUILTIN_DOMAIN)
- domain_str = "Builtin";
+ rc = (data->kd_type == NT_DOMAIN_BUILTIN)
+ ? smb_lgrp_numbydomain(SMB_LGRP_BUILTIN, &alias_cnt)
+ : smb_lgrp_numbydomain(SMB_LGRP_LOCAL, &alias_cnt);
+ if (rc != SMB_LGRP_SUCCESS) {
+ bzero(param, sizeof (struct samr_QueryDomainInfo));
+ param->status = NT_SC_ERROR(NT_STATUS_INTERNAL_ERROR);
+ return (MLRPC_DRC_OK);
}
param->ru.info2.unknown1 = 0x00000000;
@@ -425,7 +476,7 @@ samr_s_QueryDomainInfo(void *arg, struct mlrpc_xaction *mxa)
"", mxa);
(void) mlsvc_string_save(
- (ms_string_t *)&(param->ru.info2.domain), domain_str, mxa);
+ (ms_string_t *)&(param->ru.info2.domain), domain, mxa);
(void) mlsvc_string_save((ms_string_t *)&(param->ru.info2.s2),
"", mxa);
@@ -437,11 +488,7 @@ samr_s_QueryDomainInfo(void *arg, struct mlrpc_xaction *mxa)
param->ru.info2.unknown6 = 0x00000001;
param->ru.info2.num_users = 0;
param->ru.info2.num_groups = 0;
- param->ru.info2.num_aliases =
- (desc->discrim == SAMR_BUILTIN_DOMAIN) ?
- nt_groups_count(NT_GROUP_CNT_BUILTIN) :
- nt_groups_count(NT_GROUP_CNT_LOCAL);
-
+ param->ru.info2.num_aliases = alias_cnt;
param->status = NT_STATUS_SUCCESS;
break;
@@ -466,83 +513,85 @@ static int
samr_s_LookupNames(void *arg, struct mlrpc_xaction *mxa)
{
struct samr_LookupNames *param = arg;
- ms_handle_desc_t *desc;
- struct passwd *pw;
- struct group *gr;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
+ ndr_handle_t *hd;
+ samr_keydata_t *data;
+ well_known_account_t *wka;
+ smb_group_t grp;
+ smb_passwd_t smbpw;
nt_sid_t *sid;
- nt_group_t *grp;
- WORD rid_type;
+ uint32_t status = NT_STATUS_SUCCESS;
+ int rc;
- desc = mlsvc_lookup_handle((ms_handle_t *)&param->handle);
- if (desc == 0 || (strcmp(desc->key, SAMR_DOMAIN_KEY) != 0)) {
- bzero(param, sizeof (struct samr_LookupNames));
- param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
- return (MLRPC_DRC_OK);
- }
+ if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL)
+ status = NT_STATUS_INVALID_HANDLE;
- if (param->n_entry != 1) {
- bzero(param, sizeof (struct samr_LookupNames));
- param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
- return (MLRPC_DRC_OK);
- }
+ if (param->n_entry != 1)
+ status = NT_STATUS_ACCESS_DENIED;
if (param->name.str == NULL) {
- bzero(param, sizeof (struct samr_LookupNames));
/*
- * Windows NT returns NT_STATUS_NONE_MAPPED when the
- * name is NULL.
+ * Windows NT returns NT_STATUS_NONE_MAPPED.
* Windows 2000 returns STATUS_INVALID_ACCOUNT_NAME.
*/
- param->status = NT_SC_ERROR(NT_STATUS_NONE_MAPPED);
+ status = NT_STATUS_NONE_MAPPED;
+ }
+
+ if (status != NT_STATUS_SUCCESS) {
+ bzero(param, sizeof (struct samr_LookupNames));
+ param->status = NT_SC_ERROR(status);
return (MLRPC_DRC_OK);
}
param->rids.rid = MLRPC_HEAP_NEW(mxa, DWORD);
param->rid_types.rid_type = MLRPC_HEAP_NEW(mxa, DWORD);
- if (desc->discrim == SAMR_BUILTIN_DOMAIN) {
- sid = nt_builtin_lookup_name((char *)param->name.str,
- &rid_type);
+ data = (samr_keydata_t *)hd->nh_data;
- if (sid != 0) {
+ switch (data->kd_type) {
+ case NT_DOMAIN_BUILTIN:
+ wka = nt_builtin_lookup((char *)param->name.str);
+ if (wka != NULL) {
param->rids.n_entry = 1;
- (void) nt_sid_get_rid(sid, &param->rids.rid[0]);
+ (void) nt_sid_get_rid(wka->binsid, &param->rids.rid[0]);
param->rid_types.n_entry = 1;
- param->rid_types.rid_type[0] = rid_type;
+ param->rid_types.rid_type[0] = wka->sid_name_use;
param->status = NT_STATUS_SUCCESS;
- free(sid);
return (MLRPC_DRC_OK);
}
- } else if (desc->discrim == SAMR_LOCAL_DOMAIN) {
- grp = nt_group_getinfo((char *)param->name.str, RWLOCK_READER);
+ break;
- if (grp != NULL) {
+ case NT_DOMAIN_LOCAL:
+ rc = smb_lgrp_getbyname((char *)param->name.str, &grp);
+ if (rc == SMB_LGRP_SUCCESS) {
param->rids.n_entry = 1;
- (void) nt_sid_get_rid(grp->sid, &param->rids.rid[0]);
+ param->rids.rid[0] = grp.sg_rid;
param->rid_types.n_entry = 1;
- param->rid_types.rid_type[0] = *grp->sid_name_use;
+ param->rid_types.rid_type[0] = grp.sg_id.gs_type;
param->status = NT_STATUS_SUCCESS;
- nt_group_putinfo(grp);
+ smb_lgrp_free(&grp);
return (MLRPC_DRC_OK);
}
- if ((pw = getpwnam((const char *)param->name.str)) != NULL) {
- param->rids.n_entry = 1;
- param->rids.rid[0] = SAM_ENCODE_UXUID(pw->pw_uid);
- param->rid_types.n_entry = 1;
- param->rid_types.rid_type[0] = SidTypeUser;
- param->status = NT_STATUS_SUCCESS;
- return (MLRPC_DRC_OK);
+ if (smb_pwd_getpasswd((const char *)param->name.str,
+ &smbpw) != NULL) {
+ if (smb_idmap_getsid(smbpw.pw_uid, SMB_IDMAP_USER,
+ &sid) == IDMAP_SUCCESS) {
+ param->rids.n_entry = 1;
+ (void) nt_sid_get_rid(sid, &param->rids.rid[0]);
+ param->rid_types.n_entry = 1;
+ param->rid_types.rid_type[0] = SidTypeUser;
+ param->status = NT_STATUS_SUCCESS;
+ free(sid);
+ return (MLRPC_DRC_OK);
+ }
}
+ break;
- if ((gr = getgrnam((const char *)param->name.str)) != NULL) {
- param->rids.n_entry = 1;
- param->rids.rid[0] = SAM_ENCODE_UXGID(gr->gr_gid);
- param->rid_types.n_entry = 1;
- param->rid_types.rid_type[0] = SidTypeAlias;
- param->status = NT_STATUS_SUCCESS;
- return (MLRPC_DRC_OK);
- }
+ default:
+ bzero(param, sizeof (struct samr_LookupNames));
+ param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
+ return (MLRPC_DRC_OK);
}
param->rids.n_entry = 0;
@@ -559,38 +608,44 @@ samr_s_LookupNames(void *arg, struct mlrpc_xaction *mxa)
* obtained via a successful domain open request. The user is
* specified by the rid in the request.
*/
-/*ARGSUSED*/
static int
samr_s_OpenUser(void *arg, struct mlrpc_xaction *mxa)
{
struct samr_OpenUser *param = arg;
- ms_handle_t *handle;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
+ ndr_handle_t *hd;
+ samr_keydata_t *data;
- if (!mlsvc_validate_handle(
- (ms_handle_t *)&param->handle, SAMR_DOMAIN_KEY)) {
+ if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
bzero(&param->user_handle, sizeof (samr_handle_t));
- param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
+ param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
return (MLRPC_DRC_OK);
}
- handle = mlsvc_get_handle(MLSVC_IFSPEC_SAMR, SAMR_USER_KEY,
- param->rid);
- bcopy(handle, &param->user_handle, sizeof (samr_handle_t));
+ data = (samr_keydata_t *)hd->nh_data;
+
+ id = samr_hdalloc(mxa, SAMR_KEY_USER, data->kd_type, param->rid);
+ if (id == NULL) {
+ bzero(&param->user_handle, sizeof (samr_handle_t));
+ param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
+ } else {
+ bcopy(id, &param->user_handle, sizeof (samr_handle_t));
+ /*
+ * Need QueryUserInfo(level 21).
+ */
+ samr_hdfree(mxa, id);
+ bzero(&param->user_handle, sizeof (samr_handle_t));
+ param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
+ }
- /*
- * Need QueryUserInfo(level 21).
- */
- bzero(&param->user_handle, sizeof (samr_handle_t));
- param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
return (MLRPC_DRC_OK);
}
/*
* samr_s_DeleteUser
*
- * This is a request to delete a user within a specified domain in the
- * local SAM database. The caller should supply a valid user handle but
- * we deny access regardless.
+ * Request to delete a user within a specified domain in the local
+ * SAM database. The caller should supply a valid user handle.
*/
/*ARGSUSED*/
static int
@@ -598,6 +653,7 @@ samr_s_DeleteUser(void *arg, struct mlrpc_xaction *mxa)
{
struct samr_DeleteUser *param = arg;
+ bzero(param, sizeof (struct samr_DeleteUser));
param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
return (MLRPC_DRC_OK);
}
@@ -605,6 +661,8 @@ samr_s_DeleteUser(void *arg, struct mlrpc_xaction *mxa)
/*
* samr_s_QueryUserInfo
*
+ * The caller should provide a valid user key.
+ *
* Returns:
* NT_STATUS_SUCCESS
* NT_STATUS_ACCESS_DENIED
@@ -616,60 +674,108 @@ samr_s_QueryUserInfo(void *arg, struct mlrpc_xaction *mxa)
{
struct samr_QueryUserInfo *param = arg;
- if (!mlsvc_validate_handle(
- (ms_handle_t *)&param->user_handle, SAMR_USER_KEY)) {
- bzero(param, sizeof (struct samr_QueryUserInfo));
- param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
- return (MLRPC_DRC_OK);
- }
-
bzero(param, sizeof (struct samr_QueryUserInfo));
- param->status = 0;
+ param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
return (MLRPC_DRC_OK);
}
/*
* samr_s_QueryUserGroups
*
- * This is a request to obtain a list of groups of which a user is a
- * member. The user is identified from the handle, which contains an
- * encoded uid in the discriminator field.
- *
- * Get complete list of groups and check for builtin domain.
+ * Request the list of groups of which a user is a member.
+ * The user is identified from the handle, which contains an
+ * rid in the discriminator field. Note that this is a local user.
*/
static int
samr_s_QueryUserGroups(void *arg, struct mlrpc_xaction *mxa)
{
struct samr_QueryUserGroups *param = arg;
struct samr_UserGroupInfo *info;
- ms_handle_desc_t *desc;
- struct passwd *pw;
- DWORD uid;
+ struct samr_UserGroups *group;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->user_handle;
+ ndr_handle_t *hd;
+ samr_keydata_t *data;
+ well_known_account_t *wka;
+ nt_sid_t *user_sid = NULL;
+ nt_sid_t *dom_sid;
+ smb_group_t grp;
+ smb_giter_t gi;
+ uint32_t status;
+ int size;
+ int ngrp_max;
+
+ if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_USER)) == NULL) {
+ status = NT_STATUS_ACCESS_DENIED;
+ goto query_error;
+ }
- desc = mlsvc_lookup_handle((ms_handle_t *)&param->user_handle);
- if (desc == 0 || strcmp(desc->key, SAMR_USER_KEY)) {
- bzero(param, sizeof (struct samr_QueryUserGroups));
- param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
- return (MLRPC_DRC_OK);
+ data = (samr_keydata_t *)hd->nh_data;
+ switch (data->kd_type) {
+ case NT_DOMAIN_BUILTIN:
+ wka = nt_builtin_lookup("builtin");
+ if (wka == NULL) {
+ status = NT_STATUS_INTERNAL_ERROR;
+ goto query_error;
+ }
+ dom_sid = wka->binsid;
+ break;
+ case NT_DOMAIN_LOCAL:
+ dom_sid = nt_domain_local_sid();
+ break;
+ default:
+ status = NT_STATUS_INVALID_HANDLE;
+ goto query_error;
+ }
+
+ user_sid = nt_sid_splice(dom_sid, data->kd_rid);
+ if (user_sid == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto query_error;
}
info = MLRPC_HEAP_NEW(mxa, struct samr_UserGroupInfo);
- info->groups = MLRPC_HEAP_NEW(mxa, struct samr_UserGroups);
+ if (info == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto query_error;
+ }
+ bzero(info, sizeof (struct samr_UserGroupInfo));
- uid = SAM_DECODE_RID(desc->discrim);
+ size = 32 * 1024;
+ info->groups = MLRPC_HEAP_MALLOC(mxa, size);
+ if (info->groups == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto query_error;
+ }
+ ngrp_max = size / sizeof (struct samr_UserGroups);
- if ((pw = getpwuid(uid)) != 0) {
- info->n_entry = 1;
- info->groups->rid = SAM_ENCODE_UXGID(pw->pw_gid);
- info->groups->attr = SE_GROUP_MANDATORY
- | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED;
- param->info = info;
- param->status = 0;
- } else {
- bzero(param, sizeof (struct samr_QueryUserGroups));
- param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
+ if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) {
+ status = NT_STATUS_INTERNAL_ERROR;
+ goto query_error;
}
+ info->n_entry = 0;
+ group = info->groups;
+ while ((info->n_entry < ngrp_max) &&
+ (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS)) {
+ if (smb_lgrp_is_member(&grp, user_sid)) {
+ group->rid = grp.sg_rid;
+ group->attr = grp.sg_attr;
+ group++;
+ info->n_entry++;
+ }
+ smb_lgrp_free(&grp);
+ }
+ smb_lgrp_iterclose(&gi);
+
+ free(user_sid);
+ param->info = info;
+ param->status = NT_STATUS_SUCCESS;
+ return (MLRPC_DRC_OK);
+
+query_error:
+ free(user_sid);
+ bzero(param, sizeof (struct samr_QueryUserGroups));
+ param->status = NT_SC_ERROR(status);
return (MLRPC_DRC_OK);
}
@@ -684,50 +790,59 @@ samr_s_QueryUserGroups(void *arg, struct mlrpc_xaction *mxa)
*
* We return a handle to be used to access information about this group.
*/
-/*ARGSUSED*/
static int
samr_s_OpenGroup(void *arg, struct mlrpc_xaction *mxa)
{
struct samr_OpenGroup *param = arg;
- ms_handle_t *handle;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
+ ndr_handle_t *hd;
+ samr_keydata_t *data;
- if (!mlsvc_validate_handle(
- (ms_handle_t *)&param->handle, SAMR_DOMAIN_KEY)) {
+ if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
bzero(&param->group_handle, sizeof (samr_handle_t));
- param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
+ param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
return (MLRPC_DRC_OK);
}
- handle = mlsvc_get_handle(MLSVC_IFSPEC_SAMR, SAMR_GROUP_KEY,
- param->rid);
- bcopy(handle, &param->group_handle, sizeof (samr_handle_t));
+ data = (samr_keydata_t *)hd->nh_data;
+ id = samr_hdalloc(mxa, SAMR_KEY_GROUP, data->kd_type, param->rid);
+
+ if (id) {
+ bcopy(id, &param->group_handle, sizeof (samr_handle_t));
+ param->status = 0;
+ } else {
+ bzero(&param->group_handle, sizeof (samr_handle_t));
+ param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
+ }
- param->status = 0;
return (MLRPC_DRC_OK);
}
/*
* samr_s_Connect
*
- * This is a request to connect to the local SAM database. We don't
- * support any form of update request and our database doesn't
- * contain any private information, so there is little point in
- * doing any access access checking here.
+ * This is a request to connect to the local SAM database.
+ * We don't support any form of update request and our database doesn't
+ * contain any private information, so there is little point in doing
+ * any access access checking here.
*
* Return a handle for use with subsequent SAM requests.
*/
-/*ARGSUSED*/
static int
samr_s_Connect(void *arg, struct mlrpc_xaction *mxa)
{
struct samr_Connect *param = arg;
- ms_handle_t *handle;
+ ndr_hdid_t *id;
- handle = mlsvc_get_handle(MLSVC_IFSPEC_SAMR,
- SAMR_CONNECT_KEY, SAMR_DATABASE_DOMAIN);
- bcopy(handle, &param->handle, sizeof (samr_handle_t));
+ id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, NT_DOMAIN_NULL, 0);
+ if (id) {
+ bcopy(id, &param->handle, sizeof (samr_handle_t));
+ param->status = 0;
+ } else {
+ bzero(&param->handle, sizeof (samr_handle_t));
+ param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
+ }
- param->status = 0;
return (MLRPC_DRC_OK);
}
@@ -741,24 +856,14 @@ static int
samr_s_GetUserPwInfo(void *arg, struct mlrpc_xaction *mxa)
{
struct samr_GetUserPwInfo *param = arg;
- ms_handle_t *handle;
- DWORD status = 0;
-
- handle = (ms_handle_t *)&param->user_handle;
-
- if (!mlsvc_validate_handle(handle, SAMR_USER_KEY))
- status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
bzero(param, sizeof (struct samr_GetUserPwInfo));
- param->status = status;
+ param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
return (MLRPC_DRC_OK);
}
/*
* samr_s_CreateUser
- *
- * This is a request to create a user within a specified domain in the
- * local SAM database. We always deny access.
*/
/*ARGSUSED*/
static int
@@ -816,25 +921,25 @@ samr_s_SetUserInfo(void *arg, struct mlrpc_xaction *mxa)
/*
* samr_s_QueryDispInfo
*
- * This function is supposed to return local users' information.
+ * This function is supposed to return local user information.
* As we don't support local users, this function dosen't send
* back any information.
*
- * I added a peice of code that returns information for Administrator
- * and Guest builtin users. All information are hard-coded which I get
- * from packet captures. Currently, this peice of code is opt-out.
+ * Added template that returns information for Administrator and Guest
+ * builtin users. All information is hard-coded from packet captures.
*/
-/*ARGSUSED*/
static int
samr_s_QueryDispInfo(void *arg, struct mlrpc_xaction *mxa)
{
struct samr_QueryDispInfo *param = arg;
- ms_handle_desc_t *desc;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->domain_handle;
DWORD status = 0;
- desc = mlsvc_lookup_handle((ms_handle_t *)&param->domain_handle);
- if (desc == NULL || (strcmp(desc->key, SAMR_DOMAIN_KEY) != 0))
- status = NT_STATUS_INVALID_HANDLE;
+ if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) == NULL) {
+ bzero(param, sizeof (struct samr_QueryDispInfo));
+ param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
+ return (MLRPC_DRC_OK);
+ }
#ifdef SAMR_SUPPORT_USER
if ((desc->discrim != SAMR_LOCAL_DOMAIN) || (param->start_idx != 0)) {
@@ -897,24 +1002,21 @@ samr_s_QueryDispInfo(void *arg, struct mlrpc_xaction *mxa)
* samr_s_EnumDomainGroups
*
*
- * This function is supposed to return local users' information.
+ * This function is supposed to return local group information.
* As we don't support local users, this function dosen't send
* back any information.
*
- * I added a peice of code that returns information for a
- * domain group as None. All information are hard-coded which I get
- * from packet captures. Currently, this peice of code is opt-out.
+ * Added template that returns information for a domain group as None.
+ * All information is hard-coded from packet captures.
*/
-/*ARGSUSED*/
static int
samr_s_EnumDomainGroups(void *arg, struct mlrpc_xaction *mxa)
{
struct samr_EnumDomainGroups *param = arg;
- ms_handle_desc_t *desc;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->domain_handle;
DWORD status = NT_STATUS_SUCCESS;
- desc = mlsvc_lookup_handle((ms_handle_t *)&param->domain_handle);
- if (desc == NULL || (strcmp(desc->key, SAMR_DOMAIN_KEY) != 0))
+ if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) == NULL)
status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
param->total_size = 0;
@@ -964,18 +1066,17 @@ samr_s_EnumDomainGroups(void *arg, struct mlrpc_xaction *mxa)
* for that alias. The alias domain sid should match with
* the passed domain handle.
*/
-/*ARGSUSED*/
static int
samr_s_OpenAlias(void *arg, struct mlrpc_xaction *mxa)
{
struct samr_OpenAlias *param = arg;
- ms_handle_desc_t *desc = 0;
- ms_handle_t *handle;
- nt_group_t *grp;
- DWORD status = NT_STATUS_SUCCESS;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->domain_handle;
+ ndr_handle_t *hd;
+ uint32_t status;
+ samr_keydata_t *data;
+ int rc;
- desc = mlsvc_lookup_handle((ms_handle_t *)&param->domain_handle);
- if (desc == 0 || (strcmp(desc->key, SAMR_DOMAIN_KEY) != 0)) {
+ if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
status = NT_STATUS_INVALID_HANDLE;
goto open_alias_err;
}
@@ -985,25 +1086,21 @@ samr_s_OpenAlias(void *arg, struct mlrpc_xaction *mxa)
goto open_alias_err;
}
- grp = nt_groups_lookup_rid(param->rid);
- if (grp == 0) {
+ data = (samr_keydata_t *)hd->nh_data;
+ rc = smb_lgrp_getbyrid(param->rid, (smb_gdomain_t)data->kd_type, NULL);
+ if (rc != SMB_LGRP_SUCCESS) {
status = NT_STATUS_NO_SUCH_ALIAS;
goto open_alias_err;
}
- if (((desc->discrim == SAMR_LOCAL_DOMAIN) &&
- !nt_sid_is_local(grp->sid)) ||
- ((desc->discrim == SAMR_BUILTIN_DOMAIN) &&
- !nt_sid_is_builtin(grp->sid))) {
- status = NT_STATUS_NO_SUCH_ALIAS;
- goto open_alias_err;
+ id = samr_hdalloc(mxa, SAMR_KEY_ALIAS, data->kd_type, param->rid);
+ if (id) {
+ bcopy(id, &param->alias_handle, sizeof (samr_handle_t));
+ param->status = NT_STATUS_SUCCESS;
+ return (MLRPC_DRC_OK);
}
- handle = mlsvc_get_handle(MLSVC_IFSPEC_SAMR, SAMR_ALIAS_KEY,
- param->rid);
- bcopy(handle, &param->alias_handle, sizeof (samr_handle_t));
- param->status = 0;
- return (MLRPC_DRC_OK);
+ status = NT_STATUS_NO_MEMORY;
open_alias_err:
bzero(&param->alias_handle, sizeof (samr_handle_t));
@@ -1025,33 +1122,29 @@ static int
samr_s_CreateDomainAlias(void *arg, struct mlrpc_xaction *mxa)
{
struct samr_CreateDomainAlias *param = arg;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->alias_handle;
+
+ if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) == NULL) {
+ bzero(param, sizeof (struct samr_CreateDomainAlias));
+ param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
+ return (MLRPC_DRC_OK);
+ }
+
+ bzero(param, sizeof (struct samr_CreateDomainAlias));
+ param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
+ return (MLRPC_DRC_OK);
#ifdef SAMR_SUPPORT_ADD_ALIAS
DWORD status = NT_STATUS_SUCCESS;
- ms_handle_desc_t *desc = 0;
- ms_handle_t *handle;
nt_group_t *grp;
char *alias_name;
-#endif
- bzero(&param->alias_handle, sizeof (samr_handle_t));
- param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
- return (MLRPC_DRC_OK);
-#ifdef SAMR_SUPPORT_ADD_ALIAS
alias_name = param->alias_name.str;
if (alias_name == 0) {
status = NT_STATUS_INVALID_PARAMETER;
goto create_alias_err;
}
- desc = mlsvc_lookup_handle((ms_handle_t *)&param->domain_handle);
- if (desc == 0 ||
- (desc->discrim != SAMR_LOCAL_DOMAIN) ||
- (strcmp(desc->key, SAMR_DOMAIN_KEY) != 0)) {
- status = NT_STATUS_INVALID_HANDLE;
- goto create_alias_err;
- }
-
/*
* Check access mask. User should be member of
* Administrators or Account Operators local group.
@@ -1087,19 +1180,17 @@ create_alias_err:
/*
* samr_s_SetAliasInfo
*
- * For more information you can look at MSDN page for NetLocalGroupSetInfo.
+ * Similar to NetLocalGroupSetInfo.
*/
-/*ARGSUSED*/
static int
samr_s_SetAliasInfo(void *arg, struct mlrpc_xaction *mxa)
{
struct samr_SetAliasInfo *param = arg;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->alias_handle;
DWORD status = NT_STATUS_SUCCESS;
- if (!mlsvc_validate_handle(
- (ms_handle_t *)&param->alias_handle, SAMR_ALIAS_KEY)) {
+ if (samr_hdlookup(mxa, id, SAMR_KEY_ALIAS) == NULL)
status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
- }
param->status = status;
return (MLRPC_DRC_OK);
@@ -1115,18 +1206,22 @@ static int
samr_s_QueryAliasInfo(void *arg, struct mlrpc_xaction *mxa)
{
struct samr_QueryAliasInfo *param = arg;
- ms_handle_desc_t *desc;
- nt_group_t *grp;
- DWORD status;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->alias_handle;
+ ndr_handle_t *hd;
+ samr_keydata_t *data;
+ smb_group_t grp;
+ uint32_t status;
+ int rc;
- desc = mlsvc_lookup_handle((ms_handle_t *)&param->alias_handle);
- if (desc == NULL || (strcmp(desc->key, SAMR_ALIAS_KEY) != 0)) {
+ if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) {
status = NT_STATUS_INVALID_HANDLE;
goto query_alias_err;
}
- grp = nt_groups_lookup_rid(desc->discrim);
- if (grp == NULL) {
+ data = (samr_keydata_t *)hd->nh_data;
+ rc = smb_lgrp_getbyrid(data->kd_rid, (smb_gdomain_t)data->kd_type,
+ &grp);
+ if (rc != SMB_LGRP_SUCCESS) {
status = NT_STATUS_NO_SUCH_ALIAS;
goto query_alias_err;
}
@@ -1135,10 +1230,10 @@ samr_s_QueryAliasInfo(void *arg, struct mlrpc_xaction *mxa)
case SAMR_QUERY_ALIAS_INFO_1:
param->ru.info1.level = param->level;
(void) mlsvc_string_save(
- (ms_string_t *)&param->ru.info1.name, grp->name, mxa);
+ (ms_string_t *)&param->ru.info1.name, grp.sg_name, mxa);
(void) mlsvc_string_save(
- (ms_string_t *)&param->ru.info1.desc, grp->comment, mxa);
+ (ms_string_t *)&param->ru.info1.desc, grp.sg_cmnt, mxa);
param->ru.info1.unknown = 1;
break;
@@ -1146,15 +1241,16 @@ samr_s_QueryAliasInfo(void *arg, struct mlrpc_xaction *mxa)
case SAMR_QUERY_ALIAS_INFO_3:
param->ru.info3.level = param->level;
(void) mlsvc_string_save(
- (ms_string_t *)&param->ru.info3.desc, grp->comment, mxa);
-
+ (ms_string_t *)&param->ru.info3.desc, grp.sg_cmnt, mxa);
break;
default:
+ smb_lgrp_free(&grp);
status = NT_STATUS_INVALID_INFO_CLASS;
goto query_alias_err;
};
+ smb_lgrp_free(&grp);
param->address = (DWORD)(uintptr_t)&param->ru;
param->status = 0;
return (MLRPC_DRC_OK);
@@ -1176,28 +1272,26 @@ query_alias_err:
* This RPC is used by CMC and right now it returns access denied.
* The peice of code that removes a local group doesn't get compiled.
*/
-/*ARGSUSED*/
static int
samr_s_DeleteDomainAlias(void *arg, struct mlrpc_xaction *mxa)
{
struct samr_DeleteDomainAlias *param = arg;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->alias_handle;
-#ifdef SAMR_SUPPORT_DEL_ALIAS
- ms_handle_desc_t *desc = 0;
- nt_group_t *grp;
- char *alias_name;
- DWORD status;
-#endif
+ if (samr_hdlookup(mxa, id, SAMR_KEY_ALIAS) == NULL) {
+ bzero(param, sizeof (struct samr_DeleteDomainAlias));
+ param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
+ return (MLRPC_DRC_OK);
+ }
+ bzero(param, sizeof (struct samr_DeleteDomainAlias));
param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
return (MLRPC_DRC_OK);
#ifdef SAMR_SUPPORT_DEL_ALIAS
- desc = mlsvc_lookup_handle((ms_handle_t *)&param->alias_handle);
- if (desc == 0 || (strcmp(desc->key, SAMR_ALIAS_KEY) != 0)) {
- status = NT_STATUS_INVALID_HANDLE;
- goto delete_alias_err;
- }
+ nt_group_t *grp;
+ char *alias_name;
+ DWORD status;
grp = nt_groups_lookup_rid(desc->discrim);
if (grp == 0) {
@@ -1234,77 +1328,65 @@ static int
samr_s_EnumDomainAliases(void *arg, struct mlrpc_xaction *mxa)
{
struct samr_EnumDomainAliases *param = arg;
- ms_handle_desc_t *desc;
- nt_group_t *grp = NULL;
- DWORD status;
- nt_group_iterator_t *gi;
- nt_sid_t *local_sid;
- nt_sid_t *builtin_sid;
- nt_sid_t *sid;
- DWORD cnt, skip;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->domain_handle;
+ ndr_handle_t *hd;
+ samr_keydata_t *data;
+ smb_group_t grp;
+ smb_giter_t gi;
+ int cnt, skip, i;
struct name_rid *info;
- desc = mlsvc_lookup_handle((ms_handle_t *)&param->domain_handle);
- if (desc == NULL || (strcmp(desc->key, SAMR_DOMAIN_KEY) != 0)) {
- status = NT_STATUS_INVALID_HANDLE;
- goto enum_alias_err;
+ if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN)) == NULL) {
+ bzero(param, sizeof (struct samr_EnumDomainAliases));
+ param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
+ return (MLRPC_DRC_OK);
}
- local_sid = nt_domain_local_sid();
- builtin_sid = nt_builtin_lookup_name("BUILTIN", 0);
+ data = (samr_keydata_t *)hd->nh_data;
- if (desc->discrim == SAMR_LOCAL_DOMAIN) {
- sid = local_sid;
- } else if (desc->discrim == SAMR_BUILTIN_DOMAIN) {
- sid = builtin_sid;
- } else {
- status = NT_STATUS_INVALID_HANDLE;
- goto enum_alias_err;
- }
+ (void) smb_lgrp_numbydomain((smb_gdomain_t)data->kd_type, &cnt);
+ if (cnt <= param->resume_handle) {
+ param->aliases = (struct aliases_info *)MLRPC_HEAP_MALLOC(mxa,
+ sizeof (struct aliases_info));
- cnt = skip = 0;
- gi = nt_group_open_iterator();
- nt_group_ht_lock(RWLOCK_READER);
- while ((grp = nt_group_iterate(gi)) != 0) {
- if (skip++ < param->resume_handle)
- continue;
- if (nt_sid_is_indomain(sid, grp->sid))
- cnt++;
+ bzero(param->aliases, sizeof (struct aliases_info));
+ param->out_resume = 0;
+ param->entries = 0;
+ param->status = NT_STATUS_SUCCESS;
+ return (MLRPC_DRC_OK);
}
- nt_group_ht_unlock();
- nt_group_close_iterator(gi);
+ cnt -= param->resume_handle;
param->aliases = (struct aliases_info *)MLRPC_HEAP_MALLOC(mxa,
sizeof (struct aliases_info) + (cnt-1) * sizeof (struct name_rid));
- param->aliases->count = cnt;
- param->aliases->address = cnt;
- info = param->aliases->info;
+ if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) {
+ bzero(param, sizeof (struct samr_EnumDomainAliases));
+ param->status = NT_SC_ERROR(NT_STATUS_INTERNAL_ERROR);
+ return (MLRPC_DRC_OK);
+ }
- skip = 0;
- gi = nt_group_open_iterator();
- nt_group_ht_lock(RWLOCK_READER);
- while ((grp = nt_group_iterate(gi)) != NULL) {
- if (skip++ < param->resume_handle)
- continue;
- if (nt_sid_is_indomain(sid, grp->sid)) {
- (void) nt_sid_get_rid(grp->sid, &info->rid);
+ skip = i = 0;
+ info = param->aliases->info;
+ while (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS) {
+ if ((skip++ >= param->resume_handle) &&
+ (grp.sg_domain == data->kd_type) && (i++ < cnt)) {
+ info->rid = grp.sg_rid;
(void) mlsvc_string_save((ms_string_t *)&info->name,
- grp->name, mxa);
+ grp.sg_name, mxa);
info++;
}
+ smb_lgrp_free(&grp);
}
- nt_group_ht_unlock();
- nt_group_close_iterator(gi);
+ smb_lgrp_iterclose(&gi);
- param->out_resume = cnt;
- param->entries = cnt;
- param->status = 0;
- return (MLRPC_DRC_OK);
+ param->aliases->count = i;
+ param->aliases->address = i;
-enum_alias_err:
- param->status = NT_SC_ERROR(status);
+ param->out_resume = i;
+ param->entries = i;
+ param->status = 0;
return (MLRPC_DRC_OK);
}
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_srvsvc.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_srvsvc.c
index 26cd32ac5d..fbb37f5d04 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_srvsvc.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_srvsvc.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -100,21 +100,6 @@ static mlrpc_service_t srvsvc_service = {
};
/*
- * srvsvc_fix_comment
- *
- * The parser sometimes has problems with empty strings so we
- * need to ensure that the comment field has something in it.
- */
-static inline char *
-srvsvc_fix_comment(char *original, char *alternative)
-{
- if (original == 0 || strlen(original) == 0)
- return (alternative);
-
- return (original);
-}
-
-/*
* srvsvc_share_mkpath
*
* Create the share path required by the share enum calls. This function
@@ -516,12 +501,10 @@ srvsvc_s_NetShareSetInfo(void *arg, struct mlrpc_xaction *mxa)
sizeof (DWORD));
param->parm_err = 0;
- smb_config_rdlock();
- if (smb_config_getyorn(SMB_CI_SRVSVC_SHRSET_ENABLE) != 0)
+ if (!smb_config_getbool(SMB_CI_SRVSVC_SHRSET_ENABLE))
param->status = ERROR_SUCCESS;
else
param->status = ERROR_ACCESS_DENIED;
- smb_config_unlock();
return (MLRPC_DRC_OK);
}
@@ -805,7 +788,7 @@ srvsvc_s_NetServerGetInfo(void *arg, struct mlrpc_xaction *mxa)
struct mslm_SERVER_INFO_100 *info100;
struct mslm_SERVER_INFO_101 *info101;
struct mslm_SERVER_INFO_102 *info102;
- char *sys_comment;
+ char sys_comment[SMB_PI_MAX_COMMENT];
char hostname[MAXHOSTNAMELEN];
if (smb_gethostname(hostname, MAXHOSTNAMELEN, 1) != 0) {
@@ -814,10 +797,10 @@ netservergetinfo_no_memory:
return (ERROR_NOT_ENOUGH_MEMORY);
}
- smb_config_rdlock();
- sys_comment = smb_config_getstr(SMB_CI_SYS_CMNT);
- sys_comment = srvsvc_fix_comment(sys_comment, " ");
- smb_config_unlock();
+ (void) smb_config_getstr(SMB_CI_SYS_CMNT, sys_comment,
+ sizeof (sys_comment));
+ if (*sys_comment == '\0')
+ (void) strcpy(sys_comment, " ");
switch (param->level) {
case 100:
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_svcctl.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_svcctl.c
index eca831f899..242fdbc75f 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_svcctl.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_svcctl.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -43,17 +43,10 @@
#include <smbsrv/ndl/svcctl.ndl>
/*
- * SVCCTL diagnostics flag: set to 1 to enable verbose logging.
+ * The handle keys for this interface.
*/
-int svcctl_debug = 0;
-
-/*
- * The handle keys for the various types of handles returned
- * by this interface.
- */
-#define SVCCTL_MANAGER_KEY "svcctlManager"
-#define SVCCTL_SERVICE_KEY "svcctlService"
-
+static int svcctl_key_manager;
+static int svcctl_key_service;
typedef struct {
char *svc_name;
@@ -93,8 +86,6 @@ static svc_info_t svc_info[] = {
static DWORD svcctl_get_status(const char *);
static DWORD svcctl_validate_service(char *);
-static DWORD svcctl_validate_handle(char *, ms_handle_t *, char *,
- struct mlrpc_xaction *);
static int svcctl_is_admin(struct mlrpc_xaction *);
static int svcctl_s_Close(void *, struct mlrpc_xaction *);
@@ -157,60 +148,51 @@ static int
svcctl_s_Close(void *arg, struct mlrpc_xaction *mxa)
{
struct svcctl_Close *param = arg;
- smb_dr_user_ctx_t *user_ctx = mxa->context->user_ctx;
- ms_handle_t *handle;
- DWORD status;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
- if (svcctl_debug)
- smb_token_log(LOG_DEBUG, user_ctx, "(SvcctlClose)");
-
- handle = (ms_handle_t *)&param->handle;
- status = svcctl_validate_handle("SvcctlClose", handle, 0, mxa);
-
- if (status == ERROR_SUCCESS)
- (void) mlsvc_put_handle((ms_handle_t *)&param->handle);
+ ndr_hdfree(mxa, id);
bzero(&param->result_handle, sizeof (svcctl_handle_t));
- param->status = status;
+ param->status = ERROR_SUCCESS;
return (MLRPC_DRC_OK);
}
/*
* svcctl_s_OpenManager
*
- * This is a request to open the service control manager. Dependent
- * on the desired access we either generate a handle to be used on
- * subsequent requests or deny access.
+ * Request to open the service control manager.
+ * The caller must have administrator rights in order to open this
+ * interface. We don't support write access.
*
* Returns:
* ERROR_SUCCESS
* ERROR_ACCESS_DENIED
*
- * Return a handle for use with subsequent svcctl requests.
+ * On success, returns a handle for use with subsequent svcctl requests.
*/
static int
svcctl_s_OpenManager(void *arg, struct mlrpc_xaction *mxa)
{
struct svcctl_OpenManager *param = arg;
- ms_handle_t *handle;
+ ndr_hdid_t *id;
int rc;
rc = svcctl_is_admin(mxa);
if ((rc == 0) || (param->desired_access & SC_MANAGER_LOCK) != 0) {
- /*
- * The user doesn't have Administrator rights
- * or wants a write lock on the Services DB.
- */
bzero(&param->handle, sizeof (svcctl_handle_t));
param->status = ERROR_ACCESS_DENIED;
return (MLRPC_DRC_OK);
}
- handle = mlsvc_get_handle(MLSVC_IFSPEC_SVCCTL, SVCCTL_MANAGER_KEY, 0);
- bcopy(handle, &param->handle, sizeof (svcctl_handle_t));
+ if ((id = ndr_hdalloc(mxa, &svcctl_key_manager)) != NULL) {
+ bcopy(id, &param->handle, sizeof (svcctl_handle_t));
+ param->status = ERROR_SUCCESS;
+ } else {
+ bzero(&param->handle, sizeof (svcctl_handle_t));
+ param->status = ERROR_ACCESS_DENIED;
+ }
- param->status = ERROR_SUCCESS;
return (MLRPC_DRC_OK);
}
@@ -228,15 +210,14 @@ static int
svcctl_s_OpenService(void *arg, struct mlrpc_xaction *mxa)
{
struct svcctl_OpenService *param = arg;
- ms_handle_t *handle;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->manager_handle;
+ ndr_handle_t *hd;
DWORD status;
- status = svcctl_validate_handle("SvcctlOpenService",
- (ms_handle_t *)&param->manager_handle, SVCCTL_MANAGER_KEY, mxa);
-
- if (status != ERROR_SUCCESS) {
+ hd = ndr_hdlookup(mxa, id);
+ if ((hd == NULL) || (hd->nh_data != &svcctl_key_manager)) {
bzero(&param->service_handle, sizeof (svcctl_handle_t));
- param->status = status;
+ param->status = ERROR_INVALID_HANDLE;
return (MLRPC_DRC_OK);
}
@@ -247,10 +228,14 @@ svcctl_s_OpenService(void *arg, struct mlrpc_xaction *mxa)
return (MLRPC_DRC_OK);
}
- handle = mlsvc_get_handle(MLSVC_IFSPEC_SVCCTL, SVCCTL_SERVICE_KEY, 0);
- bcopy(handle, &param->service_handle, sizeof (svcctl_handle_t));
+ if ((id = ndr_hdalloc(mxa, &svcctl_key_service)) != NULL) {
+ bcopy(id, &param->service_handle, sizeof (svcctl_handle_t));
+ param->status = ERROR_SUCCESS;
+ } else {
+ bzero(&param->service_handle, sizeof (svcctl_handle_t));
+ param->status = ERROR_ACCESS_DENIED;
+ }
- param->status = ERROR_SUCCESS;
return (MLRPC_DRC_OK);
}
@@ -265,14 +250,13 @@ static int
svcctl_s_QueryServiceStatus(void *arg, struct mlrpc_xaction *mxa)
{
struct svcctl_QueryServiceStatus *param = arg;
- DWORD status;
-
- status = svcctl_validate_handle("SvcctlQueryServiceStatus",
- (ms_handle_t *)&param->service_handle, SVCCTL_SERVICE_KEY, mxa);
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->service_handle;
+ ndr_handle_t *hd;
- if (status != ERROR_SUCCESS) {
+ hd = ndr_hdlookup(mxa, id);
+ if ((hd == NULL) || (hd->nh_data != &svcctl_key_service)) {
bzero(&param, sizeof (struct svcctl_QueryServiceStatus));
- param->status = status;
+ param->status = ERROR_INVALID_HANDLE;
return (MLRPC_DRC_OK);
}
@@ -303,19 +287,19 @@ static int
svcctl_s_EnumServicesStatus(void *arg, struct mlrpc_xaction *mxa)
{
struct svcctl_EnumServicesStatus *param = arg;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->manager_handle;
+ ndr_handle_t *hd;
svc_enum_status_t *service_table;
svc_enum_status_t *svc;
mts_wchar_t *wide_name;
char *name;
int i, namelen;
int offs;
- DWORD status;
- status = svcctl_validate_handle("SvcctlEnumServicesStatus",
- (ms_handle_t *)&param->manager_handle, SVCCTL_MANAGER_KEY, mxa);
-
- if (status != ERROR_SUCCESS) {
- param->status = status;
+ hd = ndr_hdlookup(mxa, id);
+ if ((hd == NULL) || (hd->nh_data != &svcctl_key_manager)) {
+ bzero(&param, sizeof (struct svcctl_EnumServicesStatus));
+ param->status = ERROR_INVALID_HANDLE;
return (MLRPC_DRC_OK);
}
@@ -382,14 +366,13 @@ static int
svcctl_s_QueryServiceConfig(void *arg, struct mlrpc_xaction *mxa)
{
struct svcctl_QueryServiceConfig *param = arg;
- DWORD status;
-
- status = svcctl_validate_handle("SvcctlQueryServiceConfig",
- (ms_handle_t *)&param->service_handle, SVCCTL_SERVICE_KEY, mxa);
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->service_handle;
+ ndr_handle_t *hd;
- if (status != ERROR_SUCCESS) {
+ hd = ndr_hdlookup(mxa, id);
+ if ((hd == NULL) || (hd->nh_data != &svcctl_key_service)) {
bzero(&param, sizeof (struct svcctl_QueryServiceConfig));
- param->status = status;
+ param->status = ERROR_INVALID_HANDLE;
return (MLRPC_DRC_OK);
}
@@ -434,30 +417,6 @@ svcctl_validate_service(char *svc_name)
}
/*
- * Check whether or not the svcctl module allocated this handle.
- *
- * Returns:
- * ERROR_SUCCESS
- * ERROR_INVALID_HANDLE.
- */
-/*ARGSUSED*/
-static DWORD
-svcctl_validate_handle(char *name, ms_handle_t *handle, char *key,
- struct mlrpc_xaction *mxa)
-{
- int mgr_erc;
- int svc_erc;
-
- mgr_erc = mlsvc_validate_handle(handle, SVCCTL_MANAGER_KEY);
- svc_erc = mlsvc_validate_handle(handle, SVCCTL_SERVICE_KEY);
-
- if (mgr_erc == 0 && svc_erc == 0)
- return (ERROR_INVALID_HANDLE);
-
- return (ERROR_SUCCESS);
-}
-
-/*
* Report the service status: SERVICE_PAUSED or SERVICE_RUNNING.
*/
/*ARGSUSED*/
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c
index 81e3893781..94f50d40b4 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -35,8 +35,6 @@
#include <unistd.h>
#include <netdb.h>
#include <stdlib.h>
-#include <pwd.h>
-#include <grp.h>
#include <sys/time.h>
#include <sys/systm.h>
@@ -53,15 +51,14 @@
#include <smbsrv/mlsvc_util.h>
#include <smbsrv/mlsvc.h>
+/* Domain join support (using MS-RPC) */
+static boolean_t mlsvc_ntjoin_support = B_FALSE;
+
extern int netr_open(char *, char *, mlsvc_handle_t *);
extern int netr_close(mlsvc_handle_t *);
extern DWORD netlogon_auth(char *, mlsvc_handle_t *, DWORD);
extern int mlsvc_user_getauth(char *, char *, smb_auth_info_t *);
-static int mlsvc_lookup_local_name(char *name, nt_sid_t **sid);
-static int mlsvc_lookup_nt_name(char *name, nt_sid_t **sid);
-static int mlsvc_lookup_nt_sid(nt_sid_t *sid, char *buf, int bufsize);
-
/*
* Compare the supplied domain name with the local hostname.
* We need to deal with both server names and fully-qualified
@@ -77,9 +74,11 @@ int
mlsvc_is_local_domain(const char *domain)
{
char hostname[MAXHOSTNAMELEN];
- uint32_t mode;
int rc;
+ if (smb_config_get_secmode() == SMB_SECMODE_WORKGRP)
+ return (1);
+
if (strchr(domain, '.') != NULL)
rc = smb_getfqhostname(hostname, MAXHOSTNAMELEN);
else
@@ -88,10 +87,7 @@ mlsvc_is_local_domain(const char *domain)
if (rc != 0)
return (-1);
- rc = strcasecmp(domain, hostname);
- mode = smb_get_security_mode();
-
- if ((rc == 0) || (mode == SMB_SECMODE_WORKGRP))
+ if (strcasecmp(domain, hostname) == 0)
return (1);
return (0);
@@ -100,163 +96,62 @@ mlsvc_is_local_domain(const char *domain)
/*
* mlsvc_lookup_name
*
- * Lookup a name in the specified domain and translate it to a SID.
- * If the name is in the NT domain, it may refer to a user, group or
- * alias. Otherwise it must refer to a UNIX username. The memory for
- * the sid is allocated using malloc so the caller should call free
- * when it is no longer required.
- *
- * On success, 0 will be returned and sid will point to a local domain
- * user SID. Otherwise -1 will be returned.
- */
-int
-mlsvc_lookup_name(char *domain, char *name, nt_sid_t **sid)
-{
- if (domain == NULL || name == NULL || sid == NULL)
- return (-1);
-
- if (mlsvc_is_local_domain(domain) == 1)
- return (mlsvc_lookup_local_name(name, sid));
- else
- return (mlsvc_lookup_nt_name(name, sid));
-}
-
-/*
- * mlsvc_lookup_local_name
- *
- * Lookup a name in the local password file and translate it to a SID.
- * The name must refer to a user. This is a private function intended
- * to support mlsvc_lookup_name so it doesn't perform any parameter
- * validation. The memory for the sid is allocated using malloc so the
- * caller must call free when it is no longer required.
- *
- * On success, 0 will be returned and sid will point to a local domain
- * user SID. Otherwise -1 will be returned.
- */
-static int
-mlsvc_lookup_local_name(char *name, nt_sid_t **sid)
-{
- struct passwd *pw;
- nt_sid_t *domain_sid;
-
- if ((pw = getpwnam(name)) == NULL)
- return (-1);
-
- if ((domain_sid = nt_domain_local_sid()) == NULL)
- return (-1);
-
- *sid = nt_sid_splice(domain_sid, pw->pw_uid);
- return (0);
-}
-
-/*
- * mlsvc_lookup_nt_name
- *
- * Lookup a name in the specified NT domain and translate it to a SID.
- * The name may refer to a user, group or alias. This is a private
- * function intended to support mlsvc_lookup_name so it doesn't do any
- * parameter validation. The memory for the sid is allocated using
- * malloc so the caller should call free when it is no longer required.
+ * This is just a wrapper for lsa_lookup_name.
*
- * On success, 0 will be returned and sid will point to an NT domain
- * user SID. Otherwise -1 will be returned.
+ * The memory for the sid is allocated using malloc so the caller should
+ * call free when it is no longer required.
*/
-static int
-mlsvc_lookup_nt_name(char *name, nt_sid_t **sid)
+uint32_t
+mlsvc_lookup_name(char *account, nt_sid_t **sid, uint16_t *sid_type)
{
- smb_userinfo_t *user_info;
+ smb_userinfo_t *ainfo;
+ uint32_t status;
- if ((user_info = mlsvc_alloc_user_info()) == NULL)
- return (-1);
+ if ((ainfo = mlsvc_alloc_user_info()) == NULL)
+ return (NT_STATUS_NO_MEMORY);
- if (lsa_lookup_name(0, 0, name, user_info) != 0)
- return (-1);
+ status = lsa_lookup_name(NULL, account, *sid_type, ainfo);
+ if (status == NT_STATUS_SUCCESS) {
+ *sid = ainfo->user_sid;
+ ainfo->user_sid = NULL;
+ *sid_type = ainfo->sid_name_use;
+ }
- *sid = nt_sid_splice(user_info->domain_sid, user_info->rid);
- mlsvc_free_user_info(user_info);
- return (0);
+ mlsvc_free_user_info(ainfo);
+ return (status);
}
/*
* mlsvc_lookup_sid
*
- * Lookup a SID and translate it to a name. The name returned may refer
- * to a domain, user, group or alias dependent on the SID. On success 0
- * will be returned. Otherwise -1 will be returned.
+ * This is just a wrapper for lsa_lookup_sid.
+ *
+ * The allocated memory for the returned name must be freed by caller upon
+ * successful return.
*/
-int
-mlsvc_lookup_sid(nt_sid_t *sid, char *buf, int bufsize)
+uint32_t
+mlsvc_lookup_sid(nt_sid_t *sid, char **name)
{
- struct passwd *pw;
- struct group *gr;
- nt_group_t *grp;
- DWORD rid;
-
- if (sid == NULL || buf == NULL)
- return (-1);
-
- if (nt_sid_is_local(sid)) {
- (void) nt_sid_get_rid(sid, &rid);
-
- switch (SAM_RID_TYPE(rid)) {
- case SAM_RT_NT_UID:
- break;
-
- case SAM_RT_NT_GID:
- if ((grp = nt_groups_lookup_rid(rid)) == NULL)
- return (-1);
-
- (void) strlcpy(buf, grp->name, bufsize);
- break;
-
- case SAM_RT_UNIX_UID:
- if ((pw = getpwuid(SAM_DECODE_RID(rid))) == NULL)
- return (-1);
+ smb_userinfo_t *ainfo;
+ uint32_t status;
+ int namelen;
- (void) strlcpy(buf, pw->pw_name, bufsize);
- break;
+ if ((ainfo = mlsvc_alloc_user_info()) == NULL)
+ return (NT_STATUS_NO_MEMORY);
- case SAM_RT_UNIX_GID:
- if ((gr = getgrgid(SAM_DECODE_RID(rid))) == NULL)
- return (-1);
-
- (void) strlcpy(buf, gr->gr_name, bufsize);
- break;
+ status = lsa_lookup_sid(sid, ainfo);
+ if (status == NT_STATUS_SUCCESS) {
+ namelen = strlen(ainfo->domain_name) + strlen(ainfo->name) + 2;
+ if ((*name = malloc(namelen)) == NULL) {
+ mlsvc_free_user_info(ainfo);
+ return (NT_STATUS_NO_MEMORY);
}
-
- return (0);
+ (void) snprintf(*name, namelen, "%s\\%s",
+ ainfo->domain_name, ainfo->name);
}
- return (mlsvc_lookup_nt_sid(sid, buf, bufsize));
-}
-
-/*
- * mlsvc_lookup_nt_sid
- *
- * Lookup an NT SID and translate it to a name. This is a private
- * function intended to support mlsvc_lookup_sid so it doesn't do any
- * parameter validation. The input account_name specifies the logon/
- * session to be used for the lookup. It doesn't need to have any
- * association with the SID being looked up. The name returned may
- * refer to a domain, user, group or alias dependent on the SID.
- *
- * On success the name will be copied into buf and 0 will be returned.
- * Otherwise -1 will be returned.
- */
-static int
-mlsvc_lookup_nt_sid(nt_sid_t *sid, char *buf, int bufsize)
-{
- smb_userinfo_t *user_info;
- int rc;
-
- if ((user_info = mlsvc_alloc_user_info()) == NULL)
- return (-1);
-
- if ((rc = lsa_lookup_sid(sid, user_info)) == 0)
- (void) strlcpy(buf, user_info->name, bufsize);
-
- mlsvc_free_user_info(user_info);
- return (rc);
+ mlsvc_free_user_info(ainfo);
+ return (status);
}
/*
@@ -337,8 +232,8 @@ void
mlsvc_setadmin_user_info(smb_userinfo_t *user_info)
{
nt_domain_t *domain;
- nt_group_t *grp;
- int i;
+ smb_group_t grp;
+ int rc, i;
if ((domain = nt_domain_lookupbytype(NT_DOMAIN_PRIMARY)) == NULL)
return;
@@ -356,12 +251,11 @@ mlsvc_setadmin_user_info(smb_userinfo_t *user_info)
user_info->flags |= SMB_UINFO_FLAG_DADMIN;
}
- grp = nt_group_getinfo("Administrators", RWLOCK_READER);
- if (grp) {
- i = nt_group_is_member(grp, user_info->user_sid);
- nt_group_putinfo(grp);
- if (i)
+ rc = smb_lgrp_getbyname("Administrators", &grp);
+ if (rc == SMB_LGRP_SUCCESS) {
+ if (smb_lgrp_is_member(&grp, user_info->user_sid))
user_info->flags |= SMB_UINFO_FLAG_LADMIN;
+ smb_lgrp_free(&grp);
}
}
@@ -447,6 +341,7 @@ mlsvc_join(char *server, char *domain, char *plain_user, char *plain_text)
DWORD status;
mlsvc_handle_t netr_handle;
char machine_passwd[MLSVC_MACHINE_ACCT_PASSWD_MAX];
+ char fqdn[MAXHOSTNAMELEN];
machine_passwd[0] = '\0';
@@ -472,14 +367,13 @@ mlsvc_join(char *server, char *domain, char *plain_user, char *plain_text)
erc = mlsvc_logon(server, domain, plain_user);
if (erc == AUTH_USER_GRANT) {
- int isenabled;
-
- smb_config_rdlock();
- isenabled = smb_config_getyorn(SMB_CI_ADS_ENABLE);
- smb_config_unlock();
- if (isenabled) {
- if (ads_join(plain_user, plain_text, machine_passwd,
- sizeof (machine_passwd)) == ADJOIN_SUCCESS)
+ if (mlsvc_ntjoin_support == B_FALSE) {
+ if (smb_resolve_fqdn(domain, fqdn, MAXHOSTNAMELEN) != 1)
+ return (NT_STATUS_INVALID_PARAMETER);
+
+ if (ads_join(fqdn, plain_user, plain_text,
+ machine_passwd, sizeof (machine_passwd))
+ == ADJOIN_SUCCESS)
status = NT_STATUS_SUCCESS;
else
status = NT_STATUS_UNSUCCESSFUL;
@@ -500,7 +394,9 @@ mlsvc_join(char *server, char *domain, char *plain_user, char *plain_text)
}
if (status == NT_STATUS_SUCCESS) {
- if (smb_set_machine_pwd(machine_passwd) != 0)
+ erc = smb_config_setstr(SMB_CI_MACHINE_PASSWD,
+ machine_passwd);
+ if (erc != SMBD_SMF_OK)
return (NT_STATUS_UNSUCCESSFUL);
/*
@@ -509,7 +405,7 @@ mlsvc_join(char *server, char *domain, char *plain_user, char *plain_text)
* that we use the SAMLOGON version of the NETLOGON
* PDC location protocol.
*/
- smb_set_domain_member(1);
+ (void) smb_config_setbool(SMB_CI_DOMAIN_MEMB, B_TRUE);
if (netr_open(server, domain, &netr_handle) == 0) {
status = netlogon_auth(server, &netr_handle,
@@ -525,197 +421,3 @@ mlsvc_join(char *server, char *domain, char *plain_user, char *plain_text)
return (status);
}
-
-/*ARGSUSED*/
-void
-nt_group_ht_lock(krwmode_t locktype)
-{
-}
-
-void
-nt_group_ht_unlock(void)
-{
-}
-
-int
-nt_group_num_groups(void)
-{
- return (0);
-}
-
-/*ARGSUSED*/
-uint32_t
-nt_group_add(char *gname, char *comment)
-{
- return (NT_STATUS_NOT_SUPPORTED);
-}
-
-/*ARGSUSED*/
-uint32_t
-nt_group_modify(char *gname, char *new_gname, char *comment)
-{
- return (NT_STATUS_NOT_SUPPORTED);
-}
-
-/*ARGSUSED*/
-uint32_t
-nt_group_delete(char *gname)
-{
- return (NT_STATUS_NOT_SUPPORTED);
-}
-
-/*ARGSUSED*/
-nt_group_t *
-nt_group_getinfo(char *gname, krwmode_t locktype)
-{
- return (NULL);
-}
-
-/*ARGSUSED*/
-void
-nt_group_putinfo(nt_group_t *grp)
-{
-}
-
-/*ARGSUSED*/
-int
-nt_group_getpriv(nt_group_t *grp, uint32_t priv_id)
-{
- return (SE_PRIVILEGE_DISABLED);
-}
-
-/*ARGSUSED*/
-uint32_t
-nt_group_setpriv(nt_group_t *grp, uint32_t priv_id, uint32_t new_attr)
-{
- return (NT_STATUS_NOT_SUPPORTED);
-}
-
-/*ARGSUSED*/
-int
-nt_group_is_member(nt_group_t *grp, nt_sid_t *sid)
-{
- return (0);
-}
-
-/*ARGSUSED*/
-uint32_t
-nt_group_add_member(nt_group_t *grp, nt_sid_t *msid, uint16_t sid_name_use,
- char *account)
-{
- return (NT_STATUS_NOT_SUPPORTED);
-}
-
-/*ARGSUSED*/
-uint32_t
-nt_group_del_member(nt_group_t *grp, void *key, int keytype)
-{
- return (NT_STATUS_NOT_SUPPORTED);
-}
-
-/*ARGSUSED*/
-int
-nt_group_num_members(nt_group_t *grp)
-{
- return (0);
-}
-
-nt_group_iterator_t *
-nt_group_open_iterator(void)
-{
- return (NULL);
-}
-
-/*ARGSUSED*/
-void
-nt_group_close_iterator(nt_group_iterator_t *gi)
-{
-}
-
-/*ARGSUSED*/
-nt_group_t *
-nt_group_iterate(nt_group_iterator_t *gi)
-{
- return (NULL);
-}
-
-int
-nt_group_cache_size(void)
-{
- return (0);
-}
-
-uint32_t
-sam_init(void)
-{
- return (NT_STATUS_SUCCESS);
-}
-
-/*ARGSUSED*/
-uint32_t
-nt_group_add_member_byname(char *gname, char *account)
-{
- return (NT_STATUS_NOT_SUPPORTED);
-}
-
-/*ARGSUSED*/
-uint32_t
-nt_group_del_member_byname(nt_group_t *grp, char *member_name)
-{
- return (NT_STATUS_NOT_SUPPORTED);
-}
-
-/*ARGSUSED*/
-void
-nt_group_add_groupprivs(nt_group_t *grp, smb_privset_t *priv)
-{
-}
-
-/*ARGSUSED*/
-uint32_t
-nt_groups_member_privs(nt_sid_t *sid, smb_privset_t *priv)
-{
- return (NT_STATUS_SUCCESS);
-}
-
-/*ARGSUSED*/
-int
-nt_groups_member_ngroups(nt_sid_t *sid)
-{
- return (0);
-}
-
-/*ARGSUSED*/
-uint32_t
-nt_groups_member_groups(nt_sid_t *sid, smb_id_t *grps, int ngrps)
-{
- return (NT_STATUS_SUCCESS);
-}
-
-/*ARGSUSED*/
-nt_group_t *
-nt_groups_lookup_rid(uint32_t rid)
-{
- return (NULL);
-}
-
-/*ARGSUSED*/
-int
-nt_groups_count(int cnt_opt)
-{
- return (0);
-}
-
-/*ARGSUSED*/
-int
-nt_group_member_list(int offset, nt_group_t *grp,
- ntgrp_member_list_t *rmembers)
-{
- return (0);
-}
-
-/*ARGSUSED*/
-void
-nt_group_list(int offset, char *pattern, ntgrp_list_t *list)
-{
-}
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_winreg.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_winreg.c
index 9dd5696526..9d017b57e1 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_winreg.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_winreg.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -45,11 +45,12 @@
#include <smbsrv/ndl/winreg.ndl>
/*
- * List of mlsvc handle (local handle management) keys.
+ * Local handle management keys.
*/
-#define WINREG_HKLM "WinregOpenHKLM"
-#define WINREG_HKU "WinregOpenUser"
-#define WINREG_KEY "WinregOpenKey"
+static int winreg_hk;
+static int winreg_hklm;
+static int winreg_hkuser;
+static int winreg_hkkey;
/*
* List of supported registry keys (case-insensitive).
@@ -62,29 +63,41 @@ static char *winreg_keys[] = {
static char *winreg_lookup_value(const char *);
+static int winreg_s_OpenHK(void *, struct mlrpc_xaction *);
static int winreg_s_OpenHKLM(void *, struct mlrpc_xaction *);
static int winreg_s_OpenHKUsers(void *, struct mlrpc_xaction *);
static int winreg_s_Close(void *, struct mlrpc_xaction *);
static int winreg_s_CreateKey(void *, struct mlrpc_xaction *);
static int winreg_s_DeleteKey(void *, struct mlrpc_xaction *);
static int winreg_s_DeleteValue(void *, struct mlrpc_xaction *);
+static int winreg_s_FlushKey(void *, struct mlrpc_xaction *);
+static int winreg_s_GetKeySec(void *, struct mlrpc_xaction *);
+static int winreg_s_NotifyChange(void *, struct mlrpc_xaction *);
static int winreg_s_OpenKey(void *, struct mlrpc_xaction *);
static int winreg_s_QueryKey(void *, struct mlrpc_xaction *);
static int winreg_s_QueryValue(void *, struct mlrpc_xaction *);
+static int winreg_s_SetKeySec(void *, struct mlrpc_xaction *);
static int winreg_s_CreateValue(void *, struct mlrpc_xaction *);
static int winreg_s_Shutdown(void *, struct mlrpc_xaction *);
static int winreg_s_GetVersion(void *, struct mlrpc_xaction *);
static mlrpc_stub_table_t winreg_stub_table[] = {
+ { winreg_s_OpenHK, WINREG_OPNUM_OpenHKCR },
+ { winreg_s_OpenHK, WINREG_OPNUM_OpenHKCU },
{ winreg_s_OpenHKLM, WINREG_OPNUM_OpenHKLM },
+ { winreg_s_OpenHK, WINREG_OPNUM_OpenHKPD },
{ winreg_s_OpenHKUsers, WINREG_OPNUM_OpenHKUsers },
{ winreg_s_Close, WINREG_OPNUM_Close },
{ winreg_s_CreateKey, WINREG_OPNUM_CreateKey },
{ winreg_s_DeleteKey, WINREG_OPNUM_DeleteKey },
{ winreg_s_DeleteValue, WINREG_OPNUM_DeleteValue },
+ { winreg_s_FlushKey, WINREG_OPNUM_FlushKey },
+ { winreg_s_GetKeySec, WINREG_OPNUM_GetKeySec },
+ { winreg_s_NotifyChange, WINREG_OPNUM_NotifyChange },
{ winreg_s_OpenKey, WINREG_OPNUM_OpenKey },
{ winreg_s_QueryKey, WINREG_OPNUM_QueryKey },
{ winreg_s_QueryValue, WINREG_OPNUM_QueryValue },
+ { winreg_s_SetKeySec, WINREG_OPNUM_SetKeySec },
{ winreg_s_CreateValue, WINREG_OPNUM_CreateValue },
{ winreg_s_Shutdown, WINREG_OPNUM_Shutdown },
{ winreg_s_GetVersion, WINREG_OPNUM_GetVersion },
@@ -131,28 +144,48 @@ winreg_initialize(void)
}
/*
+ * winreg_s_OpenHK
+ *
+ * Stub.
+ */
+static int
+winreg_s_OpenHK(void *arg, struct mlrpc_xaction *mxa)
+{
+ struct winreg_OpenHKCR *param = arg;
+ ndr_hdid_t *id;
+
+ if ((id = ndr_hdalloc(mxa, &winreg_hk)) == NULL) {
+ bzero(&param->handle, sizeof (winreg_handle_t));
+ param->status = ERROR_ACCESS_DENIED;
+ } else {
+ bcopy(id, &param->handle, sizeof (winreg_handle_t));
+ param->status = ERROR_SUCCESS;
+ }
+
+ return (MLRPC_DRC_OK);
+}
+
+/*
* winreg_s_OpenHKLM
*
- * This is a request to open the HKLM and get a handle. The client
- * should treat the handle as an opaque object.
+ * This is a request to open the HKLM and get a handle.
+ * The client should treat the handle as an opaque object.
*
* Status:
* ERROR_SUCCESS Valid handle returned.
* ERROR_ACCESS_DENIED Unable to allocate a handle.
*/
-/*ARGSUSED*/
static int
winreg_s_OpenHKLM(void *arg, struct mlrpc_xaction *mxa)
{
- struct msreg_OpenHKLM *param = arg;
- ms_handle_t *handle;
+ struct winreg_OpenHKLM *param = arg;
+ ndr_hdid_t *id;
- handle = mlsvc_get_handle(MLSVC_IFSPEC_WINREG, WINREG_HKLM, 0);
- if (handle == NULL) {
- bzero(&param->handle, sizeof (msreg_handle_t));
+ if ((id = ndr_hdalloc(mxa, &winreg_hklm)) == NULL) {
+ bzero(&param->handle, sizeof (winreg_handle_t));
param->status = ERROR_ACCESS_DENIED;
} else {
- bcopy(handle, &param->handle, sizeof (msreg_handle_t));
+ bcopy(id, &param->handle, sizeof (winreg_handle_t));
param->status = ERROR_SUCCESS;
}
@@ -167,19 +200,17 @@ winreg_s_OpenHKLM(void *arg, struct mlrpc_xaction *mxa)
* to support subsequent requests, but we may support enough now. It
* seems okay with regedt32.
*/
-/*ARGSUSED*/
static int
winreg_s_OpenHKUsers(void *arg, struct mlrpc_xaction *mxa)
{
- struct msreg_OpenHKUsers *param = arg;
- ms_handle_t *handle;
+ struct winreg_OpenHKUsers *param = arg;
+ ndr_hdid_t *id;
- handle = mlsvc_get_handle(MLSVC_IFSPEC_WINREG, WINREG_HKU, 0);
- if (handle == NULL) {
- bzero(&param->handle, sizeof (msreg_handle_t));
+ if ((id = ndr_hdalloc(mxa, &winreg_hkuser)) == NULL) {
+ bzero(&param->handle, sizeof (winreg_handle_t));
param->status = ERROR_ACCESS_DENIED;
} else {
- bcopy(handle, &param->handle, sizeof (msreg_handle_t));
+ bcopy(id, &param->handle, sizeof (winreg_handle_t));
param->status = ERROR_SUCCESS;
}
@@ -194,14 +225,15 @@ winreg_s_OpenHKUsers(void *arg, struct mlrpc_xaction *mxa)
* and return MLRPC_DRC_OK. Setting the handle to zero appears to be
* standard behaviour.
*/
-/*ARGSUSED*/
static int
winreg_s_Close(void *arg, struct mlrpc_xaction *mxa)
{
- struct msreg_Close *param = arg;
+ struct winreg_Close *param = arg;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
- (void) mlsvc_put_handle((ms_handle_t *)&param->handle);
- bzero(&param->result_handle, sizeof (msreg_handle_t));
+ ndr_hdfree(mxa, id);
+
+ bzero(&param->result_handle, sizeof (winreg_handle_t));
param->status = ERROR_SUCCESS;
return (MLRPC_DRC_OK);
}
@@ -213,7 +245,7 @@ winreg_s_Close(void *arg, struct mlrpc_xaction *mxa)
static int
winreg_s_CreateKey(void *arg, struct mlrpc_xaction *mxa)
{
- struct msreg_CreateKey *param = arg;
+ struct winreg_CreateKey *param = arg;
param->status = ERROR_ACCESS_DENIED;
return (MLRPC_DRC_OK);
@@ -226,7 +258,7 @@ winreg_s_CreateKey(void *arg, struct mlrpc_xaction *mxa)
static int
winreg_s_DeleteKey(void *arg, struct mlrpc_xaction *mxa)
{
- struct msreg_DeleteKey *param = arg;
+ struct winreg_DeleteKey *param = arg;
param->status = ERROR_ACCESS_DENIED;
return (MLRPC_DRC_OK);
@@ -239,13 +271,53 @@ winreg_s_DeleteKey(void *arg, struct mlrpc_xaction *mxa)
static int
winreg_s_DeleteValue(void *arg, struct mlrpc_xaction *mxa)
{
- struct msreg_DeleteValue *param = arg;
+ struct winreg_DeleteValue *param = arg;
param->status = ERROR_ACCESS_DENIED;
return (MLRPC_DRC_OK);
}
/*
+ * winreg_s_FlushKey
+ */
+/*ARGSUSED*/
+static int
+winreg_s_FlushKey(void *arg, struct mlrpc_xaction *mxa)
+{
+ struct winreg_FlushKey *param = arg;
+
+ param->status = ERROR_SUCCESS;
+ return (MLRPC_DRC_OK);
+}
+
+/*
+ * winreg_s_GetKeySec
+ */
+/*ARGSUSED*/
+static int
+winreg_s_GetKeySec(void *arg, struct mlrpc_xaction *mxa)
+{
+ struct winreg_GetKeySec *param = arg;
+
+ bzero(param, sizeof (struct winreg_GetKeySec));
+ param->status = ERROR_SUCCESS;
+ return (MLRPC_DRC_OK);
+}
+
+/*
+ * winreg_s_NotifyChange
+ */
+/*ARGSUSED*/
+static int
+winreg_s_NotifyChange(void *arg, struct mlrpc_xaction *mxa)
+{
+ struct winreg_NotifyChange *param = arg;
+
+ param->status = ERROR_SUCCESS;
+ return (MLRPC_DRC_OK);
+}
+
+/*
* winreg_s_OpenKey
*
* This is a request to open a windows registry key. The list
@@ -256,33 +328,29 @@ winreg_s_DeleteValue(void *arg, struct mlrpc_xaction *mxa)
* ERROR_SUCCESS Valid handle returned.
* ERROR_FILE_NOT_FOUND No key or unable to allocate a handle.
*/
-/*ARGSUSED*/
static int
winreg_s_OpenKey(void *arg, struct mlrpc_xaction *mxa)
{
- struct msreg_OpenKey *param = arg;
- ms_handle_t *handle;
+ struct winreg_OpenKey *param = arg;
char *key = (char *)param->name.str;
+ ndr_hdid_t *id = NULL;
int i;
for (i = 0; i < sizeof (winreg_keys)/sizeof (winreg_keys[0]); ++i) {
if (strcasecmp(key, winreg_keys[i]) == 0) {
- handle = mlsvc_get_handle(MLSVC_IFSPEC_WINREG,
- WINREG_KEY, 0);
-
- if (handle == NULL)
- break;
-
- bcopy(handle, &param->result_handle,
- sizeof (msreg_handle_t));
-
- param->status = ERROR_SUCCESS;
- return (MLRPC_DRC_OK);
+ id = ndr_hdalloc(mxa, &winreg_hkkey);
+ break;
}
}
- bzero(&param->result_handle, sizeof (msreg_handle_t));
- param->status = ERROR_FILE_NOT_FOUND;
+ if (id == NULL) {
+ bzero(&param->result_handle, sizeof (winreg_handle_t));
+ param->status = ERROR_FILE_NOT_FOUND;
+ } else {
+ bcopy(id, &param->result_handle, sizeof (winreg_handle_t));
+ param->status = ERROR_SUCCESS;
+ }
+
return (MLRPC_DRC_OK);
}
@@ -294,9 +362,9 @@ static int
winreg_s_QueryKey(void *arg, struct mlrpc_xaction *mxa)
{
static char nullstr[2] = { 0, 0 };
- struct msreg_QueryKey *param = arg;
+ struct winreg_QueryKey *param = arg;
- bzero(param, sizeof (struct msreg_QueryKey));
+ bzero(param, sizeof (struct winreg_QueryKey));
param->name.length = 2;
param->name.allosize = 0;
@@ -311,15 +379,15 @@ winreg_s_QueryKey(void *arg, struct mlrpc_xaction *mxa)
* This is a request to get the value associated with a specified name.
*
* Returns:
- * ERROR_SUCCESS Value returned.
+ * ERROR_SUCCESS Value returned.
* ERROR_FILE_NOT_FOUND PrimaryModule is not supported.
* ERROR_CANTREAD No such name or memory problem.
*/
static int
winreg_s_QueryValue(void *arg, struct mlrpc_xaction *mxa)
{
- struct msreg_QueryValue *param = arg;
- struct msreg_value *pv;
+ struct winreg_QueryValue *param = arg;
+ struct winreg_value *pv;
char *name;
char *value;
DWORD slen;
@@ -338,9 +406,9 @@ winreg_s_QueryValue(void *arg, struct mlrpc_xaction *mxa)
}
slen = mts_wcequiv_strlen(value) + sizeof (mts_wchar_t);
- msize = sizeof (struct msreg_value) + slen;
+ msize = sizeof (struct winreg_value) + slen;
- param->value = (struct msreg_value *)MLRPC_HEAP_MALLOC(mxa, msize);
+ param->value = (struct winreg_value *)MLRPC_HEAP_MALLOC(mxa, msize);
param->type = MLRPC_HEAP_NEW(mxa, DWORD);
param->value_size = MLRPC_HEAP_NEW(mxa, DWORD);
param->value_size_total = MLRPC_HEAP_NEW(mxa, DWORD);
@@ -408,13 +476,26 @@ winreg_lookup_value(const char *name)
}
/*
+ * winreg_s_SetKeySec
+ */
+/*ARGSUSED*/
+static int
+winreg_s_SetKeySec(void *arg, struct mlrpc_xaction *mxa)
+{
+ struct winreg_SetKeySec *param = arg;
+
+ param->status = ERROR_ACCESS_DENIED;
+ return (MLRPC_DRC_OK);
+}
+
+/*
* winreg_s_CreateValue
*/
/*ARGSUSED*/
static int
winreg_s_CreateValue(void *arg, struct mlrpc_xaction *mxa)
{
- struct msreg_CreateValue *param = arg;
+ struct winreg_CreateValue *param = arg;
param->status = ERROR_ACCESS_DENIED;
return (MLRPC_DRC_OK);
@@ -429,7 +510,7 @@ winreg_s_CreateValue(void *arg, struct mlrpc_xaction *mxa)
static int
winreg_s_Shutdown(void *arg, struct mlrpc_xaction *mxa)
{
- struct msreg_Shutdown *param = arg;
+ struct winreg_Shutdown *param = arg;
param->status = ERROR_ACCESS_DENIED;
return (MLRPC_DRC_OK);
@@ -446,7 +527,7 @@ winreg_s_Shutdown(void *arg, struct mlrpc_xaction *mxa)
static int
winreg_s_GetVersion(void *arg, struct mlrpc_xaction *mxa)
{
- struct msreg_GetVersion *param = arg;
+ struct winreg_GetVersion *param = arg;
param->version = 5;
param->status = ERROR_SUCCESS;
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_wkssvc.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_wkssvc.c
index b7453b171e..294acef207 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_wkssvc.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_wkssvc.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -84,7 +84,7 @@ wkssvc_s_NetWkstaGetInfo(void *arg, struct mlrpc_xaction *mxa)
struct mslm_NetWkstaGetInfo *param = arg;
mslm_NetWkstaGetInfo_rb *rb;
char hostname[MAXHOSTNAMELEN];
- char *resource_domain;
+ char resource_domain[SMB_PI_MAX_DOMAIN];
char *p;
DWORD status;
int rc;
@@ -113,16 +113,12 @@ wkssvc_s_NetWkstaGetInfo(void *arg, struct mlrpc_xaction *mxa)
}
rb->buf100.wki100_computername = (unsigned char *)p;
- smb_config_rdlock();
- resource_domain = smb_config_getstr(SMB_CI_DOMAIN_NAME);
-
+ (void) smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN);
if ((p = MLRPC_HEAP_STRSAVE(mxa, resource_domain)) == NULL) {
- smb_config_unlock();
status = ERROR_NOT_ENOUGH_MEMORY;
break;
}
- smb_config_unlock();
rb->buf100.wki100_langroup = (unsigned char *)p;
status = ERROR_SUCCESS;
break;
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c b/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c
index 1b26087fb8..c385d837b8 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -292,7 +292,6 @@ netr_gen_session_key(netr_info_t *netr_info)
DWORD *client_challenge;
DWORD *server_challenge;
int rc;
- char *machine_passwd;
DWORD le_data[2];
client_challenge = (DWORD *)(uintptr_t)&netr_info->client_challenge;
@@ -304,20 +303,15 @@ netr_gen_session_key(netr_info_t *netr_info)
* the appropriate password but it isn't working yet. So we
* always use the default one for now.
*/
- smb_config_rdlock();
- machine_passwd = smb_config_getstr(SMB_CI_MACHINE_PASSWD);
+ bzero(netr_info->password, sizeof (netr_info->password));
+ rc = smb_config_getstr(SMB_CI_MACHINE_PASSWD,
+ (char *)netr_info->password, sizeof (netr_info->password));
- if (!machine_passwd || *machine_passwd == 0) {
- smb_config_unlock();
+ if ((rc != SMBD_SMF_OK) || *netr_info->password == '\0') {
return (-1);
}
- bzero(netr_info->password, sizeof (netr_info->password));
- (void) strlcpy((char *)netr_info->password, (char *)machine_passwd,
- sizeof (netr_info->password));
-
- rc = smb_auth_ntlm_hash((char *)machine_passwd, md4hash);
- smb_config_unlock();
+ rc = smb_auth_ntlm_hash((char *)netr_info->password, md4hash);
if (rc != SMBAUTH_SUCCESS)
return (SMBAUTH_FAILURE);
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c b/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c
index 93079001e9..152d97cd85 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -38,6 +38,7 @@
#include <netdb.h>
#include <smbsrv/libsmb.h>
+#include <smbsrv/libsmbrdr.h>
#include <smbsrv/ndl/netlogon.ndl>
#include <smbsrv/mlsvc_util.h>
#include <smbsrv/mlsvc.h>
@@ -94,32 +95,18 @@ netlogon_logon(netr_client_t *clnt, smb_userinfo_t *user_info)
DWORD status;
int retries = 0;
- smb_config_rdlock();
- (void) strlcpy(resource_domain, smb_config_getstr(SMB_CI_DOMAIN_NAME),
- sizeof (resource_domain));
- smb_config_unlock();
+ (void) smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN);
- /*
- * If the SMB info cache is not valid,
- * try to locate a domain controller.
- */
- if ((di = smb_getdomaininfo(0)) == NULL) {
- (void) mlsvc_locate_domain_controller(resource_domain);
-
- if ((di = smb_getdomaininfo(0)) == NULL)
- return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
- }
+ if ((di = smb_getdomaininfo(0)) == NULL)
+ return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
if ((mlsvc_echo(di->server)) < 0) {
/*
* We had a session to the DC but it's not responding.
- * So drop the credential chain and find another DC.
+ * So drop the credential chain.
*/
netr_invalidate_chain();
- (void) mlsvc_locate_domain_controller(resource_domain);
-
- if ((di = smb_getdomaininfo(0)) == NULL)
- return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
+ return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
}
do {
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/samlib.c b/usr/src/lib/smbsrv/libmlsvc/common/samlib.c
index ef303a8b21..1e8e533721 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/samlib.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/samlib.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -50,99 +50,6 @@
#define SAM_KEYLEN 16
extern DWORD samr_set_user_info(mlsvc_handle_t *, smb_auth_info_t *);
-static int get_user_group_info(mlsvc_handle_t *, smb_userinfo_t *);
-
-/*
- * sam_lookup_user_info
- *
- * Lookup user information in the SAM database on the specified server
- * (domain controller). The LSA interface is used to obtain the user
- * RID, the domain name and the domain SID (user privileges are TBD).
- * Then the various SAM layers are opened using the domain SID and the
- * user RID to obtain the users's group membership information.
- *
- * The information is returned in the user_info structure. The caller
- * is responsible for allocating and releasing this structure. If the
- * lookup is successful, sid_name_use will be set to SidTypeUser.
- *
- * On success 0 is returned. Otherwise a -ve error code.
- */
-int
-sam_lookup_user_info(char *server, char *domain_name,
- char *account_name, smb_userinfo_t *user_info)
-{
- mlsvc_handle_t samr_handle;
- mlsvc_handle_t domain_handle;
- mlsvc_handle_t user_handle;
- struct samr_sid *sid;
- int rc;
- DWORD access_mask;
- DWORD status;
-
- if (lsa_lookup_name(server, domain_name, account_name, user_info) != 0)
- return (-1);
-
- if (user_info->sid_name_use != SidTypeUser ||
- user_info->rid == 0 || user_info->domain_sid == 0) {
- return (-1);
- }
-
- rc = samr_open(server, domain_name, account_name,
- SAM_LOOKUP_INFORMATION, &samr_handle);
- if (rc != 0)
- return (-1);
- sid = (struct samr_sid *)user_info->domain_sid;
-
- status = samr_open_domain(&samr_handle, SAM_LOOKUP_INFORMATION,
- sid, &domain_handle);
- if (status == 0) {
- access_mask = STANDARD_RIGHTS_EXECUTE | SAM_ACCESS_USER_READ;
-
- status = samr_open_user(&domain_handle, access_mask,
- user_info->rid, &user_handle);
-
- if (status == NT_STATUS_SUCCESS) {
- (void) get_user_group_info(&user_handle, user_info);
- (void) samr_close_handle(&user_handle);
- } else {
- rc = -1;
- }
-
- (void) samr_close_handle(&domain_handle);
- } else {
- rc = -1;
- }
-
- (void) samr_close_handle(&samr_handle);
- return (rc);
-}
-
-/*
- * get_user_group_info
- *
- * This is a private function to obtain the primary group and group
- * memberships for the user specified by the user_handle. This function
- * should only be called from sam_lookup_user_info.
- *
- * On success 0 is returned. Otherwise -1 is returned.
- */
-static int
-get_user_group_info(mlsvc_handle_t *user_handle, smb_userinfo_t *user_info)
-{
- union samr_user_info sui;
- int rc;
-
- rc = samr_query_user_info(user_handle, SAMR_QUERY_USER_GROUPRID, &sui);
- if (rc != 0)
- return (-1);
-
- rc = samr_query_user_groups(user_handle, user_info);
- if (rc != 0)
- return (-1);
-
- user_info->primary_group_rid = sui.info9.group_rid;
- return (0);
-}
/*
* sam_create_trust_account
@@ -157,7 +64,6 @@ get_user_group_info(mlsvc_handle_t *user_handle, smb_userinfo_t *user_info)
DWORD
sam_create_trust_account(char *server, char *domain, smb_auth_info_t *auth)
{
- smb_userinfo_t *user_info;
char account_name[MAXHOSTNAMELEN];
DWORD status;
@@ -166,19 +72,13 @@ sam_create_trust_account(char *server, char *domain, smb_auth_info_t *auth)
(void) strlcat(account_name, "$", MAXHOSTNAMELEN);
- if ((user_info = mlsvc_alloc_user_info()) == 0)
- return (NT_STATUS_NO_MEMORY);
-
/*
* The trust account value here should match
* the value that will be used when the user
* information is set on this account.
*/
status = sam_create_account(server, domain, account_name,
- auth, SAMR_AF_WORKSTATION_TRUST_ACCOUNT, user_info);
-
- mlsvc_free_user_info(user_info);
-
+ auth, SAMR_AF_WORKSTATION_TRUST_ACCOUNT);
/*
* Based on network traces, a Windows 2000 client will
@@ -209,11 +109,12 @@ sam_create_trust_account(char *server, char *domain, smb_auth_info_t *auth)
*/
DWORD
sam_create_account(char *server, char *domain_name, char *account_name,
- smb_auth_info_t *auth, DWORD account_flags, smb_userinfo_t *user_info)
+ smb_auth_info_t *auth, DWORD account_flags)
{
mlsvc_handle_t samr_handle;
mlsvc_handle_t domain_handle;
mlsvc_handle_t user_handle;
+ smb_userinfo_t *user_info;
union samr_user_info sui;
struct samr_sid *sid;
DWORD rid;
@@ -221,6 +122,9 @@ sam_create_account(char *server, char *domain_name, char *account_name,
int rc;
char *user = smbrdr_ipc_get_user();
+ if ((user_info = mlsvc_alloc_user_info()) == 0)
+ return (NT_STATUS_NO_MEMORY);
+
rc = samr_open(server, domain_name, user, SAM_CONNECT_CREATE_ACCOUNT,
&samr_handle);
@@ -228,6 +132,7 @@ sam_create_account(char *server, char *domain_name, char *account_name,
status = NT_STATUS_OPEN_FAILED;
smb_tracef("SamCreateAccount[%s\\%s]: %s",
domain_name, account_name, xlate_nt_status(status));
+ mlsvc_free_user_info(user_info);
return (status);
}
@@ -242,6 +147,7 @@ sam_create_account(char *server, char *domain_name, char *account_name,
smb_tracef("SamCreateAccount[%s\\%s]: %s",
domain_name, account_name,
xlate_nt_status(status));
+ mlsvc_free_user_info(user_info);
return (status);
}
}
@@ -254,6 +160,7 @@ sam_create_account(char *server, char *domain_name, char *account_name,
smb_tracef("SamCreateAccount[%s]: lookup failed",
account_name);
+ mlsvc_free_user_info(user_info);
return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
}
@@ -274,14 +181,7 @@ sam_create_account(char *server, char *domain_name, char *account_name,
(void) samr_get_user_pwinfo(&user_handle);
(void) samr_set_user_info(&user_handle, auth);
(void) samr_close_handle(&user_handle);
- } else if (status == NT_STATUS_USER_EXISTS) {
- mlsvc_release_user_info(user_info);
-
- rc = lsa_lookup_name(server, domain_name, account_name,
- user_info);
- if (rc == 0)
- rid = user_info->rid;
- } else {
+ } else if (status != NT_STATUS_USER_EXISTS) {
smb_tracef("SamCreateAccount[%s]: %s",
account_name, xlate_nt_status(status));
}
@@ -294,6 +194,7 @@ sam_create_account(char *server, char *domain_name, char *account_name,
}
(void) samr_close_handle(&samr_handle);
+ mlsvc_free_user_info(user_info);
return (status);
}
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/samr_lookup.c b/usr/src/lib/smbsrv/libmlsvc/common/samr_lookup.c
index e20b6404d7..463cd7f223 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/samr_lookup.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/samr_lookup.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -473,7 +473,7 @@ samr_set_user_unknowns(struct samr_SetUserInfo23 *info)
info->sd.length = 0;
info->sd.data = 0;
info->user_rid = 0;
- info->group_rid = MLSVC_DOMAIN_GROUP_RID_USERS;
+ info->group_rid = DOMAIN_GROUP_RID_USERS;
/*
* The trust account value used here should probably
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/samr_open.c b/usr/src/lib/smbsrv/libmlsvc/common/samr_open.c
index 233acdf84d..015165798f 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/samr_open.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/samr_open.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -318,7 +318,7 @@ samr_connect4(char *server, char *domain, char *username, DWORD access_mask,
{
struct samr_Connect4 arg;
mlrpc_heapref_t heapref;
- char *dns_name;
+ char dns_name[MAXHOSTNAMELEN];
int len;
int opnum;
DWORD status;
@@ -327,9 +327,10 @@ samr_connect4(char *server, char *domain, char *username, DWORD access_mask,
opnum = SAMR_OPNUM_Connect;
status = NT_STATUS_SUCCESS;
+ if (smb_resolve_fqdn(domain, dns_name, MAXHOSTNAMELEN) != 1)
+ return (NT_STATUS_UNSUCCESSFUL);
+
(void) mlsvc_rpc_init(&heapref);
- dns_name = mlrpc_heap_malloc(heapref.heap, MAXHOSTNAMELEN);
- (void) smb_getdomainname(dns_name, MAXHOSTNAMELEN);
if (strlen(dns_name) > 0) {
len = strlen(server) + strlen(dns_name) + 4;
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/secdb.c b/usr/src/lib/smbsrv/libmlsvc/common/secdb.c
index cc4d96456f..1c46a89504 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/secdb.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/secdb.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -338,23 +338,36 @@ static smb_privset_t *
smb_token_create_privs(smb_userinfo_t *user_info)
{
smb_privset_t *privs;
- nt_group_t *grp;
+ smb_giter_t gi;
+ smb_group_t grp;
+ int rc;
privs = smb_privset_new();
if (privs == NULL)
return (NULL);
- (void) nt_groups_member_privs(user_info->user_sid, privs);
+ if (smb_lgrp_iteropen(&gi) != SMB_LGRP_SUCCESS) {
+ smb_privset_free(privs);
+ return (NULL);
+ }
+
+ while (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS) {
+ if (smb_lgrp_is_member(&grp, user_info->user_sid)) {
+ smb_privset_merge(privs, grp.sg_privs);
+ }
+ smb_lgrp_free(&grp);
+ }
+ smb_lgrp_iterclose(&gi);
if (user_info->flags & SMB_UINFO_FLAG_ADMIN) {
- grp = nt_group_getinfo("Administrators", RWLOCK_READER);
- if (grp) {
- nt_group_add_groupprivs(grp, privs);
- nt_group_putinfo(grp);
+ rc = smb_lgrp_getbyname("Administrators", &grp);
+ if (rc == SMB_LGRP_SUCCESS) {
+ smb_privset_merge(privs, grp.sg_privs);
+ smb_lgrp_free(&grp);
}
/*
- * This privilege is required for view/edit of SACL
+ * This privilege is required to view/edit SACL
*/
smb_privset_enable(privs, SE_SECURITY_LUID);
}
@@ -513,6 +526,8 @@ smb_token_create_wingrps(smb_userinfo_t *user_info)
smb_rid_attrs_t *g_grps;
smb_sid_attrs_t *grp;
nt_sid_t *builtin_sid;
+ smb_giter_t gi;
+ smb_group_t lgrp;
uint32_t n_gg, n_lg, n_dlg, n_wg;
uint32_t i, j;
int size, count;
@@ -524,7 +539,7 @@ smb_token_create_wingrps(smb_userinfo_t *user_info)
n_dlg = user_info->n_other_grps; /* Domain Local Groups */
/* Local Groups */
- n_lg = nt_groups_member_ngroups(user_info->user_sid);
+ (void) smb_lgrp_numbymember(user_info->user_sid, (int *)&n_lg);
/* Well known Groups */
if ((user_info->flags & SMB_UINFO_FLAG_ADMIN) == SMB_UINFO_FLAG_DADMIN)
@@ -538,20 +553,18 @@ smb_token_create_wingrps(smb_userinfo_t *user_info)
count = n_gg + n_dlg + n_lg + n_wg;
size = sizeof (smb_win_grps_t) + (count * sizeof (smb_id_t));
- tkn_grps = (smb_win_grps_t *)malloc(size);
- if (tkn_grps == NULL) {
+ if ((tkn_grps = malloc(size)) == NULL)
return (NULL);
- }
bzero(tkn_grps, size);
- tkn_grps->wg_count = count;
-
/* Add global groups */
g_grps = user_info->groups;
- for (i = 0; i < n_gg; ++i) {
+ for (i = 0; i < n_gg; i++) {
grp = &tkn_grps->wg_groups[i].i_sidattr;
- grp->attrs = g_grps[i].attributes;
grp->sid = nt_sid_splice(user_info->domain_sid, g_grps[i].rid);
+ if (grp->sid == NULL)
+ break;
+ grp->attrs = g_grps[i].attributes;
}
if (n_gg == 0) {
@@ -559,34 +572,55 @@ smb_token_create_wingrps(smb_userinfo_t *user_info)
* if there's no global group should add the
* primary group.
*/
- grp = &tkn_grps->wg_groups[i++].i_sidattr;
- grp->attrs = 0x7;
+ grp = &tkn_grps->wg_groups[i].i_sidattr;
grp->sid = nt_sid_dup(user_info->pgrp_sid);
- tkn_grps->wg_count++;
+ if (grp->sid != NULL) {
+ grp->attrs = 0x7;
+ i++;
+ }
}
/* Add domain local groups */
dlg_grps = user_info->other_grps;
- for (j = 0; j < n_dlg; ++j, ++i) {
+ for (j = 0; j < n_dlg; j++, i++) {
grp = &tkn_grps->wg_groups[i].i_sidattr;
- grp->attrs = dlg_grps[j].attrs;
grp->sid = nt_sid_dup(dlg_grps[j].sid);
+ if (grp->sid == NULL)
+ break;
+ grp->attrs = dlg_grps[j].attrs;
}
- if (n_lg) {
- /* Add local groups */
- (void) nt_groups_member_groups(user_info->user_sid,
- &tkn_grps->wg_groups[i], n_lg);
- i += n_lg;
+ /* Add local groups */
+ if (n_lg && (smb_lgrp_iteropen(&gi) == SMB_LGRP_SUCCESS)) {
+ j = 0;
+ while (smb_lgrp_iterate(&gi, &lgrp) == SMB_LGRP_SUCCESS) {
+ if ((j < n_lg) &&
+ smb_lgrp_is_member(&lgrp, user_info->user_sid)) {
+ grp = &tkn_grps->wg_groups[i].i_sidattr;
+ grp->sid = nt_sid_dup(lgrp.sg_id.gs_sid);
+ if (grp->sid == NULL) {
+ smb_lgrp_free(&lgrp);
+ break;
+ }
+ grp->attrs = lgrp.sg_attr;
+ i++;
+ j++;
+ }
+ smb_lgrp_free(&lgrp);
+ }
+ smb_lgrp_iterclose(&gi);
}
/* Add well known groups */
- for (j = 0; j < n_wg; ++j, ++i) {
+ for (j = 0; j < n_wg; j++, i++) {
builtin_sid = nt_builtin_lookup_name(wk_grps[j], NULL);
+ if (builtin_sid == NULL)
+ break;
tkn_grps->wg_groups[i].i_sidattr.sid = builtin_sid;
tkn_grps->wg_groups[i].i_sidattr.attrs = 0x7;
}
+ tkn_grps->wg_count = i;
return (tkn_grps);
}
@@ -698,6 +732,7 @@ smb_logon_local(netr_client_t *clnt, smb_userinfo_t *uinfo)
&smbpw,
clnt->lm_password.lm_password_val,
clnt->lm_password.lm_password_len,
+ clnt->domain,
clnt->username);
}
@@ -708,6 +743,7 @@ smb_logon_local(netr_client_t *clnt, smb_userinfo_t *uinfo)
&smbpw,
clnt->nt_password.nt_password_val,
clnt->nt_password.nt_password_len,
+ clnt->domain,
clnt->username);
}
@@ -747,7 +783,7 @@ smb_setup_luinfo(smb_userinfo_t *lui, netr_client_t *clnt, uid_t uid)
idmap_stat stat;
smb_idmap_batch_t sib;
smb_idmap_t *umap, *gmap;
- nt_group_t *grp;
+ smb_group_t grp;
struct passwd pw;
char pwbuf[1024];
@@ -820,11 +856,10 @@ smb_setup_luinfo(smb_userinfo_t *lui, netr_client_t *clnt, uid_t uid)
if ((lui->user_sid == NULL) || (lui->pgrp_sid == NULL))
return (NT_STATUS_NO_MEMORY);
- grp = nt_group_getinfo("Administrators", RWLOCK_READER);
- if (grp) {
- if (nt_group_is_member(grp, lui->user_sid))
+ if (smb_lgrp_getbyname("Administrators", &grp) == SMB_LGRP_SUCCESS) {
+ if (smb_lgrp_is_member(&grp, lui->user_sid))
lui->flags = SMB_UINFO_FLAG_LADMIN;
- nt_group_putinfo(grp);
+ smb_lgrp_free(&grp);
}
return (NT_STATUS_SUCCESS);
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/smb_autohome.c b/usr/src/lib/smbsrv/libmlsvc/common/smb_autohome.c
index 6d0610add3..bc3f526046 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/smb_autohome.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/smb_autohome.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -224,8 +224,9 @@ void
smb_autohome_setent(void)
{
smb_autohome_info_t *si;
- char *mappath;
+ char path[MAXNAMELEN];
char filename[MAXNAMELEN];
+ int rc;
if ((si = smb_autohome_getinfo()) != 0) {
(void) fseek(si->fp, 0L, SEEK_SET);
@@ -236,12 +237,12 @@ smb_autohome_setent(void)
if ((si = &smb_ai) == 0)
return;
- smb_config_rdlock();
- if ((mappath = smb_config_get(SMB_CI_AUTOHOME_MAP)) == NULL)
- mappath = SMB_AUTOHOME_PATH;
- (void) snprintf(filename, MAXNAMELEN, "%s/%s", mappath,
+ rc = smb_config_getstr(SMB_CI_AUTOHOME_MAP, path, sizeof (path));
+ if (rc != SMBD_SMF_OK)
+ return;
+
+ (void) snprintf(filename, MAXNAMELEN, "%s/%s", path,
SMB_AUTOHOME_FILE);
- smb_config_unlock();
if ((si->fp = fopen(filename, "r")) == NULL)
return;
diff --git a/usr/src/lib/smbsrv/libsmb/Makefile.com b/usr/src/lib/smbsrv/libsmb/Makefile.com
index 3771f7d993..857605eb72 100644
--- a/usr/src/lib/smbsrv/libsmb/Makefile.com
+++ b/usr/src/lib/smbsrv/libsmb/Makefile.com
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -56,11 +56,10 @@ OBJS_COMMON = \
smb_door_encdec.o \
smb_doorclnt.o \
smb_downcalls.o \
- smb_group_door_encdec.o \
- smb_group_xdr.o \
smb_ht.o \
smb_idmap.o \
smb_info.o \
+ smb_lgrp.o \
smb_mac.o \
smb_pwdutil.o \
smb_privilege.o \
@@ -77,7 +76,7 @@ include ../../Makefile.lib
INCS += -I$(SRC)/common/smbsrv
LDLIBS += $(MACH_LDLIBS)
-LDLIBS += -lscf -lmd -lnsl -lpkcs11 -lc -lidmap
+LDLIBS += -lscf -lmd -lnsl -lpkcs11 -lc -lresolv -lidmap
CPPFLAGS += $(INCS) -D_REENTRANT
SRCS= $(OBJS_COMMON:%.o=$(SRCDIR)/%.c) \
diff --git a/usr/src/lib/smbsrv/libsmb/amd64/Makefile b/usr/src/lib/smbsrv/libsmb/amd64/Makefile
index b3c4916b0c..03c6ea5b61 100644
--- a/usr/src/lib/smbsrv/libsmb/amd64/Makefile
+++ b/usr/src/lib/smbsrv/libsmb/amd64/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
diff --git a/usr/src/lib/smbsrv/libsmb/common/libsmb.h b/usr/src/lib/smbsrv/libsmb/common/libsmb.h
index 510f68c20d..50a3c3d989 100644
--- a/usr/src/lib/smbsrv/libsmb/common/libsmb.h
+++ b/usr/src/lib/smbsrv/libsmb/common/libsmb.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,11 +34,14 @@ extern "C" {
#include <sys/types.h>
#include <arpa/inet.h>
+#include <netdb.h>
#include <stdlib.h>
#include <libscf.h>
#include <libshare.h>
+#include <sqlite/sqlite.h>
+#include <smbsrv/string.h>
#include <smbsrv/smb_idmap.h>
/*
@@ -67,7 +70,6 @@ extern "C" {
/* Max value length of all SMB properties */
#define MAX_VALUE_BUFLEN 512
-#define SMB_PI_MAX_DOMAIN_U 48
#define SMBD_FMRI_PREFIX "network/smb/server"
#define SMBD_DEFAULT_INSTANCE_FMRI "svc:/network/smb/server:default"
@@ -78,6 +80,7 @@ extern "C" {
#define SMBD_SMF_NO_MEMORY 1 /* no memory for data structures */
#define SMBD_SMF_SYSTEM_ERR 2 /* system error, use errno */
#define SMBD_SMF_NO_PERMISSION 3 /* no permission for operation */
+#define SMBD_SMF_INVALID_ARG 4
#define SCH_STATE_UNINIT 0
#define SCH_STATE_INITIALIZING 1
@@ -99,72 +102,8 @@ typedef struct smb_scfhandle {
/*
* CIFS Configuration Management
*/
-
-/* macros for the description of all config params */
-#define SMB_CD_RDR_IPCMODE "rdr_ipcmode"
-#define SMB_CD_RDR_IPCUSER "rdr_ipcuser"
-#define SMB_CD_RDR_IPCPWD "rdr_ipcpasswd"
-
-#define SMB_CD_OPLOCK_ENABLE "oplock_enable"
-#define SMB_CD_OPLOCK_TIMEOUT "oplock_timeout"
-
-#define SMB_CD_AUTOHOME_MAP "autohome_map"
-
-#define SMB_CD_DOMAIN_SID "domain_sid"
-#define SMB_CD_DOMAIN_MEMB "domain_member"
-#define SMB_CD_DOMAIN_NAME "domain_name"
-#define SMB_CD_DOMAIN_SRV "pdc"
-
-#define SMB_CD_WINS_SRV1 "wins_server_1"
-#define SMB_CD_WINS_SRV2 "wins_server_2"
-#define SMB_CD_WINS_EXCL "wins_exclude"
-
-#define SMB_CD_SRVSVC_SHRSET_ENABLE "srvsvc_sharesetinfo_enable"
-#define SMB_CD_LOGR_ENABLE "logr_enable"
-#define SMB_CD_MLRPC_KALIVE "mlrpc_keep_alive_interval"
-
-#define SMB_CD_MAX_BUFSIZE "max_bufsize"
-#define SMB_CD_MAX_WORKERS "max_workers"
-#define SMB_CD_MAX_CONNECTIONS "max_connections"
-#define SMB_CD_KEEPALIVE "keep_alive"
-#define SMB_CD_RESTRICT_ANON "restrict_anonymous"
-
-#define SMB_CD_SIGNING_ENABLE "signing_enabled"
-#define SMB_CD_SIGNING_REQD "signing_required"
-#define SMB_CD_SIGNING_CHECK "signing_check"
-
-#define SMB_CD_FLUSH_REQUIRED "flush_required"
-#define SMB_CD_SYNC_ENABLE "sync_enable"
-#define SMB_CD_DIRSYMLINK_DISABLE "dir_symlink_disable"
-#define SMB_CD_ANNONCE_QUOTA "announce_quota"
-
-#define SMB_CD_SECURITY "security"
-#define SMB_CD_NBSCOPE "netbios_scope"
-#define SMB_CD_SYS_CMNT "system_comment"
-#define SMB_CD_LM_LEVEL "lmauth_level"
-#define SMB_CD_MSDCS_DISABLE "msdcs_disable"
-
-#define SMB_CD_ADS_ENABLE "ads_enable"
-#define SMB_CD_ADS_USER "ads_user"
-#define SMB_CD_ADS_PASSWD "ads_passwd"
-#define SMB_CD_ADS_DOMAIN "ads_domain"
-#define SMB_CD_ADS_USER_CONTAINER "ads_user_container"
-#define SMB_CD_ADS_SITE "ads_site"
-#define SMB_CD_ADS_IPLOOKUP "ads_ip_lookup"
-
-#define SMB_CD_DYNDNS_ENABLE "ddns_enable"
-#define SMB_CD_DYNDNS_RETRY_COUNT "ddns_retry_cnt"
-#define SMB_CD_DYNDNS_RETRY_SEC "ddns_retry_sec"
-
-#define SMB_CD_MACHINE_PASSWD "machine_passwd"
-
-/* configuration identifier */
typedef enum {
- SMB_CI_RDR_IPCMODE = 0,
- SMB_CI_RDR_IPCUSER,
- SMB_CI_RDR_IPCPWD,
-
- SMB_CI_OPLOCK_ENABLE,
+ SMB_CI_OPLOCK_ENABLE = 0,
SMB_CI_OPLOCK_TIMEOUT,
SMB_CI_AUTOHOME_MAP,
@@ -179,7 +118,6 @@ typedef enum {
SMB_CI_WINS_EXCL,
SMB_CI_SRVSVC_SHRSET_ENABLE,
- SMB_CI_LOGR_ENABLE,
SMB_CI_MLRPC_KALIVE,
SMB_CI_MAX_BUFSIZE,
@@ -201,19 +139,10 @@ typedef enum {
SMB_CI_NBSCOPE,
SMB_CI_SYS_CMNT,
SMB_CI_LM_LEVEL,
- SMB_CI_MSDCS_DISABLE,
- SMB_CI_ADS_ENABLE,
- SMB_CI_ADS_USER,
- SMB_CI_ADS_PASSWD,
- SMB_CI_ADS_DOMAIN,
- SMB_CI_ADS_USER_CONTAINER,
SMB_CI_ADS_SITE,
- SMB_CI_ADS_IPLOOKUP,
SMB_CI_DYNDNS_ENABLE,
- SMB_CI_DYNDNS_RETRY_COUNT,
- SMB_CI_DYNDNS_RETRY_SEC,
SMB_CI_MACHINE_PASSWD,
SMB_CI_MAX
@@ -236,41 +165,20 @@ extern int smb_smf_set_opaque_property(smb_scfhandle_t *, char *,
extern int smb_smf_get_opaque_property(smb_scfhandle_t *, char *,
void *, size_t);
extern int smb_smf_create_service_pgroup(smb_scfhandle_t *, char *);
-extern int smb_smf_delete_service_pgroup(smb_scfhandle_t *, char *);
-extern int smb_smf_create_instance_pgroup(smb_scfhandle_t *, char *);
-extern int smb_smf_delete_instance_pgroup(smb_scfhandle_t *, char *);
-extern int smb_smf_delete_property(smb_scfhandle_t *, char *);
-extern int smb_smf_instance_exists(smb_scfhandle_t *, char *);
-extern int smb_smf_instance_create(smb_scfhandle_t *, char *, char *);
-extern int smb_smf_instance_delete(smb_scfhandle_t *, char *);
-extern smb_scfhandle_t *smb_smf_get_iterator(char *);
-extern int smb_smf_get_property(smb_scfhandle_t *, int, char *, char *,
- size_t);
-extern int smb_smf_set_property(smb_scfhandle_t *, int, char *, char *);
/* Configuration management functions */
-extern int smb_config_load(void);
-extern void smb_config_rdlock(void);
-extern void smb_config_wrlock(void);
-extern void smb_config_unlock(void);
-extern char *smb_config_get(smb_cfg_id_t);
-extern char *smb_config_getstr(smb_cfg_id_t);
-extern int smb_config_getyorn(smb_cfg_id_t);
-extern uint32_t smb_config_getnum(smb_cfg_id_t);
-
-/*
- * smb_config_getenv
- *
- * Retrieves the property value from SMF.
- * Caller must free the returned buffer.
- *
- */
-extern char *smb_config_getenv(smb_cfg_id_t id);
+extern int smb_config_get(smb_cfg_id_t, char *, int);
+extern char *smb_config_getname(smb_cfg_id_t);
+extern int smb_config_getstr(smb_cfg_id_t, char *, int);
+extern int smb_config_getnum(smb_cfg_id_t, int64_t *);
+extern boolean_t smb_config_getbool(smb_cfg_id_t);
extern int smb_config_set(smb_cfg_id_t, char *);
-extern int smb_config_setnum(smb_cfg_id_t, uint32_t);
+extern int smb_config_setstr(smb_cfg_id_t, char *);
+extern int smb_config_setnum(smb_cfg_id_t, int64_t);
+extern int smb_config_setbool(smb_cfg_id_t, boolean_t);
+
extern uint8_t smb_config_get_fg_flag(void);
-extern int smb_config_setenv(smb_cfg_id_t id, char *);
extern char *smb_config_get_localsid(void);
extern int smb_config_secmode_fromstr(char *secmode);
extern char *smb_config_secmode_tostr(int secmode);
@@ -283,7 +191,7 @@ extern int smb_config_refresh(void);
/* smb_door_client.c */
typedef struct smb_joininfo {
- char domain_name[SMB_PI_MAX_DOMAIN];
+ char domain_name[MAXHOSTNAMELEN];
char domain_username[BUF_LEN + 1];
char domain_passwd[BUF_LEN + 1];
uint32_t mode;
@@ -293,10 +201,8 @@ typedef struct smb_joininfo {
extern int smbd_set_param(smb_cfg_id_t, char *);
extern int smbd_get_param(smb_cfg_id_t, char *);
extern int smbd_get_security_mode(int *);
-extern int smb_set_machine_pwd(char *);
extern int smbd_netbios_reconfig(void);
extern uint32_t smb_join(smb_joininfo_t *info);
-extern int smb_ads_domain_change_notify(char *);
#define SMB_DOMAIN_NOMACHINE_SID -1
@@ -317,22 +223,15 @@ extern int smb_wins_iplist(char *list, uint32_t iplist[], int max_naddr);
* name of a controller (PDC or BDC) and it's ip address.
*/
typedef struct smb_ntdomain {
- char domain[SMB_PI_MAX_DOMAIN_U];
- char server[SMB_PI_MAX_DOMAIN_U];
+ char domain[SMB_PI_MAX_DOMAIN];
+ char server[SMB_PI_MAX_DOMAIN];
uint32_t ipaddr;
} smb_ntdomain_t;
/* SMB domain information management functions */
-extern void smb_purge_domain_info(void);
-extern int smb_is_domain_member(void);
-extern uint8_t smb_get_fg_flag(void);
-extern void smb_set_domain_member(int set);
extern smb_ntdomain_t *smb_getdomaininfo(uint32_t timeout);
extern void smb_setdomaininfo(char *domain, char *server, uint32_t ipaddr);
extern void smb_logdomaininfo(smb_ntdomain_t *di);
-extern uint32_t smb_get_security_mode(void);
-
-extern int nt_priv_presentable_num(void);
/*
* Following set of function, handle calls to SMB Kernel driver, via
@@ -373,9 +272,12 @@ extern char *trim_whitespace(char *buf);
extern void randomize(char *, unsigned);
extern void rand_hash(unsigned char *, size_t, unsigned char *, size_t);
+extern int smb_resolve_netbiosname(char *, char *, size_t);
+extern int smb_resolve_fqdn(char *, char *, size_t);
extern int smb_getdomainname(char *, size_t);
-extern int smb_getfqhostname(char *, size_t);
+extern int smb_getfqdomainname(char *, size_t);
extern int smb_gethostname(char *, size_t, int);
+extern int smb_getfqhostname(char *, size_t);
extern int smb_getnetbiosname(char *, size_t);
void smb_trace(const char *s);
@@ -493,14 +395,6 @@ typedef struct smb_auth_info {
smb_auth_data_blob_t data_blob;
} smb_auth_info_t;
-extern int smb_getdomainname(char *, size_t);
-extern int smb_getfqhostname(char *, size_t);
-extern int smb_gethostname(char *, size_t, int);
-extern int smb_getnetbiosname(char *, size_t);
-
-void smb_trace(const char *s);
-void smb_tracef(const char *fmt, ...);
-
/*
* SMB password management
*/
@@ -567,9 +461,9 @@ extern int smb_auth_set_info(char *, char *,
extern int smb_auth_gen_session_key(smb_auth_info_t *, unsigned char *);
boolean_t smb_auth_validate_lm(unsigned char *, uint32_t, smb_passwd_t *,
- unsigned char *, int, char *);
+ unsigned char *, int, char *, char *);
boolean_t smb_auth_validate_nt(unsigned char *, uint32_t, smb_passwd_t *,
- unsigned char *, int, char *);
+ unsigned char *, int, char *, char *);
/*
* SMB MAC Signing
@@ -682,97 +576,94 @@ nt_domain_t *nt_domain_lookup_sid(nt_sid_t *domain_sid);
nt_domain_t *nt_domain_lookupbytype(nt_domain_type_t type);
nt_sid_t *nt_domain_local_sid(void);
-#define SMB_GROUP_PER_LIST 5
-
-/*
- * This structure takes different args passed from the client/server routines
- * of the SMB local group door service. Extend this structure if a new type
- * client paramater needs to be passed.
- */
-typedef struct ntgrp_dr_arg {
- char *gname;
- char *desc;
- char *member;
- char *newgname;
- uint32_t privid;
- uint32_t priv_attr;
- int offset;
- char *scope;
- int type;
- int count;
- uint32_t ntstatus;
-} ntgrp_dr_arg_t;
-
-typedef struct ntgrp {
- DWORD rid; /* Rid of the group */
- char *name; /* Name of the group */
- char *desc; /* Desc of gruup */
- char *type; /* sid_name_use */
- char *sid; /* Sid */
- DWORD attr; /* Attribute */
-} ntgrp_t;
-
-typedef struct ntgrp_list {
- int cnt;
- ntgrp_t groups[SMB_GROUP_PER_LIST];
-} ntgrp_list_t;
-
-typedef char *members_list;
-typedef struct ntgrp_member_list {
- DWORD rid; /* Rid of the group in which members belong */
- int cnt; /* members */
- members_list members[SMB_GROUP_PER_LIST];
-} ntgrp_member_list_t;
-
-typedef struct ntpriv {
- DWORD id; /* Id of priv */
- char *name; /* Name of priv */
-} ntpriv_t;
-typedef ntpriv_t *privs_t;
-
-typedef struct ntpriv_list {
- int cnt; /* Number of privs */
- privs_t privs[ANY_SIZE_ARRAY]; /* privs only presentable ones */
-} ntpriv_list_t;
-
-
-/* the xdr functions */
-extern bool_t xdr_ntgrp_dr_arg_t(XDR *, ntgrp_dr_arg_t *);
-extern bool_t xdr_ntgrp_t(XDR *, ntgrp_t *);
-extern bool_t xdr_ntgrp_list_t(XDR *, ntgrp_list_t *);
-extern bool_t xdr_members_list(XDR *, members_list *);
-extern bool_t xdr_ntgrp_member_list_t(XDR *, ntgrp_member_list_t *);
-extern bool_t xdr_ntpriv_t(XDR *, ntpriv_t *);
-extern bool_t xdr_privs_t(XDR *, privs_t *);
-extern bool_t xdr_ntpriv_list_t(XDR *, ntpriv_list_t *);
-
-extern void smb_group_free_memberlist(ntgrp_member_list_t *, int);
-extern void smb_group_free_list(ntgrp_list_t *, int);
-extern void smb_group_free_privlist(ntpriv_list_t *, int);
-
-extern uint32_t smb_group_add(char *, char *);
-extern uint32_t smb_group_modify(char *, char *, char *);
-extern uint32_t smb_group_delete(char *);
-extern uint32_t smb_group_member_remove(char *, char *);
-extern uint32_t smb_group_member_add(char *, char *);
-extern uint32_t smb_group_priv_num(int *);
-extern uint32_t smb_group_priv_list(ntpriv_list_t **);
-extern uint32_t smb_group_priv_get(char *, uint32_t, uint32_t *);
-extern uint32_t smb_group_priv_set(char *, uint32_t, uint32_t);
-extern uint32_t smb_group_count(int *);
-extern uint32_t smb_group_list(int, ntgrp_list_t **, char *, int);
-extern uint32_t smb_group_member_count(char *, int *);
-extern uint32_t smb_group_member_list(char *, int, ntgrp_member_list_t **);
-
-extern char *smb_dr_encode_grp_privlist(uint32_t, ntpriv_list_t *, size_t *);
-extern ntpriv_list_t *smb_dr_decode_grp_privlist(char *, size_t);
-
-extern char *smb_dr_encode_grp_list(uint32_t, ntgrp_list_t *, size_t *);
-extern ntgrp_list_t *smb_dr_decode_grp_list(char *, size_t);
-
-extern char *smb_dr_encode_grp_memberlist(uint32_t, ntgrp_member_list_t *,
- size_t *);
-extern ntgrp_member_list_t *smb_dr_decode_grp_memberlist(char *buf, size_t len);
+typedef enum {
+ SMB_LGRP_BUILTIN = 1,
+ SMB_LGRP_LOCAL
+} smb_gdomain_t;
+
+typedef struct smb_gsid {
+ nt_sid_t *gs_sid;
+ uint16_t gs_type;
+} smb_gsid_t;
+
+typedef struct smb_giter {
+ sqlite_vm *sgi_vm;
+ sqlite *sgi_db;
+} smb_giter_t;
+
+typedef struct smb_group {
+ char *sg_name;
+ char *sg_cmnt;
+ uint32_t sg_attr;
+ uint32_t sg_rid;
+ smb_gsid_t sg_id;
+ smb_gdomain_t sg_domain;
+ smb_privset_t *sg_privs;
+ uint32_t sg_nmembers;
+ smb_gsid_t *sg_members;
+} smb_group_t;
+
+int smb_lgrp_start(void);
+void smb_lgrp_stop(void);
+int smb_lgrp_add(char *, char *);
+int smb_lgrp_rename(char *, char *);
+int smb_lgrp_delete(char *);
+int smb_lgrp_setcmnt(char *, char *);
+int smb_lgrp_getcmnt(char *, char **);
+int smb_lgrp_getpriv(char *, uint8_t, boolean_t *);
+int smb_lgrp_setpriv(char *, uint8_t, boolean_t);
+int smb_lgrp_add_member(char *, nt_sid_t *, uint16_t);
+int smb_lgrp_del_member(char *, nt_sid_t *, uint16_t);
+int smb_lgrp_getbyname(char *, smb_group_t *);
+int smb_lgrp_getbyrid(uint32_t, smb_gdomain_t, smb_group_t *);
+int smb_lgrp_numbydomain(smb_gdomain_t, int *);
+int smb_lgrp_numbymember(nt_sid_t *, int *);
+void smb_lgrp_free(smb_group_t *);
+boolean_t smb_lgrp_is_member(smb_group_t *, nt_sid_t *);
+char *smb_lgrp_strerror(int);
+int smb_lgrp_iteropen(smb_giter_t *);
+void smb_lgrp_iterclose(smb_giter_t *);
+int smb_lgrp_iterate(smb_giter_t *, smb_group_t *);
+
+int smb_lookup_sid(nt_sid_t *, char *buf, int buflen);
+int smb_lookup_name(char *, smb_gsid_t *);
+
+#define SMB_LGRP_SUCCESS 0
+#define SMB_LGRP_INVALID_ARG 1
+#define SMB_LGRP_INVALID_MEMBER 2
+#define SMB_LGRP_INVALID_NAME 3
+#define SMB_LGRP_NOT_FOUND 4
+#define SMB_LGRP_EXISTS 5
+#define SMB_LGRP_NO_SID 6
+#define SMB_LGRP_NO_LOCAL_SID 7
+#define SMB_LGRP_SID_NOTLOCAL 8
+#define SMB_LGRP_WKSID 9
+#define SMB_LGRP_NO_MEMORY 10
+#define SMB_LGRP_DB_ERROR 11
+#define SMB_LGRP_DBINIT_ERROR 12
+#define SMB_LGRP_INTERNAL_ERROR 13
+#define SMB_LGRP_MEMBER_IN_GROUP 14
+#define SMB_LGRP_MEMBER_NOT_IN_GROUP 15
+#define SMB_LGRP_NO_SUCH_PRIV 16
+#define SMB_LGRP_NO_SUCH_DOMAIN 17
+#define SMB_LGRP_PRIV_HELD 18
+#define SMB_LGRP_PRIV_NOT_HELD 19
+#define SMB_LGRP_BAD_DATA 20
+#define SMB_LGRP_NO_MORE 21
+#define SMB_LGRP_DBOPEN_FAILED 22
+#define SMB_LGRP_DBEXEC_FAILED 23
+#define SMB_LGRP_DBINIT_FAILED 24
+#define SMB_LGRP_DOMLKP_FAILED 25
+#define SMB_LGRP_DOMINS_FAILED 26
+#define SMB_LGRP_INSERT_FAILED 27
+#define SMB_LGRP_DELETE_FAILED 28
+#define SMB_LGRP_UPDATE_FAILED 29
+#define SMB_LGRP_LOOKUP_FAILED 30
+#define SMB_LGRP_NOT_SUPPORTED 31
+
+#define SMB_LGRP_NAME_CHAR_MAX 32
+#define SMB_LGRP_COMMENT_MAX 256
+#define SMB_LGRP_NAME_MAX (SMB_LGRP_NAME_CHAR_MAX * MTS_MB_CHAR_MAX + 1)
#ifdef __cplusplus
}
diff --git a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers
index 3fa172f5d6..c5ad0f8219 100644
--- a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers
+++ b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers
@@ -18,7 +18,7 @@
# CDDL HEADER END
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -108,7 +108,6 @@ SUNWprivate {
oemstounicodes;
rand_hash;
randomize;
- smb_ads_domain_change_notify;
smb_auth_DES;
smb_auth_gen_session_key;
smb_auth_ntlm_hash;
@@ -120,12 +119,10 @@ SUNWprivate {
smb_config_get_fg_flag;
smb_config_get_localsid;
smb_config_get_secmode;
- smb_config_getenv;
+ smb_config_getbool;
+ smb_config_getname;
smb_config_getnum;
smb_config_getstr;
- smb_config_getyorn;
- smb_config_load;
- smb_config_rdlock;
smb_config_refresh;
smb_config_refresh_idmap;
smb_config_secmode_fromstr;
@@ -133,26 +130,19 @@ SUNWprivate {
smb_config_set;
smb_config_set_idmap_domain;
smb_config_set_secmode;
- smb_config_setenv;
+ smb_config_setbool;
smb_config_setnum;
- smb_config_unlock;
- smb_config_wrlock;
+ smb_config_setstr;
smb_ctxbuf_init;
smb_ctxbuf_len;
smb_ctxbuf_printf;
smb_dr_decode_arg_get_token;
smb_dr_decode_common;
smb_dr_decode_finish;
- smb_dr_decode_grp_list;
- smb_dr_decode_grp_memberlist;
- smb_dr_decode_grp_privlist;
smb_dr_decode_start;
smb_dr_decode_string;
smb_dr_encode_common;
smb_dr_encode_finish;
- smb_dr_encode_grp_list;
- smb_dr_encode_grp_memberlist;
- smb_dr_encode_grp_privlist;
smb_dr_encode_res_token;
smb_dr_encode_start;
smb_dr_encode_string;
@@ -193,41 +183,47 @@ SUNWprivate {
smb_dwncall_install_callback;
smb_dwncall_share;
smb_dwncall_user_num;
- smb_get_fg_flag;
- smb_get_security_mode;
smb_getdomaininfo;
smb_getdomainname;
+ smb_getfqdomainname;
smb_getfqhostname;
smb_gethostname;
smb_getnetbiosname;
- smb_group_add;
- smb_group_count;
- smb_group_delete;
- smb_group_free_list;
- smb_group_free_memberlist;
- smb_group_free_privlist;
- smb_group_list;
- smb_group_member_add;
- smb_group_member_count;
- smb_group_member_list;
- smb_group_member_remove;
- smb_group_modify;
- smb_group_priv_get;
- smb_group_priv_list;
- smb_group_priv_num;
- smb_group_priv_set;
smb_idmap_batch_create;
smb_idmap_batch_destroy;
smb_idmap_batch_getid;
smb_idmap_batch_getmappings;
smb_idmap_batch_getsid;
+ smb_idmap_getid;
smb_idmap_getsid;
smb_idmap_restart;
smb_idmap_start;
smb_idmap_stop;
- smb_is_domain_member;
smb_join;
+ smb_lgrp_add;
+ smb_lgrp_add_member;
+ smb_lgrp_delete;
+ smb_lgrp_del_member;
+ smb_lgrp_free;
+ smb_lgrp_getbyname;
+ smb_lgrp_getbyrid;
+ smb_lgrp_getcmnt;
+ smb_lgrp_getpriv;
+ smb_lgrp_is_member;
+ smb_lgrp_iterate;
+ smb_lgrp_iterclose;
+ smb_lgrp_iteropen;
+ smb_lgrp_numbydomain;
+ smb_lgrp_numbymember;
+ smb_lgrp_rename;
+ smb_lgrp_setcmnt;
+ smb_lgrp_setpriv;
+ smb_lgrp_start;
+ smb_lgrp_stop;
+ smb_lgrp_strerror;
smb_load_kconfig;
+ smb_lookup_name;
+ smb_lookup_sid;
smb_mac_chk;
smb_mac_dec_seqnum;
smb_mac_inc_seqnum;
@@ -245,37 +241,25 @@ SUNWprivate {
smb_privset_free;
smb_privset_init;
smb_privset_log;
+ smb_privset_merge;
smb_privset_new;
smb_privset_query;
smb_privset_size;
smb_privset_validate;
- smb_purge_domain_info;
smb_trace;
smb_tracef;
- xdr_ntgrp_dr_arg_t;
- xdr_ntgrp_list_t;
- xdr_ntgrp_member_list_t;
- xdr_ntpriv_list_t;
smb_pwd_getpasswd;
smb_pwd_setcntl;
smb_pwd_setpasswd;
- smb_set_domain_member;
- smb_set_machine_pwd;
+ smb_resolve_fqdn;
+ smb_resolve_netbiosname;
smb_setdomaininfo;
- smb_smf_create_instance_pgroup;
smb_smf_create_service_pgroup;
- smb_smf_delete_instance_pgroup;
- smb_smf_delete_property;
- smb_smf_delete_service_pgroup;
smb_smf_end_transaction;
smb_smf_get_boolean_property;
smb_smf_get_integer_property;
- smb_smf_get_iterator;
smb_smf_get_opaque_property;
smb_smf_get_string_property;
- smb_smf_instance_create;
- smb_smf_instance_delete;
- smb_smf_instance_exists;
smb_smf_scf_fini;
smb_smf_scf_init;
smb_smf_set_boolean_property;
@@ -313,10 +297,6 @@ SUNWprivate {
utf8_strlwr;
utf8_strncasecmp;
utf8_strupr;
- xdr_ntgrp_dr_arg_t;
- xdr_ntgrp_list_t;
- xdr_ntgrp_member_list_t;
- xdr_ntpriv_list_t;
xdr_smb_dr_bytes_t;
xdr_smb_dr_string_t;
xdr_smb_dr_ulist_t;
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_api_door_calls.c b/usr/src/lib/smbsrv/libsmb/common/smb_api_door_calls.c
index 4a84b5d462..79a512be2d 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_api_door_calls.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_api_door_calls.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -47,20 +47,8 @@ char *smbapi_desc[] = {
"",
"",
"SmbapiUserList",
- "SmbGroupAdd",
- "SmbGroupDelete",
- "SmbGroupAddMember",
- "SmbGroupRemoveMember",
- "SmbGroupGetCount",
- "SmbGroupGetCacheSize",
- "SmbGroupModify",
- "SmbGroupPresentablePrivNum",
- "SmbGroupPresentablePriv",
- "SmbGroupGetPriv",
- "SmbGroupSetPriv",
- "SmbGroupListGroups",
- "SmbGroupListMembers",
- "SmbGroupMembersCount",
+ "SmbLookupSid",
+ "SmbLookupName",
0
};
@@ -104,535 +92,48 @@ smb_api_ulist(int offset, smb_dr_ulist_t *users)
return (rc);
}
-/* Routines for SMB Group Door Client APIs */
-uint32_t
-smb_group_add(char *gname, char *desc)
-{
- ntgrp_dr_arg_t *args;
- char *buf, *rbufp;
- size_t buflen, rbufsize;
- uint32_t rc = NT_STATUS_UNSUCCESSFUL;
- int opcode = SMB_DR_GROUP_ADD;
- int fd;
-
- if ((gname == 0) || (*gname == 0)) {
- syslog(LOG_ERR, "%s: invalid parameter(s)",
- smbapi_desc[opcode]);
- return (NT_STATUS_INVALID_PARAMETER);
- }
-
- if (smb_dr_clnt_open(&fd, SMB_DR_SVC_NAME, smbapi_desc[opcode]) == -1)
- return (NT_STATUS_INTERNAL_ERROR);
-
- /* Encode */
- if ((args = (ntgrp_dr_arg_t *)malloc(sizeof (ntgrp_dr_arg_t))) == 0) {
- syslog(LOG_ERR, "%s: cannot allocate memory",
- smbapi_desc[opcode]);
- (void) close(fd);
- return (NT_STATUS_NO_MEMORY);
- }
- bzero(args, sizeof (ntgrp_dr_arg_t));
- args->gname = gname;
- args->desc = desc;
- if ((buf = smb_dr_encode_common(opcode, args,
- xdr_ntgrp_dr_arg_t, &buflen)) == 0) {
- syslog(LOG_ERR, "%s: Encode error", smbapi_desc[opcode]);
- free(args);
- (void) close(fd);
- return (NT_STATUS_INTERNAL_ERROR);
- }
- free(args);
-
- rbufp = smb_dr_clnt_call(fd, buf, buflen, &rbufsize,
- smbapi_desc[opcode]);
-
- /* Decode Result. */
- if (rbufp) {
- if (smb_dr_decode_common(rbufp + SMB_DR_DATA_OFFSET,
- rbufsize - SMB_DR_DATA_OFFSET, xdr_uint32_t, &rc) != 0) {
- (void) close(fd);
- return (NT_STATUS_INTERNAL_ERROR);
- }
- }
-
- smb_dr_clnt_free(buf, buflen, rbufp, rbufsize);
- (void) close(fd);
- return (rc);
-}
-
-uint32_t
-smb_group_delete(char *gname)
-{
- char *buf, *rbufp;
- size_t buflen, rbufsize;
- uint32_t rc = NT_STATUS_UNSUCCESSFUL;
- int opcode = SMB_DR_GROUP_DELETE;
- int fd;
-
- if ((gname == 0) || (*gname == 0)) {
- syslog(LOG_ERR, "%s: invalid parameter(s)",
- smbapi_desc[opcode]);
- return (NT_STATUS_INVALID_PARAMETER);
- }
-
- if (smb_dr_clnt_open(&fd, SMB_DR_SVC_NAME, smbapi_desc[opcode]) == -1)
- return (NT_STATUS_INTERNAL_ERROR);
-
- /* Encode */
- if ((buf = smb_dr_encode_string(opcode, gname, &buflen)) == 0) {
- syslog(LOG_ERR, "%s: Encode error", smbapi_desc[opcode]);
- (void) close(fd);
- return (NT_STATUS_INTERNAL_ERROR);
- }
-
- rbufp = smb_dr_clnt_call(fd, buf, buflen, &rbufsize,
- smbapi_desc[opcode]);
-
- /* Decode Result. */
- if (rbufp) {
- if (smb_dr_decode_common(rbufp + SMB_DR_DATA_OFFSET,
- rbufsize - SMB_DR_DATA_OFFSET, xdr_uint32_t, &rc) != 0) {
- (void) close(fd);
- return (NT_STATUS_INTERNAL_ERROR);
- }
- }
-
- smb_dr_clnt_free(buf, buflen, rbufp, rbufsize);
- (void) close(fd);
- return (rc);
-}
-
-uint32_t
-smb_group_member_add(char *gname, char *member)
-{
- ntgrp_dr_arg_t *args;
- char *buf, *rbufp;
- size_t buflen, rbufsize;
- uint32_t rc = NT_STATUS_UNSUCCESSFUL;
- int opcode = SMB_DR_GROUP_MEMBER_ADD;
- int fd;
-
- if ((gname == 0) || (*gname == 0) ||
- (member == 0) || (*member == 0)) {
- syslog(LOG_ERR, "%s: invalid parameter(s)",
- smbapi_desc[opcode]);
- return (NT_STATUS_INVALID_PARAMETER);
- }
-
- if (smb_dr_clnt_open(&fd, SMB_DR_SVC_NAME, smbapi_desc[opcode]) == -1)
- return (NT_STATUS_INTERNAL_ERROR);
-
- /* Encode */
- if ((args = (ntgrp_dr_arg_t *)malloc(sizeof (ntgrp_dr_arg_t))) == 0) {
- syslog(LOG_ERR, "%s: cannot allocate memory",
- smbapi_desc[opcode]);
- (void) close(fd);
- return (NT_STATUS_NO_MEMORY);
- }
- bzero(args, sizeof (ntgrp_dr_arg_t));
- args->gname = gname;
- args->member = member;
- if ((buf = smb_dr_encode_common(opcode, args, xdr_ntgrp_dr_arg_t,
- &buflen)) == 0) {
- syslog(LOG_ERR, "%s: Encode error", smbapi_desc[opcode]);
- free(args);
- (void) close(fd);
- return (NT_STATUS_INTERNAL_ERROR);
- }
- free(args);
-
- rbufp = smb_dr_clnt_call(fd, buf, buflen, &rbufsize,
- smbapi_desc[opcode]);
-
- /* Decode Result. */
- if (rbufp) {
- if (smb_dr_decode_common(rbufp + SMB_DR_DATA_OFFSET,
- rbufsize - SMB_DR_DATA_OFFSET, xdr_uint32_t, &rc) != 0) {
- (void) close(fd);
- return (NT_STATUS_INTERNAL_ERROR);
- }
- }
-
- smb_dr_clnt_free(buf, buflen, rbufp, rbufsize);
- (void) close(fd);
- return (rc);
-}
-
-uint32_t
-smb_group_member_remove(char *gname, char *member)
-{
- ntgrp_dr_arg_t *args;
- char *buf, *rbufp;
- size_t buflen, rbufsize;
- uint32_t rc = NT_STATUS_UNSUCCESSFUL;
- int opcode = SMB_DR_GROUP_MEMBER_REMOVE;
- int fd;
-
- if ((gname == 0) || (*gname == 0) ||
- (member == 0) || (*member == 0)) {
- syslog(LOG_ERR, "%s: invalid parameter(s)",
- smbapi_desc[opcode]);
- return (NT_STATUS_INVALID_PARAMETER);
- }
-
- if (smb_dr_clnt_open(&fd, SMB_DR_SVC_NAME, smbapi_desc[opcode]) == -1)
- return (NT_STATUS_INTERNAL_ERROR);
-
- /* Encode */
- if ((args = (ntgrp_dr_arg_t *)malloc(sizeof (ntgrp_dr_arg_t))) == 0) {
- syslog(LOG_ERR, "%s: cannot allocate memory",
- smbapi_desc[opcode]);
- (void) close(fd);
- return (NT_STATUS_NO_MEMORY);
- }
- bzero(args, sizeof (ntgrp_dr_arg_t));
- args->gname = gname;
- args->member = member;
- if ((buf = smb_dr_encode_common(opcode, args, xdr_ntgrp_dr_arg_t,
- &buflen)) == 0) {
- syslog(LOG_ERR, "%s: Encode error", smbapi_desc[opcode]);
- free(args);
- (void) close(fd);
- return (NT_STATUS_INTERNAL_ERROR);
- }
- free(args);
-
- rbufp = smb_dr_clnt_call(fd, buf, buflen, &rbufsize,
- smbapi_desc[opcode]);
-
- /* Decode Result. */
- if (rbufp) {
- if (smb_dr_decode_common(rbufp + SMB_DR_DATA_OFFSET,
- rbufsize - SMB_DR_DATA_OFFSET, xdr_uint32_t, &rc) != 0) {
- (void) close(fd);
- return (NT_STATUS_INTERNAL_ERROR);
- }
- }
-
- smb_dr_clnt_free(buf, buflen, rbufp, rbufsize);
- (void) close(fd);
- return (rc);
-}
-
-
-uint32_t
-smb_group_count(int *cnt)
-{
- char *buf, *rbufp;
- size_t buflen, rbufsize;
- uint32_t rc = NT_STATUS_UNSUCCESSFUL;
- uint_t opcode = SMB_DR_GROUP_COUNT;
- int fd;
-
- if (cnt == 0) {
- syslog(LOG_ERR, "%s: invalid parameter(s)",
- smbapi_desc[opcode]);
- return (NT_STATUS_INVALID_PARAMETER);
- }
- *cnt = 0;
- if (smb_dr_clnt_open(&fd, SMB_DR_SVC_NAME,
- smbapi_desc[opcode]) == -1)
- return (NT_STATUS_INTERNAL_ERROR);
-
- if ((buf = smb_dr_set_opcode(opcode, &buflen)) == 0) {
- (void) close(fd);
- return (NT_STATUS_INVALID_PARAMETER);
- }
-
- rbufp = smb_dr_clnt_call(fd, buf, buflen, &rbufsize,
- smbapi_desc[opcode]);
-
- /* Decode Result */
- if (rbufp) {
- if (smb_dr_decode_common(rbufp + SMB_DR_DATA_OFFSET,
- rbufsize - SMB_DR_DATA_OFFSET, xdr_uint32_t, cnt) != 0) {
- (void) close(fd);
- return (NT_STATUS_INVALID_PARAMETER);
- }
- rc = NT_STATUS_SUCCESS;
- }
-
- smb_dr_clnt_free(buf, buflen, rbufp, rbufsize);
- (void) close(fd);
- return (rc);
-}
-
-uint32_t
-smb_group_cachesize(int *sz)
-{
- char *buf, *rbufp;
- size_t buflen, rbufsize;
- uint32_t rc = NT_STATUS_UNSUCCESSFUL;
- uint_t opcode = SMB_DR_GROUP_CACHE_SIZE;
- int fd;
-
- if (sz == 0) {
- syslog(LOG_ERR, "%s: invalid parameter(s)",
- smbapi_desc[opcode]);
- return (NT_STATUS_INVALID_PARAMETER);
- }
- *sz = 0;
-
- if (smb_dr_clnt_open(&fd, SMB_DR_SVC_NAME,
- smbapi_desc[opcode]) == -1)
- return (NT_STATUS_INTERNAL_ERROR);
-
- if ((buf = smb_dr_set_opcode(opcode, &buflen)) == 0) {
- (void) close(fd);
- return (NT_STATUS_INVALID_PARAMETER);
- }
-
- rbufp = smb_dr_clnt_call(fd, buf, buflen, &rbufsize,
- smbapi_desc[opcode]);
-
- /* Decode Result */
- if (rbufp) {
- if (smb_dr_decode_common(rbufp + SMB_DR_DATA_OFFSET,
- rbufsize - SMB_DR_DATA_OFFSET, xdr_uint32_t, sz) != 0) {
- (void) close(fd);
- return (NT_STATUS_INVALID_PARAMETER);
- }
- rc = NT_STATUS_SUCCESS;
- }
-
- smb_dr_clnt_free(buf, buflen, rbufp, rbufsize);
- (void) close(fd);
- return (rc);
-}
-
-uint32_t
-smb_group_modify(char *gname, char *newgname, char *desc)
-{
- ntgrp_dr_arg_t *args;
- char *buf, *rbufp;
- size_t buflen, rbufsize;
- uint32_t rc = NT_STATUS_UNSUCCESSFUL;
- int opcode = SMB_DR_GROUP_MODIFY;
- int fd;
-
- if ((gname == 0) || (*gname == 0) ||
- (newgname == 0) || (*newgname == 0)) {
- syslog(LOG_ERR, "%s: invalid parameter(s)",
- smbapi_desc[opcode]);
- return (NT_STATUS_INVALID_PARAMETER);
- }
-
- if (smb_dr_clnt_open(&fd, SMB_DR_SVC_NAME, smbapi_desc[opcode]) == -1)
- return (NT_STATUS_INTERNAL_ERROR);
-
- /* Encode */
- if ((args = (ntgrp_dr_arg_t *)malloc(sizeof (ntgrp_dr_arg_t))) == 0) {
- syslog(LOG_ERR, "%s: cannot allocate memory",
- smbapi_desc[opcode]);
- (void) close(fd);
- return (NT_STATUS_NO_MEMORY);
- }
- bzero(args, sizeof (ntgrp_dr_arg_t));
- args->gname = gname;
- args->desc = desc;
- args->newgname = newgname;
- if ((buf = smb_dr_encode_common(opcode, args, xdr_ntgrp_dr_arg_t,
- &buflen)) == 0) {
- syslog(LOG_ERR, "%s: Encode error", smbapi_desc[opcode]);
- free(args);
- (void) close(fd);
- return (NT_STATUS_INTERNAL_ERROR);
- }
- free(args);
-
- rbufp = smb_dr_clnt_call(fd, buf, buflen, &rbufsize,
- smbapi_desc[opcode]);
-
- /* Decode Result. */
- if (rbufp) {
- if (smb_dr_decode_common(rbufp + SMB_DR_DATA_OFFSET,
- rbufsize - SMB_DR_DATA_OFFSET, xdr_uint32_t, &rc) != 0) {
- (void) close(fd);
- return (NT_STATUS_INTERNAL_ERROR);
- }
- }
-
- smb_dr_clnt_free(buf, buflen, rbufp, rbufsize);
- (void) close(fd);
- return (rc);
-}
-
-uint32_t
-smb_group_priv_num(int *num)
+int
+smb_lookup_sid(nt_sid_t *sid, char *sidbuf, int sidbuflen)
{
char *buf, *rbufp;
size_t buflen, rbufsize;
- uint32_t rc = NT_STATUS_UNSUCCESSFUL;
- int opcode = SMB_DR_GROUP_PRIV_NUM;
+ int opcode = SMB_DR_LOOKUP_SID;
+ char strsid[NT_SID_FMTBUF_SIZE];
+ char *name = NULL;
int fd;
- if (num == 0) {
+ if ((sidbuf == NULL) || (sidbuflen == 0)) {
syslog(LOG_ERR, "%s: invalid parameter(s)",
smbapi_desc[opcode]);
return (NT_STATUS_INVALID_PARAMETER);
}
- *num = 0;
-
- if (smb_dr_clnt_open(&fd, SMB_DR_SVC_NAME,
- smbapi_desc[opcode]) == -1)
- return (NT_STATUS_INTERNAL_ERROR);
-
- if ((buf = smb_dr_set_opcode(opcode, &buflen)) == 0) {
- (void) close(fd);
- return (NT_STATUS_INVALID_PARAMETER);
- }
- rbufp = smb_dr_clnt_call(fd, buf, buflen, &rbufsize,
- smbapi_desc[opcode]);
-
- /* Decode Result */
- if (rbufp) {
- if (smb_dr_decode_common(rbufp + SMB_DR_DATA_OFFSET,
- rbufsize - SMB_DR_DATA_OFFSET, xdr_uint32_t, num) != 0) {
- (void) close(fd);
- return (NT_STATUS_INTERNAL_ERROR);
- }
- rc = NT_STATUS_SUCCESS;
- }
-
- smb_dr_clnt_free(buf, buflen, rbufp, rbufsize);
- (void) close(fd);
- return (rc);
-}
-
-uint32_t
-smb_group_priv_list(ntpriv_list_t **list)
-{
- char *buf, *rbufp;
- size_t buflen, rbufsize;
- uint32_t rc = NT_STATUS_UNSUCCESSFUL;
- int opcode = SMB_DR_GROUP_PRIV_LIST;
- int fd;
- *list = NULL;
-
- if (smb_dr_clnt_open(&fd, SMB_DR_SVC_NAME,
- smbapi_desc[opcode]) == -1)
- return (NT_STATUS_INTERNAL_ERROR);
-
- if ((buf = smb_dr_set_opcode(opcode, &buflen)) == 0) {
- (void) close(fd);
- return (NT_STATUS_INVALID_PARAMETER);
- }
-
- rbufp = smb_dr_clnt_call(fd, buf, buflen, &rbufsize,
- smbapi_desc[opcode]);
-
- /* Decode Result */
- if (rbufp) {
- if ((*list = smb_dr_decode_grp_privlist(
- rbufp + SMB_DR_DATA_OFFSET,
- rbufsize - SMB_DR_DATA_OFFSET)) == 0) {
- (void) close(fd);
- return (NT_STATUS_INTERNAL_ERROR);
- }
- rc = NT_STATUS_SUCCESS;
- }
-
- smb_dr_clnt_free(buf, buflen, rbufp, rbufsize);
- (void) close(fd);
- return (rc);
-}
-
-uint32_t
-smb_group_priv_get(char *gname, uint32_t privid, uint32_t *privval)
-{
- char *buf, *rbufp;
- size_t buflen, rbufsize;
- ntgrp_dr_arg_t *args;
- uint32_t rc = NT_STATUS_UNSUCCESSFUL;
- int opcode = SMB_DR_GROUP_PRIV_GET;
- int fd;
- uint32_t retval;
-
- *privval = SE_PRIVILEGE_DISABLED;
-
- if (smb_dr_clnt_open(&fd, SMB_DR_SVC_NAME, smbapi_desc[opcode]) == -1)
- return (NT_STATUS_INTERNAL_ERROR);
-
- /* Encode */
- if ((args = (ntgrp_dr_arg_t *)malloc(sizeof (ntgrp_dr_arg_t))) == 0) {
- syslog(LOG_ERR, "%s: cannot allocate memory",
+ if (!nt_sid_is_valid(sid)) {
+ syslog(LOG_ERR, "%s: invalid SID",
smbapi_desc[opcode]);
- (void) close(fd);
- return (NT_STATUS_NO_MEMORY);
+ return (NT_STATUS_INVALID_SID);
}
- bzero(args, sizeof (ntgrp_dr_arg_t));
- args->gname = gname;
- args->privid = privid;
- if ((buf = smb_dr_encode_common(opcode, args, xdr_ntgrp_dr_arg_t,
- &buflen)) == 0) {
- syslog(LOG_ERR, "%s: Encode error", smbapi_desc[opcode]);
- free(args);
- (void) close(fd);
- return (NT_STATUS_INTERNAL_ERROR);
- }
- free(args);
-
- rbufp = smb_dr_clnt_call(fd, buf, buflen, &rbufsize,
- smbapi_desc[opcode]);
-
- /* Decode Result. */
- if (rbufp) {
- if (smb_dr_decode_common(rbufp + SMB_DR_DATA_OFFSET,
- rbufsize - SMB_DR_DATA_OFFSET, xdr_uint32_t,
- &retval) != 0) {
- (void) close(fd);
- return (NT_STATUS_INTERNAL_ERROR);
- }
- *privval = retval;
- rc = NT_STATUS_SUCCESS;
- }
-
- smb_dr_clnt_free(buf, buflen, rbufp, rbufsize);
- (void) close(fd);
- return (rc);
-}
-
-uint32_t
-smb_group_priv_set(char *gname, uint32_t privid, uint32_t priv_attr)
-{
- char *buf, *rbufp;
- size_t buflen, rbufsize;
- ntgrp_dr_arg_t *args;
- uint32_t rc = NT_STATUS_UNSUCCESSFUL;
- int opcode = SMB_DR_GROUP_PRIV_SET;
- int fd;
if (smb_dr_clnt_open(&fd, SMB_DR_SVC_NAME, smbapi_desc[opcode]) == -1)
return (NT_STATUS_INTERNAL_ERROR);
/* Encode */
- if ((args = (ntgrp_dr_arg_t *)malloc(sizeof (ntgrp_dr_arg_t))) == 0) {
- syslog(LOG_ERR, "%s: cannot allocate memory",
- smbapi_desc[opcode]);
- (void) close(fd);
- return (NT_STATUS_NO_MEMORY);
- }
- bzero(args, sizeof (ntgrp_dr_arg_t));
- args->gname = gname;
- args->privid = privid;
- args->priv_attr = priv_attr;
- if ((buf = smb_dr_encode_common(opcode, args, xdr_ntgrp_dr_arg_t,
- &buflen)) == 0) {
+ nt_sid_format2(sid, strsid);
+ if ((buf = smb_dr_encode_string(opcode, strsid, &buflen)) == 0) {
syslog(LOG_ERR, "%s: Encode error", smbapi_desc[opcode]);
- free(args);
(void) close(fd);
return (NT_STATUS_INTERNAL_ERROR);
}
- free(args);
rbufp = smb_dr_clnt_call(fd, buf, buflen, &rbufsize,
smbapi_desc[opcode]);
/* Decode Result. */
if (rbufp) {
- if (smb_dr_decode_common(rbufp + SMB_DR_DATA_OFFSET,
- rbufsize - SMB_DR_DATA_OFFSET, xdr_uint32_t, &rc) != 0) {
+ name = smb_dr_decode_string(rbufp + SMB_DR_DATA_OFFSET,
+ rbufsize - SMB_DR_DATA_OFFSET);
+ if (name == NULL) {
+ smb_dr_clnt_free(buf, buflen, rbufp, rbufsize);
(void) close(fd);
return (NT_STATUS_INTERNAL_ERROR);
}
@@ -640,73 +141,26 @@ smb_group_priv_set(char *gname, uint32_t privid, uint32_t priv_attr)
smb_dr_clnt_free(buf, buflen, rbufp, rbufsize);
(void) close(fd);
- return (rc);
-}
-uint32_t
-smb_group_list(int offset, ntgrp_list_t **list, char *scope, int type)
-{
- char *buf, *rbufp;
- size_t buflen, rbufsize;
- ntgrp_dr_arg_t *args;
- uint32_t rc = NT_STATUS_UNSUCCESSFUL;
- int opcode = SMB_DR_GROUP_LIST;
- int fd;
- *list = NULL;
-
- if (smb_dr_clnt_open(&fd, SMB_DR_SVC_NAME, smbapi_desc[opcode]) == -1)
- return (NT_STATUS_INTERNAL_ERROR);
+ if ((name == NULL) || (*name == '\0'))
+ nt_sid_format2(sid, sidbuf);
- /* Encode */
- if ((args = (ntgrp_dr_arg_t *)malloc(sizeof (ntgrp_dr_arg_t))) == 0) {
- syslog(LOG_ERR, "%s: cannot allocate memory",
- smbapi_desc[opcode]);
- (void) close(fd);
- return (NT_STATUS_NO_MEMORY);
- }
- bzero(args, sizeof (ntgrp_dr_arg_t));
- args->offset = offset;
- args->type = type;
- args->scope = scope;
- if ((buf = smb_dr_encode_common(opcode, args, xdr_ntgrp_dr_arg_t,
- &buflen)) == 0) {
- syslog(LOG_ERR, "%s: Encode error", smbapi_desc[opcode]);
- free(args);
- (void) close(fd);
- return (NT_STATUS_INTERNAL_ERROR);
- }
- free(args);
-
- rbufp = smb_dr_clnt_call(fd, buf, buflen, &rbufsize,
- smbapi_desc[opcode]);
-
- /* Decode Result. */
- if (rbufp) {
- if ((*list = smb_dr_decode_grp_list(rbufp + SMB_DR_DATA_OFFSET,
- rbufsize - SMB_DR_DATA_OFFSET)) == 0) {
- (void) close(fd);
- return (NT_STATUS_INTERNAL_ERROR);
- }
- rc = NT_STATUS_SUCCESS;
- }
-
- smb_dr_clnt_free(buf, buflen, rbufp, rbufsize);
- (void) close(fd);
- return (rc);
+ (void) strlcpy(sidbuf, name, sidbuflen);
+ xdr_free(xdr_string, (char *)&name);
+ return (NT_STATUS_SUCCESS);
}
-uint32_t
-smb_group_member_list(char *gname, int offset, ntgrp_member_list_t **members)
+int
+smb_lookup_name(char *name, smb_gsid_t *sid)
{
char *buf, *rbufp;
size_t buflen, rbufsize;
- ntgrp_dr_arg_t *args;
- uint32_t rc = NT_STATUS_UNSUCCESSFUL;
- int opcode = SMB_DR_GROUP_MEMBER_LIST;
+ int opcode = SMB_DR_LOOKUP_NAME;
+ char *strsid = NULL;
+ char *p;
int fd;
- *members = NULL;
- if ((gname == 0) || (*gname == 0)) {
+ if ((name == NULL) || (*name == '\0')) {
syslog(LOG_ERR, "%s: invalid parameter(s)",
smbapi_desc[opcode]);
return (NT_STATUS_INVALID_PARAMETER);
@@ -716,149 +170,38 @@ smb_group_member_list(char *gname, int offset, ntgrp_member_list_t **members)
return (NT_STATUS_INTERNAL_ERROR);
/* Encode */
- if ((args = (ntgrp_dr_arg_t *)malloc(sizeof (ntgrp_dr_arg_t))) == 0) {
- syslog(LOG_ERR, "%s: cannot allocate memory for ret_mem_list",
- smbapi_desc[opcode]);
- (void) close(fd);
- return (NT_STATUS_NO_MEMORY);
- }
- bzero(args, sizeof (ntgrp_dr_arg_t));
- args->gname = gname;
- args->offset = offset;
- if ((buf = smb_dr_encode_common(opcode, args, xdr_ntgrp_dr_arg_t,
- &buflen)) == 0) {
+ if ((buf = smb_dr_encode_string(opcode, name, &buflen)) == 0) {
syslog(LOG_ERR, "%s: Encode error", smbapi_desc[opcode]);
- free(args);
(void) close(fd);
return (NT_STATUS_INTERNAL_ERROR);
}
- free(args);
rbufp = smb_dr_clnt_call(fd, buf, buflen, &rbufsize,
smbapi_desc[opcode]);
/* Decode Result. */
if (rbufp) {
- if ((*members = smb_dr_decode_grp_memberlist(
- rbufp + SMB_DR_DATA_OFFSET,
- rbufsize - SMB_DR_DATA_OFFSET)) == 0) {
+ strsid = smb_dr_decode_string(rbufp + SMB_DR_DATA_OFFSET,
+ rbufsize - SMB_DR_DATA_OFFSET);
+ if (strsid == NULL) {
+ smb_dr_clnt_free(buf, buflen, rbufp, rbufsize);
(void) close(fd);
return (NT_STATUS_INTERNAL_ERROR);
}
- rc = NT_STATUS_SUCCESS;
- }
-
- smb_dr_clnt_free(buf, buflen, rbufp, rbufsize);
- (void) close(fd);
- return (rc);
-}
-
-uint32_t
-smb_group_member_count(char *gname, int *cnt)
-{
- char *buf, *rbufp;
- size_t buflen, rbufsize;
- ntgrp_dr_arg_t *dec_args;
- uint32_t rc = NT_STATUS_UNSUCCESSFUL;
- int opcode = SMB_DR_GROUP_MEMBER_COUNT;
- int fd;
-
- if ((gname == 0) || (*gname == 0) || (cnt == 0)) {
- syslog(LOG_ERR, "%s: invalid parameter(s)",
- smbapi_desc[opcode]);
- return (NT_STATUS_INVALID_PARAMETER);
}
- if (smb_dr_clnt_open(&fd, SMB_DR_SVC_NAME, smbapi_desc[opcode]) == -1)
- return (NT_STATUS_INTERNAL_ERROR);
-
- /* Encode */
- if ((buf = smb_dr_encode_string(opcode, gname, &buflen)) == 0) {
- syslog(LOG_ERR, "%s: Encode error", smbapi_desc[opcode]);
- (void) close(fd);
- return (NT_STATUS_INTERNAL_ERROR);
- }
-
- rbufp = smb_dr_clnt_call(fd, buf, buflen, &rbufsize,
- smbapi_desc[opcode]);
-
- /* Decode Result. */
- if ((dec_args = (ntgrp_dr_arg_t *)
- malloc(sizeof (ntgrp_dr_arg_t))) == 0) {
- syslog(LOG_ERR, "%s: cannot allocate memory",
- smbapi_desc[opcode]);
- (void) close(fd);
- return (NT_STATUS_NO_MEMORY);
- }
- bzero(dec_args, sizeof (ntgrp_dr_arg_t));
- if (rbufp) {
- if (smb_dr_decode_common(rbufp + SMB_DR_DATA_OFFSET,
- rbufsize - SMB_DR_DATA_OFFSET, xdr_ntgrp_dr_arg_t, dec_args)
- != 0) {
- free(dec_args);
- (void) close(fd);
- return (dec_args->ntstatus);
- }
- }
- *cnt = dec_args->count;
- rc = dec_args->ntstatus;
smb_dr_clnt_free(buf, buflen, rbufp, rbufsize);
- free(dec_args);
(void) close(fd);
- return (rc);
-}
-/* Helper functions for local group door service to free up data structures */
-void
-smb_group_free_privlist(ntpriv_list_t *list, int deletelist)
-{
- int i;
- if (!list)
- return;
- if (list->privs != NULL) {
- for (i = 0; i < list->cnt; i++) {
- if (list->privs[i] != NULL) {
- free(list->privs[i]->name);
- free(list->privs[i]);
- }
- }
- if (deletelist)
- free(list);
+ p = strchr(strsid, '-');
+ if (p == NULL) {
+ xdr_free(xdr_string, (char *)&strsid);
+ return (NT_STATUS_NONE_MAPPED);
}
-}
-void
-smb_group_free_list(ntgrp_list_t *list, int entries_only)
-{
- int i;
-
- if (!list) {
- return;
- }
-
- for (i = 0; i < list->cnt; i++) {
- free(list->groups[i].name);
- free(list->groups[i].desc);
- free(list->groups[i].type);
- free(list->groups[i].sid);
- }
- if (!entries_only)
- free(list);
-}
-
-void
-smb_group_free_memberlist(ntgrp_member_list_t *members,
- int entries_only)
-{
- int i;
-
- if (!members) {
- return;
- }
-
- for (i = 0; i < members->cnt; i++) {
- free(members->members[i]);
- }
- if (!entries_only)
- free(members);
+ *p++ = '\0';
+ sid->gs_type = atoi(strsid);
+ sid->gs_sid = nt_sid_strtosid(p);
+ xdr_free(xdr_string, (char *)&strsid);
+ return (NT_STATUS_SUCCESS);
}
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_auth.c b/usr/src/lib/smbsrv/libsmb/common/smb_auth.c
index d8950616db..ccd33ca1af 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_auth.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_auth.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -303,7 +303,6 @@ smb_auth_ntlmv2_hash(unsigned char *ntlm_hash,
return (SMBAUTH_FAILURE);
(void) utf8_strupr(username);
- (void) utf8_strupr(ntdomain);
data_len = strlen(username) + strlen(ntdomain);
buf = (unsigned char *)malloc((data_len + 1) * sizeof (char));
@@ -397,6 +396,7 @@ smb_auth_set_info(char *username,
unsigned short blob_len;
unsigned char blob_buf[SMBAUTH_BLOB_MAXLEN];
int rc;
+ char *uppercase_dom;
auth->lmcompatibility_lvl = lmcomp_lvl;
if (lmcomp_lvl == 2) {
@@ -421,12 +421,23 @@ smb_auth_set_info(char *username,
(void) memcpy(auth->hash, ntlm_hash, SMBAUTH_HASH_SZ);
}
+ if (!domain)
+ return (-1);
+
+ if ((uppercase_dom = strdup(domain)) == NULL)
+ return (-1);
+
+ (void) utf8_strupr(uppercase_dom);
+
if (smb_auth_ntlmv2_hash(auth->hash, username,
- domain, auth->hash_v2) != SMBAUTH_SUCCESS)
+ uppercase_dom, auth->hash_v2) != SMBAUTH_SUCCESS) {
+ free(uppercase_dom);
return (-1);
+ }
/* generate data blob */
- smb_auth_gen_data_blob(&auth->data_blob, domain);
+ smb_auth_gen_data_blob(&auth->data_blob, uppercase_dom);
+ free(uppercase_dom);
blob_len = smb_auth_blob_to_string(&auth->data_blob, blob_buf);
/* generate NTLMv2 response */
@@ -538,67 +549,90 @@ smb_ntlmv2_password_ok(
unsigned char *ntlm_hash,
unsigned char *passwd,
int pwdlen,
+ char *domain,
char *username)
{
unsigned char *clnt_blob;
int clnt_blob_len;
unsigned char ntlmv2_hash[SMBAUTH_HASH_SZ];
unsigned char *ntlmv2_resp;
- boolean_t ok;
+ boolean_t ok = B_FALSE;
+ char *dest[3];
+ int i;
clnt_blob_len = pwdlen - SMBAUTH_HASH_SZ;
clnt_blob = &passwd[SMBAUTH_HASH_SZ];
+ dest[0] = domain;
+ if ((dest[1] = strdup(domain)) == NULL)
+ return (B_FALSE);
+ (void) utf8_strupr(dest[1]);
+ dest[2] = "";
/*
* 15.5.2 The NTLMv2 Password Hash, pg. 279, of the "Implementing CIFS"
*
- * * The NTLMv2 Hash is created from:
+ * The NTLMv2 Hash is created from:
* - NTLM hash
* - user's username, and
* - the name of the logon destination(i.e. the NetBIOS name of either
- * the SMB server or NT Domain against which the suer is trying to
+ * the SMB server or NT Domain against which the user is trying to
* authenticate.
*
- * (N.L.) With my experience, this is not exactly true. It's really
- * tricky how the NTLMv2 hash is generated by the Windows client when
- * logging into a standalone server using NTLMv2 challenge / response.
- * The NTLMv2 hash is actually created with the destination info=""
- * as opposed to the SMB server name mentioned in the book.
+ * Experiments show this is not exactly the case.
+ * For Windows Server 2003, the domain name needs to be included and
+ * converted to uppercase. For Vista, the domain name needs to be
+ * included also, but leave the case alone. And in some cases it needs
+ * to be empty. All three variants are tried here.
*/
- if (smb_auth_ntlmv2_hash(ntlm_hash, username, "", ntlmv2_hash) !=
- SMBAUTH_SUCCESS) {
- return (B_FALSE);
- }
ntlmv2_resp = (unsigned char *)malloc(SMBAUTH_HASH_SZ + clnt_blob_len);
- if (ntlmv2_resp == NULL)
- return (B_FALSE);
-
- if (smb_auth_v2_response(ntlmv2_hash, challenge,
- clen, clnt_blob, clnt_blob_len, ntlmv2_resp) < 0) {
- free(ntlmv2_resp);
+ if (ntlmv2_resp == NULL) {
+ free(dest[1]);
return (B_FALSE);
}
- ok = (bcmp(passwd, ntlmv2_resp, pwdlen) == 0);
+ for (i = 0; i < (sizeof (dest) / sizeof (char *)); i++) {
+ if (smb_auth_ntlmv2_hash(ntlm_hash, username, dest[i],
+ ntlmv2_hash) != SMBAUTH_SUCCESS)
+ break;
+
+ if (smb_auth_v2_response(ntlmv2_hash, challenge,
+ clen, clnt_blob, clnt_blob_len, ntlmv2_resp) < 0)
+ break;
+
+ ok = (bcmp(passwd, ntlmv2_resp, pwdlen) == 0);
+ if (ok == B_TRUE)
+ break;
+ }
+
+ free(dest[1]);
free(ntlmv2_resp);
return (ok);
}
-static int
+static boolean_t
smb_lmv2_password_ok(
unsigned char *challenge,
uint32_t clen,
unsigned char *ntlm_hash,
unsigned char *passwd,
+ char *domain,
char *username)
{
unsigned char *clnt_challenge;
unsigned char ntlmv2_hash[SMBAUTH_HASH_SZ];
unsigned char lmv2_resp[SMBAUTH_LM_RESP_SZ];
+ boolean_t ok = B_FALSE;
+ char *dest[3];
+ int i;
clnt_challenge = &passwd[SMBAUTH_HASH_SZ];
+ dest[0] = domain;
+ if ((dest[1] = strdup(domain)) == NULL)
+ return (B_FALSE);
+ (void) utf8_strupr(dest[1]);
+ dest[2] = "";
/*
* 15.5.2 The NTLMv2 Password Hash, pg. 279, of the "Implementing CIFS"
@@ -610,23 +644,31 @@ smb_lmv2_password_ok(
* the SMB server or NT Domain against which the suer is trying to
* authenticate.
*
- * (N.L.) With my experience, this is not exactly true. It's really
- * tricky how the NTLMv2 hash is generated by the Windows client when
- * logging into a standalone server using LMv2 challenge/response.
- * The NTLMv2 hash is actually created with the destination info = ""
- * as opposed to the SMB server name mentioned in the book.
+ * Experiments show this is not exactly the case.
+ * For Windows Server 2003, the domain name needs to be included and
+ * converted to uppercase. For Vista, the domain name needs to be
+ * included also, but leave the case alone. And in some cases it needs
+ * to be empty. All three variants are tried here.
*/
- if (smb_auth_ntlmv2_hash(ntlm_hash, username, "", ntlmv2_hash) !=
- SMBAUTH_SUCCESS) {
- return (B_FALSE);
- }
- if (smb_auth_v2_response(ntlmv2_hash, challenge,
- clen, clnt_challenge, SMBAUTH_V2_CLNT_CHALLENGE_SZ,
- lmv2_resp) < 0) {
- return (B_FALSE);
+
+ for (i = 0; i < (sizeof (dest) / sizeof (char *)); i++) {
+ if (smb_auth_ntlmv2_hash(ntlm_hash, username, dest[i],
+ ntlmv2_hash) != SMBAUTH_SUCCESS)
+ break;
+
+ if (smb_auth_v2_response(ntlmv2_hash, challenge,
+ clen, clnt_challenge, SMBAUTH_V2_CLNT_CHALLENGE_SZ,
+ lmv2_resp) < 0)
+ break;
+
+ ok = (bcmp(passwd, lmv2_resp, SMBAUTH_LM_RESP_SZ) == 0);
+ if (ok == B_TRUE)
+ break;
+
}
- return (bcmp(passwd, lmv2_resp, SMBAUTH_LM_RESP_SZ) == 0);
+ free(dest[1]);
+ return (ok);
}
/*
@@ -644,17 +686,17 @@ smb_auth_validate_lm(
smb_passwd_t *smbpw,
unsigned char *passwd,
int pwdlen,
+ char *domain,
char *username)
{
- int lmlevel;
boolean_t ok = B_FALSE;
+ int64_t lmlevel;
if (pwdlen != SMBAUTH_LM_RESP_SZ)
return (B_FALSE);
- smb_config_rdlock();
- lmlevel = smb_config_getnum(SMB_CI_LM_LEVEL);
- smb_config_unlock();
+ if (smb_config_getnum(SMB_CI_LM_LEVEL, &lmlevel) != SMBD_SMF_OK)
+ return (B_FALSE);
if (lmlevel <= 3) {
ok = smb_lm_password_ok(challenge, clen, smbpw->pw_lmhash,
@@ -663,7 +705,7 @@ smb_auth_validate_lm(
if (!ok)
ok = smb_lmv2_password_ok(challenge, clen, smbpw->pw_nthash,
- passwd, username);
+ passwd, domain, username);
return (ok);
}
@@ -683,21 +725,21 @@ smb_auth_validate_nt(
smb_passwd_t *smbpw,
unsigned char *passwd,
int pwdlen,
+ char *domain,
char *username)
{
- int lmlevel;
+ int64_t lmlevel;
boolean_t ok;
- smb_config_rdlock();
- lmlevel = smb_config_getnum(SMB_CI_LM_LEVEL);
- smb_config_unlock();
+ if (smb_config_getnum(SMB_CI_LM_LEVEL, &lmlevel) != SMBD_SMF_OK)
+ return (B_FALSE);
if ((lmlevel == 5) && (pwdlen <= SMBAUTH_LM_RESP_SZ))
return (B_FALSE);
if (pwdlen > SMBAUTH_LM_RESP_SZ)
ok = smb_ntlmv2_password_ok(challenge, clen,
- smbpw->pw_nthash, passwd, pwdlen, username);
+ smbpw->pw_nthash, passwd, pwdlen, domain, username);
else
ok = smb_ntlm_password_ok(challenge, clen,
smbpw->pw_nthash, passwd);
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c b/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c
index 84d95609e5..f5e6bb8a48 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -40,27 +40,20 @@
#include <ctype.h>
#include <sys/types.h>
#include <libscf.h>
+#include <assert.h>
#include <smbsrv/libsmb.h>
typedef struct smb_cfg_param {
- char *sc_pg;
+ smb_cfg_id_t sc_id;
char *sc_name;
int sc_type;
- char *sc_value;
uint32_t sc_flags;
} smb_cfg_param_t;
/*
* config parameter flags
*/
-#define SMB_CF_NOTINIT 0x00 /* Not initialized yet */
-#define SMB_CF_DEFINED 0x01 /* Defined/read from env */
-#define SMB_CF_MODIFIED 0x02 /* Has been modified */
-#define SMB_CF_SYSTEM 0x04 /* system; not part of cifs config */
-
-#define SMB_CL_NONE 0
-#define SMB_CL_READ 1
-#define SMB_CL_WRITE 2
+#define SMB_CF_PROTECTED 0x01
/* idmap SMF fmri and Property Group */
#define IDMAP_FMRI_PREFIX "system/idmap"
@@ -77,115 +70,79 @@ typedef struct smb_cfg_param {
static char *b64_data =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-static rwlock_t smb_cfg_rwlk;
-static int lock_type = SMB_CL_NONE;
-
-/*
- * IMPORTANT: any changes to the order of this table's entries
- * need to be reflected in smb_cfg_id_t enum in libsmb.h
- */
static smb_cfg_param_t smb_cfg_table[] =
{
- /* Redirector configuration, User space */
- {SMBD_PG_NAME, SMB_CD_RDR_IPCMODE, SCF_TYPE_ASTRING, 0, SMB_CF_NOTINIT},
- {SMBD_PROTECTED_PG_NAME, SMB_CD_RDR_IPCUSER,
- SCF_TYPE_ASTRING, 0, SMB_CF_NOTINIT},
- {SMBD_PROTECTED_PG_NAME, SMB_CD_RDR_IPCPWD,
- SCF_TYPE_ASTRING, 0, SMB_CF_NOTINIT},
-
/* Oplock configuration, Kernel Only */
- {SMBD_PG_NAME, SMB_CD_OPLOCK_ENABLE,
- SCF_TYPE_BOOLEAN, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_OPLOCK_TIMEOUT,
- SCF_TYPE_INTEGER, 0, SMB_CF_NOTINIT},
+ {SMB_CI_OPLOCK_ENABLE, "oplock_enable", SCF_TYPE_BOOLEAN, 0},
+ {SMB_CI_OPLOCK_TIMEOUT, "oplock_timeout", SCF_TYPE_INTEGER, 0},
/* Autohome configuration */
- {SMBD_PG_NAME, SMB_CD_AUTOHOME_MAP,
- SCF_TYPE_ASTRING, 0, SMB_CF_NOTINIT},
+ {SMB_CI_AUTOHOME_MAP, "autohome_map", SCF_TYPE_ASTRING, 0},
/* Domain/PDC configuration */
- {SMBD_PG_NAME, SMB_CD_DOMAIN_SID, SCF_TYPE_ASTRING, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_DOMAIN_MEMB, SCF_TYPE_BOOLEAN, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_DOMAIN_NAME, SCF_TYPE_ASTRING, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_DOMAIN_SRV, SCF_TYPE_ASTRING, 0, SMB_CF_NOTINIT},
+ {SMB_CI_DOMAIN_SID, "domain_sid", SCF_TYPE_ASTRING, 0},
+ {SMB_CI_DOMAIN_MEMB, "domain_member", SCF_TYPE_BOOLEAN, 0},
+ {SMB_CI_DOMAIN_NAME, "domain_name", SCF_TYPE_ASTRING, 0},
+ {SMB_CI_DOMAIN_SRV, "pdc", SCF_TYPE_ASTRING, 0},
/* WINS configuration */
- {SMBD_PG_NAME, SMB_CD_WINS_SRV1, SCF_TYPE_ASTRING, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_WINS_SRV2, SCF_TYPE_ASTRING, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_WINS_EXCL, SCF_TYPE_ASTRING, 0, SMB_CF_NOTINIT},
+ {SMB_CI_WINS_SRV1, "wins_server_1", SCF_TYPE_ASTRING, 0},
+ {SMB_CI_WINS_SRV2, "wins_server_2", SCF_TYPE_ASTRING, 0},
+ {SMB_CI_WINS_EXCL, "wins_exclude", SCF_TYPE_ASTRING, 0},
/* RPC services configuration */
- {SMBD_PG_NAME, SMB_CD_SRVSVC_SHRSET_ENABLE,
- SCF_TYPE_BOOLEAN, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_LOGR_ENABLE, SCF_TYPE_BOOLEAN, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_MLRPC_KALIVE,
- SCF_TYPE_INTEGER, 0, SMB_CF_NOTINIT},
+ {SMB_CI_SRVSVC_SHRSET_ENABLE, "srvsvc_sharesetinfo_enable",
+ SCF_TYPE_BOOLEAN, 0},
+ {SMB_CI_MLRPC_KALIVE, "mlrpc_keep_alive_interval",
+ SCF_TYPE_INTEGER, 0},
/* Kmod specific configuration */
- {SMBD_PG_NAME, SMB_CD_MAX_BUFSIZE, SCF_TYPE_INTEGER, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_MAX_WORKERS, SCF_TYPE_INTEGER, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_MAX_CONNECTIONS,
- SCF_TYPE_INTEGER, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_KEEPALIVE, SCF_TYPE_INTEGER, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_RESTRICT_ANON,
- SCF_TYPE_BOOLEAN, 0, SMB_CF_NOTINIT},
-
- {SMBD_PG_NAME, SMB_CD_SIGNING_ENABLE,
- SCF_TYPE_BOOLEAN, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_SIGNING_REQD,
- SCF_TYPE_BOOLEAN, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_SIGNING_CHECK,
- SCF_TYPE_BOOLEAN, 0, SMB_CF_NOTINIT},
+ {SMB_CI_MAX_BUFSIZE, "max_bufsize", SCF_TYPE_INTEGER, 0},
+ {SMB_CI_MAX_WORKERS, "max_workers", SCF_TYPE_INTEGER, 0},
+ {SMB_CI_MAX_CONNECTIONS, "max_connections", SCF_TYPE_INTEGER, 0},
+ {SMB_CI_KEEPALIVE, "keep_alive", SCF_TYPE_INTEGER, 0},
+ {SMB_CI_RESTRICT_ANON, "restrict_anonymous", SCF_TYPE_BOOLEAN, 0},
+
+ {SMB_CI_SIGNING_ENABLE, "signing_enabled", SCF_TYPE_BOOLEAN, 0},
+ {SMB_CI_SIGNING_REQD, "signing_required", SCF_TYPE_BOOLEAN, 0},
+ {SMB_CI_SIGNING_CHECK, "signing_check", SCF_TYPE_BOOLEAN, 0},
/* Kmod tuning configuration */
- {SMBD_PG_NAME, SMB_CD_FLUSH_REQUIRED,
- SCF_TYPE_BOOLEAN, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_SYNC_ENABLE, SCF_TYPE_BOOLEAN, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_DIRSYMLINK_DISABLE,
- SCF_TYPE_BOOLEAN, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_ANNONCE_QUOTA,
- SCF_TYPE_BOOLEAN, 0, SMB_CF_NOTINIT},
+ {SMB_CI_FLUSH_REQUIRED, "flush_required", SCF_TYPE_BOOLEAN, 0},
+ {SMB_CI_SYNC_ENABLE, "sync_enable", SCF_TYPE_BOOLEAN, 0},
+ {SMB_CI_DIRSYMLINK_DISABLE, "dir_symlink_disable", SCF_TYPE_BOOLEAN, 0},
+ {SMB_CI_ANNONCE_QUOTA, "announce_quota", SCF_TYPE_BOOLEAN, 0},
/* SMBd configuration */
- {SMBD_PG_NAME, SMB_CD_SECURITY, SCF_TYPE_ASTRING, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_NBSCOPE, SCF_TYPE_ASTRING, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_SYS_CMNT, SCF_TYPE_ASTRING, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_LM_LEVEL, SCF_TYPE_INTEGER, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_MSDCS_DISABLE,
- SCF_TYPE_BOOLEAN, 0, SMB_CF_NOTINIT},
+ {SMB_CI_SECURITY, "security", SCF_TYPE_ASTRING, 0},
+ {SMB_CI_NBSCOPE, "netbios_scope", SCF_TYPE_ASTRING, 0},
+ {SMB_CI_SYS_CMNT, "system_comment", SCF_TYPE_ASTRING, 0},
+ {SMB_CI_LM_LEVEL, "lmauth_level", SCF_TYPE_INTEGER, 0},
/* ADS Configuration */
- {SMBD_PG_NAME, SMB_CD_ADS_ENABLE, SCF_TYPE_BOOLEAN, 0, SMB_CF_NOTINIT},
- {SMBD_PROTECTED_PG_NAME, SMB_CD_ADS_USER,
- SCF_TYPE_ASTRING, 0, SMB_CF_NOTINIT},
- {SMBD_PROTECTED_PG_NAME, SMB_CD_ADS_PASSWD,
- SCF_TYPE_ASTRING, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_ADS_DOMAIN, SCF_TYPE_ASTRING, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_ADS_USER_CONTAINER,
- SCF_TYPE_ASTRING, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_ADS_SITE, SCF_TYPE_ASTRING, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_ADS_IPLOOKUP,
- SCF_TYPE_BOOLEAN, 0, SMB_CF_NOTINIT},
+ {SMB_CI_ADS_SITE, "ads_site", SCF_TYPE_ASTRING, 0},
/* Dynamic DNS */
- {SMBD_PG_NAME, SMB_CD_DYNDNS_ENABLE,
- SCF_TYPE_BOOLEAN, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_DYNDNS_RETRY_COUNT,
- SCF_TYPE_INTEGER, 0, SMB_CF_NOTINIT},
- {SMBD_PG_NAME, SMB_CD_DYNDNS_RETRY_SEC,
- SCF_TYPE_INTEGER, 0, SMB_CF_NOTINIT},
-
- {SMBD_PROTECTED_PG_NAME, SMB_CD_MACHINE_PASSWD,
- SCF_TYPE_ASTRING, 0, SMB_CF_NOTINIT}
+ {SMB_CI_DYNDNS_ENABLE, "ddns_enable", SCF_TYPE_BOOLEAN, 0},
+
+ {SMB_CI_MACHINE_PASSWD, "machine_passwd", SCF_TYPE_ASTRING,
+ SMB_CF_PROTECTED}
/* SMB_CI_MAX */
};
+static smb_cfg_param_t *smb_config_getent(smb_cfg_id_t);
+
static boolean_t smb_is_base64(unsigned char c);
static char *smb_base64_encode(char *str_to_encode);
static char *smb_base64_decode(char *encoded_str);
-static int smb_config_update(smb_cfg_param_t *cfg, char *value);
-static int smb_config_save_all();
-static int smb_config_save(char *pgname);
+
+char *
+smb_config_getname(smb_cfg_id_t id)
+{
+ smb_cfg_param_t *cfg;
+ cfg = smb_config_getent(id);
+ return (cfg->sc_name);
+}
static boolean_t
smb_is_base64(unsigned char c)
@@ -321,105 +278,6 @@ smb_base64_decode(char *encoded_str)
return (ret);
}
-/*
- * Basically commit the transaction.
- */
-static int
-smb_config_saveenv(smb_scfhandle_t *handle)
-{
- int ret = 0;
-
- ret = smb_smf_end_transaction(handle);
-
- smb_smf_scf_fini(handle);
- return (ret);
-}
-
-/*
- * smb_config_getenv
- *
- * Get the property value from SMF.
- */
-char *
-smb_config_getenv(smb_cfg_id_t id)
-{
- smb_scfhandle_t *handle;
- char *value;
-
- if ((value = malloc(MAX_VALUE_BUFLEN * sizeof (char))) == NULL)
- return (NULL);
-
- handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
- if (handle == NULL) {
- free(value);
- return (NULL);
- }
-
- (void) smb_smf_create_service_pgroup(handle, smb_cfg_table[id].sc_pg);
-
- if (smb_smf_get_property(handle, smb_cfg_table[id].sc_type,
- smb_cfg_table[id].sc_name, value,
- sizeof (char) * MAX_VALUE_BUFLEN) != 0) {
- smb_smf_scf_fini(handle);
- free(value);
- return (NULL);
- }
-
- smb_smf_scf_fini(handle);
- return (value);
-}
-
-/*
- * smb_config_getenv_dec
- *
- * For protected property, the value obtained from SMF will be decoded.
- * The decoded property value will be returned.
- *
- * This function should only be called by smb_config_load to populate
- * the SMB config cache.
- */
-static char *
-smb_config_getenv_dec(smb_cfg_id_t id)
-{
- smb_scfhandle_t *handle;
- char *value;
- char *dec;
-
- if ((value = malloc(MAX_VALUE_BUFLEN * sizeof (char))) == NULL)
- return (NULL);
-
- handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
- if (handle == NULL) {
- free(value);
- return (NULL);
- }
-
- (void) smb_smf_create_service_pgroup(handle, smb_cfg_table[id].sc_pg);
-
- if (smb_smf_get_property(handle, smb_cfg_table[id].sc_type,
- smb_cfg_table[id].sc_name, value,
- sizeof (char) * MAX_VALUE_BUFLEN) != 0) {
- smb_smf_scf_fini(handle);
- free(value);
- return (NULL);
- }
- smb_smf_scf_fini(handle);
- if (strcmp(smb_cfg_table[id].sc_pg, SMBD_PROTECTED_PG_NAME))
- return (value);
-
- if (!value)
- return (NULL);
-
- if (*value == '\0') {
- free(value);
- return (NULL);
- }
-
- dec = smb_base64_decode(value);
- free(value);
- return (dec);
-}
-
static char *
smb_config_getenv_generic(char *name, char *svc_fmri_prefix, char *svc_propgrp)
{
@@ -449,7 +307,7 @@ smb_config_getenv_generic(char *name, char *svc_fmri_prefix, char *svc_propgrp)
}
-int
+static int
smb_config_setenv_generic(char *svc_fmri_prefix, char *svc_propgrp,
char *name, char *value)
{
@@ -480,495 +338,302 @@ smb_config_setenv_generic(char *svc_fmri_prefix, char *svc_propgrp,
}
/*
- * smb_config_setenv
+ * smb_config_getstr
*
- * For protected properties, the value will be encoded using base64
- * algorithm. The encoded string will be stored in SMF.
+ * Fetch the specified string configuration item from SMF
*/
int
-smb_config_setenv(smb_cfg_id_t id, char *value)
+smb_config_getstr(smb_cfg_id_t id, char *cbuf, int bufsz)
{
- smb_scfhandle_t *handle = NULL;
- char *enc = NULL;
- int is_protected = 0;
+ smb_scfhandle_t *handle;
+ smb_cfg_param_t *cfg;
+ int rc = SMBD_SMF_OK;
- if ((id >= SMB_CI_MAX) || (id < 0)) {
- return (1);
- }
+ *cbuf = '\0';
+ cfg = smb_config_getent(id);
+ assert(cfg->sc_type == SCF_TYPE_ASTRING);
handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
- if (handle == NULL) {
- return (1);
- }
+ if (handle == NULL)
+ return (SMBD_SMF_SYSTEM_ERR);
- (void) smb_smf_create_service_pgroup(handle, smb_cfg_table[id].sc_pg);
+ if (cfg->sc_flags & SMB_CF_PROTECTED) {
+ char protbuf[SMB_ENC_LEN];
+ char *tmp;
- if (smb_smf_start_transaction(handle) != SMBD_SMF_OK) {
- smb_smf_scf_fini(handle);
- return (1);
- }
+ if ((rc = smb_smf_create_service_pgroup(handle,
+ SMBD_PROTECTED_PG_NAME)) != SMBD_SMF_OK)
+ goto error;
- if (strcmp(smb_cfg_table[id].sc_pg, SMBD_PROTECTED_PG_NAME) == 0) {
- if ((value == NULL) || (*value == '\0')) {
- (void) smb_smf_end_transaction(handle);
- smb_smf_scf_fini(handle);
- return (1);
- }
+ if ((rc = smb_smf_get_string_property(handle, cfg->sc_name,
+ protbuf, sizeof (protbuf))) != SMBD_SMF_OK)
+ goto error;
- if ((enc = smb_base64_encode(value)) == NULL) {
- (void) smb_smf_end_transaction(handle);
- smb_smf_scf_fini(handle);
- return (1);
+ if (*protbuf != '\0') {
+ tmp = smb_base64_decode(protbuf);
+ (void) strlcpy(cbuf, tmp, bufsz);
+ free(tmp);
}
-
- is_protected = 1;
- }
-
- if (smb_smf_set_property(handle, smb_cfg_table[id].sc_type,
- smb_cfg_table[id].sc_name, is_protected ? enc : value)
- != SMBD_SMF_OK) {
- if (enc)
- free(enc);
- (void) smb_smf_end_transaction(handle);
- smb_smf_scf_fini(handle);
- return (1);
- }
-
- if (enc)
- free(enc);
-
- if (smb_smf_end_transaction(handle) != SMBD_SMF_OK) {
- smb_smf_scf_fini(handle);
- return (1);
+ } else {
+ rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME);
+ if (rc == SMBD_SMF_OK)
+ rc = smb_smf_get_string_property(handle, cfg->sc_name,
+ cbuf, bufsz);
}
+error:
smb_smf_scf_fini(handle);
- return (0);
-}
-
-static void
-smb_config_setenv_trans(smb_scfhandle_t *handle, int type,
- char *name, char *value)
-{
- if (smb_smf_set_property(handle, type, name, value) != SMBD_SMF_OK) {
- syslog(LOG_ERR, "Failed to save service property %s", name);
- }
+ return (rc);
}
/*
- * smb_config_setenv_trans_protected
+ * smb_config_getnum
*
- * This function should only be called to set protected properties
- * in SMF. The argument 'value' will be encoded using base64 algorithm.
- * The encoded string will be stored in SMF.
+ * Returns the value of a numeric config param.
*/
-static void
-smb_config_setenv_trans_protected(smb_scfhandle_t *handle, char *name,
- char *value)
-{
- char *enc;
-
- if ((value == NULL) || (*value == '\0'))
- return;
-
- if ((enc = smb_base64_encode(value)) == NULL)
- return;
-
- if (smb_smf_set_string_property(handle, name, enc) != SMBD_SMF_OK) {
- syslog(LOG_ERR, "Failed to save service protected property"
- " %s", name);
- }
-
- free(enc);
-}
-
int
-smb_config_unsetenv(smb_cfg_id_t id)
+smb_config_getnum(smb_cfg_id_t id, int64_t *cint)
{
- smb_scfhandle_t *handle = NULL;
- int ret = 1;
+ smb_scfhandle_t *handle;
+ smb_cfg_param_t *cfg;
+ int rc = SMBD_SMF_OK;
- handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
- if (handle == NULL) {
- return (ret);
- }
+ *cint = 0;
+ cfg = smb_config_getent(id);
+ assert(cfg->sc_type == SCF_TYPE_INTEGER);
- (void) smb_smf_create_service_pgroup(handle, smb_cfg_table[id].sc_pg);
- if (smb_smf_start_transaction(handle) != SMBD_SMF_OK) {
- smb_smf_scf_fini(handle);
- return (ret);
- }
- ret = smb_smf_delete_property(handle, smb_cfg_table[id].sc_name);
- (void) smb_smf_end_transaction(handle);
+ handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
+ if (handle == NULL)
+ return (SMBD_SMF_SYSTEM_ERR);
+ rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME);
+ if (rc == SMBD_SMF_OK)
+ rc = smb_smf_get_integer_property(handle, cfg->sc_name, cint);
smb_smf_scf_fini(handle);
- return (ret);
-}
-static int
-smb_config_unsetenv_trans(smb_scfhandle_t *handle, char *name)
-{
- return (smb_smf_delete_property(handle, name));
+ return (rc);
}
/*
- * smb_config_load
+ * smb_config_getbool
*
- * Loads all the CIFS configuration parameters and sets up the
- * config table.
+ * Returns the value of a boolean config param.
*/
-int
-smb_config_load()
+boolean_t
+smb_config_getbool(smb_cfg_id_t id)
{
- smb_cfg_id_t id;
+ smb_scfhandle_t *handle;
smb_cfg_param_t *cfg;
- char *value;
+ int rc = SMBD_SMF_OK;
+ uint8_t vbool;
- (void) rw_rdlock(&smb_cfg_rwlk);
- for (id = 0; id < SMB_CI_MAX; id++) {
- value = smb_config_getenv_dec(id);
- cfg = &smb_cfg_table[id];
- /*
- * enval == 0 could mean two things, either the
- * config param is not defined, or it has been
- * removed. If the variable has already been defined
- * and now enval is 0, it should be removed, otherwise
- * we don't need to do anything in this case.
- */
- if ((cfg->sc_flags & SMB_CF_DEFINED) || value) {
- if (smb_config_update(cfg, value) != 0) {
- (void) rw_unlock(&smb_cfg_rwlk);
- if (value)
- free(value);
- return (1);
- }
- }
- if (value) {
- free(value);
- }
- }
+ cfg = smb_config_getent(id);
+ assert(cfg->sc_type == SCF_TYPE_BOOLEAN);
- (void) rw_unlock(&smb_cfg_rwlk);
+ handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
+ if (handle == NULL)
+ return (B_FALSE);
+
+ rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME);
+ if (rc == SMBD_SMF_OK)
+ rc = smb_smf_get_boolean_property(handle, cfg->sc_name, &vbool);
+ smb_smf_scf_fini(handle);
- return (0);
+ return ((rc == SMBD_SMF_OK) ? (vbool == 1) : B_FALSE);
}
/*
* smb_config_get
*
- * Returns value of the specified config param.
- * The return value is a string pointer to the locally
- * allocated memory if the config param is defined
- * otherwise it would be NULL.
- *
- * This function MUST be called after a smb_config_rd/wrlock
- * function. Caller MUST NOT modify the returned buffer directly.
+ * This function returns the value of the requested config
+ * iterm regardless of its type in string format. This should
+ * be used when the config item type is not known by the caller.
*/
-char *
-smb_config_get(smb_cfg_id_t id)
+int
+smb_config_get(smb_cfg_id_t id, char *cbuf, int bufsz)
{
- if (id < SMB_CI_MAX)
- return (smb_cfg_table[id].sc_value);
+ smb_cfg_param_t *cfg;
+ int64_t cint;
+ int rc;
- return (0);
-}
+ cfg = smb_config_getent(id);
+ switch (cfg->sc_type) {
+ case SCF_TYPE_ASTRING:
+ return (smb_config_getstr(id, cbuf, bufsz));
-/*
- * smb_config_getstr
- *
- * Returns value of the specified config param.
- * The returned pointer never will be NULL if the given
- * 'id' is valid. If the config param is not defined its
- * default value will be returned.
- *
- * This function MUST be called after a smb_config_rd/wrlock
- * function. Caller MUST NOT modify the returned buffer directly.
- */
-char *
-smb_config_getstr(smb_cfg_id_t id)
-{
- smb_cfg_param_t *cfg;
+ case SCF_TYPE_INTEGER:
+ rc = smb_config_getnum(id, &cint);
+ if (rc == SMBD_SMF_OK)
+ (void) snprintf(cbuf, bufsz, "%lld", cint);
+ return (rc);
- if (id < SMB_CI_MAX) {
- cfg = &smb_cfg_table[id];
- if (cfg->sc_value)
- return (cfg->sc_value);
+ case SCF_TYPE_BOOLEAN:
+ if (smb_config_getbool(id))
+ (void) strlcpy(cbuf, "true", bufsz);
+ else
+ (void) strlcpy(cbuf, "false", bufsz);
+ return (SMBD_SMF_OK);
}
- return (NULL);
+ return (SMBD_SMF_INVALID_ARG);
}
/*
- * smb_config_getnum
+ * smb_config_setstr
*
- * Returns the value of a numeric config param.
- * If the config param is not defined it'll return the
- * default value.
- *
- * This function MUST be called after a smb_config_rd/wrlock
- * function.
+ * Set the specified config param with the given
+ * value.
*/
-uint32_t
-smb_config_getnum(smb_cfg_id_t id)
+int
+smb_config_setstr(smb_cfg_id_t id, char *value)
{
+ smb_scfhandle_t *handle;
smb_cfg_param_t *cfg;
- char *strval = NULL;
+ int rc = SMBD_SMF_OK;
+ boolean_t protected;
+ char *tmp = NULL;
+ char *pg;
- if (id < SMB_CI_MAX) {
- cfg = &smb_cfg_table[id];
- if (cfg->sc_value)
- strval = cfg->sc_value;
+ cfg = smb_config_getent(id);
+ assert(cfg->sc_type == SCF_TYPE_ASTRING);
- if (strval)
- return (strtol(strval, 0, 10));
+ if (cfg->sc_flags & SMB_CF_PROTECTED) {
+ pg = SMBD_PROTECTED_PG_NAME;
+ protected = B_TRUE;
+ } else {
+ pg = SMBD_PG_NAME;
+ protected = B_FALSE;
}
- return (0);
-}
+ handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
+ if (handle == NULL)
+ return (SMBD_SMF_SYSTEM_ERR);
-/*
- * smb_config_getyorn
- *
- * Returns the value of a yes/no config param.
- * Returns 1 is config is set to "yes", otherwise 0.
- *
- * This function MUST be called after a smb_config_rd/wrlock
- * function.
- */
-int
-smb_config_getyorn(smb_cfg_id_t id)
-{
- char *val;
+ rc = smb_smf_create_service_pgroup(handle, pg);
+ if (rc == SMBD_SMF_OK)
+ rc = smb_smf_start_transaction(handle);
- val = smb_config_get(id);
- if (val) {
- if (strcasecmp(val, "true") == 0)
- return (1);
+ if (rc != SMBD_SMF_OK) {
+ smb_smf_scf_fini(handle);
+ return (rc);
}
- return (0);
-}
-
-/*
- * smb_config_set
- *
- * Set/update the specified config param with the given
- * value. If the value is NULL the config param will be
- * unset as if it is not defined.
- *
- * This function MUST be called after a smb_config_wrlock
- * function.
- */
-int
-smb_config_set(smb_cfg_id_t id, char *value)
-{
- smb_cfg_param_t *cfg;
- int rc = 0;
+ if (protected && value && (*value != '\0')) {
+ if ((tmp = smb_base64_encode(value)) == NULL) {
+ (void) smb_smf_end_transaction(handle);
+ smb_smf_scf_fini(handle);
+ return (SMBD_SMF_NO_MEMORY);
+ }
- if (id < SMB_CI_MAX) {
- cfg = &smb_cfg_table[id];
- rc = smb_config_update(cfg, value);
- if (rc == 0)
- cfg->sc_flags |= SMB_CF_MODIFIED;
- return (rc);
+ value = tmp;
}
- return (1);
+ rc = smb_smf_set_string_property(handle, cfg->sc_name, value);
+
+ free(tmp);
+ (void) smb_smf_end_transaction(handle);
+ smb_smf_scf_fini(handle);
+ return (rc);
}
/*
* smb_config_setnum
*
- * Set/update the specified config param with the given
- * value. This is used for numeric config params. The given
- * number will be converted to string before setting the
- * config param.
- *
- * This function MUST be called after a smb_config_wrlock
- * function.
+ * Sets a numeric configuration iterm
*/
int
-smb_config_setnum(smb_cfg_id_t id, uint32_t num)
+smb_config_setnum(smb_cfg_id_t id, int64_t value)
{
+ smb_scfhandle_t *handle;
smb_cfg_param_t *cfg;
- char value[32];
- int rc = 0;
+ int rc = SMBD_SMF_OK;
- if (id < SMB_CI_MAX) {
- cfg = &smb_cfg_table[id];
- (void) snprintf(value, sizeof (value), "%u", num);
- rc = smb_config_update(cfg, value);
- if (rc == 0)
- cfg->sc_flags |= SMB_CF_MODIFIED;
- return (rc);
- }
-
- return (1);
-}
+ cfg = smb_config_getent(id);
+ assert(cfg->sc_type == SCF_TYPE_INTEGER);
-/*
- * smb_config_rdlock
- *
- * Lock the config table for read access.
- * This function MUST be called before any kind of
- * read access to the config table i.e. all flavors of
- * smb_config_get function
- */
-void
-smb_config_rdlock()
-{
- (void) rw_rdlock(&smb_cfg_rwlk);
- lock_type = SMB_CL_READ;
-}
-
-/*
- * smb_config_wrlock
- *
- * Lock the config table for write access.
- * This function MUST be called before any kind of
- * write access to the config table i.e. all flavors of
- * smb_config_set function
- */
-void
-smb_config_wrlock()
-{
- (void) rw_wrlock(&smb_cfg_rwlk);
- lock_type = SMB_CL_WRITE;
-}
-
-/*
- * smb_config_wrlock
- *
- * Unlock the config table.
- * If the config table has been locked for write access
- * smb_config_save_all() will be called to save the changes
- * before unlocking the table.
- *
- * This function MUST be called after smb_config_rd/wrlock
- */
-void
-smb_config_unlock()
-{
- if (lock_type == SMB_CL_WRITE)
- (void) smb_config_save_all();
- (void) rw_unlock(&smb_cfg_rwlk);
-}
+ handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
+ if (handle == NULL)
+ return (SMBD_SMF_SYSTEM_ERR);
-/*
- * smb_config_save_all
- *
- * Save all modified parameters to SMF.
- */
-static int
-smb_config_save_all()
-{
- int rc;
+ rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME);
+ if (rc == SMBD_SMF_OK)
+ rc = smb_smf_start_transaction(handle);
- if ((rc = smb_config_save(SMBD_PG_NAME)) != 0)
+ if (rc != SMBD_SMF_OK) {
+ smb_smf_scf_fini(handle);
return (rc);
+ }
- return (smb_config_save(SMBD_PROTECTED_PG_NAME));
+ rc = smb_smf_set_integer_property(handle, cfg->sc_name, value);
+
+ (void) smb_smf_end_transaction(handle);
+ smb_smf_scf_fini(handle);
+ return (rc);
}
/*
- * smb_config_save
+ * smb_config_setbool
*
- * Scan the config table and call smb_config_setenv/smb_config_unsetenv
- * for params in the specified property group that has been modified.
- * When the scan is finished, smb_config_saveenv() will be called to
- * make the changes persistent.
+ * Sets a boolean configuration iterm
*/
-static int
-smb_config_save(char *pgname)
+int
+smb_config_setbool(smb_cfg_id_t id, boolean_t value)
{
- smb_cfg_id_t id;
+ smb_scfhandle_t *handle;
smb_cfg_param_t *cfg;
- smb_scfhandle_t *handle = NULL;
- int dorefresh = 0;
+ int rc = SMBD_SMF_OK;
+
+ cfg = smb_config_getent(id);
+ assert(cfg->sc_type == SCF_TYPE_BOOLEAN);
handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
- if (handle == NULL) {
- syslog(LOG_ERR, "smbd: cannot save configuration");
- return (1);
- }
+ if (handle == NULL)
+ return (SMBD_SMF_SYSTEM_ERR);
- (void) smb_smf_create_service_pgroup(handle, pgname);
- if (smb_smf_start_transaction(handle) != SMBD_SMF_OK) {
- syslog(LOG_ERR, "smbd: cannot save configuration");
- return (1);
- }
+ rc = smb_smf_create_service_pgroup(handle, SMBD_PG_NAME);
+ if (rc == SMBD_SMF_OK)
+ rc = smb_smf_start_transaction(handle);
- for (id = 0; id < SMB_CI_MAX; id++) {
- cfg = &smb_cfg_table[id];
- if (strcmp(cfg->sc_pg, pgname))
- continue;
-
- if (cfg->sc_flags & SMB_CF_MODIFIED) {
- if (cfg->sc_value) {
- if (strcmp(pgname, SMBD_PG_NAME) == 0)
- smb_config_setenv_trans(handle,
- cfg->sc_type, cfg->sc_name,
- cfg->sc_value);
- else
- smb_config_setenv_trans_protected(
- handle, cfg->sc_name,
- cfg->sc_value);
- } else {
- (void) smb_config_unsetenv_trans(handle,
- cfg->sc_name);
- }
- cfg->sc_flags &= ~SMB_CF_MODIFIED;
- dorefresh = 1;
- }
+ if (rc != SMBD_SMF_OK) {
+ smb_smf_scf_fini(handle);
+ return (rc);
}
- if (smb_config_saveenv(handle) != 0) {
- syslog(LOG_ERR, "smbd: cannot save configuration");
- return (1);
- }
- if (dorefresh)
- (void) smf_refresh_instance(SMBD_DEFAULT_INSTANCE_FMRI);
- return (0);
+ rc = smb_smf_set_boolean_property(handle, cfg->sc_name, value);
+
+ (void) smb_smf_end_transaction(handle);
+ smb_smf_scf_fini(handle);
+ return (rc);
}
/*
- * smb_config_update
+ * smb_config_set
*
- * Updates the specified config param with the given value.
- * This function is called both on (re)load and set.
+ * This function sets the value of the specified config
+ * iterm regardless of its type in string format. This should
+ * be used when the config item type is not known by the caller.
*/
-static int
-smb_config_update(smb_cfg_param_t *cfg, char *value)
+int
+smb_config_set(smb_cfg_id_t id, char *value)
{
- char *curval;
- int rc = 0;
- int len;
-
- if (value) {
- len = strlen(value);
- if (cfg->sc_value) {
- curval = (char *)realloc(cfg->sc_value,
- (len + 1));
- } else {
- curval = (char *)malloc(len + 1);
- }
+ smb_cfg_param_t *cfg;
+ int64_t cint;
- if (curval) {
- cfg->sc_value = curval;
- (void) strcpy(cfg->sc_value, value);
- cfg->sc_flags |= SMB_CF_DEFINED;
- } else {
- rc = 1;
- }
- } else if (cfg->sc_value) {
- free(cfg->sc_value);
- cfg->sc_value = NULL;
- cfg->sc_flags &= ~SMB_CF_DEFINED;
+ cfg = smb_config_getent(id);
+ switch (cfg->sc_type) {
+ case SCF_TYPE_ASTRING:
+ return (smb_config_setstr(id, value));
+
+ case SCF_TYPE_INTEGER:
+ cint = atoi(value);
+ return (smb_config_setnum(id, cint));
+
+ case SCF_TYPE_BOOLEAN:
+ return (smb_config_setbool(id, strcasecmp(value, "true") == 0));
}
- return (rc);
+ return (SMBD_SMF_INVALID_ARG);
}
-
uint8_t
smb_config_get_fg_flag()
{
@@ -1072,9 +737,9 @@ smb_config_secmode_tostr(int secmode)
int
smb_config_get_secmode()
{
- char *p;
+ char p[16];
- p = smb_config_getstr(SMB_CI_SECURITY);
+ (void) smb_config_getstr(SMB_CI_SECURITY, p, sizeof (p));
return (smb_config_secmode_fromstr(p));
}
@@ -1084,5 +749,18 @@ smb_config_set_secmode(int secmode)
char *p;
p = smb_config_secmode_tostr(secmode);
- return (smb_config_set(SMB_CI_SECURITY, p));
+ return (smb_config_setstr(SMB_CI_SECURITY, p));
+}
+
+static smb_cfg_param_t *
+smb_config_getent(smb_cfg_id_t id)
+{
+ int i;
+
+ for (i = 0; i < SMB_CI_MAX; i++)
+ if (smb_cfg_table[i].sc_id == id)
+ return (&smb_cfg_table[id]);
+
+ assert(0);
+ return (NULL);
}
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_domain.c b/usr/src/lib/smbsrv/libsmb/common/smb_domain.c
index 22ea5e61fb..f57dadc806 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_domain.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_domain.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -77,10 +77,11 @@ int
nt_domain_init(char *resource_domain, uint32_t secmode)
{
nt_domain_t *domain;
- nt_sid_t *sid;
- char *sidstr;
+ nt_sid_t *sid = NULL;
+ char sidstr[128];
char *lsidstr;
char hostname[MAXHOSTNAMELEN];
+ int rc;
if (rwlock_init(&nt_domain_lock, USYNC_THREAD, NULL))
return (SMB_DOMAIN_NODOMAIN_SID);
@@ -112,17 +113,18 @@ nt_domain_init(char *resource_domain, uint32_t secmode)
(void) nt_domain_add(domain);
free(sid);
- smb_config_rdlock();
- sidstr = smb_config_get(SMB_CI_DOMAIN_SID);
- if (sidstr) {
+ sid = NULL;
+ rc = smb_config_getstr(SMB_CI_DOMAIN_SID, sidstr,
+ sizeof (sidstr));
+ if (rc == SMBD_SMF_OK)
sid = nt_sid_strtosid(sidstr);
- smb_config_unlock();
+ if (nt_sid_is_valid(sid)) {
domain = nt_domain_new(NT_DOMAIN_PRIMARY,
resource_domain, sid);
(void) nt_domain_add(domain);
free(sid);
} else {
- smb_config_unlock();
+ free(sid);
(void) rwlock_destroy(&nt_domain_lock);
return (SMB_DOMAIN_NODOMAIN_SID);
}
@@ -198,9 +200,7 @@ nt_domain_add(nt_domain_t *new_domain)
if (new_domain->type == NT_DOMAIN_PRIMARY) {
sidstr = nt_sid_format(new_domain->sid);
- smb_config_wrlock();
- (void) smb_config_set(SMB_CI_DOMAIN_SID, sidstr);
- smb_config_unlock();
+ (void) smb_config_setstr(SMB_CI_DOMAIN_SID, sidstr);
free(sidstr);
}
(void) rw_unlock(&nt_domain_lock);
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_door_client.c b/usr/src/lib/smbsrv/libsmb/common/smb_door_client.c
index 06eeac365c..7884b972a5 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_door_client.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_door_client.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -36,7 +36,6 @@
#include <strings.h>
#include <stdlib.h>
#include <errno.h>
-#include <unistd.h>
#include <smbsrv/smbinfo.h>
#include <smbsrv/wintypes.h>
@@ -54,7 +53,6 @@ static char *smbd_desc[] = {
"SmbdGetParam",
"SmbdSetParam",
"SmbdNetbiosReconfig",
- "SmbdAdsDomainChanged",
0
};
@@ -411,95 +409,3 @@ smbd_get_security_mode(int *mode)
*mode = smb_config_secmode_fromstr(buf);
return (rc);
}
-
-/*
- * smb_ads_domain_change_notify
- *
- * When ADS domain has changed, this function is called to clear the
- * ADS_HOST_INFO cache and remove the old keys from the Kerberos keytab.
- */
-int
-smb_ads_domain_change_notify(char *dom)
-{
- door_arg_t arg;
- char *buf;
- uint32_t used;
- smb_dr_ctx_t *dec_ctx;
- smb_dr_ctx_t *enc_ctx;
- int status;
- int rc;
- int opcode = SMBD_DOOR_ADS_DOMAIN_CHANGED;
-
- if (smbd_door_open(opcode) == -1) {
- syslog(LOG_ERR, "%s: cannot open the door", smbd_desc[opcode]);
- return (1);
- }
-
- buf = MEM_MALLOC("smb_door_client", SMBD_DOOR_SIZE);
- if (!buf) {
- syslog(LOG_ERR, "%s: resource shortage", smbd_desc[opcode]);
- (void) close(smb_door_fildes);
- smb_door_fildes = -1;
- return (1);
- }
-
- enc_ctx = smb_dr_encode_start(buf, SMBD_DOOR_SIZE);
- if (enc_ctx == 0) {
- syslog(LOG_ERR, "%s: encode start failed", smbd_desc[opcode]);
- MEM_FREE("smb_door_client", buf);
- (void) close(smb_door_fildes);
- smb_door_fildes = -1;
- return (1);
- }
-
- smb_dr_put_uint32(enc_ctx, opcode);
- smb_dr_put_string(enc_ctx, dom);
-
- if ((status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
- syslog(LOG_ERR, "%s: Encode error %s",
- smbd_desc[opcode], strerror(status));
- MEM_FREE("smb_door_client", buf);
- (void) close(smb_door_fildes);
- smb_door_fildes = -1;
- return (1);
- }
-
- arg.data_ptr = buf;
- arg.data_size = used;
- arg.desc_ptr = NULL;
- arg.desc_num = 0;
- arg.rbuf = buf;
- arg.rsize = SMBD_DOOR_SIZE;
-
- if (door_call(smb_door_fildes, &arg) < 0) {
- syslog(LOG_ERR, "%s: Door call failed %s", smbd_desc[opcode],
- strerror(errno));
- MEM_FREE("smb_door_client", buf);
- (void) close(smb_door_fildes);
- smb_door_fildes = -1;
- return (1);
- }
-
- dec_ctx = smb_dr_decode_start(arg.data_ptr, arg.data_size);
- if (smbd_door_check_srv_status(opcode, dec_ctx) != 0) {
- MEM_FREE("smb_door_client", buf);
- (void) close(smb_door_fildes);
- smb_door_fildes = -1;
- return (1);
- }
- rc = smb_dr_get_uint32(dec_ctx);
-
- if ((status = smb_dr_decode_finish(dec_ctx)) != 0) {
- syslog(LOG_ERR, "%s: Decode error %s",
- smbd_desc[opcode], strerror(status));
- MEM_FREE("smb_door_client", buf);
- (void) close(smb_door_fildes);
- smb_door_fildes = -1;
- return (1);
- }
- MEM_FREE("smb_door_client", buf);
- (void) close(smb_door_fildes);
- smb_door_fildes = -1;
-
- return (rc);
-}
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_idmap.c b/usr/src/lib/smbsrv/libsmb/common/smb_idmap.c
index f410fe3237..862bcf919d 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_idmap.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_idmap.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -126,6 +126,43 @@ smb_idmap_getsid(uid_t id, int idtype, nt_sid_t **sid)
}
/*
+ * smb_idmap_getid
+ *
+ * Tries to get a mapping for the given SID
+ */
+idmap_stat
+smb_idmap_getid(nt_sid_t *sid, uid_t *id, int *id_type)
+{
+ smb_idmap_batch_t sib;
+ smb_idmap_t *sim;
+ idmap_stat stat;
+
+ stat = smb_idmap_batch_create(&sib, 1, SMB_IDMAP_SID2ID);
+ if (stat != IDMAP_SUCCESS)
+ return (stat);
+
+ sim = &sib.sib_maps[0];
+ sim->sim_id = id;
+ stat = smb_idmap_batch_getid(sib.sib_idmaph, sim, sid, *id_type);
+ if (stat != IDMAP_SUCCESS) {
+ smb_idmap_batch_destroy(&sib);
+ return (stat);
+ }
+
+ stat = smb_idmap_batch_getmappings(&sib);
+
+ if (stat != IDMAP_SUCCESS) {
+ smb_idmap_batch_destroy(&sib);
+ return (stat);
+ }
+
+ *id_type = sim->sim_idtype;
+ smb_idmap_batch_destroy(&sib);
+
+ return (IDMAP_SUCCESS);
+}
+
+/*
* smb_idmap_batch_create
*
* Creates and initializes the context for batch ID mapping.
@@ -163,7 +200,6 @@ void
smb_idmap_batch_destroy(smb_idmap_batch_t *sib)
{
nt_sid_t *sid;
- char *domsid;
int i;
if (!sib)
@@ -177,8 +213,7 @@ smb_idmap_batch_destroy(smb_idmap_batch_t *sib)
if (!sib->sib_maps)
return;
- switch (sib->sib_flags) {
- case SMB_IDMAP_SID2ID:
+ if (sib->sib_flags & SMB_IDMAP_ID2SID) {
/*
* SIDs are allocated only when mapping
* UID/GID to SIDs
@@ -188,20 +223,6 @@ smb_idmap_batch_destroy(smb_idmap_batch_t *sib)
if (sid)
free(sid);
}
- break;
- case SMB_IDMAP_ID2SID:
- /*
- * SID prefixes are allocated only when mapping
- * SIDs to UID/GID
- */
- for (i = 0; i < sib->sib_nmap; i++) {
- domsid = sib->sib_maps[i].sim_domsid;
- if (domsid)
- free(domsid);
- }
- break;
- default:
- break;
}
if (sib->sib_size && sib->sib_maps) {
@@ -262,9 +283,11 @@ smb_idmap_batch_getid(idmap_get_handle_t *idmaph, smb_idmap_t *sim,
break;
default:
+ free(sim->sim_domsid);
return (IDMAP_ERR_ARG);
}
+ free(sim->sim_domsid);
return (stat);
}
@@ -371,6 +394,7 @@ smb_idmap_batch_binsid(smb_idmap_batch_t *sib)
return (-1);
sid = nt_sid_strtosid(sim->sim_domsid);
+ free(sim->sim_domsid);
if (sid == NULL)
return (-1);
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_info.c b/usr/src/lib/smbsrv/libsmb/common/smb_info.c
index d39eaf9208..918cc02acb 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_info.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_info.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -37,6 +37,9 @@
#include <errno.h>
#include <net/if.h>
#include <netdb.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
#include <sys/sockio.h>
#include <smbsrv/smbinfo.h>
#include <smbsrv/netbios.h>
@@ -48,85 +51,6 @@ static cond_t smbpdc_cv;
extern int getdomainname(char *, int);
-uint32_t
-smb_get_security_mode()
-{
- uint32_t mode;
-
- smb_config_rdlock();
- mode = smb_config_get_secmode();
- smb_config_unlock();
-
- return (mode);
-}
-
-/*
- * smb_purge_domain_info
- *
- * Clean out the environment in preparation for joining a domain.
- * This ensures that we don't have any old information lying around.
- */
-void
-smb_purge_domain_info(void)
-{
- smb_config_wrlock();
- (void) smb_config_set(SMB_CI_DOMAIN_NAME, 0);
- (void) smb_config_set(SMB_CI_DOMAIN_SID, 0);
- (void) smb_config_set(SMB_CI_DOMAIN_MEMB, 0);
- smb_config_unlock();
-}
-
-int
-smb_is_domain_member(void)
-{
- int is_memb;
-
- smb_config_rdlock();
- is_memb = smb_config_getyorn(SMB_CI_DOMAIN_MEMB);
- smb_config_unlock();
-
- return (is_memb);
-}
-
-uint8_t
-smb_get_fg_flag(void)
-{
- uint8_t run_fg;
-
- smb_config_rdlock();
- run_fg = smb_config_get_fg_flag();
- smb_config_unlock();
-
- return (run_fg);
-}
-
-void
-smb_set_domain_member(int set)
-{
- char *member;
-
- smb_config_wrlock();
- member = (set) ? "true" : "false";
- (void) smb_config_set(SMB_CI_DOMAIN_MEMB, member);
- smb_config_unlock();
-}
-
-/*
- * smb_set_machine_pwd
- *
- * Returns 0 upon success. Otherwise, returns 1.
- */
-int
-smb_set_machine_pwd(char *pwd)
-{
- int rc;
-
- smb_config_wrlock();
- rc = smb_config_set(SMB_CI_MACHINE_PASSWD, pwd);
- smb_config_unlock();
- return (rc);
-}
-
/*
* smb_getdomaininfo
*
@@ -206,47 +130,41 @@ smb_setdomaininfo(char *domain, char *server, uint32_t ipaddr)
void
smb_load_kconfig(smb_kmod_cfg_t *kcfg)
{
- smb_config_rdlock();
+ int64_t citem;
+
bzero(kcfg, sizeof (smb_kmod_cfg_t));
- kcfg->skc_maxbufsize = smb_config_getnum(SMB_CI_MAX_BUFSIZE);
- kcfg->skc_maxworkers = smb_config_getnum(SMB_CI_MAX_WORKERS);
- kcfg->skc_keepalive = smb_config_getnum(SMB_CI_KEEPALIVE);
+ (void) smb_config_getnum(SMB_CI_MAX_BUFSIZE, &citem);
+ kcfg->skc_maxbufsize = (uint32_t)citem;
+ (void) smb_config_getnum(SMB_CI_MAX_WORKERS, &citem);
+ kcfg->skc_maxworkers = (uint32_t)citem;
+ (void) smb_config_getnum(SMB_CI_KEEPALIVE, &citem);
+ kcfg->skc_keepalive = (uint32_t)citem;
if ((kcfg->skc_keepalive != 0) &&
(kcfg->skc_keepalive < SMB_PI_KEEP_ALIVE_MIN))
kcfg->skc_keepalive = SMB_PI_KEEP_ALIVE_MIN;
- kcfg->skc_restrict_anon = smb_config_getyorn(SMB_CI_RESTRICT_ANON);
-
- kcfg->skc_signing_enable = smb_config_getyorn(SMB_CI_SIGNING_ENABLE);
- kcfg->skc_signing_required = smb_config_getyorn(SMB_CI_SIGNING_REQD);
- kcfg->skc_signing_check = smb_config_getyorn(SMB_CI_SIGNING_CHECK);
- kcfg->skc_oplock_enable = smb_config_getyorn(SMB_CI_OPLOCK_ENABLE);
- kcfg->skc_oplock_timeout = smb_config_getnum(SMB_CI_OPLOCK_TIMEOUT);
-
- kcfg->skc_flush_required = smb_config_getyorn(SMB_CI_FLUSH_REQUIRED);
- kcfg->skc_sync_enable = smb_config_getyorn(SMB_CI_SYNC_ENABLE);
+ (void) smb_config_getnum(SMB_CI_OPLOCK_TIMEOUT, &citem);
+ kcfg->skc_oplock_timeout = (uint32_t)citem;
+ (void) smb_config_getnum(SMB_CI_MAX_CONNECTIONS, &citem);
+ kcfg->skc_maxconnections = (uint32_t)citem;
+ kcfg->skc_restrict_anon = smb_config_getbool(SMB_CI_RESTRICT_ANON);
+ kcfg->skc_signing_enable = smb_config_getbool(SMB_CI_SIGNING_ENABLE);
+ kcfg->skc_signing_required = smb_config_getbool(SMB_CI_SIGNING_REQD);
+ kcfg->skc_signing_check = smb_config_getbool(SMB_CI_SIGNING_CHECK);
+ kcfg->skc_oplock_enable = smb_config_getbool(SMB_CI_OPLOCK_ENABLE);
+ kcfg->skc_flush_required = smb_config_getbool(SMB_CI_FLUSH_REQUIRED);
+ kcfg->skc_sync_enable = smb_config_getbool(SMB_CI_SYNC_ENABLE);
kcfg->skc_dirsymlink_enable =
- !smb_config_getyorn(SMB_CI_DIRSYMLINK_DISABLE);
- kcfg->skc_announce_quota = smb_config_getyorn(SMB_CI_ANNONCE_QUOTA);
- kcfg->skc_announce_quota = smb_config_getyorn(SMB_CI_ANNONCE_QUOTA);
-
+ !smb_config_getbool(SMB_CI_DIRSYMLINK_DISABLE);
+ kcfg->skc_announce_quota = smb_config_getbool(SMB_CI_ANNONCE_QUOTA);
kcfg->skc_secmode = smb_config_get_secmode();
- kcfg->skc_lmlevel = smb_config_getnum(SMB_CI_LM_LEVEL);
- kcfg->skc_maxconnections = smb_config_getnum(SMB_CI_MAX_CONNECTIONS);
-
- (void) strlcpy(kcfg->skc_resource_domain,
- smb_config_getstr(SMB_CI_DOMAIN_NAME),
+ (void) smb_getdomainname(kcfg->skc_resource_domain,
sizeof (kcfg->skc_resource_domain));
-
- (void) smb_gethostname(kcfg->skc_hostname,
- sizeof (kcfg->skc_hostname), 1);
-
- (void) strlcpy(kcfg->skc_system_comment,
- smb_config_getstr(SMB_CI_SYS_CMNT),
+ (void) smb_gethostname(kcfg->skc_hostname, sizeof (kcfg->skc_hostname),
+ 1);
+ (void) smb_config_getstr(SMB_CI_SYS_CMNT, kcfg->skc_system_comment,
sizeof (kcfg->skc_system_comment));
-
- smb_config_unlock();
}
/*
@@ -304,74 +222,200 @@ smb_gethostname(char *buf, size_t buflen, int upcase)
}
/*
- * The ADS domain is often the same as the DNS domain but they can be
- * different - one might be a sub-domain of the other.
- *
- * If an ADS domain name has been configured, return it. Otherwise,
- * return the DNS domain name.
- *
- * If getdomainname fails, the returned buffer will contain an empty
- * string.
+ * Obtain the fully-qualified name for this machine. If the
+ * hostname is fully-qualified, accept it. Otherwise, try to
+ * find an appropriate domain name to append to the hostname.
*/
int
-smb_getdomainname(char *buf, size_t buflen)
+smb_getfqhostname(char *buf, size_t buflen)
{
- char *domain;
+ char hostname[MAXHOSTNAMELEN];
+ char domain[MAXHOSTNAMELEN];
- if (buf == NULL || buflen == 0)
+ hostname[0] = '\0';
+ domain[0] = '\0';
+
+ if (smb_gethostname(hostname, MAXHOSTNAMELEN, 0) != 0)
return (-1);
- smb_config_rdlock();
+ if (smb_getfqdomainname(domain, MAXHOSTNAMELEN) != 0)
+ return (-1);
+
+ if (hostname[0] == '\0')
+ return (-1);
- domain = smb_config_getstr(SMB_CI_ADS_DOMAIN);
- if ((domain != NULL) && (*domain != '\0')) {
- (void) strlcpy(buf, domain, buflen);
- smb_config_unlock();
+ if (domain[0] == '\0') {
+ (void) strlcpy(buf, hostname, buflen);
return (0);
}
- smb_config_unlock();
+ (void) snprintf(buf, buflen, "%s.%s", hostname, domain);
+ return (0);
+}
- if (getdomainname(buf, buflen) != 0) {
- *buf = '\0';
+/*
+ * smb_resolve_netbiosname
+ *
+ * Convert the fully-qualified domain name (i.e. fqdn) to a NETBIOS name.
+ * Upon success, the NETBIOS name will be returned via buf parameter.
+ * Returns 0 upon success. Otherwise, returns -1.
+ */
+int
+smb_resolve_netbiosname(char *fqdn, char *buf, size_t buflen)
+{
+ char *p;
+
+ if (!buf)
return (-1);
- }
+
+ *buf = '\0';
+ if (!fqdn)
+ return (-1);
+
+ (void) strlcpy(buf, fqdn, buflen);
+ if ((p = strchr(buf, '.')) != NULL)
+ *p = 0;
+
+ if (strlen(buf) >= NETBIOS_NAME_SZ)
+ buf[NETBIOS_NAME_SZ - 1] = '\0';
return (0);
}
/*
- * Obtain the fully-qualified name for this machine. If the
- * hostname is fully-qualified, accept it. Otherwise, try to
- * find an appropriate domain name to append to the hostname.
+ * smb_getdomainname
+ *
+ * Returns NETBIOS name of the domain if the system is in domain
+ * mode. Or returns workgroup name if the system is in workgroup
+ * mode.
*/
int
-smb_getfqhostname(char *buf, size_t buflen)
+smb_getdomainname(char *buf, size_t buflen)
{
- char hostname[MAXHOSTNAMELEN];
char domain[MAXHOSTNAMELEN];
+ int rc;
- hostname[0] = '\0';
- domain[0] = '\0';
+ if (buf == NULL || buflen == 0)
+ return (-1);
- if (smb_gethostname(hostname, MAXHOSTNAMELEN, 0) != 0)
+ *buf = '\0';
+ rc = smb_config_getstr(SMB_CI_DOMAIN_NAME, domain,
+ sizeof (domain));
+
+ if ((rc != SMBD_SMF_OK) || (*domain == '\0'))
return (-1);
- if (smb_getdomainname(domain, MAXHOSTNAMELEN) != 0)
+ (void) smb_resolve_netbiosname(domain, buf, buflen);
+ return (0);
+}
+
+/*
+ * smb_resolve_fqdn
+ *
+ * Converts the NETBIOS name of the domain (i.e. nbt_domain) to a fully
+ * qualified domain name. The domain from either the domain field or
+ * search list field of the /etc/resolv.conf will be returned via the
+ * buf parameter if the first label of the domain matches the given
+ * NETBIOS name.
+ *
+ * Returns -1 upon error. If a match is found, returns 1. Otherwise,
+ * returns 0.
+ */
+int
+smb_resolve_fqdn(char *nbt_domain, char *buf, size_t buflen)
+{
+ struct __res_state res_state;
+ int i, found = 0;
+ char *p;
+ int dlen;
+
+ if (!buf)
return (-1);
- if (hostname[0] == '\0')
+ *buf = '\0';
+ if (!nbt_domain)
return (-1);
- if (domain[0] == '\0') {
- (void) strlcpy(buf, hostname, buflen);
- return (0);
+ bzero(&res_state, sizeof (struct __res_state));
+ if (res_ninit(&res_state))
+ return (-1);
+
+ if (*nbt_domain == '\0') {
+ if (*res_state.defdname == '\0') {
+ res_ndestroy(&res_state);
+ return (0);
+ }
+
+ (void) strlcpy(buf, res_state.defdname, buflen);
+ res_ndestroy(&res_state);
+ return (1);
}
- (void) snprintf(buf, buflen, "%s.%s", hostname, domain);
- return (0);
+ dlen = strlen(nbt_domain);
+ if (!strncasecmp(nbt_domain, res_state.defdname, dlen)) {
+ (void) strlcpy(buf, res_state.defdname, buflen);
+ res_ndestroy(&res_state);
+ return (1);
+ }
+
+ for (i = 0; (p = res_state.dnsrch[i]) != NULL; i++) {
+ if (!strncasecmp(nbt_domain, p, dlen)) {
+ (void) strlcpy(buf, p, buflen);
+ found = 1;
+ break;
+ }
+
+ }
+
+ res_ndestroy(&res_state);
+ return (found);
+}
+
+/*
+ * smb_getfqdomainname
+ *
+ * If the domain_name property value is FQDN, it will be returned.
+ * In domain mode, the domain from either the domain field or
+ * search list field of the /etc/resolv.conf will be returned via the
+ * buf parameter if the first label of the domain matches the
+ * domain_name property. In workgroup mode, it returns the local
+ * domain.
+ *
+ * Returns 0 upon success. Otherwise, returns -1.
+ */
+int
+smb_getfqdomainname(char *buf, size_t buflen)
+{
+ char domain[MAXHOSTNAMELEN];
+ int rc = 0;
+
+ if (buf == NULL || buflen == 0)
+ return (-1);
+
+ *buf = '\0';
+ if (smb_config_get_secmode() == SMB_SECMODE_DOMAIN) {
+ rc = smb_config_getstr(SMB_CI_DOMAIN_NAME, domain,
+ sizeof (domain));
+
+ if ((rc != SMBD_SMF_OK) || (*domain == '\0'))
+ return (-1);
+
+ if (strchr(domain, '.') == NULL) {
+ if (smb_resolve_fqdn(domain, buf, buflen) != 1)
+ rc = -1;
+ } else {
+ (void) strlcpy(buf, domain, buflen);
+ }
+ } else {
+ if (smb_resolve_fqdn("", buf, buflen) != 1)
+ rc = -1;
+ }
+
+ return (rc);
}
+
+
/*
* Temporary fbt for dtrace until user space sdt enabled.
*/
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c b/usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c
new file mode 100644
index 0000000000..934b804dcd
--- /dev/null
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c
@@ -0,0 +1,2319 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdlib.h>
+#include <strings.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <thread.h>
+#include <synch.h>
+#include <grp.h>
+#include <assert.h>
+#include <libintl.h>
+#include <smbsrv/libsmb.h>
+
+#define SMB_LGRP_LOCAL_IDX 0
+#define SMB_LGRP_BUILTIN_IDX 1
+
+#define SMB_LGRP_DB_NAME "/var/smb/smbgroup.db"
+#define SMB_LGRP_DB_TIMEOUT 3000 /* in millisecond */
+#define SMB_LGRP_DB_VERMAJOR 1
+#define SMB_LGRP_DB_VERMINOR 0
+#define SMB_LGRP_DB_MAGIC 0x4C475250 /* LGRP */
+
+#define SMB_LGRP_DB_ORD 1 /* open read-only */
+#define SMB_LGRP_DB_ORW 2 /* open read/write */
+
+#define SMB_LGRP_DB_ADDMEMBER 1
+#define SMB_LGRP_DB_DELMEMBER 2
+
+/*
+ * members column of the groups table is an array of
+ * member structure smb_lgmid_t defined below.
+ *
+ * privs column of the groups table is an array of bytes
+ * where each byte is the id of an enable privilege
+ */
+#define SMB_LGRP_DB_SQL \
+ "CREATE TABLE db_info (" \
+ " ver_major INTEGER," \
+ " ver_minor INTEGER," \
+ " magic INTEGER" \
+ ");" \
+ "" \
+ "CREATE TABLE domains (" \
+ " dom_idx INTEGER PRIMARY KEY," \
+ " dom_sid TEXT UNIQUE," \
+ " dom_cnt INTEGER" \
+ ");" \
+ "" \
+ "CREATE UNIQUE INDEX domsid_idx ON domains (dom_sid);" \
+ "" \
+ "CREATE TABLE groups (" \
+ " name TEXT PRIMARY KEY," \
+ " sid_idx INTEGER," \
+ " sid_rid INTEGER," \
+ " sid_type INTEGER," \
+ " sid_attrs INTEGER," \
+ " comment TEXT," \
+ " n_privs INTEGER," \
+ " privs BLOB," \
+ " n_members INTEGER," \
+ " members BLOB" \
+ ");" \
+ "" \
+ "CREATE INDEX grprid_idx ON groups (sid_rid);"
+
+/*
+ * Number of groups table columns
+ */
+#define SMB_LGRP_GTBL_NCOL 10
+
+#define SMB_LGRP_GTBL_NAME 0
+#define SMB_LGRP_GTBL_SIDIDX 1
+#define SMB_LGRP_GTBL_SIDRID 2
+#define SMB_LGRP_GTBL_SIDTYP 3
+#define SMB_LGRP_GTBL_SIDATR 4
+#define SMB_LGRP_GTBL_CMNT 5
+#define SMB_LGRP_GTBL_NPRIVS 6
+#define SMB_LGRP_GTBL_PRIVS 7
+#define SMB_LGRP_GTBL_NMEMBS 8
+#define SMB_LGRP_GTBL_MEMBS 9
+
+#define SMB_LGRP_INFO_NONE 0x00
+#define SMB_LGRP_INFO_NAME 0x01
+#define SMB_LGRP_INFO_CMNT 0x02
+#define SMB_LGRP_INFO_SID 0x04
+#define SMB_LGRP_INFO_PRIV 0x08
+#define SMB_LGRP_INFO_MEMB 0x10
+#define SMB_LGRP_INFO_ALL 0x1F
+
+#define NULL_MSGCHK(msg) ((msg) ? (msg) : "NULL")
+
+/* Member ID */
+typedef struct smb_lgmid {
+ uint32_t m_idx;
+ uint32_t m_rid;
+ uint16_t m_type;
+} smb_lgmid_t;
+
+#define SMB_LGRP_MID_HEXSZ 32
+
+/* Member list */
+typedef struct smb_lgmlist {
+ uint32_t m_cnt;
+ char *m_ids;
+} smb_lgmlist_t;
+
+/* Privilege ID */
+typedef uint8_t smb_lgpid_t;
+
+/* Privilege list */
+typedef struct smb_lgplist {
+ uint32_t p_cnt;
+ smb_lgpid_t *p_ids;
+} smb_lgplist_t;
+
+static mutex_t smb_lgrp_lsid_mtx;
+static nt_sid_t *smb_lgrp_lsid;
+
+static int smb_lgrp_db_init(void);
+static sqlite *smb_lgrp_db_open(int);
+static void smb_lgrp_db_close(sqlite *);
+static int smb_lgrp_db_setinfo(sqlite *);
+
+static boolean_t smb_lgrp_gtbl_exists(sqlite *, char *);
+static int smb_lgrp_gtbl_lookup(sqlite *, int, smb_group_t *, int, ...);
+static int smb_lgrp_gtbl_insert(sqlite *, smb_group_t *);
+static int smb_lgrp_gtbl_update(sqlite *, char *, smb_group_t *, int);
+static int smb_lgrp_gtbl_delete(sqlite *, char *);
+static int smb_lgrp_gtbl_update_mlist(sqlite *, char *, smb_gsid_t *, int);
+static int smb_lgrp_gtbl_update_plist(sqlite *, char *, uint8_t, boolean_t);
+static int smb_lgrp_gtbl_count(sqlite *, int, int *);
+
+static int smb_lgrp_dtbl_insert(sqlite *, char *, uint32_t *);
+static int smb_lgrp_dtbl_getidx(sqlite *, nt_sid_t *, uint16_t,
+ uint32_t *, uint32_t *);
+static int smb_lgrp_dtbl_getsid(sqlite *, uint32_t, nt_sid_t **);
+
+static int smb_lgrp_mlist_add(smb_lgmlist_t *, smb_lgmid_t *, smb_lgmlist_t *);
+static int smb_lgrp_mlist_del(smb_lgmlist_t *, smb_lgmid_t *, smb_lgmlist_t *);
+
+static int smb_lgrp_plist_add(smb_lgplist_t *, smb_lgpid_t, smb_lgplist_t *);
+static int smb_lgrp_plist_del(smb_lgplist_t *, smb_lgpid_t, smb_lgplist_t *);
+
+static void smb_lgrp_encode_privset(smb_group_t *, smb_lgplist_t *);
+
+static int smb_lgrp_decode(smb_group_t *, char **, int, sqlite *);
+static int smb_lgrp_decode_privset(smb_group_t *, char *, char *);
+static int smb_lgrp_decode_members(smb_group_t *, char *, char *, sqlite *);
+
+static void smb_lgrp_set_default_privs(smb_group_t *);
+static boolean_t smb_lgrp_chkname(char *);
+static boolean_t smb_lgrp_chkmember(uint16_t);
+static int smb_lgrp_getsid(int, uint32_t *, uint16_t, sqlite *, nt_sid_t **);
+
+#ifdef _LP64
+/*
+ * We cannot make 64-bit version of libsqlite because the code
+ * has some problems.
+ */
+
+/*ARGSUSED*/
+sqlite *
+sqlite_open(const char *filename, int mode, char **errmsg)
+{
+ return (NULL);
+}
+
+/*ARGSUSED*/
+void
+sqlite_close(sqlite *db)
+{
+}
+
+/*ARGSUSED*/
+char *
+sqlite_mprintf(const char *fmt, ...)
+{
+ return (NULL);
+}
+
+/*ARGSUSED*/
+void
+sqlite_freemem(void *p)
+{
+}
+
+/*ARGSUSED*/
+int
+sqlite_compile(sqlite *db, const char *zSql, const char **pzTail,
+ sqlite_vm **ppVm, char **pzErrmsg)
+{
+ return (SQLITE_ERROR);
+}
+
+/*ARGSUSED*/
+void
+sqlite_free_table(char **res)
+{
+}
+
+/*ARGSUSED*/
+int
+sqlite_last_insert_rowid(sqlite *db)
+{
+ return (-1);
+}
+
+/*ARGSUSED*/
+void
+sqlite_busy_timeout(sqlite *db, int ms)
+{
+}
+
+/*ARGSUSED*/
+int
+sqlite_get_table(sqlite *db, const char *zSql, char ***pazResult, int *pnRow,
+ int *pnColumn, char **pzErrMsg)
+{
+ return (SQLITE_ERROR);
+}
+
+/*ARGSUSED*/
+int
+sqlite_step(sqlite_vm *pVm, int *pN, const char ***pazValue,
+ const char ***pazColName)
+{
+ return (SQLITE_ERROR);
+}
+
+/*ARGSUSED*/
+int
+sqlite_exec(sqlite *db, const char *zSql, sqlite_callback xCallback, void *pArg,
+ char **pzErrMsg)
+{
+ return (SQLITE_ERROR);
+}
+
+/*ARGSUSED*/
+int
+sqlite_finalize(sqlite_vm *pVm, char **pzErrMsg)
+{
+ return (SQLITE_ERROR);
+}
+#endif /* _LP64 */
+
+/*
+ * smb_lgrp_add
+ *
+ * Create a local group with the given name and comment.
+ * This new group doesn't have any members and no enabled
+ * privileges.
+ *
+ * No well-known accounts can be added other than Administators,
+ * Backup Operators and Power Users. These built-in groups
+ * won't have any members when created but a set of default
+ * privileges will be enabled for them.
+ */
+int
+smb_lgrp_add(char *gname, char *cmnt)
+{
+ well_known_account_t *wk_acct;
+ struct group *pxgrp;
+ smb_group_t grp;
+ nt_sid_t *sid = NULL;
+ sqlite *db;
+ int rc;
+
+ (void) trim_whitespace(gname);
+ if (!smb_lgrp_chkname(gname))
+ return (SMB_LGRP_INVALID_NAME);
+
+ if (cmnt && (strlen(cmnt) > SMB_LGRP_COMMENT_MAX))
+ return (SMB_LGRP_INVALID_ARG);
+
+ bzero(&grp, sizeof (grp));
+ grp.sg_name = utf8_strlwr(gname);
+ grp.sg_cmnt = cmnt;
+
+ wk_acct = nt_builtin_lookup(gname);
+ if (wk_acct == NULL) {
+ if ((pxgrp = getgrnam(gname)) == NULL)
+ return (SMB_LGRP_NOT_FOUND);
+
+ /*
+ * Make sure a local SID can be obtained
+ */
+ if (smb_idmap_getsid(pxgrp->gr_gid, SMB_IDMAP_GROUP, &sid)
+ != IDMAP_SUCCESS)
+ return (SMB_LGRP_NO_SID);
+
+ if (!nt_sid_is_indomain(smb_lgrp_lsid, sid)) {
+ free(sid);
+ return (SMB_LGRP_SID_NOTLOCAL);
+ }
+
+ grp.sg_id.gs_type = SidTypeAlias;
+ grp.sg_domain = SMB_LGRP_LOCAL;
+ grp.sg_rid = pxgrp->gr_gid;
+ } else {
+ if (wk_acct->flags & LGF_HIDDEN) {
+ /* cannot add well-known accounts */
+ return (SMB_LGRP_WKSID);
+ }
+
+ grp.sg_id.gs_type = wk_acct->sid_name_use;
+ if ((sid = nt_sid_strtosid(wk_acct->sid)) == NULL)
+ return (SMB_LGRP_NO_MEMORY);
+ (void) nt_sid_get_rid(sid, &grp.sg_rid);
+ free(sid);
+ grp.sg_domain = SMB_LGRP_BUILTIN;
+
+ grp.sg_privs = smb_privset_new();
+ smb_lgrp_set_default_privs(&grp);
+ }
+
+
+ grp.sg_attr = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT |
+ SE_GROUP_ENABLED;
+
+ db = smb_lgrp_db_open(SMB_LGRP_DB_ORW);
+ rc = smb_lgrp_gtbl_insert(db, &grp);
+ smb_lgrp_db_close(db);
+
+ smb_privset_free(grp.sg_privs);
+ return (rc);
+}
+
+/*
+ * smb_lgrp_rename
+ *
+ * Renames the given group
+ */
+int
+smb_lgrp_rename(char *gname, char *new_gname)
+{
+ smb_group_t grp;
+ sqlite *db;
+ int rc;
+
+ (void) trim_whitespace(gname);
+ if (!smb_lgrp_chkname(gname))
+ return (SMB_LGRP_INVALID_NAME);
+
+ (void) trim_whitespace(new_gname);
+ if (!smb_lgrp_chkname(gname))
+ return (SMB_LGRP_INVALID_NAME);
+
+ if (utf8_strcasecmp(gname, new_gname) == 0)
+ return (SMB_LGRP_SUCCESS);
+
+ /* Cannot rename well-known groups */
+ if (nt_builtin_is_wellknown(gname))
+ return (SMB_LGRP_WKSID);
+
+ /* Cannot rename to a well-known groups */
+ if (nt_builtin_is_wellknown(new_gname))
+ return (SMB_LGRP_WKSID);
+
+ grp.sg_name = new_gname;
+
+ db = smb_lgrp_db_open(SMB_LGRP_DB_ORW);
+ rc = smb_lgrp_gtbl_update(db, gname, &grp, SMB_LGRP_GTBL_NAME);
+ smb_lgrp_db_close(db);
+
+ return (rc);
+}
+
+/*
+ * smb_lgrp_delete
+ *
+ * Deletes the specified local group.
+ */
+int
+smb_lgrp_delete(char *gname)
+{
+ sqlite *db;
+ int rc;
+
+ (void) trim_whitespace(gname);
+ if (!smb_lgrp_chkname(gname))
+ return (SMB_LGRP_INVALID_NAME);
+
+ /* Cannot remove a built-in group */
+ if (nt_builtin_is_wellknown(gname))
+ return (SMB_LGRP_WKSID);
+
+ db = smb_lgrp_db_open(SMB_LGRP_DB_ORW);
+ rc = smb_lgrp_gtbl_delete(db, gname);
+ smb_lgrp_db_close(db);
+
+ return (rc);
+}
+
+/*
+ * smb_lgrp_setcmnt
+ *
+ * Sets the description for the given group
+ */
+int
+smb_lgrp_setcmnt(char *gname, char *cmnt)
+{
+ smb_group_t grp;
+ sqlite *db;
+ int rc;
+
+ (void) trim_whitespace(gname);
+ if (!smb_lgrp_chkname(gname))
+ return (SMB_LGRP_INVALID_NAME);
+
+ if (cmnt && (strlen(cmnt) > SMB_LGRP_COMMENT_MAX))
+ return (SMB_LGRP_INVALID_ARG);
+
+ grp.sg_cmnt = cmnt;
+
+ db = smb_lgrp_db_open(SMB_LGRP_DB_ORW);
+ rc = smb_lgrp_gtbl_update(db, gname, &grp, SMB_LGRP_GTBL_CMNT);
+ smb_lgrp_db_close(db);
+
+ return (rc);
+}
+
+/*
+ * smb_lgrp_getcmnt
+ *
+ * Obtain the description of the specified group
+ */
+int
+smb_lgrp_getcmnt(char *gname, char **cmnt)
+{
+ smb_group_t grp;
+ sqlite *db;
+ int rc;
+
+ (void) trim_whitespace(gname);
+ if (!smb_lgrp_chkname(gname))
+ return (SMB_LGRP_INVALID_NAME);
+
+ if (cmnt == NULL)
+ return (SMB_LGRP_INVALID_ARG);
+
+ db = smb_lgrp_db_open(SMB_LGRP_DB_ORD);
+ rc = smb_lgrp_gtbl_lookup(db, SMB_LGRP_GTBL_NAME, &grp,
+ SMB_LGRP_INFO_CMNT, gname);
+ smb_lgrp_db_close(db);
+
+ if (rc == SMB_LGRP_SUCCESS) {
+ *cmnt = grp.sg_cmnt;
+ grp.sg_cmnt = NULL;
+ smb_lgrp_free(&grp);
+ }
+
+ return (rc);
+}
+
+
+/*
+ * smb_lgrp_setpriv
+ *
+ * Enable/disable the specified privilge for the group
+ */
+int
+smb_lgrp_setpriv(char *gname, uint8_t priv_lid, boolean_t enable)
+{
+ sqlite *db;
+ int rc;
+
+ (void) trim_whitespace(gname);
+ if (!smb_lgrp_chkname(gname))
+ return (SMB_LGRP_INVALID_NAME);
+
+ if ((priv_lid < SE_MIN_LUID) || (priv_lid > SE_MAX_LUID))
+ return (SMB_LGRP_NO_SUCH_PRIV);
+
+ db = smb_lgrp_db_open(SMB_LGRP_DB_ORW);
+ rc = smb_lgrp_gtbl_update_plist(db, gname, priv_lid, enable);
+ smb_lgrp_db_close(db);
+
+ if (enable) {
+ if (rc == SMB_LGRP_PRIV_HELD)
+ rc = SMB_LGRP_SUCCESS;
+ } else {
+ if (rc == SMB_LGRP_PRIV_NOT_HELD)
+ rc = SMB_LGRP_SUCCESS;
+ }
+
+ return (rc);
+}
+
+/*
+ * smb_lgrp_getpriv
+ *
+ * Obtain the status of the specified privilge for the group
+ */
+int
+smb_lgrp_getpriv(char *gname, uint8_t priv_lid, boolean_t *enable)
+{
+ sqlite *db;
+ smb_group_t grp;
+ int rc;
+
+ (void) trim_whitespace(gname);
+ if (!smb_lgrp_chkname(gname))
+ return (SMB_LGRP_INVALID_NAME);
+
+ if ((priv_lid < SE_MIN_LUID) || (priv_lid > SE_MAX_LUID))
+ return (SMB_LGRP_NO_SUCH_PRIV);
+
+ db = smb_lgrp_db_open(SMB_LGRP_DB_ORD);
+ rc = smb_lgrp_gtbl_lookup(db, SMB_LGRP_GTBL_NAME, &grp,
+ SMB_LGRP_INFO_PRIV, gname);
+ smb_lgrp_db_close(db);
+
+ if (rc == SMB_LGRP_SUCCESS) {
+ *enable = (smb_privset_query(grp.sg_privs, priv_lid) == 1);
+ smb_lgrp_free(&grp);
+ }
+
+ return (rc);
+}
+
+/*
+ * smb_lgrp_add_member
+ *
+ * Add the given account to the specified group as its member.
+ */
+int
+smb_lgrp_add_member(char *gname, nt_sid_t *msid, uint16_t sid_type)
+{
+ sqlite *db;
+ smb_gsid_t mid;
+ int rc;
+
+ (void) trim_whitespace(gname);
+ if (!smb_lgrp_chkname(gname))
+ return (SMB_LGRP_INVALID_NAME);
+
+ if (!nt_sid_is_valid(msid))
+ return (SMB_LGRP_INVALID_ARG);
+
+ if (!smb_lgrp_chkmember(sid_type))
+ return (SMB_LGRP_INVALID_MEMBER);
+
+ mid.gs_sid = msid;
+ mid.gs_type = sid_type;
+
+ db = smb_lgrp_db_open(SMB_LGRP_DB_ORW);
+ rc = smb_lgrp_gtbl_update_mlist(db, gname, &mid, SMB_LGRP_DB_ADDMEMBER);
+ smb_lgrp_db_close(db);
+
+ return (rc);
+}
+
+/*
+ * smb_lgrp_del_member
+ *
+ * Delete the specified member from the given group.
+ */
+int
+smb_lgrp_del_member(char *gname, nt_sid_t *msid, uint16_t sid_type)
+{
+ sqlite *db;
+ smb_gsid_t mid;
+ int rc;
+
+ (void) trim_whitespace(gname);
+ if (!smb_lgrp_chkname(gname))
+ return (SMB_LGRP_INVALID_NAME);
+
+ if (!nt_sid_is_valid(msid))
+ return (SMB_LGRP_INVALID_ARG);
+
+ mid.gs_sid = msid;
+ mid.gs_type = sid_type;
+
+ db = smb_lgrp_db_open(SMB_LGRP_DB_ORW);
+ rc = smb_lgrp_gtbl_update_mlist(db, gname, &mid, SMB_LGRP_DB_DELMEMBER);
+ smb_lgrp_db_close(db);
+
+ return (rc);
+}
+
+/*
+ * smb_lgrp_getbyname
+ *
+ * Retrieves the information of the group specified by
+ * the given name.
+ *
+ * Note that this function doesn't allocate the group
+ * structure itself only the fields, so the given grp
+ * pointer has to point to a group structure.
+ * Caller must free the allocated memories for the fields
+ * by calling smb_lgrp_free().
+ */
+int
+smb_lgrp_getbyname(char *gname, smb_group_t *grp)
+{
+ sqlite *db;
+ int rc;
+
+ (void) trim_whitespace(gname);
+ if (!smb_lgrp_chkname(gname))
+ return (SMB_LGRP_INVALID_NAME);
+
+ db = smb_lgrp_db_open(SMB_LGRP_DB_ORD);
+ rc = smb_lgrp_gtbl_lookup(db, SMB_LGRP_GTBL_NAME, grp,
+ SMB_LGRP_INFO_ALL, gname);
+ smb_lgrp_db_close(db);
+
+ return (rc);
+}
+
+/*
+ * smb_lgrp_getbyrid
+ *
+ * Retrieves the information of the group specified by
+ * the given RID and domain type.
+ *
+ * Note that this function doesn't allocate the group
+ * structure itself only the fields, so the given grp
+ * pointer has to point to a group structure.
+ * Caller must free the allocated memories for the fields
+ * by calling smb_lgrp_free().
+ *
+ * If grp is NULL no information would be returned. The
+ * return value of SMB_LGRP_SUCCESS will indicate that a
+ * group with the given information exists.
+ */
+int
+smb_lgrp_getbyrid(uint32_t rid, smb_gdomain_t domtype, smb_group_t *grp)
+{
+ smb_group_t tmpgrp;
+ sqlite *db;
+ int infolvl = SMB_LGRP_INFO_ALL;
+ int rc;
+
+ if (grp == NULL) {
+ grp = &tmpgrp;
+ infolvl = SMB_LGRP_INFO_NONE;
+ }
+
+ db = smb_lgrp_db_open(SMB_LGRP_DB_ORD);
+ rc = smb_lgrp_gtbl_lookup(db, SMB_LGRP_GTBL_SIDRID, grp, infolvl,
+ rid, domtype);
+ smb_lgrp_db_close(db);
+
+ return (rc);
+}
+
+/*
+ * smb_lgrp_numbydomain
+ *
+ * Returns the number of groups in the given domain in the
+ * arg 'count'
+ */
+int
+smb_lgrp_numbydomain(smb_gdomain_t dom_type, int *count)
+{
+ sqlite *db;
+ int dom_idx;
+ int rc;
+
+ switch (dom_type) {
+ case SMB_LGRP_LOCAL:
+ dom_idx = SMB_LGRP_LOCAL_IDX;
+ break;
+ case SMB_LGRP_BUILTIN:
+ dom_idx = SMB_LGRP_BUILTIN_IDX;
+ break;
+ default:
+ *count = 0;
+ return (SMB_LGRP_INVALID_ARG);
+ }
+
+ db = smb_lgrp_db_open(SMB_LGRP_DB_ORD);
+ rc = smb_lgrp_gtbl_count(db, dom_idx, count);
+ smb_lgrp_db_close(db);
+
+ return (rc);
+}
+
+/*
+ * smb_lgrp_numbydomain
+ *
+ * Returns the number of groups which have the given SID
+ * as a member.
+ */
+int
+smb_lgrp_numbymember(nt_sid_t *msid, int *count)
+{
+ smb_giter_t gi;
+ smb_group_t grp;
+ int rc;
+
+ *count = 0;
+ rc = smb_lgrp_iteropen(&gi);
+ if (rc != SMB_LGRP_SUCCESS)
+ return (rc);
+
+ while (smb_lgrp_iterate(&gi, &grp) == SMB_LGRP_SUCCESS) {
+ if (smb_lgrp_is_member(&grp, msid))
+ (*count)++;
+ smb_lgrp_free(&grp);
+ }
+ smb_lgrp_iterclose(&gi);
+ return (SMB_LGRP_SUCCESS);
+}
+
+/*
+ * smb_lgrp_free
+ *
+ * Frees the allocated memory for the fields of the given
+ * group structure. Note that this function doesn't free
+ * the group itself.
+ */
+void
+smb_lgrp_free(smb_group_t *grp)
+{
+ int i;
+
+ if (grp == NULL)
+ return;
+
+ free(grp->sg_name);
+ free(grp->sg_cmnt);
+ free(grp->sg_id.gs_sid);
+ smb_privset_free(grp->sg_privs);
+
+ for (i = 0; i < grp->sg_nmembers; i++)
+ free(grp->sg_members[i].gs_sid);
+ free(grp->sg_members);
+}
+
+/*
+ * smb_lgrp_iteropen
+ *
+ * Initializes the given group iterator by opening
+ * the group database and creating a virtual machine
+ * for iteration.
+ */
+int
+smb_lgrp_iteropen(smb_giter_t *iter)
+{
+ char *sql;
+ char *errmsg = NULL;
+ int rc = SMB_LGRP_SUCCESS;
+
+ assert(iter);
+
+ bzero(iter, sizeof (smb_giter_t));
+
+ sql = sqlite_mprintf("SELECT * FROM groups");
+ if (sql == NULL)
+ return (SMB_LGRP_NO_MEMORY);
+
+ iter->sgi_db = smb_lgrp_db_open(SMB_LGRP_DB_ORD);
+ if (iter->sgi_db == NULL) {
+ sqlite_freemem(sql);
+ return (SMB_LGRP_DBOPEN_FAILED);
+ }
+
+ rc = sqlite_compile(iter->sgi_db, sql, NULL, &iter->sgi_vm, &errmsg);
+ sqlite_freemem(sql);
+
+ if (rc != SQLITE_OK) {
+ syslog(LOG_DEBUG, "failed to create a VM (%s)",
+ NULL_MSGCHK(errmsg));
+ rc = SMB_LGRP_DB_ERROR;
+ }
+
+ return (rc);
+}
+
+/*
+ * smb_lgrp_iterclose
+ *
+ * Closes the given group iterator.
+ */
+void
+smb_lgrp_iterclose(smb_giter_t *iter)
+{
+ char *errmsg = NULL;
+ int rc;
+
+ assert(iter);
+
+ rc = sqlite_finalize(iter->sgi_vm, &errmsg);
+ if (rc != SQLITE_OK) {
+ syslog(LOG_DEBUG, "failed to destroy a VM (%s)",
+ NULL_MSGCHK(errmsg));
+ }
+
+ smb_lgrp_db_close(iter->sgi_db);
+}
+
+/*
+ * smb_lgrp_iterate
+ *
+ * Iterate through group database
+ * Group information is returned in provided group structure.
+ *
+ * Note that this function doesn't allocate the group
+ * structure itself only the fields, so the given grp
+ * pointer has to point to a group structure.
+ * Caller must free the allocated memories for the fields
+ * by calling smb_lgrp_free().
+ */
+int
+smb_lgrp_iterate(smb_giter_t *iter, smb_group_t *grp)
+{
+ const char **values;
+ int ncol;
+ int rc;
+ int i;
+
+ if (iter->sgi_vm == NULL || iter->sgi_db == NULL)
+ return (SMB_LGRP_INVALID_ARG);
+
+ bzero(grp, sizeof (smb_group_t));
+ rc = sqlite_step(iter->sgi_vm, &ncol, &values, NULL);
+ if (rc == SQLITE_DONE)
+ return (SMB_LGRP_NO_MORE);
+
+ if (rc != SQLITE_ROW)
+ return (SMB_LGRP_DBEXEC_FAILED);
+
+ if (ncol != SMB_LGRP_GTBL_NCOL)
+ return (SMB_LGRP_DB_ERROR);
+
+ for (i = 0; i < ncol; i++) {
+ if (values[i] == NULL)
+ return (SMB_LGRP_DB_ERROR);
+ }
+
+ return (smb_lgrp_decode(grp, (char **)values, SMB_LGRP_INFO_ALL,
+ iter->sgi_db));
+}
+
+/*
+ * smb_lgrp_is_member
+ *
+ * Check to see if the specified account is a member of
+ * the given group.
+ */
+boolean_t
+smb_lgrp_is_member(smb_group_t *grp, nt_sid_t *sid)
+{
+ int i;
+
+ if (grp == NULL || grp->sg_members == NULL || sid == NULL)
+ return (B_FALSE);
+
+ for (i = 0; i < grp->sg_nmembers; i++) {
+ if (nt_sid_is_equal(grp->sg_members[i].gs_sid, sid))
+ return (B_TRUE);
+ }
+
+ return (B_FALSE);
+}
+
+/*
+ * smb_lgrp_strerror
+ *
+ * Returns a text for the given group error code.
+ */
+char *
+smb_lgrp_strerror(int errno)
+{
+ switch (errno) {
+ case SMB_LGRP_SUCCESS:
+ return (dgettext(TEXT_DOMAIN, "success"));
+ case SMB_LGRP_INVALID_ARG:
+ return (dgettext(TEXT_DOMAIN, "invalid argument"));
+ case SMB_LGRP_INVALID_MEMBER:
+ return (dgettext(TEXT_DOMAIN, "invalid member type"));
+ case SMB_LGRP_INVALID_NAME:
+ return (dgettext(TEXT_DOMAIN, "invalid name"));
+ case SMB_LGRP_NOT_FOUND:
+ return (dgettext(TEXT_DOMAIN, "group not found"));
+ case SMB_LGRP_EXISTS:
+ return (dgettext(TEXT_DOMAIN, "group exists"));
+ case SMB_LGRP_NO_SID:
+ return (dgettext(TEXT_DOMAIN, "cannot obtain a SID"));
+ case SMB_LGRP_NO_LOCAL_SID:
+ return (dgettext(TEXT_DOMAIN, "cannot get the machine SID"));
+ case SMB_LGRP_SID_NOTLOCAL:
+ return (dgettext(TEXT_DOMAIN, "not a local SID"));
+ case SMB_LGRP_WKSID:
+ return (dgettext(TEXT_DOMAIN,
+ "operation not permitted on well-known accounts"));
+ case SMB_LGRP_NO_MEMORY:
+ return (dgettext(TEXT_DOMAIN, "not enough memory"));
+ case SMB_LGRP_DB_ERROR:
+ return (dgettext(TEXT_DOMAIN, "database operation error"));
+ case SMB_LGRP_DBINIT_ERROR:
+ return (dgettext(TEXT_DOMAIN, "database initialization error"));
+ case SMB_LGRP_INTERNAL_ERROR:
+ return (dgettext(TEXT_DOMAIN, "internal error"));
+ case SMB_LGRP_MEMBER_IN_GROUP:
+ return (dgettext(TEXT_DOMAIN, "member already in the group"));
+ case SMB_LGRP_MEMBER_NOT_IN_GROUP:
+ return (dgettext(TEXT_DOMAIN, "not a member"));
+ case SMB_LGRP_NO_SUCH_PRIV:
+ return (dgettext(TEXT_DOMAIN, "no such privilege"));
+ case SMB_LGRP_NO_SUCH_DOMAIN:
+ return (dgettext(TEXT_DOMAIN, "no such domain SID"));
+ case SMB_LGRP_PRIV_HELD:
+ return (dgettext(TEXT_DOMAIN, "already holds the privilege"));
+ case SMB_LGRP_PRIV_NOT_HELD:
+ return (dgettext(TEXT_DOMAIN, "privilege not held"));
+ case SMB_LGRP_BAD_DATA:
+ return (dgettext(TEXT_DOMAIN, "bad data"));
+ case SMB_LGRP_NO_MORE:
+ return (dgettext(TEXT_DOMAIN, "no more groups"));
+ case SMB_LGRP_DBOPEN_FAILED:
+ return (dgettext(TEXT_DOMAIN, "failed openning database"));
+ case SMB_LGRP_DBEXEC_FAILED:
+ return (dgettext(TEXT_DOMAIN,
+ "failed executing database operation"));
+ case SMB_LGRP_DBINIT_FAILED:
+ return (dgettext(TEXT_DOMAIN, "failed initializing database"));
+ case SMB_LGRP_DOMLKP_FAILED:
+ return (dgettext(TEXT_DOMAIN, "failed getting the domain SID"));
+ case SMB_LGRP_DOMINS_FAILED:
+ return (dgettext(TEXT_DOMAIN,
+ "failed inserting the domain SID"));
+ case SMB_LGRP_INSERT_FAILED:
+ return (dgettext(TEXT_DOMAIN, "failed inserting the group"));
+ case SMB_LGRP_DELETE_FAILED:
+ return (dgettext(TEXT_DOMAIN, "failed deleting the group"));
+ case SMB_LGRP_UPDATE_FAILED:
+ return (dgettext(TEXT_DOMAIN, "failed updating the group"));
+ case SMB_LGRP_LOOKUP_FAILED:
+ return (dgettext(TEXT_DOMAIN, "failed looking up the group"));
+ }
+
+ return (dgettext(TEXT_DOMAIN, "unknown error code"));
+}
+
+/*
+ * smb_lgrp_chkmember
+ *
+ * Determines valid account types for being member of
+ * a local group.
+ *
+ * Currently, we just support users as valid members.
+ */
+static boolean_t
+smb_lgrp_chkmember(uint16_t sid_type)
+{
+ return (sid_type == SidTypeUser);
+}
+
+/*
+ * smb_lgrp_start
+ *
+ * Initializes the library private global variables.
+ * If the database doesn't exist, it'll create it and adds the
+ * predefined builtin groups.
+ */
+int
+smb_lgrp_start(void)
+{
+ char *supported_bg[] =
+ {"Administrators", "Backup Operators", "Power Users"};
+ well_known_account_t *wka;
+ int rc, i, ngrp;
+ char *lsid_str;
+
+ (void) mutex_init(&smb_lgrp_lsid_mtx, USYNC_THREAD, NULL);
+ (void) mutex_lock(&smb_lgrp_lsid_mtx);
+ lsid_str = smb_config_get_localsid();
+ if (lsid_str == NULL) {
+ (void) mutex_unlock(&smb_lgrp_lsid_mtx);
+ return (SMB_LGRP_NO_LOCAL_SID);
+ }
+
+ smb_lgrp_lsid = nt_sid_strtosid(lsid_str);
+ free(lsid_str);
+ if (!nt_sid_is_valid(smb_lgrp_lsid)) {
+ free(smb_lgrp_lsid);
+ smb_lgrp_lsid = NULL;
+ (void) mutex_unlock(&smb_lgrp_lsid_mtx);
+ return (SMB_LGRP_NO_LOCAL_SID);
+ }
+
+ rc = smb_lgrp_db_init();
+ if (rc != SMB_LGRP_SUCCESS) {
+ free(smb_lgrp_lsid);
+ smb_lgrp_lsid = NULL;
+ (void) mutex_unlock(&smb_lgrp_lsid_mtx);
+ return (rc);
+ }
+ (void) mutex_unlock(&smb_lgrp_lsid_mtx);
+
+ ngrp = sizeof (supported_bg) / sizeof (supported_bg[0]);
+ for (i = 0; i < ngrp; i++) {
+ wka = nt_builtin_lookup(supported_bg[i]);
+ if (wka == NULL)
+ continue;
+ rc = smb_lgrp_add(wka->name, wka->desc);
+ if (rc != SMB_LGRP_SUCCESS)
+ syslog(LOG_DEBUG, "failed to add %s", wka->name);
+ }
+
+ return (SMB_LGRP_SUCCESS);
+}
+
+/*
+ * smb_lgrp_stop
+ *
+ * Unintialize the library global private variables.
+ */
+void
+smb_lgrp_stop(void)
+{
+ (void) mutex_lock(&smb_lgrp_lsid_mtx);
+ free(smb_lgrp_lsid);
+ smb_lgrp_lsid = NULL;
+ (void) mutex_unlock(&smb_lgrp_lsid_mtx);
+ (void) mutex_destroy(&smb_lgrp_lsid_mtx);
+}
+
+/*
+ * smb_lgrp_db_open
+ *
+ * Opens group database with the given mode.
+ */
+static sqlite *
+smb_lgrp_db_open(int mode)
+{
+ sqlite *db;
+ char *errmsg = NULL;
+
+ db = sqlite_open(SMB_LGRP_DB_NAME, mode, &errmsg);
+ if (db == NULL) {
+ syslog(LOG_ERR, "failed to open group database (%s)",
+ NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ }
+
+ return (db);
+}
+
+/*
+ * smb_lgrp_db_close
+ *
+ * Closes the given database handle
+ */
+static void
+smb_lgrp_db_close(sqlite *db)
+{
+ if (db) {
+ sqlite_close(db);
+ }
+}
+
+/*
+ * smb_lgrp_db_init
+ *
+ * Creates the group database based on the defined SQL statement.
+ * It also initializes db_info and domain tables.
+ */
+static int
+smb_lgrp_db_init(void)
+{
+ int dbrc = SQLITE_OK;
+ int rc = SMB_LGRP_SUCCESS;
+ sqlite *db = NULL;
+ char *errmsg = NULL;
+
+ db = sqlite_open(SMB_LGRP_DB_NAME, 0600, &errmsg);
+ if (db == NULL) {
+ syslog(LOG_ERR, "failed to create group database (%s)",
+ NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ return (SMB_LGRP_DBOPEN_FAILED);
+ }
+
+ sqlite_busy_timeout(db, SMB_LGRP_DB_TIMEOUT);
+ dbrc = sqlite_exec(db, "BEGIN TRANSACTION;", NULL, NULL, &errmsg);
+ if (dbrc != SQLITE_OK) {
+ syslog(LOG_DEBUG, "failed to begin database transaction (%s)",
+ NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ sqlite_close(db);
+ return (SMB_LGRP_DBEXEC_FAILED);
+ }
+
+ switch (sqlite_exec(db, SMB_LGRP_DB_SQL, NULL, NULL, &errmsg)) {
+ case SQLITE_ERROR:
+ /*
+ * This is the normal situation: CREATE probably failed because
+ * tables already exist. It may indicate an error in SQL as well
+ * but we cannot tell.
+ */
+ sqlite_freemem(errmsg);
+ dbrc = sqlite_exec(db, "ROLLBACK TRANSACTION", NULL, NULL,
+ &errmsg);
+ rc = SMB_LGRP_SUCCESS;
+ break;
+
+ case SQLITE_OK:
+ dbrc = sqlite_exec(db, "COMMIT TRANSACTION", NULL, NULL,
+ &errmsg);
+ if (dbrc != SQLITE_OK)
+ break;
+ rc = smb_lgrp_dtbl_insert(db, NT_BUILTIN_DOMAIN_SIDSTR,
+ NULL);
+ if (rc == SMB_LGRP_SUCCESS)
+ rc = smb_lgrp_db_setinfo(db);
+ if (rc != SMB_LGRP_SUCCESS) {
+ (void) sqlite_close(db);
+ (void) unlink(SMB_LGRP_DB_NAME);
+ return (rc);
+ }
+ break;
+
+ default:
+ syslog(LOG_ERR,
+ "failed to initialize group database (%s)", errmsg);
+ sqlite_freemem(errmsg);
+ dbrc = sqlite_exec(db, "ROLLBACK TRANSACTION", NULL, NULL,
+ &errmsg);
+ rc = SMB_LGRP_DBINIT_FAILED;
+ break;
+ }
+
+ if (dbrc != SQLITE_OK) {
+ /* this is bad - database may be left in a locked state */
+ syslog(LOG_DEBUG, "failed to close a transaction (%s)",
+ NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ }
+
+ (void) sqlite_close(db);
+ return (rc);
+}
+
+/*
+ * smb_lgrp_gtbl_lookup
+ *
+ * This is a flexible lookup function for the group database.
+ * The key type can be specified by the 'key' arg and the actual key
+ * values can be passed after the 'infolvl' arg. 'infolvl' arg specifies
+ * what information items for the specified group is needed.
+ *
+ * Note that the function assumes the given key is unique and only
+ * specifies one or 0 group. The keys that are supported now are
+ * the group name and the group SID
+ *
+ * Note that this function doesn't allocate the group
+ * structure itself only the fields, so the given grp
+ * pointer has to point to a group structure.
+ * Caller must free the allocated memories for the fields
+ * by calling smb_lgrp_free().
+ */
+static int
+smb_lgrp_gtbl_lookup(sqlite *db, int key, smb_group_t *grp, int infolvl, ...)
+{
+ char *errmsg = NULL;
+ char *sql;
+ char **result;
+ int nrow, ncol;
+ int rc, dom_idx;
+ smb_group_t kgrp;
+ va_list ap;
+
+ if (db == NULL)
+ return (SMB_LGRP_DBOPEN_FAILED);
+
+ bzero(grp, sizeof (smb_group_t));
+ va_start(ap, infolvl);
+
+ switch (key) {
+ case SMB_LGRP_GTBL_NAME:
+ kgrp.sg_name = va_arg(ap, char *);
+ sql = sqlite_mprintf("SELECT * FROM groups WHERE name = '%s'",
+ kgrp.sg_name);
+ break;
+
+ case SMB_LGRP_GTBL_SIDRID:
+ kgrp.sg_rid = va_arg(ap, uint32_t);
+ kgrp.sg_domain = va_arg(ap, smb_gdomain_t);
+ dom_idx = (kgrp.sg_domain == SMB_LGRP_LOCAL)
+ ? SMB_LGRP_LOCAL_IDX : SMB_LGRP_BUILTIN_IDX;
+ sql = sqlite_mprintf("SELECT * FROM groups"
+ "WHERE (sid_idx = %d) AND (sid_rid = %u)",
+ dom_idx, kgrp.sg_rid);
+ break;
+
+ default:
+ va_end(ap);
+ return (SMB_LGRP_INVALID_ARG);
+ }
+
+ va_end(ap);
+ if (sql == NULL)
+ return (SMB_LGRP_NO_MEMORY);
+
+ rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
+ sqlite_freemem(sql);
+
+ if (rc != SQLITE_OK) {
+ syslog(LOG_DEBUG, "failed to lookup (%s)", NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ return (SMB_LGRP_LOOKUP_FAILED);
+ }
+
+ if (nrow == 0) {
+ /* group not found */
+ sqlite_free_table(result);
+ return (SMB_LGRP_NOT_FOUND);
+ }
+
+ if (nrow != 1 || ncol != SMB_LGRP_GTBL_NCOL) {
+ sqlite_free_table(result);
+ return (SMB_LGRP_DB_ERROR);
+ }
+
+ rc = smb_lgrp_decode(grp, &result[SMB_LGRP_GTBL_NCOL], infolvl, db);
+ sqlite_free_table(result);
+ return (rc);
+}
+
+/*
+ * smb_lgrp_gtbl_exists
+ *
+ * Checks to see if the given group exists or not.
+ */
+static boolean_t
+smb_lgrp_gtbl_exists(sqlite *db, char *gname)
+{
+ char *errmsg = NULL;
+ char *sql;
+ char **result;
+ int nrow, ncol;
+ int rc;
+
+ if (db == NULL)
+ return (NULL);
+
+ sql = sqlite_mprintf("SELECT name FROM groups WHERE name = '%s'",
+ gname);
+ rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
+ sqlite_freemem(sql);
+
+ if (rc != SQLITE_OK) {
+ syslog(LOG_DEBUG, "failed to lookup %s (%s)",
+ gname, NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ return (B_FALSE);
+ }
+
+ sqlite_free_table(result);
+ return (nrow != 0);
+}
+
+/*
+ * smb_lgrp_gtbl_count
+ *
+ * Counts the number of groups in the domain specified by
+ * 'dom_idx'
+ */
+static int
+smb_lgrp_gtbl_count(sqlite *db, int dom_idx, int *count)
+{
+ char *errmsg = NULL;
+ char *sql;
+ char **result;
+ int nrow, ncol;
+ int rc;
+
+ *count = 0;
+ if (db == NULL)
+ return (SMB_LGRP_DBOPEN_FAILED);
+
+ sql = sqlite_mprintf("SELECT sid_idx FROM groups WHERE sid_idx = %d",
+ dom_idx);
+ rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
+ sqlite_freemem(sql);
+
+ if (rc != SQLITE_OK) {
+ syslog(LOG_DEBUG, "failed to count (%s)", NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ return (SMB_LGRP_LOOKUP_FAILED);
+ }
+
+ sqlite_free_table(result);
+ if (ncol != 1)
+ return (SMB_LGRP_DB_ERROR);
+
+ *count = nrow;
+ return (SMB_LGRP_SUCCESS);
+}
+
+/*
+ * smb_lgrp_gtbl_insert
+ *
+ * Insert a record for the given group in the group database.
+ *
+ * NOTE: this function assumes that this group has no members
+ * at this time.
+ */
+static int
+smb_lgrp_gtbl_insert(sqlite *db, smb_group_t *grp)
+{
+ smb_lgpid_t privs[SE_MAX_LUID + 1];
+ smb_lgplist_t plist;
+ char *errmsg = NULL;
+ char *sql;
+ int dom_idx;
+ int rc;
+
+ if (db == NULL)
+ return (SMB_LGRP_DBOPEN_FAILED);
+
+ dom_idx = (grp->sg_domain == SMB_LGRP_LOCAL)
+ ? SMB_LGRP_LOCAL_IDX : SMB_LGRP_BUILTIN_IDX;
+
+ plist.p_cnt = SE_MAX_LUID;
+ plist.p_ids = privs;
+ smb_lgrp_encode_privset(grp, &plist);
+
+ sql = sqlite_mprintf("INSERT INTO groups"
+ "(name, sid_idx, sid_rid, sid_type, sid_attrs, comment, "
+ "n_privs, privs, n_members, members) "
+ "VALUES('%s', %u, %u, %u, %u, '%q', %u, '%q', %u, '%q')",
+ grp->sg_name, dom_idx, grp->sg_rid, grp->sg_id.gs_type,
+ grp->sg_attr, (grp->sg_cmnt) ? grp->sg_cmnt : "",
+ plist.p_cnt, (char *)plist.p_ids, 0, "");
+
+ if (sql == NULL)
+ return (SMB_LGRP_NO_MEMORY);
+
+ rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
+ sqlite_freemem(sql);
+
+ if (rc != SQLITE_OK) {
+ syslog(LOG_DEBUG, "failed to insert %s (%s)",
+ grp->sg_name, NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ rc = SMB_LGRP_INSERT_FAILED;
+ } else {
+ rc = SMB_LGRP_SUCCESS;
+ }
+
+ return (rc);
+}
+
+/*
+ * smb_lgrp_gtbl_delete
+ *
+ * Removes the specified group from the database
+ */
+static int
+smb_lgrp_gtbl_delete(sqlite *db, char *gname)
+{
+ char *errmsg = NULL;
+ char *sql;
+ int rc;
+
+ if (db == NULL)
+ return (SMB_LGRP_DBOPEN_FAILED);
+
+ sql = sqlite_mprintf("DELETE FROM groups WHERE name = '%s'", gname);
+ if (sql == NULL)
+ return (SMB_LGRP_NO_MEMORY);
+
+ rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
+ sqlite_freemem(sql);
+
+ if (rc != SQLITE_OK) {
+ syslog(LOG_DEBUG, "failed to delete %s (%s)",
+ gname, NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ rc = SMB_LGRP_DELETE_FAILED;
+ } else {
+ rc = SMB_LGRP_SUCCESS;
+ }
+
+ return (rc);
+}
+
+/*
+ * smb_lgrp_gtbl_update
+ *
+ * Updates the specified group information, the supported items
+ * are group name and comment
+ */
+static int
+smb_lgrp_gtbl_update(sqlite *db, char *gname, smb_group_t *grp, int col_id)
+{
+ char *errmsg = NULL;
+ char *sql;
+ int rc;
+
+ if (db == NULL)
+ return (SMB_LGRP_DBOPEN_FAILED);
+
+ /* UPDATE doesn't fail if gname doesn't exist */
+ if (!smb_lgrp_gtbl_exists(db, gname))
+ return (SMB_LGRP_NOT_FOUND);
+
+ switch (col_id) {
+ case SMB_LGRP_GTBL_NAME:
+ if (smb_lgrp_gtbl_exists(db, grp->sg_name))
+ return (SMB_LGRP_EXISTS);
+ sql = sqlite_mprintf("UPDATE groups SET name = '%s' "
+ "WHERE name = '%s'", grp->sg_name, gname);
+ break;
+
+ case SMB_LGRP_GTBL_CMNT:
+ sql = sqlite_mprintf("UPDATE groups SET comment = '%q' "
+ "WHERE name = '%s'", grp->sg_cmnt, gname);
+ break;
+
+ default:
+ return (SMB_LGRP_INVALID_ARG);
+ }
+
+ if (sql == NULL)
+ return (SMB_LGRP_NO_MEMORY);
+
+ rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
+ sqlite_freemem(sql);
+
+ if (rc != SQLITE_OK) {
+ syslog(LOG_DEBUG, "failed to update %s (%s)",
+ gname, NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ rc = SMB_LGRP_UPDATE_FAILED;
+ } else {
+ rc = SMB_LGRP_SUCCESS;
+ }
+
+ return (rc);
+}
+
+/*
+ * smb_lgrp_gtbl_update_mlist
+ *
+ * Adds/removes the specified member from the member list of the
+ * given group
+ */
+static int
+smb_lgrp_gtbl_update_mlist(sqlite *db, char *gname, smb_gsid_t *member,
+ int flags)
+{
+ smb_lgmlist_t new_members;
+ smb_lgmlist_t members;
+ smb_lgmid_t mid;
+ char *errmsg = NULL;
+ char *sql;
+ char **result;
+ int nrow, ncol;
+ int rc;
+
+ if (db == NULL)
+ return (SMB_LGRP_DBOPEN_FAILED);
+
+ sql = sqlite_mprintf("SELECT n_members, members FROM groups "
+ "WHERE name = '%s'", gname);
+
+ if (sql == NULL)
+ return (SMB_LGRP_NO_MEMORY);
+
+ rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
+ sqlite_freemem(sql);
+
+ if (rc != SQLITE_OK) {
+ syslog(LOG_DEBUG, "failed to lookup %s (%s)",
+ gname, NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ return (SMB_LGRP_LOOKUP_FAILED);
+ }
+
+ if (nrow == 0) {
+ /* group not found */
+ sqlite_free_table(result);
+ return (SMB_LGRP_NOT_FOUND);
+ }
+
+ if (nrow != 1 || ncol != 2) {
+ sqlite_free_table(result);
+ return (SMB_LGRP_DB_ERROR);
+ }
+
+ bzero(&mid, sizeof (mid));
+ mid.m_type = member->gs_type;
+ rc = smb_lgrp_dtbl_getidx(db, member->gs_sid, mid.m_type,
+ &mid.m_idx, &mid.m_rid);
+ if (rc != SMB_LGRP_SUCCESS) {
+ sqlite_free_table(result);
+ return (rc);
+ }
+
+ members.m_cnt = atoi(result[2]);
+ members.m_ids = result[3];
+
+ switch (flags) {
+ case SMB_LGRP_DB_ADDMEMBER:
+ rc = smb_lgrp_mlist_add(&members, &mid, &new_members);
+ break;
+ case SMB_LGRP_DB_DELMEMBER:
+ rc = smb_lgrp_mlist_del(&members, &mid, &new_members);
+ break;
+ default:
+ rc = SMB_LGRP_INVALID_ARG;
+ }
+
+ sqlite_free_table(result);
+ if (rc != SMB_LGRP_SUCCESS)
+ return (rc);
+
+ sql = sqlite_mprintf("UPDATE groups SET n_members = %u, members = '%s'"
+ " WHERE name = '%s'", new_members.m_cnt, new_members.m_ids, gname);
+
+ free(new_members.m_ids);
+
+ if (sql == NULL)
+ return (SMB_LGRP_NO_MEMORY);
+
+ rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
+ sqlite_freemem(sql);
+
+ if (rc != SQLITE_OK) {
+ syslog(LOG_DEBUG, "failed to update %s (%s)", gname,
+ NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ rc = SMB_LGRP_UPDATE_FAILED;
+ } else {
+ rc = SMB_LGRP_SUCCESS;
+ }
+
+ return (rc);
+}
+
+/*
+ * smb_lgrp_gtbl_update_plist
+ *
+ * Adds/removes the specified privilege from the privilege list of the
+ * given group
+ */
+static int
+smb_lgrp_gtbl_update_plist(sqlite *db, char *gname, uint8_t priv_id,
+ boolean_t enable)
+{
+ char *sql;
+ char *errmsg = NULL;
+ char **result;
+ int nrow, ncol;
+ int rc;
+ smb_lgplist_t privs;
+ smb_lgplist_t new_privs;
+
+ if (db == NULL)
+ return (SMB_LGRP_DBOPEN_FAILED);
+
+ sql = sqlite_mprintf("SELECT n_privs, privs FROM groups "
+ "WHERE name = '%s'", gname);
+
+ if (sql == NULL)
+ return (SMB_LGRP_NO_MEMORY);
+
+ rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
+ sqlite_freemem(sql);
+
+ if (rc != SQLITE_OK) {
+ syslog(LOG_DEBUG, "failed to lookup %s (%s)",
+ gname, NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ return (SMB_LGRP_LOOKUP_FAILED);
+ }
+
+ if (nrow == 0) {
+ /* group not found */
+ sqlite_free_table(result);
+ return (SMB_LGRP_NOT_FOUND);
+ }
+
+ if (nrow != 1 || ncol != 2) {
+ sqlite_free_table(result);
+ return (SMB_LGRP_DB_ERROR);
+ }
+
+ privs.p_cnt = atoi(result[2]);
+ privs.p_ids = (smb_lgpid_t *)result[3];
+
+ if (enable)
+ rc = smb_lgrp_plist_add(&privs, priv_id, &new_privs);
+ else
+ rc = smb_lgrp_plist_del(&privs, priv_id, &new_privs);
+
+ sqlite_free_table(result);
+ if (rc != SMB_LGRP_SUCCESS)
+ return (rc);
+
+ sql = sqlite_mprintf("UPDATE groups SET n_privs = %u, privs = '%q'"
+ " WHERE name = '%s'", new_privs.p_cnt, (char *)new_privs.p_ids,
+ gname);
+
+ free(new_privs.p_ids);
+
+ if (sql == NULL)
+ return (SMB_LGRP_NO_MEMORY);
+
+ rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
+ sqlite_freemem(sql);
+
+ if (rc != SQLITE_OK) {
+ syslog(LOG_DEBUG, "failed to update %s (%s)",
+ gname, NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ rc = SMB_LGRP_UPDATE_FAILED;
+ } else {
+ rc = SMB_LGRP_SUCCESS;
+ }
+
+ return (rc);
+}
+
+/*
+ * smb_lgrp_dtbl_insert
+ *
+ * Inserts the specified domain SID in the dmain table.
+ * Upon successful insert the index will be returned in
+ * 'dom_idx' arg.
+ */
+static int
+smb_lgrp_dtbl_insert(sqlite *db, char *dom_sid, uint32_t *dom_idx)
+{
+ char *errmsg = NULL;
+ char *sql;
+ int rc;
+
+ sql = sqlite_mprintf("INSERT INTO domains (dom_sid, dom_cnt)"
+ " VALUES('%s', 1);", dom_sid);
+ if (sql == NULL)
+ return (SMB_LGRP_NO_MEMORY);
+
+ rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
+ sqlite_freemem(sql);
+
+ if (rc != SQLITE_OK) {
+ syslog(LOG_DEBUG, "failed to insert domain SID (%s)",
+ NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ return (SMB_LGRP_DOMINS_FAILED);
+ }
+
+ if (dom_idx)
+ *dom_idx = sqlite_last_insert_rowid(db);
+ return (SMB_LGRP_SUCCESS);
+}
+
+/*
+ * smb_lgrp_dtbl_getidx
+ *
+ * Searches the domain table for the domain SID of the
+ * given member SID. If it finds the domain SID it'll
+ * return the index and the RID, otherwise it'll insert
+ * it in the domain table as a new SID.
+ */
+static int
+smb_lgrp_dtbl_getidx(sqlite *db, nt_sid_t *sid, uint16_t sid_type,
+ uint32_t *dom_idx, uint32_t *rid)
+{
+ char sidstr[NT_SID_FMTBUF_SIZE];
+ nt_sid_t *dom_sid;
+ char **result;
+ int nrow, ncol;
+ char *errmsg = NULL;
+ char *sql;
+ int rc;
+
+ if (nt_sid_is_indomain(smb_lgrp_lsid, sid)) {
+ /* This is a local SID */
+ int id_type = (sid_type == SidTypeUser)
+ ? SMB_IDMAP_USER : SMB_IDMAP_GROUP;
+ *dom_idx = SMB_LGRP_LOCAL_IDX;
+ if (smb_idmap_getid(sid, rid, &id_type) != IDMAP_SUCCESS)
+ return (SMB_LGRP_INTERNAL_ERROR);
+ }
+
+ dom_sid = nt_sid_dup(sid);
+ if (dom_sid == NULL)
+ return (SMB_LGRP_NO_MEMORY);
+
+ (void) nt_sid_split(dom_sid, rid);
+ nt_sid_format2(dom_sid, sidstr);
+ free(dom_sid);
+
+ sql = sqlite_mprintf("SELECT dom_idx FROM domains WHERE dom_sid = '%s'",
+ sidstr);
+ if (sql == NULL)
+ return (SMB_LGRP_NO_MEMORY);
+
+ rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
+ sqlite_freemem(sql);
+
+ if (rc != SQLITE_OK) {
+ syslog(LOG_DEBUG, "failed to lookup domain SID (%s)",
+ NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ return (SMB_LGRP_DOMLKP_FAILED);
+ }
+
+ switch (nrow) {
+ case 0:
+ /* new domain SID; insert it into the domains table */
+ sqlite_free_table(result);
+ return (smb_lgrp_dtbl_insert(db, sidstr, dom_idx));
+
+ case 1:
+ *dom_idx = atoi(result[1]);
+ sqlite_free_table(result);
+ return (SMB_LGRP_SUCCESS);
+ }
+
+ sqlite_free_table(result);
+ return (SMB_LGRP_DB_ERROR);
+}
+
+/*
+ * smb_lgrp_dtbl_getsid
+ *
+ * Searchs the domain table for the given domain index.
+ * Converts the found domain SID to binary format and
+ * returns it in the 'sid' arg.
+ *
+ * Caller must free the returned SID by calling free().
+ */
+static int
+smb_lgrp_dtbl_getsid(sqlite *db, uint32_t dom_idx, nt_sid_t **sid)
+{
+ char **result;
+ int nrow, ncol;
+ char *errmsg = NULL;
+ char *sql;
+ int rc;
+
+ sql = sqlite_mprintf("SELECT dom_sid FROM domains WHERE dom_idx = %u",
+ dom_idx);
+ if (sql == NULL)
+ return (SMB_LGRP_NO_MEMORY);
+
+ rc = sqlite_get_table(db, sql, &result, &nrow, &ncol, &errmsg);
+ sqlite_freemem(sql);
+
+ if (rc != SQLITE_OK) {
+ syslog(LOG_DEBUG, "failed to lookup domain index (%s)",
+ NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ return (SMB_LGRP_DOMLKP_FAILED);
+ }
+
+ switch (nrow) {
+ case 0:
+ rc = SMB_LGRP_NO_SUCH_DOMAIN;
+ break;
+
+ case 1:
+ *sid = nt_sid_strtosid(result[1]);
+ rc = (*sid == NULL)
+ ? SMB_LGRP_INTERNAL_ERROR : SMB_LGRP_SUCCESS;
+ break;
+
+ default:
+ rc = SMB_LGRP_DB_ERROR;
+ break;
+ }
+
+ sqlite_free_table(result);
+ return (rc);
+}
+
+/*
+ * smb_lgrp_db_setinfo
+ *
+ * Initializes the db_info table upon database creation.
+ */
+static int
+smb_lgrp_db_setinfo(sqlite *db)
+{
+ char *errmsg = NULL;
+ char *sql;
+ int rc;
+
+ sql = sqlite_mprintf("INSERT INTO db_info (ver_major, ver_minor,"
+ " magic) VALUES (%d, %d, %u)", SMB_LGRP_DB_VERMAJOR,
+ SMB_LGRP_DB_VERMINOR, SMB_LGRP_DB_MAGIC);
+
+ if (sql == NULL)
+ return (SMB_LGRP_NO_MEMORY);
+
+ rc = sqlite_exec(db, sql, NULL, NULL, &errmsg);
+ sqlite_freemem(sql);
+ if (rc != SQLITE_OK) {
+ syslog(LOG_DEBUG, "failed to insert database information (%s)",
+ NULL_MSGCHK(errmsg));
+ sqlite_freemem(errmsg);
+ rc = SMB_LGRP_DBINIT_ERROR;
+ } else {
+ rc = SMB_LGRP_SUCCESS;
+ }
+
+ return (rc);
+}
+
+/*
+ * smb_lgrp_mlist_add
+ *
+ * Adds the given member (newm) to the input member list (in_members)
+ * if it's not already there. The result list will be returned in
+ * out_members. The caller must free the allocated memory for
+ * out_members by calling free().
+ *
+ * in_members and out_members are hex strings.
+ */
+static int
+smb_lgrp_mlist_add(smb_lgmlist_t *in_members, smb_lgmid_t *newm,
+ smb_lgmlist_t *out_members)
+{
+ char mid_hex[SMB_LGRP_MID_HEXSZ];
+ char *in_list;
+ char *out_list;
+ int in_size;
+ int out_size;
+ int mid_hexsz;
+ int i;
+
+ out_members->m_cnt = 0;
+ out_members->m_ids = NULL;
+
+ bzero(mid_hex, sizeof (mid_hex));
+ mid_hexsz = bintohex((const char *)newm, sizeof (smb_lgmid_t),
+ mid_hex, sizeof (mid_hex));
+
+ /*
+ * Check to see if this is already a group member
+ */
+ in_list = in_members->m_ids;
+ for (i = 0; i < in_members->m_cnt; i++) {
+ if (strncmp(in_list, mid_hex, mid_hexsz) == 0)
+ return (SMB_LGRP_MEMBER_IN_GROUP);
+ in_list += mid_hexsz;
+ }
+
+ in_size = (in_members->m_ids) ? strlen(in_members->m_ids) : 0;
+ out_size = in_size + sizeof (mid_hex) + 1;
+ out_list = malloc(out_size);
+ if (out_list == NULL)
+ return (SMB_LGRP_NO_MEMORY);
+
+ bzero(out_list, out_size);
+ if (in_members->m_ids)
+ (void) strlcpy(out_list, in_members->m_ids, out_size);
+ (void) strcat(out_list, mid_hex);
+
+ out_members->m_cnt = in_members->m_cnt + 1;
+ out_members->m_ids = out_list;
+
+ return (SMB_LGRP_SUCCESS);
+}
+
+/*
+ * smb_lgrp_mlist_del
+ *
+ * Removes the given member (msid) from the input member list
+ * (in_members) if it's already there. The result list will b
+ * returned in out_members. The caller must free the allocated
+ * memory for out_members by calling free().
+ *
+ * in_members and out_members are hex strings.
+ */
+static int
+smb_lgrp_mlist_del(smb_lgmlist_t *in_members, smb_lgmid_t *mid,
+ smb_lgmlist_t *out_members)
+{
+ char mid_hex[SMB_LGRP_MID_HEXSZ];
+ char *in_list;
+ char *out_list;
+ int in_size;
+ int out_size;
+ int mid_hexsz;
+ int out_cnt;
+ int i;
+
+ out_members->m_cnt = 0;
+ out_members->m_ids = NULL;
+
+ if ((in_members == NULL) || (in_members->m_cnt == 0))
+ return (SMB_LGRP_MEMBER_NOT_IN_GROUP);
+
+ in_size = strlen(in_members->m_ids);
+ out_size = in_size + sizeof (mid_hex) + 1;
+ out_list = malloc(out_size);
+ if (out_list == NULL)
+ return (SMB_LGRP_NO_MEMORY);
+
+ *out_list = '\0';
+
+ bzero(mid_hex, sizeof (mid_hex));
+ mid_hexsz = bintohex((const char *)mid, sizeof (smb_lgmid_t),
+ mid_hex, sizeof (mid_hex));
+
+ in_list = in_members->m_ids;
+ for (i = 0, out_cnt = 0; i < in_members->m_cnt; i++) {
+ if (strncmp(in_list, mid_hex, mid_hexsz)) {
+ (void) strncat(out_list, in_list, mid_hexsz);
+ out_cnt++;
+ }
+ in_list += mid_hexsz;
+ }
+
+ if (out_cnt == in_members->m_cnt) {
+ free(out_list);
+ return (SMB_LGRP_MEMBER_NOT_IN_GROUP);
+ }
+
+ out_members->m_cnt = out_cnt;
+ out_members->m_ids = out_list;
+ return (SMB_LGRP_SUCCESS);
+}
+
+/*
+ * smb_lgrp_plist_add
+ *
+ * Adds the given privilege to the input list (in_privs)
+ * if it's not already there. The result list is returned
+ * in out_privs. The caller must free the allocated memory
+ * for out_privs by calling free().
+ */
+static int
+smb_lgrp_plist_add(smb_lgplist_t *in_privs, smb_lgpid_t priv_id,
+ smb_lgplist_t *out_privs)
+{
+ int i, size;
+ smb_lgpid_t *pbuf;
+
+ out_privs->p_cnt = 0;
+ out_privs->p_ids = NULL;
+
+ for (i = 0; i < in_privs->p_cnt; i++) {
+ if (in_privs->p_ids[i] == priv_id)
+ return (SMB_LGRP_PRIV_HELD);
+ }
+
+ size = (in_privs->p_cnt + 1) * sizeof (smb_lgpid_t) + 1;
+ pbuf = malloc(size);
+ if (pbuf == NULL)
+ return (SMB_LGRP_NO_MEMORY);
+
+ bzero(pbuf, size);
+ bcopy(in_privs->p_ids, pbuf, in_privs->p_cnt * sizeof (smb_lgpid_t));
+ pbuf[in_privs->p_cnt] = priv_id;
+
+ out_privs->p_cnt = in_privs->p_cnt + 1;
+ out_privs->p_ids = pbuf;
+
+ return (SMB_LGRP_SUCCESS);
+}
+
+/*
+ * smb_lgrp_plist_del
+ *
+ * Removes the given privilege from the input list (in_privs)
+ * if it's already there. The result list is returned
+ * in out_privs. The caller must free the allocated memory
+ * for out_privs by calling free().
+ */
+static int
+smb_lgrp_plist_del(smb_lgplist_t *in_privs, smb_lgpid_t priv_id,
+ smb_lgplist_t *out_privs)
+{
+ int i, size;
+
+ out_privs->p_cnt = 0;
+ out_privs->p_ids = NULL;
+
+ if ((in_privs == NULL) || (in_privs->p_cnt == 0))
+ return (SMB_LGRP_PRIV_NOT_HELD);
+
+ size = (in_privs->p_cnt - 1) * sizeof (smb_lgpid_t) + 1;
+ out_privs->p_ids = malloc(size);
+ if (out_privs->p_ids == NULL)
+ return (SMB_LGRP_NO_MEMORY);
+
+ bzero(out_privs->p_ids, size);
+
+ for (i = 0; i < in_privs->p_cnt; i++) {
+ if (in_privs->p_ids[i] != priv_id)
+ out_privs->p_ids[out_privs->p_cnt++] =
+ in_privs->p_ids[i];
+ }
+
+ if (out_privs->p_cnt == in_privs->p_cnt) {
+ free(out_privs->p_ids);
+ out_privs->p_cnt = 0;
+ out_privs->p_ids = NULL;
+ return (SMB_LGRP_PRIV_NOT_HELD);
+ }
+
+ return (SMB_LGRP_SUCCESS);
+}
+
+/*
+ * smb_lgrp_encode_privset
+ *
+ * Encodes given privilege set into a buffer to be stored in the group
+ * database. Each entry of the encoded buffer contains the privilege ID
+ * of an enable privilege. The returned buffer is null-terminated.
+ */
+static void
+smb_lgrp_encode_privset(smb_group_t *grp, smb_lgplist_t *plist)
+{
+ smb_privset_t *privs;
+ uint32_t pcnt = plist->p_cnt;
+ int i;
+
+ bzero(plist->p_ids, sizeof (smb_lgpid_t) * plist->p_cnt);
+ plist->p_cnt = 0;
+
+ privs = grp->sg_privs;
+ if ((privs == NULL) || (privs->priv_cnt == 0))
+ return;
+
+ if (pcnt < privs->priv_cnt) {
+ assert(0);
+ }
+
+ for (i = 0; i < privs->priv_cnt; i++) {
+ if (privs->priv[i].attrs == SE_PRIVILEGE_ENABLED) {
+ plist->p_ids[plist->p_cnt++] =
+ (uint8_t)privs->priv[i].luid.lo_part;
+ }
+ }
+}
+
+/*
+ * smb_lgrp_decode_privset
+ *
+ * Decodes the privilege information read from group table
+ * (nprivs, privs) into a binray format specified by the
+ * privilege field of smb_group_t
+ */
+static int
+smb_lgrp_decode_privset(smb_group_t *grp, char *nprivs, char *privs)
+{
+ smb_lgplist_t plist;
+ int i;
+
+ plist.p_cnt = atoi(nprivs);
+ if (strlen(privs) != plist.p_cnt)
+ return (SMB_LGRP_BAD_DATA);
+
+ plist.p_ids = (smb_lgpid_t *)privs;
+ grp->sg_privs = smb_privset_new();
+ if (grp->sg_privs == NULL)
+ return (SMB_LGRP_NO_MEMORY);
+
+ for (i = 0; i < plist.p_cnt; i++)
+ smb_privset_enable(grp->sg_privs, plist.p_ids[i]);
+
+ return (SMB_LGRP_SUCCESS);
+}
+
+/*
+ * smb_lgrp_decode_members
+ *
+ * Decodes the members information read from group table
+ * (nmembers, members) into a binray format specified by the
+ * member fields of smb_group_t
+ */
+static int
+smb_lgrp_decode_members(smb_group_t *grp, char *nmembers, char *members,
+ sqlite *db)
+{
+ smb_lgmid_t *m_ids;
+ smb_lgmid_t *mid;
+ smb_gsid_t *member;
+ int mids_size;
+ int i, rc;
+
+ grp->sg_nmembers = atoi(nmembers);
+ mids_size = grp->sg_nmembers * sizeof (smb_lgmid_t);
+ m_ids = malloc(mids_size);
+ if (m_ids == NULL)
+ return (SMB_LGRP_NO_MEMORY);
+
+ grp->sg_members = malloc(grp->sg_nmembers * sizeof (smb_gsid_t));
+ if (grp->sg_members == NULL) {
+ free(m_ids);
+ return (SMB_LGRP_NO_MEMORY);
+ }
+
+ (void) hextobin(members, strlen(members), (char *)m_ids, mids_size);
+
+ mid = m_ids;
+ member = grp->sg_members;
+ for (i = 0; i < grp->sg_nmembers; i++, mid++, member++) {
+ rc = smb_lgrp_getsid(mid->m_idx, &mid->m_rid, mid->m_type, db,
+ &member->gs_sid);
+ if (rc != SMB_LGRP_SUCCESS) {
+ free(m_ids);
+ return (SMB_LGRP_DB_ERROR);
+ }
+
+ member->gs_type = mid->m_type;
+ }
+
+ free(m_ids);
+ return (SMB_LGRP_SUCCESS);
+}
+
+/*
+ * smb_lgrp_decode
+ *
+ * Fills out the fields of the given group (grp) based in the
+ * string information read from the group table. infolvl determines
+ * which fields are requested and need to be decoded.
+ *
+ * Allocated memories must be freed by calling smb_lgrp_free()
+ * upon successful return.
+ */
+static int
+smb_lgrp_decode(smb_group_t *grp, char **values, int infolvl, sqlite *db)
+{
+ uint32_t sid_idx;
+ int rc;
+
+ if (infolvl == SMB_LGRP_INFO_NONE)
+ return (SMB_LGRP_SUCCESS);
+
+ if (infolvl & SMB_LGRP_INFO_NAME) {
+ grp->sg_name = strdup(values[SMB_LGRP_GTBL_NAME]);
+ if (grp->sg_name == NULL)
+ return (SMB_LGRP_NO_MEMORY);
+ }
+
+ if (infolvl & SMB_LGRP_INFO_CMNT) {
+ grp->sg_cmnt = strdup(values[SMB_LGRP_GTBL_CMNT]);
+ if (grp->sg_cmnt == NULL) {
+ smb_lgrp_free(grp);
+ return (SMB_LGRP_NO_MEMORY);
+ }
+ }
+
+
+ if (infolvl & SMB_LGRP_INFO_SID) {
+ sid_idx = atoi(values[SMB_LGRP_GTBL_SIDIDX]);
+ grp->sg_rid = atoi(values[SMB_LGRP_GTBL_SIDRID]);
+ grp->sg_attr = atoi(values[SMB_LGRP_GTBL_SIDATR]);
+ grp->sg_id.gs_type = atoi(values[SMB_LGRP_GTBL_SIDTYP]);
+ rc = smb_lgrp_getsid(sid_idx, &grp->sg_rid, grp->sg_id.gs_type,
+ db, &grp->sg_id.gs_sid);
+ if (rc != SMB_LGRP_SUCCESS) {
+ smb_lgrp_free(grp);
+ return (SMB_LGRP_NO_MEMORY);
+ }
+ grp->sg_domain = (sid_idx == SMB_LGRP_LOCAL_IDX)
+ ? SMB_LGRP_LOCAL : SMB_LGRP_BUILTIN;
+ }
+
+ if (infolvl & SMB_LGRP_INFO_PRIV) {
+ rc = smb_lgrp_decode_privset(grp, values[SMB_LGRP_GTBL_NPRIVS],
+ values[SMB_LGRP_GTBL_PRIVS]);
+
+ if (rc != SMB_LGRP_SUCCESS) {
+ smb_lgrp_free(grp);
+ return (rc);
+ }
+ }
+
+ if (infolvl & SMB_LGRP_INFO_MEMB) {
+ rc = smb_lgrp_decode_members(grp, values[SMB_LGRP_GTBL_NMEMBS],
+ values[SMB_LGRP_GTBL_MEMBS], db);
+ if (rc != SMB_LGRP_SUCCESS) {
+ smb_lgrp_free(grp);
+ return (rc);
+ }
+ }
+
+ return (SMB_LGRP_SUCCESS);
+}
+
+/*
+ * smb_lgrp_chkname
+ *
+ * User account names are limited to 20 characters and group names are
+ * limited to 256 characters. In addition, account names cannot be terminated
+ * by a period and they cannot include commas or any of the following printable
+ * characters: ", /, \, [, ], :, |, <, >, +, =, ;, ?, *.
+ * Names also cannot include characters in the range 1-31, which are
+ * nonprintable.
+ *
+ * Source: MSDN, description of NetLocalGroupAdd function.
+ */
+static boolean_t
+smb_lgrp_chkname(char *name)
+{
+ static char *invalid_chars =
+ "\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017"
+ "\020\021\022\023\024\025\026\027\030\031"
+ "\"/\\[]:|<>+=;,*?";
+ int len, i;
+
+ if (name == NULL || *name == '\0')
+ return (B_FALSE);
+
+ len = strlen(name);
+ if (len > SMB_LGRP_NAME_MAX)
+ return (B_FALSE);
+
+ if (name[len - 1] == '.')
+ return (B_FALSE);
+
+ for (i = 0; i < len; i++)
+ if (strchr(invalid_chars, name[i]))
+ return (B_FALSE);
+
+ (void) utf8_strlwr(name);
+ return (B_TRUE);
+}
+
+/*
+ * smb_lgrp_set_default_privs
+ *
+ * set default privileges for Administrators and Backup Operators
+ */
+static void
+smb_lgrp_set_default_privs(smb_group_t *grp)
+{
+ if (utf8_strcasecmp(grp->sg_name, "Administrators") == 0) {
+ smb_privset_enable(grp->sg_privs, SE_TAKE_OWNERSHIP_LUID);
+ return;
+ }
+
+ if (utf8_strcasecmp(grp->sg_name, "Backup Operators") == 0) {
+ smb_privset_enable(grp->sg_privs, SE_BACKUP_LUID);
+ smb_privset_enable(grp->sg_privs, SE_RESTORE_LUID);
+ return;
+ }
+}
+
+/*
+ * smb_lgrp_getsid
+ *
+ * Returns a SID based on the provided information
+ * If dom_idx is 0, it means 'rid' contains a UID/GID and the
+ * returned SID will be a local SID. If dom_idx is not 0 then
+ * the domain SID will be fetched from the domain table.
+ */
+static int
+smb_lgrp_getsid(int dom_idx, uint32_t *rid, uint16_t sid_type,
+ sqlite *db, nt_sid_t **sid)
+{
+ nt_sid_t *dom_sid = NULL;
+ nt_sid_t *res_sid = NULL;
+ int id_type;
+ int rc;
+
+ *sid = NULL;
+ if (dom_idx == SMB_LGRP_LOCAL_IDX) {
+ id_type = (sid_type == SidTypeUser)
+ ? SMB_IDMAP_USER : SMB_IDMAP_GROUP;
+ if (smb_idmap_getsid(*rid, id_type, &res_sid) != IDMAP_SUCCESS)
+ return (SMB_LGRP_NO_SID);
+
+ /*
+ * Make sure the returned SID is local
+ */
+ if (!nt_sid_is_indomain(smb_lgrp_lsid, res_sid)) {
+ free(res_sid);
+ return (SMB_LGRP_SID_NOTLOCAL);
+ }
+
+ (void) nt_sid_get_rid(res_sid, rid);
+ *sid = res_sid;
+ return (SMB_LGRP_SUCCESS);
+ }
+
+ rc = smb_lgrp_dtbl_getsid(db, dom_idx, &dom_sid);
+ if (rc != SMB_LGRP_SUCCESS)
+ return (SMB_LGRP_DB_ERROR);
+
+ res_sid = nt_sid_splice(dom_sid, *rid);
+ free(dom_sid);
+ if (res_sid == NULL)
+ return (SMB_LGRP_NO_MEMORY);
+
+ *sid = res_sid;
+ return (SMB_LGRP_SUCCESS);
+}
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_privilege.c b/usr/src/lib/smbsrv/libsmb/common/smb_privilege.c
index ce7cef198a..be8853f4bc 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_privilege.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_privilege.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -41,9 +41,6 @@
#include <smbsrv/libsmb.h>
#include <smbsrv/smb_privilege.h>
-#define SMB_PRIV_MIN 2
-#define SMB_PRIV_MAX 24
-
static char *smb_priv_getname(uint32_t id);
/*
@@ -98,7 +95,7 @@ smb_priv_presentable_num()
int i, num;
num = 0;
- for (i = SMB_PRIV_MIN; i <= SMB_PRIV_MAX; i++)
+ for (i = SE_MIN_LUID; i <= SE_MAX_LUID; i++)
if (priv_table[i].flags == PF_PRESENTABLE)
num++;
@@ -119,7 +116,7 @@ smb_priv_presentable_ids(uint32_t *ids, int num)
if (ids == NULL || num <= 0)
return (0);
- for (i = SMB_PRIV_MIN, j = 0; i <= SMB_PRIV_MAX; i++)
+ for (i = SE_MIN_LUID, j = 0; i <= SE_MAX_LUID; i++)
if (priv_table[i].flags == PF_PRESENTABLE)
ids[j++] = priv_table[i].id;
@@ -135,7 +132,7 @@ smb_priv_presentable_ids(uint32_t *ids, int num)
smb_privinfo_t *
smb_priv_getbyvalue(uint32_t id)
{
- if (id < SMB_PRIV_MIN || id > SMB_PRIV_MAX)
+ if (id < SE_MIN_LUID || id > SE_MAX_LUID)
return (0);
return (&priv_table[id]);
@@ -157,7 +154,7 @@ smb_priv_getbyname(char *name)
if (name == 0)
return (0);
- for (i = SMB_PRIV_MIN; i <= SMB_PRIV_MAX; ++i) {
+ for (i = SE_MIN_LUID; i <= SE_MAX_LUID; ++i) {
entry = &priv_table[i];
if (utf8_strcasecmp(name, entry->name) == 0)
@@ -176,7 +173,7 @@ smb_priv_getbyname(char *name)
int
smb_privset_size()
{
- int pcnt = SMB_PRIV_MAX - SMB_PRIV_MIN + 1;
+ int pcnt = SE_MAX_LUID - SE_MIN_LUID + 1;
return (2 * sizeof (uint32_t) +
pcnt * sizeof (smb_luid_attrs_t));
@@ -198,7 +195,7 @@ smb_privset_validate(smb_privset_t *privset)
return (0);
}
- count = SMB_PRIV_MAX - SMB_PRIV_MIN + 1;
+ count = SE_MAX_LUID - SE_MIN_LUID + 1;
if (privset->priv_cnt != count) {
return (0);
@@ -210,7 +207,7 @@ smb_privset_validate(smb_privset_t *privset)
}
if (privset->priv[i].luid.lo_part !=
- i + SMB_PRIV_MIN) {
+ i + SE_MIN_LUID) {
return (0);
}
}
@@ -232,13 +229,13 @@ smb_privset_init(smb_privset_t *privset)
if (privset == 0)
return;
- count = SMB_PRIV_MAX - SMB_PRIV_MIN + 1;
+ count = SE_MAX_LUID - SE_MIN_LUID + 1;
privset->priv_cnt = count;
privset->control = 0;
for (i = 0; i < count; i++) {
privset->priv[i].luid.hi_part = 0;
- privset->priv[i].luid.lo_part = i + SMB_PRIV_MIN;
+ privset->priv[i].luid.lo_part = i + SE_MIN_LUID;
privset->priv[i].attrs = 0;
}
}
@@ -280,6 +277,25 @@ smb_privset_copy(smb_privset_t *dst, smb_privset_t *src)
}
/*
+ * smb_privset_merge
+ *
+ * Enable the privileges that are enabled in src in dst
+ */
+void
+smb_privset_merge(smb_privset_t *dst, smb_privset_t *src)
+{
+ int i;
+
+ if (src == NULL || dst == NULL)
+ return;
+
+ for (i = 0; i < src->priv_cnt; i++) {
+ if (src->priv[i].attrs == SE_PRIVILEGE_ENABLED)
+ smb_privset_enable(dst, src->priv[i].luid.lo_part);
+ }
+}
+
+/*
* smb_privset_free
*
* This will free the memory allocated by the 'privset'.
@@ -354,7 +370,7 @@ smb_privset_query(smb_privset_t *privset, uint32_t id)
static char *
smb_priv_getname(uint32_t id)
{
- if (id < SMB_PRIV_MIN || id > SMB_PRIV_MAX)
+ if (id < SE_MIN_LUID || id > SE_MAX_LUID)
return ("Unknown Privilege");
return (priv_table[id].name);
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_pwdutil.c b/usr/src/lib/smbsrv/libsmb/common/smb_pwdutil.c
index 10026d7418..cc0cddebcd 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_pwdutil.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_pwdutil.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -173,8 +173,7 @@ smb_pwd_update(const char *name, const char *password, int control)
boolean_t user_disable = B_FALSE;
char uxbuf[1024];
struct passwd uxpw;
- int lm_level;
- char *lm_str;
+ int64_t lm_level;
err = smb_pwd_lock();
if (err != SMB_PWE_SUCCESS)
@@ -202,13 +201,8 @@ smb_pwd_update(const char *name, const char *password, int control)
goto passwd_exit;
}
- lm_str = smb_config_getenv(SMB_CI_LM_LEVEL);
- if (lm_str) {
- lm_level = strtoul(lm_str, 0, 10);
- free(lm_str);
- } else {
+ if (smb_config_getnum(SMB_CI_LM_LEVEL, &lm_level) != SMBD_SMF_OK)
lm_level = 4;
- }
if (lm_level >= 4)
control |= SMB_PWC_NOLM;
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_scfutil.c b/usr/src/lib/smbsrv/libsmb/common/smb_scfutil.c
index 1f5083f448..4460e70154 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_scfutil.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_scfutil.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -60,95 +60,6 @@ smb_smf_scf_log_error(char *msg)
}
/*
- * Check if instance with given name exists for a service.
- * Returns 0 is instance exist
- */
-int
-smb_smf_instance_exists(smb_scfhandle_t *handle, char *inst_name)
-{
- int ret = SMBD_SMF_OK;
- if (handle == NULL)
- return (SMBD_SMF_SYSTEM_ERR);
-
- handle->scf_instance = scf_instance_create(handle->scf_handle);
- if (scf_service_get_instance(handle->scf_service, inst_name,
- handle->scf_instance) != SCF_SUCCESS)
- ret = SMBD_SMF_SYSTEM_ERR;
-
- scf_instance_destroy(handle->scf_instance);
- handle->scf_instance = NULL;
- return (ret);
-}
-
-/*
- * Create a service instance. returns 0 if successful.
- * If instance already exists enable it.
- */
-int
-smb_smf_instance_create(smb_scfhandle_t *handle, char *serv_prefix,
- char *inst_name)
-{
- char *instance;
- int ret = SMBD_SMF_OK;
- int sz;
-
- if (handle == NULL)
- return (SMBD_SMF_SYSTEM_ERR);
-
- if (!serv_prefix || !inst_name)
- return (SMBD_SMF_SYSTEM_ERR);
-
- sz = strlen(serv_prefix) + strlen(inst_name) + 2;
- instance = malloc(sz);
- if (!instance)
- return (SMBD_SMF_NO_MEMORY);
-
- (void) snprintf(instance, sz, "%s:%s", serv_prefix, inst_name);
- handle->scf_instance = scf_instance_create(handle->scf_handle);
- if (scf_service_get_instance(handle->scf_service, inst_name,
- handle->scf_instance) != SCF_SUCCESS) {
- if (scf_service_add_instance(handle->scf_service,
- inst_name, handle->scf_instance) == SCF_SUCCESS) {
- if (smf_enable_instance(instance, 0))
- ret = SMBD_SMF_SYSTEM_ERR;
- } else {
- ret = SMBD_SMF_SYSTEM_ERR;
- }
- } else {
- if (smf_enable_instance(instance, 0))
- ret = SMBD_SMF_SYSTEM_ERR;
- }
- free(instance);
- return (ret);
-}
-
-/*
- * Delete a specified instance. Return SMBD_SMF_OK for success.
- */
-int
-smb_smf_instance_delete(smb_scfhandle_t *handle, char *inst_name)
-{
- int ret = SMBD_SMF_OK;
-
- if (handle == NULL)
- return (SMBD_SMF_SYSTEM_ERR);
-
- handle->scf_instance = scf_instance_create(handle->scf_handle);
- if (scf_service_get_instance(handle->scf_service, inst_name,
- handle->scf_instance) == SCF_SUCCESS) {
- if (scf_instance_delete(handle->scf_instance) == SCF_SUCCESS) {
- return (ret);
- } else {
- ret = SMBD_SMF_SYSTEM_ERR;
- }
- } else {
- smb_smf_scf_log_error(NULL);
- ret = SMBD_SMF_SYSTEM_ERR;
- }
- return (ret);
-}
-
-/*
* smb_smf_create_service_pgroup(handle, pgroup)
*
* create a new property group at service level.
@@ -196,152 +107,6 @@ smb_smf_create_service_pgroup(smb_scfhandle_t *handle, char *pgroup)
}
/*
- * smb_smf_create_instance_pgroup(handle, pgroup)
- *
- * create a new property group at instance level.
- */
-int
-smb_smf_create_instance_pgroup(smb_scfhandle_t *handle, char *pgroup)
-{
- int ret = SMBD_SMF_OK;
- int err;
-
- if (handle == NULL) {
- return (SMBD_SMF_SYSTEM_ERR);
- }
-
- /*
- * only create a handle if it doesn't exist. It is ok to exist
- * since the pg handle will be set as a side effect.
- */
- if (handle->scf_pg == NULL)
- handle->scf_pg = scf_pg_create(handle->scf_handle);
-
- /*
- * if the pgroup exists, we are done. If it doesn't, then we
- * need to actually add one to the service instance.
- */
- if (scf_instance_get_pg(handle->scf_instance,
- pgroup, handle->scf_pg) != 0) {
- /* doesn't exist so create one */
- if (scf_instance_add_pg(handle->scf_instance, pgroup,
- SCF_GROUP_FRAMEWORK, 0, handle->scf_pg) != 0) {
- err = scf_error();
- if (err != SCF_ERROR_NONE)
- smb_smf_scf_log_error(NULL);
- switch (err) {
- case SCF_ERROR_PERMISSION_DENIED:
- ret = SMBD_SMF_NO_PERMISSION;
- break;
- default:
- ret = SMBD_SMF_SYSTEM_ERR;
- break;
- }
- }
- }
- return (ret);
-}
-
-/*
- * smb_smf_delete_service_pgroup(handle, pgroup)
- *
- * remove the property group from the current service.
- * but only if it actually exists.
- */
-int
-smb_smf_delete_service_pgroup(smb_scfhandle_t *handle, char *pgroup)
-{
- int ret = SMBD_SMF_OK;
- int err;
-
- if (handle == NULL) {
- return (SMBD_SMF_SYSTEM_ERR);
- }
-
- /*
- * only create a handle if it doesn't exist. It is ok to exist
- * since the pg handle will be set as a side effect.
- */
- if (handle->scf_pg == NULL)
- handle->scf_pg = scf_pg_create(handle->scf_handle);
-
- /*
- * only delete if it does exist.
- */
- if (scf_service_get_pg(handle->scf_service,
- pgroup, handle->scf_pg) == 0) {
- /* does exist so delete it */
- if (scf_pg_delete(handle->scf_pg) != 0) {
- ret = SMBD_SMF_SYSTEM_ERR;
- err = scf_error();
- if (err != SCF_ERROR_NONE) {
- smb_smf_scf_log_error("SMF delpg "
- "problem: %s\n");
- }
- }
- } else {
- err = scf_error();
- if (err != SCF_ERROR_NONE)
- smb_smf_scf_log_error("SMF getpg problem: %s\n");
- ret = SMBD_SMF_SYSTEM_ERR;
- }
- if (ret == SMBD_SMF_SYSTEM_ERR &&
- scf_error() == SCF_ERROR_PERMISSION_DENIED) {
- ret = SMBD_SMF_NO_PERMISSION;
- }
- return (ret);
-}
-
-/*
- * smb_smf_delete_instance_pgroup(handle, pgroup)
- *
- * remove the property group from the current instance.
- * but only if it actually exists.
- */
-int
-smb_smf_delete_instance_pgroup(smb_scfhandle_t *handle, char *pgroup)
-{
- int ret = SMBD_SMF_OK;
- int err;
-
- if (handle == NULL)
- return (SMBD_SMF_SYSTEM_ERR);
-
- /*
- * only create a handle if it doesn't exist. It is ok to exist
- * since the pg handle will be set as a side effect.
- */
- if (handle->scf_pg == NULL)
- handle->scf_pg = scf_pg_create(handle->scf_handle);
-
- /*
- * only delete if it does exist.
- */
- if (scf_instance_get_pg(handle->scf_instance,
- pgroup, handle->scf_pg) == 0) {
- /* does exist so delete it */
- if (scf_pg_delete(handle->scf_pg) != 0) {
- ret = SMBD_SMF_SYSTEM_ERR;
- err = scf_error();
- if (err != SCF_ERROR_NONE) {
- smb_smf_scf_log_error("SMF delpg "
- "problem: %s\n");
- }
- }
- } else {
- err = scf_error();
- if (err != SCF_ERROR_NONE)
- smb_smf_scf_log_error("SMF getpg problem: %s\n");
- ret = SMBD_SMF_SYSTEM_ERR;
- }
- if (ret == SMBD_SMF_SYSTEM_ERR &&
- scf_error() == SCF_ERROR_PERMISSION_DENIED)
- ret = SMBD_SMF_NO_PERMISSION;
-
- return (ret);
-}
-
-/*
* Start transaction on current pg in handle.
* The pg could be service or instance level.
* Must be called after pg handle is obtained
@@ -413,49 +178,6 @@ smb_smf_end_transaction(smb_scfhandle_t *handle)
}
/*
- * Deletes property in current pg
- */
-int
-smb_smf_delete_property(smb_scfhandle_t *handle, char *propname)
-{
- int ret = SMBD_SMF_OK;
- scf_transaction_entry_t *entry = NULL;
-
- if (handle == NULL)
- return (SMBD_SMF_SYSTEM_ERR);
-
- /*
- * properties must be set in transactions and don't take
- * effect until the transaction has been ended/committed.
- */
- entry = scf_entry_create(handle->scf_handle);
- if (entry != NULL) {
- if (scf_transaction_property_delete(handle->scf_trans, entry,
- propname) != 0) {
- ret = SMBD_SMF_SYSTEM_ERR;
- }
- } else {
- ret = SMBD_SMF_SYSTEM_ERR;
- }
- if (ret == SMBD_SMF_SYSTEM_ERR) {
- switch (scf_error()) {
- case SCF_ERROR_PERMISSION_DENIED:
- ret = SMBD_SMF_NO_PERMISSION;
- break;
- }
- }
-
- /*
- * cleanup if there were any errors that didn't leave these
- * values where they would be cleaned up later.
- */
- if ((ret != SMBD_SMF_OK) && (entry != NULL))
- scf_entry_destroy(entry);
-
- return (ret);
-}
-
-/*
* Sets string property in current pg
*/
int
@@ -843,103 +565,6 @@ smb_smf_get_opaque_property(smb_scfhandle_t *handle, char *propname,
}
/*
- * Get property based on property type. Returns string value of that
- * property. Only SCF_TYPE_ASTRING, SCF_TYPE_INTEGER, SCF_TYPE_BOOLEAN
- * supported.
- */
-int
-smb_smf_get_property(smb_scfhandle_t *handle, int proptype, char *propname,
- char *valstr, size_t sz)
-{
- int64_t valint = 0;
- uint8_t valbool = 0;
- int ret = SMBD_SMF_OK;
-
- switch (proptype) {
- case SCF_TYPE_ASTRING:
- ret = smb_smf_get_string_property(handle, propname,
- valstr, sz);
- break;
- case SCF_TYPE_INTEGER:
- if ((ret = smb_smf_get_integer_property(handle, propname,
- &valint)) != 0)
- return (ret);
- (void) snprintf(valstr, sz, "%lld", valint);
- break;
- case SCF_TYPE_BOOLEAN:
- if ((ret = smb_smf_get_boolean_property(handle, propname,
- &valbool)) != 0)
- return (ret);
- (void) strlcpy(valstr, (valbool ? "true" : "false"), sz);
- break;
- default:
- return (SMBD_SMF_SYSTEM_ERR);
- }
- return (ret);
-}
-
-/*
- * Set property based on property type.
- * Only SCF_TYPE_ASTRING, SCF_TYPE_INTEGER, SCF_TYPE_BOOLEAN supported.
- */
-int
-smb_smf_set_property(smb_scfhandle_t *handle, int proptype,
- char *propname, char *valstr)
-{
- int64_t valint = 0;
- uint8_t valbool = 0;
- int ret = SMBD_SMF_OK;
-
- switch (proptype) {
- case SCF_TYPE_ASTRING:
- ret = smb_smf_set_string_property(handle, propname,
- valstr);
- break;
- case SCF_TYPE_INTEGER:
- valint = strtol(valstr, 0, 10);
- ret = smb_smf_set_integer_property(handle, propname,
- valint);
- break;
- case SCF_TYPE_BOOLEAN:
- if (strcasecmp(valstr, "true") == 0)
- valbool = 1;
- ret = smb_smf_set_boolean_property(handle, propname, valbool);
- break;
- default:
- return (SMBD_SMF_SYSTEM_ERR);
- }
- return (ret);
-}
-
-/*
- * Gets an instance iterator for the service specified.
- */
-smb_scfhandle_t *
-smb_smf_get_iterator(char *svc_name)
-{
- smb_scfhandle_t *handle = NULL;
-
- handle = smb_smf_scf_init(svc_name);
- if (!handle)
- return (NULL);
-
- handle->scf_inst_iter = scf_iter_create(handle->scf_handle);
- if (handle->scf_inst_iter) {
- if (scf_iter_service_instances(handle->scf_inst_iter,
- handle->scf_service) != 0) {
- smb_smf_scf_fini(handle);
- handle = NULL;
- } else {
- handle->scf_instance = NULL;
- }
- } else {
- smb_smf_scf_fini(handle);
- handle = NULL;
- }
- return (handle);
-}
-
-/*
* smb_smf_scf_init()
*
* must be called before using any of the SCF functions.
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_util.c b/usr/src/lib/smbsrv/libsmb/common/smb_util.c
index bce8efee8e..b1c5c32653 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_util.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_util.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -30,10 +30,10 @@
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
-#include <syslog.h>
#include <sys/varargs.h>
#include <sys/types.h>
#include <smbsrv/string.h>
+#include <smbsrv/libsmb.h>
#define C2H(c) "0123456789ABCDEF"[(c)]
#define H2C(c) (((c) >= '0' && (c) <= '9') ? ((c) - '0') : \
@@ -56,7 +56,7 @@
*
*/
void
-hexdump_offset(unsigned char *buffer, int nbytes, unsigned long *start, int log)
+hexdump_offset(unsigned char *buffer, int nbytes, unsigned long *start)
{
static char *hex = "0123456789ABCDEF";
int i, count;
@@ -67,13 +67,8 @@ hexdump_offset(unsigned char *buffer, int nbytes, unsigned long *start, int log)
char *ap = ascbuf;
char *hp = hexbuf;
- if ((p = buffer) == 0) {
- if (log)
- syslog(LOG_DEBUG, "hexdump: (null)");
- else
- (void) printf("hexdump: (null)\n");
+ if ((p = buffer) == NULL)
return;
- }
offset = *start;
@@ -83,12 +78,7 @@ hexdump_offset(unsigned char *buffer, int nbytes, unsigned long *start, int log)
for (i = 0; i < nbytes; ++i) {
if (i && (i % 16) == 0) {
- if (log)
- syslog(LOG_DEBUG,
- "%06X %s %s", offset, hexbuf, ascbuf);
- else
- (void) printf("%06X %s %s\n",
- offset, hexbuf, ascbuf);
+ smb_tracef("%06X %s %s", offset, hexbuf, ascbuf);
ap = ascbuf;
hp = hexbuf;
count = 0;
@@ -104,13 +94,7 @@ hexdump_offset(unsigned char *buffer, int nbytes, unsigned long *start, int log)
}
if (count) {
- if (log)
- syslog(LOG_DEBUG,
- "%06X %-48s %s", offset, hexbuf, ascbuf);
- else
- (void) printf("%06X %-48s %s\n",
- offset, hexbuf, ascbuf);
-
+ smb_tracef("%06X %-48s %s", offset, hexbuf, ascbuf);
offset += count;
}
@@ -122,7 +106,7 @@ hexdump(unsigned char *buffer, int nbytes)
{
unsigned long start = 0;
- hexdump_offset(buffer, nbytes, &start, 1);
+ hexdump_offset(buffer, nbytes, &start);
}
/*
@@ -213,8 +197,8 @@ trim_whitespace(char *buf)
char *p = buf;
char *q = buf;
- if (buf == 0)
- return (0);
+ if (buf == NULL)
+ return (NULL);
while (*p && isspace(*p))
++p;
diff --git a/usr/src/lib/smbsrv/libsmb/i386/Makefile b/usr/src/lib/smbsrv/libsmb/i386/Makefile
index 710c9eb3dd..7ac7d3d534 100644
--- a/usr/src/lib/smbsrv/libsmb/i386/Makefile
+++ b/usr/src/lib/smbsrv/libsmb/i386/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -27,6 +27,7 @@
include ../Makefile.com
+LDLIBS += -lsqlite
DYNFLAGS += -R/usr/lib/smbsrv
install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
diff --git a/usr/src/lib/smbsrv/libsmb/sparc/Makefile b/usr/src/lib/smbsrv/libsmb/sparc/Makefile
index 710c9eb3dd..7ac7d3d534 100644
--- a/usr/src/lib/smbsrv/libsmb/sparc/Makefile
+++ b/usr/src/lib/smbsrv/libsmb/sparc/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -27,6 +27,7 @@
include ../Makefile.com
+LDLIBS += -lsqlite
DYNFLAGS += -R/usr/lib/smbsrv
install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT)
diff --git a/usr/src/lib/smbsrv/libsmb/sparcv9/Makefile b/usr/src/lib/smbsrv/libsmb/sparcv9/Makefile
index b3c4916b0c..03c6ea5b61 100644
--- a/usr/src/lib/smbsrv/libsmb/sparcv9/Makefile
+++ b/usr/src/lib/smbsrv/libsmb/sparcv9/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
diff --git a/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h b/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h
index 01de8f7f02..f7034dd64d 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h
+++ b/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -74,6 +74,8 @@ typedef enum adjoin_status {
} adjoin_status_t;
/* ADS functions */
+extern void ads_init(void);
+extern void ads_refresh(void);
extern ADS_HANDLE *ads_open(void);
extern void ads_close(ADS_HANDLE *);
extern int ads_publish_share(ADS_HANDLE *, const char *, const char *,
@@ -84,11 +86,12 @@ extern int ads_build_unc_name(char *, int, const char *, const char *);
extern int ads_lookup_share(ADS_HANDLE *, const char *, const char *, char *);
extern int ads_add_share(ADS_HANDLE *, const char *, const char *,
const char *);
-extern int ads_domain_change_notify_handler(char *);
-extern adjoin_status_t ads_join(char *, char *, char *, int);
+extern adjoin_status_t ads_join(char *, char *, char *, char *, int);
extern char *adjoin_report_err(adjoin_status_t status);
+extern int ads_domain_change_cleanup(char *);
/* DYNDNS functions */
+extern int dns_msgid_init(void);
extern int dyndns_update(void);
extern int dyndns_clear_rev_zone(void);
@@ -97,8 +100,8 @@ extern int smb_kinit(char *user, char *passwd);
/* NETBIOS Functions */
-extern int msdcs_lookup_ads(void);
-extern void smb_netbios_start(void);
+extern int msdcs_lookup_ads(char *);
+extern int smb_netbios_start(void);
extern void smb_netbios_shutdown(void);
extern void smb_netbios_name_reconfig(void);
@@ -142,10 +145,7 @@ struct ip_alias {
#define GATEWAY_FILE "/etc/defaultrouter"
/* NIC Config functions */
-extern void smb_resolver_init(void);
-extern void smb_resolver_close(void);
extern int smb_get_nameservers(struct in_addr *, int);
-extern uint16_t smb_get_next_resid(void);
extern void smb_nic_lock(void);
extern void smb_nic_unlock(void);
extern int smb_nic_init(void);
diff --git a/usr/src/lib/smbsrv/libsmbns/common/mapfile-vers b/usr/src/lib/smbsrv/libsmbns/common/mapfile-vers
index 63cf1a8f5b..ed0fde1e08 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/mapfile-vers
+++ b/usr/src/lib/smbsrv/libsmbns/common/mapfile-vers
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -31,18 +31,20 @@ SUNWprivate {
ads_add_share;
ads_build_unc_name;
ads_close;
- ads_domain_change_notify_handler;
+ ads_domain_change_cleanup;
+ ads_init;
ads_join;
ads_lookup_share;
ads_open;
ads_publish_share;
+ ads_refresh;
ads_remove_share;
+ dns_msgid_init;
dyndns_clear_rev_zone;
dyndns_update;
msdcs_lookup_ads;
smb_browser_config;
smb_get_nameservers;
- smb_get_next_resid;
smb_kinit;
smb_netbios_name_reconfig;
smb_netbios_start;
@@ -75,8 +77,6 @@ SUNWprivate {
smb_nic_status;
smb_nic_unlock;
smb_nic_validate_ip_address;
- smb_resolver_close;
- smb_resolver_init;
local:
*;
};
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c
index 5ea03bbd41..b988026dd3 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -59,10 +59,14 @@
#define ADS_COMPUTERS_CN "Computers"
#define ADS_COMPUTER_NUM_ATTR 7
#define ADS_SHARE_NUM_ATTR 3
+#define ADS_SITE_MAX MAXHOSTNAMELEN
/* current ADS server to communicate with */
ADS_HOST_INFO *ads_host_info = NULL;
-mutex_t ads_mtx;
+mutex_t ads_host_mtx;
+char ads_site[ADS_SITE_MAX];
+mutex_t ads_site_mtx;
+
/*
* adjoin_errmsg
@@ -88,7 +92,7 @@ static char *adjoin_errmsg[] = {
"ADJOIN failed to refresh SMB service."
};
-static ADS_HANDLE *ads_open_main(char *user, char *password);
+static ADS_HANDLE *ads_open_main(char *domain, char *user, char *password);
static int ads_bind(ADS_HANDLE *);
static void ads_get_computer_dn(ADS_HANDLE *, char *, size_t);
static char *ads_get_host_principal(char *fqhost);
@@ -105,6 +109,39 @@ static krb5_kvno ads_lookup_computer_attr_kvno(ADS_HANDLE *ah);
static int ads_gen_machine_passwd(char *machine_passwd, int bufsz);
static ADS_HOST_INFO *ads_get_host_info(void);
static void ads_set_host_info(ADS_HOST_INFO *host);
+static void ads_free_host_info(void);
+
+/*
+ * ads_init
+ *
+ * Initializes the ads_site global variable.
+ */
+void
+ads_init(void)
+{
+ (void) mutex_lock(&ads_site_mtx);
+ (void) smb_config_getstr(SMB_CI_ADS_SITE, ads_site, sizeof (ads_site));
+ (void) mutex_unlock(&ads_site_mtx);
+}
+
+/*
+ * ads_refresh
+ *
+ * If the ads_site has changed, clear the ads_host_info cache.
+ */
+void
+ads_refresh(void)
+{
+ char new_site[ADS_SITE_MAX];
+
+ (void) smb_config_getstr(SMB_CI_ADS_SITE, new_site, sizeof (new_site));
+ (void) mutex_lock(&ads_site_mtx);
+ if (strcasecmp(ads_site, new_site)) {
+ (void) strlcpy(ads_site, new_site, sizeof (ads_site));
+ ads_free_host_info();
+ }
+ (void) mutex_unlock(&ads_site_mtx);
+}
/*
* ads_build_unc_name
@@ -118,9 +155,9 @@ int
ads_build_unc_name(char *unc_name, int maxlen,
const char *hostname, const char *shareUNC)
{
- char my_domain[ADS_MAXBUFLEN];
+ char my_domain[MAXHOSTNAMELEN];
- if (smb_getdomainname(my_domain, sizeof (my_domain)) != 0)
+ if (smb_getfqdomainname(my_domain, sizeof (my_domain)) != 0)
return (-1);
(void) snprintf(unc_name, maxlen, "\\\\%s.%s\\%s",
@@ -301,10 +338,10 @@ ads_free_host_list(ADS_HOST_INFO *host_list, int count)
static void
ads_set_host_info(ADS_HOST_INFO *host)
{
- (void) mutex_lock(&ads_mtx);
+ (void) mutex_lock(&ads_host_mtx);
if (!ads_host_info)
ads_host_info = host;
- (void) mutex_unlock(&ads_mtx);
+ (void) mutex_unlock(&ads_host_mtx);
}
/*
@@ -316,9 +353,9 @@ ads_get_host_info(void)
{
ADS_HOST_INFO *host;
- (void) mutex_lock(&ads_mtx);
+ (void) mutex_lock(&ads_host_mtx);
host = ads_host_info;
- (void) mutex_unlock(&ads_mtx);
+ (void) mutex_unlock(&ads_host_mtx);
return (host);
}
/*
@@ -355,14 +392,13 @@ ads_find_host(char *ns, char *domain, int *port, char *service, int *go_next)
int s;
uint16_t id, rid, data_len, eport;
int ipaddr;
- struct hostent *h;
char buf[NS_PACKETSZ], buf2[NS_PACKETSZ];
char *bufptr, *str;
int i, ret;
int queryReq;
uint16_t query_cnt, ans_cnt, namser_cnt, addit_cnt;
int quest_type, quest_class;
- int dns_ip, decode_ip;
+ int dns_ip;
struct in_addr addr;
uint16_t flags = 0;
int force_recurs = 0;
@@ -397,7 +433,7 @@ retry:
(void) memset(buf, 0, NS_PACKETSZ);
bufptr = buf;
- id = smb_get_next_resid();
+ id = dns_get_msgid();
if (dyndns_build_header(&bufptr, BUFLEN_UDP(bufptr, buf), id, queryReq,
query_cnt, ans_cnt, namser_cnt, addit_cnt, flags) == -1) {
(void) close(s);
@@ -514,13 +550,7 @@ retry:
}
/* check additional section to get IP address of ads host */
- decode_ip = 1;
- smb_config_rdlock();
- if (smb_config_getyorn(SMB_CI_ADS_IPLOOKUP) == 1)
- decode_ip = 0;
- smb_config_unlock();
-
- if (decode_ip && (addit_cnt > 0)) {
+ if (addit_cnt > 0) {
int j;
ads_hosts_list2 = (ADS_HOST_INFO *)
@@ -589,50 +619,8 @@ retry:
return (ads_host);
}
ads_free_host_list(ads_hosts_list2, addit_cnt);
- } else {
- /* use DNS to get IP address of ads host */
- /*
- * Shouldn't get here unless entries exist in
- * DNS but DNS server did
- * not put them in additional section of DNS reply packet.
- */
- for (i = 0; i < ans_cnt; i++) {
- h = gethostbyname(ads_hosts_list[i].name);
- if (h == NULL)
- continue;
- if (h->h_addr == NULL)
- continue;
- (void) memcpy(&ads_hosts_list[i].ip_addr,
- h->h_addr, sizeof (addr.s_addr));
- if (ads_ping(ads_hosts_list[i].ip_addr) == 0) {
- ads_host = (ADS_HOST_INFO *)
- malloc(sizeof (ADS_HOST_INFO));
- if (ads_host == NULL) {
- ads_free_host_list(ads_hosts_list,
- ans_cnt);
- return (NULL);
- }
- bzero(ads_host, sizeof (ADS_HOST_INFO));
- ads_host->name = strdup(ads_hosts_list[i].name);
- if (ads_host->name == NULL) {
- ads_free_host_list(ads_hosts_list,
- ans_cnt);
- return (NULL);
- }
- ads_host->ip_addr = ads_hosts_list[i].ip_addr;
- ads_host->port = ads_hosts_list[i].port;
- *port = ads_host->port;
- addr.s_addr = ads_host->ip_addr;
- syslog(LOG_DEBUG, "smb_ads: Found ADS server"
- " using DNS: %s (%s) port %d",
- ads_host->name, inet_ntoa(addr),
- ads_host->port);
- ads_free_host_list(ads_hosts_list, ans_cnt);
- ads_set_host_info(ads_host);
- return (ads_host);
- }
- }
}
+
syslog(LOG_ERR, "smb_ads: Can't get IP for "
"ADS host or ADS host is down.\n");
ads_free_host_list(ads_hosts_list, ans_cnt);
@@ -720,16 +708,16 @@ ads_convert_domain(char *s)
* ads_free_host_info
* Free the memory use by the global ads_host_info and set it to NULL.
*/
-void
+static void
ads_free_host_info(void)
{
- (void) mutex_lock(&ads_mtx);
+ (void) mutex_lock(&ads_host_mtx);
if (ads_host_info) {
free(ads_host_info->name);
free(ads_host_info);
ads_host_info = NULL;
}
- (void) mutex_unlock(&ads_mtx);
+ (void) mutex_unlock(&ads_host_mtx);
}
/*
@@ -743,12 +731,15 @@ ads_free_host_info(void)
ADS_HANDLE *
ads_open(void)
{
- uint32_t mode = smb_get_security_mode();
+ char domain[MAXHOSTNAMELEN];
- if (mode != SMB_SECMODE_DOMAIN)
+ if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN)
return (NULL);
- return (ads_open_main(NULL, NULL));
+ if (smb_getfqdomainname(domain, MAXHOSTNAMELEN) != 0)
+ return (NULL);
+
+ return (ads_open_main(domain, NULL, NULL));
}
/*
@@ -770,75 +761,54 @@ ads_open(void)
*
* The ads_bind() routine is also called before the ADS handle is returned.
* Parameters:
- * None
+ * domain - fully-qualified domain name
+ * user - the user account for whom the Kerberos TGT ticket and ADS
+ * service tickets are acquired.
+ * password - password of the specified user
+ *
* Returns:
* NULL : can't connect to ADS server or other errors
* ADS_HANDLE* : handle to ADS server
*/
-ADS_HANDLE *
-ads_open_main(char *user, char *password)
+static ADS_HANDLE *
+ads_open_main(char *domain, char *user, char *password)
{
ADS_HANDLE *ah;
LDAP *ld;
int version = 3, ads_port, find_ads_retry;
- char domain[MAXHOSTNAMELEN];
- int enable;
ADS_HOST_INFO *ads_host = NULL;
struct in_addr addr;
- char *site, *service = NULL, *site_service = NULL;
- int service_sz;
+ char site[ADS_SITE_MAX];
+ char service[MAXHOSTNAMELEN];
+ char site_service[MAXHOSTNAMELEN];
struct in_addr ns_list[MAXNS];
int i, cnt, go_next;
- if (smb_getdomainname(domain, MAXHOSTNAMELEN) != 0)
- return (NULL);
-
- smb_config_rdlock();
- enable = smb_config_getyorn(SMB_CI_ADS_ENABLE);
- if (!enable) {
- smb_config_unlock();
- return (NULL);
- }
- site = smb_config_getstr(SMB_CI_ADS_SITE);
- smb_config_unlock();
+ (void) mutex_lock(&ads_site_mtx);
+ (void) strlcpy(site, ads_site, sizeof (site));
+ (void) mutex_unlock(&ads_site_mtx);
find_ads_retry = 0;
find_ads_host:
ads_host = ads_get_host_info();
if (!ads_host) {
- if (site && *site != 0) {
- service_sz = strlen("_ldap._tcp.._sites.dc._msdcs.") +
- strlen(site) + strlen(domain) + 1;
- site_service = (char *)malloc(service_sz);
- if (site_service == NULL) {
- syslog(LOG_ERR, "smb_ads: No ADS host found"
- " malloc failed...");
- return (NULL);
- }
- (void) snprintf(site_service, service_sz,
+ if (*site != '\0') {
+ (void) snprintf(site_service, sizeof (site_service),
"_ldap._tcp.%s._sites.dc._msdcs.%s", site, domain);
+ } else {
+ *site_service = '\0';
}
- service_sz = strlen("_ldap._tcp.dc._msdcs.") + strlen(domain)
- + 1;
- service = (char *)malloc(service_sz);
- if (service == NULL) {
- syslog(LOG_ERR, "smb_ads: No ADS host found malloc"
- " failed...");
- if (site_service != NULL)
- (void) free(site_service);
- return (NULL);
- }
- (void) snprintf(service, service_sz, "_ldap._tcp.dc._msdcs.%s",
- domain);
+ (void) snprintf(service, sizeof (service),
+ "_ldap._tcp.dc._msdcs.%s", domain);
cnt = smb_get_nameservers(ns_list, MAXNS);
ads_host = NULL;
go_next = 0;
for (i = 0; i < cnt; i++) {
- if (site_service != NULL) {
+ if (*site_service != '\0') {
ads_host = ads_find_host(inet_ntoa(ns_list[i]),
domain, &ads_port, site_service, &go_next);
}
@@ -853,11 +823,6 @@ find_ads_host:
}
}
- if (site_service)
- (void) free(site_service);
- if (service)
- (void) free(service);
-
if (ads_host == NULL) {
syslog(LOG_ERR, "smb_ads: No ADS host found from "
"configured nameservers");
@@ -1789,8 +1754,11 @@ ads_get_host_principals(char *fqhost, char *domain, char **princ,
if (fqhost) {
(void) strlcpy(hostname, fqhost, MAXHOSTNAMELEN);
} else {
- if (smb_getfqhostname(hostname, MAXHOSTNAMELEN) != 0)
+ if (smb_gethostname(hostname, MAXHOSTNAMELEN, 0) != 0)
return (-1);
+
+ (void) snprintf(hostname, MAXHOSTNAMELEN, "%s.%s", hostname,
+ domain);
}
if ((p = ads_get_host_principal(hostname)) == NULL) {
@@ -1846,13 +1814,13 @@ ads_computer_op(ADS_HANDLE *ah, int op)
char usrctl_buf[16];
int max;
- if (smb_getfqhostname(fqhost, MAXHOSTNAMELEN) != 0)
- return (-1);
-
- if (smb_gethostname(sam_acct, MAXHOSTNAMELEN, 0) != 0)
+ if (smb_gethostname(fqhost, MAXHOSTNAMELEN, 0) != 0)
return (-1);
+ (void) strlcpy(sam_acct, fqhost, MAXHOSTNAMELEN + 1);
(void) strlcat(sam_acct, "$", MAXHOSTNAMELEN + 1);
+ (void) snprintf(fqhost, MAXHOSTNAMELEN, "%s.%s", fqhost,
+ ah->domain);
if (ads_get_host_principals(fqhost, ah->domain, &svc_principal,
&user_principal) == -1) {
@@ -2165,22 +2133,32 @@ ads_gen_machine_passwd(char *machine_passwd, int bufsz)
}
/*
- * ads_domain_change_notify_handler
+ * ads_domain_change_cleanup
*
- * Clear the host info cache and remove the old keys from the keytab
- * as the ads_domain property has changed.
+ * If we're attempting to join the system to a new domain, the keys for
+ * the host principal regarding the old domain should be removed from
+ * Kerberos keytab. Also, the ads_host_info cache should be cleared.
*
- * domain - is the old ADS domain name.
+ * newdom is fully-qualified domain name. It can be set to empty string
+ * if user attempts to switch to workgroup mode.
*/
int
-ads_domain_change_notify_handler(char *domain)
+ads_domain_change_cleanup(char *newdom)
{
+ char origdom[MAXHOSTNAMELEN];
char *princ_r;
krb5_context ctx = NULL;
krb5_principal krb5princ;
int rc;
- if (ads_get_host_principals(NULL, domain, NULL, &princ_r) == -1)
+ if (smb_getfqdomainname(origdom, MAXHOSTNAMELEN))
+ return (0);
+
+ if (strcasecmp(origdom, newdom) == 0)
+ return (0);
+
+ ads_free_host_info();
+ if (ads_get_host_principals(NULL, origdom, NULL, &princ_r) == -1)
return (-1);
if (smb_krb5_ctx_init(&ctx) != 0) {
@@ -2198,7 +2176,7 @@ ads_domain_change_notify_handler(char *domain)
rc = smb_krb5_remove_keytab_entries(ctx, krb5princ, SMBNS_KRB5_KEYTAB);
free(princ_r);
smb_krb5_ctx_fini(ctx);
- ads_free_host_info();
+
return (rc);
}
@@ -2228,7 +2206,8 @@ ads_domain_change_notify_handler(char *domain)
* principal after the domain join operation.
*/
adjoin_status_t
-ads_join(char *user, char *usr_passwd, char *machine_passwd, int len)
+ads_join(char *domain, char *user, char *usr_passwd, char *machine_passwd,
+ int len)
{
ADS_HANDLE *ah = NULL;
krb5_context ctx = NULL;
@@ -2250,7 +2229,7 @@ ads_join(char *user, char *usr_passwd, char *machine_passwd, int len)
krb5_enctype enctypes[] = {ENCTYPE_DES_CBC_CRC, ENCTYPE_DES_CBC_MD5,
ENCTYPE_ARCFOUR_HMAC, ENCTYPE_AES128_CTS_HMAC_SHA1_96};
- if ((ah = ads_open_main(user, usr_passwd)) == NULL) {
+ if ((ah = ads_open_main(domain, user, usr_passwd)) == NULL) {
(void) smb_config_refresh();
return (ADJOIN_ERR_GET_HANDLE);
}
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c
index 853d1ff814..7ab634fd4d 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -37,6 +37,7 @@
#include <sys/socket.h>
#include <arpa/inet.h>
+#include <smbsrv/libsmb.h>
#include <smbsrv/libsmbns.h>
#include <smbsrv/cifs.h>
@@ -852,13 +853,9 @@ smb_browser_send_HostAnnouncement(int net, int32_t next_announcement,
uint32_t type;
char resource_domain[SMB_PI_MAX_DOMAIN];
- syslog(LOG_DEBUG, "smb_browse: send_HostAnnouncement(%d)", net);
-
- smb_config_rdlock();
- (void) strlcpy(resource_domain,
- smb_config_getstr(SMB_CI_DOMAIN_NAME), SMB_PI_MAX_DOMAIN);
+ if (smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN) != 0)
+ return;
(void) utf8_strupr(resource_domain);
- smb_config_unlock();
if (addr == 0) {
/* Local master Browser */
@@ -1134,15 +1131,10 @@ smb_browser_config(void)
int net;
char resource_domain[SMB_PI_MAX_DOMAIN];
- syslog(LOG_DEBUG, "smb_browse: reconfigure");
-
smb_browser_init();
-
- smb_config_rdlock();
- (void) strlcpy(resource_domain,
- smb_config_getstr(SMB_CI_DOMAIN_NAME), SMB_PI_MAX_DOMAIN);
+ if (smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN) != 0)
+ return;
(void) utf8_strupr(resource_domain);
- smb_config_unlock();
/* domain<00> */
smb_init_name_struct((unsigned char *)resource_domain, 0x00,
@@ -1201,11 +1193,7 @@ smb_browser_init()
net_cfg_t cfg;
(void) smb_gethostname(hostname, MAXHOSTNAMELEN, 1);
-
- smb_config_rdlock();
- (void) strlcpy(cmnt, smb_config_getstr(SMB_CI_SYS_CMNT),
- sizeof (cmnt));
- smb_config_unlock();
+ (void) smb_config_getstr(SMB_CI_SYS_CMNT, cmnt, sizeof (cmnt));
smb_nc_cnt = smb_nic_get_num();
for (i = 0; i < smb_nc_cnt; i++) {
@@ -1281,12 +1269,10 @@ smb_browser_non_master_duties(int net)
smb_browser_putnet(subnet);
smb_browser_send_HostAnnouncement(net, interval, 0, 0x1D);
+ if (smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN) != 0)
+ return;
- smb_config_rdlock();
- (void) strlcpy(resource_domain,
- smb_config_getstr(SMB_CI_DOMAIN_NAME), SMB_PI_MAX_DOMAIN);
(void) utf8_strupr(resource_domain);
- smb_config_unlock();
smb_init_name_struct((unsigned char *)resource_domain, 0x1D,
0, 0, 0, 0, 0, &name);
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c
index 094c1b4946..c0f870b2ad 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -52,16 +52,39 @@
#define DEL_NONE 2
/* Maximum retires if not authoritative */
#define MAX_AUTH_RETRIES 3
+/* Number of times to retry a DNS query */
+#define DYNDNS_MAX_QUERY_RETRIES 3
+/* Timeout value, in seconds, for DNS query responses */
+#define DYNDNS_QUERY_TIMEOUT 2
-static int
-dyndns_enabled(void)
+static uint16_t dns_msgid;
+mutex_t dns_msgid_mtx;
+
+int
+dns_msgid_init(void)
{
- int enabled;
+ struct __res_state res;
+
+ bzero(&res, sizeof (struct __res_state));
+ if (res_ninit(&res) < 0)
+ return (-1);
- smb_config_rdlock();
- enabled = smb_config_getyorn(SMB_CI_DYNDNS_ENABLE);
- smb_config_unlock();
- return (enabled);
+ (void) mutex_lock(&dns_msgid_mtx);
+ dns_msgid = res.id;
+ (void) mutex_unlock(&dns_msgid_mtx);
+ res_nclose(&res);
+ return (0);
+}
+
+int
+dns_get_msgid(void)
+{
+ uint16_t id;
+
+ (void) mutex_lock(&dns_msgid_mtx);
+ id = ++dns_msgid;
+ (void) mutex_unlock(&dns_msgid_mtx);
+ return (id);
}
/*
@@ -651,7 +674,7 @@ dyndns_build_tkey_msg(char *buf, char *key_name, uint16_t *id,
(void) memset(buf, 0, MAX_TCP_SIZE);
bufptr = buf;
- *id = smb_get_next_resid();
+ *id = dns_get_msgid();
/* add TCP length info that follows this field */
bufptr = dyndns_put_nshort(bufptr,
@@ -931,7 +954,7 @@ dyndns_build_add_remove_msg(char *buf, int update_zone, const char *hostname,
bufptr = buf;
if (*id == 0)
- *id = smb_get_next_resid();
+ *id = dns_get_msgid();
if (dyndns_build_header(&bufptr, BUFLEN_UDP(bufptr, buf), *id, queryReq,
zoneCount, preqCount, updateCount, additionalCount, 0) == -1) {
@@ -1114,13 +1137,7 @@ dyndns_build_signed_tsig_msg(char *buf, int update_zone, const char *hostname,
/*
* dyndns_udp_send_recv
- * This routine sends and receives UDP DNS request and reply messages. Time
- * out value and retry count is indicated by two environment variables:
- * lookup_dns_retry_cnt
- * lookup_dns_retry_sec
- * If either of these two variables are undefined or their value exceed the
- * value of 10 then a default value of 3 retry and/or a default value of 3
- * secs are used.
+ * This routine sends and receives UDP DNS request and reply messages.
*
* Pre-condition: Caller must call dyndns_open_init_socket() before calling
* this function.
@@ -1137,34 +1154,15 @@ dyndns_build_signed_tsig_msg(char *buf, int update_zone, const char *hostname,
int
dyndns_udp_send_recv(int s, char *buf, int buf_sz, char *rec_buf)
{
- int i, retval, addr_len, max_retries;
+ int i, retval, addr_len;
struct timeval tv, timeout;
fd_set rfds;
struct sockaddr_in from_addr;
- char *p;
-
- smb_config_rdlock();
- p = smb_config_getstr(SMB_CI_DYNDNS_RETRY_COUNT);
- if (p == NULL || *p == 0) {
- max_retries = 3;
- } else {
- max_retries = atoi(p);
- if (max_retries < 1 || max_retries > 10)
- max_retries = 3;
- }
- p = smb_config_getstr(SMB_CI_DYNDNS_RETRY_SEC);
timeout.tv_usec = 0;
- if (p == NULL || *p == 0) {
- timeout.tv_sec = 3;
- } else {
- timeout.tv_sec = atoi(p);
- if (timeout.tv_sec < 1 || timeout.tv_sec > 10)
- timeout.tv_sec = 3;
- }
- smb_config_unlock();
+ timeout.tv_sec = DYNDNS_QUERY_TIMEOUT;
- for (i = 0; i < max_retries + 1; i++) {
+ for (i = 0; i <= DYNDNS_MAX_QUERY_RETRIES; i++) {
if (send(s, buf, buf_sz, 0) == -1) {
syslog(LOG_ERR, "dyndns: UDP send error (%s)\n",
strerror(errno));
@@ -1193,7 +1191,8 @@ dyndns_udp_send_recv(int s, char *buf, int buf_sz, char *rec_buf)
}
}
- if (i == (max_retries + 1)) { /* did not receive anything */
+ /* did not receive anything */
+ if (i == (DYNDNS_MAX_QUERY_RETRIES + 1)) {
syslog(LOG_ERR, "dyndns: max retries for UDP recv reached\n");
return (-1);
}
@@ -1506,7 +1505,7 @@ retry_higher:
return (-1);
}
- if (smb_get_security_mode() == SMB_SECMODE_DOMAIN)
+ if (smb_config_get_secmode() == SMB_SECMODE_DOMAIN)
ret = dyndns_sec_add_remove_entry(update_zone, hostname,
ip_addr, life_time, update_type, del_type, dns_str);
@@ -1679,7 +1678,7 @@ dyndns_update(void)
struct in_addr addr;
int rc;
- if (!dyndns_enabled())
+ if (!smb_config_getbool(SMB_CI_DYNDNS_ENABLE))
return (-1);
if (smb_getfqhostname(fqdn, MAXHOSTNAMELEN) != 0)
@@ -1760,7 +1759,7 @@ dyndns_clear_rev_zone(void)
struct in_addr addr;
int rc;
- if (!dyndns_enabled())
+ if (!smb_config_getbool(SMB_CI_DYNDNS_ENABLE))
return (-1);
if (smb_getfqhostname(fqdn, MAXHOSTNAMELEN) != 0)
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.h b/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.h
index 7140eb4d59..42f69751cc 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.h
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -182,6 +182,7 @@ extern "C" {
#define BUFLEN_TCP(x, y) (MAX_TCP_SIZE-(x-y))
#define BUFLEN_UDP(x, y) (NS_PACKETSZ-(x-y))
+extern int dns_get_msgid(void);
extern char *dyndns_get_nshort(char *, uint16_t *);
extern char *dyndns_get_int(char *, int *);
extern int dyndns_build_header(char **, int, uint16_t, int,
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.c
index 7b165e3b44..4f8340dcca 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -73,8 +73,8 @@ smb_netbios_shutdown(void)
nb_status.state = NETBIOS_SHUT_DOWN;
}
-void
-smb_netbios_start()
+int
+smb_netbios_start(void)
{
int rc;
mutex_t *mp;
@@ -84,13 +84,12 @@ smb_netbios_start()
rc = pthread_create(&smb_nbns_thr, 0,
smb_netbios_name_service_daemon, 0);
if (rc)
- return;
+ return (-1);
mp = &nb_status.mtx;
cvp = &nb_status.cv;
(void) mutex_lock(mp);
-
while (!(nb_status.state & (NETBIOS_NAME_SVC_RUNNING |
NETBIOS_NAME_SVC_FAILED))) {
(void) cond_wait(cvp, mp);
@@ -98,71 +97,62 @@ smb_netbios_start()
if (nb_status.state & NETBIOS_NAME_SVC_FAILED) {
(void) mutex_unlock(mp);
- (void) fprintf(stderr,
- "smbd: Netbios Name service startup failed!");
smb_netbios_shutdown();
- return;
+ return (-1);
}
(void) mutex_unlock(mp);
- (void) fprintf(stderr, "smbd: Netbios Name service started.");
smb_netbios_name_config();
/* Startup Netbios datagram service; port 138 */
rc = pthread_create(&smb_nbds_thr, 0,
smb_netbios_datagram_service_daemon, 0);
- if (rc == 0) {
- (void) mutex_lock(mp);
- while (!(nb_status.state & (NETBIOS_DATAGRAM_SVC_RUNNING |
- NETBIOS_DATAGRAM_SVC_FAILED))) {
- (void) cond_wait(cvp, mp);
- }
+ if (rc != 0) {
+ smb_netbios_shutdown();
+ return (-1);
+ }
- if (nb_status.state & NETBIOS_DATAGRAM_SVC_FAILED) {
- (void) mutex_unlock(mp);
- (void) fprintf(stderr, "smbd: Netbios Datagram service "
- "startup failed!");
- smb_netbios_shutdown();
- return;
- }
+ (void) mutex_lock(mp);
+ while (!(nb_status.state & (NETBIOS_DATAGRAM_SVC_RUNNING |
+ NETBIOS_DATAGRAM_SVC_FAILED))) {
+ (void) cond_wait(cvp, mp);
+ }
+
+ if (nb_status.state & NETBIOS_DATAGRAM_SVC_FAILED) {
(void) mutex_unlock(mp);
- } else {
smb_netbios_shutdown();
- return;
+ return (-1);
}
-
- (void) fprintf(stderr, "smbd: Netbios Datagram service started.");
+ (void) mutex_unlock(mp);
/* Startup Netbios browser service */
rc = pthread_create(&smb_nbbs_thr, 0, smb_browser_daemon, 0);
if (rc) {
smb_netbios_shutdown();
- return;
+ return (-1);
}
- (void) fprintf(stderr, "smbd: Netbios Browser client started.");
-
/* Startup Our internal, 1 second resolution, timer */
rc = pthread_create(&smb_nbts_thr, 0, smb_netbios_timer, 0);
- if (rc == 0) {
- (void) mutex_lock(mp);
- while (!(nb_status.state & (NETBIOS_TIMER_RUNNING |
- NETBIOS_TIMER_FAILED))) {
- (void) cond_wait(cvp, mp);
- }
+ if (rc != 0) {
+ smb_netbios_shutdown();
+ return (-1);
+ }
- if (nb_status.state & NETBIOS_TIMER_FAILED) {
- (void) mutex_unlock(mp);
- smb_netbios_shutdown();
- return;
- }
+ (void) mutex_lock(mp);
+ while (!(nb_status.state & (NETBIOS_TIMER_RUNNING |
+ NETBIOS_TIMER_FAILED))) {
+ (void) cond_wait(cvp, mp);
+ }
+
+ if (nb_status.state & NETBIOS_TIMER_FAILED) {
(void) mutex_unlock(mp);
- } else {
smb_netbios_shutdown();
- return;
+ return (-1);
}
+ (void) mutex_unlock(mp);
- (void) fprintf(stderr, "smbd: Netbios Timer service started.");
+ return (0);
}
/*ARGSUSED*/
@@ -253,10 +243,8 @@ smb_encode_netbios_name(unsigned char *name, char suffix, unsigned char *scope,
dest->name[NETBIOS_NAME_SZ - 1] = suffix;
if (scope == NULL) {
- smb_config_rdlock();
- (void) strlcpy((char *)dest->scope,
- smb_config_getstr(SMB_CI_NBSCOPE), NETBIOS_DOMAIN_NAME_MAX);
- smb_config_unlock();
+ (void) smb_config_getstr(SMB_CI_NBSCOPE, (char *)dest->scope,
+ NETBIOS_DOMAIN_NAME_MAX);
} else {
(void) strlcpy((char *)dest->scope, (const char *)scope,
NETBIOS_DOMAIN_NAME_MAX);
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_cache.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_cache.c
index 1e47658700..a1c3bb2c03 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_cache.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_cache.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -111,11 +111,9 @@ smb_netbios_cache_lookup(struct name_entry *name)
if (NETBIOS_NAME_IS_STAR(name->name)) {
/* Return our address */
- smb_config_rdlock();
- (void) strlcpy((char *)scope,
- smb_config_getstr(SMB_CI_NBSCOPE), sizeof (scope));
+ (void) smb_config_getstr(SMB_CI_NBSCOPE, (char *)scope,
+ sizeof (scope));
(void) utf8_strupr((char *)scope);
- smb_config_unlock();
if (smb_getnetbiosname((char *)hostname, MAXHOSTNAMELEN) != 0)
return (NULL);
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_name.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_name.c
index b8de94a504..f7794479ab 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_name.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_name.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -2126,7 +2126,8 @@ static int
smb_send_node_status_response(struct addr_entry *addr,
struct name_packet *original_packet)
{
- uint32_t net_ipaddr, max_connections;
+ uint32_t net_ipaddr;
+ int64_t max_connections;
struct arpreq arpreq;
struct name_packet packet;
struct resource_record answer;
@@ -2166,9 +2167,8 @@ smb_send_node_status_response(struct addr_entry *addr,
else
net_ipaddr = cfg.ip;
- smb_config_rdlock();
- max_connections = smb_config_getnum(SMB_CI_MAX_CONNECTIONS);
- smb_config_unlock();
+ (void) smb_config_getnum(SMB_CI_MAX_CONNECTIONS, &max_connections);
+
while (!scan_done) {
if ((scan + 6) >= scan_end) {
packet.info |= NAME_NM_FLAGS_TC;
@@ -4489,10 +4489,6 @@ smb_netbios_wins_config(char *ip)
{
uint32_t ipaddr;
- /* Return if ip == NULL since this is the same as "" */
- if (ip == NULL)
- return;
-
ipaddr = inet_addr(ip);
if (ipaddr != INADDR_NONE) {
smb_nbns[nbns_num].flags = ADDR_FLAG_VALID;
@@ -4511,9 +4507,10 @@ smb_netbios_name_config(void)
uint32_t ipaddr;
struct name_entry name;
char myname[MAXHOSTNAMELEN];
- int i;
+ int i;
int smb_nc_cnt;
net_cfg_t cfg;
+ char wins_ip[16];
if (smb_getnetbiosname(myname, MAXHOSTNAMELEN) != 0)
return;
@@ -4544,10 +4541,10 @@ smb_netbios_name_config(void)
bzero(smb_nbns, sizeof (addr_entry_t) * SMB_PI_MAX_WINS);
/* add any configured WINS */
- smb_config_rdlock();
- smb_netbios_wins_config(smb_config_getstr(SMB_CI_WINS_SRV1));
- smb_netbios_wins_config(smb_config_getstr(SMB_CI_WINS_SRV2));
- smb_config_unlock();
+ (void) smb_config_getstr(SMB_CI_WINS_SRV1, wins_ip, sizeof (wins_ip));
+ smb_netbios_wins_config(wins_ip);
+ (void) smb_config_getstr(SMB_CI_WINS_SRV2, wins_ip, sizeof (wins_ip));
+ smb_netbios_wins_config(wins_ip);
for (i = 0; i < smb_nc_cnt; i++) {
if (smb_nic_get_byind(i, &cfg) == NULL) {
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_netlogon.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_netlogon.c
index d74bcb168d..2631bd0f68 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_netlogon.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_netlogon.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -478,27 +478,22 @@ smb_netlogon_rdc_rsp(char *src_name, uint32_t src_ipaddr)
uint32_t prefer_ipaddr = 0;
char ipstr[16];
char srcip[16];
- char *p;
int rc;
(void) inet_ntop(AF_INET, (const void *)(&src_ipaddr),
srcip, sizeof (srcip));
- smb_config_rdlock();
- if ((p = smb_config_get(SMB_CI_DOMAIN_SRV)) != 0) {
- rc = inet_pton(AF_INET, p, &prefer_ipaddr);
+ rc = smb_config_getstr(SMB_CI_DOMAIN_SRV, ipstr, sizeof (ipstr));
+ if (rc == SMBD_SMF_OK) {
+ rc = inet_pton(AF_INET, ipstr, &prefer_ipaddr);
if (rc == 0)
prefer_ipaddr = 0;
if (!initialized) {
- (void) inet_ntop(AF_INET,
- (const void *)(&prefer_ipaddr),
- ipstr, sizeof (ipstr));
syslog(LOG_DEBUG, "SMB DC Preference: %s", ipstr);
initialized = 1;
}
}
- smb_config_unlock();
syslog(LOG_DEBUG, "DC Offer [%s]: %s [%s]",
resource_domain, src_name, srcip);
@@ -553,49 +548,35 @@ better_dc(uint32_t cur_ip, uint32_t new_ip)
* best way. The IP address isn't set up in the ADS_HANDLE so we need to
* make the ads_find_host call. This will only succeed if ADS is enabled.
*
+ * Parameter:
+ * nbt_domain - NETBIOS name of the domain
+ *
* Returns 1 if a domain controller was found and its name and IP address
* have been updated. Otherwise returns 0.
*/
int
-msdcs_lookup_ads(void)
+msdcs_lookup_ads(char *nbt_domain)
{
ADS_HOST_INFO *hinfo = 0;
int ads_port = 0;
char ads_domain[MAXHOSTNAMELEN];
char site_service[MAXHOSTNAMELEN];
char service[MAXHOSTNAMELEN];
- char *site;
+ char site[MAXHOSTNAMELEN];
char *p;
char *ip_addr;
struct in_addr ns_list[MAXNS];
int i, cnt, go_next;
- if (smb_getdomainname(ads_domain, MAXHOSTNAMELEN) != 0)
+ if (!nbt_domain)
return (0);
- /*
- * Initialize the NT domain name.
- */
- (void) strlcpy(resource_domain, ads_domain, SMB_PI_MAX_DOMAIN);
- if ((p = strchr(resource_domain, '.')) != 0)
- *p = '\0';
-
- smb_config_rdlock();
- if (smb_config_getyorn(SMB_CI_MSDCS_DISABLE) != 0) {
- /*
- * The system administrator doesn't
- * want to use ADS to find the PDC.
- */
- syslog(LOG_DEBUG, "msdcsLookupADS: disabled");
- smb_config_unlock();
+ (void) strlcpy(resource_domain, nbt_domain, SMB_PI_MAX_DOMAIN);
+ if (smb_resolve_fqdn(nbt_domain, ads_domain, MAXHOSTNAMELEN) != 1)
return (0);
- }
- site = smb_config_getstr(SMB_CI_ADS_SITE);
- smb_config_unlock();
- syslog(LOG_DEBUG, "msdcsLookupADS %s, MAXHOSTNAMELEN=%d",
- ads_domain, MAXHOSTNAMELEN);
- if (site && *site != 0) {
+ (void) smb_config_getstr(SMB_CI_ADS_SITE, site, sizeof (site));
+ if (*site != '\0') {
(void) snprintf(site_service, MAXHOSTNAMELEN,
"_ldap._tcp.%s._sites.dc._msdcs.%s",
site, ads_domain);
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_nicconfig.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_nicconfig.c
index 6adeca1d50..2316bd595f 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_nicconfig.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_nicconfig.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -57,41 +57,22 @@ static void smb_nic_clear_if_list(struct if_list *);
/* This is the list we will monitor */
static net_cfg_list_t smb_nic_list = { NULL, 0 };
static pthread_mutex_t smb_nic_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t smb_ns_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-/* Nameserver information */
-static struct __res_state smb_res;
-
-void
-smb_resolver_init(void)
-{
- int ret;
- (void) pthread_mutex_lock(&smb_ns_mutex);
- ret = res_ninit(&smb_res);
- (void) pthread_mutex_unlock(&smb_ns_mutex);
- if (ret < 0) {
- syslog(LOG_ERR, "Failed to initialize resolver lib");
- }
-}
-
-void
-smb_resolver_close(void)
-{
- (void) pthread_mutex_lock(&smb_ns_mutex);
- res_nclose(&smb_res);
- (void) pthread_mutex_unlock(&smb_ns_mutex);
-}
int
smb_get_nameservers(struct in_addr *ips, int sz)
{
union res_sockaddr_union set[MAXNS];
int i, cnt;
+ struct __res_state res_state;
if (ips == NULL)
return (0);
- (void) pthread_mutex_lock(&smb_ns_mutex);
- cnt = res_getservers(&smb_res, set, MAXNS);
+
+ bzero(&res_state, sizeof (struct __res_state));
+ if (res_ninit(&res_state) < 0)
+ return (0);
+
+ cnt = res_getservers(&res_state, set, MAXNS);
for (i = 0; i < cnt; i++) {
if (i >= sz)
break;
@@ -100,20 +81,10 @@ smb_get_nameservers(struct in_addr *ips, int sz)
inet_ntoa(ips[i]));
}
syslog(LOG_DEBUG, "NS Found %d name servers\n", i);
- (void) pthread_mutex_unlock(&smb_ns_mutex);
+ res_nclose(&res_state);
return (i);
}
-uint16_t
-smb_get_next_resid(void)
-{
- uint16_t id;
- (void) pthread_mutex_lock(&smb_ns_mutex);
- id = ++smb_res.id;
- (void) pthread_mutex_unlock(&smb_ns_mutex);
- return (id);
-}
-
/*
* The common NIC library will provide functions to obtain information
* on all interfaces. Information will include IP addresses, netmasks
@@ -651,7 +622,6 @@ smb_nic_build_network_structures(net_cfg_t **nc, int *number)
char excludestr[MAX_EXCLUDE_LIST_LEN];
ipaddr_t exclude[SMB_PI_MAX_NETWORKS];
int nexclude;
- char *winsexclude;
*number = 0;
numnics = smb_nic_build_if_name(&names);
@@ -662,12 +632,8 @@ smb_nic_build_network_structures(net_cfg_t **nc, int *number)
}
bzero(nc_array, sizeof (net_cfg_t) * numnics);
- smb_config_rdlock();
- excludestr[0] = '\0';
- winsexclude = smb_config_getstr(SMB_CI_WINS_EXCL);
- if (winsexclude != NULL)
- (void) strlcpy(excludestr, winsexclude, sizeof (excludestr));
- smb_config_unlock();
+ (void) smb_config_getstr(SMB_CI_WINS_EXCL, excludestr,
+ sizeof (excludestr));
nexclude = smb_wins_iplist(excludestr, exclude, SMB_PI_MAX_NETWORKS);
for (i = 0; i < numnics; i++) {
diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/libsmbrdr.h b/usr/src/lib/smbsrv/libsmbrdr/common/libsmbrdr.h
index 8d537650ac..3c450da186 100644
--- a/usr/src/lib/smbsrv/libsmbrdr/common/libsmbrdr.h
+++ b/usr/src/lib/smbsrv/libsmbrdr/common/libsmbrdr.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -52,7 +52,7 @@ extern unsigned char *smbrdr_ipc_get_passwd(void);
/* Redirector LOGON function */
extern int mlsvc_logon(char *, char *, char *);
-extern int smbrdr_rpc_readx(int, char *, int);
+extern int smbrdr_readx(int, char *, int);
/* Redirector rpcpipe functions */
@@ -62,14 +62,12 @@ extern int mlsvc_close_pipe(int);
/* Redirector session functions */
extern void smbrdr_init(void);
-extern int mlsvc_locate_domain_controller(char *);
extern int mlsvc_session_native_values(int, int *, int *, int *);
-extern void mlsvc_check_sessions(void);
extern int mlsvc_echo(char *);
extern void mlsvc_disconnect(char *);
-extern int smbrdr_rpc_transact(int, char *, int, char *, int);
+extern int smbrdr_transact(int, char *, int, char *, int);
/* DEBUG functions */
diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/mapfile-vers b/usr/src/lib/smbsrv/libsmbrdr/common/mapfile-vers
index b6902203ef..ffa2d56871 100644
--- a/usr/src/lib/smbsrv/libsmbrdr/common/mapfile-vers
+++ b/usr/src/lib/smbsrv/libsmbrdr/common/mapfile-vers
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -27,12 +27,9 @@
SUNWprivate {
global:
- mlsvc_check_sessions;
mlsvc_close_pipe;
mlsvc_disconnect;
mlsvc_echo;
- mlsvc_install_pdc_cb;
- mlsvc_locate_domain_controller;
mlsvc_logon;
mlsvc_open_pipe;
mlsvc_session_native_values;
@@ -47,8 +44,8 @@ SUNWprivate {
smbrdr_ipc_set;
smbrdr_ipc_skip_lsa_query;
smbrdr_ipc_get_passwd;
- smbrdr_rpc_readx;
- smbrdr_rpc_transact;
+ smbrdr_readx;
+ smbrdr_transact;
local:
*;
};
diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr.h b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr.h
index 35db51adc6..5275708b72 100644
--- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr.h
+++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -117,16 +117,16 @@ struct sdb_session {
char native_lanman[SMB_PI_MAX_LANMAN];
int sock;
short port;
- unsigned short secmode;
+ uint16_t secmode;
uint32_t sesskey;
uint32_t challenge_len;
- unsigned char challenge_key[32];
- unsigned char smb_flags;
- unsigned short smb_flags2;
- unsigned short vc;
+ uint8_t challenge_key[32];
+ uint8_t smb_flags;
+ uint16_t smb_flags2;
+ uint16_t vc;
uint32_t remote_caps;
- unsigned short state;
- unsigned int sid; /* session id */
+ uint8_t state;
+ uint32_t sid; /* session id */
int remote_os;
int remote_lm;
int pdc_type;
@@ -208,12 +208,12 @@ void smbrdr_session_unlock(struct sdb_session *);
/*
* smbrdr_logon.c
*/
-int smbrdr_smb_logoff(struct sdb_logon *);
+int smbrdr_logoffx(struct sdb_logon *);
/* smbrdr_netuse.c */
void smbrdr_netuse_logoff(unsigned short);
struct sdb_netuse *smbrdr_netuse_get(int);
-unsigned short mlsvc_tree_connect(char *, char *, char *);
+unsigned short smbrdr_tree_connect(char *, char *, char *);
int smbrdr_tree_disconnect(unsigned short);
void smbrdr_netuse_put(struct sdb_netuse *);
@@ -232,8 +232,8 @@ DWORD smbrdr_rcv(smbrdr_handle_t *, int);
DWORD smbrdr_exchange(smbrdr_handle_t *, smb_hdr_t *, long);
void smbrdr_handle_free(smbrdr_handle_t *);
int smbrdr_sign_init(struct sdb_session *, struct sdb_logon *);
-int smbrdr_sign_fini(struct sdb_session *);
-int smbrdr_sign_unset_key(struct sdb_session *);
+void smbrdr_sign_fini(struct sdb_session *);
+void smbrdr_sign_unset_key(struct sdb_session *);
void smbrdr_lock_transport(void);
void smbrdr_unlock_transport(void);
diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_ipc_util.c b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_ipc_util.c
index cbce43db5e..8185ddee5e 100644
--- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_ipc_util.c
+++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_ipc_util.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,11 +34,9 @@
#include <string.h>
#include <strings.h>
-#include <syslog.h>
#include <synch.h>
#include <smbsrv/libsmbrdr.h>
-
#include <smbsrv/mlsvc.h>
#include <smbsrv/smbinfo.h>
#include <smbrdr.h>
@@ -53,20 +51,17 @@ static smbrdr_ipc_t orig_ipc_info;
static int
smbrdr_get_machine_pwd_hash(unsigned char *hash)
{
- char *pwd;
+ char pwd[SMB_PI_MAX_PASSWD];
int rc = 0;
- smb_config_rdlock();
- pwd = smb_config_getstr(SMB_CI_MACHINE_PASSWD);
- if (!pwd || *pwd == 0) {
- smb_config_unlock();
+ rc = smb_config_getstr(SMB_CI_MACHINE_PASSWD, pwd, sizeof (pwd));
+ if ((rc != SMBD_SMF_OK) || *pwd == '\0') {
return (-1);
}
- if (smb_auth_ntlm_hash((char *)pwd, hash) != 0)
+ if (smb_auth_ntlm_hash(pwd, hash) != 0)
rc = -1;
- smb_config_unlock();
return (rc);
}
diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_lib.c b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_lib.c
index ac4743548c..432d66141e 100644
--- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_lib.c
+++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_lib.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -36,17 +36,12 @@
#include <smbsrv/ntstatus.h>
#include <smbrdr.h>
-static DWORD smbrdr_handle_setup(smbrdr_handle_t *srh, unsigned char cmd,
- struct sdb_session *session, struct sdb_logon *logon,
- struct sdb_netuse *netuse);
-
-static int smbrdr_hdr_setup(smbrdr_handle_t *srh);
-
-static DWORD smbrdr_hdr_process(smbrdr_handle_t *srh, smb_hdr_t *smb_hdr);
-
-static int smbrdr_sign(smb_sign_ctx_t *sign_ctx, smb_msgbuf_t *mb);
-static int smbrdr_sign_chk(smb_sign_ctx_t *sign_ctx, smb_msgbuf_t *mb,
- unsigned char *signature);
+static DWORD smbrdr_handle_setup(smbrdr_handle_t *, unsigned char,
+ struct sdb_session *, struct sdb_logon *, struct sdb_netuse *);
+static int smbrdr_hdr_setup(smbrdr_handle_t *);
+static DWORD smbrdr_hdr_process(smbrdr_handle_t *, smb_hdr_t *);
+static int smbrdr_sign(smb_sign_ctx_t *, smb_msgbuf_t *);
+static int smbrdr_sign_chk(smb_sign_ctx_t *, smb_msgbuf_t *, unsigned char *);
void smbrdr_lock_transport() { nb_lock(); }
void smbrdr_unlock_transport() { nb_unlock(); }
@@ -73,13 +68,10 @@ smbrdr_request_init(smbrdr_handle_t *srh,
DWORD status;
status = smbrdr_handle_setup(srh, cmd, session, logon, netuse);
- if (status != NT_STATUS_SUCCESS) {
- syslog(LOG_DEBUG, "Smbrdr[%d]: initialization failed", cmd);
+ if (status != NT_STATUS_SUCCESS)
return (status);
- }
if (smbrdr_hdr_setup(srh) < SMB_HEADER_LEN) {
- syslog(LOG_DEBUG, "Smbrdr[%d]: cannot setup header", cmd);
smbrdr_handle_free(srh);
return (NT_STATUS_INTERNAL_ERROR);
}
@@ -105,8 +97,11 @@ smbrdr_send(smbrdr_handle_t *srh)
int rc;
if (smbrdr_sign(&srh->srh_session->sign_ctx, &srh->srh_mbuf) !=
- SMBAUTH_SUCCESS)
+ SMBAUTH_SUCCESS) {
+ syslog(LOG_DEBUG, "smbrdr_send[%d]: signing failed",
+ srh->srh_cmd);
return (NT_STATUS_INTERNAL_ERROR);
+ }
rc = nb_send(srh->srh_session->sock, srh->srh_buf,
smb_msgbuf_used(&srh->srh_mbuf));
@@ -163,7 +158,6 @@ smbrdr_rcv(smbrdr_handle_t *srh, int is_first_rsp)
return (NT_STATUS_UNEXPECTED_NETWORK_ERROR);
}
- /* initialize for processing response */
smb_msgbuf_init(&srh->srh_mbuf, srh->srh_buf, rc, srh->srh_mbflags);
status = smbrdr_hdr_process(srh, &smb_hdr);
@@ -177,7 +171,7 @@ smbrdr_rcv(smbrdr_handle_t *srh, int is_first_rsp)
if (!smbrdr_sign_chk(sign_ctx,
&srh->srh_mbuf, smb_hdr.extra.extra.security_sig)) {
- syslog(LOG_ERR, "SmbrdrExchange[%d]: bad signature",
+ syslog(LOG_DEBUG, "smbrdr_rcv[%d]: bad signature",
srh->srh_cmd);
return (NT_STATUS_INVALID_NETWORK_RESPONSE);
}
@@ -217,15 +211,18 @@ smbrdr_exchange(smbrdr_handle_t *srh, smb_hdr_t *smb_hdr, long timeout)
mb = &srh->srh_mbuf;
sign_ctx = &srh->srh_session->sign_ctx;
- if (smbrdr_sign(sign_ctx, mb) != SMBAUTH_SUCCESS)
+ if (smbrdr_sign(sign_ctx, mb) != SMBAUTH_SUCCESS) {
+ syslog(LOG_DEBUG, "smbrdr_exchange[%d]: signing failed",
+ srh->srh_cmd);
return (NT_STATUS_INTERNAL_ERROR);
+ }
rc = nb_exchange(srh->srh_session->sock,
srh->srh_buf, smb_msgbuf_used(mb),
srh->srh_buf, SMBRDR_REQ_BUFSZ, timeout);
if (rc < 0) {
- syslog(LOG_ERR, "SmbrdrExchange[%d]: failed (%d)",
+ syslog(LOG_DEBUG, "smbrdr_exchange[%d]: failed (%d)",
srh->srh_cmd, rc);
if (srh->srh_cmd != SMB_COM_ECHO) {
@@ -251,7 +248,7 @@ smbrdr_exchange(smbrdr_handle_t *srh, smb_hdr_t *smb_hdr, long timeout)
/* Signature validation */
if (!smbrdr_sign_chk(sign_ctx, mb, smb_hdr->extra.extra.security_sig)) {
- syslog(LOG_ERR, "SmbrdrExchange[%d]: bad signature",
+ syslog(LOG_DEBUG, "smbrdr_exchange[%d]: bad signature",
srh->srh_cmd);
return (NT_STATUS_INVALID_NETWORK_RESPONSE);
}
@@ -313,14 +310,12 @@ smbrdr_sign_init(struct sdb_session *session, struct sdb_logon *logon)
if ((sign_ctx->ssc_flags & SMB_SCF_REQUIRED) &&
!(sign_ctx->ssc_flags & SMB_SCF_STARTED) &&
(logon->type != SDB_LOGON_ANONYMOUS)) {
- if (smb_mac_init(sign_ctx, &logon->auth) != SMBAUTH_SUCCESS) {
- syslog(LOG_DEBUG, "SmbrdrSignInit: mac_init failed");
+ if (smb_mac_init(sign_ctx, &logon->auth) != SMBAUTH_SUCCESS)
return (-1);
- }
+
sign_ctx->ssc_flags |=
(SMB_SCF_STARTED | SMB_SCF_KEY_ISSET_THIS_LOGON);
session->smb_flags2 |= SMB_FLAGS2_SMB_SECURITY_SIGNATURE;
- syslog(LOG_DEBUG, "SmbrdrSignInit: mac key is set");
rc = 1;
}
@@ -333,23 +328,16 @@ smbrdr_sign_init(struct sdb_session *session, struct sdb_logon *logon)
* Invalidate the MAC key if the first non-anonymous/non-guest user logon
* fail.
*/
-int
+void
smbrdr_sign_fini(struct sdb_session *session)
{
- smb_sign_ctx_t *sign_ctx;
- int rc = 0;
-
- sign_ctx = &session->sign_ctx;
+ smb_sign_ctx_t *sign_ctx = &session->sign_ctx;
if (sign_ctx->ssc_flags & SMB_SCF_KEY_ISSET_THIS_LOGON) {
sign_ctx->ssc_flags &= ~SMB_SCF_STARTED;
sign_ctx->ssc_flags &= ~SMB_SCF_KEY_ISSET_THIS_LOGON;
sign_ctx->ssc_seqnum = 0;
- syslog(LOG_DEBUG, "SmbrdrSignFini: packet signing stopped");
- rc = 1;
}
-
- return (rc);
}
/*
@@ -359,21 +347,12 @@ smbrdr_sign_fini(struct sdb_session *session)
* SmbSessionSetupAndX request for the first non-anonymous/non-guest
* logon.
*/
-int
+void
smbrdr_sign_unset_key(struct sdb_session *session)
{
- smb_sign_ctx_t *sign_ctx;
- int rc = 0;
-
- sign_ctx = &session->sign_ctx;
-
- if (sign_ctx->ssc_flags & SMB_SCF_KEY_ISSET_THIS_LOGON) {
- sign_ctx->ssc_flags &= ~SMB_SCF_KEY_ISSET_THIS_LOGON;
- syslog(LOG_DEBUG, "SmbrdrSignUnsetKey: unset KEY_ISSET flag");
- rc = 1;
- }
+ smb_sign_ctx_t *sign_ctx = &session->sign_ctx;
- return (rc);
+ sign_ctx->ssc_flags &= ~SMB_SCF_KEY_ISSET_THIS_LOGON;
}
/*
@@ -396,10 +375,9 @@ smbrdr_handle_setup(smbrdr_handle_t *srh,
struct sdb_netuse *netuse)
{
srh->srh_buf = (unsigned char *)malloc(SMBRDR_REQ_BUFSZ);
- if (srh->srh_buf == 0) {
- syslog(LOG_ERR, "Smbrdr[%d]: resource shortage", cmd);
+ if (srh->srh_buf == NULL)
return (NT_STATUS_NO_MEMORY);
- }
+
bzero(srh->srh_buf, SMBRDR_REQ_BUFSZ);
srh->srh_mbflags = (session->remote_caps & CAP_UNICODE)
@@ -468,6 +446,10 @@ smb_decode_nt_hdr(smb_msgbuf_t *mb, smb_hdr_t *hdr)
* Assuming 'srh->srh_mbuf' contains a response from a Windows client,
* decodes the 32 bytes SMB header.
*
+ * Buffer overflow typically means that the server has more data than
+ * it could fit in the response buffer. The client can use subsequent
+ * SmbReadX requests to obtain the remaining data (KB 193839).
+ *
* Returns:
*
* NT_STATUS_INVALID_NETWORK_RESPONSE error decoding the header
@@ -480,43 +462,26 @@ smbrdr_hdr_process(smbrdr_handle_t *srh, smb_hdr_t *smb_hdr)
{
int rc;
- /*
- * Returns the number of decoded bytes on success
- * or some negative MSGBUF_XXX error code on failure
- */
rc = smb_decode_nt_hdr(&srh->srh_mbuf, smb_hdr);
-
if (rc < SMB_HEADER_LEN) {
- syslog(LOG_ERR, "Smbrdr[%d]: bad SMB header (%d)",
+ syslog(LOG_DEBUG, "smbrdr[%d]: invalid header (%d)",
srh->srh_cmd, rc);
return (NT_STATUS_INVALID_NETWORK_RESPONSE);
}
- if (smb_hdr->status.ntstatus != 0) {
- /*
- * MSDN article: 193839
- * "The buffer overflow status is usually returned by a Windows
- * server to inform the client that there is more data in its
- * buffer than it could put in the packet.
- *
- * The buffer overflow should not be considered as an error.
- * Subsequent SmbReadX request is required to obtain the
- * remaining data in the server's buffer.
- */
- if (NT_SC_VALUE(smb_hdr->status.ntstatus)
- == NT_STATUS_BUFFER_OVERFLOW) {
- syslog(LOG_DEBUG, "Smbrdr[%d]: %s", srh->srh_cmd,
- xlate_nt_status(smb_hdr->status.ntstatus));
- } else {
- syslog(LOG_ERR, "Smbrdr[%d]: request failed (%s)",
- srh->srh_cmd,
- xlate_nt_status(smb_hdr->status.ntstatus));
- return (smb_hdr->status.ntstatus);
- }
+ switch (NT_SC_VALUE(smb_hdr->status.ntstatus)) {
+ case NT_STATUS_SUCCESS:
+ case NT_STATUS_BUFFER_OVERFLOW:
+ break;
+
+ default:
+ syslog(LOG_DEBUG, "smbrdr[%d]: request failed (%s)",
+ srh->srh_cmd, xlate_nt_status(smb_hdr->status.ntstatus));
+ return (smb_hdr->status.ntstatus);
}
if (smb_hdr->command != srh->srh_cmd) {
- syslog(LOG_ERR, "Smbrdr[%d]: reply mismatch (%d)",
+ syslog(LOG_DEBUG, "smbrdr[%d]: reply mismatch (%d)",
srh->srh_cmd, smb_hdr->command);
return (NT_STATUS_REPLY_MESSAGE_MISMATCH);
}
@@ -551,8 +516,7 @@ smbrdr_sign(smb_sign_ctx_t *sign_ctx, smb_msgbuf_t *mb)
{
if (sign_ctx->ssc_flags & SMB_SCF_STARTED) {
if (sign_ctx->ssc_seqnum % 2) {
- syslog(LOG_DEBUG, "SmbrdrSign: even sequence number"
- " is expected(%d)",
+ syslog(LOG_DEBUG, "smbrdr_sign: invalid sequence (%d)",
sign_ctx->ssc_seqnum);
}
if (smb_mac_sign(sign_ctx, smb_msgbuf_base(mb),
diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_logon.c b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_logon.c
index d33f253b29..374afe8c6f 100644
--- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_logon.c
+++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_logon.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,6 +34,7 @@
#include <strings.h>
#include <syslog.h>
#include <synch.h>
+#include <sys/errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -44,10 +45,10 @@
#include <smbrdr_ipc_util.h>
#include <smbrdr.h>
-static int mlsvc_anonymous_logon(char *domain_controller, char *domain_name);
-static int mlsvc_auth_logon(char *domain_controller, char *domain_name,
- char *username, unsigned char *pwd_hash);
-static int smbrdr_smb_session_setupandx(struct sdb_logon *logon);
+static int smbrdr_anonymous_logon(char *domain_controller, char *domain_name);
+static int smbrdr_auth_logon(char *domain_controller, char *domain_name,
+ char *username);
+static int smbrdr_session_setupx(struct sdb_logon *logon);
static boolean_t smbrdr_logon_validate(char *server, char *username);
static struct sdb_logon *smbrdr_logon_init(struct sdb_session *session,
char *username, unsigned char *pwd);
@@ -58,7 +59,7 @@ static int smbrdr_authenticate(char *primary_domain, char *account_name,
/*
* mlsvc_logon
*
- * If the username is NULL, an anonymous session will be established.
+ * If the username is MLSVC_ANON_USER, an anonymous session will be established.
* Otherwise, an authenticated session will be established based on the
* specified credentials.
*/
@@ -66,48 +67,39 @@ int
mlsvc_logon(char *domain_controller, char *domain, char *username)
{
int rc;
- unsigned char *pwd_hash = NULL;
- if (username) {
- pwd_hash = smbrdr_ipc_get_passwd();
- rc = mlsvc_auth_logon(domain_controller, domain, username,
- pwd_hash);
- } else {
- rc = mlsvc_anonymous_logon(domain_controller, domain);
- }
+ if (strcmp(username, MLSVC_ANON_USER) == 0)
+ rc = smbrdr_anonymous_logon(domain_controller, domain);
+ else
+ rc = smbrdr_auth_logon(domain_controller, domain, username);
return (rc);
}
/*
- * mlsvc_anonymous_logon
+ * smbrdr_anonymous_logon
*
* Set up an anonymous session. If the session to the resource domain
* controller appears to be okay we shouldn't need to do anything here.
* Otherwise we clean up the stale session and create a new one.
*/
static int
-mlsvc_anonymous_logon(char *domain_controller, char *domain_name)
+smbrdr_anonymous_logon(char *domain_controller, char *domain_name)
{
- int rc = 0;
-
if (smbrdr_logon_validate(domain_controller, MLSVC_ANON_USER))
- /* session & user are good use them */
return (0);
-
if (smbrdr_negotiate(domain_name) != 0) {
- syslog(LOG_ERR, "smbrdr: (anon logon) negotiate <%s> failed",
- (domain_name ? domain_name : "NoName"));
+ syslog(LOG_DEBUG, "smbrdr_anonymous_logon: negotiate failed");
return (-1);
}
if (smbrdr_logon_user(domain_controller, MLSVC_ANON_USER, 0) < 0) {
- syslog(LOG_ERR, "smbrdr: (anon logon) logon failed");
- rc = -1;
+ syslog(LOG_DEBUG, "smbrdr_anonymous_logon: logon failed");
+ return (-1);
}
- return (rc);
+ return (0);
}
int
@@ -131,7 +123,7 @@ mlsvc_user_getauth(char *domain_controller, char *username,
}
/*
- * mlsvc_auth_logon
+ * smbrdr_auth_logon
*
* Set up a user session. If the session to the resource domain controller
* appears to be okay we shouldn't need to do anything here. Otherwise we
@@ -140,18 +132,19 @@ mlsvc_user_getauth(char *domain_controller, char *username,
* due to an inactivity timeout or a domain controller reset.
*/
static int
-mlsvc_auth_logon(char *domain_controller, char *domain_name, char *username,
- unsigned char *pwd_hash)
+smbrdr_auth_logon(char *domain_controller, char *domain_name, char *username)
{
int erc;
+ unsigned char *pwd_hash = NULL;
if (username == NULL || *username == 0) {
- syslog(LOG_ERR, "smbrdr: auth logon (no username)");
+ syslog(LOG_DEBUG, "smbrdr_auth_logon: no username");
return (-1);
}
+ pwd_hash = smbrdr_ipc_get_passwd();
if (!pwd_hash || *pwd_hash == 0) {
- syslog(LOG_ERR, "smbrdr: auth logon (no password)");
+ syslog(LOG_DEBUG, "smbrdr_auth_logon: no password");
return (-1);
}
@@ -159,7 +152,7 @@ mlsvc_auth_logon(char *domain_controller, char *domain_name, char *username,
return (0);
if (smbrdr_negotiate(domain_name) != 0) {
- syslog(LOG_ERR, "smbrdr: admin logon (negotiate failed)");
+ syslog(LOG_DEBUG, "smbrdr_auth_logon: negotiate failed");
return (-1);
}
@@ -189,7 +182,7 @@ smbrdr_authenticate(char *primary_domain, char *account_name,
if ((di = smb_getdomaininfo(0)) == 0) {
- syslog(LOG_ERR, "MlsvcAuthenticate[%s]: %s", account_name,
+ syslog(LOG_DEBUG, "smbrdr_authenticate[%s]: %s", account_name,
xlate_nt_status(NT_STATUS_CANT_ACCESS_DOMAIN_INFO));
return (-1);
}
@@ -211,7 +204,7 @@ smbrdr_authenticate(char *primary_domain, char *account_name,
* to the resource domain.
*/
if (strcasecmp(di->domain, primary_domain)) {
- syslog(LOG_ERR, "MlsvcAuthenticate: %s\\%s: not account domain",
+ syslog(LOG_DEBUG, "smbrdr_authenticate: %s\\%s: invalid domain",
primary_domain, account_name);
return (-2);
}
@@ -225,9 +218,9 @@ smbrdr_authenticate(char *primary_domain, char *account_name,
* This is the entry point for logging a user onto the domain. The
* session structure should have been obtained via a successful call
* to smbrdr_smb_connect. We allocate a logon structure to hold the
- * user details and attempt to logon using smbrdr_smb_session_setupandx. Note
- * that we expect the password fields to have been encrypted before
- * this call.
+ * user details and attempt to logon using smbrdr_session_setupx.
+ * Note that we expect the password fields to have been encrypted
+ * before this call.
*
* On success, the logon structure will be returned. Otherwise a null
* pointer will be returned.
@@ -245,8 +238,8 @@ smbrdr_logon_user(char *server, char *username, unsigned char *pwd)
}
session = smbrdr_session_lock(server, 0, SDB_SLCK_WRITE);
- if (session == 0) {
- syslog(LOG_ERR, "smbrdr: (logon[%s]) no session with %s",
+ if (session == NULL) {
+ syslog(LOG_DEBUG, "smbrdr_logon_user: %s: no session with %s",
username, server);
return (-1);
}
@@ -267,14 +260,14 @@ smbrdr_logon_user(char *server, char *username, unsigned char *pwd)
logon = smbrdr_logon_init(session, username, pwd);
- if (logon == 0) {
- syslog(LOG_ERR, "smbrdr: (logon[%s]) resource shortage",
- username);
+ if (logon == NULL) {
+ syslog(LOG_DEBUG, "smbrdr_logon_user: %s: %s",
+ username, strerror(ENOMEM));
smbrdr_session_unlock(session);
return (-1);
}
- if (smbrdr_smb_session_setupandx(logon) < 0) {
+ if (smbrdr_session_setupx(logon) < 0) {
free(logon);
smbrdr_session_unlock(session);
return (-1);
@@ -284,7 +277,7 @@ smbrdr_logon_user(char *server, char *username, unsigned char *pwd)
free(logon);
if (old_logon.type != SDB_LOGON_NONE) {
- (void) smbrdr_smb_logoff(&old_logon);
+ (void) smbrdr_logoffx(&old_logon);
}
smbrdr_session_unlock(session);
@@ -294,7 +287,7 @@ smbrdr_logon_user(char *server, char *username, unsigned char *pwd)
/*
- * smbrdr_smb_session_setupandx
+ * smbrdr_session_setupx
*
* Build and send an SMB session setup command. This is used to log a
* user onto the domain. See CIFS section 4.1.2.
@@ -302,7 +295,7 @@ smbrdr_logon_user(char *server, char *username, unsigned char *pwd)
* Returns 0 on success. Otherwise returns a -ve error code.
*/
static int
-smbrdr_smb_session_setupandx(struct sdb_logon *logon)
+smbrdr_session_setupx(struct sdb_logon *logon)
{
struct sdb_session *session;
smb_hdr_t smb_hdr;
@@ -322,10 +315,8 @@ smbrdr_smb_session_setupandx(struct sdb_logon *logon)
* Paranoia check - we should never get this
* far without a valid session structure.
*/
- if ((session = logon->session) == 0) {
- syslog(LOG_ERR, "smbrdr_smb_session_setupandx: no data");
+ if ((session = logon->session) == NULL)
return (-1);
- }
if (session->remote_caps & CAP_UNICODE) {
strlen_fn = mts_wcequiv_strlen;
@@ -336,15 +327,18 @@ smbrdr_smb_session_setupandx(struct sdb_logon *logon)
null_size = sizeof (char);
}
- if (smbrdr_sign_init(session, logon) < 0)
+ if (smbrdr_sign_init(session, logon) < 0) {
+ syslog(LOG_DEBUG,
+ "smbrdr_session_setupx: smbrdr_sign_init failed");
return (-1);
+ }
status = smbrdr_request_init(&srh, SMB_COM_SESSION_SETUP_ANDX,
session, 0, 0);
if (status != NT_STATUS_SUCCESS) {
- (void) smbrdr_sign_fini(session);
- syslog(LOG_ERR, "SmbrdrSessionSetup: %s",
+ smbrdr_sign_fini(session);
+ syslog(LOG_DEBUG, "smbrdr_session_setupx: %s",
xlate_nt_status(status));
return (-1);
}
@@ -415,18 +409,18 @@ smbrdr_smb_session_setupandx(struct sdb_logon *logon)
}
if (rc <= 0) {
- syslog(LOG_ERR, "smbrdr_smb_session_setupandx: encode failed");
+ syslog(LOG_DEBUG, "smbrdr_session_setupx: encode failed");
smbrdr_handle_free(&srh);
- (void) smbrdr_sign_fini(session);
+ smbrdr_sign_fini(session);
return (-1);
}
status = smbrdr_exchange(&srh, &smb_hdr, 0);
if (status != NT_STATUS_SUCCESS) {
- syslog(LOG_ERR, "SmbrdrSessionSetup: %s",
+ syslog(LOG_DEBUG, "smbrdr_session_setupx: %s",
xlate_nt_status(status));
smbrdr_handle_free(&srh);
- (void) smbrdr_sign_fini(session);
+ smbrdr_sign_fini(session);
return (-1);
}
@@ -461,9 +455,9 @@ smbrdr_smb_session_setupandx(struct sdb_logon *logon)
}
if (rc <= 0) {
- syslog(LOG_ERR, "RdrSessionSetup: decode failed");
+ syslog(LOG_DEBUG, "smbrdr_session_setupx: decode failed");
smbrdr_handle_free(&srh);
- (void) smbrdr_sign_fini(session);
+ smbrdr_sign_fini(session);
return (-1);
}
@@ -476,7 +470,7 @@ smbrdr_smb_session_setupandx(struct sdb_logon *logon)
logon->type = SDB_LOGON_GUEST;
smbrdr_handle_free(&srh);
- (void) smbrdr_sign_unset_key(session);
+ smbrdr_sign_unset_key(session);
logon->state = SDB_LSTATE_SETUP;
@@ -484,7 +478,7 @@ smbrdr_smb_session_setupandx(struct sdb_logon *logon)
}
/*
- * smbrdr_smb_logoff
+ * smbrdr_logoffx
*
* Build and send an SMB session logoff (SMB_COM_LOGOFF_ANDX) command.
* This is the inverse of an SMB_COM_SESSION_SETUP_ANDX. See CIFS
@@ -494,7 +488,7 @@ smbrdr_smb_session_setupandx(struct sdb_logon *logon)
* Returns 0 on success. Otherwise returns a -ve error code.
*/
int
-smbrdr_smb_logoff(struct sdb_logon *logon)
+smbrdr_logoffx(struct sdb_logon *logon)
{
struct sdb_session *session;
smbrdr_handle_t srh;
@@ -527,7 +521,7 @@ smbrdr_smb_logoff(struct sdb_logon *logon)
if (status != NT_STATUS_SUCCESS) {
logon->state = SDB_LSTATE_SETUP;
- syslog(LOG_ERR, "smbrdr: logoff %s (%s)", logon->username,
+ syslog(LOG_DEBUG, "smbrdr_logoffx: %s: %s", logon->username,
xlate_nt_status(status));
return (-1);
}
@@ -536,14 +530,14 @@ smbrdr_smb_logoff(struct sdb_logon *logon)
if (rc < 0) {
logon->state = SDB_LSTATE_SETUP;
smbrdr_handle_free(&srh);
- syslog(LOG_ERR, "smbrdr: logoff %s (encode failed)",
+ syslog(LOG_DEBUG, "smbrdr_logoffx: %s: encode failed",
logon->username);
return (rc);
}
status = smbrdr_exchange(&srh, &smb_hdr, 0);
if (status != NT_STATUS_SUCCESS) {
- syslog(LOG_ERR, "smbrdr: logoff %s (%s)", logon->username,
+ syslog(LOG_DEBUG, "smbrdr_logoffx: %s: %s", logon->username,
xlate_nt_status(status));
rc = -1;
} else {
@@ -570,7 +564,7 @@ smbrdr_logon_init(struct sdb_session *session, char *username,
unsigned char *pwd)
{
struct sdb_logon *logon;
- int smbrdr_lmcompl;
+ int64_t smbrdr_lmcompl;
int rc;
logon = (struct sdb_logon *)malloc(sizeof (sdb_logon_t));
@@ -580,9 +574,7 @@ smbrdr_logon_init(struct sdb_session *session, char *username,
bzero(logon, sizeof (struct sdb_logon));
logon->session = session;
- smb_config_rdlock();
- smbrdr_lmcompl = smb_config_getnum(SMB_CI_LM_LEVEL);
- smb_config_unlock();
+ (void) smb_config_getnum(SMB_CI_LM_LEVEL, &smbrdr_lmcompl);
if (strcmp(username, "IPC$") == 0) {
logon->type = SDB_LOGON_ANONYMOUS;
@@ -625,7 +617,8 @@ smbrdr_logon_validate(char *server, char *username)
valid = B_TRUE;
} else {
session->state = SDB_SSTATE_STALE;
- syslog(LOG_DEBUG, "smbrdr: (logon) stale session");
+ syslog(LOG_DEBUG,
+ "smbrdr_logon_validate: stale session");
}
smbrdr_session_unlock(session);
diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_netbios.c b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_netbios.c
index 2066dab051..756a816378 100644
--- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_netbios.c
+++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_netbios.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -41,7 +41,6 @@
#include <string.h>
#include <unistd.h>
-#include <syslog.h>
#include <synch.h>
#include <sys/types.h>
#include <sys/uio.h>
@@ -128,8 +127,6 @@ nb_keep_alive(int fd)
(void) mutex_lock(&nb_mutex);
rc = nb_write_msg(fd, (unsigned char *)&nothing, 0, SESSION_KEEP_ALIVE);
- if (rc < 0)
- syslog(LOG_ERR, "nb_keep_alive: write failed");
(void) mutex_unlock(&nb_mutex);
return (rc);
@@ -145,9 +142,7 @@ nb_send(int fd, unsigned char *send_buf, unsigned send_cnt)
{
int rc;
- if ((rc = nb_write_msg(fd, send_buf, send_cnt, SESSION_MESSAGE)) < 0)
- syslog(LOG_ERR, "nb_send: write failed: rc=%d", rc);
-
+ rc = nb_write_msg(fd, send_buf, send_cnt, SESSION_MESSAGE);
return (rc);
}
@@ -166,16 +161,12 @@ nb_rcv(int fd, unsigned char *recv_buf, unsigned recv_max, long timeout)
do {
rc = nb_read_msg(fd, recv_buf, recv_max, &type, timeout);
- if (rc < 0) {
- syslog(LOG_ERR, "nb_rcv: read failed: rc=%d", rc);
+ if (rc < 0)
return (rc);
- }
} while (type == SESSION_KEEP_ALIVE);
- if (type != SESSION_MESSAGE) {
- syslog(LOG_ERR, "nb_rcv: invalid type: %d", type);
+ if (type != SESSION_MESSAGE)
return (NB_RCV_MSG_ERR_INVTYPE);
- }
return (rc);
}
@@ -236,8 +227,6 @@ nb_session_request(int fd, char *called_name, char *called_scope,
rc = nb_write_msg(fd, (unsigned char *)sr_buf, len, SESSION_REQUEST);
if (rc < 0) {
- syslog(LOG_ERR, "nb_session_request: write failed:"
- " rc=%d", rc);
(void) mutex_unlock(&nb_mutex);
return (rc);
}
@@ -287,7 +276,6 @@ nb_write_msg(int fd, unsigned char *buf, unsigned count, int type)
/*
* We should never see descriptor 0 (stdin).
*/
- syslog(LOG_ERR, "nb_write_msg: invalid descriptor (%d)", fd);
return (-1);
}
@@ -310,7 +298,6 @@ nb_write_msg(int fd, unsigned char *buf, unsigned count, int type)
rc = writev(fd, iov, 2);
if (rc != 4 + count) {
- syslog(LOG_ERR, "nb_write_msg: writev rc=%d", rc);
return (-3); /* error */
}
@@ -340,7 +327,6 @@ nb_read_msg(int fd, unsigned char *buf, unsigned max_buf,
/*
* We should never see descriptor 0 (stdin).
*/
- syslog(LOG_ERR, "nb_write_msg: invalid descriptor (%d)", fd);
return (NB_READ_MSG_ERR);
}
@@ -350,7 +336,6 @@ nb_read_msg(int fd, unsigned char *buf, unsigned max_buf,
tval.tv_usec = 0;
if ((rc = select(fd + 1, &readfds, 0, 0, &tval)) <= 0) {
- syslog(LOG_ERR, "nb_read_msg: select: %d", rc);
return (NB_READ_MSG_ERR);
}
diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_netuse.c b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_netuse.c
index 508b258cd6..2cb74e66e8 100644
--- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_netuse.c
+++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_netuse.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,6 +31,7 @@
* Specification (December 19, 1997).
*/
+#include <sys/errno.h>
#include <string.h>
#include <strings.h>
#include <syslog.h>
@@ -38,7 +39,6 @@
#include <pthread.h>
#include <smbsrv/libsmbrdr.h>
-
#include <smbrdr.h>
#include <smbsrv/ntstatus.h>
@@ -48,12 +48,12 @@
*/
static struct sdb_netuse netuse_table[N_NETUSE_TABLE];
-static int smbrdr_smb_tcon(struct sdb_session *session,
+static int smbrdr_tree_connectx(struct sdb_session *session,
struct sdb_netuse *netuse, char *path, int path_len);
static struct sdb_netuse *smbrdr_netuse_alloc(struct sdb_session *session,
char *sharename);
-static int smbrdr_smb_tdcon(struct sdb_netuse *netuse);
+static int smbrdr_tdcon(struct sdb_netuse *netuse);
static void
smbrdr_netuse_clear(struct sdb_netuse *netuse)
@@ -69,19 +69,19 @@ smbrdr_netuse_free(struct sdb_netuse *netuse)
}
/*
- * mlsvc_tree_connect
+ * smbrdr_tree_connect
*
* Establish a share (tree connect). We need to retrieve the session
* for the specified host and allocate a netuse structure. We set up
* the path here (UNC encoded) to make handling the malloc/free easier
- * and pass everything on to smbrdr_smb_tcon where, if everything goes well,
- * a valid tid will be stored in the netuse structure.
+ * and pass everything on to smbrdr_tree_connectx where. If everything
+ * goes well, a valid tid will be stored in the netuse structure.
*
* On success, a pointer to the netuse is returned. Otherwise the
* netuse is cleared and a null pointer is returned.
*/
unsigned short
-mlsvc_tree_connect(char *hostname, char *username, char *sharename)
+smbrdr_tree_connect(char *hostname, char *username, char *sharename)
{
struct sdb_session *session;
struct sdb_netuse *netuse;
@@ -92,15 +92,15 @@ mlsvc_tree_connect(char *hostname, char *username, char *sharename)
* Make sure there is a session & logon for given info
*/
session = smbrdr_session_lock(hostname, username, SDB_SLCK_READ);
- if (session == 0) {
- syslog(LOG_ERR, "smbrdr: (tcon) no session for %s@%s",
+ if (session == NULL) {
+ syslog(LOG_DEBUG, "smbrdr_tree_connect: no session for %s@%s",
username, hostname);
return (0);
}
if ((netuse = smbrdr_netuse_alloc(session, sharename)) == 0) {
- syslog(LOG_ERR, "smbrdr: (tcon) init failed");
+ syslog(LOG_DEBUG, "smbrdr_tree_connect: init failed");
smbrdr_session_unlock(session);
return (0);
}
@@ -114,7 +114,7 @@ mlsvc_tree_connect(char *hostname, char *username, char *sharename)
if ((path = (char *)malloc(path_len)) == 0) {
smbrdr_netuse_free(netuse);
smbrdr_session_unlock(session);
- syslog(LOG_ERR, "smbrdr: (tcon) resource shortage");
+ syslog(LOG_DEBUG, "smbrdr_tree_connect: %s", strerror(ENOMEM));
return (0);
}
@@ -125,11 +125,11 @@ mlsvc_tree_connect(char *hostname, char *username, char *sharename)
else
path_len = strlen(path);
- if (smbrdr_smb_tcon(session, netuse, path, path_len) < 0) {
+ if (smbrdr_tree_connectx(session, netuse, path, path_len) < 0) {
smbrdr_netuse_free(netuse);
smbrdr_session_unlock(session);
free(path);
- syslog(LOG_ERR, "smbrdr: (tcon) failed connecting to %s", path);
+ syslog(LOG_DEBUG, "smbrdr_tree_connect: %s failed", path);
return (0);
}
@@ -141,7 +141,7 @@ mlsvc_tree_connect(char *hostname, char *username, char *sharename)
/*
- * smbrdr_smb_tcon
+ * smbrdr_tree_connectx
*
* This message requests a share (tree connect) request to the server
* associated with the session. The password is not relevant here if
@@ -151,7 +151,7 @@ mlsvc_tree_connect(char *hostname, char *username, char *sharename)
* Returns 0 on success. Otherwise returns a -ve error code.
*/
static int
-smbrdr_smb_tcon(struct sdb_session *session, struct sdb_netuse *netuse,
+smbrdr_tree_connectx(struct sdb_session *session, struct sdb_netuse *netuse,
char *path, int path_len)
{
smb_hdr_t smb_hdr;
@@ -170,7 +170,8 @@ smbrdr_smb_tcon(struct sdb_session *session, struct sdb_netuse *netuse,
session, &session->logon, 0);
if (status != NT_STATUS_SUCCESS) {
- syslog(LOG_ERR, "SmbrdrTcon: %s", xlate_nt_status(status));
+ syslog(LOG_DEBUG, "smbrdr_tree_connectx: %s",
+ xlate_nt_status(status));
return (-1);
}
@@ -202,26 +203,25 @@ smbrdr_smb_tcon(struct sdb_session *session, struct sdb_netuse *netuse,
service); /* Service */
if (rc <= 0) {
- syslog(LOG_ERR, "smbrdr_smb_tcon: encode failed");
+ syslog(LOG_DEBUG, "smbrdr_tree_connectx: encode failed");
smbrdr_handle_free(&srh);
return (-1);
}
status = smbrdr_exchange(&srh, &smb_hdr, 0);
if (status != NT_STATUS_SUCCESS) {
- syslog(LOG_ERR, "SmbrdrTcon: %s", xlate_nt_status(status));
- rc = -1;
- } else {
- rc = 0;
+ syslog(LOG_DEBUG, "smbrdr_tree_connectx: %s",
+ xlate_nt_status(status));
+ smbrdr_handle_free(&srh);
+ return (-1);
}
netuse->tid = smb_hdr.tid;
netuse->state = SDB_NSTATE_CONNECTED;
smbrdr_handle_free(&srh);
- return (rc);
+ return (0);
}
-
/*
* smbrdr_netuse_logoff
*
@@ -242,7 +242,7 @@ smbrdr_netuse_logoff(unsigned short uid)
netuse = &netuse_table[i];
(void) mutex_lock(&netuse->mtx);
if (netuse->uid == uid)
- (void) smbrdr_smb_tdcon(netuse);
+ (void) smbrdr_tdcon(netuse);
(void) mutex_unlock(&netuse->mtx);
}
}
@@ -255,7 +255,7 @@ smbrdr_tree_disconnect(unsigned short tid)
netuse = smbrdr_netuse_get(tid);
if (netuse) {
- (void) smbrdr_smb_tdcon(netuse);
+ (void) smbrdr_tdcon(netuse);
smbrdr_netuse_put(netuse);
rc = 0;
}
@@ -264,17 +264,17 @@ smbrdr_tree_disconnect(unsigned short tid)
}
/*
- * smbrdr_smb_tdcon
+ * smbrdr_tdcon
*
* Disconnect a share. This message informs the server that we no longer
* wish to access the resource specified by tid, obtained via a prior
- * mlsvc_tree_connect. The tid is passed in the SMB header so the setup
+ * smbrdr_tree_connect. The tid is passed in the SMB header so the setup
* for this call is very straightforward.
*
* Returns 0 on success. Otherwise returns a -ve error code.
*/
static int
-smbrdr_smb_tdcon(struct sdb_netuse *netuse)
+smbrdr_tdcon(struct sdb_netuse *netuse)
{
struct sdb_session *session;
smbrdr_handle_t srh;
@@ -285,7 +285,7 @@ smbrdr_smb_tdcon(struct sdb_netuse *netuse)
netuse->state = SDB_NSTATE_DISCONNECTING;
smbrdr_ofile_end_of_share(netuse->tid);
- if ((session = netuse->session) == 0) {
+ if ((session = netuse->session) == NULL) {
smbrdr_netuse_clear(netuse);
return (0);
}
@@ -300,7 +300,7 @@ smbrdr_smb_tdcon(struct sdb_netuse *netuse)
session, &session->logon, netuse);
if (status != NT_STATUS_SUCCESS) {
- syslog(LOG_ERR, "smbrdr: (tdcon) %s", xlate_nt_status(status));
+ syslog(LOG_DEBUG, "smbrdr_tdcon: %s", xlate_nt_status(status));
/* should we clear here? */
smbrdr_netuse_clear(netuse);
return (-1);
@@ -308,7 +308,7 @@ smbrdr_smb_tdcon(struct sdb_netuse *netuse)
rc = smb_msgbuf_encode(&srh.srh_mbuf, "bw.", 0, 0);
if (rc < 0) {
- syslog(LOG_ERR, "smbrdr: (tdcon) encode failed");
+ syslog(LOG_DEBUG, "smbrdr_tdcon: encode failed");
smbrdr_handle_free(&srh);
/* should we clear here? */
smbrdr_netuse_clear(netuse);
@@ -317,7 +317,7 @@ smbrdr_smb_tdcon(struct sdb_netuse *netuse)
status = smbrdr_exchange(&srh, &smb_hdr, 0);
if (status != NT_STATUS_SUCCESS) {
- syslog(LOG_ERR, "smbrdr: (tdcon) %s", xlate_nt_status(status));
+ syslog(LOG_DEBUG, "smbrdr_tdcon: %s", xlate_nt_status(status));
rc = -1;
} else {
rc = 0;
@@ -347,10 +347,8 @@ smbrdr_netuse_alloc(struct sdb_session *session, char *sharename)
struct sdb_netuse *netuse;
int i;
- if (session == 0 || sharename == 0) {
- syslog(LOG_ERR, "smbrdr: (tcon) invalid arg");
- return (0);
- }
+ if (session == NULL || sharename == NULL)
+ return (NULL);
for (i = 0; i < N_NETUSE_TABLE; ++i) {
netuse = &netuse_table[i];
@@ -369,7 +367,7 @@ smbrdr_netuse_alloc(struct sdb_session *session, char *sharename)
(void) mutex_unlock(&netuse->mtx);
}
- syslog(LOG_WARNING, "smbrdr: (tcon) table full");
+ syslog(LOG_DEBUG, "smbrdr_netuse_alloc: table full");
return (0);
}
@@ -431,7 +429,7 @@ smbrdr_netuse_get(int tid)
(void) mutex_unlock(&netuse->mtx);
}
- syslog(LOG_WARNING, "smbrdr: (lookup) no such TID %d", tid);
+ syslog(LOG_DEBUG, "smbrdr_netuse_get: %d: no such TID", tid);
return (0);
}
diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_read_andx.c b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_read_andx.c
index ef90fa79ac..3b2fc4dd7a 100644
--- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_read_andx.c
+++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_read_andx.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -33,7 +33,6 @@
#include <strings.h>
#include <smbsrv/libsmbrdr.h>
-
#include <smbsrv/netbios.h>
#include <smbsrv/ntstatus.h>
#include <smbrdr.h>
@@ -46,15 +45,13 @@
static int smbrdr_decode_readx_rsp(smb_msgbuf_t *, char *, unsigned,
smb_read_andx_rsp_t *);
-static void smbrdr_dump_readx_rsp(smb_read_andx_rsp_t *);
-
/*
- * smbrdr_rpc_readx
+ * smbrdr_readx
*
* Send SMB_COM_READ_ANDX request.
*/
int
-smbrdr_rpc_readx(int fid, char *in_buf, int in_len)
+smbrdr_readx(int fid, char *in_buf, int in_len)
{
struct sdb_netuse *netuse;
struct sdb_ofile *ofile;
@@ -64,7 +61,7 @@ smbrdr_rpc_readx(int fid, char *in_buf, int in_len)
DWORD status;
int rc, max_return;
- if ((ofile = smbrdr_ofile_get(fid)) == 0)
+ if ((ofile = smbrdr_ofile_get(fid)) == NULL)
return (-1);
netuse = ofile->netuse;
@@ -73,7 +70,7 @@ smbrdr_rpc_readx(int fid, char *in_buf, int in_len)
netuse->session, &netuse->session->logon, netuse);
if (status != NT_STATUS_SUCCESS) {
- syslog(LOG_ERR, "SmbrdrReadAndx: %s", xlate_nt_status(status));
+ syslog(LOG_DEBUG, "smbrdr_readx: %s", xlate_nt_status(status));
smbrdr_ofile_put(ofile);
return (-1);
}
@@ -104,7 +101,7 @@ smbrdr_rpc_readx(int fid, char *in_buf, int in_len)
0); /* Count of data bytes = 0 */
if (rc < 0) {
- syslog(LOG_ERR, "SmbrdrReadAndx: smbrdr_prep_readx_req failed");
+ syslog(LOG_DEBUG, "smbrdr_readx: prep failed");
smbrdr_handle_free(&srh);
smbrdr_ofile_put(ofile);
return (rc);
@@ -117,14 +114,14 @@ smbrdr_rpc_readx(int fid, char *in_buf, int in_len)
smbrdr_unlock_transport();
smbrdr_handle_free(&srh);
smbrdr_ofile_put(ofile);
- syslog(LOG_ERR, "SmbrdrReadAndx: send failed");
+ syslog(LOG_DEBUG, "smbrdr_readx: send failed");
return (-1);
}
status = smbrdr_rcv(&srh, 1);
if (status != NT_STATUS_SUCCESS) {
- syslog(LOG_ERR, "SmbrdrReadAndx: nb_rcv failed");
+ syslog(LOG_DEBUG, "smbrdr_readx: nb_rcv failed");
smbrdr_unlock_transport();
smbrdr_handle_free(&srh);
smbrdr_ofile_put(ofile);
@@ -134,7 +131,7 @@ smbrdr_rpc_readx(int fid, char *in_buf, int in_len)
rc = smbrdr_decode_readx_rsp(mb, in_buf, in_len, &rsp);
if (rc < 0) {
- syslog(LOG_ERR, "SmbrdrReadAndx: read decode failure!");
+ syslog(LOG_DEBUG, "smbrdr_readx: decode failed");
smbrdr_unlock_transport();
smbrdr_handle_free(&srh);
smbrdr_ofile_put(ofile);
@@ -148,20 +145,6 @@ smbrdr_rpc_readx(int fid, char *in_buf, int in_len)
return ((rc < 0) ? rc : rsp.DataLength);
}
-static void
-smbrdr_dump_readx_rsp(smb_read_andx_rsp_t *rsp)
-{
-
- syslog(LOG_DEBUG, "[SmbReadX Rsp] WordCount:%x,AndXCmd:%x,"
- " AndXReserved:%x, AndXOffset:%d",
- rsp->WordCount, rsp->AndXCmd, rsp->AndXReserved, rsp->AndXOffset);
-
- syslog(LOG_DEBUG, "[SmbReadX Rsp] Remaining:%d, Mode:%d, Reserved:%x, "
- "DataLen:%d, DataOffset:%d, ByteCount: %d",
- rsp->Remaining, rsp->DataCompactionMode, rsp->Reserved,
- rsp->DataLength, rsp->DataOffset, rsp->ByteCount);
-}
-
/*
* smbrdr_decode_readx_rsp
*
@@ -198,9 +181,6 @@ smbrdr_decode_readx_rsp(smb_msgbuf_t *mb,
if (rc <= 0)
return (-1);
- smbrdr_dump_readx_rsp(rsp);
-
- /* it should never happen, but check anyway */
if (rsp->DataLength > in_len)
return (-1);
diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_rpcpipe.c b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_rpcpipe.c
index b89eddf275..3059a0cf0e 100644
--- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_rpcpipe.c
+++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_rpcpipe.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -38,14 +38,12 @@
#include <synch.h>
#include <smbsrv/libsmbrdr.h>
-
#include <smbsrv/ntstatus.h>
#include <smbrdr.h>
-static int smbrdr_smb_close(struct sdb_ofile *ofile);
-static DWORD smbrdr_smb_ntcreate(struct sdb_ofile *ofile);
-static struct sdb_ofile *smbrdr_ofile_alloc(struct sdb_netuse *netuse,
- char *name);
+static int smbrdr_close(struct sdb_ofile *);
+static DWORD smbrdr_ntcreatex(struct sdb_ofile *);
+static struct sdb_ofile *smbrdr_ofile_alloc(struct sdb_netuse *, char *);
static void
smbrdr_ofile_clear(struct sdb_ofile *ofile)
@@ -86,24 +84,24 @@ mlsvc_open_pipe(char *hostname, char *domain, char *username, char *pipename)
int retry;
struct timespec st;
- tid = mlsvc_tree_connect(hostname, username, "IPC$");
+ tid = smbrdr_tree_connect(hostname, username, "IPC$");
if (tid == 0) {
- syslog(LOG_ERR, "smbrdr: (open) %s %s %s %s %s",
+ syslog(LOG_DEBUG, "smbrdr: (open) %s %s %s %s %s",
hostname, domain, username, pipename,
xlate_nt_status(NT_STATUS_UNEXPECTED_NETWORK_ERROR));
return (-1);
}
netuse = smbrdr_netuse_get(tid);
- if (netuse == 0) {
- syslog(LOG_ERR, "smbrdr: (open) %s %s %s %s %s",
+ if (netuse == NULL) {
+ syslog(LOG_DEBUG, "smbrdr: (open) %s %s %s %s %s",
hostname, domain, username, pipename,
xlate_nt_status(NT_STATUS_CONNECTION_INVALID));
return (-1);
}
if ((ofile = smbrdr_ofile_alloc(netuse, pipename)) == 0) {
- syslog(LOG_ERR, "smbrdr: (open) %s %s %s %s %s",
+ syslog(LOG_DEBUG, "smbrdr: (open) %s %s %s %s %s",
hostname, domain, username, pipename,
xlate_nt_status(NT_STATUS_INSUFFICIENT_RESOURCES));
smbrdr_netuse_put(netuse);
@@ -113,7 +111,7 @@ mlsvc_open_pipe(char *hostname, char *domain, char *username, char *pipename)
status = NT_STATUS_OPEN_FAILED;
for (retry = 0; retry < mlsvc_pipe_recon_tries; retry++) {
- status = smbrdr_smb_ntcreate(ofile);
+ status = smbrdr_ntcreatex(ofile);
switch (status) {
case NT_STATUS_SUCCESS:
@@ -163,13 +161,11 @@ mlsvc_close_pipe(int fid)
unsigned short tid;
int rc;
- if ((ofile = smbrdr_ofile_get(fid)) == 0) {
- syslog(LOG_ERR, "mlsvc_close_pipe: unknown file (%d)", fid);
+ if ((ofile = smbrdr_ofile_get(fid)) == NULL)
return (-1);
- }
tid = ofile->tid;
- rc = smbrdr_smb_close(ofile);
+ rc = smbrdr_close(ofile);
smbrdr_ofile_put(ofile);
if (rc == 0)
@@ -238,8 +234,7 @@ smbrdr_ofile_get(int fid)
(void) mutex_unlock(&ofile->mtx);
}
- syslog(LOG_WARNING, "smbrdr: (lookup) no such FID %d", fid);
- return (0);
+ return (NULL);
}
/*
@@ -261,7 +256,7 @@ smbrdr_ofile_end_of_share(unsigned short tid)
ofile = &ofile_table[i];
(void) mutex_lock(&ofile->mtx);
if (ofile->tid == tid)
- (void) smbrdr_smb_close(ofile);
+ (void) smbrdr_close(ofile);
(void) mutex_unlock(&ofile->mtx);
}
}
@@ -300,12 +295,12 @@ smbrdr_dump_ofiles()
*/
/*
- * smbrdr_smb_close
+ * smbrdr_close
*
* Send SMBClose request for the given open file.
*/
static int
-smbrdr_smb_close(struct sdb_ofile *ofile)
+smbrdr_close(struct sdb_ofile *ofile)
{
struct sdb_session *session;
struct sdb_netuse *netuse;
@@ -316,12 +311,12 @@ smbrdr_smb_close(struct sdb_ofile *ofile)
int fid;
int rc;
- if (ofile == 0)
+ if (ofile == NULL)
return (0);
ofile->state = SDB_FSTATE_CLOSING;
- if ((session = ofile->session) == 0) {
+ if ((session = ofile->session) == NULL) {
smbrdr_ofile_clear(ofile);
return (0);
}
@@ -341,20 +336,12 @@ smbrdr_smb_close(struct sdb_ofile *ofile)
session, logon, netuse);
if (status != NT_STATUS_SUCCESS) {
- syslog(LOG_ERR, "SmbrdrClose: %s", xlate_nt_status(status));
smbrdr_ofile_clear(ofile);
return (-1);
}
- rc = smb_msgbuf_encode(&srh.srh_mbuf,
- "(wct)b (fid)w (lwrtm)l (bcc)w (pad).",
- 3, /* WordCount */
- fid, /* Fid */
- 0x00000000ul, /* LastWriteTime */
- 0); /* ByteCount */
-
+ rc = smb_msgbuf_encode(&srh.srh_mbuf, "bwlw.", 3, fid, 0x00000000ul, 0);
if (rc <= 0) {
- syslog(LOG_ERR, "SmbrdrClose: encode failed");
smbrdr_handle_free(&srh);
smbrdr_ofile_clear(ofile);
return (-1);
@@ -362,7 +349,7 @@ smbrdr_smb_close(struct sdb_ofile *ofile)
status = smbrdr_exchange(&srh, &smb_hdr, 0);
if (status != NT_STATUS_SUCCESS)
- syslog(LOG_ERR, "SmbrdrClose: %s", xlate_nt_status(status));
+ syslog(LOG_DEBUG, "smbrdr_close: %s", xlate_nt_status(status));
smbrdr_handle_free(&srh);
smbrdr_ofile_clear(ofile);
@@ -405,19 +392,18 @@ smbrdr_ofile_alloc(struct sdb_netuse *netuse, char *name)
(void) mutex_unlock(&ofile->mtx);
}
- syslog(LOG_WARNING, "smbrdr: (open) table full");
- return (0);
+ return (NULL);
}
/*
- * smbrdr_smb_ntcreate
+ * smbrdr_ntcreatex
*
* This will do an SMB_COM_NT_CREATE_ANDX with lots of default values.
* All of the underlying session and share data should already be set
* up before we get here. If everything works we'll get a valid fid.
*/
static DWORD
-smbrdr_smb_ntcreate(struct sdb_ofile *ofile)
+smbrdr_ntcreatex(struct sdb_ofile *ofile)
{
struct sdb_logon *logon;
struct sdb_netuse *netuse;
@@ -458,13 +444,14 @@ smbrdr_smb_ntcreate(struct sdb_ofile *ofile)
null_size = sizeof (char);
}
- syslog(LOG_DEBUG, "SmbRdrNtCreate: %d %s", path_len, path);
+ syslog(LOG_DEBUG, "smbrdr_ntcreatex: %d %s", path_len, path);
status = smbrdr_request_init(&srh, SMB_COM_NT_CREATE_ANDX,
sess, logon, netuse);
if (status != NT_STATUS_SUCCESS) {
- syslog(LOG_ERR, "SmbrdrNtCreate: %s", xlate_nt_status(status));
+ syslog(LOG_DEBUG, "smbrdr_ntcreatex: %s",
+ xlate_nt_status(status));
return (NT_STATUS_INVALID_PARAMETER_1);
}
diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_session.c b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_session.c
index 535ad537d9..6bcba07778 100644
--- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_session.c
+++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_session.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -61,38 +61,17 @@ static uint16_t smbrdr_ports[] = {
static int smbrdr_nports = sizeof (smbrdr_ports) / sizeof (smbrdr_ports[0]);
-/*
- * Pointer to the PDC location interface.
- * To be set up by SMB when it loads.
- */
-static mlsvc_locate_pdc_t mlsvc_locate_pdc;
-
-/*
- * This is a temporary hack to stop the DC from closing a session
- * due to inactivity.
- */
-#define MLSVC_SESSION_FORCE_KEEPALIVE 10
-
-/*
- * This is the session data table.
- *
- * The rwlock synchronizes access to the session table
- *
- * The mutex is to make session lookup and create atomic
- * so we don't end up with two sessions with the same
- * system.
- */
static struct sdb_session session_table[MLSVC_DOMAIN_MAX];
static mutex_t smbrdr_screate_mtx;
-static unsigned int session_id = 0;
+static uint32_t session_id = 0;
-static struct sdb_session *smbrdr_session_init(smb_ntdomain_t *di);
+static struct sdb_session *smbrdr_session_init(smb_ntdomain_t *);
static int smbrdr_trnsprt_connect(struct sdb_session *, uint16_t);
-static int smbrdr_session_connect(smb_ntdomain_t *di);
-static int smbrdr_smb_negotiate(struct sdb_session *session);
-static int smbrdr_smb_echo(struct sdb_session *session);
-static void smbrdr_session_disconnect(struct sdb_session *session, int cleanup);
-static int smbrdr_locate_dc(char *domain);
+static int smbrdr_session_connect(smb_ntdomain_t *);
+static int smbrdr_smb_negotiate(struct sdb_session *);
+static int smbrdr_echo(struct sdb_session *);
+static void smbrdr_session_disconnect(struct sdb_session *, int);
+
static void
smbrdr_session_clear(struct sdb_session *session)
@@ -101,33 +80,6 @@ smbrdr_session_clear(struct sdb_session *session)
}
/*
- * mlsvc_install_pdc_cb
- *
- * Function to be called by SMB initialization code to set up a
- * callback to the PDC location interface.
- */
-void
-mlsvc_install_pdc_cb(mlsvc_locate_pdc_t locate_pdc_cb)
-{
- mlsvc_locate_pdc = locate_pdc_cb;
-}
-
-/*
- * mlsvc_locate_domain_controller
- *
- * Locate a domain controller. Note that this may close an existing
- * connection to the current domain controller.
- */
-int
-mlsvc_locate_domain_controller(char *domain)
-{
- if (mlsvc_locate_pdc)
- return (mlsvc_locate_pdc(domain));
-
- return (0);
-}
-
-/*
* Entry pointy for smbrdr initialization.
*/
void
@@ -168,25 +120,17 @@ mlsvc_disconnect(char *server)
*
* Returns 0 on success, otherwise -1.
*/
+/*ARGSUSED*/
int
-smbrdr_negotiate(char *domain_name)
+smbrdr_negotiate(char *domain)
{
struct sdb_session *session = 0;
smb_ntdomain_t *di;
int retry = 1;
int res = 0;
- if ((di = smb_getdomaininfo(0)) == 0) {
- /*
- * Attempting to locate a domain controller
- * will shutdown an existing PDC connection.
- */
- (void) smbrdr_locate_dc(domain_name);
- di = smb_getdomaininfo(0);
- }
-
- if (di == 0) {
- syslog(LOG_ERR, "smbrdr: negotiate (cannot access domain)");
+ if ((di = smb_getdomaininfo(0)) == NULL) {
+ syslog(LOG_DEBUG, "smbrdr_negotiate: cannot access domain");
return (-1);
}
@@ -198,7 +142,7 @@ smbrdr_negotiate(char *domain_name)
(void) mutex_lock(&smbrdr_screate_mtx);
while (retry > 0) {
session = smbrdr_session_lock(di->server, 0, SDB_SLCK_WRITE);
- if (session != 0) {
+ if (session != 0) {
if (nb_keep_alive(session->sock) == 0) {
/* session is good, use it */
smbrdr_session_unlock(session);
@@ -212,12 +156,8 @@ smbrdr_negotiate(char *domain_name)
if (smbrdr_session_connect(di) != 0) {
if (retry > 0) {
- /* Do we really need to do this here? */
- (void) smbrdr_locate_dc(domain_name);
di = smb_getdomaininfo(0);
- if (di == 0) {
- syslog(LOG_ERR, "smbrdr: negotiate"
- " (cannot access domain)");
+ if (di == NULL) {
res = -1;
break;
}
@@ -230,6 +170,8 @@ smbrdr_negotiate(char *domain_name)
}
(void) mutex_unlock(&smbrdr_screate_mtx);
+ if (di == NULL)
+ syslog(LOG_DEBUG, "smbrdr_negotiate: cannot access domain");
return (res);
}
@@ -254,8 +196,8 @@ smbrdr_session_connect(smb_ntdomain_t *di)
* be accessible until it's established otherwise another thread
* might get access to a session which is not fully established.
*/
- if ((session = smbrdr_session_init(di)) == 0) {
- syslog(LOG_ERR, "smbrdr: session init failed");
+ if ((session = smbrdr_session_init(di)) == NULL) {
+ syslog(LOG_DEBUG, "smbrdr_session_init failed");
return (-1);
}
@@ -275,7 +217,7 @@ smbrdr_session_connect(smb_ntdomain_t *di)
if (rc < 0) {
smbrdr_session_clear(session);
smbrdr_session_unlock(session);
- syslog(LOG_ERR, "smbrdr: NBT/TCP connect failed");
+ syslog(LOG_DEBUG, "smbrdr: connect failed");
return (-1);
}
@@ -283,7 +225,7 @@ smbrdr_session_connect(smb_ntdomain_t *di)
(void) close(session->sock);
smbrdr_session_clear(session);
smbrdr_session_unlock(session);
- syslog(LOG_ERR, "smbrdr: SMB negotiate failed");
+ syslog(LOG_DEBUG, "smbrdr: negotiate failed");
return (-1);
}
@@ -313,11 +255,7 @@ smbrdr_trnsprt_connect(struct sdb_session *sess, uint16_t port)
unsigned int cpid = oem_get_smb_cpid();
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) <= 0) {
- /*
- * We should never see descriptor 0 (stdin).
- */
- syslog(LOG_ERR, "smbrdr: socket(%d) failed (%s)", sock,
- strerror(errno));
+ syslog(LOG_DEBUG, "smbrdr: socket failed: %s", strerror(errno));
return (-1);
}
@@ -327,7 +265,8 @@ smbrdr_trnsprt_connect(struct sdb_session *sess, uint16_t port)
sin.sin_port = htons(port);
if ((rc = connect(sock, (struct sockaddr *)&sin, sizeof (sin))) < 0) {
- syslog(LOG_ERR, "smbrdr: connect failed (%s)", strerror(errno));
+ syslog(LOG_DEBUG, "smbrdr: connect failed: %s",
+ strerror(errno));
if (sock != 0)
(void) close(sock);
return (-1);
@@ -338,7 +277,7 @@ smbrdr_trnsprt_connect(struct sdb_session *sess, uint16_t port)
rc = unicodestooems(server_name, unicode_server_name,
SMB_PI_MAX_DOMAIN, cpid);
if (rc == 0) {
- syslog(LOG_ERR, "smbrdr: unicode conversion failed");
+ syslog(LOG_DEBUG, "smbrdr: unicode conversion failed");
if (sock != 0)
(void) close(sock);
return (-1);
@@ -352,7 +291,7 @@ smbrdr_trnsprt_connect(struct sdb_session *sess, uint16_t port)
*/
if (port == SSN_SRVC_TCP_PORT) {
if (smb_getnetbiosname(hostname, MAXHOSTNAMELEN) != 0) {
- syslog(LOG_ERR, "smbrdr: no hostname");
+ syslog(LOG_DEBUG, "smbrdr: no hostname");
if (sock != 0)
(void) close(sock);
return (-1);
@@ -362,7 +301,7 @@ smbrdr_trnsprt_connect(struct sdb_session *sess, uint16_t port)
server_name, sess->scope, hostname, sess->scope);
if (rc != 0) {
- syslog(LOG_ERR,
+ syslog(LOG_DEBUG,
"smbrdr: NBT session request to %s failed %d",
server_name, rc);
if (sock != 0)
@@ -404,28 +343,19 @@ smbrdr_smb_negotiate(struct sdb_session *sess)
status = smbrdr_request_init(&srh, SMB_COM_NEGOTIATE, sess, 0, 0);
- if (status != NT_STATUS_SUCCESS) {
- syslog(LOG_ERR, "smbrdr: negotiate (%s)",
- xlate_nt_status(status));
+ if (status != NT_STATUS_SUCCESS)
return (-1);
- }
mb = &srh.srh_mbuf;
- rc = smb_msgbuf_encode(mb, "(wct)b (bcc)w (dialect)bs",
- 0, /* smb_wct */
- 12, /* smb_bcc */
- 0x02, /* dialect marker */
- "NT LM 0.12"); /* only dialect we care about */
-
+ rc = smb_msgbuf_encode(mb, "bwbs", 0, 12, 0x02, "NT LM 0.12");
if (rc <= 0) {
- syslog(LOG_ERR, "smbrdr: negotiate (encode failed)");
smbrdr_handle_free(&srh);
return (-1);
}
status = smbrdr_exchange(&srh, &smb_hdr, 0);
if (status != NT_STATUS_SUCCESS) {
- syslog(LOG_ERR, "smbrdr: negotiate (%s)",
+ syslog(LOG_DEBUG, "smbrdr: negotiate: %s",
xlate_nt_status(status));
smbrdr_handle_free(&srh);
return (-1);
@@ -436,12 +366,11 @@ smbrdr_smb_negotiate(struct sdb_session *sess)
sess->challenge_len = 0;
rc = smb_msgbuf_decode(mb,
- "(wordcnt)1.(dialect)w(secm)b12.(skey)l(cap)l10.(klen)b2.",
+ "1.(dialect)w(mode)b12.(key)l(cap)l10.(keylen)b2.",
&dialect, &tmp_secmode, &sess->sesskey, &sess->remote_caps,
&tmp_clen);
if (rc <= 0 || dialect != 0) {
- syslog(LOG_ERR, "smbrdr: negotiate (response error)");
smbrdr_handle_free(&srh);
return (-1);
}
@@ -451,7 +380,6 @@ smbrdr_smb_negotiate(struct sdb_session *sess)
rc = smb_msgbuf_decode(mb, "#c",
sess->challenge_len, sess->challenge_key);
if (rc <= 0) {
- syslog(LOG_ERR, "smbrdr: negotiate (decode error)");
smbrdr_handle_free(&srh);
return (-1);
}
@@ -461,7 +389,7 @@ smbrdr_smb_negotiate(struct sdb_session *sess)
if ((sess->secmode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) &&
(sess->secmode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) {
sess->sign_ctx.ssc_flags |= SMB_SCF_REQUIRED;
- syslog(LOG_DEBUG, "smbrdr: %s requires signing",
+ syslog(LOG_DEBUG, "smbrdr: %s: signing required",
sess->di.server);
}
@@ -482,12 +410,11 @@ smbrdr_smb_negotiate(struct sdb_session *sess)
static struct sdb_session *
smbrdr_session_init(smb_ntdomain_t *di)
{
- struct sdb_session *session = 0;
+ struct sdb_session *session = NULL;
int i;
- char *p;
- if (di == 0)
- return (0);
+ if (di == NULL)
+ return (NULL);
for (i = 0; i < MLSVC_DOMAIN_MAX; ++i) {
session = &session_table[i];
@@ -499,10 +426,8 @@ smbrdr_session_init(smb_ntdomain_t *di)
(void) utf8_strupr(session->di.domain);
(void) utf8_strupr(session->di.server);
- smb_config_rdlock();
- p = smb_config_getstr(SMB_CI_NBSCOPE);
- (void) strlcpy(session->scope, p, SMB_PI_MAX_SCOPE);
- smb_config_unlock();
+ (void) smb_config_getstr(SMB_CI_NBSCOPE, session->scope,
+ sizeof (session->scope));
(void) strlcpy(session->native_os,
"Solaris", SMB_PI_MAX_NATIVE_OS);
@@ -530,8 +455,8 @@ smbrdr_session_init(smb_ntdomain_t *di)
(void) rw_unlock(&session->rwl);
}
- syslog(LOG_WARNING, "smbrdr: no session available");
- return (0);
+ syslog(LOG_DEBUG, "smbrdr: no session available");
+ return (NULL);
}
/*
@@ -550,10 +475,8 @@ smbrdr_session_disconnect(struct sdb_session *session, int cleanup)
{
int state;
- if (session == 0) {
- syslog(LOG_ERR, "smbrdr: (disconnect) null session");
+ if (session == NULL)
return;
- }
state = session->state;
if ((state != SDB_SSTATE_DISCONNECTING) &&
@@ -567,7 +490,7 @@ smbrdr_session_disconnect(struct sdb_session *session, int cleanup)
*/
session->state = (state == SDB_SSTATE_STALE)
? SDB_SSTATE_CLEANING : SDB_SSTATE_DISCONNECTING;
- (void) smbrdr_smb_logoff(&session->logon);
+ (void) smbrdr_logoffx(&session->logon);
nb_close(session->sock);
smbrdr_session_clear(session);
}
@@ -605,10 +528,8 @@ smbrdr_session_lock(char *server, char *username, int lmode)
struct sdb_session *session;
int i;
- if (server == 0) {
- syslog(LOG_ERR, "smbrdr: (lookup) no server specified");
- return (0);
- }
+ if (server == NULL)
+ return (NULL);
for (i = 0; i < MLSVC_DOMAIN_MAX; ++i) {
session = &session_table[i];
@@ -624,7 +545,7 @@ smbrdr_session_lock(char *server, char *username, int lmode)
return (session);
(void) rw_unlock(&session->rwl);
- return (0);
+ return (NULL);
}
return (session);
}
@@ -632,7 +553,7 @@ smbrdr_session_lock(char *server, char *username, int lmode)
(void) rw_unlock(&session->rwl);
}
- return (0);
+ return (NULL);
}
/*
@@ -649,13 +570,11 @@ mlsvc_session_native_values(int fid, int *remote_os,
struct sdb_netuse *netuse;
struct sdb_ofile *ofile;
- if (remote_os == 0 || remote_lm == 0) {
- syslog(LOG_ERR, "mlsvc_session_native_values: null");
+ if (remote_os == NULL || remote_lm == NULL)
return (-1);
- }
if ((ofile = smbrdr_ofile_get(fid)) == 0) {
- syslog(LOG_ERR,
+ syslog(LOG_DEBUG,
"mlsvc_session_native_values: unknown file (%d)", fid);
return (-1);
}
@@ -672,96 +591,6 @@ mlsvc_session_native_values(int fid, int *remote_os,
}
/*
- * smbrdr_disconnect_sessions
- *
- * Disconnects/cleanups all the sessions
- */
-static void
-smbrdr_disconnect_sessions(int cleanup)
-{
- struct sdb_session *session;
- int i;
-
- for (i = 0; i < MLSVC_DOMAIN_MAX; ++i) {
- session = &session_table[i];
- (void) rw_wrlock(&session->rwl);
- smbrdr_session_disconnect(&session_table[i], cleanup);
- (void) rw_unlock(&session->rwl);
- }
-}
-
-
-/*
- * mlsvc_check_sessions
- *
- * This function should be run in an independent thread. At the time of
- * writing it is called periodically from an infinite loop in the start
- * up thread once initialization is complete. It sends a NetBIOS keep-
- * alive message on each active session and handles cleanup if a session
- * is closed from the remote end. Testing demonstrated that the domain
- * controller will close a session after 15 minutes of inactivity. Note
- * that neither NetBIOS keep-alive nor SMB echo is deemed as activity
- * in this case, however, RPC requests appear to reset the timeout and
- * keep the session open. Note that the NetBIOS request does stop the
- * remote NetBIOS layer from timing out the connection.
- */
-void
-mlsvc_check_sessions(void)
-{
- static int session_keep_alive;
- struct sdb_session *session;
- smb_ntdomain_t di;
- int i;
-
- ++session_keep_alive;
-
- for (i = 0; i < MLSVC_DOMAIN_MAX; ++i) {
- session = &session_table[i];
-
- (void) rw_wrlock(&session->rwl);
-
- if (session->state < SDB_SSTATE_CONNECTED) {
- (void) rw_unlock(&session->rwl);
- continue;
- }
-
- /*
- * NetBIOS is only used on with port 139. The keep alive
- * is not relevant over NetBIOS-less SMB over port 445.
- * This is just to see if the socket is still alive.
- */
- if (session->port == SSN_SRVC_TCP_PORT) {
- if (nb_keep_alive(session->sock) != 0) {
- session->state = SDB_SSTATE_STALE;
- (void) rw_unlock(&session->rwl);
- continue;
- }
- }
-
- if (session_keep_alive >= MLSVC_SESSION_FORCE_KEEPALIVE) {
- if (smbrdr_smb_echo(session) != 0) {
- syslog(LOG_WARNING,
- "smbrdr: monitor[%s] cannot contact %s",
- session->di.domain, session->di.server);
- (void) memcpy(&di, &session->di,
- sizeof (smb_ntdomain_t));
- session->state = SDB_SSTATE_STALE;
- (void) rw_unlock(&session->rwl);
- if (smb_getdomaininfo(0) == 0)
- (void) smbrdr_locate_dc(di.domain);
- }
- } else
- (void) rw_unlock(&session->rwl);
- }
-
- if (session_keep_alive >= MLSVC_SESSION_FORCE_KEEPALIVE) {
- session_keep_alive = 0;
- /* cleanup */
- smbrdr_disconnect_sessions(1);
- }
-}
-
-/*
* smbrdr_dump_sessions
*
* Debug function to dump the session table.
@@ -812,7 +641,7 @@ mlsvc_echo(char *server)
if ((session = smbrdr_session_lock(server, 0, SDB_SLCK_WRITE)) == 0)
return (1);
- if (smbrdr_smb_echo(session) != 0) {
+ if (smbrdr_echo(session) != 0) {
session->state = SDB_SSTATE_STALE;
res = -1;
}
@@ -822,7 +651,7 @@ mlsvc_echo(char *server)
}
/*
- * smbrdr_smb_echo
+ * smbrdr_echo
*
* This request can be used to test the connection to the server. The
* server should echo the data sent. The server should ignore the tid
@@ -832,7 +661,7 @@ mlsvc_echo(char *server)
* Return 0 on success. Otherwise return a -ve error code.
*/
static int
-smbrdr_smb_echo(struct sdb_session *session)
+smbrdr_echo(struct sdb_session *session)
{
static char *echo_str = "smbrdr";
smbrdr_handle_t srh;
@@ -847,43 +676,21 @@ smbrdr_smb_echo(struct sdb_session *session)
}
status = smbrdr_request_init(&srh, SMB_COM_ECHO, session, 0, 0);
-
- if (status != NT_STATUS_SUCCESS) {
- syslog(LOG_ERR, "SmbrdrEcho: %s", xlate_nt_status(status));
+ if (status != NT_STATUS_SUCCESS)
return (-1);
- }
rc = smb_msgbuf_encode(&srh.srh_mbuf, "bwws", 1, 1,
strlen(echo_str), echo_str);
if (rc <= 0) {
- syslog(LOG_ERR, "SmbrdrEcho: encode failed");
smbrdr_handle_free(&srh);
return (-1);
}
status = smbrdr_exchange(&srh, &smb_hdr, 10);
- if (status != NT_STATUS_SUCCESS) {
- syslog(LOG_ERR, "SmbrdrEcho: %s", xlate_nt_status(status));
- rc = -1;
- } else {
- rc = 0;
- }
-
smbrdr_handle_free(&srh);
- return (rc);
-}
-/*
- * smbrdr_locate_dc
- *
- * Locate a domain controller. Note that this may close an existing
- * connection to the current domain controller.
- */
-static int
-smbrdr_locate_dc(char *domain)
-{
- if (mlsvc_locate_pdc)
- return (mlsvc_locate_pdc(domain));
+ if (status != NT_STATUS_SUCCESS)
+ return (-1);
return (0);
}
diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_transact.c b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_transact.c
index 24bf3a5cea..1fea4e831d 100644
--- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_transact.c
+++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_transact.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -33,7 +33,6 @@
#include <strings.h>
#include <smbsrv/libsmbrdr.h>
-
#include <smbsrv/ntstatus.h>
#include <smbsrv/smb.h>
#include <smbrdr.h>
@@ -54,13 +53,12 @@ static int decode_smb_transact(smb_msgbuf_t *, char *, unsigned,
smb_transact_rsp_t *);
/*
- * smbrdr_rpc_transact
+ * smbrdr_transact
*
* Send a SMB_COM_TRANSACTION request.
*/
int
-smbrdr_rpc_transact(int fid, char *out_buf, int out_len,
- char *in_buf, int in_len)
+smbrdr_transact(int fid, char *out_buf, int out_len, char *in_buf, int in_len)
{
struct sdb_session *session;
struct sdb_netuse *netuse;
@@ -86,7 +84,8 @@ smbrdr_rpc_transact(int fid, char *out_buf, int out_len,
session, logon, netuse);
if (status != NT_STATUS_SUCCESS) {
- syslog(LOG_ERR, "SmbrdrTransact: %s", xlate_nt_status(status));
+ syslog(LOG_DEBUG, "smbrdr_transact: %s",
+ xlate_nt_status(status));
smbrdr_ofile_put(ofile);
return (-1);
}
@@ -96,8 +95,7 @@ smbrdr_rpc_transact(int fid, char *out_buf, int out_len,
rc = prep_smb_transact(mb, ofile->fid, out_buf, out_len, in_len,
session->remote_caps & CAP_UNICODE);
if (rc < 0) {
- syslog(LOG_ERR,
- "smbrdr_rpc_transact: prep_smb_transact failed");
+ syslog(LOG_DEBUG, "smbrdr_transact: prep failed");
smbrdr_handle_free(&srh);
smbrdr_ofile_put(ofile);
return (rc);
@@ -110,7 +108,7 @@ smbrdr_rpc_transact(int fid, char *out_buf, int out_len,
smbrdr_unlock_transport();
smbrdr_handle_free(&srh);
smbrdr_ofile_put(ofile);
- syslog(LOG_ERR, "smbrdr_rpc_transact: send failed");
+ syslog(LOG_DEBUG, "smbrdr_transact: send failed");
return (-1);
}
@@ -120,15 +118,15 @@ smbrdr_rpc_transact(int fid, char *out_buf, int out_len,
do {
if (smbrdr_rcv(&srh, first_rsp) != NT_STATUS_SUCCESS) {
- syslog(LOG_ERR, "smbrdr_rpc_transact: nb_rcv failed");
+ syslog(LOG_DEBUG, "smbrdr_transact: nb_rcv failed");
rc = -1;
break;
}
rc = decode_smb_transact(mb, in_buf, cur_inlen, &rsp);
if (rc < 0 || rsp.TotalDataCount > in_len) {
- syslog(LOG_ERR,
- "SmbTransact: transact decode failure!");
+ syslog(LOG_DEBUG,
+ "smbrdr_transact: decode failed");
rc = -1;
break;
}
@@ -222,7 +220,6 @@ decode_smb_transact(smb_msgbuf_t *mb, char *in, unsigned in_len,
rc = smb_msgbuf_decode(mb, "b", &rsp->WordCount);
if (rc <= 0 || rsp->WordCount < 10) {
- syslog(LOG_ERR, "SmbTransact: invalid word count");
return (-1);
}
diff --git a/usr/src/pkgdefs/SUNWsmbsu/prototype_com b/usr/src/pkgdefs/SUNWsmbsu/prototype_com
index ba9aa3d77d..c9963bdfd2 100644
--- a/usr/src/pkgdefs/SUNWsmbsu/prototype_com
+++ b/usr/src/pkgdefs/SUNWsmbsu/prototype_com
@@ -20,7 +20,7 @@
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -64,6 +64,8 @@ d none usr/lib/mdb/kvm 755 root sys
d none usr/lib/fs 755 root sys
d none usr/lib/fs/smb 755 root sys
f none usr/lib/fs/smb/libshare_smb.so.1 755 root bin
+f none usr/lib/libsqlite.so.1 755 root bin
+s none usr/lib/libsqlite.so=libsqlite.so.1
d none usr/lib/security 755 root bin
f none usr/lib/security/pam_smb_passwd.so.1 755 root bin
-s none usr/lib/security/pam_smb_passwd.so=./pam_smb_passwd.so.1
+s none usr/lib/security/pam_smb_passwd.so=pam_smb_passwd.so.1
diff --git a/usr/src/uts/common/fs/smbsrv/smb_check_directory.c b/usr/src/uts/common/fs/smbsrv/smb_check_directory.c
index d29e55eda6..9d6d0c202d 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_check_directory.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_check_directory.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -74,7 +74,7 @@ smb_com_check_directory(struct smb_request *sr)
struct smb_node *dnode;
if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS,
ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -88,7 +88,7 @@ smb_com_check_directory(struct smb_request *sr)
rc = smbd_fs_query(sr, &sr->arg.dirop.fqi, FQM_PATH_MUST_EXIST);
if (rc) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -104,7 +104,7 @@ smb_com_check_directory(struct smb_request *sr)
smb_node_release(dnode);
SMB_NULL_FQI_NODES(sr->arg.dirop.fqi);
- smbsr_raise_errno(sr, ENOTDIR);
+ smbsr_errno(sr, ENOTDIR);
/* NOTREACHED */
}
@@ -114,8 +114,7 @@ smb_com_check_directory(struct smb_request *sr)
SMB_NULL_FQI_NODES(sr->arg.dirop.fqi);
if (rc != 0) {
- smbsr_raise_cifs_error(sr,
- NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_close.c b/usr/src/uts/common/fs/smbsrv/smb_close.c
index c4d129c2e4..f2d7faeb8d 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_close.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_close.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -53,14 +53,13 @@ smb_com_close(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
rc = smb_common_close(sr, last_wtime);
if (rc) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -86,8 +85,7 @@ smb_com_close_and_tree_disconnect(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -96,7 +94,7 @@ smb_com_close_and_tree_disconnect(struct smb_request *sr)
smb_tree_disconnect(sr->tid_tree);
if (rc) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_common_open.c b/usr/src/uts/common/fs/smbsrv/smb_common_open.c
index d3a462fbc5..5e0d94976b 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_common_open.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_common_open.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -37,22 +37,10 @@
#include <smbsrv/ntstatus.h>
#include <smbsrv/smbinfo.h>
#include <sys/fcntl.h>
+#include <sys/nbmlock.h>
extern uint32_t smb_is_executable(char *path);
-#define DENY_READ(share_access) ((share_access & FILE_SHARE_READ) == 0)
-
-#define DENY_WRITE(share_access) ((share_access & FILE_SHARE_WRITE) == 0)
-
-#define DENY_DELETE(share_access) ((share_access & FILE_SHARE_DELETE) == 0)
-
-#define DENY_RW(share_access) \
- ((share_access & (FILE_SHARE_READ | FILE_SHARE_WRITE)) == 0)
-
-#define DENY_ALL(share_access) (share_access == 0)
-
-#define DENY_NONE(share_access) (share_access == FILE_SHARE_ALL)
-
/*
* The default stability mode is to perform the write-through
* behaviour requested by the client.
@@ -219,130 +207,6 @@ smb_ofun_to_crdisposition(uint16_t ofun)
}
/*
- * smb_open_share_check
- *
- * check file sharing rules for current open request
- * against the given existing open.
- *
- * Returns NT_STATUS_SHARING_VIOLATION if there is any
- * sharing conflict, otherwise returns NT_STATUS_SUCCESS.
- */
-uint32_t
-smb_open_share_check(struct smb_request *sr,
- struct smb_node *node,
- struct smb_ofile *open)
-{
- uint32_t desired_access;
- uint32_t share_access;
-
- desired_access = sr->arg.open.desired_access;
- share_access = sr->arg.open.share_access;
-
- /*
- * As far as I can tell share modes are not relevant to
- * directories. The check for exclusive access (Deny RW)
- * remains because I don't know whether or not it was here
- * for a reason.
- */
- if (node->attr.sa_vattr.va_type == VDIR) {
- if (DENY_RW(open->f_share_access) &&
- (node->n_orig_uid != crgetuid(sr->user_cr))) {
- return (NT_STATUS_SHARING_VIOLATION);
- }
-
- return (NT_STATUS_SUCCESS);
- }
-
- /* if it's just meta data */
- if ((open->f_granted_access & FILE_DATA_ALL) == 0)
- return (NT_STATUS_SUCCESS);
-
- /*
- * Check requested share access against the
- * open granted (desired) access
- */
- if (DENY_DELETE(share_access) && (open->f_granted_access & DELETE))
- return (NT_STATUS_SHARING_VIOLATION);
-
- if (DENY_READ(share_access) &&
- (open->f_granted_access & (FILE_READ_DATA | FILE_EXECUTE)))
- return (NT_STATUS_SHARING_VIOLATION);
-
- if (DENY_WRITE(share_access) &&
- (open->f_granted_access & (FILE_WRITE_DATA | FILE_APPEND_DATA)))
- return (NT_STATUS_SHARING_VIOLATION);
-
- /* check requested desired access against the open share access */
- if (DENY_DELETE(open->f_share_access) && (desired_access & DELETE))
- return (NT_STATUS_SHARING_VIOLATION);
-
- if (DENY_READ(open->f_share_access) &&
- (desired_access & (FILE_READ_DATA | FILE_EXECUTE)))
- return (NT_STATUS_SHARING_VIOLATION);
-
- if (DENY_WRITE(open->f_share_access) &&
- (desired_access & (FILE_WRITE_DATA | FILE_APPEND_DATA)))
- return (NT_STATUS_SHARING_VIOLATION);
-
- return (NT_STATUS_SUCCESS);
-}
-
-/*
- * smb_file_share_check
- *
- * check file sharing rules for current open request
- * against all existing opens for a file.
- *
- * Returns NT_STATUS_SHARING_VIOLATION if there is any
- * sharing conflict, otherwise returns NT_STATUS_SUCCESS.
- */
-uint32_t
-smb_file_share_check(struct smb_request *sr, struct smb_node *node)
-{
- struct smb_ofile *open;
- uint32_t status;
-
- if (node == 0 || node->n_refcnt <= 1)
- return (NT_STATUS_SUCCESS);
-
- /* if it's just meta data */
- if ((sr->arg.open.desired_access & FILE_DATA_ALL) == 0)
- return (NT_STATUS_SUCCESS);
-
- smb_llist_enter(&node->n_ofile_list, RW_READER);
- open = smb_llist_head(&node->n_ofile_list);
- while (open) {
- status = smb_open_share_check(sr, node, open);
- if (status == NT_STATUS_SHARING_VIOLATION) {
- smb_llist_exit(&node->n_ofile_list);
- return (status);
- }
- open = smb_llist_next(&node->n_ofile_list, open);
- }
- smb_llist_exit(&node->n_ofile_list);
-
- return (NT_STATUS_SUCCESS);
-}
-
-/*
- * smb_amask_to_amode
- * Converts specific read/write access rights of access mask to access
- * mode flags.
- */
-int
-smb_amask_to_amode(unsigned long amask)
-{
- if ((amask & FILE_READ_DATA) &&
- (amask & (FILE_WRITE_DATA | FILE_APPEND_DATA)))
- return (O_RDWR);
-
- if (amask & (FILE_WRITE_DATA | FILE_APPEND_DATA))
- return (O_WRONLY);
-
- return (O_RDONLY);
-}
-
-/*
* smb_open_subr
*
* Notes on write-through behaviour. It looks like pre-LM0.12 versions
@@ -364,6 +228,7 @@ smb_amask_to_amode(unsigned long amask)
* in which case it won't return to the caller. Be careful how you
* handle things in here.
*/
+
uint32_t
smb_open_subr(struct smb_request *sr)
{
@@ -385,6 +250,8 @@ smb_open_subr(struct smb_request *sr)
int is_stream;
int lookup_flags = SMB_FOLLOW_LINKS;
uint32_t daccess;
+ uint32_t share_access = op->share_access;
+ uint32_t uniq_fid;
is_dir = (op->create_options & FILE_DIRECTORY_FILE) ? 1 : 0;
@@ -397,7 +264,7 @@ smb_open_subr(struct smb_request *sr)
if ((op->create_disposition != FILE_CREATE) &&
(op->create_disposition != FILE_OPEN_IF) &&
(op->create_disposition != FILE_OPEN)) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_PARAMETER,
+ smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
ERRDOS, ERROR_INVALID_ACCESS);
/* invalid open mode */
/* NOTREACHED */
@@ -417,7 +284,7 @@ smb_open_subr(struct smb_request *sr)
sr->uid_user->u_name,
xlate_nt_status(NT_STATUS_TOO_MANY_OPENED_FILES));
- smbsr_raise_cifs_error(sr, NT_STATUS_TOO_MANY_OPENED_FILES,
+ smbsr_error(sr, NT_STATUS_TOO_MANY_OPENED_FILES,
ERRDOS, ERROR_TOO_MANY_OPEN_FILES);
/* NOTREACHED */
}
@@ -437,7 +304,7 @@ smb_open_subr(struct smb_request *sr)
* raise an exception or return success here.
*/
if ((rc = smb_rpc_open(sr)) != 0) {
- smbsr_raise_nt_error(sr, rc);
+ smbsr_error(sr, rc, 0, 0);
/* NOTREACHED */
} else {
return (NT_STATUS_SUCCESS);
@@ -445,13 +312,13 @@ smb_open_subr(struct smb_request *sr)
break;
default:
- smbsr_raise_error(sr, ERRSRV, ERRinvdevice);
+ smbsr_error(sr, 0, ERRSRV, ERRinvdevice);
/* NOTREACHED */
break;
}
if ((pathlen = strlen(op->fqi.path)) >= MAXPATHLEN) {
- smbsr_raise_error(sr, ERRSRV, ERRfilespecs);
+ smbsr_error(sr, 0, ERRSRV, ERRfilespecs);
/* NOTREACHED */
}
@@ -466,7 +333,7 @@ smb_open_subr(struct smb_request *sr)
op->fqi.srch_attr = op->fqi.srch_attr;
if ((status = smb_validate_object_name(op->fqi.path, is_dir)) != 0) {
- smbsr_raise_cifs_error(sr, status, ERRDOS, ERROR_INVALID_NAME);
+ smbsr_error(sr, status, ERRDOS, ERROR_INVALID_NAME);
/* NOTREACHED */
}
@@ -476,7 +343,7 @@ smb_open_subr(struct smb_request *sr)
if (rc = smb_pathname_reduce(sr, sr->user_cr, op->fqi.path,
sr->tid_tree->t_snode, cur_node, &op->fqi.dir_snode,
op->fqi.last_comp)) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -508,26 +375,41 @@ smb_open_subr(struct smb_request *sr)
} else {
smb_node_release(op->fqi.dir_snode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
+ /*
+ * The uniq_fid is a CIFS-server-wide unique identifier for an ofile
+ * which is used to uniquely identify open instances for the
+ * VFS share reservation mechanism (accessed via smb_fsop_shrlock()).
+ */
+
+ uniq_fid = SMB_UNIQ_FID();
+
if (op->fqi.last_comp_was_found) {
node = op->fqi.last_snode;
dnode = op->fqi.dir_snode;
/*
+ * Enter critical region for share reservations.
+ * (See comments above smb_fsop_shrlock().)
+ */
+
+ rw_enter(&node->n_share_lock, RW_WRITER);
+
+ /*
* Reject this request if the target is a directory
* and the client has specified that it must not be
* a directory (required by Lotus Notes).
*/
if ((op->create_options & FILE_NON_DIRECTORY_FILE) &&
(op->fqi.last_attr.sa_vattr.va_type == VDIR)) {
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_cifs_error(sr,
- NT_STATUS_FILE_IS_A_DIRECTORY,
+ smbsr_error(sr, NT_STATUS_FILE_IS_A_DIRECTORY,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -539,19 +421,20 @@ smb_open_subr(struct smb_request *sr)
* Directories cannot be opened
* with the above commands
*/
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_cifs_error(sr,
- NT_STATUS_FILE_IS_A_DIRECTORY,
+ smbsr_error(sr, NT_STATUS_FILE_IS_A_DIRECTORY,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
} else if (op->my_flags & MYF_MUST_BE_DIRECTORY) {
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_cifs_error(sr, NT_STATUS_NOT_A_DIRECTORY,
+ smbsr_error(sr, NT_STATUS_NOT_A_DIRECTORY,
ERRDOS, ERROR_DIRECTORY);
/* NOTREACHED */
}
@@ -561,10 +444,11 @@ smb_open_subr(struct smb_request *sr)
* flag is set.
*/
if (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) {
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_cifs_error(sr, NT_STATUS_DELETE_PENDING,
+ smbsr_error(sr, NT_STATUS_DELETE_PENDING,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -573,12 +457,12 @@ smb_open_subr(struct smb_request *sr)
* Specified file already exists so the operation should fail.
*/
if (op->create_disposition == FILE_CREATE) {
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_cifs_error(sr,
- NT_STATUS_OBJECT_NAME_COLLISION, ERRDOS,
- ERROR_ALREADY_EXISTS);
+ smbsr_error(sr, NT_STATUS_OBJECT_NAME_COLLISION,
+ ERRDOS, ERROR_ALREADY_EXISTS);
/* NOTREACHED */
}
@@ -591,18 +475,42 @@ smb_open_subr(struct smb_request *sr)
if (node->attr.sa_vattr.va_type != VDIR) {
if (op->desired_access & (FILE_WRITE_DATA |
FILE_APPEND_DATA)) {
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_error(sr, ERRDOS,
- ERRnoaccess);
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
+ ERRDOS, ERRnoaccess);
/* NOTREACHED */
}
}
}
- status = smb_file_share_check(sr, node);
+ /*
+ * The following check removes the need to check share
+ * reservations again when a truncate is done.
+ */
+
+ if ((op->create_disposition == FILE_SUPERSEDE) ||
+ (op->create_disposition == FILE_OVERWRITE_IF) ||
+ (op->create_disposition == FILE_OVERWRITE)) {
+
+ if (!(op->desired_access &
+ (FILE_WRITE_DATA | FILE_APPEND_DATA))) {
+ rw_exit(&node->n_share_lock);
+ smb_node_release(node);
+ smb_node_release(dnode);
+ SMB_NULL_FQI_NODES(op->fqi);
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
+ ERRDOS, ERRnoaccess);
+ }
+ }
+
+ status = smb_fsop_shrlock(sr->user_cr, node, uniq_fid,
+ op->desired_access, share_access);
+
if (status == NT_STATUS_SHARING_VIOLATION) {
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
@@ -613,19 +521,19 @@ smb_open_subr(struct smb_request *sr)
op->desired_access);
if (status != NT_STATUS_SUCCESS) {
+ smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
+
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
+
if (status == NT_STATUS_PRIVILEGE_NOT_HELD) {
- smbsr_raise_cifs_error(sr,
- status,
- ERRDOS,
- ERROR_PRIVILEGE_NOT_HELD);
+ smbsr_error(sr, status,
+ ERRDOS, ERROR_PRIVILEGE_NOT_HELD);
} else {
- smbsr_raise_cifs_error(sr,
- NT_STATUS_ACCESS_DENIED,
- ERRDOS,
- ERROR_ACCESS_DENIED);
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
+ ERRDOS, ERROR_ACCESS_DENIED);
}
}
@@ -634,14 +542,16 @@ smb_open_subr(struct smb_request *sr)
* has the file open, this will force a flush or close,
* which may affect the outcome of any share checking.
*/
+
if (OPLOCKS_IN_FORCE(node)) {
status = smb_break_oplock(sr, node);
if (status != NT_STATUS_SUCCESS) {
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_cifs_error(sr, status,
+ smbsr_error(sr, status,
ERRDOS, ERROR_VC_DISCONNECTED);
/* NOTREACHED */
}
@@ -652,29 +562,37 @@ smb_open_subr(struct smb_request *sr)
case FILE_OVERWRITE_IF:
case FILE_OVERWRITE:
if (node->attr.sa_vattr.va_type == VDIR) {
+ smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_cifs_error(sr,
- NT_STATUS_ACCESS_DENIED, ERRDOS,
- ERROR_ACCESS_DENIED);
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
+ ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
if (node->attr.sa_vattr.va_size != op->dsize) {
node->flags &= ~NODE_FLAGS_SET_SIZE;
+ bzero(&new_attr, sizeof (new_attr));
new_attr.sa_vattr.va_size = op->dsize;
new_attr.sa_mask = SMB_AT_SIZE;
- if ((rc = smb_fsop_setattr(sr, sr->user_cr,
- (&op->fqi)->last_snode, &new_attr,
- &op->fqi.last_attr)) != 0) {
+
+ rc = smb_fsop_setattr(sr, sr->user_cr,
+ node, &new_attr, &op->fqi.last_attr);
+
+ if (rc) {
+ smb_fsop_unshrlock(sr->user_cr,
+ node, uniq_fid);
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
+ op->dsize = op->fqi.last_attr.sa_vattr.va_size;
}
/*
@@ -712,11 +630,10 @@ smb_open_subr(struct smb_request *sr)
* fail with these two dispositions
*/
if (is_stream)
- smbsr_raise_cifs_error(sr,
- NT_STATUS_OBJECT_NAME_NOT_FOUND,
+ smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND,
ERRDOS, ERROR_FILE_NOT_FOUND);
else
- smbsr_raise_error(sr, ERRDOS, ERRbadfile);
+ smbsr_error(sr, 0, ERRDOS, ERRbadfile);
/* NOTREACHED */
}
@@ -731,32 +648,93 @@ smb_open_subr(struct smb_request *sr)
new_attr.sa_vattr.va_type = VREG;
new_attr.sa_vattr.va_mode = 0666;
new_attr.sa_mask = SMB_AT_TYPE | SMB_AT_MODE;
+
+ /*
+ * A problem with setting the readonly bit at
+ * create time is that this bit will prevent
+ * writes to the file from the same fid (which
+ * should be allowed).
+ *
+ * The solution is to set the bit at close time.
+ * Meanwhile, to prevent racing opens from being
+ * able to write to the file, the bit is set at
+ * create time until share reservations can be set
+ * to prevent write and delete access. At that point,
+ * the bit can be turned off until close (so as to
+ * allow writes from the same fid to the file).
+ */
+
+ if (op->dattr & SMB_FA_READONLY) {
+ new_attr.sa_dosattr = FILE_ATTRIBUTE_READONLY;
+ new_attr.sa_mask |= SMB_AT_DOSATTR;
+ }
+
rc = smb_fsop_create(sr, sr->user_cr, dnode,
op->fqi.last_comp, &new_attr,
&op->fqi.last_snode, &op->fqi.last_attr);
+
if (rc != 0) {
smb_rwx_rwexit(&dnode->n_lock);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
+ if (op->dattr & SMB_FA_READONLY) {
+ share_access &= ~(FILE_SHARE_WRITE |
+ FILE_SHARE_DELETE);
+ }
+
+ node = op->fqi.last_snode;
+
+ rw_enter(&node->n_share_lock, RW_WRITER);
+
+ status = smb_fsop_shrlock(sr->user_cr, node,
+ uniq_fid, op->desired_access,
+ share_access);
+
+ if (status == NT_STATUS_SHARING_VIOLATION) {
+ rw_exit(&node->n_share_lock);
+ smb_node_release(node);
+ smb_node_release(dnode);
+ SMB_NULL_FQI_NODES(op->fqi);
+ return (status);
+ }
+
+ new_attr = op->fqi.last_attr;
+ new_attr.sa_mask = 0;
+
+ if (op->dattr & SMB_FA_READONLY) {
+ new_attr.sa_dosattr &= ~FILE_ATTRIBUTE_READONLY;
+ new_attr.sa_mask |= SMB_AT_DOSATTR;
+ }
+
if (op->dsize) {
new_attr.sa_vattr.va_size = op->dsize;
- new_attr.sa_mask = SMB_AT_SIZE;
- rc = smb_fsop_setattr(sr, sr->user_cr,
- op->fqi.last_snode, &new_attr,
- &op->fqi.last_attr);
+ new_attr.sa_mask |= SMB_AT_SIZE;
+ }
+
+ if (new_attr.sa_mask) {
+ node->attr = new_attr;
+ node->what = new_attr.sa_mask;
+ rc = smb_sync_fsattr(sr, sr->user_cr, node);
+
if (rc != 0) {
- smb_node_release(op->fqi.last_snode);
+ smb_fsop_unshrlock(sr->user_cr, node,
+ uniq_fid);
+
+ rw_exit(&node->n_share_lock);
+ smb_node_release(node);
(void) smb_fsop_remove(sr, sr->user_cr,
dnode, op->fqi.last_comp, 0);
smb_rwx_rwexit(&dnode->n_lock);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
+ } else {
+ op->fqi.last_attr = node->attr;
}
}
@@ -772,30 +750,33 @@ smb_open_subr(struct smb_request *sr)
smb_rwx_rwexit(&dnode->n_lock);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
+
+ node = op->fqi.last_snode;
+ rw_enter(&node->n_share_lock, RW_WRITER);
}
created = 1;
op->action_taken = SMB_OACT_CREATED;
}
- if (node == 0) {
- node = op->fqi.last_snode;
- }
-
if ((op->fqi.last_attr.sa_vattr.va_type != VREG) &&
(op->fqi.last_attr.sa_vattr.va_type != VDIR) &&
(op->fqi.last_attr.sa_vattr.va_type != VLNK)) {
/* not allowed to do this */
+
+ smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
+
SMB_DEL_NEWOBJ(op->fqi);
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
if (created)
smb_rwx_rwexit(&dnode->n_lock);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_error(sr, ERRDOS, ERRnoaccess);
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
/* NOTREACHED */
}
@@ -811,17 +792,20 @@ smb_open_subr(struct smb_request *sr)
*/
of = smb_ofile_open(sr->tid_tree, node, sr->smb_pid, op->desired_access,
- op->create_options, op->share_access, SMB_FTYPE_DISK, NULL, 0,
- &err);
+ op->create_options, share_access, SMB_FTYPE_DISK, NULL, 0,
+ uniq_fid, &err);
if (of == NULL) {
+ smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
+
SMB_DEL_NEWOBJ(op->fqi);
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
if (created)
smb_rwx_rwexit(&dnode->n_lock);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_cifs_error(sr, err.status, err.errcls, err.errcode);
+ smbsr_error(sr, err.status, err.errcls, err.errcode);
/* NOTREACHED */
}
@@ -847,14 +831,20 @@ smb_open_subr(struct smb_request *sr)
op->my_flags &= ~MYF_OPLOCK_MASK;
if (status != NT_STATUS_SUCCESS) {
+ rw_exit(&node->n_share_lock);
+ /*
+ * smb_fsop_unshrlock() and smb_fsop_close()
+ * are called from smb_ofile_close()
+ */
(void) smb_ofile_close(of, 0);
smb_ofile_release(of);
if (created)
smb_rwx_rwexit(&dnode->n_lock);
+
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_cifs_error(sr, status,
+ smbsr_error(sr, status,
ERRDOS, ERROR_SHARING_VIOLATION);
/* NOTREACHED */
}
@@ -868,11 +858,15 @@ smb_open_subr(struct smb_request *sr)
/*
* Clients may set the DOS readonly bit on create but they
* expect subsequent write operations on the open fid to
- * succeed. Thus the DOS readonly bit is not set until the
- * file is closed. The NODE_CREATED_READONLY flag will
- * inhibit other attempts to open the file with write access
- * and act as the indicator to set the DOS readonly bit on
+ * succeed. Thus the DOS readonly bit is not set permanently
+ * until the file is closed. The NODE_CREATED_READONLY flag
+ * will act as the indicator to set the DOS readonly bit on
* close.
+ * Above, the readonly bit is set on create, share
+ * reservations are set, and then the bit is unset.
+ * These actions allow writes to the open fid to succeed
+ * until the file is closed while preventing write access
+ * from other opens while this fid is active.
*/
if (op->dattr & SMB_FA_READONLY) {
node->flags |= NODE_CREATED_READONLY;
@@ -913,9 +907,11 @@ smb_open_subr(struct smb_request *sr)
sr->smb_fid = of->f_fid;
sr->fid_ofile = of;
- if (created) {
+ rw_exit(&node->n_share_lock);
+
+ if (created)
smb_rwx_rwexit(&dnode->n_lock);
- }
+
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_common_search.c b/usr/src/uts/common/fs/smbsrv/smb_common_search.c
index a17555669b..84d35fe9b0 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_common_search.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_common_search.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -41,7 +41,6 @@ smb_rdir_open(smb_request_t *sr, char *path, unsigned short sattr)
smb_odir_t *od;
smb_node_t *node;
char *last_component;
- smb_session_t *session = sr->session;
unsigned int rc;
int erc;
@@ -51,14 +50,14 @@ smb_rdir_open(smb_request_t *sr, char *path, unsigned short sattr)
sr->tid_tree->t_snode, sr->tid_tree->t_snode,
&node, last_component)) != 0) {
kmem_free(last_component, MAXNAMELEN);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
if ((node->vp)->v_type != VDIR) {
smb_node_release(node);
kmem_free(last_component, MAXNAMELEN);
- smbsr_raise_error(sr, ERRDOS, ERRbadpath);
+ smbsr_error(sr, 0, ERRDOS, ERRbadpath);
/* NOTREACHED */
}
@@ -67,18 +66,11 @@ smb_rdir_open(smb_request_t *sr, char *path, unsigned short sattr)
smb_node_release(node);
kmem_free(last_component, MAXNAMELEN);
if (sr->smb_com == SMB_COM_SEARCH) {
- if (session->capabilities & CAP_STATUS32) {
- smbsr_setup_nt_status(sr,
- ERROR_SEVERITY_WARNING,
- NT_STATUS_NO_MORE_FILES);
- return (SDRC_NORMAL_REPLY);
- } else {
- smbsr_raise_error(sr,
- ERRDOS, ERROR_NO_MORE_FILES);
- /* NOTREACHED */
- }
+ smbsr_warn(sr, NT_STATUS_NO_MORE_FILES,
+ ERRDOS, ERROR_NO_MORE_FILES);
+ return (SDRC_NORMAL_REPLY);
} else {
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -89,7 +81,7 @@ smb_rdir_open(smb_request_t *sr, char *path, unsigned short sattr)
kmem_free(last_component, sizeof (od->d_pattern));
if (od == NULL) {
smb_node_release(node);
- smbsr_raise_error(sr, ERRDOS, ERROR_NO_MORE_FILES);
+ smbsr_error(sr, 0, ERRDOS, ERROR_NO_MORE_FILES);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_common_transact.c b/usr/src/uts/common/fs/smbsrv/smb_common_transact.c
index 2558716c5e..dff0a689dd 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_common_transact.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_common_transact.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
*/
@@ -89,7 +89,7 @@ smb_com_transaction(struct smb_request *sr)
xa = smb_xa_create(sr->session, sr, tpscnt, tdscnt, mprcnt, mdrcnt,
msrcnt, suwcnt);
if (xa == NULL) {
- smbsr_raise_error(sr, ERRSRV, ERRnoroom);
+ smbsr_error(sr, 0, ERRSRV, ERRnoroom);
/* NOTREACHED */
}
@@ -114,17 +114,17 @@ smb_com_transaction(struct smb_request *sr)
if (MBC_SHADOW_CHAIN(&xa->req_setup_mb, &sr->smb_vwv,
sr->smb_vwv.chain_offset, suwcnt * 2)) {
smb_xa_rele(sr->session, xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
if (MBC_SHADOW_CHAIN(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
smb_xa_rele(sr->session, xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
if (MBC_SHADOW_CHAIN(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
smb_xa_rele(sr->session, xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
@@ -132,7 +132,7 @@ smb_com_transaction(struct smb_request *sr)
if (smb_xa_open(xa)) {
smb_xa_rele(sr->session, xa);
- smbsr_raise_error(sr, ERRDOS, ERRsrverror);
+ smbsr_error(sr, 0, ERRDOS, ERRsrverror);
/* NOTREACHED */
}
sr->r_xa = xa;
@@ -144,7 +144,7 @@ smb_com_transaction(struct smb_request *sr)
if (!smb_xa_complete(xa)) {
smb_xa_close(xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
@@ -161,13 +161,13 @@ smb_com_transaction_secondary(struct smb_request *sr)
int rc;
if ((xa = smbsr_lookup_xa(sr)) == 0) {
- smbsr_raise_error(sr, ERRSRV, ERRsrverror);
+ smbsr_error(sr, 0, ERRSRV, ERRsrverror);
/* NOTREACHED */
}
if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
if (smb_sign_check_secondary(sr, xa->reply_seqnum) != 0) {
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERRnoaccess);
/* NOTREACHED */
}
@@ -194,13 +194,13 @@ smb_com_transaction_secondary(struct smb_request *sr)
if (MBC_SHADOW_CHAIN(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
mutex_exit(&xa->xa_mutex);
smb_xa_close(xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
if (MBC_SHADOW_CHAIN(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
mutex_exit(&xa->xa_mutex);
smb_xa_close(xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
mutex_exit(&xa->xa_mutex);
@@ -266,7 +266,7 @@ smb_com_transaction2(struct smb_request *sr)
xa = smb_xa_create(sr->session, sr, tpscnt, tdscnt, mprcnt, mdrcnt,
msrcnt, suwcnt);
if (xa == 0) {
- smbsr_raise_error(sr, ERRSRV, ERRnoroom);
+ smbsr_error(sr, 0, ERRSRV, ERRnoroom);
/* NOTREACHED */
}
@@ -278,17 +278,17 @@ smb_com_transaction2(struct smb_request *sr)
if (MBC_SHADOW_CHAIN(&xa->req_setup_mb, &sr->smb_vwv,
sr->smb_vwv.chain_offset, suwcnt*2)) {
smb_xa_rele(sr->session, xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
if (MBC_SHADOW_CHAIN(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
smb_xa_rele(sr->session, xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
if (MBC_SHADOW_CHAIN(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
smb_xa_rele(sr->session, xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
@@ -296,7 +296,7 @@ smb_com_transaction2(struct smb_request *sr)
if (smb_xa_open(xa)) {
smb_xa_rele(sr->session, xa);
- smbsr_raise_error(sr, ERRDOS, ERRsrverror);
+ smbsr_error(sr, 0, ERRDOS, ERRsrverror);
/* NOTREACHED */
}
sr->r_xa = xa;
@@ -308,7 +308,7 @@ smb_com_transaction2(struct smb_request *sr)
if (!smb_xa_complete(xa)) {
smb_xa_close(xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
@@ -325,13 +325,13 @@ smb_com_transaction2_secondary(struct smb_request *sr)
int rc;
if ((xa = smbsr_lookup_xa(sr)) == 0) {
- smbsr_raise_error(sr, ERRSRV, ERRsrverror);
+ smbsr_error(sr, 0, ERRSRV, ERRsrverror);
/* NOTREACHED */
}
if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
if (smb_sign_check_secondary(sr, xa->reply_seqnum) != 0) {
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERRnoaccess);
/* NOTREACHED */
}
@@ -359,13 +359,13 @@ smb_com_transaction2_secondary(struct smb_request *sr)
if (MBC_SHADOW_CHAIN(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
mutex_exit(&xa->xa_mutex);
smb_xa_close(xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
if (MBC_SHADOW_CHAIN(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
mutex_exit(&xa->xa_mutex);
smb_xa_close(xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
mutex_exit(&xa->xa_mutex);
@@ -418,15 +418,15 @@ smb_nt_trans_dispatch(struct smb_request *sr, struct smb_xa *xa)
case NT_TRANSACT_QUERY_QUOTA:
(void) smb_nt_transact_query_quota(sr, xa);
- smbsr_raise_error(sr, ERRSRV, ERRaccess);
+ smbsr_error(sr, 0, ERRSRV, ERRaccess);
/* NOTREACHED */
case NT_TRANSACT_SET_QUOTA:
- smbsr_raise_error(sr, ERRSRV, ERRaccess);
+ smbsr_error(sr, 0, ERRSRV, ERRaccess);
/* NOTREACHED */
default:
- smbsr_raise_error(sr, ERRSRV, ERRsmbcmd);
+ smbsr_error(sr, 0, ERRSRV, ERRsmbcmd);
/* NOTREACHED */
}
@@ -441,7 +441,7 @@ smb_nt_trans_dispatch(struct smb_request *sr, struct smb_xa *xa)
case SDRC_UNIMPLEMENTED:
case SDRC_UNSUPPORTED:
- smbsr_raise_error(sr, ERRSRV, ERRsmbcmd);
+ smbsr_error(sr, 0, ERRSRV, ERRsmbcmd);
/* NOTREACHED */
default:
@@ -455,7 +455,7 @@ smb_nt_trans_dispatch(struct smb_request *sr, struct smb_xa *xa)
if (xa->smb_msrcnt < n_setup ||
xa->smb_mprcnt < n_param ||
xa->smb_mdrcnt < n_data) {
- smbsr_raise_error(sr, ERRSRV, ERRsmbcmd);
+ smbsr_error(sr, 0, ERRSRV, ERRsmbcmd);
/* NOTREACHED */
}
@@ -539,7 +539,7 @@ smb_com_nt_transact(struct smb_request *sr)
xa = smb_xa_create(sr->session, sr, TotalParameterCount, TotalDataCount,
MaxParameterCount, MaxDataCount, MaxSetupCount, SetupCount);
if (xa == 0) {
- smbsr_raise_error(sr, ERRSRV, ERRnoroom);
+ smbsr_error(sr, 0, ERRSRV, ERRnoroom);
/* NOTREACHED */
}
@@ -552,17 +552,17 @@ smb_com_nt_transact(struct smb_request *sr)
if (MBC_SHADOW_CHAIN(&xa->req_setup_mb, &sr->smb_vwv,
sr->smb_vwv.chain_offset, SetupCount * 2)) {
smb_xa_rele(sr->session, xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
if (MBC_SHADOW_CHAIN(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
smb_xa_rele(sr->session, xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
if (MBC_SHADOW_CHAIN(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
smb_xa_rele(sr->session, xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
@@ -570,7 +570,7 @@ smb_com_nt_transact(struct smb_request *sr)
if (smb_xa_open(xa)) {
smb_xa_rele(sr->session, xa);
- smbsr_raise_error(sr, ERRDOS, ERRsrverror);
+ smbsr_error(sr, 0, ERRDOS, ERRsrverror);
/* NOTREACHED */
}
sr->r_xa = xa;
@@ -582,7 +582,7 @@ smb_com_nt_transact(struct smb_request *sr)
if (!smb_xa_complete(xa)) {
smb_xa_close(xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
@@ -599,13 +599,13 @@ smb_com_nt_transact_secondary(struct smb_request *sr)
int rc;
if ((xa = smbsr_lookup_xa(sr)) == 0) {
- smbsr_raise_error(sr, ERRSRV, ERRsrverror);
+ smbsr_error(sr, 0, ERRSRV, ERRsrverror);
/* NOTREACHED */
}
if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
if (smb_sign_check_secondary(sr, xa->reply_seqnum) != 0) {
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERRnoaccess);
/* NOTREACHED */
}
@@ -633,13 +633,13 @@ smb_com_nt_transact_secondary(struct smb_request *sr)
if (MBC_SHADOW_CHAIN(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
mutex_exit(&xa->xa_mutex);
smb_xa_close(xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
if (MBC_SHADOW_CHAIN(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
mutex_exit(&xa->xa_mutex);
smb_xa_close(xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
mutex_exit(&xa->xa_mutex);
@@ -1926,8 +1926,7 @@ smb_trans_dispatch(struct smb_request *sr, struct smb_xa *xa)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree,
sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr,
- NT_STATUS_INVALID_HANDLE,
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -1942,7 +1941,7 @@ smb_trans_dispatch(struct smb_request *sr, struct smb_xa *xa)
case TRANS_WAIT_NMPIPE:
if (is_supported_pipe(xa->xa_smb_trans_name) == 0) {
- smbsr_raise_error(sr, ERRDOS, ERRbadfile);
+ smbsr_error(sr, 0, ERRDOS, ERRbadfile);
/* NOT REACHED */
}
rc = SDRC_NORMAL_REPLY;
@@ -2120,8 +2119,7 @@ smb_trans2_dispatch(struct smb_request *sr, struct smb_xa *xa)
* data back to client.
*/
if (n_data == 0) {
- smbsr_raise_cifs_error(sr,
- NT_STATUS_INFO_LENGTH_MISMATCH,
+ smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
ERRDOS, ERROR_BAD_LENGTH);
/* NOT REACHED */
}
@@ -2134,8 +2132,7 @@ smb_trans2_dispatch(struct smb_request *sr, struct smb_xa *xa)
* data back to client.
*/
if (n_data == 0) {
- smbsr_raise_cifs_error(sr,
- NT_STATUS_INFO_LENGTH_MISMATCH,
+ smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
ERRDOS, ERROR_BAD_LENGTH);
/* NOT REACHED */
}
@@ -2148,8 +2145,7 @@ smb_trans2_dispatch(struct smb_request *sr, struct smb_xa *xa)
* data back to client.
*/
if (n_data == 0) {
- smbsr_raise_cifs_error(sr,
- NT_STATUS_INFO_LENGTH_MISMATCH,
+ smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
ERRDOS, ERROR_BAD_LENGTH);
/* NOT REACHED */
}
@@ -2162,8 +2158,7 @@ smb_trans2_dispatch(struct smb_request *sr, struct smb_xa *xa)
* data back to client.
*/
if (n_data == 0) {
- smbsr_raise_cifs_error(sr,
- NT_STATUS_INFO_LENGTH_MISMATCH,
+ smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
ERRDOS, ERROR_BAD_LENGTH);
/* NOT REACHED */
}
@@ -2176,8 +2171,7 @@ smb_trans2_dispatch(struct smb_request *sr, struct smb_xa *xa)
* data back to client.
*/
if (n_data == 0) {
- smbsr_raise_cifs_error(sr,
- NT_STATUS_INFO_LENGTH_MISMATCH,
+ smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
ERRDOS, ERROR_BAD_LENGTH);
/* NOT REACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_common_tree.c b/usr/src/uts/common/fs/smbsrv/smb_common_tree.c
index 7906233a35..6947474f77 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_common_tree.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_common_tree.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -66,6 +66,7 @@ smbsr_connect_tree(struct smb_request *sr)
char *sharename;
char *access_msg;
int32_t stype;
+ DWORD status;
int rc;
errmsg[0] = '\0';
@@ -77,12 +78,12 @@ smbsr_connect_tree(struct smb_request *sr)
* Looks like a UNC path, make sure the format is correct.
*/
if (sharename[1] != '\\') {
- smbsr_raise_error(sr, ERRSRV, ERRinvnetname);
+ smbsr_error(sr, 0, ERRSRV, ERRinvnetname);
/* NOTREACHED */
}
if ((sharename = strchr(sharename+2, '\\')) == 0) {
- smbsr_raise_error(sr, ERRSRV, ERRinvnetname);
+ smbsr_error(sr, 0, ERRSRV, ERRinvnetname);
/* NOTREACHED */
}
@@ -91,12 +92,12 @@ smbsr_connect_tree(struct smb_request *sr)
/*
* This should be a sharename: no embedded '\' allowed.
*/
- smbsr_raise_error(sr, ERRSRV, ERRinvnetname);
+ smbsr_error(sr, 0, ERRSRV, ERRinvnetname);
/* NOTREACHED */
}
if (smb_get_stype(sharename, sr->arg.tcon.service, &stype) != 0) {
- smbsr_raise_cifs_error(sr, NT_STATUS_BAD_DEVICE_TYPE,
+ smbsr_error(sr, NT_STATUS_BAD_DEVICE_TYPE,
ERRDOS, ERROR_BAD_DEV_TYPE);
/* NOTREACHED */
}
@@ -106,14 +107,11 @@ smbsr_connect_tree(struct smb_request *sr)
smbsr_share_report(sr, sharename, access_msg, errmsg);
/*
- * W2K sometimes tries to connect to user shares using an
- * anonymous IPC connection. NT returns access denied.
+ * Windows 2000 may try to connect to user shares using
+ * an anonymous IPC connection. NT returns access denied.
*/
- if (rc == ERRaccess)
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
- ERRSRV, ERRaccess);
- else
- smbsr_raise_error(sr, ERRSRV, rc);
+ status = (rc == ERRaccess) ? NT_STATUS_ACCESS_DENIED : 0;
+ smbsr_error(sr, status, ERRSRV, rc);
/* NOTREACHED */
}
@@ -167,11 +165,11 @@ smbsr_share_report(struct smb_request *sr, char *sharename,
/*
* smbsr_setup_share
*
- * This is where the real of setting up share is done. The main thing
- * to note is that we resolve ambiguities by assuming that a directory is
- * being requested. This function returns error codes, rather than calling
- * smbsr_raise_error. We return 0 on success or a non-zero error code if
- * there is a problem.
+ * This is where the real of setting up share is done.
+ * Note that ambiguities are resolved by assuming that a directory
+ * is being requested.
+ *
+ * Returns 0 on success or a non-zero error code on failure.
*/
int
smbsr_setup_share(struct smb_request *sr, char *sharename, int32_t stype,
diff --git a/usr/src/uts/common/fs/smbsrv/smb_create.c b/usr/src/uts/common/fs/smbsrv/smb_create.c
index 8fd289bb75..c38bbfd819 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_create.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_create.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -62,13 +62,13 @@ smb_com_create(struct smb_request *sr)
break;
case NT_STATUS_SHARING_VIOLATION:
- smbsr_raise_cifs_error(sr, NT_STATUS_SHARING_VIOLATION,
+ smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
ERRDOS, ERROR_SHARING_VIOLATION);
/* NOTREACHED */
break;
default:
- smbsr_raise_nt_error(sr, status);
+ smbsr_error(sr, status, 0, 0);
/* NOTREACHED */
break;
}
@@ -107,13 +107,13 @@ smb_com_create_new(struct smb_request *sr)
break;
case NT_STATUS_SHARING_VIOLATION:
- smbsr_raise_cifs_error(sr, NT_STATUS_SHARING_VIOLATION,
+ smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
ERRDOS, ERROR_SHARING_VIOLATION);
/* NOTREACHED */
break;
default:
- smbsr_raise_nt_error(sr, status);
+ smbsr_error(sr, status, 0, 0);
/* NOTREACHED */
break;
}
@@ -165,13 +165,13 @@ smb_com_create_temporary(struct smb_request *sr)
break;
case NT_STATUS_SHARING_VIOLATION:
- smbsr_raise_cifs_error(sr, NT_STATUS_SHARING_VIOLATION,
+ smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
ERRDOS, ERROR_SHARING_VIOLATION);
/* NOTREACHED */
break;
default:
- smbsr_raise_nt_error(sr, status);
+ smbsr_error(sr, status, 0, 0);
/* NOTREACHED */
break;
}
@@ -198,7 +198,7 @@ smb_common_create(struct smb_request *sr)
if ((op->desired_access == ((uint32_t)SMB_INVALID_AMASK)) ||
(op->share_access == ((uint32_t)SMB_INVALID_SHAREMODE))) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_PARAMETER,
+ smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
ERRDOS, ERROR_INVALID_PARAMETER);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_create_directory.c b/usr/src/uts/common/fs/smbsrv/smb_create_directory.c
index e369f59b47..cb6e3f6e72 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_create_directory.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_create_directory.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -93,11 +93,7 @@ smb_com_create_directory(struct smb_request *sr)
}
if ((status = smb_validate_dirname(sr->arg.dirop.fqi.path)) != 0) {
- if (sr->session->capabilities & CAP_STATUS32)
- smbsr_raise_nt_error(sr, status);
- else
- smbsr_raise_error(sr, ERRDOS, ERROR_INVALID_NAME);
-
+ smbsr_error(sr, status, ERRDOS, ERROR_INVALID_NAME);
/* NOTREACHED */
}
@@ -110,12 +106,12 @@ smb_com_create_directory(struct smb_request *sr)
while (smbpath_next(spp)) {
rc = smb_common_create_directory(sr);
if (rc != 0 && rc != EEXIST)
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
}
/* We should have created one directory successfully! */
if (rc != 0)
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
smbsr_encode_empty_result(sr);
return (SDRC_NORMAL_REPLY);
@@ -164,7 +160,7 @@ smb_common_create_directory(struct smb_request *sr)
struct smb_node *node;
if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_delete.c b/usr/src/uts/common/fs/smbsrv/smb_delete.c
index f35e3c4273..c3a4dad862 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_delete.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_delete.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -28,10 +28,10 @@
#include <smbsrv/smb_incl.h>
#include <smbsrv/smb_fsops.h>
#include <smbsrv/smbinfo.h>
+#include <sys/nbmlock.h>
-static DWORD smb_delete_check(struct smb_request *sr, struct smb_node *node,
- uint16_t dattr, smb_error_t *smberr);
-static DWORD smb_delete_share_check(struct smb_node *node);
+static uint32_t smb_delete_check(smb_request_t *sr, smb_node_t *node,
+ smb_error_t *smberr);
/*
* smb_com_delete
@@ -104,32 +104,22 @@ smb_com_delete(struct smb_request *sr)
int is_stream;
smb_odir_context_t *pc;
- pc = kmem_zalloc(sizeof (*pc), KM_SLEEP);
- fname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
- sname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
- name = kmem_alloc(MAXNAMELEN, KM_SLEEP);
- fullname = kmem_alloc(MAXPATHLEN, KM_SLEEP);
-
if (smbsr_decode_vwv(sr, "w", &sattr) != 0) {
- kmem_free(pc, sizeof (*pc));
- kmem_free(name, MAXNAMELEN);
- kmem_free(fname, MAXNAMELEN);
- kmem_free(sname, MAXNAMELEN);
- kmem_free(fullname, MAXPATHLEN);
smbsr_decode_error(sr);
/* NOTREACHED */
}
if (smbsr_decode_data(sr, "%S", sr, &path) != 0) {
- kmem_free(pc, sizeof (*pc));
- kmem_free(name, MAXNAMELEN);
- kmem_free(fname, MAXNAMELEN);
- kmem_free(sname, MAXNAMELEN);
- kmem_free(fullname, MAXPATHLEN);
smbsr_decode_error(sr);
/* NOTREACHED */
}
+ pc = kmem_zalloc(sizeof (*pc), KM_SLEEP);
+ fname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+ sname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+ name = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+ fullname = kmem_alloc(MAXPATHLEN, KM_SLEEP);
+
is_stream = smb_stream_parse_name(path, fname, sname);
(void) smb_rdir_open(sr, path, sattr);
@@ -145,14 +135,50 @@ smb_com_delete(struct smb_request *sr)
while ((rc = smb_rdir_next(sr, &node, pc)) == 0) {
(void) strlcpy(name, pc->dc_name, MAXNAMELEN);
- if (smb_delete_check(sr, node, pc->dc_dattr, &smberr)
- != NT_STATUS_SUCCESS) {
+ if (pc->dc_dattr & SMB_FA_DIRECTORY) {
+ smberr.errcls = ERRDOS;
+ smberr.errcode = ERROR_ACCESS_DENIED;
+ smberr.status = NT_STATUS_FILE_IS_A_DIRECTORY;
smb_node_release(node);
goto delete_error;
}
- smb_node_release(node);
- node = NULL;
+ if ((pc->dc_dattr & SMB_FA_READONLY) ||
+ (node->flags & NODE_CREATED_READONLY)) {
+ smberr.errcls = ERRDOS;
+ smberr.errcode = ERROR_ACCESS_DENIED;
+ smberr.status = NT_STATUS_CANNOT_DELETE;
+ smb_node_release(node);
+ goto delete_error;
+ }
+
+ /*
+ * NT does not always close a file immediately, which
+ * can cause the share and access checking to fail
+ * (the node refcnt is greater than one), and the file
+ * doesn't get deleted. Breaking the oplock before
+ * share and access checking gives the client a chance
+ * to close the file.
+ */
+
+ if (OPLOCKS_IN_FORCE(node)) {
+ smberr.status = smb_break_oplock(sr, node);
+
+ if (smberr.status != NT_STATUS_SUCCESS) {
+ smberr.errcls = ERRDOS;
+ smberr.errcode = ERROR_VC_DISCONNECTED;
+ smb_node_release(node);
+ goto delete_error;
+ }
+ }
+
+ smb_node_start_crit(node, RW_READER);
+
+ if (smb_delete_check(sr, node, &smberr)) {
+ smb_node_end_crit(node);
+ smb_node_release(node);
+ goto delete_error;
+ }
if (is_stream) {
/*
@@ -177,6 +203,10 @@ smb_com_delete(struct smb_request *sr)
name, od);
}
+ smb_node_end_crit(node);
+ smb_node_release(node);
+ node = NULL;
+
if (rc != 0) {
if (rc != ENOENT) {
smb_rdir_close(sr);
@@ -185,7 +215,7 @@ smb_com_delete(struct smb_request *sr)
kmem_free(fname, MAXNAMELEN);
kmem_free(sname, MAXNAMELEN);
kmem_free(fullname, MAXPATHLEN);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
} else {
@@ -201,7 +231,7 @@ smb_com_delete(struct smb_request *sr)
kmem_free(fname, MAXNAMELEN);
kmem_free(sname, MAXNAMELEN);
kmem_free(fullname, MAXPATHLEN);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -231,57 +261,20 @@ delete_error:
kmem_free(fname, MAXNAMELEN);
kmem_free(sname, MAXNAMELEN);
kmem_free(fullname, MAXPATHLEN);
- smbsr_raise_cifs_error(sr,
- smberr.status, smberr.errcls, smberr.errcode);
+ smbsr_error(sr, smberr.status, smberr.errcls, smberr.errcode);
/* NOTREACHED */
return (SDRC_NORMAL_REPLY); /* compiler complains otherwise */
}
-static DWORD
-smb_delete_check(
- struct smb_request *sr,
- struct smb_node *node,
- uint16_t dattr,
- smb_error_t *smberr)
+uint32_t
+smb_delete_check(smb_request_t *sr, smb_node_t *node, smb_error_t *smberr)
{
- if (dattr & SMB_FA_DIRECTORY) {
- smberr->errcls = ERRDOS;
- smberr->errcode = ERROR_ACCESS_DENIED;
- smberr->status = NT_STATUS_FILE_IS_A_DIRECTORY;
- return (NT_STATUS_UNSUCCESSFUL);
- }
-
- if ((dattr & SMB_FA_READONLY) ||
- (node->flags & NODE_CREATED_READONLY)) {
- smberr->errcls = ERRDOS;
- smberr->errcode = ERROR_ACCESS_DENIED;
- smberr->status = NT_STATUS_CANNOT_DELETE;
- return (NT_STATUS_UNSUCCESSFUL);
- }
-
- /*
- * NT does not always close a file immediately, which
- * can cause the share and access checking to fail
- * (the node refcnt is greater than one), and the file
- * doesn't get deleted. Breaking the oplock before
- * share and access checking gives the client a chance
- * to close the file.
- */
- if (OPLOCKS_IN_FORCE(node)) {
- smberr->status = smb_break_oplock(sr, node);
+ smberr->status = smb_node_delete_check(node);
- if (smberr->status != NT_STATUS_SUCCESS) {
- smberr->errcls = ERRDOS;
- smberr->errcode = ERROR_VC_DISCONNECTED;
- return (NT_STATUS_UNSUCCESSFUL);
- }
- }
-
- smberr->status = smb_delete_share_check(node);
if (smberr->status == NT_STATUS_SHARING_VIOLATION) {
smberr->errcls = ERRDOS;
smberr->errcode = ERROR_SHARING_VIOLATION;
- return (NT_STATUS_UNSUCCESSFUL);
+ return (smberr->status);
}
/*
@@ -294,61 +287,15 @@ smb_delete_check(
* W2K rejects lock requests on open files which are opened
* with Metadata open modes. The error is STATUS_ACCESS_DENIED.
*/
- if (smb_lock_range_access(sr, node, 0, 0, FILE_WRITE_DATA) !=
- NT_STATUS_SUCCESS) {
+
+ smberr->status = smb_range_check(sr, sr->user_cr, node, 0,
+ UINT64_MAX, B_TRUE);
+
+ if (smberr->status != NT_STATUS_SUCCESS) {
smberr->errcls = ERRDOS;
smberr->errcode = ERROR_ACCESS_DENIED;
smberr->status = NT_STATUS_ACCESS_DENIED;
- return (NT_STATUS_UNSUCCESSFUL);
}
-
- return (NT_STATUS_SUCCESS);
-}
-
-/*
- * smb_delete_share_check
- *
- * An open file can be deleted only if opened for
- * accessing meta data. Share modes aren't important
- * in this case.
- *
- * NOTE: there is another mechanism for deleting an
- * open file that NT clients usually use this method.
- * That's setting "Delete on close" flag for an open
- * file, in this way the file will be deleted after
- * last close. This flag can be set by SmbTrans2SetFileInfo
- * with FILE_DISPOSITION_INFO information level.
- * For setting this flag file should be opened by
- * DELETE access in the FID that is passed in the Trans2
- * request.
- */
-static DWORD
-smb_delete_share_check(struct smb_node *node)
-{
- smb_ofile_t *file;
-
- if (node == 0 || node->n_refcnt <= 1)
- return (NT_STATUS_SUCCESS);
-
- if (node->attr.sa_vattr.va_type == VDIR)
- return (NT_STATUS_SUCCESS);
-
- smb_llist_enter(&node->n_ofile_list, RW_READER);
- file = smb_llist_head(&node->n_ofile_list);
- while (file) {
- ASSERT(file->f_magic == SMB_OFILE_MAGIC);
- if (file->f_granted_access &
- (FILE_READ_DATA |
- FILE_WRITE_DATA |
- FILE_APPEND_DATA |
- FILE_EXECUTE |
- DELETE)) {
- smb_llist_exit(&node->n_ofile_list);
- return (NT_STATUS_SHARING_VIOLATION);
- }
- file = smb_llist_next(&node->n_ofile_list, file);
- }
- smb_llist_exit(&node->n_ofile_list);
- return (NT_STATUS_SUCCESS);
+ return (smberr->status);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_delete_directory.c b/usr/src/uts/common/fs/smbsrv/smb_delete_directory.c
index e959b240b8..514551ad97 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_delete_directory.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_delete_directory.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -63,7 +63,7 @@ smb_com_delete_directory(struct smb_request *sr)
int rc;
if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -77,7 +77,7 @@ smb_com_delete_directory(struct smb_request *sr)
rc = smbd_fs_query(sr, &sr->arg.dirop.fqi, FQM_PATH_MUST_EXIST);
if (rc) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -88,7 +88,7 @@ smb_com_delete_directory(struct smb_request *sr)
smb_node_release(sr->arg.dirop.fqi.dir_snode);
SMB_NULL_FQI_NODES(sr->arg.dirop.fqi);
- smbsr_raise_cifs_error(sr, NT_STATUS_CANNOT_DELETE,
+ smbsr_error(sr, NT_STATUS_CANNOT_DELETE,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -102,7 +102,7 @@ smb_com_delete_directory(struct smb_request *sr)
if (rc != 0) {
smb_node_release(dnode);
SMB_NULL_FQI_NODES(sr->arg.dirop.fqi);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_dispatch.c b/usr/src/uts/common/fs/smbsrv/smb_dispatch.c
index 96a23bb995..0cc54ae43e 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_dispatch.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_dispatch.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
*
@@ -145,7 +145,6 @@
#define SMB_ALL_DISPATCH_STAT_INCR(stat) atomic_inc_64(&stat);
-int smb_dispatch_diags = 0;
static kstat_t *smb_dispatch_ksp = NULL;
static kstat_named_t *smb_dispatch_kstat_data = NULL;
static int smb_dispatch_kstat_size = 0;
@@ -773,6 +772,7 @@ smb_dispatch_request(struct smb_request *sr)
{
int rc;
smb_dispatch_table_t *sdd;
+ smb_error_t err;
ASSERT(sr->tid_tree == 0);
ASSERT(sr->uid_user == 0);
@@ -834,20 +834,16 @@ smb_dispatch_request(struct smb_request *sr)
sr->first_smb_com = sr->smb_com;
/*
- * Verify SMB signature if signing is enabled,
- * dialiect is NT LM 0.12,
+ * Verify SMB signature if signing is enabled, dialect is NT LM 0.12,
* signing was negotiated and authentication has occurred.
*/
if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
if (smb_sign_check_request(sr) != 0) {
- /* Reply with ACCESS_DENIED */
- if (sr->session->capabilities & CAP_STATUS32)
- smbsr_setup_nt_status(sr, ERROR_SEVERITY_ERROR,
- NT_STATUS_ACCESS_DENIED);
- else {
- sr->smb_rcls = ERRDOS;
- sr->smb_err = ERRnoaccess;
- }
+ err.severity = ERROR_SEVERITY_ERROR;
+ err.status = NT_STATUS_ACCESS_DENIED;
+ err.errcls = ERRDOS;
+ err.errcode = ERROR_ACCESS_DENIED;
+ smbsr_set_error(sr, &err);
rc = -1;
smb_rwx_rwenter(&sr->session->s_lock, RW_READER);
goto reply_error;
@@ -956,15 +952,14 @@ andx_more:
sr->uid_user = smb_user_lookup_by_uid(sr->session,
&sr->user_cr, sr->smb_uid);
if (sr->uid_user == NULL) {
- smbsr_raise_error(sr, ERRSRV, ERRbaduid);
+ smbsr_error(sr, 0, ERRSRV, ERRbaduid);
/* NOTREACHED */
}
if (!(sdd->sdt_flags & SDDF_SUPPRESS_TID)) {
sr->tid_tree = smb_tree_lookup_by_tid(
sr->uid_user, sr->smb_tid);
if (sr->tid_tree == NULL) {
- smbsr_raise_error(sr, ERRSRV,
- ERRinvnid);
+ smbsr_error(sr, 0, ERRSRV, ERRinvnid);
/* NOTREACHED */
}
}
@@ -1274,78 +1269,15 @@ smbsr_encode_empty_result(struct smb_request *sr)
}
/*
- * cifs_raise_error
- *
- * Temporary workaround to the NT status versus Win32/SMB error codes
- * decision: just report them both here.
- */
-void
-smbsr_raise_cifs_error(struct smb_request *sr,
- DWORD status,
- int error_class,
- int error_code)
-{
- if (sr->session->capabilities & CAP_STATUS32)
- smbsr_raise_nt_error(sr, status);
- else
- smbsr_raise_error(sr, error_class, error_code);
-
- /* NOTREACHED */
-}
-
-void
-smbsr_raise_error(struct smb_request *sr, int errcls, int errcod)
-{
- sr->smb_rcls = (unsigned char)errcls;
- sr->smb_err = (uint16_t)errcod;
- longjmp(&sr->exjb);
-}
-
-/*
- * smbsr_setup_nt_status
- *
- * Set up an NT status in the smb_request but don't long jump or try
- * to do any error handling. There are times when we need a status set
- * up in the response to indicate that the request has either failed
- * or, at least, is only partially complete (possibly indicated by the
- * severity) but we also need to return some information to the client.
- */
-void
-smbsr_setup_nt_status(struct smb_request *sr,
- uint32_t severity,
- uint32_t nt_status)
-{
- nt_status |= severity;
- sr->smb_rcls = nt_status & 0xff;
- sr->smb_reh = (nt_status >> 8) & 0xff;
- sr->smb_err = nt_status >> 16;
- sr->smb_flg2 |= SMB_FLAGS2_NT_STATUS;
-}
-
-void
-smbsr_raise_nt_error(struct smb_request *sr, uint32_t errcod)
-{
- errcod |= 0xc0000000;
- sr->smb_rcls = errcod & 0xff;
- sr->smb_reh = (errcod >> 8) & 0xff;
- sr->smb_err = errcod >> 16;
- sr->smb_flg2 |= SMB_FLAGS2_NT_STATUS;
- longjmp(&sr->exjb);
-}
-
-
-/*
- * Attempt to map errno values to SMB and NT status values.
- * Note: ESRCH is used as special case to handle a lookup
- * failure on streams.
+ * Map errno values to SMB and NT status values.
+ * Note: ESRCH is a special case to handle a streams lookup failure.
*/
static struct {
- int unix_errno;
- int smb_error_class;
- int smb_error_value;
- DWORD nt_status;
-}
-smb_errno_map[] = {
+ int errnum;
+ int errcls;
+ int errcode;
+ DWORD status32;
+} smb_errno_map[] = {
{ ENOSPC, ERRDOS, ERROR_DISK_FULL, NT_STATUS_DISK_FULL },
{ EDQUOT, ERRDOS, ERROR_DISK_FULL, NT_STATUS_DISK_FULL },
{ EPERM, ERRSRV, ERRaccess, NT_STATUS_ACCESS_DENIED },
@@ -1375,74 +1307,115 @@ smb_errno_map[] = {
};
void
-smb_errmap_unix2smb(int en, smb_error_t *smberr)
+smbsr_map_errno(int errnum, smb_error_t *err)
{
int i;
- smberr->status = NT_STATUS_UNSUCCESSFUL;
- smberr->errcls = ERRDOS;
- smberr->errcode = ERROR_GEN_FAILURE;
-
for (i = 0; i < sizeof (smb_errno_map)/sizeof (smb_errno_map[0]); ++i) {
- if (smb_errno_map[i].unix_errno == en) {
- smberr->status = smb_errno_map[i].nt_status;
- smberr->errcls = smb_errno_map[i].smb_error_class;
- smberr->errcode = smb_errno_map[i].smb_error_value;
+ if (smb_errno_map[i].errnum == errnum) {
+ err->severity = ERROR_SEVERITY_ERROR;
+ err->status = smb_errno_map[i].status32;
+ err->errcls = smb_errno_map[i].errcls;
+ err->errcode = smb_errno_map[i].errcode;
return;
}
}
+
+ err->severity = ERROR_SEVERITY_ERROR;
+ err->status = NT_STATUS_INTERNAL_ERROR;
+ err->errcls = ERRDOS;
+ err->errcode = ERROR_INTERNAL_ERROR;
}
-int
-smbsr_set_errno(struct smb_request *sr, int en)
+void
+smbsr_errno(struct smb_request *sr, int errnum)
{
- int i;
+ smb_error_t err;
- ASSERT(en != -1);
+ smbsr_map_errno(errnum, &err);
+ smbsr_set_error(sr, &err);
+ longjmp(&sr->exjb);
+ /* NOTREACHED */
+}
- /*
- * If the client supports 32-bit NT status values, check for
- * an appropriate mapping and raise an NT error, control won't
- * return here due to the longjmp in smbsr_raise_nt_error.
- */
- if (sr->session->capabilities & CAP_STATUS32) {
- for (i = 0;
- i < sizeof (smb_errno_map)/sizeof (smb_errno_map[0]);
- ++i) {
- if (smb_errno_map[i].unix_errno == en) {
- smbsr_raise_nt_error(sr,
- smb_errno_map[i].nt_status);
- /* NOTREACHED */
- }
- }
- } else {
- for (i = 0;
- i < sizeof (smb_errno_map)/sizeof (smb_errno_map[0]);
- ++i) {
- if (smb_errno_map[i].unix_errno == en) {
- sr->smb_rcls = smb_errno_map[i].smb_error_class;
- sr->smb_err = smb_errno_map[i].smb_error_value;
- return (0);
- }
- }
- }
+/*
+ * Report a request processing warning.
+ */
+void
+smbsr_warn(smb_request_t *sr, DWORD status, uint16_t errcls, uint16_t errcode)
+{
+ smb_error_t err;
+
+ err.severity = ERROR_SEVERITY_WARNING;
+ err.status = status;
+ err.errcls = errcls;
+ err.errcode = errcode;
- sr->smb_rcls = ERRSRV;
- sr->smb_err = ERRerror;
- return (-1);
+ smbsr_set_error(sr, &err);
}
+/*
+ * Report a request processing error. This function will not return.
+ */
void
-smbsr_raise_errno(struct smb_request *sr, int en)
+smbsr_error(smb_request_t *sr, DWORD status, uint16_t errcls, uint16_t errcode)
{
- if (smbsr_set_errno(sr, en) != 0) {
- if (smb_dispatch_diags) {
- cmn_err(CE_NOTE, "SmbErrno: errno=%d", en);
- }
- }
+ smb_error_t err;
+ err.severity = ERROR_SEVERITY_ERROR;
+ err.status = status;
+ err.errcls = errcls;
+ err.errcode = errcode;
+
+ smbsr_set_error(sr, &err);
longjmp(&sr->exjb);
- /* no return */
+ /* NOTREACHED */
+}
+
+/*
+ * Setup a request processing error. This function can be used to
+ * report 32-bit status codes or DOS errors. Set the status code
+ * to 0 (NT_STATUS_SUCCESS) to explicitly report a DOS error,
+ * regardless of the client capabilities.
+ *
+ * If status is non-zero and the client supports 32-bit status
+ * codes, report the status. Otherwise, report the DOS error.
+ */
+void
+smbsr_set_error(smb_request_t *sr, smb_error_t *err)
+{
+ uint32_t status;
+ uint32_t severity;
+ uint32_t capabilities;
+
+ ASSERT(sr);
+ ASSERT(err);
+
+ status = err->status;
+ severity = (err->severity == 0) ? ERROR_SEVERITY_ERROR : err->severity;
+ capabilities = sr->session->capabilities;
+
+ if ((err->errcls == 0) && (err->errcode == 0)) {
+ capabilities |= CAP_STATUS32;
+ if (status == 0)
+ status = NT_STATUS_INTERNAL_ERROR;
+ }
+
+ if ((capabilities & CAP_STATUS32) && (status != 0)) {
+ status |= severity;
+ sr->smb_rcls = status & 0xff;
+ sr->smb_reh = (status >> 8) & 0xff;
+ sr->smb_err = status >> 16;
+ sr->smb_flg2 |= SMB_FLAGS2_NT_STATUS;
+ } else {
+ if ((err->errcls == 0) || (err->errcode == 0)) {
+ sr->smb_rcls = ERRSRV;
+ sr->smb_err = ERRerror;
+ } else {
+ sr->smb_rcls = (uint8_t)err->errcls;
+ sr->smb_err = (uint16_t)err->errcode;
+ }
+ }
}
smb_xa_t *
diff --git a/usr/src/uts/common/fs/smbsrv/smb_find.c b/usr/src/uts/common/fs/smbsrv/smb_find.c
index 1492219714..a45e5cab64 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_find.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_find.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -248,7 +248,7 @@ smb_com_find(struct smb_request *sr)
sr->sid_odir = smb_odir_lookup_by_sid(sr->tid_tree,
sr->smb_sid);
if (sr->sid_odir == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -286,13 +286,13 @@ smb_com_find(struct smb_request *sr)
if ((rc != 0) && (rc != ENOENT)) {
/* returned error by smb_rdir_next() */
smb_rdir_close(sr);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
if (count == 0) {
smb_rdir_close(sr);
- smbsr_raise_error(sr, ERRDOS, ERRnofiles);
+ smbsr_error(sr, 0, ERRDOS, ERRnofiles);
/* NOTREACHED */
}
@@ -408,7 +408,7 @@ smb_com_find_close(struct smb_request *sr)
}
if (key_len == 0) { /* begin search */
- smbsr_raise_error(sr, ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -423,7 +423,7 @@ smb_com_find_close(struct smb_request *sr)
sr->sid_odir = smb_odir_lookup_by_sid(sr->tid_tree,
sr->smb_sid);
if (sr->sid_odir == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERRbadfid);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_find_unique.c b/usr/src/uts/common/fs/smbsrv/smb_find_unique.c
index 59f9ba12b2..f9686297f0 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_find_unique.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_find_unique.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -264,13 +264,13 @@ smb_com_find_unique(struct smb_request *sr)
if ((rc != 0) && (rc != ENOENT)) {
/* returned error by smb_rdir_next() */
kmem_free(vdb, sizeof (struct vardata_block));
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
if (count == 0) {
kmem_free(vdb, sizeof (struct vardata_block));
- smbsr_raise_error(sr, ERRDOS, ERRnofiles);
+ smbsr_error(sr, 0, ERRDOS, ERRnofiles);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_flush.c b/usr/src/uts/common/fs/smbsrv/smb_flush.c
index b9cfb8c349..c3da4a2352 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_flush.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_flush.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -93,7 +93,7 @@ smb_com_flush(smb_request_t *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree,
sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERRbadfid);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_fsops.c b/usr/src/uts/common/fs/smbsrv/smb_fsops.c
index 3d7292961e..561f640fd1 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_fsops.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_fsops.c
@@ -19,26 +19,31 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/sid.h>
+#include <sys/nbmlock.h>
#include <smbsrv/smb_fsops.h>
#include <smbsrv/smb_kproto.h>
#include <smbsrv/smbvar.h>
#include <smbsrv/ntstatus.h>
#include <smbsrv/ntaccess.h>
+#include <smbsrv/smb_incl.h>
#include <acl/acl_common.h>
-
-u_longlong_t smb_caller_id;
+#include <sys/fcntl.h>
+#include <sys/flock.h>
+#include <fs/fs_subr.h>
static int smb_fsop_amask_to_omode(uint32_t granted_access);
static int smb_fsop_sdinherit(smb_request_t *sr, smb_node_t *dnode,
smb_fssd_t *fs_sd);
+static callb_cpr_t *smb_fsop_frlock_callback(flk_cb_when_t when, void *error);
+
/*
* The smb_fsop_* functions have knowledge of CIFS semantics.
*
@@ -65,7 +70,8 @@ smb_fsop_start()
{
int error;
- smb_caller_id = fs_new_caller_id();
+ smb_vop_start();
+
error = smb_node_root_init();
if (error == 0)
@@ -85,32 +91,26 @@ smb_fsop_stop()
int
smb_fsop_open(smb_ofile_t *of)
{
- caller_context_t ct;
int mode;
mode = smb_fsop_amask_to_omode(of->f_granted_access);
- smb_get_caller_context(NULL, &ct);
-
/*
* Assuming that same vnode is returned as we had before
* (i.e. no special vnodes)
*/
- return (smb_vop_open(&of->f_node->vp, mode, of->f_cr, &ct));
+ return (smb_vop_open(&of->f_node->vp, mode, of->f_cr));
}
int
smb_fsop_close(smb_ofile_t *of)
{
- caller_context_t ct;
int mode;
mode = smb_fsop_amask_to_omode(of->f_granted_access);
- smb_get_caller_context(NULL, &ct);
-
- return (smb_vop_close(of->f_node->vp, mode, of->f_cr, &ct));
+ return (smb_vop_close(of->f_node->vp, mode, of->f_cr));
}
static int
@@ -141,7 +141,6 @@ smb_fsop_create_with_sd(
smb_attr_t *ret_attr,
smb_fssd_t *fs_sd)
{
- caller_context_t ct;
vsecattr_t *vsap;
vsecattr_t vsecattr;
acl_t *acl, *dacl, *sacl;
@@ -159,7 +158,6 @@ smb_fsop_create_with_sd(
flags = SMB_IGNORE_CASE;
ASSERT(cr);
- smb_get_caller_context(sr, &ct);
is_dir = ((fs_sd->sd_flags & SMB_FSSD_FLAGS_DIR) != 0);
@@ -191,10 +189,10 @@ smb_fsop_create_with_sd(
if (is_dir) {
rc = smb_vop_mkdir(snode->vp, name, attr, &vp, flags,
- cr, &ct, vsap);
+ cr, vsap);
} else {
rc = smb_vop_create(snode->vp, name, attr, &vp, flags,
- cr, &ct, vsap);
+ cr, vsap);
}
if (vsap != NULL)
@@ -226,7 +224,7 @@ smb_fsop_create_with_sd(
if (sr->tid_tree->t_flags & SMB_TREE_FLAG_UFS)
no_xvattr = B_TRUE;
rc = smb_vop_setattr(snode->vp, NULL, &set_attr,
- 0, kcred, no_xvattr, &ct);
+ 0, kcred, no_xvattr);
}
} else {
@@ -241,10 +239,10 @@ smb_fsop_create_with_sd(
if (is_dir) {
rc = smb_vop_mkdir(snode->vp, name, attr, &vp, flags,
- cr, &ct, NULL);
+ cr, NULL);
} else {
rc = smb_vop_create(snode->vp, name, attr, &vp, flags,
- cr, &ct, NULL);
+ cr, NULL);
}
if (rc != 0)
@@ -266,9 +264,9 @@ smb_fsop_create_with_sd(
if (rc != 0) {
if (is_dir) {
- (void) smb_vop_rmdir(snode->vp, name, flags, cr, &ct);
+ (void) smb_vop_rmdir(snode->vp, name, flags, cr);
} else {
- (void) smb_vop_remove(snode->vp, name, flags, cr, &ct);
+ (void) smb_vop_remove(snode->vp, name, flags, cr);
}
}
@@ -303,7 +301,6 @@ smb_fsop_create(
struct open_param *op = &sr->arg.open;
smb_node_t *fnode;
smb_attr_t file_attr;
- caller_context_t ct;
vnode_t *xattrdirvp;
vnode_t *vp;
char *longname = NULL;
@@ -397,10 +394,8 @@ smb_fsop_create(
return (rc);
}
- smb_get_caller_context(sr, &ct);
-
rc = smb_vop_stream_create(fnode->vp, sname, attr, &vp,
- &xattrdirvp, flags, cr, &ct);
+ &xattrdirvp, flags, cr);
if (rc != 0) {
smb_node_release(fnode);
@@ -457,9 +452,8 @@ smb_fsop_create(
* No incoming SD and filesystem is not ZFS
* let the filesystem handles the inheritance.
*/
- smb_get_caller_context(sr, &ct);
rc = smb_vop_create(dir_snode->vp, name, attr, &vp,
- flags, cr, &ct, NULL);
+ flags, cr, NULL);
if (rc == 0) {
*ret_snode = smb_node_lookup(sr, op, cr, vp,
@@ -503,7 +497,6 @@ smb_fsop_mkdir(
smb_attr_t *ret_attr)
{
struct open_param *op = &sr->arg.open;
- caller_context_t ct;
char *longname;
vnode_t *vp;
int flags = 0;
@@ -511,7 +504,6 @@ smb_fsop_mkdir(
uint32_t secinfo;
uint32_t status;
int rc;
-
ASSERT(cr);
ASSERT(dir_snode);
ASSERT(dir_snode->n_magic == SMB_NODE_MAGIC);
@@ -557,8 +549,6 @@ smb_fsop_mkdir(
if (SMB_TREE_CASE_INSENSITIVE(sr))
flags = SMB_IGNORE_CASE;
- smb_get_caller_context(sr, &ct);
-
if (op->sd) {
/*
* SD sent by client in Windows format. Needs to be
@@ -592,7 +582,7 @@ smb_fsop_mkdir(
} else {
rc = smb_vop_mkdir(dir_snode->vp, name, attr, &vp, flags, cr,
- &ct, NULL);
+ NULL);
if (rc == 0) {
*ret_snode = smb_node_lookup(sr, op, cr, vp, name,
@@ -632,7 +622,6 @@ smb_fsop_remove(
{
smb_node_t *fnode;
smb_attr_t file_attr;
- caller_context_t ct;
char *longname;
char *fname;
char *sname;
@@ -654,8 +643,6 @@ smb_fsop_remove(
if (SMB_TREE_IS_READ_ONLY(sr))
return (EROFS);
- smb_get_caller_context(sr, &ct);
-
fname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
sname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
@@ -687,7 +674,7 @@ smb_fsop_remove(
* Need to find out what permission is required by NTFS
* to remove a stream.
*/
- rc = smb_vop_stream_remove(fnode->vp, sname, flags, cr, &ct);
+ rc = smb_vop_stream_remove(fnode->vp, sname, flags, cr);
smb_node_release(fnode);
} else {
@@ -705,7 +692,7 @@ smb_fsop_remove(
if ((od == 0) && SMB_TREE_CASE_INSENSITIVE(sr))
flags = SMB_IGNORE_CASE;
- rc = smb_vop_remove(dir_snode->vp, name, flags, cr, &ct);
+ rc = smb_vop_remove(dir_snode->vp, name, flags, cr);
if (rc == ENOENT) {
if (smb_maybe_mangled_name(name) == 0) {
@@ -729,7 +716,7 @@ smb_fsop_remove(
*/
flags &= ~SMB_IGNORE_CASE;
rc = smb_vop_remove(dir_snode->vp, longname,
- flags, cr, &ct);
+ flags, cr);
}
kmem_free(longname, MAXNAMELEN);
@@ -754,7 +741,6 @@ smb_fsop_remove_streams(struct smb_request *sr, cred_t *cr,
smb_node_t *fnode)
{
struct fs_stream_info stream_info;
- caller_context_t ct;
uint32_t cookie = 0;
int flags = 0;
int rc;
@@ -773,17 +759,15 @@ smb_fsop_remove_streams(struct smb_request *sr, cred_t *cr,
if (SMB_TREE_CASE_INSENSITIVE(sr))
flags = SMB_IGNORE_CASE;
- smb_get_caller_context(sr, &ct);
-
for (;;) {
rc = smb_vop_stream_readdir(fnode->vp, &cookie, &stream_info,
- NULL, NULL, flags, cr, &ct);
+ NULL, NULL, flags, cr);
if ((rc != 0) || (cookie == SMB_EOF))
break;
(void) smb_vop_stream_remove(fnode->vp, stream_info.name, flags,
- cr, &ct);
+ cr);
}
return (rc);
}
@@ -809,7 +793,6 @@ smb_fsop_rmdir(
char *name,
int od)
{
- caller_context_t ct;
int rc;
int flags = 0;
char *longname;
@@ -843,9 +826,7 @@ smb_fsop_rmdir(
if ((od == 0) && SMB_TREE_CASE_INSENSITIVE(sr))
flags = SMB_IGNORE_CASE;
- smb_get_caller_context(sr, &ct);
-
- rc = smb_vop_rmdir(dir_snode->vp, name, flags, cr, &ct);
+ rc = smb_vop_rmdir(dir_snode->vp, name, flags, cr);
if (rc == ENOENT) {
if (smb_maybe_mangled_name(name) == 0)
@@ -867,8 +848,7 @@ smb_fsop_rmdir(
* a unique directory.
*/
flags &= ~SMB_IGNORE_CASE;
- rc = smb_vop_rmdir(dir_snode->vp, longname, flags, cr,
- &ct);
+ rc = smb_vop_rmdir(dir_snode->vp, longname, flags, cr);
}
kmem_free(longname, MAXNAMELEN);
@@ -893,10 +873,10 @@ smb_fsop_getattr(struct smb_request *sr, cred_t *cr, smb_node_t *snode,
{
smb_node_t *unnamed_node;
vnode_t *unnamed_vp = NULL;
- caller_context_t ct;
uint32_t status;
uint32_t access = 0;
int flags = 0;
+ int rc;
ASSERT(cr);
ASSERT(snode);
@@ -923,8 +903,6 @@ smb_fsop_getattr(struct smb_request *sr, cred_t *cr, smb_node_t *snode,
flags = ATTR_NOACLCHECK;
}
- smb_get_caller_context(sr, &ct);
-
unnamed_node = SMB_IS_STREAM(snode);
if (unnamed_node) {
@@ -933,7 +911,11 @@ smb_fsop_getattr(struct smb_request *sr, cred_t *cr, smb_node_t *snode,
unnamed_vp = unnamed_node->vp;
}
- return (smb_vop_getattr(snode->vp, unnamed_vp, attr, flags, cr, &ct));
+ rc = smb_vop_getattr(snode->vp, unnamed_vp, attr, flags, cr);
+ if (rc == 0)
+ snode->attr = *attr;
+
+ return (rc);
}
/*
@@ -959,7 +941,6 @@ smb_fsop_readdir(
smb_node_t **ret_snode,
smb_attr_t *ret_attr)
{
- caller_context_t ct;
smb_node_t *ret_snodep;
smb_node_t *fnode;
smb_attr_t tmp_attr;
@@ -986,13 +967,11 @@ smb_fsop_readdir(
if (SMB_TREE_CASE_INSENSITIVE(sr))
flags = SMB_IGNORE_CASE;
- smb_get_caller_context(sr, &ct);
-
od_name = kmem_alloc(MAXNAMELEN, KM_SLEEP);
if (stream_info) {
rc = smb_vop_lookup(dir_snode->vp, name, &fvp, od_name,
- SMB_FOLLOW_LINKS, sr->tid_tree->t_snode->vp, cr, &ct);
+ SMB_FOLLOW_LINKS, sr->tid_tree->t_snode->vp, cr);
if (rc != 0) {
kmem_free(od_name, MAXNAMELEN);
@@ -1017,7 +996,7 @@ smb_fsop_readdir(
* Might have to use kcred.
*/
rc = smb_vop_stream_readdir(fvp, cookie, stream_info, &vp,
- &xattrdirvp, flags, cr, &ct);
+ &xattrdirvp, flags, cr);
if ((rc != 0) || (*cookie == SMB_EOF)) {
smb_node_release(fnode);
@@ -1047,7 +1026,7 @@ smb_fsop_readdir(
} else {
rc = smb_vop_readdir(dir_snode->vp, cookie, name, namelen,
- fileid, &vp, od_name, flags, cr, &ct);
+ fileid, &vp, od_name, flags, cr);
if (rc != 0) {
kmem_free(od_name, MAXNAMELEN);
@@ -1104,7 +1083,6 @@ smb_fsop_getdents(
char *args,
char *pattern)
{
- caller_context_t ct;
int flags = 0;
ASSERT(cr);
@@ -1118,10 +1096,8 @@ smb_fsop_getdents(
if (SMB_TREE_CASE_INSENSITIVE(sr))
flags = SMB_IGNORE_CASE;
- smb_get_caller_context(sr, &ct);
-
return (smb_vop_getdents(dir_snode, cookie, 0, maxcnt, args, pattern,
- flags, sr, cr, &ct));
+ flags, sr, cr));
}
/*
@@ -1145,7 +1121,6 @@ smb_fsop_rename(
char *to_name)
{
smb_node_t *from_snode;
- caller_context_t ct;
smb_attr_t tmp_attr;
vnode_t *from_vp;
int flags = 0;
@@ -1188,16 +1163,14 @@ smb_fsop_rename(
* XXX: Lock required through smb_node_release() below?
*/
- smb_get_caller_context(sr, &ct);
-
rc = smb_vop_lookup(from_dir_snode->vp, from_name, &from_vp, NULL, 0,
- NULL, cr, &ct);
+ NULL, cr);
if (rc != 0)
return (rc);
rc = smb_vop_rename(from_dir_snode->vp, from_name, to_dir_snode->vp,
- to_name, flags, cr, &ct);
+ to_name, flags, cr);
if (rc == 0) {
from_snode = smb_node_lookup(sr, NULL, cr, from_vp, from_name,
@@ -1242,7 +1215,6 @@ smb_fsop_setattr(
{
smb_node_t *unnamed_node;
vnode_t *unnamed_vp = NULL;
- caller_context_t ct;
uint32_t status;
uint32_t access = 0;
int rc = 0;
@@ -1278,8 +1250,6 @@ smb_fsop_setattr(
flags = ATTR_NOACLCHECK;
}
- smb_get_caller_context(sr, &ct);
-
unnamed_node = SMB_IS_STREAM(snode);
if (unnamed_node) {
@@ -1291,18 +1261,18 @@ smb_fsop_setattr(
if (sr->tid_tree->t_flags & SMB_TREE_FLAG_UFS)
no_xvattr = B_TRUE;
- rc = smb_vop_setattr(snode->vp, unnamed_vp,
- set_attr, flags, cr, no_xvattr, &ct);
+ rc = smb_vop_setattr(snode->vp, unnamed_vp, set_attr, flags, cr,
+ no_xvattr);
if ((rc == 0) && ret_attr) {
/*
- * This is an operation on behalf of CIFS service (to update
- * smb node's attr) not on behalf of the user so it's done
- * using kcred and the return value is intentionally ignored.
+ * Use kcred to update the node attr because this
+ * call is not being made on behalf of the user.
*/
ret_attr->sa_mask = SMB_AT_ALL;
- (void) smb_vop_getattr(snode->vp, unnamed_vp, ret_attr, 0,
- kcred, &ct);
+ rc = smb_vop_getattr(snode->vp, unnamed_vp, ret_attr, 0, kcred);
+ if (rc == 0)
+ snode->attr = *ret_attr;
}
return (rc);
@@ -1328,7 +1298,7 @@ smb_fsop_read(
{
smb_node_t *unnamed_node;
vnode_t *unnamed_vp = NULL;
- caller_context_t ct;
+ int svmand;
int rc;
ASSERT(cr);
@@ -1360,20 +1330,36 @@ smb_fsop_read(
cr = kcred;
}
- smb_get_caller_context(sr, &ct);
- rc = smb_vop_read(snode->vp, uio, cr, &ct);
+ smb_node_start_crit(snode, RW_READER);
+ rc = nbl_svmand(snode->vp, cr, &svmand);
+ if (rc) {
+ smb_node_end_crit(snode);
+ return (rc);
+ }
+
+ rc = nbl_lock_conflict(snode->vp, NBL_READ, uio->uio_loffset,
+ uio->uio_iov->iov_len, svmand, &smb_ct);
- if (rc == 0) {
+ if (rc) {
+ smb_node_end_crit(snode);
+ return (rc);
+ }
+ rc = smb_vop_read(snode->vp, uio, cr);
+
+ if (rc == 0 && ret_attr) {
/*
- * This is an operation on behalf of CIFS service (to update
- * smb node's attr) not on behalf of the user so it's done
- * using kcred and the return value is intentionally ignored.
+ * Use kcred to update the node attr because this
+ * call is not being made on behalf of the user.
*/
ret_attr->sa_mask = SMB_AT_ALL;
- (void) smb_vop_getattr(snode->vp, unnamed_vp, ret_attr, 0,
- kcred, &ct);
+ if (smb_vop_getattr(snode->vp, unnamed_vp, ret_attr, 0,
+ kcred) == 0) {
+ snode->attr = *ret_attr;
+ }
}
+ smb_node_end_crit(snode);
+
return (rc);
}
@@ -1396,7 +1382,7 @@ smb_fsop_write(
{
smb_node_t *unnamed_node;
vnode_t *unnamed_vp = NULL;
- caller_context_t ct;
+ int svmand;
int rc;
ASSERT(cr);
@@ -1410,15 +1396,13 @@ smb_fsop_write(
if (SMB_TREE_IS_READ_ONLY(sr))
return (EROFS);
- /*
- * XXX what if the file has been opened only with
- * FILE_APPEND_DATA?
- */
- rc = smb_ofile_access(sr->fid_ofile, cr, FILE_WRITE_DATA);
- if (rc != NT_STATUS_SUCCESS)
- return (EACCES);
- smb_get_caller_context(sr, &ct);
+ rc = smb_ofile_access(sr->fid_ofile, cr, FILE_WRITE_DATA);
+ if (rc != NT_STATUS_SUCCESS) {
+ rc = smb_ofile_access(sr->fid_ofile, cr, FILE_APPEND_DATA);
+ if (rc != NT_STATUS_SUCCESS)
+ return (EACCES);
+ }
unnamed_node = SMB_IS_STREAM(snode);
@@ -1435,19 +1419,35 @@ smb_fsop_write(
cr = kcred;
}
- rc = smb_vop_write(snode->vp, uio, flag, lcount, cr, &ct);
+ smb_node_start_crit(snode, RW_READER);
+ rc = nbl_svmand(snode->vp, cr, &svmand);
+ if (rc) {
+ smb_node_end_crit(snode);
+ return (rc);
+ }
+ rc = nbl_lock_conflict(snode->vp, NBL_WRITE, uio->uio_loffset,
+ uio->uio_iov->iov_len, svmand, &smb_ct);
- if (rc == 0) {
+ if (rc) {
+ smb_node_end_crit(snode);
+ return (rc);
+ }
+ rc = smb_vop_write(snode->vp, uio, flag, lcount, cr);
+
+ if (rc == 0 && ret_attr) {
/*
- * This is an operation on behalf of CIFS service (to update
- * smb node's attr) not on behalf of the user so it's done
- * using kcred and the return value is intentionally ignored.
+ * Use kcred to update the node attr because this
+ * call is not being made on behalf of the user.
*/
ret_attr->sa_mask = SMB_AT_ALL;
- (void) smb_vop_getattr(snode->vp, unnamed_vp, ret_attr, 0,
- kcred, &ct);
+ if (smb_vop_getattr(snode->vp, unnamed_vp, ret_attr, 0,
+ kcred) == 0) {
+ snode->attr = *ret_attr;
+ }
}
+ smb_node_end_crit(snode);
+
return (rc);
}
@@ -1577,7 +1577,6 @@ smb_fsop_lookup_name(
{
smb_node_t *fnode;
smb_attr_t file_attr;
- caller_context_t ct;
vnode_t *xattrdirvp;
vnode_t *vp;
char *od_name;
@@ -1627,7 +1626,7 @@ smb_fsop_lookup_name(
* What permissions NTFS requires for stream lookup if any?
*/
rc = smb_vop_stream_lookup(fnode->vp, sname, &vp, od_name,
- &xattrdirvp, flags, root_node->vp, cr, &ct);
+ &xattrdirvp, flags, root_node->vp, cr);
if (rc != 0) {
smb_node_release(fnode);
@@ -1707,7 +1706,6 @@ smb_fsop_lookup(
{
smb_node_t *lnk_target_node;
smb_node_t *lnk_dnode;
- caller_context_t ct;
char *longname;
char *od_name;
vnode_t *vp;
@@ -1727,12 +1725,10 @@ smb_fsop_lookup(
if (SMB_TREE_CASE_INSENSITIVE(sr))
flags |= SMB_IGNORE_CASE;
- smb_get_caller_context(sr, &ct);
-
od_name = kmem_alloc(MAXNAMELEN, KM_SLEEP);
rc = smb_vop_lookup(dir_snode->vp, name, &vp, od_name, flags,
- root_node ? root_node->vp : NULL, cr, &ct);
+ root_node ? root_node->vp : NULL, cr);
if (rc != 0) {
if (smb_maybe_mangled_name(name) == 0) {
@@ -1764,7 +1760,7 @@ smb_fsop_lookup(
flags &= ~SMB_IGNORE_CASE;
rc = smb_vop_lookup(dir_snode->vp, longname, &vp, od_name,
- flags, root_node ? root_node->vp : NULL, cr, &ct);
+ flags, root_node ? root_node->vp : NULL, cr);
kmem_free(longname, MAXNAMELEN);
@@ -1871,7 +1867,6 @@ smb_fsop_stream_readdir(struct smb_request *sr, cred_t *cr, smb_node_t *fnode,
smb_node_t **ret_snode, smb_attr_t *ret_attr)
{
smb_node_t *ret_snodep = NULL;
- caller_context_t ct;
smb_attr_t tmp_attr;
vnode_t *xattrdirvp;
vnode_t *vp;
@@ -1889,10 +1884,8 @@ smb_fsop_stream_readdir(struct smb_request *sr, cred_t *cr, smb_node_t *fnode,
if (SMB_TREE_CASE_INSENSITIVE(sr))
flags = SMB_IGNORE_CASE;
- smb_get_caller_context(sr, &ct);
-
rc = smb_vop_stream_readdir(fnode->vp, cookiep, stream_info, &vp,
- &xattrdirvp, flags, cr, &ct);
+ &xattrdirvp, flags, cr);
if ((rc != 0) || *cookiep == SMB_EOF)
return (rc);
@@ -1922,8 +1915,6 @@ smb_fsop_stream_readdir(struct smb_request *sr, cred_t *cr, smb_node_t *fnode,
int /*ARGSUSED*/
smb_fsop_commit(smb_request_t *sr, cred_t *cr, smb_node_t *snode)
{
- caller_context_t ct;
-
ASSERT(cr);
ASSERT(snode);
ASSERT(snode->n_magic == SMB_NODE_MAGIC);
@@ -1934,9 +1925,7 @@ smb_fsop_commit(smb_request_t *sr, cred_t *cr, smb_node_t *snode)
if (SMB_TREE_IS_READ_ONLY(sr))
return (EROFS);
- smb_get_caller_context(sr, &ct);
-
- return (smb_vop_commit(snode->vp, cr, &ct));
+ return (smb_vop_commit(snode->vp, cr));
}
/*
@@ -1961,7 +1950,6 @@ smb_fsop_aclread(smb_request_t *sr, cred_t *cr, smb_node_t *snode,
int flags = 0;
int access = 0;
acl_t *acl;
- caller_context_t ct;
smb_node_t *unnamed_node;
ASSERT(cr);
@@ -1993,9 +1981,8 @@ smb_fsop_aclread(smb_request_t *sr, cred_t *cr, smb_node_t *snode,
if (sr->tid_tree->t_flags & SMB_TREE_FLAG_ACEMASKONACCESS)
flags = ATTR_NOACLCHECK;
- smb_get_caller_context(sr, &ct);
error = smb_vop_acl_read(snode->vp, &acl, flags,
- sr->tid_tree->t_acltype, cr, &ct);
+ sr->tid_tree->t_acltype, cr);
if (error != 0) {
return (error);
}
@@ -2025,7 +2012,6 @@ smb_fsop_aclwrite(smb_request_t *sr, cred_t *cr, smb_node_t *snode,
int error = 0;
int flags = 0;
int access = 0;
- caller_context_t ct;
acl_t *acl, *dacl, *sacl;
smb_node_t *unnamed_node;
@@ -2088,11 +2074,10 @@ smb_fsop_aclwrite(smb_request_t *sr, cred_t *cr, smb_node_t *snode,
error = acl_translate(acl, target_flavor, (snode->vp->v_type == VDIR),
fs_sd->sd_uid, fs_sd->sd_gid);
if (error == 0) {
- smb_get_caller_context(sr, &ct);
if (sr->tid_tree->t_flags & SMB_TREE_FLAG_ACEMASKONACCESS)
flags = ATTR_NOACLCHECK;
- error = smb_vop_acl_write(snode->vp, acl, flags, cr, &ct);
+ error = smb_vop_acl_write(snode->vp, acl, flags, cr);
}
if (dacl && sacl)
@@ -2474,11 +2459,131 @@ smb_fsop_eaccess(smb_request_t *sr, cred_t *cr, smb_node_t *snode,
FILE_WRITE_EA | FILE_APPEND_DATA | FILE_DELETE_CHILD;
}
-/*ARGSUSED*/
+/*
+ * smb_fsop_shrlock
+ *
+ * For the current open request, check file sharing rules
+ * against existing opens.
+ *
+ * Returns NT_STATUS_SHARING_VIOLATION if there is any
+ * sharing conflict. Returns NT_STATUS_SUCCESS otherwise.
+ *
+ * Full system-wide share reservation synchronization is available
+ * when the nbmand (non-blocking mandatory) mount option is set
+ * (i.e. nbl_need_crit() is true) and nbmand critical regions are used.
+ * This provides synchronization with NFS and local processes. The
+ * critical regions are entered in VOP_SHRLOCK()/fs_shrlock() (called
+ * from smb_open_subr()/smb_fsop_shrlock()/smb_vop_shrlock()) as well
+ * as the CIFS rename and delete paths.
+ *
+ * The CIFS server will also enter the nbl critical region in the open,
+ * rename, and delete paths when nbmand is not set. There is limited
+ * coordination with local and VFS share reservations in this case.
+ * Note that when the nbmand mount option is not set, the VFS layer
+ * only processes advisory reservations and the delete mode is not checked.
+ *
+ * Whether or not the nbmand mount option is set, intra-CIFS share
+ * checking is done in the open, delete, and rename paths using a CIFS
+ * critical region (node->n_share_lock).
+ */
+
+uint32_t
+smb_fsop_shrlock(cred_t *cr, struct smb_node *node, uint32_t uniq_fid,
+ uint32_t desired_access, uint32_t share_access)
+{
+ int rc;
+
+ if (node->attr.sa_vattr.va_type == VDIR)
+ return (NT_STATUS_SUCCESS);
+
+ /* Allow access if the request is just for meta data */
+ if ((desired_access & FILE_DATA_ALL) == 0)
+ return (NT_STATUS_SUCCESS);
+
+ rc = smb_node_open_check(node, cr, desired_access, share_access);
+ if (rc)
+ return (NT_STATUS_SHARING_VIOLATION);
+
+ rc = smb_vop_shrlock(node->vp, uniq_fid, desired_access, share_access,
+ cr);
+ if (rc)
+ return (NT_STATUS_SHARING_VIOLATION);
+
+ return (NT_STATUS_SUCCESS);
+}
+
void
-smb_get_caller_context(smb_request_t *sr, caller_context_t *ct)
+smb_fsop_unshrlock(cred_t *cr, smb_node_t *node, uint32_t uniq_fid)
+{
+ if (node->attr.sa_vattr.va_type == VDIR)
+ return;
+
+ (void) smb_vop_unshrlock(node->vp, uniq_fid, cr);
+}
+
+/*
+ * smb_fsop_frlock_callback
+ *
+ * smb wrapper function for fs_frlock
+ * this should never happen, as we are not attempting
+ * to set Mandatory Locks, cmd = F_SETLK_NBMAND
+ *
+ */
+
+static callb_cpr_t *
+/* ARGSUSED */
+smb_fsop_frlock_callback(flk_cb_when_t when, void *error)
{
- ct->cc_caller_id = smb_caller_id;
- ct->cc_pid = 0; /* TBD */
- ct->cc_sysid = 0; /* TBD */
+ return (0);
+}
+
+/*
+ * smb_fs_frlock
+ *
+ * smb wrapper function for fs_frlock
+ */
+
+int
+smb_fsop_frlock(smb_request_t *sr, smb_node_t *node, smb_lock_t *lock,
+ boolean_t unlock)
+{
+ vnode_t *vp;
+ flock64_t bf;
+ cred_t *cr;
+ caller_context_t *ct;
+ int cmd;
+ flk_callback_t flk_cb;
+ offset_t offset = 0;
+ int flag;
+ int error;
+ int i;
+
+ flk_init_callback(&flk_cb, smb_fsop_frlock_callback, &error);
+ cr = sr->user_cr;
+ ct = &smb_ct;
+ vp = node->vp;
+ cmd = F_SETLK;
+
+ if (unlock == B_TRUE) {
+ bf.l_type = F_UNLCK;
+ flag = 0;
+ } else if (lock->l_type == SMB_LOCK_TYPE_READONLY) {
+ bf.l_type = F_RDLCK;
+ flag = FREAD;
+ } else if (lock->l_type == SMB_LOCK_TYPE_READWRITE) {
+ bf.l_type = F_WRLCK;
+ flag = FWRITE;
+ }
+
+ bf.l_start = lock->l_start;
+ bf.l_len = lock->l_length;
+ bf.l_whence = 0; /* SEEK_SET */
+ bf.l_pid = lock->l_pid;
+ bf.l_sysid = 0;
+
+ for (i = 0; i < 4; i++)
+ bf.l_pad[i] = 0;
+
+ error = fs_frlock(vp, cmd, &bf, flag, offset, &flk_cb, cr, ct);
+ return (error);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_lock_byte_range.c b/usr/src/uts/common/fs/smbsrv/smb_lock_byte_range.c
index cb5aa042ee..d9773cb50f 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_lock_byte_range.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_lock_byte_range.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -76,7 +76,7 @@ smb_com_lock_byte_range(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -90,7 +90,7 @@ smb_com_lock_byte_range(struct smb_request *sr)
result = smb_lock_range(sr, sr->fid_ofile,
(u_offset_t)off, (uint64_t)count, 0, SMB_LOCK_TYPE_READWRITE);
if (result != NT_STATUS_SUCCESS) {
- smb_lock_range_raise_error(sr, result);
+ smb_lock_range_error(sr, result);
/* NOT REACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_lock_svc.c b/usr/src/uts/common/fs/smbsrv/smb_lock_svc.c
index 7326d5a12c..b39188ebbd 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_lock_svc.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_lock_svc.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,6 +34,17 @@
*/
#include <smbsrv/smb_incl.h>
+#include <smbsrv/smb_fsops.h>
+#include <sys/nbmlock.h>
+#include <sys/param.h>
+
+static void
+smb_unlock_to_posix_unlock(smb_request_t *sr, smb_node_t *node,
+ smb_lock_t *lock, boolean_t unlock);
+
+static boolean_t
+smb_is_range_unlocked(uint64_t start, uint64_t end, smb_llist_t *llist_head,
+ uint64_t *new_mark);
static int
smb_lock_range_overlap(struct smb_lock *lock, uint64_t start, uint64_t length);
@@ -367,6 +378,9 @@ smb_unlock_range(
}
smb_llist_remove(&node->n_lock_list, lock);
+
+ smb_unlock_to_posix_unlock(sr, node, lock, B_TRUE);
+
smb_llist_exit(&node->n_lock_list);
smb_lock_destroy(lock);
@@ -481,7 +495,14 @@ smb_lock_range(
smb_lock_free(lock);
} else {
- smb_llist_insert_tail(&node->n_lock_list, lock);
+ /*
+ * don't insert into the CIFS lock list unless the
+ * posix lock worked
+ */
+ if (smb_fsop_frlock(sr, node, lock, B_FALSE))
+ result = NT_STATUS_FILE_LOCK_CONFLICT;
+ else
+ smb_llist_insert_tail(&node->n_lock_list, lock);
}
smb_llist_exit(&node->n_lock_list);
@@ -506,15 +527,12 @@ smb_lock_range_access(
struct smb_node *node,
uint64_t start,
uint64_t length,
- uint32_t desired_access)
+ boolean_t will_write)
{
smb_lock_t *lock;
smb_llist_t *llist;
int status = NT_STATUS_SUCCESS;
- ASSERT((desired_access & ~(FILE_READ_DATA | FILE_WRITE_DATA)) == 0);
- ASSERT((desired_access & (FILE_READ_DATA | FILE_WRITE_DATA)) != 0);
-
llist = &node->n_lock_list;
smb_llist_enter(llist, RW_READER);
/* Search for any applicable lock */
@@ -526,8 +544,7 @@ smb_lock_range_access(
/* Lock does not overlap */
continue;
- if (lock->l_type == SMB_LOCK_TYPE_READONLY &&
- desired_access == FILE_READ_DATA)
+ if (lock->l_type == SMB_LOCK_TYPE_READONLY && !will_write)
continue;
if (lock->l_type == SMB_LOCK_TYPE_READWRITE &&
@@ -664,46 +681,196 @@ smb_node_destroy_lock_by_ofile(smb_node_t *node, smb_ofile_t *file)
}
void
-smb_lock_range_raise_error(smb_request_t *sr, uint32_t ntstatus)
+smb_lock_range_error(smb_request_t *sr, uint32_t status32)
{
- switch (ntstatus) {
- case NT_STATUS_CANCELLED:
- /*
- * XXX What is the proper error here?
- */
- smbsr_raise_error(sr, ERRDOS, ERRlock);
- /* NOTREACHED */
- case NT_STATUS_FILE_LOCK_CONFLICT:
- smbsr_raise_cifs_error(sr, NT_STATUS_FILE_LOCK_CONFLICT,
- ERRDOS, ERRlock);
- /* NOTREACHED */
- case NT_STATUS_LOCK_NOT_GRANTED:
- smbsr_raise_cifs_error(sr, NT_STATUS_LOCK_NOT_GRANTED,
- ERRDOS, ERRlock);
- /* NOTREACHED */
- case NT_STATUS_RANGE_NOT_LOCKED:
- smbsr_raise_cifs_error(sr, NT_STATUS_RANGE_NOT_LOCKED,
- ERRDOS, ERRlock);
- /* NOTREACHED */
- default:
- ASSERT(0);
- smbsr_raise_error(sr, ERRDOS, ntstatus);
- /* NOTREACHED */
+ uint16_t errcode;
+
+ if (status32 == NT_STATUS_CANCELLED)
+ errcode = ERROR_OPERATION_ABORTED;
+ else
+ errcode = ERRlock;
+
+ smbsr_error(sr, status32, ERRDOS, errcode);
+ /* NOTREACHED */
+}
+
+/*
+ * smb_range_check()
+ *
+ * Perform range checking. First check for internal CIFS range conflicts
+ * and then check for external conflicts, for example, with NFS or local
+ * access.
+ *
+ * If nbmand is enabled, this function must be called from within an nbmand
+ * critical region
+ */
+
+DWORD
+smb_range_check(smb_request_t *sr, cred_t *cr, smb_node_t *node, uint64_t start,
+ uint64_t length, boolean_t will_write)
+{
+ smb_error_t smberr;
+ int svmand;
+ int nbl_op;
+ int rc;
+
+ ASSERT(node);
+ ASSERT(node->n_magic == SMB_NODE_MAGIC);
+ ASSERT(node->n_state == SMB_NODE_STATE_AVAILABLE);
+
+ ASSERT(smb_node_in_crit(node));
+
+ if (node->attr.sa_vattr.va_type == VDIR)
+ return (NT_STATUS_SUCCESS);
+
+ rc = smb_lock_range_access(sr, node, start, length, will_write);
+ if (rc)
+ return (NT_STATUS_UNSUCCESSFUL);
+
+ if ((rc = nbl_svmand(node->vp, cr, &svmand)) != 0) {
+ smbsr_map_errno(rc, &smberr);
+ return (smberr.status);
}
+
+ if (will_write)
+ nbl_op = NBL_WRITE;
+ else
+ nbl_op = NBL_READ;
+
+ if (nbl_lock_conflict(node->vp, nbl_op, start, length,
+ svmand, &smb_ct))
+ return (NT_STATUS_UNSUCCESSFUL);
+
+ return (NT_STATUS_SUCCESS);
}
+/*
+ * smb_unlock_to_posix_unlock
+ *
+ * checks if the current unlock request is in another lock
+ * and repeatedly calls smb_is_range_unlocked on a sliding basis to
+ * to unlock all bits of the lock that are not in other locks
+ *
+ */
void
-smb_unlock_range_raise_error(smb_request_t *sr, uint32_t ntstatus)
+smb_unlock_to_posix_unlock(smb_request_t *sr, smb_node_t *node,
+ smb_lock_t *lock, boolean_t unlock)
{
- switch (ntstatus) {
- case NT_STATUS_RANGE_NOT_LOCKED:
- smbsr_raise_cifs_error(sr, NT_STATUS_RANGE_NOT_LOCKED,
- ERRDOS, ERRnotlocked);
- /* NOTREACHED */
- default:
- ASSERT(0);
- smbsr_raise_error(sr, ERRDOS, ntstatus);
- /* NOTREACHED */
+ uint64_t new_mark;
+ uint64_t unlock_start;
+ uint64_t unlock_end;
+ boolean_t unlocked;
+ smb_lock_t new_unlock;
+ smb_llist_t *llist_head;
+ int cnt = 1;
+
+ new_mark = 0;
+ unlock_start = lock->l_start;
+ unlock_end = unlock_start + lock->l_length;
+ llist_head = &node->n_lock_list;
+
+ while (cnt) {
+ if ((unlocked = smb_is_range_unlocked(unlock_start, unlock_end,
+ llist_head, &new_mark)) == B_TRUE) {
+ if (new_mark) {
+ new_unlock = *lock;
+ new_unlock.l_start = unlock_start;
+ new_unlock.l_length = new_mark - unlock_start;
+ (void) smb_fsop_frlock(sr, node,
+ &new_unlock, unlock);
+ unlock_start = new_mark;
+ } else {
+ new_unlock = *lock;
+ new_unlock.l_start = unlock_start;
+ new_unlock.l_length = unlock_end - unlock_start;
+ (void) smb_fsop_frlock(sr, node,
+ &new_unlock, unlock);
+ break;
+ }
+ } else if ((unlocked == B_FALSE) && new_mark) {
+ unlock_start = new_mark;
+ } else {
+ break;
+ }
+ }
+}
+
+/*
+ * smb_is_range_unlocked
+ *
+ * Checks if the current unlock byte range request overlaps another lock
+ * The return code and the value of new_mark must be interpreted as
+ * follows:
+ *
+ * B_TRUE and (new_mark == 0):
+ * This is the last or only lock left to be unlocked
+ *
+ * B_TRUE and (new_mark > 0):
+ * The range from start to new_mark can be unlocked
+ *
+ * B_FALSE and (new_mark == 0):
+ * The unlock can't be performed and we are done
+ *
+ * B_FALSE and (new_mark > 0),
+ * The range from start to new_mark can't be unlocked
+ * Start should be reset to new_mark for the next pass
+ */
+
+static boolean_t
+smb_is_range_unlocked(uint64_t start, uint64_t end, smb_llist_t *llist_head,
+ uint64_t *new_mark)
+{
+ struct smb_lock *lk = 0;
+ uint64_t low_water_mark = MAXOFFSET_T;
+ uint64_t lk_start;
+ uint64_t lk_end;
+
+ *new_mark = 0;
+ lk = smb_llist_head(llist_head);
+ while (lk) {
+
+ lk_end = lk->l_start + lk->l_length - 1;
+ lk_start = lk->l_start;
+
+ /*
+ * there is no overlap for the first 2 cases
+ * check next node
+ */
+ if (lk_end < start) {
+ lk = smb_llist_next(llist_head, lk);
+ continue;
+ }
+ if (lk_start > end) {
+ lk = smb_llist_next(llist_head, lk);
+ continue;
+ }
+
+ /* this range is completely locked */
+ if ((lk_start <= start) && (lk_end >= end)) {
+ return (B_FALSE);
+ }
+
+ /* the first part of this range is locked */
+ if ((start >= lk_start) && (start <= lk_end)) {
+ if (end > lk_end)
+ *new_mark = lk_end + 1;
+ return (B_FALSE);
+ }
+
+ /* this piece is unlocked */
+ if ((lk_start >= start) && (lk_start <= end)) {
+ if (low_water_mark > lk_start)
+ low_water_mark = lk_start;
+ }
+
+ lk = smb_llist_next(llist_head, lk);
+ }
+
+ if (low_water_mark != MAXOFFSET_T) {
+ *new_mark = low_water_mark;
+ return (B_TRUE);
}
+ /* the range is completely unlocked */
+ return (B_TRUE);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_locking_andx.c b/usr/src/uts/common/fs/smbsrv/smb_locking_andx.c
index 0acf7922c4..4aa585091e 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_locking_andx.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_locking_andx.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -239,8 +239,7 @@ smb_com_locking_andx(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -275,7 +274,7 @@ smb_com_locking_andx(struct smb_request *sr)
* implement this)
*/
if (lock_type & LOCKING_ANDX_CHANGE_LOCK_TYPE) {
- smbsr_raise_error(sr, ERRDOS, ERRnoatomiclocks);
+ smbsr_error(sr, 0, ERRDOS, ERRnoatomiclocks);
/* NOT REACHED */
}
@@ -283,8 +282,7 @@ smb_com_locking_andx(struct smb_request *sr)
* No support for cancel lock (smbtorture expects this)
*/
if (lock_type & LOCKING_ANDX_CANCEL_LOCK) {
- smbsr_raise_cifs_error(sr,
- NT_STATUS_INVALID_PARAMETER,
+ smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
ERRDOS, ERROR_INVALID_PARAMETER);
/* NOT REACHED */
}
@@ -294,8 +292,7 @@ smb_com_locking_andx(struct smb_request *sr)
* negotiated protocol should be NT LM 0.12 or later
*/
if (sr->session->dialect < NT_LM_0_12) {
- smbsr_raise_cifs_error(sr,
- NT_STATUS_INVALID_PARAMETER,
+ smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
ERRDOS, ERROR_INVALID_PARAMETER);
/* NOT REACHED */
}
@@ -305,17 +302,18 @@ smb_com_locking_andx(struct smb_request *sr)
&sr->smb_pid, &offset64, &length64);
if (rc) {
/*
- * This is the error returned by a W2K system
- * even when NT Status is negotiated.
+ * This is the error returned by Windows 2000
+ * even when STATUS32 has been negotiated.
*/
- smbsr_raise_error(sr, ERRSRV, ERRerror);
+ smbsr_error(sr, 0, ERRSRV, ERRerror);
/* NOT REACHED */
}
result = smb_unlock_range(sr, sr->fid_ofile->f_node,
offset64, length64);
if (result != NT_STATUS_SUCCESS) {
- smb_unlock_range_raise_error(sr, result);
+ smbsr_error(sr, NT_STATUS_RANGE_NOT_LOCKED,
+ ERRDOS, ERRnotlocked);
/* NOT REACHED */
}
}
@@ -324,14 +322,14 @@ smb_com_locking_andx(struct smb_request *sr)
rc = smb_decode_mbc(&sr->smb_data, "w2.QQ",
&sr->smb_pid, &offset64, &length64);
if (rc) {
- smbsr_raise_error(sr, ERRSRV, ERRerror);
+ smbsr_error(sr, 0, ERRSRV, ERRerror);
/* NOT REACHED */
}
result = smb_lock_range(sr, sr->fid_ofile,
offset64, length64, timeout, ltype);
if (result != NT_STATUS_SUCCESS) {
- smb_lock_range_raise_error(sr, result);
+ smb_lock_range_error(sr, result);
/* NOT REACHED */
}
}
@@ -340,14 +338,15 @@ smb_com_locking_andx(struct smb_request *sr)
rc = smb_decode_mbc(&sr->smb_data, "wll", &sr->smb_pid,
&offset32, &length32);
if (rc) {
- smbsr_raise_error(sr, ERRSRV, ERRerror);
+ smbsr_error(sr, 0, ERRSRV, ERRerror);
/* NOT REACHED */
}
result = smb_unlock_range(sr, sr->fid_ofile->f_node,
(uint64_t)offset32, (uint64_t)length32);
if (result != NT_STATUS_SUCCESS) {
- smb_unlock_range_raise_error(sr, result);
+ smbsr_error(sr, NT_STATUS_RANGE_NOT_LOCKED,
+ ERRDOS, ERRnotlocked);
/* NOT REACHED */
}
}
@@ -356,7 +355,7 @@ smb_com_locking_andx(struct smb_request *sr)
rc = smb_decode_mbc(&sr->smb_data, "wll", &sr->smb_pid,
&offset32, &length32);
if (rc) {
- smbsr_raise_error(sr, ERRSRV, ERRerror);
+ smbsr_error(sr, 0, ERRSRV, ERRerror);
/* NOT REACHED */
}
@@ -365,7 +364,7 @@ smb_com_locking_andx(struct smb_request *sr)
(uint64_t)length32,
timeout, ltype);
if (result != NT_STATUS_SUCCESS) {
- smb_lock_range_raise_error(sr, result);
+ smb_lock_range_error(sr, result);
/* NOT REACHED */
}
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_logoff_andx.c b/usr/src/uts/common/fs/smbsrv/smb_logoff_andx.c
index 278916b8fd..4b56c61b73 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_logoff_andx.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_logoff_andx.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -66,8 +66,7 @@ int
smb_com_logoff_andx(struct smb_request *sr)
{
if (sr->uid_user == NULL) {
- cmn_err(CE_WARN, "SmbLogoffAndX: bad uid");
- smbsr_raise_error(sr, ERRSRV, ERRbaduid);
+ smbsr_error(sr, 0, ERRSRV, ERRbaduid);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_negotiate.c b/usr/src/uts/common/fs/smbsrv/smb_negotiate.c
index 844e84a889..a14ae7d3a5 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_negotiate.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_negotiate.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -261,7 +261,7 @@ smb_com_negotiate(struct smb_request *sr)
if (sr->session->s_state != SMB_SESSION_STATE_ESTABLISHED) {
/* The protocol has already been negotiated. */
- smbsr_raise_error(sr, ERRSRV, ERRerror);
+ smbsr_error(sr, 0, ERRSRV, ERRerror);
/* NOTREACHED */
}
@@ -269,7 +269,7 @@ smb_com_negotiate(struct smb_request *sr)
sr->smb_data.chain_offset < sr->smb_data.max_bytes;
pos++) {
if (smb_decode_mbc(&sr->smb_data, "%L", sr, &p) != 0) {
- smbsr_raise_error(sr, ERRSRV, ERRerror);
+ smbsr_error(sr, 0, ERRSRV, ERRerror);
/* NOTREACHED */
}
@@ -284,7 +284,7 @@ smb_com_negotiate(struct smb_request *sr)
}
}
if (sel_pos < 0) {
- smbsr_raise_error(sr, ERRSRV, ERRerror);
+ smbsr_error(sr, 0, ERRSRV, ERRerror);
/* NOTREACHED */
}
@@ -435,9 +435,7 @@ smb_com_negotiate(struct smb_request *sr)
break;
default:
- /* Just to make sure. */
- ASSERT(0);
- smbsr_raise_error(sr, ERRSRV, ERRerror);
+ smbsr_error(sr, 0, ERRSRV, ERRerror);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_node.c b/usr/src/uts/common/fs/smbsrv/smb_node.c
index 5ea8c5f1c3..13be0f3cf3 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_node.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_node.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -84,6 +84,7 @@
#include <smbsrv/smb_fsops.h>
#include <sys/pathname.h>
#include <sys/sdt.h>
+#include <sys/nbmlock.h>
uint32_t smb_is_executable(char *path);
static void smb_node_delete_on_close(smb_node_t *node);
@@ -138,7 +139,6 @@ smb_node_lookup(
fs_desc_t fsd;
int error;
krw_t lock_mode;
- caller_context_t ct;
vnode_t *unnamed_vp = NULL;
/*
@@ -154,9 +154,8 @@ smb_node_lookup(
* This getattr is performed on behalf of the server
* that's why kcred is used not the user's cred
*/
- smb_get_caller_context(sr, &ct);
attr->sa_mask = SMB_AT_ALL;
- error = smb_vop_getattr(vp, unnamed_vp, attr, 0, kcred, &ct);
+ error = smb_vop_getattr(vp, unnamed_vp, attr, 0, kcred);
if (error)
return (NULL);
@@ -208,6 +207,7 @@ smb_node_lookup(
smb_node_ref(dir_snode);
}
node->attr = *attr;
+ node->n_size = attr->sa_vattr.va_size;
smb_audit_node(node);
smb_rwx_xexit(&node->n_lock);
@@ -768,3 +768,252 @@ smb_node_reset_delete_on_close(smb_node_t *node)
}
smb_rwx_xexit(&node->n_lock);
}
+
+/*
+ * smb_node_share_check
+ *
+ * check file sharing rules for current open request
+ * against all existing opens for a file.
+ *
+ * Returns NT_STATUS_SHARING_VIOLATION if there is any
+ * sharing conflict, otherwise returns NT_STATUS_SUCCESS.
+ */
+uint32_t
+smb_node_open_check(struct smb_node *node, cred_t *cr,
+ uint32_t desired_access, uint32_t share_access)
+{
+ smb_ofile_t *of;
+ uint32_t status;
+
+ ASSERT(node);
+ ASSERT(node->n_magic == SMB_NODE_MAGIC);
+ ASSERT(node->n_state == SMB_NODE_STATE_AVAILABLE);
+
+ smb_llist_enter(&node->n_ofile_list, RW_READER);
+ of = smb_llist_head(&node->n_ofile_list);
+ while (of) {
+ status = smb_node_share_check(node, cr, desired_access,
+ share_access, of);
+ if (status == NT_STATUS_SHARING_VIOLATION) {
+ smb_llist_exit(&node->n_ofile_list);
+ return (status);
+ }
+ of = smb_llist_next(&node->n_ofile_list, of);
+ }
+ smb_llist_exit(&node->n_ofile_list);
+
+ return (NT_STATUS_SUCCESS);
+}
+
+/*
+ * smb_open_share_check
+ *
+ * check file sharing rules for current open request
+ * against the given existing open.
+ *
+ * Returns NT_STATUS_SHARING_VIOLATION if there is any
+ * sharing conflict, otherwise returns NT_STATUS_SUCCESS.
+ */
+uint32_t
+smb_node_share_check(
+ struct smb_node *node,
+ cred_t *cr,
+ uint32_t desired_access,
+ uint32_t share_access,
+ smb_ofile_t *of)
+{
+ /*
+ * It appears that share modes are not relevant to
+ * directories, but this check will remain as it is not
+ * clear whether it was originally put here for a reason.
+ */
+ if (node->attr.sa_vattr.va_type == VDIR) {
+ if (SMB_DENY_RW(of->f_share_access) &&
+ (node->n_orig_uid != crgetuid(cr))) {
+ return (NT_STATUS_SHARING_VIOLATION);
+ }
+
+ return (NT_STATUS_SUCCESS);
+ }
+
+ /* if it's just meta data */
+ if ((of->f_granted_access & FILE_DATA_ALL) == 0)
+ return (NT_STATUS_SUCCESS);
+
+ /*
+ * Check requested share access against the
+ * open granted (desired) access
+ */
+ if (SMB_DENY_DELETE(share_access) && (of->f_granted_access & DELETE))
+ return (NT_STATUS_SHARING_VIOLATION);
+
+ if (SMB_DENY_READ(share_access) &&
+ (of->f_granted_access & (FILE_READ_DATA | FILE_EXECUTE)))
+ return (NT_STATUS_SHARING_VIOLATION);
+
+ if (SMB_DENY_WRITE(share_access) &&
+ (of->f_granted_access & (FILE_WRITE_DATA | FILE_APPEND_DATA)))
+ return (NT_STATUS_SHARING_VIOLATION);
+
+ /* check requested desired access against the open share access */
+ if (SMB_DENY_DELETE(of->f_share_access) && (desired_access & DELETE))
+ return (NT_STATUS_SHARING_VIOLATION);
+
+ if (SMB_DENY_READ(of->f_share_access) &&
+ (desired_access & (FILE_READ_DATA | FILE_EXECUTE)))
+ return (NT_STATUS_SHARING_VIOLATION);
+
+ if (SMB_DENY_WRITE(of->f_share_access) &&
+ (desired_access & (FILE_WRITE_DATA | FILE_APPEND_DATA)))
+ return (NT_STATUS_SHARING_VIOLATION);
+
+ return (NT_STATUS_SUCCESS);
+}
+
+/*
+ * smb_rename_share_check
+ *
+ * An open file can be renamed if
+ *
+ * 1. isn't opened for data writing or deleting
+ *
+ * 2. Opened with "Deny Delete" share mode
+ * But not opened for data reading or executing
+ * (opened for accessing meta data)
+ */
+
+DWORD
+smb_node_rename_check(struct smb_node *node)
+{
+ struct smb_ofile *open;
+
+ ASSERT(node);
+ ASSERT(node->n_magic == SMB_NODE_MAGIC);
+ ASSERT(node->n_state == SMB_NODE_STATE_AVAILABLE);
+
+ /*
+ * Intra-CIFS check
+ */
+
+ smb_llist_enter(&node->n_ofile_list, RW_READER);
+ open = smb_llist_head(&node->n_ofile_list);
+ while (open) {
+ if (open->f_granted_access &
+ (FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE)) {
+ smb_llist_exit(&node->n_ofile_list);
+ return (NT_STATUS_SHARING_VIOLATION);
+ }
+
+ if ((open->f_share_access & FILE_SHARE_DELETE) == 0) {
+ if (open->f_granted_access &
+ (FILE_READ_DATA | FILE_EXECUTE)) {
+ smb_llist_exit(&node->n_ofile_list);
+ return (NT_STATUS_SHARING_VIOLATION);
+ }
+ }
+ open = smb_llist_next(&node->n_ofile_list, open);
+ }
+ smb_llist_exit(&node->n_ofile_list);
+
+ /*
+ * system-wide share check
+ */
+
+ if (nbl_share_conflict(node->vp, NBL_RENAME, NULL))
+ return (NT_STATUS_SHARING_VIOLATION);
+ else
+ return (NT_STATUS_SUCCESS);
+}
+
+/*
+ * smb_node_delete_check
+ *
+ * An open file can be deleted only if opened for
+ * accessing meta data. Share modes aren't important
+ * in this case.
+ *
+ * NOTE: there is another mechanism for deleting an
+ * open file that NT clients usually use.
+ * That's setting "Delete on close" flag for an open
+ * file. In this way the file will be deleted after
+ * last close. This flag can be set by SmbTrans2SetFileInfo
+ * with FILE_DISPOSITION_INFO information level.
+ * For setting this flag, the file should be opened by
+ * DELETE access in the FID that is passed in the Trans2
+ * request.
+ */
+DWORD
+smb_node_delete_check(smb_node_t *node)
+{
+ smb_ofile_t *file;
+
+ ASSERT(node);
+ ASSERT(node->n_magic == SMB_NODE_MAGIC);
+ ASSERT(node->n_state == SMB_NODE_STATE_AVAILABLE);
+
+ if (node->attr.sa_vattr.va_type == VDIR)
+ return (NT_STATUS_SUCCESS);
+
+ /*
+ * intra-CIFS check
+ */
+
+ smb_llist_enter(&node->n_ofile_list, RW_READER);
+ file = smb_llist_head(&node->n_ofile_list);
+ while (file) {
+ ASSERT(file->f_magic == SMB_OFILE_MAGIC);
+ if (file->f_granted_access &
+ (FILE_READ_DATA |
+ FILE_WRITE_DATA |
+ FILE_APPEND_DATA |
+ FILE_EXECUTE |
+ DELETE)) {
+ smb_llist_exit(&node->n_ofile_list);
+ return (NT_STATUS_SHARING_VIOLATION);
+ }
+ file = smb_llist_next(&node->n_ofile_list, file);
+ }
+ smb_llist_exit(&node->n_ofile_list);
+
+ /*
+ * system-wide share check
+ */
+
+ if (nbl_share_conflict(node->vp, NBL_REMOVE, NULL))
+ return (NT_STATUS_SHARING_VIOLATION);
+ else
+ return (NT_STATUS_SUCCESS);
+}
+
+/*
+ * smb_node_start_crit()
+ *
+ * Enter critical region for share reservations.
+ * See comments above smb_fsop_shrlock().
+ */
+
+void
+smb_node_start_crit(smb_node_t *node, krw_t mode)
+{
+ rw_enter(&node->n_share_lock, mode);
+ nbl_start_crit(node->vp, mode);
+}
+
+/*
+ * smb_node_end_crit()
+ *
+ * Exit critical region for share reservations.
+ */
+
+void
+smb_node_end_crit(smb_node_t *node)
+{
+ nbl_end_crit(node->vp);
+ rw_exit(&node->n_share_lock);
+}
+
+int
+smb_node_in_crit(smb_node_t *node)
+{
+ return (nbl_in_crit(node->vp) && RW_LOCK_HELD(&node->n_share_lock));
+}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_nt_create_andx.c b/usr/src/uts/common/fs/smbsrv/smb_nt_create_andx.c
index 36a3df5992..e7dbe26746 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_nt_create_andx.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_nt_create_andx.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -206,7 +206,7 @@ smb_com_nt_create_andx(struct smb_request *sr)
}
if (NameLength >= MAXPATHLEN) {
- smbsr_raise_nt_error(sr, NT_STATUS_OBJECT_PATH_NOT_FOUND);
+ smbsr_error(sr, NT_STATUS_OBJECT_PATH_NOT_FOUND, 0, 0);
/* NOTREACHED */
}
@@ -217,7 +217,7 @@ smb_com_nt_create_andx(struct smb_request *sr)
if ((op->create_options & FILE_DELETE_ON_CLOSE) &&
!(op->desired_access & DELETE)) {
- smbsr_raise_nt_error(sr, NT_STATUS_INVALID_PARAMETER);
+ smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0);
/* NOTREACHED */
}
@@ -253,7 +253,7 @@ smb_com_nt_create_andx(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree,
sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -284,11 +284,10 @@ smb_com_nt_create_andx(struct smb_request *sr)
if (status != NT_STATUS_SUCCESS) {
if (status == NT_STATUS_SHARING_VIOLATION)
- smbsr_raise_cifs_error(sr,
- NT_STATUS_SHARING_VIOLATION,
+ smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
ERRDOS, ERROR_SHARING_VIOLATION);
else
- smbsr_raise_nt_error(sr, status);
+ smbsr_error(sr, status, 0, 0);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c
index 00d648cc32..d844733b36 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -115,14 +115,14 @@ smb_nt_transact_create(struct smb_request *sr, struct smb_xa *xa)
if ((op->create_options & FILE_DELETE_ON_CLOSE) &&
!(op->desired_access & DELETE)) {
- smbsr_raise_nt_error(sr, NT_STATUS_INVALID_PARAMETER);
+ smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0);
/* NOTREACHED */
}
if (sd_len) {
status = smb_decode_sd(xa, &sd);
if (status != NT_STATUS_SUCCESS) {
- smbsr_raise_nt_error(sr, status);
+ smbsr_error(sr, status, 0, 0);
/* NOTREACHED */
}
op->sd = &sd;
@@ -177,11 +177,10 @@ smb_nt_transact_create(struct smb_request *sr, struct smb_xa *xa)
if (status != NT_STATUS_SUCCESS) {
if (status == NT_STATUS_SHARING_VIOLATION)
- smbsr_raise_cifs_error(sr,
- NT_STATUS_SHARING_VIOLATION,
+ smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
ERRDOS, ERROR_SHARING_VIOLATION);
else
- smbsr_raise_nt_error(sr, status);
+ smbsr_error(sr, status, 0, 0);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_ioctl.c b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_ioctl.c
index 5725814a0f..16fbdbede8 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_ioctl.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_ioctl.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -90,7 +90,7 @@ smb_nt_transact_ioctl(struct smb_request *sr, struct smb_xa *xa)
&fid,
&is_fsctl,
&is_flags) != 0) {
- smbsr_raise_nt_error(sr, NT_STATUS_INVALID_PARAMETER);
+ smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0);
}
for (i = 0;
@@ -103,7 +103,7 @@ smb_nt_transact_ioctl(struct smb_request *sr, struct smb_xa *xa)
}
if (status != NT_STATUS_SUCCESS)
- smbsr_raise_nt_error(sr, status);
+ smbsr_error(sr, status, 0, 0);
(void) smb_encode_mbc(&xa->rep_param_mb, "l", 0);
return (SDRC_NORMAL_REPLY);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_notify_change.c b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_notify_change.c
index d70ddf4fc0..264a078a48 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_notify_change.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_notify_change.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -135,8 +135,7 @@ smb_nt_transact_notify_change(struct smb_request *sr, struct smb_xa *xa)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -144,10 +143,9 @@ smb_nt_transact_notify_change(struct smb_request *sr, struct smb_xa *xa)
if (node->attr.sa_vattr.va_type != VDIR) {
/*
- * notify change requests are only valid for
- * directories
+ * Notify change requests are only valid on directories.
*/
- smbsr_raise_nt_error(sr, NT_STATUS_NOT_A_DIRECTORY);
+ smbsr_error(sr, NT_STATUS_NOT_A_DIRECTORY, 0, 0);
/* NOTREACHED */
}
@@ -192,7 +190,7 @@ smb_nt_transact_notify_change(struct smb_request *sr, struct smb_xa *xa)
case SMB_REQ_STATE_CANCELED:
mutex_exit(&sr->sr_mutex);
- smbsr_raise_nt_error(sr, NT_STATUS_CANCELLED);
+ smbsr_error(sr, NT_STATUS_CANCELLED, 0, 0);
/* NOTREACHED */
default:
ASSERT(0);
@@ -211,13 +209,13 @@ smb_nt_transact_notify_change(struct smb_request *sr, struct smb_xa *xa)
* is sent in reply.
*/
int
-smb_reply_notify_change_request(
- smb_request_t *sr)
+smb_reply_notify_change_request(smb_request_t *sr)
{
smb_node_t *node;
int total_bytes, n_setup, n_param, n_data;
int param_off, param_pad, data_off, data_pad;
struct smb_xa *xa;
+ smb_error_t err;
xa = sr->r_xa;
node = sr->sr_ncr.nc_node;
@@ -273,12 +271,12 @@ smb_reply_notify_change_request(
break;
case SMB_REQ_STATE_CANCELED:
- /*
- * an STATUS should be sent,
- * we need an implementation of nt_raise_error
- * but without long jump.
- */
- smbsr_setup_nt_status(sr, 0xc0000000, NT_STATUS_CANCELLED);
+ err.severity = ERROR_SEVERITY_ERROR;
+ err.status = NT_STATUS_CANCELLED;
+ err.errcls = ERRDOS;
+ err.errcode = ERROR_OPERATION_ABORTED;
+ smbsr_set_error(sr, &err);
+
(void) smb_encode_mbc(&sr->reply, "bwbw",
(short)0, 0L, (short)0, 0L);
sr->smb_wct = 0;
diff --git a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_security.c b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_security.c
index fec95a2835..69ea40bdb3 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_security.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_security.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -74,25 +74,24 @@ smb_nt_transact_query_security_info(struct smb_request *sr, struct smb_xa *xa)
uint32_t secinfo;
uint32_t sdlen;
uint32_t status;
-
+ smb_error_t err;
if (smb_decode_mbc(&xa->req_param_mb, "w2.l",
&sr->smb_fid, &secinfo) != 0) {
- smbsr_raise_nt_error(sr, NT_STATUS_INVALID_PARAMETER);
+ smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0);
/* NOTREACHED */
}
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
if ((sr->fid_ofile->f_node == NULL) ||
(sr->fid_ofile->f_ftype != SMB_FTYPE_DISK)) {
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -107,14 +106,14 @@ smb_nt_transact_query_security_info(struct smb_request *sr, struct smb_xa *xa)
status = smb_sd_read(sr, &sd, secinfo);
if (status != NT_STATUS_SUCCESS) {
- smbsr_raise_nt_error(sr, status);
+ smbsr_error(sr, status, 0, 0);
/* NOTREACHED */
}
sdlen = smb_sd_len(&sd, secinfo);
if (sdlen == 0) {
smb_sd_term(&sd);
- smbsr_raise_nt_error(sr, NT_STATUS_INVALID_SECURITY_DESCR);
+ smbsr_error(sr, NT_STATUS_INVALID_SECURITY_DESCR, 0, 0);
/* NOTREACHED */
}
@@ -126,8 +125,11 @@ smb_nt_transact_query_security_info(struct smb_request *sr, struct smb_xa *xa)
* should provide a buffer size hint for the client.
*/
(void) smb_encode_mbc(&xa->rep_param_mb, "l", sdlen);
- smbsr_setup_nt_status(sr, ERROR_SEVERITY_ERROR,
- NT_STATUS_BUFFER_TOO_SMALL);
+ err.severity = ERROR_SEVERITY_ERROR;
+ err.status = NT_STATUS_BUFFER_TOO_SMALL;
+ err.errcls = ERRDOS;
+ err.errcode = ERROR_INSUFFICIENT_BUFFER;
+ smbsr_set_error(sr, &err);
smb_sd_term(&sd);
return (SDRC_NORMAL_REPLY);
}
@@ -166,25 +168,24 @@ smb_nt_transact_set_security_info(struct smb_request *sr, struct smb_xa *xa)
if (smb_decode_mbc(&xa->req_param_mb, "w2.l",
&sr->smb_fid, &secinfo) != 0) {
- smbsr_raise_nt_error(sr, NT_STATUS_INVALID_PARAMETER);
+ smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0);
/* NOTREACHED */
}
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
if ((sr->fid_ofile->f_node == NULL) ||
(sr->fid_ofile->f_ftype != SMB_FTYPE_DISK)) {
- smbsr_raise_nt_error(sr, NT_STATUS_ACCESS_DENIED);
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED, 0, 0);
/* NOTREACHED */
}
if (sr->fid_ofile->f_node->flags & NODE_READ_ONLY) {
- smbsr_raise_nt_error(sr, NT_STATUS_MEDIA_WRITE_PROTECTED);
+ smbsr_error(sr, NT_STATUS_MEDIA_WRITE_PROTECTED, 0, 0);
/* NOTREACHED */
}
@@ -202,20 +203,20 @@ smb_nt_transact_set_security_info(struct smb_request *sr, struct smb_xa *xa)
status = smb_decode_sd(xa, &sd);
if (status != NT_STATUS_SUCCESS) {
- smbsr_raise_nt_error(sr, status);
+ smbsr_error(sr, status, 0, 0);
/* NOTREACHED */
}
if (((secinfo & SMB_OWNER_SECINFO) && (sd.sd_owner == NULL)) ||
((secinfo & SMB_GROUP_SECINFO) && (sd.sd_group == NULL))) {
- smbsr_raise_nt_error(sr, NT_STATUS_INVALID_PARAMETER);
+ smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0);
/* NOTREACHED */
}
status = smb_sd_write(sr, &sd, secinfo);
smb_sd_term(&sd);
if (status != NT_STATUS_SUCCESS) {
- smbsr_raise_nt_error(sr, status);
+ smbsr_error(sr, status, 0, 0);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_ofile.c b/usr/src/uts/common/fs/smbsrv/smb_ofile.c
index e8eb106291..fa9631336b 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_ofile.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_ofile.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -186,6 +186,7 @@ smb_ofile_open(
uint16_t ftype,
char *pipe_name,
uint32_t rpc_fid,
+ uint32_t uniqid,
smb_error_t *err)
{
smb_ofile_t *of;
@@ -203,6 +204,7 @@ smb_ofile_open(
of->f_magic = SMB_OFILE_MAGIC;
of->f_refcnt = 1;
of->f_fid = fid;
+ of->f_uniqid = uniqid;
of->f_opened_by_pid = pid;
of->f_granted_access = access_granted;
of->f_share_access = share_access;
@@ -271,7 +273,6 @@ smb_ofile_close(
{
int rc = 0;
-
ASSERT(of);
ASSERT(of->f_magic == SMB_OFILE_MAGIC);
@@ -286,9 +287,6 @@ smb_ofile_close(
if (of->f_ftype == SMB_FTYPE_MESG_PIPE) {
smb_rpc_close(of);
} else {
- if (of->f_node->vp->v_type == VREG)
- (void) smb_fsop_close(of);
-
if (of->f_node->flags & NODE_CREATED_READONLY) {
smb_node_set_dosattr(of->f_node,
of->f_node->attr.sa_dosattr |
@@ -300,12 +298,20 @@ smb_ofile_close(
rc = smb_sync_fsattr(NULL, of->f_cr, of->f_node);
smb_commit_delete_on_close(of);
smb_release_oplock(of, OPLOCK_RELEASE_FILE_CLOSED);
- smb_commit_delete_on_close(of);
+
+ /*
+ * Share reservations cannot be removed until the
+ * readonly bit has been set (if needed), above.
+ * See comments in smb_open_subr().
+ */
+ smb_fsop_unshrlock(of->f_cr, of->f_node, of->f_uniqid);
+
+ if (of->f_node->vp->v_type == VREG)
+ (void) smb_fsop_close(of);
+
/*
- * if there is any notify change request for
- * this file then see if any of them is related
- * to this open instance. If there is any then
- * cancel them.
+ * Cancel any notify change requests related
+ * to this open instance.
*/
if (of->f_node->flags & NODE_FLAGS_NOTIFY_CHANGE)
smb_process_file_notify_change_queue(of);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_open_andx.c b/usr/src/uts/common/fs/smbsrv/smb_open_andx.c
index b195ed6353..486422d9c5 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_open_andx.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_open_andx.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -245,7 +245,7 @@ smb_com_open(struct smb_request *sr)
if ((op->desired_access == ((uint32_t)SMB_INVALID_AMASK)) ||
(op->share_access == ((uint32_t)SMB_INVALID_SHAREMODE))) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_PARAMETER,
+ smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
ERRDOS, ERROR_INVALID_PARAMETER);
/* NOTREACHED */
}
@@ -266,11 +266,10 @@ smb_com_open(struct smb_request *sr)
if ((status = smb_open_subr(sr)) != NT_STATUS_SUCCESS) {
if (status == NT_STATUS_SHARING_VIOLATION)
- smbsr_raise_cifs_error(sr,
- NT_STATUS_SHARING_VIOLATION,
+ smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
ERRDOS, ERROR_SHARING_VIOLATION);
else
- smbsr_raise_nt_error(sr, status);
+ smbsr_error(sr, status, 0, 0);
/* NOTREACHED */
}
@@ -281,7 +280,7 @@ smb_com_open(struct smb_request *sr)
}
if (op->dsize > UINT_MAX)
- smbsr_raise_error(sr, ERRDOS, ERRbadfunc);
+ smbsr_error(sr, 0, ERRDOS, ERRbadfunc);
file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
@@ -330,7 +329,7 @@ smb_com_open_andx(struct smb_request *sr)
if ((op->desired_access == ((uint32_t)SMB_INVALID_AMASK)) ||
(op->share_access == ((uint32_t)SMB_INVALID_SHAREMODE))) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_PARAMETER,
+ smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
ERRDOS, ERROR_INVALID_PARAMETER);
/* NOTREACHED */
}
@@ -338,7 +337,7 @@ smb_com_open_andx(struct smb_request *sr)
op->dattr = file_attr;
op->create_disposition = smb_ofun_to_crdisposition(ofun);
if (op->create_disposition == ((uint32_t)SMB_INVALID_CRDISPOSITION)) {
- smbsr_raise_error(sr, ERRDOS, ERROR_INVALID_PARAMETER);
+ smbsr_error(sr, 0, ERRDOS, ERROR_INVALID_PARAMETER);
/* NOTREACHED */
}
@@ -376,17 +375,16 @@ smb_com_open_andx(struct smb_request *sr)
if (status != NT_STATUS_SUCCESS) {
if (status == NT_STATUS_SHARING_VIOLATION)
- smbsr_raise_cifs_error(sr,
- NT_STATUS_SHARING_VIOLATION,
+ smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
ERRDOS, ERROR_SHARING_VIOLATION);
else
- smbsr_raise_nt_error(sr, status);
+ smbsr_error(sr, status, 0, 0);
/* NOTREACHED */
}
if (op->dsize > UINT_MAX)
- smbsr_raise_error(sr, ERRDOS, ERRbadfunc);
+ smbsr_error(sr, 0, ERRDOS, ERRbadfunc);
if (MYF_OPLOCK_TYPE(op->my_flags) != MYF_OPLOCK_NONE) {
op->action_taken |= SMB_OACT_LOCK;
diff --git a/usr/src/uts/common/fs/smbsrv/smb_path_name_reduction.c b/usr/src/uts/common/fs/smbsrv/smb_path_name_reduction.c
index cc203a7315..c31c764bf4 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_path_name_reduction.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_path_name_reduction.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -59,10 +59,6 @@ smb_is_executable(char *path)
/*
* smbd_fs_query
*
- * This function has been changed to return errors instead of using
- * smbsr_raise_errno to longjmp round the calling code. This allows
- * the caller to release resources when an error occurs.
- *
* Upon success, the caller will need to call smb_node_release() on
* fqi.last_snode (if it isn't already set to NULL by this routine) and
* and fqi.dir_snode. These pointers will not be used after the caller
diff --git a/usr/src/uts/common/fs/smbsrv/smb_query_information.c b/usr/src/uts/common/fs/smbsrv/smb_query_information.c
index 8cb636aaa9..391c3f9c24 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_query_information.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_query_information.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -95,7 +95,7 @@ smb_com_query_information(struct smb_request *sr)
sr->tid_tree->t_snode, sr->tid_tree->t_snode, &dir_node, name))
!= 0) {
kmem_free(name, MAXNAMELEN);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -103,7 +103,7 @@ smb_com_query_information(struct smb_request *sr)
sr->tid_tree->t_snode, dir_node, name, &node, &attr, 0, 0)) != 0) {
smb_node_release(dir_node);
kmem_free(name, MAXNAMELEN);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_query_information2.c b/usr/src/uts/common/fs/smbsrv/smb_query_information2.c
index a1324aa74e..d6fa3d1f26 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_query_information2.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_query_information2.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -76,15 +76,13 @@ smb_com_query_information2(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
if (sr->fid_ofile->f_ftype != SMB_FTYPE_DISK) {
- cmn_err(CE_NOTE, "SmbQueryInfo2: access denied");
- smbsr_raise_error(sr, ERRDOS, ERRnoaccess);
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_query_information_disk.c b/usr/src/uts/common/fs/smbsrv/smb_query_information_disk.c
index 4c69d8516e..6e38758502 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_query_information_disk.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_query_information_disk.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -79,7 +79,7 @@ smb_com_query_information_disk(struct smb_request *sr)
if ((rc = smb_fsop_statfs(sr->user_cr, sr->tid_tree->t_snode, &df))
!= 0)
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
unit_size = 1;
block_size = df.f_frsize;
diff --git a/usr/src/uts/common/fs/smbsrv/smb_read.c b/usr/src/uts/common/fs/smbsrv/smb_read.c
index 8542a1a1f9..4e5ba4ec88 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_read.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_read.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -75,13 +75,12 @@ smb_com_read(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
if ((rc = smb_common_read(sr, &param)) != 0) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -123,7 +122,7 @@ smb_com_lock_and_read(struct smb_request *sr)
int rc;
if (STYPE_ISDSK(sr->tid_tree->t_res_type) == 0) {
- smbsr_raise_error(sr, ERRDOS, ERRnoaccess);
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
/* NOTREACHED */
}
@@ -139,19 +138,18 @@ smb_com_lock_and_read(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
result = smb_lock_range(sr, sr->fid_ofile, param.r_offset,
(uint64_t)param.r_count, UINT_MAX, SMB_LOCK_TYPE_READWRITE);
if (result != NT_STATUS_SUCCESS) {
- smb_lock_range_raise_error(sr, result);
+ smb_lock_range_error(sr, result);
}
if ((rc = smb_common_read(sr, &param)) != 0) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -214,7 +212,7 @@ smb_com_read_raw(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree,
sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -301,13 +299,12 @@ smb_com_read_andx(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
if ((rc = smb_common_read(sr, &param)) != 0) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -379,7 +376,7 @@ smb_common_read(struct smb_request *sr, smb_read_param_t *param)
if (node->attr.sa_vattr.va_type != VDIR) {
rc = smb_lock_range_access(sr, node, param->r_offset,
- param->r_count, FILE_READ_DATA);
+ param->r_count, B_FALSE);
if (rc != NT_STATUS_SUCCESS) {
rc = ERANGE;
break;
diff --git a/usr/src/uts/common/fs/smbsrv/smb_rename.c b/usr/src/uts/common/fs/smbsrv/smb_rename.c
index f22e7187de..0239635663 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_rename.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_rename.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -29,12 +29,12 @@
#include <sys/synch.h>
#include <smbsrv/smb_incl.h>
#include <smbsrv/smb_fsops.h>
+#include <sys/nbmlock.h>
static int smb_do_rename(struct smb_request *sr,
struct smb_fqi *src_fqi,
struct smb_fqi *dst_fqi);
-
/*
* smb_com_rename
*
@@ -63,7 +63,7 @@ smb_com_rename(struct smb_request *sr)
int rc;
if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -99,19 +99,18 @@ smb_com_rename(struct smb_request *sr)
* NT and W2K client behaviour.
*/
if (rc == EEXIST) {
- smbsr_raise_cifs_error(sr,
- NT_STATUS_OBJECT_NAME_COLLISION,
+ smbsr_error(sr, NT_STATUS_OBJECT_NAME_COLLISION,
ERRDOS, ERROR_ALREADY_EXISTS);
/* NOTREACHED */
}
if (rc == EPIPE) {
- smbsr_raise_cifs_error(sr, NT_STATUS_SHARING_VIOLATION,
+ smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
ERRDOS, ERROR_SHARING_VIOLATION);
/* NOTREACHED */
}
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -136,48 +135,6 @@ smb_com_rename(struct smb_request *sr)
}
/*
- * smb_rename_share_check
- *
- * An open file can be renamed if
- *
- * 1. isn't opened for data writing or deleting
- *
- * 2. Opened with "Deny Delete" share mode
- * But not opened for data reading or executing
- * (opened for accessing meta data)
- */
-DWORD
-smb_rename_share_check(struct smb_node *node)
-{
- struct smb_ofile *open;
-
- if (node == 0 || node->n_refcnt <= 1)
- return (NT_STATUS_SUCCESS);
-
- smb_llist_enter(&node->n_ofile_list, RW_READER);
- open = smb_llist_head(&node->n_ofile_list);
- while (open) {
- if (open->f_granted_access &
- (FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE)) {
- smb_llist_exit(&node->n_ofile_list);
- return (NT_STATUS_SHARING_VIOLATION);
- }
-
- if ((open->f_share_access & FILE_SHARE_DELETE) == 0) {
- if (open->f_granted_access &
- (FILE_READ_DATA | FILE_EXECUTE)) {
- smb_llist_exit(&node->n_ofile_list);
- return (NT_STATUS_SHARING_VIOLATION);
- }
- }
- open = smb_llist_next(&node->n_ofile_list, open);
- }
- smb_llist_exit(&node->n_ofile_list);
- return (NT_STATUS_SUCCESS);
-}
-
-
-/*
* smb_do_rename
*
* Backend to smb_com_rename to ensure that the rename operation is atomic.
@@ -228,28 +185,24 @@ smb_do_rename(
}
}
- status = smb_lock_range_access(sr, src_node, 0, 0, FILE_WRITE_DATA);
- if (status != NT_STATUS_SUCCESS) {
- smb_node_release(src_node);
- smb_node_release(src_fqi->dir_snode);
+ for (count = 0; count <= 3; count++) {
+ if (count) {
+ smb_node_end_crit(src_node);
+ delay(MSEC_TO_TICK(400));
+ }
- SMB_NULL_FQI_NODES(*src_fqi);
- SMB_NULL_FQI_NODES(*dst_fqi);
- return (EACCES);
- }
+ smb_node_start_crit(src_node, RW_READER);
+ status = smb_node_rename_check(src_node);
- for (count = 0; count <= 3; count++) {
- if (count)
- delay(MSEC_TO_TICK(400));
- status = smb_rename_share_check(src_node);
if (status != NT_STATUS_SHARING_VIOLATION)
break;
}
- smb_node_release(src_node);
-
if (status == NT_STATUS_SHARING_VIOLATION) {
+ smb_node_end_crit(src_node);
+
+ smb_node_release(src_node);
smb_node_release(src_fqi->dir_snode);
SMB_NULL_FQI_NODES(*src_fqi);
@@ -257,8 +210,25 @@ smb_do_rename(
return (EPIPE); /* = ERRbadshare */
}
+ status = smb_range_check(sr, sr->user_cr, src_node, 0, UINT64_MAX,
+ B_TRUE);
+
+ if (status != NT_STATUS_SUCCESS) {
+ smb_node_end_crit(src_node);
+
+ smb_node_release(src_node);
+ smb_node_release(src_fqi->dir_snode);
+
+ SMB_NULL_FQI_NODES(*src_fqi);
+ SMB_NULL_FQI_NODES(*dst_fqi);
+ return (EACCES);
+ }
+
if (utf8_strcasecmp(src_fqi->path, dst_fqi->path) == 0) {
if ((rc = smbd_fs_query(sr, dst_fqi, 0)) != 0) {
+ smb_node_end_crit(src_node);
+
+ smb_node_release(src_node);
smb_node_release(src_fqi->dir_snode);
SMB_NULL_FQI_NODES(*src_fqi);
@@ -276,6 +246,9 @@ smb_do_rename(
rc = strcmp(src_fqi->last_comp_od, dst_fqi->last_comp);
if (rc == 0) {
+ smb_node_end_crit(src_node);
+
+ smb_node_release(src_node);
smb_node_release(src_fqi->dir_snode);
smb_node_release(dst_fqi->dir_snode);
@@ -297,11 +270,18 @@ smb_do_rename(
SMB_NULL_FQI_NODES(*src_fqi);
SMB_NULL_FQI_NODES(*dst_fqi);
}
+
+ smb_node_end_crit(src_node);
+
+ smb_node_release(src_node);
return (rc);
}
rc = smbd_fs_query(sr, dst_fqi, FQM_PATH_MUST_NOT_EXIST);
if (rc != 0) {
+ smb_node_end_crit(src_node);
+
+ smb_node_release(src_node);
smb_node_release(src_fqi->dir_snode);
SMB_NULL_FQI_NODES(*src_fqi);
@@ -343,5 +323,9 @@ smb_do_rename(
SMB_NULL_FQI_NODES(*dst_fqi);
}
+ smb_node_end_crit(src_node);
+
+ smb_node_release(src_node);
+
return (rc);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_rpc.c b/usr/src/uts/common/fs/smbsrv/smb_rpc.c
index 5059c909b4..a270f442b1 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_rpc.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_rpc.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -205,7 +205,8 @@ smb_rpc_initialize(struct smb_request *sr, char *pipe_name)
op = &sr->arg.open;
of = smb_ofile_open(sr->tid_tree, NULL, sr->smb_pid,
op->desired_access, 0, op->share_access,
- SMB_FTYPE_MESG_PIPE, pipe_name, smb_rpc_fid(), &err);
+ SMB_FTYPE_MESG_PIPE, pipe_name, smb_rpc_fid(),
+ SMB_UNIQ_FID(), &err);
if (of == NULL)
return (err.status);
@@ -267,7 +268,7 @@ smb_rpc_transact(struct smb_request *sr, struct uio *uio)
if (pipe_info->fid == 0) {
smb_rpc_exit(pipe_info);
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERROR_INVALID_HANDLE);
/* NOTREACHED */
}
@@ -286,8 +287,8 @@ smb_rpc_transact(struct smb_request *sr, struct uio *uio)
if (rc != 0) {
smb_rpc_exit(pipe_info);
- smbsr_raise_nt_error(sr,
- NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID);
+ smbsr_error(sr, NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID,
+ 0, 0);
/* NOTREACHED */
}
@@ -310,13 +311,8 @@ smb_rpc_transact(struct smb_request *sr, struct uio *uio)
xa->rep_data_mb.max_bytes = mdrcnt;
MBC_ATTACH_MBUF(&xa->rep_data_mb, mhead);
- if (sr->session->capabilities & CAP_STATUS32)
- smbsr_setup_nt_status(sr, ERROR_SEVERITY_WARNING,
- NT_STATUS_BUFFER_OVERFLOW);
- else {
- sr->smb_rcls = ERRDOS;
- sr->smb_err = ERRmoredata;
- }
+ smbsr_warn(sr, NT_STATUS_BUFFER_OVERFLOW,
+ ERRDOS, ERROR_MORE_DATA);
} else {
/*
* The client has provided enough buffer space, all
diff --git a/usr/src/uts/common/fs/smbsrv/smb_sd.c b/usr/src/uts/common/fs/smbsrv/smb_sd.c
index fa2bf223d7..c26b70169a 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_sd.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_sd.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -145,7 +145,7 @@ smb_sd_read(smb_request_t *sr, smb_sd_t *sd, uint32_t secinfo)
error = smb_fsop_sdread(sr, sr->user_cr, node, &fs_sd);
if (error) {
- smb_errmap_unix2smb(error, &smb_err);
+ smbsr_map_errno(error, &smb_err);
return (smb_err.status);
}
@@ -186,7 +186,7 @@ smb_sd_write(smb_request_t *sr, smb_sd_t *sd, uint32_t secinfo)
smb_fssd_term(&fs_sd);
if (error) {
- smb_errmap_unix2smb(error, &smb_err);
+ smbsr_map_errno(error, &smb_err);
return (smb_err.status);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_search.c b/usr/src/uts/common/fs/smbsrv/smb_search.c
index 0700b8fd2d..d0411e1e58 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_search.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_search.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -162,7 +162,7 @@ smb_com_search(struct smb_request *sr)
}
if ((rc = fsd_getattr(&sr->tid_tree->t_fsd, &vol_attr)) != 0) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -212,8 +212,7 @@ smb_com_search(struct smb_request *sr)
sr->sid_odir = smb_odir_lookup_by_sid(sr->tid_tree,
sr->smb_sid);
if (sr->sid_odir == NULL) {
- smbsr_raise_cifs_error(sr,
- NT_STATUS_INVALID_HANDLE,
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -270,13 +269,13 @@ smb_com_search(struct smb_request *sr)
if ((rc != 0) && (rc != ENOENT)) {
/* returned error by smb_rdir_next() */
smb_rdir_close(sr);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
if (count == 0) {
smb_rdir_close(sr);
- smbsr_raise_error(sr, ERRDOS, ERRnofiles);
+ smbsr_error(sr, 0, ERRDOS, ERRnofiles);
/* NOTREACHED */
}
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_seek.c b/usr/src/uts/common/fs/smbsrv/smb_seek.c
index a120a26a9d..cffb9ce2d0 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_seek.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_seek.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -94,8 +94,7 @@ smb_com_seek(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -103,27 +102,16 @@ smb_com_seek(struct smb_request *sr)
(void) smb_set_file_size(sr);
}
- rc = smb_ofile_seek(sr->fid_ofile, mode, off, &off_ret);
- if (rc == 0) {
- smbsr_encode_result(sr, 2, 0, "blw", 2, off_ret, 0);
- return (SDRC_NORMAL_REPLY);
+ if ((rc = smb_ofile_seek(sr->fid_ofile, mode, off, &off_ret)) != 0) {
+ if (rc == EINVAL) {
+ smbsr_error(sr, 0, ERRDOS, ERRbadfunc);
+ /* NOTREACHED */
+ } else {
+ smbsr_error(sr, 0, ERRSRV, ERRerror);
+ /* NOTREACHED */
+ }
}
- if (rc == EINVAL) {
- smbsr_raise_error(sr, ERRDOS, ERRbadfunc);
- /* NOTREACHED */
- }
- if (rc == EOVERFLOW) {
- smbsr_raise_error(sr, ERRSRV, ERRerror);
- /* NOTREACHED */
- }
- ASSERT(0);
- smbsr_raise_error(sr, ERRSRV, ERRerror);
- /* NOTREACHED */
- /*
- * Although smbsr_raise_error() doesn't return and the compiler is
- * told so in smb_kproto.h it still has a problem if it doesn't
- * find here a return instruction with a value.
- */
- return (0);
+ smbsr_encode_result(sr, 2, 0, "blw", 2, off_ret, 0);
+ return (SDRC_NORMAL_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_session_setup_andx.c b/usr/src/uts/common/fs/smbsrv/smb_session_setup_andx.c
index b7217cf78b..887a0ca648 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_session_setup_andx.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_session_setup_andx.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -370,7 +370,7 @@ smb_com_session_setup_andx(struct smb_request *sr)
kmem_free(ci_password, ci_pwlen + 1);
if (cs_password)
kmem_free(cs_password, cs_pwlen + 1);
- smbsr_raise_error(sr, ERRSRV, ERRaccess);
+ smbsr_error(sr, 0, ERRSRV, ERRaccess);
/* NOTREACHED */
} else if (utf8_strcasecmp(primary_domain, hostname) == 0) {
/*
@@ -385,8 +385,6 @@ smb_com_session_setup_andx(struct smb_request *sr)
clnt_info.flags |= NETR_CFLG_LOCAL;
}
- (void) utf8_strupr(primary_domain);
-
/*
* If this is an additional setup for an existing user
* on this session, duplicate the authenticated user.
@@ -431,7 +429,7 @@ smb_com_session_setup_andx(struct smb_request *sr)
kmem_free(ci_password, ci_pwlen + 1);
if (cs_password)
kmem_free(cs_password, cs_pwlen + 1);
- smbsr_raise_error(sr, ERRSRV, ERRbadpw);
+ smbsr_error(sr, 0, ERRSRV, ERRbadpw);
/* NOTREACHED */
}
@@ -463,7 +461,7 @@ smb_com_session_setup_andx(struct smb_request *sr)
if (user == NULL) {
if (session_key)
kmem_free(session_key, sizeof (smb_session_key_t));
- smbsr_raise_error(sr, ERRDOS, ERROR_INVALID_HANDLE);
+ smbsr_error(sr, 0, ERRDOS, ERROR_INVALID_HANDLE);
/* no return */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_set_information.c b/usr/src/uts/common/fs/smbsrv/smb_set_information.c
index 728c86b8cd..e7b1237fa9 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_set_information.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_set_information.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -88,7 +88,7 @@ smb_com_set_information(struct smb_request *sr)
sr->tid_tree->t_snode, sr->tid_tree->t_snode, &dir_node, name))
!= 0) {
kmem_free(name, MAXNAMELEN);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -96,7 +96,7 @@ smb_com_set_information(struct smb_request *sr)
sr->tid_tree->t_snode, dir_node, name, &node, &attr, 0, 0)) != 0) {
smb_node_release(dir_node);
kmem_free(name, MAXNAMELEN);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -118,7 +118,7 @@ smb_com_set_information(struct smb_request *sr)
smb_node_release(node);
if (rc) {
kmem_free(name, MAXNAMELEN);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_set_information2.c b/usr/src/uts/common/fs/smbsrv/smb_set_information2.c
index 1510f7228a..8f00ff66d1 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_set_information2.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_set_information2.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -77,16 +77,14 @@ smb_com_set_information2(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
node = sr->fid_ofile->f_node;
if (node == 0 || sr->fid_ofile->f_ftype != SMB_FTYPE_DISK) {
- cmn_err(CE_NOTE, "SmbSetInfo2: access denied");
- smbsr_raise_error(sr, ERRDOS, ERRnoaccess);
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
/* NOTREACHED */
}
@@ -113,7 +111,7 @@ smb_com_set_information2(struct smb_request *sr)
smb_node_set_time(node, &crtime, &mtime, &atime, 0, what);
rc = smb_sync_fsattr(sr, sr->user_cr, node);
if (rc) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_create_directory.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_create_directory.c
index 6ef6691df3..dc85916d04 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_create_directory.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_create_directory.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -67,8 +67,8 @@ extern int smb_common_create_directory(struct smb_request *sr);
int
smb_com_trans2_create_directory(struct smb_request *sr, struct smb_xa *xa)
{
- int rc;
- DWORD status;
+ int rc;
+ DWORD status;
if (smb_decode_mbc(&xa->req_param_mb, "%4.s",
sr, &sr->arg.dirop.fqi.path) != 0) {
@@ -77,16 +77,12 @@ smb_com_trans2_create_directory(struct smb_request *sr, struct smb_xa *xa)
}
if ((status = smb_validate_dirname(sr->arg.dirop.fqi.path)) != 0) {
- if (sr->session->capabilities & CAP_STATUS32)
- smbsr_raise_nt_error(sr, status);
- else
- smbsr_raise_error(sr, ERRDOS, ERROR_INVALID_NAME);
-
+ smbsr_error(sr, status, ERRDOS, ERROR_INVALID_NAME);
/* NOTREACHED */
}
if ((rc = smb_common_create_directory(sr)) != 0) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_find.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_find.c
index c92a248a93..57b3ba257c 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_find.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_find.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -176,36 +176,50 @@
#include <smbsrv/smbtrans.h>
#include <smbsrv/smb_fsops.h>
-int smb_trans2_find_get_maxdata(struct smb_request *, unsigned short,
- unsigned short);
+static int smb_trans2_find_get_maxdata(smb_request_t *, uint16_t, uint16_t);
-int smb_trans2_find_get_dents(struct smb_request *, struct smb_xa *,
- unsigned short, unsigned short, int, struct smb_node *,
- unsigned short, uint32_t, int, char *, uint32_t *, int *, int *);
+int smb_trans2_find_get_dents(smb_request_t *, smb_xa_t *,
+ uint16_t, uint16_t, int, smb_node_t *,
+ uint16_t, uint16_t, int, char *, uint32_t *, int *, int *);
int smb_gather_dents_info(char *, ino_t, int, char *, uint32_t, int32_t *,
- smb_attr_t *, struct smb_node *, char *, char *);
+ smb_attr_t *, smb_node_t *, char *, char *);
-int smb_trans2_find_process_ients(struct smb_request *, struct smb_xa *,
- smb_dent_info_hdr_t *, unsigned short, unsigned short, int,
- struct smb_node *, int *, uint32_t *);
+int smb_trans2_find_process_ients(smb_request_t *, smb_xa_t *,
+ smb_dent_info_hdr_t *, uint16_t, uint16_t, int,
+ smb_node_t *, int *, uint32_t *);
-int smb_trans2_find_mbc_encode(struct smb_request *, struct smb_xa *,
- smb_dent_info_t *, int, unsigned short, unsigned short,
- unsigned int, struct smb_node *, struct smb_node *);
+int smb_trans2_find_mbc_encode(smb_request_t *, smb_xa_t *,
+ smb_dent_info_t *, int, uint16_t, uint16_t,
+ uint32_t, smb_node_t *, smb_node_t *);
/*
- * Support for Catia Version 5 Deployment
+ * The UNIX characters below are considered illegal in Windows file names.
+ * The following character conversions are used to support sites in which
+ * Catia v4 is in use on UNIX and Catia v5 is in use on Windows.
+ *
+ * ---------------------------
+ * Unix-char | Windows-char
+ * ---------------------------
+ * " | (0x00a8) Diaeresis
+ * * | (0x00a4) Currency Sign
+ * : | (0x00f7) Division Sign
+ * < | (0x00ab) Left-Pointing Double Angle Quotation Mark
+ * > | (0x00bb) Right-Pointing Double Angle Quotation Mark
+ * ? | (0x00bf) Inverted Question mark
+ * \ | (0x00ff) Latin Small Letter Y with Diaeresis
+ * | | (0x00a6) Broken Bar
*/
-static int (*catia_callback)(unsigned char *, unsigned char *, int) = NULL;
+static int (*catia_callback)(uint8_t *, uint8_t *, int) = NULL;
void smb_register_catia_callback(
- int (*catia_v4tov5)(unsigned char *, unsigned char *, int));
+ int (*catia_v4tov5)(uint8_t *, uint8_t *, int));
void smb_unregister_catia_callback();
/*
- * Patchable parameter for find maximum count
+ * Tunable parameter to limit the maximum
+ * number of entries to be returned.
*/
-int max_find_count = 64;
+uint16_t smb_trans2_find_max = 128;
/*
* smb_register_catia_callback
@@ -216,7 +230,7 @@ int max_find_count = 64;
*/
void
smb_register_catia_callback(
- int (*catia_v4tov5)(unsigned char *, unsigned char *, int))
+ int (*catia_v4tov5)(uint8_t *, uint8_t *, int))
{
catia_callback = catia_v4tov5;
}
@@ -277,20 +291,21 @@ smb_unregister_catia_callback()
* found in the search
*/
int
-smb_com_trans2_find_first2(struct smb_request *sr, struct smb_xa *xa)
+smb_com_trans2_find_first2(smb_request_t *sr, smb_xa_t *xa)
{
int more = 0, rc;
- unsigned short sattr, fflag, infolev;
+ uint16_t sattr, fflag, infolev;
+ uint16_t maxcount = 0;
int maxdata;
- int count, maxcount = 0, wildcards;
+ int count, wildcards;
uint32_t cookie;
char *path;
- struct smb_node *dir_snode;
+ smb_node_t *dir_snode;
char *pattern;
- unsigned short sid;
+ uint16_t sid;
if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -302,27 +317,36 @@ smb_com_trans2_find_first2(struct smb_request *sr, struct smb_xa *xa)
}
maxdata = smb_trans2_find_get_maxdata(sr, infolev, fflag);
-
if (maxdata == 0) {
- smbsr_raise_error(sr, ERRDOS, ERRunknownlevel);
+ smbsr_error(sr, NT_STATUS_INVALID_LEVEL,
+ ERRDOS, ERROR_INVALID_LEVEL);
/* NOTREACHED */
}
- /* Convert name to our form */
- if (sr->smb_flg2 & SMB_FLAGS2_UNICODE) {
+ /*
+ * When maxcount is zero Windows behaves as if it was 1.
+ */
+ if (maxcount == 0)
+ maxcount = 1;
+
+ if ((smb_trans2_find_max != 0) && (maxcount > smb_trans2_find_max))
+ maxcount = smb_trans2_find_max;
+
+ if (sr->smb_flg2 & SMB_FLAGS2_UNICODE)
(void) smb_convert_unicode_wildcards(path);
- }
+
(void) smb_rdir_open(sr, path, sattr);
/*
* Get a copy of information
*/
- pattern = kmem_alloc(MAXNAMELEN, KM_SLEEP);
dir_snode = sr->sid_odir->d_dir_snode;
+ pattern = kmem_alloc(MAXNAMELEN, KM_SLEEP);
(void) strcpy(pattern, sr->sid_odir->d_pattern);
- /* this is funky */
+
if (strcmp(pattern, "*.*") == 0)
(void) strncpy(pattern, "*", sizeof (pattern));
+
wildcards = sr->sid_odir->d_wildcards;
sattr = sr->sid_odir->d_sattr;
cookie = 0;
@@ -337,23 +361,22 @@ smb_com_trans2_find_first2(struct smb_request *sr, struct smb_xa *xa)
if (rc) {
smb_rdir_close(sr);
kmem_free(pattern, MAXNAMELEN);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
/*
- * Save the sid here because search might get closed
- * and sr->smb_sid becomes invalid.
- * This might not seem important because the search
- * is going to be finished anyways, but it's just for
- * the sake of compatibility with Windows.
+ * Save the sid here in case the search is closed below,
+ * which will invalidate sr->smb_sid. We return the
+ * sid, even though the search has been closed, to be
+ * compatible with Windows.
*/
sid = sr->smb_sid;
if (fflag & SMB_FIND_CLOSE_AFTER_REQUEST ||
- (!more && fflag & SMB_FIND_CLOSE_AT_EOS))
+ (!more && fflag & SMB_FIND_CLOSE_AT_EOS)) {
smb_rdir_close(sr);
- else {
+ } else {
mutex_enter(&sr->sid_odir->d_mutex);
sr->sid_odir->d_cookie = cookie;
mutex_exit(&sr->sid_odir->d_mutex);
@@ -366,8 +389,6 @@ smb_com_trans2_find_first2(struct smb_request *sr, struct smb_xa *xa)
return (SDRC_NORMAL_REPLY);
}
-
-
/*
* smb_com_trans2_find_next2
*
@@ -418,57 +439,61 @@ smb_com_trans2_find_first2(struct smb_request *sr, struct smb_xa *xa)
* matches found in the search
*/
int
-smb_com_trans2_find_next2(struct smb_request *sr, struct smb_xa *xa)
+smb_com_trans2_find_next2(smb_request_t *sr, smb_xa_t *xa)
{
- unsigned short fflag, infolev;
+ uint16_t fflag, infolev;
int maxdata, count, wildcards, more = 0, rc;
uint32_t cookie;
- uint32_t maxcount = 0;
- struct smb_node *dir_snode;
+ uint16_t maxcount = 0;
+ smb_node_t *dir_snode;
char *pattern;
- unsigned short sattr;
+ uint16_t sattr;
- pattern = kmem_alloc(MAXNAMELEN, KM_SLEEP);
/*
- * There is a path field as the last piece of input information:
+ * The last parameter in the request is a path, which is a
+ * null-terminated unicode string.
*
* smb_decode_mbc(&xa->req_param_mb, "%www lwu", sr,
- * &sr->smb_sid, &maxcount, &infolev, &cookie, &fflag, &path)
+ * &sr->smb_sid, &maxcount, &infolev, &cookie, &fflag, &path)
*
- * This feild has been removed because it's causing problem
- * with Mac OS 10 and it's not used anyways.
- * The problem is that code expects to see a 2-byte null
- * because the strings are supposed to be Unicode, but
- * Max OS 10 sends a 1-byte null which leads to decode error.
+ * We don't reference this parameter and it is not currently
+ * decoded because we a expect 2-byte null but Mac OS 10
+ * clients send a 1-byte null, which leads to a decode error.
*/
if (smb_decode_mbc(&xa->req_param_mb, "%www lw", sr,
&sr->smb_sid, &maxcount, &infolev, &cookie, &fflag) != 0) {
- kmem_free(pattern, MAXNAMELEN);
smbsr_decode_error(sr);
/* NOTREACHED */
}
- maxdata = smb_trans2_find_get_maxdata(sr, infolev, fflag);
-
sr->sid_odir = smb_odir_lookup_by_sid(sr->tid_tree, sr->smb_sid);
if (sr->sid_odir == NULL) {
- kmem_free(pattern, MAXNAMELEN);
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
+ maxdata = smb_trans2_find_get_maxdata(sr, infolev, fflag);
if (maxdata == 0) {
smb_rdir_close(sr);
- kmem_free(pattern, MAXNAMELEN);
- smbsr_raise_error(sr, ERRDOS, ERRunknownlevel);
+ smbsr_error(sr, NT_STATUS_INVALID_LEVEL,
+ ERRDOS, ERROR_INVALID_LEVEL);
/* NOTREACHED */
}
/*
+ * When maxcount is zero Windows behaves as if it was 1.
+ */
+ if (maxcount == 0)
+ maxcount = 1;
+
+ if ((smb_trans2_find_max != 0) && (maxcount > smb_trans2_find_max))
+ maxcount = smb_trans2_find_max;
+
+ /*
* Get a copy of information
*/
dir_snode = sr->sid_odir->d_dir_snode;
+ pattern = kmem_alloc(MAXNAMELEN, KM_SLEEP);
(void) strcpy(pattern, sr->sid_odir->d_pattern);
wildcards = sr->sid_odir->d_wildcards;
sattr = sr->sid_odir->d_sattr;
@@ -478,17 +503,6 @@ smb_com_trans2_find_next2(struct smb_request *sr, struct smb_xa *xa)
mutex_exit(&sr->sid_odir->d_mutex);
}
- /*
- * XXX this is an optimization made for SFS2 filesystem, it might
- * not be required for ZFS
- *
- * Break the count to smaller counts (less than the default 150)
- * to reduce the number of transaction failures
- * which may cause excessive delays and eventually a SMB staled
- * connection.
- */
- maxcount = (maxcount > max_find_count) ? max_find_count : maxcount;
-
rc = smb_trans2_find_get_dents(sr, xa, fflag, infolev, maxdata,
dir_snode, sattr, maxcount, wildcards, pattern, &cookie,
&more, &count);
@@ -496,7 +510,7 @@ smb_com_trans2_find_next2(struct smb_request *sr, struct smb_xa *xa)
if (rc) {
smb_rdir_close(sr);
kmem_free(pattern, MAXNAMELEN);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -516,21 +530,17 @@ smb_com_trans2_find_next2(struct smb_request *sr, struct smb_xa *xa)
return (SDRC_NORMAL_REPLY);
}
-
/*
* smb_trans2_find_get_maxdata
*
- * This function calculates the minimum space requirement for the
- * base on information level and fflag.
+ * Calculate the minimum response space required for the specified
+ * information level.
*
- * When success, minimum space requirement will be returned; otherwise,
- * 0 will be returned.
+ * A non-zero return value provides the minimum space required.
+ * A return value of zero indicates an unknown information level.
*/
-int
-smb_trans2_find_get_maxdata(
- struct smb_request *sr,
- unsigned short infolev,
- unsigned short fflag)
+static int
+smb_trans2_find_get_maxdata(smb_request_t *sr, uint16_t infolev, uint16_t fflag)
{
int maxdata;
@@ -573,8 +583,6 @@ smb_trans2_find_get_maxdata(
return (maxdata);
}
-
-
/*
* smb_trans2_find_get_dents
*
@@ -591,12 +599,12 @@ smb_trans2_find_get_maxdata(
int smb_trans2_find_get_dents(
smb_request_t *sr,
smb_xa_t *xa,
- unsigned short fflag,
- unsigned short infolev,
+ uint16_t fflag,
+ uint16_t infolev,
int maxdata,
smb_node_t *dir_snode,
- unsigned short sattr,
- uint32_t maxcount,
+ uint16_t sattr,
+ uint16_t maxcount,
int wildcards,
char *pattern,
uint32_t *cookie,
@@ -686,7 +694,7 @@ int smb_get_dents(
smb_request_t *sr,
uint32_t *cookie,
smb_node_t *dir_snode,
- unsigned int wildcards,
+ uint32_t wildcards,
smb_dent_info_hdr_t *ihdr,
int *more)
{
@@ -787,8 +795,8 @@ smb_gather_dents_info(
/*LINTED E_BAD_PTR_CAST_ALIGN*/
smb_dent_info_hdr_t *ihdr = (smb_dent_info_hdr_t *)args;
smb_dent_info_t *ient;
- unsigned char *v5_name = NULL;
- unsigned char *np = (unsigned char *)name;
+ uint8_t *v5_name = NULL;
+ uint8_t *np = (uint8_t *)name;
int reclen = sizeof (smb_dent_info_t) + namelen;
v5_name = kmem_alloc(MAXNAMELEN-1, KM_SLEEP);
@@ -805,28 +813,8 @@ smb_gather_dents_info(
return (0);
}
- /*
- * If StorEdge is configured to support Catia Version 5 deployments,
- * any directory entry whose name contains the special Unix character
- * that is considered to be illegal in Windows environement will be
- * translated based on the following
- * Special Character Translation Table.
- *
- * ---------------------------
- * Unix-char | Windows-char
- * ---------------------------
- * " | (0x00a8) Diaeresis
- * * | (0x00a4) Currency Sign
- * : | (0x00f7) Division Sign
- * < | (0x00ab) Left-Pointing Double Angle Quotation Mark
- * > | (0x00bb) Right-Pointing Double Angle Quotation Mark
- * ? | (0x00bf) Inverted Question mark
- * \ | (0x00ff) Latin Small Letter Y with Diaeresis
- * | | (0x00a6) Broken Bar
- */
if (catia_callback) {
- /* XXX 255 should be max name len or something */
- catia_callback(v5_name, (unsigned char *)name, 255);
+ catia_callback(v5_name, (uint8_t *)name, MAXNAMELEN-1);
np = v5_name;
reclen = sizeof (smb_dent_info_t) + strlen((char *)v5_name);
}
@@ -876,15 +864,15 @@ smb_gather_dents_info(
*/
int
smb_trans2_find_process_ients(
- struct smb_request *sr,
- struct smb_xa *xa,
- smb_dent_info_hdr_t *ihdr,
- unsigned short fflag,
- unsigned short infolev,
- int maxdata,
- struct smb_node *dir_snode,
- int *more,
- uint32_t *cookie)
+ smb_request_t *sr,
+ smb_xa_t *xa,
+ smb_dent_info_hdr_t *ihdr,
+ uint16_t fflag,
+ uint16_t infolev,
+ int maxdata,
+ smb_node_t *dir_snode,
+ int *more,
+ uint32_t *cookie)
{
int i, err = 0;
smb_dent_info_t *ient;
@@ -897,15 +885,15 @@ smb_trans2_find_process_ients(
break;
/*
- * FYI: Some observed differences between our response and
- * Windows response which hasn't caused problem yet!
+ * Observed differences between our response and Windows
+ * response, which hasn't caused a problem yet!
*
- * 1. The NextEntryOffset field for the last entry should be 0
- * This code always calculate the record length and put the
- * result in this field.
+ * 1. The NextEntryOffset field for the last entry should
+ * be 0. This code always calculate the record length
+ * and puts the result in the NextEntryOffset field.
*
- * 2. The FileIndex field is always 0. This code put the cookie
- * in this field.
+ * 2. The FileIndex field is always 0. This code puts
+ * the cookie in the FileIndex field.
*/
err = smb_trans2_find_mbc_encode(sr, xa, ient, maxdata, infolev,
fflag, mb_flags, dir_snode, NULL);
@@ -915,8 +903,8 @@ smb_trans2_find_process_ients(
}
/*
- * Not enough space to store all the entries returned; therefore,
- * update the more to 1.
+ * Not enough space to store all the entries returned,
+ * which is indicated by setting more.
*/
if (more && err < 0) {
*more = 1;
@@ -931,8 +919,6 @@ smb_trans2_find_process_ients(
return (i);
}
-
-
/*
* smb_trans2_find_mbc_encode
*
@@ -942,45 +928,45 @@ smb_trans2_find_process_ients(
* is reached. If the entry is valid and successful encoded, 0
* will be returned; otherwise, 1 will be returned.
*/
-int smb_trans2_find_mbc_encode(
- struct smb_request *sr,
- struct smb_xa *xa,
- smb_dent_info_t *ient,
- int maxdata,
- unsigned short infolev,
- unsigned short fflag,
- unsigned int mb_flags,
- struct smb_node *dir_snode, /*LINTED E_FUNC_ARG_UNUSED*/
- struct smb_node *sd_snode)
+int /*ARGSUSED*/
+smb_trans2_find_mbc_encode(
+ smb_request_t *sr,
+ smb_xa_t *xa,
+ smb_dent_info_t *ient,
+ int maxdata,
+ uint16_t infolev,
+ uint16_t fflag,
+ uint32_t mb_flags,
+ smb_node_t *dir_snode,
+ smb_node_t *sd_snode)
{
int uni_namelen;
- int sl, rl;
+ int shortlen;
+ uint32_t next_entry_offset;
char buf83[26];
smb_msgbuf_t mb;
uint32_t dattr = 0;
uint32_t size32 = 0;
uint64_t size64 = 0;
- struct smb_node *lnk_snode;
+ smb_node_t *lnk_snode;
smb_attr_t lnkattr;
int rc;
uni_namelen = smb_ascii_or_unicode_strlen(sr, ient->name);
-
if (uni_namelen == -1)
return (1);
+ next_entry_offset = maxdata + uni_namelen;
+
if (MBC_ROOM_FOR(&xa->rep_data_mb, (maxdata + uni_namelen)) == 0)
return (-1);
if (ient->attr.sa_vattr.va_type == VLNK) {
-
rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS,
sr->tid_tree->t_snode, dir_snode, ient->name, &lnk_snode,
&lnkattr, 0, 0);
/*
- * IR 104598
- *
* We normally want to resolve the object to which a symlink
* refers so that CIFS clients can access sub-directories and
* find the correct association for files. This causes a
@@ -990,7 +976,7 @@ int smb_trans2_find_mbc_encode(
* Some Windows applications (i.e. virus scanning) loop/hang
* trying to follow this recursive path and there is little
* we can do because the path is constructed on the client.
- * So we've added a flag that allows an end-user to disable
+ * skc_dirsymlink_enable allows an end-user to disable
* symlinks to directories. Symlinks to other object types
* should be unaffected.
*/
@@ -1012,10 +998,6 @@ int smb_trans2_find_mbc_encode(
dattr = smb_mode_to_dos_attributes(&ient->attr);
}
- /*
- * we don't send the '.stream' to client. User shouldn't
- * see this directory.
- */
switch (infolev) {
case SMB_INFO_STANDARD:
if (fflag & SMB_FIND_RETURN_RESUME_KEYS)
@@ -1036,8 +1018,8 @@ int smb_trans2_find_mbc_encode(
case SMB_INFO_QUERY_EA_SIZE:
if (fflag & SMB_FIND_RETURN_RESUME_KEYS)
- (void) smb_encode_mbc(&xa->rep_data_mb,
- "l", ient->cookie);
+ (void) smb_encode_mbc(&xa->rep_data_mb, "l",
+ ient->cookie);
(void) smb_encode_mbc(&xa->rep_data_mb, "%yyyllwlbu", sr,
ient->attr.sa_crtime.tv_sec ? ient->attr.sa_crtime.tv_sec :
@@ -1053,11 +1035,8 @@ int smb_trans2_find_mbc_encode(
break;
case SMB_FIND_FILE_DIRECTORY_INFO:
- /* Use maxdata instead */
- rl = maxdata + uni_namelen;
-
(void) smb_encode_mbc(&xa->rep_data_mb, "%llTTTTqqllu", sr,
- rl,
+ next_entry_offset,
ient->cookie,
ient->attr.sa_crtime.tv_sec ? &ient->attr.sa_crtime :
&ient->attr.sa_vattr.va_mtime,
@@ -1072,20 +1051,18 @@ int smb_trans2_find_mbc_encode(
break;
case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
- /* Use maxdata instead */
- rl = maxdata + uni_namelen;
bzero(buf83, sizeof (buf83));
- smb_msgbuf_init(&mb, (unsigned char *)buf83, sizeof (buf83),
+ smb_msgbuf_init(&mb, (uint8_t *)buf83, sizeof (buf83),
mb_flags);
if (smb_msgbuf_encode(&mb, "u", ient->shortname) < 0) {
smb_msgbuf_term(&mb);
return (-1);
}
- sl = smb_ascii_or_unicode_strlen(sr, ient->shortname);
+ shortlen = smb_ascii_or_unicode_strlen(sr, ient->shortname);
- (void) smb_encode_mbc(&xa->rep_data_mb,
- "%llTTTTqqlllb.24cu", sr,
- rl,
+ (void) smb_encode_mbc(&xa->rep_data_mb, "%llTTTTqqlllb.24cu",
+ sr,
+ next_entry_offset,
ient->cookie,
ient->attr.sa_crtime.tv_sec ? &ient->attr.sa_crtime :
&ient->attr.sa_vattr.va_mtime,
@@ -1097,7 +1074,7 @@ int smb_trans2_find_mbc_encode(
dattr,
uni_namelen,
0L,
- sl,
+ shortlen,
buf83,
ient->name);
@@ -1105,9 +1082,8 @@ int smb_trans2_find_mbc_encode(
break;
case SMB_FIND_FILE_NAMES_INFO:
- rl = maxdata + uni_namelen;
(void) smb_encode_mbc(&xa->rep_data_mb, "%lllu", sr,
- rl,
+ next_entry_offset,
ient->cookie,
uni_namelen,
ient->name);
@@ -1121,7 +1097,7 @@ int smb_trans2_find_mbc_encode(
* Close a search started by a Trans2FindFirst2 request.
*/
int
-smb_com_find_close2(struct smb_request *sr)
+smb_com_find_close2(smb_request_t *sr)
{
if (smbsr_decode_vwv(sr, "w", &sr->smb_sid) != 0) {
smbsr_decode_error(sr);
@@ -1130,13 +1106,11 @@ smb_com_find_close2(struct smb_request *sr)
sr->sid_odir = smb_odir_lookup_by_sid(sr->tid_tree, sr->smb_sid);
if (sr->sid_odir == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
smb_rdir_close(sr);
-
smbsr_encode_empty_result(sr);
return (SDRC_NORMAL_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_query_file_info.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_query_file_info.c
index e6d4dbeccf..d4b5443cd9 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_query_file_info.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_query_file_info.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -105,8 +105,7 @@ smb_com_trans2_query_file_information(struct smb_request *sr, struct smb_xa *xa)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -176,7 +175,7 @@ smb_com_trans2_query_file_information(struct smb_request *sr, struct smb_xa *xa)
break;
default:
- smbsr_raise_error(sr, ERRDOS, ERRbadfile);
+ smbsr_error(sr, 0, ERRDOS, ERRbadfile);
/* NOTREACHED */
break;
}
@@ -359,7 +358,7 @@ smb_com_trans2_query_file_information(struct smb_request *sr, struct smb_xa *xa)
if (dir_snode == NULL) {
kmem_free(filebuf, MAXNAMELEN+1);
kmem_free(mangled_name, MAXNAMELEN);
- smbsr_raise_error(sr, ERRDOS, ERRbadfile);
+ smbsr_error(sr, 0, ERRDOS, ERRbadfile);
/* NOT REACHED */
}
(void) smb_encode_mbc(&xa->rep_param_mb, "w", 0);
@@ -386,7 +385,7 @@ smb_com_trans2_query_file_information(struct smb_request *sr, struct smb_xa *xa)
default:
kmem_free(filebuf, MAXNAMELEN+1);
kmem_free(mangled_name, MAXNAMELEN);
- smbsr_raise_error(sr, ERRDOS, ERRunknownlevel);
+ smbsr_error(sr, 0, ERRDOS, ERRunknownlevel);
/* NOTREACHED */
break;
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_query_fs_information.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_query_fs_information.c
index 509c4094f0..a1820b899e 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_query_fs_information.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_query_fs_information.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -283,14 +283,14 @@ smb_com_trans2_query_fs_information(struct smb_request *sr, struct smb_xa *xa)
snode = sr->tid_tree->t_snode;
if (fsd_getattr(&sr->tid_tree->t_fsd, &vol_attr) != 0) {
- smbsr_raise_errno(sr, ESTALE);
+ smbsr_errno(sr, ESTALE);
/* NOTREACHED */
}
switch (infolev) {
case SMB_INFO_ALLOCATION:
if ((rc = smb_fsop_statfs(sr->user_cr, snode, &df)) != 0) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -365,7 +365,7 @@ smb_com_trans2_query_fs_information(struct smb_request *sr, struct smb_xa *xa)
case SMB_QUERY_FS_SIZE_INFO:
if ((rc = smb_fsop_statfs(sr->user_cr, snode, &df)) != 0) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -425,7 +425,7 @@ smb_com_trans2_query_fs_information(struct smb_request *sr, struct smb_xa *xa)
break;
default:
- smbsr_raise_error(sr, ERRDOS, ERRunknownlevel);
+ smbsr_error(sr, 0, ERRDOS, ERRunknownlevel);
/* NOTREACHED */
break;
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_query_path_info.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_query_path_info.c
index 374a6de2bd..bea67e6545 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_query_path_info.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_query_path_info.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -341,7 +341,7 @@ smb_com_trans2_query_path_information(struct smb_request *sr, struct smb_xa *xa)
int len;
if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS,
ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -382,7 +382,7 @@ smb_com_trans2_query_path_information(struct smb_request *sr, struct smb_xa *xa)
kmem_free(name, MAXNAMELEN);
kmem_free(short_name, MAXNAMELEN);
kmem_free(name83, MAXNAMELEN);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -393,7 +393,7 @@ smb_com_trans2_query_path_information(struct smb_request *sr, struct smb_xa *xa)
kmem_free(name, MAXNAMELEN);
kmem_free(short_name, MAXNAMELEN);
kmem_free(name83, MAXNAMELEN);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
smb_node_release(dir_node);
@@ -576,7 +576,7 @@ smb_com_trans2_query_path_information(struct smb_request *sr, struct smb_xa *xa)
kmem_free(name, MAXNAMELEN);
kmem_free(short_name, MAXNAMELEN);
kmem_free(name83, MAXNAMELEN);
- smbsr_raise_error(sr, ERRDOS, ERRunknownlevel);
+ smbsr_error(sr, 0, ERRDOS, ERRunknownlevel);
/* NOTREACHED */
break;
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_set_file_information.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_set_file_information.c
index 094032da1c..de71abb6d3 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_set_file_information.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_set_file_information.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -123,7 +123,7 @@ smb_com_trans2_set_file_information(struct smb_request *sr, struct smb_xa *xa)
if (!STYPE_ISDSK(sr->tid_tree->t_res_type) ||
SMB_TREE_IS_READ_ONLY(sr)) {
kmem_free(info, sizeof (smb_trans2_setinfo_t));
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -131,8 +131,7 @@ smb_com_trans2_set_file_information(struct smb_request *sr, struct smb_xa *xa)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
kmem_free(info, sizeof (smb_trans2_setinfo_t));
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -142,7 +141,7 @@ smb_com_trans2_set_file_information(struct smb_request *sr, struct smb_xa *xa)
!SMB_FTYPE_IS_DISK(sr->fid_ofile->f_ftype)) {
cmn_err(CE_NOTE, "SmbT2SetFileInfo: access denied");
kmem_free(info, sizeof (smb_trans2_setinfo_t));
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -154,8 +153,7 @@ smb_com_trans2_set_file_information(struct smb_request *sr, struct smb_xa *xa)
/* NOTREACHED */
} else if (status == NT_STATUS_UNSUCCESSFUL) {
kmem_free(info, sizeof (smb_trans2_setinfo_t));
- smbsr_raise_cifs_error(sr, smberr.status,
- smberr.errcls, smberr.errcode);
+ smbsr_error(sr, smberr.status, smberr.errcls, smberr.errcode);
/* NOTREACHED */
}
kmem_free(info, sizeof (smb_trans2_setinfo_t));
diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_set_information.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_set_information.c
index 8c4368f93f..782e42f36d 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_set_information.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_set_information.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -228,7 +228,7 @@ smb_set_standard_info(
smb_node_set_time(node, &crtime, &mtime, &atime, 0, what);
rc = smb_sync_fsattr(sr, sr->user_cr, node);
if (rc) {
- smb_errmap_unix2smb(rc, smberr);
+ smbsr_map_errno(rc, smberr);
status = NT_STATUS_UNSUCCESSFUL;
}
@@ -295,7 +295,7 @@ smb_set_basic_info(
smb_node_set_time(node, &crtime, &mtime, &atime, &ctime, what);
rc = smb_sync_fsattr(sr, sr->user_cr, node);
if (rc) {
- smb_errmap_unix2smb(rc, smberr);
+ smbsr_map_errno(rc, smberr);
status = NT_STATUS_UNSUCCESSFUL;
}
@@ -339,7 +339,7 @@ smb_set_alloc_info(
* write requests without the inode ever being updated.
*/
if ((rc = smb_set_file_size(sr)) != 0) {
- smb_errmap_unix2smb(rc, smberr);
+ smbsr_map_errno(rc, smberr);
status = NT_STATUS_UNSUCCESSFUL;
}
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_set_path_information.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_set_path_information.c
index 02be8c53cb..fd3c2d571f 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_set_path_information.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_set_path_information.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -134,7 +134,7 @@ smb_com_trans2_set_path_information(struct smb_request *sr, struct smb_xa *xa)
if (!STYPE_ISDSK(sr->tid_tree->t_res_type) ||
SMB_TREE_IS_READ_ONLY(sr)) {
kmem_free(info, sizeof (smb_trans2_setinfo_t));
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -145,7 +145,7 @@ smb_com_trans2_set_path_information(struct smb_request *sr, struct smb_xa *xa)
if (rc != 0) {
kmem_free(info, sizeof (smb_trans2_setinfo_t));
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -157,7 +157,7 @@ smb_com_trans2_set_path_information(struct smb_request *sr, struct smb_xa *xa)
if (rc != 0) {
kmem_free(info, sizeof (smb_trans2_setinfo_t));
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
}
info->node = ret_snode;
@@ -170,8 +170,7 @@ smb_com_trans2_set_path_information(struct smb_request *sr, struct smb_xa *xa)
/* NOTREACHED */
} else if (status == NT_STATUS_UNSUCCESSFUL) {
kmem_free(info, sizeof (smb_trans2_setinfo_t));
- smbsr_raise_cifs_error(sr, smberr.status,
- smberr.errcls, smberr.errcode);
+ smbsr_error(sr, smberr.status, smberr.errcls, smberr.errcode);
/* NOTREACHED */
}
kmem_free(info, sizeof (smb_trans2_setinfo_t));
diff --git a/usr/src/uts/common/fs/smbsrv/smb_tree_disconnect.c b/usr/src/uts/common/fs/smbsrv/smb_tree_disconnect.c
index 9139930a4d..560c1d7b76 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_tree_disconnect.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_tree_disconnect.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -100,9 +100,10 @@ smb_com_tree_disconnect(struct smb_request *sr)
sr->smb_tid);
if (sr->uid_user == NULL || sr->tid_tree == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRinvnid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRinvnid);
+ /* NOTREACHED */
}
+
smbsr_rq_notify(sr, sr->session, sr->tid_tree);
smb_tree_disconnect(sr->tid_tree);
smbsr_encode_empty_result(sr);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_unlock_byte_range.c b/usr/src/uts/common/fs/smbsrv/smb_unlock_byte_range.c
index fef432d9fc..8e75fadc36 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_unlock_byte_range.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_unlock_byte_range.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -69,15 +69,15 @@ smb_com_unlock_byte_range(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
result = smb_unlock_range(sr, sr->fid_ofile->f_node,
(u_offset_t)Offset, (uint64_t)Length);
if (result != NT_STATUS_SUCCESS) {
- smb_unlock_range_raise_error(sr, result);
+ smbsr_error(sr, NT_STATUS_RANGE_NOT_LOCKED,
+ ERRDOS, ERRnotlocked);
/* NOT REACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_vops.c b/usr/src/uts/common/fs/smbsrv/smb_vops.c
index 538c9cfc91..0e9bbe45f2 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_vops.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_vops.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,6 +34,9 @@
#include <sys/pathname.h>
#include <sys/cred.h>
#include <sys/extdirent.h>
+#include <sys/nbmlock.h>
+#include <sys/share.h>
+#include <sys/fcntl.h>
#include <smbsrv/smb_vops.h>
#include <smbsrv/string.h>
@@ -43,21 +46,22 @@
#include <smbsrv/smb_kproto.h>
#include <smbsrv/smb_incl.h>
+void
+smb_vop_setup_xvattr(smb_attr_t *smb_attr, xvattr_t *xvattr);
static int
smb_vop_readdir_readpage(vnode_t *vp, void *buf, uint32_t offset, int *count,
- cred_t *cr, caller_context_t *ct, int flags);
+ cred_t *cr, int flags);
static int
smb_vop_readdir_entry(vnode_t *dvp, uint32_t *cookiep, char *name, int *namelen,
ino64_t *inop, vnode_t **vpp, char *od_name, int flags, cred_t *cr,
- caller_context_t *ct, char *dirbuf, int num_bytes);
+ char *dirbuf, int num_bytes);
static int
smb_vop_getdents_entries(smb_node_t *dir_snode, uint32_t *cookiep,
int32_t *dircountp, char *arg, uint32_t flags, struct smb_request *sr,
- cred_t *cr, caller_context_t *ct, char *dirbuf, int *maxentries,
- int num_bytes, char *);
+ cred_t *cr, char *dirbuf, int *maxentries, int num_bytes, char *);
extern int
smb_gather_dents_info(char *args, ino_t fileid, int namelen,
@@ -68,6 +72,8 @@ smb_gather_dents_info(char *args, ino_t fileid, int namelen,
static void
smb_sa_to_va_mask(uint_t sa_mask, uint_t *va_maskp);
+extern sysid_t lm_alloc_sysidt();
+
#define SMB_AT_MAX 16
static uint_t smb_attrmap[SMB_AT_MAX] = {
0,
@@ -88,16 +94,45 @@ static uint_t smb_attrmap[SMB_AT_MAX] = {
AT_SEQ
};
+/*
+ * The smb_ct will be used primarily for range locking.
+ * Since the CIFS server is mapping its locks to POSIX locks,
+ * only one pid is used for operations originating from the
+ * CIFS server (to represent CIFS in the VOP_FRLOCK routines).
+ */
+
+caller_context_t smb_ct;
+
+/*
+ * smb_vop_start()
+ *
+ * Initialize the smb caller context. This function must be called
+ * before any other smb_vop calls.
+ */
+
+void
+smb_vop_start(void)
+{
+ static boolean_t initialized = B_FALSE;
+
+ if (!initialized) {
+ smb_ct.cc_caller_id = fs_new_caller_id();
+ smb_ct.cc_pid = ttoproc(curthread)->p_pid;
+ smb_ct.cc_sysid = lm_alloc_sysidt();
+ initialized = B_TRUE;
+ }
+}
+
int
-smb_vop_open(vnode_t **vpp, int mode, cred_t *cred, caller_context_t *ct)
+smb_vop_open(vnode_t **vpp, int mode, cred_t *cred)
{
- return (VOP_OPEN(vpp, mode, cred, ct));
+ return (VOP_OPEN(vpp, mode, cred, &smb_ct));
}
int
-smb_vop_close(vnode_t *vp, int mode, cred_t *cred, caller_context_t *ct)
+smb_vop_close(vnode_t *vp, int mode, cred_t *cred)
{
- return (VOP_CLOSE(vp, mode, 1, (offset_t)0, cred, ct));
+ return (VOP_CLOSE(vp, mode, 1, (offset_t)0, cred, &smb_ct));
}
/*
@@ -115,19 +150,19 @@ smb_vop_close(vnode_t *vp, int mode, cred_t *cred, caller_context_t *ct)
*/
int
-smb_vop_read(vnode_t *vp, uio_t *uiop, cred_t *cr, caller_context_t *ct)
+smb_vop_read(vnode_t *vp, uio_t *uiop, cred_t *cr)
{
int error;
(void) VOP_RWLOCK(vp, V_WRITELOCK_FALSE, NULL);
- error = VOP_READ(vp, uiop, 0, cr, ct);
+ error = VOP_READ(vp, uiop, 0, cr, &smb_ct);
VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
return (error);
}
int
smb_vop_write(vnode_t *vp, uio_t *uiop, uint32_t *flag, uint32_t *lcount,
- cred_t *cr, caller_context_t *ct)
+ cred_t *cr)
{
int error;
int ioflag = 0;
@@ -140,7 +175,7 @@ smb_vop_write(vnode_t *vp, uio_t *uiop, uint32_t *flag, uint32_t *lcount,
uiop->uio_llimit = MAXOFFSET_T;
(void) VOP_RWLOCK(vp, V_WRITELOCK_TRUE, NULL);
- error = VOP_WRITE(vp, uiop, ioflag, cr, ct);
+ error = VOP_WRITE(vp, uiop, ioflag, cr, &smb_ct);
VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL);
*lcount -= uiop->uio_resid;
@@ -168,7 +203,7 @@ smb_vop_write(vnode_t *vp, uio_t *uiop, uint32_t *flag, uint32_t *lcount,
int
smb_vop_getattr(vnode_t *vp, vnode_t *unnamed_vp, smb_attr_t *ret_attr,
- int flags, cred_t *cr, caller_context_t *ct)
+ int flags, cred_t *cr)
{
int error;
vnode_t *use_vp;
@@ -197,7 +232,7 @@ smb_vop_getattr(vnode_t *vp, vnode_t *unnamed_vp, smb_attr_t *ret_attr,
XVA_SET_REQ(&tmp_xvattr, XAT_CREATETIME);
if ((error = VOP_GETATTR(use_vp, (vattr_t *)&tmp_xvattr, flags,
- cr, ct)) != 0)
+ cr, &smb_ct)) != 0)
return (error);
ret_attr->sa_vattr = tmp_xvattr.xva_vattr;
@@ -250,7 +285,7 @@ smb_vop_getattr(vnode_t *vp, vnode_t *unnamed_vp, smb_attr_t *ret_attr,
tmp_xvattr.xva_vattr.va_mask = AT_SIZE;
if ((error = VOP_GETATTR(vp, (vattr_t *)&tmp_xvattr,
- flags, cr, ct)) != 0)
+ flags, cr, &smb_ct)) != 0)
return (error);
ret_attr->sa_vattr.va_size =
@@ -272,7 +307,7 @@ smb_vop_getattr(vnode_t *vp, vnode_t *unnamed_vp, smb_attr_t *ret_attr,
smb_sa_to_va_mask(ret_attr->sa_mask,
&ret_attr->sa_vattr.va_mask);
- error = VOP_GETATTR(use_vp, &ret_attr->sa_vattr, flags, cr, ct);
+ error = VOP_GETATTR(use_vp, &ret_attr->sa_vattr, flags, cr, &smb_ct);
if (error != 0)
return (error);
@@ -297,7 +332,7 @@ smb_vop_getattr(vnode_t *vp, vnode_t *unnamed_vp, smb_attr_t *ret_attr,
*/
tmp_attr.sa_vattr.va_mask = AT_SIZE;
- error = VOP_GETATTR(vp, &tmp_attr.sa_vattr, flags, cr, ct);
+ error = VOP_GETATTR(vp, &tmp_attr.sa_vattr, flags, cr, &smb_ct);
if (error != 0)
return (error);
@@ -326,14 +361,13 @@ smb_vop_getattr(vnode_t *vp, vnode_t *unnamed_vp, smb_attr_t *ret_attr,
int
smb_vop_setattr(vnode_t *vp, vnode_t *unnamed_vp, smb_attr_t *set_attr,
- int flags, cred_t *cr, boolean_t no_xvattr, caller_context_t *ct)
+ int flags, cred_t *cr, boolean_t no_xvattr)
{
int error = 0;
int at_size = 0;
vnode_t *use_vp;
- xvattr_t tmp_xvattr;
- xoptattr_t *xoap = NULL;
- uint_t xva_mask;
+ xvattr_t xvattr;
+ vattr_t *vap;
if (unnamed_vp) {
use_vp = unnamed_vp;
@@ -354,116 +388,24 @@ smb_vop_setattr(vnode_t *vp, vnode_t *unnamed_vp, smb_attr_t *set_attr,
if ((no_xvattr == B_FALSE) &&
vfs_has_feature(use_vp->v_vfsp, VFSFT_XVATTR)) {
- /*
- * Initialize xvattr, including bzero
- */
- xva_init(&tmp_xvattr);
- xoap = xva_getxoptattr(&tmp_xvattr);
-
- ASSERT(xoap);
-
- /*
- * Copy caller-specified classic attributes to tmp_xvattr.
- * First save tmp_xvattr's mask (set in xva_init()), which
- * contains AT_XVATTR. This is |'d in later if needed.
- */
-
- xva_mask = tmp_xvattr.xva_vattr.va_mask;
- tmp_xvattr.xva_vattr = set_attr->sa_vattr;
+ smb_vop_setup_xvattr(set_attr, &xvattr);
+ vap = (vattr_t *)&xvattr;
+ } else {
smb_sa_to_va_mask(set_attr->sa_mask,
- &tmp_xvattr.xva_vattr.va_mask);
-
- /*
- * Do not set ctime (only the file system can do it)
- */
-
- tmp_xvattr.xva_vattr.va_mask &= ~AT_CTIME;
-
- if (set_attr->sa_mask & SMB_AT_DOSATTR) {
-
- /*
- * "|" in the original xva_mask, which contains
- * AT_XVATTR
- */
-
- tmp_xvattr.xva_vattr.va_mask |= xva_mask;
-
- XVA_SET_REQ(&tmp_xvattr, XAT_ARCHIVE);
- XVA_SET_REQ(&tmp_xvattr, XAT_SYSTEM);
- XVA_SET_REQ(&tmp_xvattr, XAT_READONLY);
- XVA_SET_REQ(&tmp_xvattr, XAT_HIDDEN);
-
- /*
- * set_attr->sa_dosattr: If a given bit is not set,
- * that indicates that the corresponding field needs
- * to be updated with a "0" value. This is done
- * implicitly as the xoap->xoa_* fields were bzero'd.
- */
-
- if (set_attr->sa_dosattr & FILE_ATTRIBUTE_ARCHIVE)
- xoap->xoa_archive = 1;
-
- if (set_attr->sa_dosattr & FILE_ATTRIBUTE_SYSTEM)
- xoap->xoa_system = 1;
-
- if (set_attr->sa_dosattr & FILE_ATTRIBUTE_READONLY)
- xoap->xoa_readonly = 1;
-
- if (set_attr->sa_dosattr & FILE_ATTRIBUTE_HIDDEN)
- xoap->xoa_hidden = 1;
- }
-
- if (set_attr->sa_mask & SMB_AT_CRTIME) {
- /*
- * "|" in the original xva_mask, which contains
- * AT_XVATTR
- */
-
- tmp_xvattr.xva_vattr.va_mask |= xva_mask;
- XVA_SET_REQ(&tmp_xvattr, XAT_CREATETIME);
- xoap->xoa_createtime = set_attr->sa_crtime;
- }
-
- if ((error = VOP_SETATTR(use_vp, (vattr_t *)&tmp_xvattr, flags,
- cr, ct)) != 0)
- return (error);
-
- /*
- * If the size of the stream needs to be set, set it on
- * the stream file directly. (All other indicated attributes
- * are set on the stream's unnamed stream, above.)
- */
-
- if (at_size) {
- /*
- * set_attr->sa_vattr.va_size already contains the
- * size as set by the caller
- *
- * Note that vp is used here, and not use_vp.
- * Also, only AT_SIZE is needed.
- */
+ &set_attr->sa_vattr.va_mask);
+ vap = &set_attr->sa_vattr;
+ }
- set_attr->sa_vattr.va_mask = AT_SIZE;
- error = VOP_SETATTR(vp, &set_attr->sa_vattr, flags,
- cr, ct);
- }
+ if ((error = VOP_SETATTR(use_vp, vap, flags, cr, &smb_ct)) != 0)
return (error);
- }
- /*
- * Support for file systems without VFSFT_XVATTR or no_xvattr == B_TRUE
- */
- smb_sa_to_va_mask(set_attr->sa_mask, &set_attr->sa_vattr.va_mask);
+
/*
- * set_attr->sa_vattr already contains new values
- * as set by the caller
+ * If the size of the stream needs to be set, set it on
+ * the stream file directly. (All other indicated attributes
+ * are set on the stream's unnamed stream, above.)
*/
- error = VOP_SETATTR(use_vp, &set_attr->sa_vattr, flags, cr, ct);
-
- if (error != 0)
- return (error);
-
if (at_size) {
/*
* set_attr->sa_vattr.va_size already contains the
@@ -474,8 +416,10 @@ smb_vop_setattr(vnode_t *vp, vnode_t *unnamed_vp, smb_attr_t *set_attr,
*/
set_attr->sa_vattr.va_mask = AT_SIZE;
- error = VOP_SETATTR(vp, &set_attr->sa_vattr, flags, cr, ct);
+ error = VOP_SETATTR(vp, &set_attr->sa_vattr, flags, cr,
+ &smb_ct);
}
+
return (error);
}
@@ -531,7 +475,7 @@ smb_vop_access(vnode_t *vp, int mode, int flags, vnode_t *dir_vp, cred_t *cr)
int
smb_vop_lookup(vnode_t *dvp, char *name, vnode_t **vpp, char *od_name,
- int flags, vnode_t *rootvp, cred_t *cr, caller_context_t *ct)
+ int flags, vnode_t *rootvp, cred_t *cr)
{
int error = 0;
int option_flags = 0;
@@ -578,7 +522,7 @@ smb_vop_lookup(vnode_t *dvp, char *name, vnode_t **vpp, char *od_name,
pn_alloc(&rpn);
error = VOP_LOOKUP(dvp, name, vpp, NULL, option_flags, NULL, cr,
- ct, NULL, &rpn);
+ &smb_ct, NULL, &rpn);
if ((error == 0) && od_name) {
bzero(od_name, MAXNAMELEN);
@@ -594,25 +538,34 @@ smb_vop_lookup(vnode_t *dvp, char *name, vnode_t **vpp, char *od_name,
int
smb_vop_create(vnode_t *dvp, char *name, smb_attr_t *attr, vnode_t **vpp,
- int flags, cred_t *cr, caller_context_t *ct, vsecattr_t *vsap)
+ int flags, cred_t *cr, vsecattr_t *vsap)
{
int error;
int option_flags = 0;
+ xvattr_t xvattr;
+ vattr_t *vap;
if (flags & SMB_IGNORE_CASE)
option_flags = FIGNORECASE;
- smb_sa_to_va_mask(attr->sa_mask, &attr->sa_vattr.va_mask);
+ attr->sa_vattr.va_mask = 0;
+
+ if (vfs_has_feature(dvp->v_vfsp, VFSFT_XVATTR)) {
+ smb_vop_setup_xvattr(attr, &xvattr);
+ vap = (vattr_t *)&xvattr;
+ } else {
+ smb_sa_to_va_mask(attr->sa_mask, &attr->sa_vattr.va_mask);
+ vap = &attr->sa_vattr;
+ }
- error = VOP_CREATE(dvp, name, &attr->sa_vattr, EXCL,
- attr->sa_vattr.va_mode, vpp, cr, option_flags, ct, vsap);
+ error = VOP_CREATE(dvp, name, vap, EXCL, attr->sa_vattr.va_mode,
+ vpp, cr, option_flags, &smb_ct, vsap);
return (error);
}
int
-smb_vop_remove(vnode_t *dvp, char *name, int flags, cred_t *cr,
- caller_context_t *ct)
+smb_vop_remove(vnode_t *dvp, char *name, int flags, cred_t *cr)
{
int error;
int option_flags = 0;
@@ -620,7 +573,7 @@ smb_vop_remove(vnode_t *dvp, char *name, int flags, cred_t *cr,
if (flags & SMB_IGNORE_CASE)
option_flags = FIGNORECASE;
- error = VOP_REMOVE(dvp, name, cr, ct, option_flags);
+ error = VOP_REMOVE(dvp, name, cr, &smb_ct, option_flags);
return (error);
}
@@ -633,7 +586,7 @@ smb_vop_remove(vnode_t *dvp, char *name, int flags, cred_t *cr,
int
smb_vop_rename(vnode_t *from_dvp, char *from_name, vnode_t *to_dvp,
- char *to_name, int flags, cred_t *cr, caller_context_t *ct)
+ char *to_name, int flags, cred_t *cr)
{
int error;
int option_flags = 0;
@@ -643,14 +596,14 @@ smb_vop_rename(vnode_t *from_dvp, char *from_name, vnode_t *to_dvp,
option_flags = FIGNORECASE;
error = VOP_RENAME(from_dvp, from_name, to_dvp, to_name, cr,
- ct, option_flags);
+ &smb_ct, option_flags);
return (error);
}
int
smb_vop_mkdir(vnode_t *dvp, char *name, smb_attr_t *attr, vnode_t **vpp,
- int flags, cred_t *cr, caller_context_t *ct, vsecattr_t *vsap)
+ int flags, cred_t *cr, vsecattr_t *vsap)
{
int error;
int option_flags = 0;
@@ -662,7 +615,7 @@ smb_vop_mkdir(vnode_t *dvp, char *name, smb_attr_t *attr, vnode_t **vpp,
smb_sa_to_va_mask(attr->sa_mask, &attr->sa_vattr.va_mask);
- error = VOP_MKDIR(dvp, name, &attr->sa_vattr, vpp, cr, ct,
+ error = VOP_MKDIR(dvp, name, &attr->sa_vattr, vpp, cr, &smb_ct,
option_flags, vsap);
return (error);
@@ -677,8 +630,7 @@ smb_vop_mkdir(vnode_t *dvp, char *name, smb_attr_t *attr, vnode_t **vpp,
*/
int
-smb_vop_rmdir(vnode_t *dvp, char *name, int flags, cred_t *cr,
- caller_context_t *ct)
+smb_vop_rmdir(vnode_t *dvp, char *name, int flags, cred_t *cr)
{
int error;
int option_flags = 0;
@@ -698,16 +650,94 @@ smb_vop_rmdir(vnode_t *dvp, char *name, int flags, cred_t *cr,
* remove.
*/
- error = VOP_RMDIR(dvp, name, rootdir, cr, ct, option_flags);
+ error = VOP_RMDIR(dvp, name, rootdir, cr, &smb_ct, option_flags);
return (error);
}
int
-smb_vop_commit(vnode_t *vp, cred_t *cr, caller_context_t *ct)
+smb_vop_commit(vnode_t *vp, cred_t *cr)
+{
+ return (VOP_FSYNC(vp, 1, cr, &smb_ct));
+}
+
+void
+smb_vop_setup_xvattr(smb_attr_t *smb_attr, xvattr_t *xvattr)
{
- return (VOP_FSYNC(vp, 1, cr, ct));
+ xoptattr_t *xoap = NULL;
+ uint_t xva_mask;
+
+ /*
+ * Initialize xvattr, including bzero
+ */
+ xva_init(xvattr);
+ xoap = xva_getxoptattr(xvattr);
+
+ ASSERT(xoap);
+
+ /*
+ * Copy caller-specified classic attributes to xvattr.
+ * First save xvattr's mask (set in xva_init()), which
+ * contains AT_XVATTR. This is |'d in later if needed.
+ */
+
+ xva_mask = xvattr->xva_vattr.va_mask;
+ xvattr->xva_vattr = smb_attr->sa_vattr;
+
+ smb_sa_to_va_mask(smb_attr->sa_mask, &xvattr->xva_vattr.va_mask);
+
+ /*
+ * Do not set ctime (only the file system can do it)
+ */
+
+ xvattr->xva_vattr.va_mask &= ~AT_CTIME;
+
+ if (smb_attr->sa_mask & SMB_AT_DOSATTR) {
+
+ /*
+ * "|" in the original xva_mask, which contains
+ * AT_XVATTR
+ */
+
+ xvattr->xva_vattr.va_mask |= xva_mask;
+
+ XVA_SET_REQ(xvattr, XAT_ARCHIVE);
+ XVA_SET_REQ(xvattr, XAT_SYSTEM);
+ XVA_SET_REQ(xvattr, XAT_READONLY);
+ XVA_SET_REQ(xvattr, XAT_HIDDEN);
+
+ /*
+ * smb_attr->sa_dosattr: If a given bit is not set,
+ * that indicates that the corresponding field needs
+ * to be updated with a "0" value. This is done
+ * implicitly as the xoap->xoa_* fields were bzero'd.
+ */
+
+ if (smb_attr->sa_dosattr & FILE_ATTRIBUTE_ARCHIVE)
+ xoap->xoa_archive = 1;
+
+ if (smb_attr->sa_dosattr & FILE_ATTRIBUTE_SYSTEM)
+ xoap->xoa_system = 1;
+
+ if (smb_attr->sa_dosattr & FILE_ATTRIBUTE_READONLY)
+ xoap->xoa_readonly = 1;
+
+ if (smb_attr->sa_dosattr & FILE_ATTRIBUTE_HIDDEN)
+ xoap->xoa_hidden = 1;
+ }
+
+ if (smb_attr->sa_mask & SMB_AT_CRTIME) {
+ /*
+ * "|" in the original xva_mask, which contains
+ * AT_XVATTR
+ */
+
+ xvattr->xva_vattr.va_mask |= xva_mask;
+ XVA_SET_REQ(xvattr, XAT_CREATETIME);
+ xoap->xoa_createtime = smb_attr->sa_crtime;
+ }
}
+
/*
* smb_vop_readdir()
*
@@ -724,8 +754,7 @@ smb_vop_commit(vnode_t *vp, cred_t *cr, caller_context_t *ct)
int
smb_vop_readdir(vnode_t *dvp, uint32_t *cookiep, char *name, int *namelen,
- ino64_t *inop, vnode_t **vpp, char *od_name, int flags, cred_t *cr,
- caller_context_t *ct)
+ ino64_t *inop, vnode_t **vpp, char *od_name, int flags, cred_t *cr)
{
int num_bytes;
int error = 0;
@@ -737,7 +766,6 @@ smb_vop_readdir(vnode_t *dvp, uint32_t *cookiep, char *name, int *namelen,
ASSERT(namelen);
ASSERT(inop);
ASSERT(cr);
- ASSERT(ct);
if (dvp->v_type != VDIR) {
*namelen = 0;
@@ -759,7 +787,7 @@ smb_vop_readdir(vnode_t *dvp, uint32_t *cookiep, char *name, int *namelen,
*/
while ((error = smb_vop_readdir_readpage(dvp, dirbuf, *cookiep,
- &num_bytes, cr, ct, flags)) == 0) {
+ &num_bytes, cr, flags)) == 0) {
if (num_bytes <= 0)
break;
@@ -767,7 +795,7 @@ smb_vop_readdir(vnode_t *dvp, uint32_t *cookiep, char *name, int *namelen,
name[0] = '\0';
error = smb_vop_readdir_entry(dvp, cookiep, name, namelen,
- inop, vpp, od_name, flags, cr, ct, dirbuf,
+ inop, vpp, od_name, flags, cr, dirbuf,
num_bytes);
if (error)
@@ -815,7 +843,7 @@ smb_vop_readdir(vnode_t *dvp, uint32_t *cookiep, char *name, int *namelen,
static int
smb_vop_readdir_readpage(vnode_t *vp, void *buf, uint32_t offset, int *count,
- cred_t *cr, caller_context_t *ct, int flags)
+ cred_t *cr, int flags)
{
int error = 0;
int rdirent_flags = 0;
@@ -856,7 +884,7 @@ smb_vop_readdir_readpage(vnode_t *vp, void *buf, uint32_t offset, int *count,
auio.uio_fmode = 0;
(void) VOP_RWLOCK(vp, V_WRITELOCK_FALSE, NULL);
- error = VOP_READDIR(vp, &auio, cr, &sink, ct, rdirent_flags);
+ error = VOP_READDIR(vp, &auio, cr, &sink, &smb_ct, rdirent_flags);
VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
if (error) {
@@ -900,7 +928,7 @@ smb_vop_readdir_readpage(vnode_t *vp, void *buf, uint32_t offset, int *count,
static int
smb_vop_readdir_entry(vnode_t *dvp, uint32_t *cookiep, char *name, int *namelen,
ino64_t *inop, vnode_t **vpp, char *od_name, int flags, cred_t *cr,
- caller_context_t *ct, char *dirbuf, int num_bytes)
+ char *dirbuf, int num_bytes)
{
uint32_t next_cookie;
int ebufsize;
@@ -969,7 +997,7 @@ smb_vop_readdir_entry(vnode_t *dvp, uint32_t *cookiep, char *name, int *namelen,
*/
error = smb_vop_lookup(dvp, edp->ed_name, vpp ? vpp : &vp,
- od_name, 0, NULL, cr, ct);
+ od_name, 0, NULL, cr);
if (error) {
if (error == ENOENT) {
@@ -1080,8 +1108,7 @@ smb_vop_getdents(
char *pattern,
uint32_t flags,
smb_request_t *sr,
- cred_t *cr,
- caller_context_t *ct)
+ cred_t *cr)
{
int error = 0;
int maxentries;
@@ -1107,13 +1134,13 @@ smb_vop_getdents(
num_bytes = SMB_MINLEN_RDDIR_BUF;
error = smb_vop_readdir_readpage(dvp, dirbuf, *cookiep,
- &num_bytes, cr, ct, flags);
+ &num_bytes, cr, flags);
if (error || (num_bytes <= 0))
break;
error = smb_vop_getdents_entries(dir_snode, cookiep, dircountp,
- arg, flags, sr, cr, ct, dirbuf, &maxentries, num_bytes,
+ arg, flags, sr, cr, dirbuf, &maxentries, num_bytes,
pattern);
if (error)
@@ -1158,7 +1185,6 @@ smb_vop_getdents_entries(
uint32_t flags,
struct smb_request *sr,
cred_t *cr,
- caller_context_t *ct,
char *dirbuf,
int *maxentries,
int num_bytes,
@@ -1219,7 +1245,7 @@ smb_vop_getdents_entries(
}
error = smb_vop_lookup(dvp, edp->ed_name, &fvp,
- NULL, 0, NULL, cr, ct);
+ NULL, 0, NULL, cr);
if (error) {
if (error == ENOENT) {
@@ -1335,14 +1361,14 @@ smb_vop_getdents_entries(
int
smb_vop_stream_lookup(vnode_t *fvp, char *stream_name, vnode_t **vpp,
char *od_name, vnode_t **xattrdirvpp, int flags, vnode_t *rootvp,
- cred_t *cr, caller_context_t *ct)
+ cred_t *cr)
{
char *solaris_stream_name;
char *name;
int error;
if ((error = smb_vop_lookup_xattrdir(fvp, xattrdirvpp,
- LOOKUP_XATTR | CREATE_XATTR_DIR, cr, ct)) != 0)
+ LOOKUP_XATTR | CREATE_XATTR_DIR, cr)) != 0)
return (error);
/*
@@ -1361,7 +1387,7 @@ smb_vop_stream_lookup(vnode_t *fvp, char *stream_name, vnode_t **vpp,
name = kmem_zalloc(MAXNAMELEN, KM_SLEEP);
if ((error = smb_vop_lookup(*xattrdirvpp, solaris_stream_name, vpp,
- name, flags, rootvp, cr, ct)) != 0) {
+ name, flags, rootvp, cr)) != 0) {
VN_RELE(*xattrdirvpp);
} else {
(void) strlcpy(od_name, &(name[SMB_STREAM_PREFIX_LEN]),
@@ -1376,14 +1402,13 @@ smb_vop_stream_lookup(vnode_t *fvp, char *stream_name, vnode_t **vpp,
int
smb_vop_stream_create(vnode_t *fvp, char *stream_name, smb_attr_t *attr,
- vnode_t **vpp, vnode_t **xattrdirvpp, int flags, cred_t *cr,
- caller_context_t *ct)
+ vnode_t **vpp, vnode_t **xattrdirvpp, int flags, cred_t *cr)
{
char *solaris_stream_name;
int error;
if ((error = smb_vop_lookup_xattrdir(fvp, xattrdirvpp,
- LOOKUP_XATTR | CREATE_XATTR_DIR, cr, ct)) != 0)
+ LOOKUP_XATTR | CREATE_XATTR_DIR, cr)) != 0)
return (error);
/*
@@ -1395,7 +1420,7 @@ smb_vop_stream_create(vnode_t *fvp, char *stream_name, smb_attr_t *attr,
stream_name);
if ((error = smb_vop_create(*xattrdirvpp, solaris_stream_name, attr,
- vpp, flags, cr, ct, NULL)) != 0)
+ vpp, flags, cr, NULL)) != 0)
VN_RELE(*xattrdirvpp);
kmem_free(solaris_stream_name, MAXNAMELEN);
@@ -1404,15 +1429,14 @@ smb_vop_stream_create(vnode_t *fvp, char *stream_name, smb_attr_t *attr,
}
int
-smb_vop_stream_remove(vnode_t *vp, char *stream_name, int flags, cred_t *cr,
- caller_context_t *ct)
+smb_vop_stream_remove(vnode_t *vp, char *stream_name, int flags, cred_t *cr)
{
char *solaris_stream_name;
vnode_t *xattrdirvp;
int error;
- if ((error = smb_vop_lookup_xattrdir(vp, &xattrdirvp, LOOKUP_XATTR, cr,
- ct)) != 0)
+ if ((error = smb_vop_lookup_xattrdir(vp, &xattrdirvp, LOOKUP_XATTR, cr))
+ != 0)
return (error);
/*
@@ -1424,7 +1448,7 @@ smb_vop_stream_remove(vnode_t *vp, char *stream_name, int flags, cred_t *cr,
stream_name);
/* XXX might have to use kcred */
- error = smb_vop_remove(xattrdirvp, solaris_stream_name, flags, cr, ct);
+ error = smb_vop_remove(xattrdirvp, solaris_stream_name, flags, cr);
kmem_free(solaris_stream_name, MAXNAMELEN);
@@ -1444,7 +1468,7 @@ smb_vop_stream_remove(vnode_t *vp, char *stream_name, int flags, cred_t *cr,
int
smb_vop_stream_readdir(vnode_t *fvp, uint32_t *cookiep,
struct fs_stream_info *stream_info, vnode_t **vpp, vnode_t **xattrdirvpp,
- int flags, cred_t *cr, caller_context_t *ct)
+ int flags, cred_t *cr)
{
int nsize = MAXNAMELEN-1;
int error = 0;
@@ -1454,7 +1478,7 @@ smb_vop_stream_readdir(vnode_t *fvp, uint32_t *cookiep,
vnode_t *vp;
if ((error = smb_vop_lookup_xattrdir(fvp, &xattrdirvp, LOOKUP_XATTR,
- cr, ct)) != 0)
+ cr)) != 0)
return (error);
bzero(stream_info->name, sizeof (stream_info->name));
@@ -1464,7 +1488,7 @@ smb_vop_stream_readdir(vnode_t *fvp, uint32_t *cookiep,
for (;;) {
error = smb_vop_readdir(xattrdirvp, cookiep, tmp_name, &nsize,
- &ino, &vp, NULL, flags | SMB_STREAM_RDDIR, cr, ct);
+ &ino, &vp, NULL, flags | SMB_STREAM_RDDIR, cr);
if (error || (*cookiep == SMB_EOF))
break;
@@ -1504,12 +1528,12 @@ smb_vop_stream_readdir(vnode_t *fvp, uint32_t *cookiep,
int
smb_vop_lookup_xattrdir(vnode_t *fvp, vnode_t **xattrdirvpp, int flags,
- cred_t *cr, caller_context_t *ct)
+ cred_t *cr)
{
int error;
- error = VOP_LOOKUP(fvp, "", xattrdirvpp, NULL, flags, NULL, cr, ct,
- NULL, NULL);
+ error = VOP_LOOKUP(fvp, "", xattrdirvpp, NULL, flags, NULL, cr,
+ &smb_ct, NULL, NULL);
return (error);
}
@@ -1560,7 +1584,7 @@ smb_vop_statfs(vnode_t *vp, struct statvfs64 *statp, cred_t *cr)
*/
int
smb_vop_acl_read(vnode_t *vp, acl_t **aclp, int flags, acl_type_t acl_type,
- cred_t *cr, caller_context_t *ct)
+ cred_t *cr)
{
int error;
vsecattr_t vsecattr;
@@ -1585,7 +1609,7 @@ smb_vop_acl_read(vnode_t *vp, acl_t **aclp, int flags, acl_type_t acl_type,
return (EINVAL);
}
- if (error = VOP_GETSECATTR(vp, &vsecattr, flags, cr, ct))
+ if (error = VOP_GETSECATTR(vp, &vsecattr, flags, cr, &smb_ct))
return (error);
*aclp = smb_fsacl_from_vsa(&vsecattr, acl_type);
@@ -1601,8 +1625,7 @@ smb_vop_acl_read(vnode_t *vp, acl_t **aclp, int flags, acl_type_t acl_type,
* Writes the given ACL in aclp for the specified file.
*/
int
-smb_vop_acl_write(vnode_t *vp, acl_t *aclp, int flags, cred_t *cr,
- caller_context_t *ct)
+smb_vop_acl_write(vnode_t *vp, acl_t *aclp, int flags, cred_t *cr)
{
int error;
vsecattr_t vsecattr;
@@ -1615,7 +1638,7 @@ smb_vop_acl_write(vnode_t *vp, acl_t *aclp, int flags, cred_t *cr,
if (error == 0) {
(void) VOP_RWLOCK(vp, V_WRITELOCK_TRUE, NULL);
- error = VOP_SETSECATTR(vp, &vsecattr, flags, cr, ct);
+ error = VOP_SETSECATTR(vp, &vsecattr, flags, cr, &smb_ct);
VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL);
}
@@ -1713,3 +1736,93 @@ smb_vop_eaccess(vnode_t *vp, int *mode, int flags, vnode_t *dir_vp, cred_t *cr)
}
}
}
+
+/*
+ * smb_vop_shrlock()
+ *
+ * See comments for smb_fsop_shrlock()
+ */
+
+int
+smb_vop_shrlock(vnode_t *vp, uint32_t uniq_fid, uint32_t desired_access,
+ uint32_t share_access, cred_t *cr)
+{
+ struct shrlock shr;
+ struct shr_locowner shr_own;
+ short new_access = 0;
+ short deny = 0;
+ int flag = 0;
+ int cmd;
+
+ cmd = (nbl_need_check(vp)) ? F_SHARE_NBMAND : F_SHARE;
+
+ /*
+ * Check if this is a metadata access
+ */
+
+ if ((desired_access & FILE_DATA_ALL) == 0) {
+ new_access |= F_MDACC;
+ } else {
+ if (desired_access & (ACE_READ_DATA | ACE_EXECUTE)) {
+ new_access |= F_RDACC;
+ flag |= FREAD;
+ }
+
+ if (desired_access & (ACE_WRITE_DATA | ACE_APPEND_DATA |
+ ACE_ADD_FILE)) {
+ new_access |= F_WRACC;
+ flag |= FWRITE;
+ }
+
+ if (SMB_DENY_READ(share_access)) {
+ deny |= F_RDDNY;
+ }
+
+ if (SMB_DENY_WRITE(share_access)) {
+ deny |= F_WRDNY;
+ }
+
+ if (cmd == F_SHARE_NBMAND) {
+ if (desired_access & ACE_DELETE)
+ new_access |= F_RMACC;
+
+ if (SMB_DENY_DELETE(share_access)) {
+ deny |= F_RMDNY;
+ }
+ }
+ }
+
+ shr.s_access = new_access;
+ shr.s_deny = deny;
+ shr.s_sysid = smb_ct.cc_sysid;
+ shr.s_pid = uniq_fid;
+ shr.s_own_len = sizeof (shr_own);
+ shr.s_owner = (caddr_t)&shr_own;
+ shr_own.sl_id = shr.s_sysid;
+ shr_own.sl_pid = shr.s_pid;
+
+ return (VOP_SHRLOCK(vp, cmd, &shr, flag, cr, NULL));
+}
+
+int
+smb_vop_unshrlock(vnode_t *vp, uint32_t uniq_fid, cred_t *cr)
+{
+ struct shrlock shr;
+ struct shr_locowner shr_own;
+
+ /*
+ * For s_access and s_deny, we do not need to pass in the original
+ * values.
+ */
+
+ shr.s_access = 0;
+ shr.s_deny = 0;
+ shr.s_sysid = smb_ct.cc_sysid;
+ shr.s_pid = uniq_fid;
+ shr.s_own_len = sizeof (shr_own);
+ shr.s_owner = (caddr_t)&shr_own;
+ shr_own.sl_id = shr.s_sysid;
+ shr_own.sl_pid = shr.s_pid;
+
+ return (VOP_SHRLOCK(vp, F_UNSHARE, &shr, 0, cr, NULL));
+}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_write.c b/usr/src/uts/common/fs/smbsrv/smb_write.c
index 93b9f6e758..79a0ed82ec 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_write.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_write.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -78,8 +78,7 @@ smb_com_write(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -104,7 +103,7 @@ smb_com_write(struct smb_request *sr)
if (rc != 0) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -151,8 +150,7 @@ smb_com_write_and_close(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -180,13 +178,13 @@ smb_com_write_and_close(struct smb_request *sr)
if (rc != 0) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
if ((rc = smb_common_close(sr, last_write)) != 0) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -219,7 +217,7 @@ smb_com_write_and_unlock(struct smb_request *sr)
int rc = 0;
if (STYPE_ISDSK(sr->tid_tree->t_res_type) == 0) {
- smbsr_raise_error(sr, ERRDOS, ERRnoaccess);
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
/* NOTREACHED */
}
@@ -236,8 +234,7 @@ smb_com_write_and_unlock(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -259,7 +256,7 @@ smb_com_write_and_unlock(struct smb_request *sr)
if ((rc = smb_write_common(sr, param)) != 0) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -267,7 +264,8 @@ smb_com_write_and_unlock(struct smb_request *sr)
(uint64_t)param->w_count);
if (result != NT_STATUS_SUCCESS) {
kmem_free(param, sizeof (smb_write_param_t));
- smb_unlock_range_raise_error(sr, result);
+ smbsr_error(sr, NT_STATUS_RANGE_NOT_LOCKED,
+ ERRDOS, ERRnotlocked);
/* NOTREACHED */
}
@@ -324,15 +322,14 @@ smb_com_write_andx(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
if (SMB_WRMODE_IS_STABLE(param->w_mode) &&
STYPE_ISDSK(sr->tid_tree->t_res_type) == 0) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_raise_error(sr, ERRSRV, ERRaccess);
+ smbsr_error(sr, 0, ERRSRV, ERRaccess);
/* NOTREACHED */
}
@@ -349,7 +346,7 @@ smb_com_write_andx(struct smb_request *sr)
if (param->w_count != 0) {
if ((rc = smb_write_common(sr, param)) != 0) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
}
@@ -381,10 +378,9 @@ smb_write_common(struct smb_request *sr, smb_write_param_t *param)
if (node->attr.sa_vattr.va_type != VDIR) {
rc = smb_lock_range_access(sr, node, param->w_offset,
- param->w_count, FILE_WRITE_DATA);
+ param->w_count, B_TRUE);
if (rc != NT_STATUS_SUCCESS) {
- smbsr_raise_cifs_error(sr, rc,
- ERRSRV, ERRaccess);
+ smbsr_error(sr, rc, ERRSRV, ERRaccess);
/* NOTREACHED */
}
}
@@ -444,35 +440,49 @@ smb_write_truncate(struct smb_request *sr, smb_write_param_t *param)
{
struct smb_ofile *ofile = sr->fid_ofile;
smb_node_t *node = ofile->f_node;
+ boolean_t append_only = B_FALSE;
int rc;
if (STYPE_ISDSK(sr->tid_tree->t_res_type) == 0)
return (0);
- if (node->attr.sa_vattr.va_type != VDIR) {
- rc = smb_lock_range_access(sr, node, param->w_offset,
- param->w_count, FILE_WRITE_DATA);
+ rc = smb_ofile_access(sr->fid_ofile, sr->user_cr, FILE_WRITE_DATA);
+ if (rc != NT_STATUS_SUCCESS) {
+ rc = smb_ofile_access(sr->fid_ofile, sr->user_cr,
+ FILE_APPEND_DATA);
if (rc != NT_STATUS_SUCCESS) {
- smbsr_raise_cifs_error(sr, rc,
- ERRSRV, ERRaccess);
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS,
+ ERROR_ACCESS_DENIED);
/* NOTREACHED */
+ } else {
+ append_only = B_TRUE;
}
}
- /*
- * XXX what if the file has been opened only with
- * FILE_APPEND_DATA?
- */
- rc = smb_ofile_access(ofile, sr->user_cr, FILE_WRITE_DATA);
- if (rc != NT_STATUS_SUCCESS) {
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
- ERRDOS, ERROR_ACCESS_DENIED);
+ smb_rwx_xenter(&node->n_lock);
+
+ if (append_only && (param->w_offset < node->n_size)) {
+ smb_rwx_xexit(&node->n_lock);
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
+ ERRDOS, ERRnoaccess);
/* NOTREACHED */
}
+ if (node->attr.sa_vattr.va_type != VDIR) {
+ rc = smb_lock_range_access(sr, node, param->w_offset,
+ param->w_count, B_TRUE);
+ if (rc != NT_STATUS_SUCCESS) {
+ smb_rwx_xexit(&node->n_lock);
+ smbsr_error(sr, rc, ERRSRV, ERRaccess);
+ /* NOTREACHED */
+ }
+ }
+
node->flags |= NODE_FLAGS_SET_SIZE;
node->n_size = param->w_offset;
+ smb_rwx_xexit(&node->n_lock);
+
if ((rc = smb_set_file_size(sr)) != 0)
return (rc);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_write_raw.c b/usr/src/uts/common/fs/smbsrv/smb_write_raw.c
index 5d02179cc2..4c7fcb6f81 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_write_raw.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_write_raw.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -216,6 +216,7 @@ smb_com_write_raw(struct smb_request *sr)
unsigned int stability;
struct mbuf_chain reply;
smb_node_t *fnode;
+ smb_error_t err;
if (sr->session->s_state != SMB_SESSION_STATE_WRITE_RAW_ACTIVE) {
return (SDRC_DROP_VC);
@@ -244,8 +245,7 @@ smb_com_write_raw(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -260,10 +260,9 @@ smb_com_write_raw(struct smb_request *sr)
*/
if (fnode->attr.sa_vattr.va_type != VDIR) {
rc = smb_lock_range_access(sr, fnode, off,
- count, FILE_WRITE_DATA);
+ count, B_TRUE);
if (rc != NT_STATUS_SUCCESS) {
- smbsr_raise_cifs_error(sr, rc,
- ERRSRV, ERRaccess);
+ smbsr_error(sr, rc, ERRSRV, ERRaccess);
/* NOTREACHED */
}
}
@@ -440,8 +439,10 @@ notify_write_raw_complete:
* If we had an error fill in the appropriate error code
*/
if (rc != 0) {
- (void) smbsr_set_errno(sr, rc);
+ smbsr_map_errno(rc, &err);
+ smbsr_set_error(sr, &err);
}
+
/*
* Free raw write buffer if present (from smb_transfer_write_raw_data)
*/
diff --git a/usr/src/uts/common/smbsrv/cifs.h b/usr/src/uts/common/smbsrv/cifs.h
index 4533a21bb6..1f657a2d8c 100644
--- a/usr/src/uts/common/smbsrv/cifs.h
+++ b/usr/src/uts/common/smbsrv/cifs.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -421,6 +421,23 @@ extern "C" {
#define SMB_DA_WRITE_THROUGH 0x4000
/*
+ * Macros used for share reservation rule checking
+ */
+
+#define SMB_DENY_READ(share_access) ((share_access & FILE_SHARE_READ) == 0)
+
+#define SMB_DENY_WRITE(share_access) ((share_access & FILE_SHARE_WRITE) == 0)
+
+#define SMB_DENY_DELETE(share_access) ((share_access & FILE_SHARE_DELETE) == 0)
+
+#define SMB_DENY_RW(share_access) \
+ ((share_access & (FILE_SHARE_READ | FILE_SHARE_WRITE)) == 0)
+
+#define SMB_DENY_ALL(share_access) (share_access == 0)
+
+#define SMB_DENY_NONE(share_access) (share_access == FILE_SHARE_ALL)
+
+/*
* The SMB open function determines what action should be taken depending
* on the existence or lack thereof of files used in the operation. It
* has the following mapping:
diff --git a/usr/src/uts/common/smbsrv/lmshare.h b/usr/src/uts/common/smbsrv/lmshare.h
index db41a5bdee..218bb86df8 100644
--- a/usr/src/uts/common/smbsrv/lmshare.h
+++ b/usr/src/uts/common/smbsrv/lmshare.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -163,7 +163,6 @@ extern DWORD lmshrd_iterate(uint64_t iterator, lmshare_info_t *si);
extern DWORD lmshrd_list(int offset, lmshare_list_t *list);
extern DWORD lmshrd_list_transient(int offset, lmshare_list_t *list);
extern DWORD lmshrd_num_transient(void);
-extern int lmshrd_dump_hash(char *logfname);
#endif
extern int lmshrd_num_shares(void);
extern DWORD lmshrd_delete(char *share_name);
diff --git a/usr/src/uts/common/smbsrv/lmshare_door.h b/usr/src/uts/common/smbsrv/lmshare_door.h
index c1c6f2ba0c..4e4413bc9a 100644
--- a/usr/src/uts/common/smbsrv/lmshare_door.h
+++ b/usr/src/uts/common/smbsrv/lmshare_door.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -70,9 +70,9 @@ extern "C" {
#define SMB_GET_KCONFIG 17
-void smb_load_kconfig(smb_kmod_cfg_t *cfg);
-void smb_dr_get_kconfig(smb_dr_ctx_t *ctx, smb_kmod_cfg_t *cfg);
-void smb_dr_put_kconfig(smb_dr_ctx_t *ctx, smb_kmod_cfg_t *cfg);
+void smb_load_kconfig(smb_kmod_cfg_t *);
+void smb_dr_get_kconfig(smb_dr_ctx_t *, smb_kmod_cfg_t *);
+void smb_dr_put_kconfig(smb_dr_ctx_t *, smb_kmod_cfg_t *);
/*
* Door server status
@@ -97,17 +97,16 @@ void smb_dr_put_kconfig(smb_dr_ctx_t *ctx, smb_kmod_cfg_t *cfg);
* };
*/
-void smb_dr_get_lmshare(smb_dr_ctx_t *ctx, lmshare_info_t *si);
-void smb_dr_put_lmshare(smb_dr_ctx_t *ctx, lmshare_info_t *si);
-
-uint64_t smb_dr_get_lmshr_iterator(smb_dr_ctx_t *ctx);
-void smb_dr_put_lmshr_iterator(smb_dr_ctx_t *ctx,
- uint64_t lmshr_iter);
-void smb_dr_free_lmshr_iterator(smb_dr_ctx_t *ctx);
-void smb_dr_get_lmshr_list(smb_dr_ctx_t *ctx,
- lmshare_list_t *shrlist);
-void smb_dr_put_lmshr_list(smb_dr_ctx_t *ctx,
- lmshare_list_t *shrlist);
+void smb_dr_get_lmshare(smb_dr_ctx_t *, lmshare_info_t *);
+void smb_dr_put_lmshare(smb_dr_ctx_t *, lmshare_info_t *);
+
+uint64_t smb_dr_get_lmshr_iterator(smb_dr_ctx_t *);
+void smb_dr_put_lmshr_iterator(smb_dr_ctx_t *, uint64_t);
+void smb_dr_free_lmshr_iterator(smb_dr_ctx_t *);
+void smb_dr_get_lmshr_list(smb_dr_ctx_t *, lmshare_list_t *);
+void smb_dr_put_lmshr_list(smb_dr_ctx_t *, lmshare_list_t *);
+
+void lmshrd_door_close(void);
#ifdef __cplusplus
}
diff --git a/usr/src/uts/common/smbsrv/lsalib.h b/usr/src/uts/common/smbsrv/lsalib.h
index ae4076bf10..535fc9d62b 100644
--- a/usr/src/uts/common/smbsrv/lsalib.h
+++ b/usr/src/uts/common/smbsrv/lsalib.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -50,31 +50,8 @@ extern "C" {
/*
* lsalib.c
*/
-int lsa_lookup_builtin_name(char *account_name,
- smb_userinfo_t *user_info);
-
-int lsa_lookup_local_sam(char *domain,
- char *account_name,
- smb_userinfo_t *user_info);
-
-int lsa_lookup_local(char *name,
- smb_userinfo_t *user_info);
-
-int lsa_lookup_name(char *server,
- char *domain,
- char *account_name,
- smb_userinfo_t *user_info);
-
-DWORD lsa_lookup_name2(char *server,
- char *domain,
- char *account_name,
- smb_userinfo_t *user_info);
-
-int lsa_lookup_sid(nt_sid_t *sid,
- smb_userinfo_t *user_info);
-
-DWORD lsa_lookup_sid2(nt_sid_t *sid,
- smb_userinfo_t *user_info);
+uint32_t lsa_lookup_name(char *, char *, uint16_t, smb_userinfo_t *);
+uint32_t lsa_lookup_sid(nt_sid_t *, smb_userinfo_t *);
int lsa_lookup_privs(char *server,
char *account_name,
@@ -111,11 +88,11 @@ int lsar_query_security_desc(mlsvc_handle_t *lsa_handle);
DWORD lsar_query_info_policy(mlsvc_handle_t *lsa_handle, WORD infoClass);
-int lsar_lookup_names(mlsvc_handle_t *lsa_handle,
+uint32_t lsar_lookup_names(mlsvc_handle_t *lsa_handle,
char *name,
smb_userinfo_t *user_info);
-int lsar_lookup_sids(mlsvc_handle_t *lsa_handle,
+uint32_t lsar_lookup_sids(mlsvc_handle_t *lsa_handle,
struct mslsa_sid *sid,
smb_userinfo_t *user_info);
@@ -145,11 +122,11 @@ DWORD lsar_lookup_priv_display_name(mlsvc_handle_t *lsa_handle,
char *display_name,
int display_len);
-DWORD lsar_lookup_sids2(mlsvc_handle_t *lsa_handle,
+uint32_t lsar_lookup_sids2(mlsvc_handle_t *lsa_handle,
struct mslsa_sid *sid,
smb_userinfo_t *user_info);
-DWORD lsar_lookup_names2(mlsvc_handle_t *lsa_handle,
+uint32_t lsar_lookup_names2(mlsvc_handle_t *lsa_handle,
char *name,
smb_userinfo_t *user_info);
diff --git a/usr/src/uts/common/smbsrv/mlrpc.h b/usr/src/uts/common/smbsrv/mlrpc.h
index 59ea5536fd..ff4d52254c 100644
--- a/usr/src/uts/common/smbsrv/mlrpc.h
+++ b/usr/src/uts/common/smbsrv/mlrpc.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -213,6 +213,21 @@ typedef struct mlrpc_service {
} mlrpc_service_t;
/*
+ * 20-byte opaque id used by various RPC services.
+ */
+typedef struct ndr_hdid {
+ uint32_t data[5];
+} ndr_hdid_t;
+
+typedef struct ndr_handle {
+ struct ndr_handle *nh_next;
+ ndr_hdid_t nh_id;
+ int nh_fid;
+ const mlrpc_service_t *nh_svc;
+ void *nh_data;
+} ndr_handle_t;
+
+/*
* The list of bindings is anchored at a connection. Nothing in the
* RPC mechanism allocates them. Binding elements which have service==0
* indicate free elements. When a connection is instantiated, at least
@@ -342,7 +357,8 @@ int mlrpc_heap_avail(mlrpc_heap_t *);
#define MLRPC_HEAP_STRSAVE(MXA, STR) \
mlrpc_heap_strsave((MXA)->heap, (STR))
-struct mlrpc_xaction {
+typedef struct mlrpc_xaction {
+ int fid;
unsigned short ptype; /* just handy, hi bits spcl */
unsigned short opnum; /* for requests */
struct mlndr_stream recv_mlnds;
@@ -353,7 +369,7 @@ struct mlrpc_xaction {
struct mlrpc_binding *binding_list; /* from connection */
mlrpc_heap_t *heap;
struct mlsvc_rpc_context *context;
-};
+} ndr_xa_t;
struct mlrpc_client {
int (*xa_init)(struct mlrpc_client *, struct mlrpc_xaction *,
@@ -371,16 +387,16 @@ struct mlrpc_client {
unsigned next_p_cont_id;
};
-/* mlndo.c */
+/* ndr_ops.c */
int mlnds_initialize(struct mlndr_stream *, unsigned, int, mlrpc_heap_t *);
void mlnds_destruct(struct mlndr_stream *);
-/* mlrpc_client.c */
+/* ndr_client.c */
int mlrpc_c_bind(struct mlrpc_client *, char *, struct mlrpc_binding **);
int mlrpc_c_call(struct mlrpc_binding *, int, void *, mlrpc_heapref_t *);
void mlrpc_c_free_heap(struct mlrpc_binding *, mlrpc_heapref_t *);
-/* mlrpc_encdec.c */
+/* ndr_marshal.c */
int mlrpc_encode_decode_common(struct mlrpc_xaction *, int, unsigned,
struct ndr_typeinfo *, void *);
int mlrpc_decode_call(struct mlrpc_xaction *, void *);
@@ -392,24 +408,30 @@ int mlrpc_encode_pdu_hdr(struct mlrpc_xaction *);
void mlrpc_decode_frag_hdr(struct mlndr_stream *, mlrpcconn_common_header_t *);
unsigned mlrpc_bind_ack_hdr_size(struct mlrpcconn_bind_ack_hdr *);
-/* mlrpc_server.c */
+/* ndr_server.c */
int mlrpc_generic_call_stub(struct mlrpc_xaction *);
-/* mlrpc_svc.c */
-struct mlrpc_stub_table *mlrpc_find_stub_in_svc(struct mlrpc_service *, int);
-struct mlrpc_service *mlrpc_find_service_by_name(const char *);
-struct mlrpc_service *mlrpc_find_service_by_uuids(mlrpc_uuid_t *, int,
- mlrpc_uuid_t *, int);
-int mlrpc_register_service(struct mlrpc_service *);
-void mlrpc_unregister_service(struct mlrpc_service *);
-void mlrpc_uuid_to_str(mlrpc_uuid_t *, char *);
-int mlrpc_str_to_uuid(char *, mlrpc_uuid_t *);
+/* ndr_svc.c */
+struct mlrpc_stub_table *mlrpc_find_stub_in_svc(mlrpc_service_t *, int);
+mlrpc_service_t *mlrpc_find_service_by_name(const char *);
+mlrpc_service_t *mlrpc_find_service_by_uuids(ndr_uuid_t *, int,
+ ndr_uuid_t *, int);
+int mlrpc_register_service(mlrpc_service_t *);
+void mlrpc_unregister_service(mlrpc_service_t *);
+void mlrpc_uuid_to_str(ndr_uuid_t *, char *);
+int mlrpc_str_to_uuid(char *, ndr_uuid_t *);
void mlrpc_binding_pool_initialize(struct mlrpc_binding **,
struct mlrpc_binding pool[], unsigned);
struct mlrpc_binding *mlrpc_find_binding(struct mlrpc_xaction *,
mlrpc_p_context_id_t);
struct mlrpc_binding *mlrpc_new_binding(struct mlrpc_xaction *);
+ndr_hdid_t *ndr_hdalloc(const ndr_xa_t *, const void *);
+void ndr_hdfree(const ndr_xa_t *, const ndr_hdid_t *);
+ndr_handle_t *ndr_hdlookup(const ndr_xa_t *, const ndr_hdid_t *);
+void ndr_hdclose(int fid);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/uts/common/smbsrv/mlsvc.h b/usr/src/uts/common/smbsrv/mlsvc.h
index 6177d9fbaf..a85066fc9f 100644
--- a/usr/src/uts/common/smbsrv/mlsvc.h
+++ b/usr/src/uts/common/smbsrv/mlsvc.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -152,17 +152,10 @@ char *mlsvc_ipc_name(int ipc_type, char *username);
* the encrypted passwords.
*/
-int mlsvc_logon(char *domain_controller, char *domain_name,
- char *username);
-int mlsvc_echo(char *server);
-int mlsvc_open_pipe(char *hostname, char *domain, char *username,
- char *pipename);
-int mlsvc_close_pipe(int fid);
void mlsvc_nt_password_hash(char *result, char *password);
int mlsvc_encrypt_nt_password(char *password, char *key, int keylen, char *out,
int outmax);
DWORD mlsvc_join(char *server, char *domain, char *username, char *password);
-int mlsvc_locate_domain_controller(char *domain);
/*
* RPC request processing interface (mlsvc_server.c).
@@ -198,16 +191,8 @@ typedef struct mlsvc_pipe {
struct mlsvc_rpc_context *mlrpc_process(int, smb_dr_user_ctx_t *);
struct mlsvc_rpc_context *mlrpc_lookup(int fid);
void mlrpc_release(int);
-int mlsvc_session_native_values(int fid, int *remote_os, int *remote_lm,
- int *pdc_type);
void mlsvc_rpc_report_status(int opnum, DWORD status);
-/*
- * This is a temporary location for this NETLOGON stuff.
- */
-typedef int (*mlsvc_locate_pdc_t)(char *domain);
-void mlsvc_install_pdc_cb(mlsvc_locate_pdc_t locate_pdc_cb);
-
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/uts/common/smbsrv/mlsvc_util.h b/usr/src/uts/common/smbsrv/mlsvc_util.h
index e9ababec15..24e6bdd1a9 100644
--- a/usr/src/uts/common/smbsrv/mlsvc_util.h
+++ b/usr/src/uts/common/smbsrv/mlsvc_util.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -48,72 +48,12 @@
extern "C" {
#endif
-/*
- * Predefined global RIDs.
- */
-#define MLSVC_DOMAIN_GROUP_RID_ADMINS 0x00000200L
-#define MLSVC_DOMAIN_GROUP_RID_USERS 0x00000201L
-#define MLSVC_DOMAIN_GROUP_RID_GUESTS 0x00000202L
-#define MLSVC_DOMAIN_GROUP_RID_COMPUTERS 0x00000203L
-#define MLSVC_DOMAIN_GROUP_RID_CONTROLLERS 0x00000204L
-#define MLSVC_DOMAIN_GROUP_RID_CERT_ADMINS 0x00000205L
-#define MLSVC_DOMAIN_GROUP_RID_SCHEMA_ADMINS 0x00000206L
-
-/*
- * Predefined local alias RIDs.
- */
-#define MLSVC_LOCAL_GROUP_RID_ADMINS 0x00000220L
-#define MLSVC_LOCAL_GROUP_RID_USERS 0x00000221L
-#define MLSVC_LOCAL_GROUP_RID_GUESTS 0x00000222L
-#define MLSVC_LOCAL_GROUP_RID_POWER_USERS 0x00000223L
-#define MLSVC_LOCAL_GROUP_RID_ACCOUNT_OPS 0x00000224L
-#define MLSVC_LOCAL_GROUP_RID_SERVER_OPS 0x00000225L
-#define MLSVC_LOCAL_GROUP_RID_PRINT_OPS 0x00000226L
-#define MLSVC_LOCAL_GROUP_RID_BACKUP_OPS 0x00000227L
-#define MLSVC_LOCAL_GROUP_RID_REPLICATOR 0x00000228L
-
-/*
- * All predefined local group RIDs belong
- * to a special domain called BUILTIN.
- */
-#define MLSVC_BUILTIN_DOMAIN_NAME "BUILTIN"
-#define MLSVC_BUILTIN_DOMAIN_SIDSTRLEN 8
-
-/*
- * Universal and NT well-known SIDs
- */
-#define MLSVC_NULL_SIDSTR "S-1-0-0"
-#define MSLVC_WORLD_SIDSTR "S-1-1-0"
-#define MSLVC_LOCAL_SIDSTR "S-1-2-0"
-#define MSLVC_CREATOR_OWNER_ID_SIDSTR "S-1-3-0"
-#define MSLVC_CREATOR_GROUP_ID_SIDSTR "S-1-3-1"
-#define MSLVC_CREATOR_OWNER_SERVER_ID_SIDSTR "S-1-3-2"
-#define MSLVC_CREATOR_GROUP_SERVER_ID_SIDSTR "S-1-3-3"
-#define MSLVC_NON_UNIQUE_IDS_SIDSTR "S-1-4"
-#define MLSVC_NT_AUTHORITY_SIDSTR "S-1-5"
-#define MLSVC_DIALUP_SIDSTR "S-1-5-1"
-#define MLSVC_NETWORK_SIDSTR "S-1-5-2"
-#define MLSVC_BATCH_SIDSTR "S-1-5-3"
-#define MLSVC_INTERACTIVE_SIDSTR "S-1-5-4"
-#define MLSVC_SERVICE_SIDSTR "S-1-5-6"
-#define MLSVC_ANONYMOUS_LOGON_SIDSTR "S-1-5-7"
-#define MLSVC_PROXY_SIDSTR "S-1-5-8"
-#define MLSVC_SERVER_LOGON_SIDSTR "S-1-5-9"
-#define MLSVC_SELF_SIDSTR "S-1-5-10"
-#define MLSVC_AUTHENTICATED_USER_SIDSTR "S-1-5-11"
-#define MLSVC_RESTRICTED_CODE_SIDSTR "S-1-5-12"
-#define MLSVC_NT_LOCAL_SYSTEM_SIDSTR "S-1-5-18"
-#define MLSVC_NT_NON_UNIQUE_SIDSTR "S-1-5-21"
-#define MLSVC_BUILTIN_DOMAIN_SIDSTR "S-1-5-32"
-
-int mlsvc_lookup_name(char *domain, char *name, nt_sid_t **sid);
-int mlsvc_lookup_sid(nt_sid_t *sid, char *buf, int bufsize);
-
smb_userinfo_t *mlsvc_alloc_user_info(void);
void mlsvc_free_user_info(smb_userinfo_t *user_info);
void mlsvc_release_user_info(smb_userinfo_t *user_info);
void mlsvc_setadmin_user_info(smb_userinfo_t *user_info);
char *mlsvc_sid_name_use(unsigned int snu_id);
+extern int mlsvc_is_local_domain(const char *);
/*
* The definition of a local unique id (LUID). This is an opaque id
@@ -148,38 +88,6 @@ typedef struct ms_handle {
} ms_handle_t;
/*
- * List of interface specifications: can be used to identify the
- * sub-system to which a handle is assigned. The handle management
- * library doesn't check or care about the ifspec value.
- */
-typedef enum ms_ifspec {
- MLSVC_IFSPEC_NULL,
- MLSVC_IFSPEC_LSAR,
- MLSVC_IFSPEC_SAMR,
- MLSVC_IFSPEC_WINREG,
- MLSVC_IFSPEC_SVCCTL,
- MLSVC_IFSPEC_SPOOLSS,
- MLSVC_IFSPEC_LOGR,
- MLSVC_IFSPEC_LLSR,
- MLSVC_NUM_IFSPECS
-} ms_ifspec_t;
-
-#define MLSVC_HANDLE_KEY_MAX 32
-
-typedef struct ms_handle_desc {
- struct ms_handle_desc *next;
- ms_handle_t handle;
- ms_ifspec_t ifspec;
- char key[MLSVC_HANDLE_KEY_MAX];
- DWORD discrim;
-} ms_handle_desc_t;
-
-ms_handle_t *mlsvc_get_handle(ms_ifspec_t ifspec, char *key, DWORD discrim);
-int mlsvc_put_handle(ms_handle_t *handle);
-int mlsvc_validate_handle(ms_handle_t *handle, char *key);
-ms_handle_desc_t *mlsvc_lookup_handle(ms_handle_t *handle);
-
-/*
* The mlsvc_rpc_context structure provides the connection binding context
* for client RPC calls. This space must be provided by the client library
* for use by the underlying RPC library. Note that we need two binding
@@ -217,11 +125,6 @@ struct mlsvc_rpc_context {
* The context contains a pointer to the top level handle for the
* interface, which is assigned during the bind. It's used when closing
* to detect when to free the context.
- *
- * I know this is really tacky but the elements in the descriptor are
- * arranged so that a handle can be overlaid directly onto a descriptor.
- * I probably won't do this but now you know - just in case you see it
- * in the code.
*/
typedef struct mlsvc_rpc_desc {
ms_handle_t handle;
diff --git a/usr/src/uts/common/smbsrv/ndl/rpcpdu.ndl b/usr/src/uts/common/smbsrv/ndl/rpcpdu.ndl
index fd42fcac1c..596329a521 100644
--- a/usr/src/uts/common/smbsrv/ndl/rpcpdu.ndl
+++ b/usr/src/uts/common/smbsrv/ndl/rpcpdu.ndl
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -46,7 +46,7 @@
* UUID (Universal Unique IDentifier)
*/
/* (X/Open CAE Spec Appendix A) */
-struct mlrpc_uuid_dce {
+struct ndr_dce_uuid {
DWORD time_low;
WORD time_mid;
WORD time_hi_and_version;
@@ -55,13 +55,13 @@ struct mlrpc_uuid_dce {
BYTE node[6];
};
-struct mlrpc_uuid {
+struct ndr_uuid {
DWORD data1;
WORD data2;
WORD data3;
BYTE data4[8];
};
-typedef struct mlrpc_uuid mlrpc_uuid_t;
+typedef struct ndr_uuid ndr_uuid_t;
/*
* Representation label -- needed for RPC header
@@ -171,7 +171,7 @@ typedef WORD mlrpc_p_context_id_t;
_NO_REORDER_
struct mlrpc_p_syntax_id {
- mlrpc_uuid_t if_uuid;
+ ndr_uuid_t if_uuid;
DWORD if_version;
};
typedef struct mlrpc_p_syntax_id mlrpc_p_syntax_id_t;
@@ -182,7 +182,7 @@ struct mlrpc_p_cont_elem {
BYTE n_transfer_syn;
BYTE _reserved;
mlrpc_p_syntax_id_t abstract_syntax;
- /*SIZE_IS(n_transfer_syn)*/
+ /*SIZE_IS(n_transfer_syn)*/
mlrpc_p_syntax_id_t transfer_syntaxes[1];
};
typedef struct mlrpc_p_cont_elem mlrpc_p_cont_elem_t;
@@ -193,7 +193,7 @@ struct mlrpc_p_cont_list {
BYTE n_context_elem;
BYTE _reserved;
WORD _reserved2;
- /*SIZE_IS(n_context_elem)*/
+ /*SIZE_IS(n_context_elem)*/
mlrpc_p_cont_elem_t p_cont_elem[1];
};
typedef struct mlrpc_p_cont_list mlrpc_p_cont_list_t;
@@ -226,7 +226,7 @@ struct mlrpc_p_result_list {
BYTE n_results;
BYTE reserved;
WORD reserved2;
- /*SIZE_IS(n_results)*/
+ /*SIZE_IS(n_results)*/
mlrpc_p_result_t p_results[1];
};
typedef struct mlrpc_p_result_list mlrpc_p_result_list_t;
@@ -236,10 +236,10 @@ EXTERNTYPEINFO(mlrpc_p_result_list)
_NO_REORDER_
struct mlrpc_port_any {
WORD length; /* always 18 */
- /*SIZE_IS(length)*/
+ /*SIZE_IS(length)*/
BYTE port_spec[MLRPC_PORT_ANY_MAX_PORT_SPEC];
- /* \PIPE\ntsvcs */
- /* We cheat by using 18, and pad on the right with zeroes */
+ /* \PIPE\ntsvcs */
+ /* We cheat by using 18, and pad on the right with zeroes */
};
typedef struct mlrpc_port_any mlrpc_port_any_t;
EXTERNTYPEINFO(mlrpc_port_any)
@@ -377,15 +377,15 @@ _NO_REORDER_
struct mlrpcconn_request_hdr {
mlrpcconn_common_header_t common_hdr; /* 00:16 (see above) */
- /* needed for request, response, or fault */
+ /* needed for request, response, or fault */
DWORD alloc_hint; /* 16:04 allocation hint */
mlrpc_p_context_id_t
p_cont_id; /* 20:02 pres context, i.e. data rep */
WORD opnum; /* 22:02 op number w/i interface */
- /* optional field if PFC_OBJECT_UUID, not present */
- /* mlrpc_uuid_t object; */
+ /* optional field if PFC_OBJECT_UUID, not present */
+ /* ndr_uuid_t object; */
/* stub-data, 8-octet aligned */ /* 24:nn */
/* nn = frag_len - sizeof(common_header) - auth_len */
@@ -399,19 +399,19 @@ _NO_REORDER_
struct mlrpcconn_request_hdr_with_object {
mlrpcconn_common_header_t common_hdr; /* 00:16 (see above) */
- /* needed for request, response, or fault */
+ /* needed for request, response, or fault */
DWORD alloc_hint; /* 16:04 allocation hint */
mlrpc_p_context_id_t
p_cont_id; /* 20:02 pres context, i.e. data rep */
WORD opnum; /* 22:02 op number w/i interface */
- /* optional field if PFC_OBJECT_UUID, is present */
- mlrpc_uuid_t object; /* 24:16 object UUID, unknown purpose*/
+ /* optional field if PFC_OBJECT_UUID, is present */
+ ndr_uuid_t object; /* 24:16 object UUID, unknown purpose*/
/* stub-data, 8-octet aligned */ /* 28:nn */
/* nn = frag_len - sizeof(common_header) - auth_len */
- /* nn -= sizeof(mlrpc_uuid_t); */
+ /* nn -= sizeof(ndr_uuid_t); */
/* optional authentication verifier iff auth_length != 0 */
/* auth_verifier_co_t auth_verifier; */
@@ -435,12 +435,12 @@ _NO_REORDER_
struct mlrpcconn_response_hdr {
mlrpcconn_common_header_t common_hdr; /* 00:16 (see above) */
- /* needed for request, response, or fault */
+ /* needed for request, response, or fault */
DWORD alloc_hint; /* 16:04 allocation hint */
mlrpc_p_context_id_t
p_cont_id; /* 20:02 pres context, i.e. data rep */
- /* needed for response or fault */
+ /* needed for response or fault */
BYTE cancel_count; /* 22:01 cancel count */
BYTE reserved; /* 23:01 mbz */
@@ -467,17 +467,17 @@ struct mlrpcconn_fault_hdr {
mlrpc_p_context_id_t
p_cont_id; /* 20:02 pres context, i.e. data rep */
- /* needed for response or fault */
+ /* needed for response or fault */
BYTE cancel_count; /* 22:01 cancel count */
BYTE reserved; /* 23:01 mbz */
- /* fault code */
+ /* fault code */
DWORD status; /* 24:04 run-time fault code or 0 */
- /* pad to 8-byte alignment */
+ /* pad to 8-byte alignment */
BYTE reserved2[4]; /* 28:04 must-be-zero */
- /* stub-data here if status==0. We do not use this mode. */
+ /* stub-data here if status==0. We do not use this mode. */
/* optional authentication verifier iff auth_length != 0 */
/* auth_verifier_co_t auth_verifier; */
diff --git a/usr/src/uts/common/smbsrv/ndl/winreg.ndl b/usr/src/uts/common/smbsrv/ndl/winreg.ndl
index 2d3d1de28d..b1a02a858b 100644
--- a/usr/src/uts/common/smbsrv/ndl/winreg.ndl
+++ b/usr/src/uts/common/smbsrv/ndl/winreg.ndl
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,7 +34,10 @@
#include "ndrtypes.ndl"
+#define WINREG_OPNUM_OpenHKCR 0x00
+#define WINREG_OPNUM_OpenHKCU 0x01
#define WINREG_OPNUM_OpenHKLM 0x02
+#define WINREG_OPNUM_OpenHKPD 0x03
#define WINREG_OPNUM_OpenHKUsers 0x04
#define WINREG_OPNUM_Close 0x05
#define WINREG_OPNUM_CreateKey 0x06
@@ -44,34 +47,40 @@
#define WINREG_OPNUM_EnumValue 0x0a
#define WINREG_OPNUM_FlushKey 0x0b
#define WINREG_OPNUM_GetKeySec 0x0c
+#define WINREG_OPNUM_LoadKey 0x0d
+#define WINREG_OPNUM_NotifyChange 0x0e
#define WINREG_OPNUM_OpenKey 0x0f
#define WINREG_OPNUM_QueryKey 0x10
#define WINREG_OPNUM_QueryValue 0x11
+#define WINREG_OPNUM_ReplaceKey 0x12
+#define WINREG_OPNUM_RestoreKey 0x13
+#define WINREG_OPNUM_SaveKey 0x14
#define WINREG_OPNUM_SetKeySec 0x15
#define WINREG_OPNUM_CreateValue 0x16
+#define WINREG_OPNUM_UnloadKey 0x17
#define WINREG_OPNUM_Shutdown 0x18
+#define WINREG_OPNUM_AbortShutdown 0x19
#define WINREG_OPNUM_GetVersion 0x1a
-
-struct msreg_handle {
+struct winreg_handle {
DWORD hand1;
DWORD hand2;
WORD hand3[2];
BYTE hand4[8];
};
-typedef struct msreg_handle msreg_handle_t;
+typedef struct winreg_handle winreg_handle_t;
-struct msreg_string_desc {
+struct winreg_string_desc {
WORD length;
WORD allosize;
LPTSTR str;
};
-typedef struct msreg_string_desc msreg_string_t;
+typedef struct winreg_string_desc winreg_string_t;
/*
* Fake Varying/Conformant with a funny conformant.
*/
-struct msreg_value {
+struct winreg_value {
DWORD vc_first_is; /* 0 */
DWORD vc_length_is;
SIZE_IS(vc_length_is)
@@ -84,37 +93,59 @@ struct file_time {
};
typedef struct file_time file_time_t;
+OPERATION(WINREG_OPNUM_OpenHKCR)
+struct winreg_OpenHKCR {
+ IN DWORD *server;
+ IN DWORD access_mask;
+ OUT winreg_handle_t handle;
+ OUT DWORD status;
+};
+
+OPERATION(WINREG_OPNUM_OpenHKCU)
+struct winreg_OpenHKCU {
+ IN DWORD *server;
+ IN DWORD access_mask;
+ OUT winreg_handle_t handle;
+ OUT DWORD status;
+};
OPERATION(WINREG_OPNUM_OpenHKLM)
-struct msreg_OpenHKLM {
- IN BYTE whatever[8];
+struct winreg_OpenHKLM {
+ IN DWORD *server;
IN DWORD access_mask;
- OUT msreg_handle_t handle;
+ OUT winreg_handle_t handle;
OUT DWORD status;
};
+OPERATION(WINREG_OPNUM_OpenHKPD)
+struct winreg_OpenHKPD {
+ IN DWORD *server;
+ IN DWORD access_mask;
+ OUT winreg_handle_t handle;
+ OUT DWORD status;
+};
OPERATION(WINREG_OPNUM_OpenHKUsers)
-struct msreg_OpenHKUsers {
- IN BYTE whatever[8];
+struct winreg_OpenHKUsers {
+ IN DWORD *server;
IN DWORD access_mask;
- OUT msreg_handle_t handle;
+ OUT winreg_handle_t handle;
OUT DWORD status;
};
OPERATION(WINREG_OPNUM_Close)
-struct msreg_Close {
- IN msreg_handle_t handle;
- OUT msreg_handle_t result_handle;
+struct winreg_Close {
+ IN winreg_handle_t handle;
+ OUT winreg_handle_t result_handle;
OUT DWORD status;
};
OPERATION(WINREG_OPNUM_CreateKey)
-struct msreg_CreateKey {
- IN msreg_handle_t handle;
- IN msreg_string_t subkey;
+struct winreg_CreateKey {
+ IN winreg_handle_t handle;
+ IN winreg_string_t subkey;
/* IN ignore the remaining input data */
OUT DWORD status;
@@ -122,9 +153,9 @@ struct msreg_CreateKey {
OPERATION(WINREG_OPNUM_DeleteKey)
-struct msreg_DeleteKey {
- IN msreg_handle_t handle;
- IN msreg_string_t subkey;
+struct winreg_DeleteKey {
+ IN winreg_handle_t handle;
+ IN winreg_string_t subkey;
/* IN ignore the remaining input data */
OUT DWORD status;
@@ -132,9 +163,9 @@ struct msreg_DeleteKey {
OPERATION(WINREG_OPNUM_DeleteValue)
-struct msreg_DeleteValue {
- IN msreg_handle_t handle;
- IN msreg_string_t name;
+struct winreg_DeleteValue {
+ IN winreg_handle_t handle;
+ IN winreg_string_t name;
/* IN ignore the remaining input data */
OUT DWORD status;
@@ -146,27 +177,48 @@ struct msreg_DeleteValue {
* as IN parameters but we can ignore them.
*/
OPERATION(WINREG_OPNUM_EnumValue)
-struct msreg_EnumValue {
- IN msreg_handle_t handle;
- IN DWORD index;
+struct winreg_EnumValue {
+ IN winreg_handle_t handle;
+ IN DWORD index;
/* IN ignore the remaining input data */
- OUT msreg_string_t name;
+ OUT winreg_string_t name;
OUT DWORD *type;
- OUT struct msreg_value *value;
+ OUT struct winreg_value *value;
OUT DWORD *value_size;
OUT DWORD *value_size_total;
OUT DWORD status;
};
+OPERATION(WINREG_OPNUM_FlushKey)
+struct winreg_FlushKey {
+ IN winreg_handle_t handle;
+ OUT DWORD status;
+};
+
+OPERATION(WINREG_OPNUM_GetKeySec)
+struct winreg_GetKeySec {
+ IN winreg_handle_t handle;
+ IN DWORD sec_info;
+ OUT DWORD *sd;
+ OUT DWORD status;
+};
+
+OPERATION(WINREG_OPNUM_NotifyChange)
+struct winreg_NotifyChange {
+ IN winreg_handle_t handle;
+ IN DWORD watch_subtree;
+ IN DWORD notify_filter;
+ OUT DWORD status;
+};
OPERATION(WINREG_OPNUM_OpenKey)
-struct msreg_OpenKey {
- IN msreg_handle_t handle;
- IN msreg_string_t name;
+struct winreg_OpenKey {
+ IN winreg_handle_t handle;
+ IN winreg_string_t name;
IN DWORD unknown;
IN DWORD access_mask;
- OUT msreg_handle_t result_handle;
+ OUT winreg_handle_t result_handle;
OUT DWORD status;
};
@@ -183,14 +235,14 @@ struct msreg_OpenKey {
*/
OPERATION(WINREG_OPNUM_QueryKey)
-struct msreg_QueryKey {
- IN msreg_handle_t handle;
+struct winreg_QueryKey {
+ IN winreg_handle_t handle;
/*
* Ignore the remaining input data
- * (2 * DWORD, possibly msreg_string_t).
+ * (2 * DWORD, possibly winreg_string_t).
*/
- OUT msreg_string_t name;
+ OUT winreg_string_t name;
OUT DWORD unknown;
OUT DWORD sub_keys;
OUT DWORD max_subkey_len;
@@ -209,23 +261,31 @@ struct msreg_QueryKey {
* as IN parameters but we can ignore them.
*/
OPERATION(WINREG_OPNUM_QueryValue)
-struct msreg_QueryValue {
- IN msreg_handle_t handle;
- IN msreg_string_t value_name;
+struct winreg_QueryValue {
+ IN winreg_handle_t handle;
+ IN winreg_string_t value_name;
/* IN ignore the remaining input data */
OUT DWORD *type;
- OUT struct msreg_value *value;
+ OUT struct winreg_value *value;
OUT DWORD *value_size;
OUT DWORD *value_size_total;
OUT DWORD status;
};
+OPERATION(WINREG_OPNUM_SetKeySec)
+struct winreg_SetKeySec {
+ IN winreg_handle_t handle;
+ IN DWORD access_mask;
+ IN DWORD sd;
+ OUT DWORD status;
+};
+
OPERATION(WINREG_OPNUM_CreateValue)
-struct msreg_CreateValue {
- IN msreg_handle_t handle;
- IN msreg_string_t name;
+struct winreg_CreateValue {
+ IN winreg_handle_t handle;
+ IN winreg_string_t name;
/* IN ignore the remaining input data */
OUT DWORD status;
@@ -238,17 +298,17 @@ struct msreg_CreateValue {
* without anything appearing in the log, and return access denied.
*/
OPERATION(WINREG_OPNUM_Shutdown)
-struct msreg_Shutdown {
- IN DWORD ignored;
- OUT DWORD status;
+struct winreg_Shutdown {
+ IN DWORD ignored;
+ OUT DWORD status;
};
OPERATION(WINREG_OPNUM_GetVersion)
-struct msreg_GetVersion {
- IN msreg_handle_t handle;
- OUT DWORD version;
- OUT DWORD status;
+struct winreg_GetVersion {
+ IN winreg_handle_t handle;
+ OUT DWORD version;
+ OUT DWORD status;
};
@@ -257,30 +317,44 @@ struct msreg_GetVersion {
*/
INTERFACE(0)
union winreg_interface {
+ CASE(WINREG_OPNUM_OpenHKCR)
+ struct winreg_OpenHKCR OpenHKCR;
+ CASE(WINREG_OPNUM_OpenHKCU)
+ struct winreg_OpenHKCU OpenHKCU;
CASE(WINREG_OPNUM_OpenHKLM)
- struct msreg_OpenHKLM OpenHKLM;
+ struct winreg_OpenHKLM OpenHKLM;
+ CASE(WINREG_OPNUM_OpenHKPD)
+ struct winreg_OpenHKPD OpenHKPD;
CASE(WINREG_OPNUM_OpenHKUsers)
- struct msreg_OpenHKUsers OpenHKUsers;
+ struct winreg_OpenHKUsers OpenHKUsers;
CASE(WINREG_OPNUM_Close)
- struct msreg_Close Close;
+ struct winreg_Close Close;
CASE(WINREG_OPNUM_CreateKey)
- struct msreg_CreateKey CreateKey;
+ struct winreg_CreateKey CreateKey;
CASE(WINREG_OPNUM_DeleteKey)
- struct msreg_DeleteKey DeleteKey;
+ struct winreg_DeleteKey DeleteKey;
CASE(WINREG_OPNUM_DeleteValue)
- struct msreg_DeleteValue DeleteValue;
+ struct winreg_DeleteValue DeleteValue;
+ CASE(WINREG_OPNUM_FlushKey)
+ struct winreg_FlushKey FlushKey;
+ CASE(WINREG_OPNUM_GetKeySec)
+ struct winreg_GetKeySec GetKeySec;
+ CASE(WINREG_OPNUM_NotifyChange)
+ struct winreg_NotifyChange NotifyChange;
CASE(WINREG_OPNUM_OpenKey)
- struct msreg_OpenKey OpenKey;
+ struct winreg_OpenKey OpenKey;
CASE(WINREG_OPNUM_QueryKey)
- struct msreg_QueryKey QueryKey;
+ struct winreg_QueryKey QueryKey;
CASE(WINREG_OPNUM_QueryValue)
- struct msreg_QueryValue QueryValue;
+ struct winreg_QueryValue QueryValue;
+ CASE(WINREG_OPNUM_SetKeySec)
+ struct winreg_SetKeySec SetKeySec;
CASE(WINREG_OPNUM_CreateValue)
- struct msreg_CreateValue CreateValue;
+ struct winreg_CreateValue CreateValue;
CASE(WINREG_OPNUM_Shutdown)
- struct msreg_Shutdown Shutdown;
+ struct winreg_Shutdown Shutdown;
CASE(WINREG_OPNUM_GetVersion)
- struct msreg_GetVersion GetVersion;
+ struct winreg_GetVersion GetVersion;
};
typedef union winreg_interface winreg_interface_t;
EXTERNTYPEINFO(winreg_interface)
diff --git a/usr/src/uts/common/smbsrv/samlib.h b/usr/src/uts/common/smbsrv/samlib.h
index efec26a922..c38986d1d5 100644
--- a/usr/src/uts/common/smbsrv/samlib.h
+++ b/usr/src/uts/common/smbsrv/samlib.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -55,7 +55,7 @@ DWORD sam_create_trust_account(char *server, char *domain,
smb_auth_info_t *auth);
DWORD sam_create_account(char *server, char *domain_name, char *account_name,
- smb_auth_info_t *auth, DWORD account_flags, smb_userinfo_t *user_info);
+ smb_auth_info_t *auth, DWORD account_flags);
DWORD sam_remove_trust_account(char *server, char *domain);
diff --git a/usr/src/uts/common/smbsrv/smb_door_svc.h b/usr/src/uts/common/smbsrv/smb_door_svc.h
index be8898f42a..6b9b943a6a 100644
--- a/usr/src/uts/common/smbsrv/smb_door_svc.h
+++ b/usr/src/uts/common/smbsrv/smb_door_svc.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -82,20 +82,8 @@ enum smb_dr_opcode_t {
SMB_DR_USER_NONAUTH_LOGON,
SMB_DR_USER_AUTH_LOGOFF,
SMB_DR_USER_LIST,
- SMB_DR_GROUP_ADD,
- SMB_DR_GROUP_DELETE,
- SMB_DR_GROUP_MEMBER_ADD,
- SMB_DR_GROUP_MEMBER_REMOVE,
- SMB_DR_GROUP_COUNT,
- SMB_DR_GROUP_CACHE_SIZE,
- SMB_DR_GROUP_MODIFY,
- SMB_DR_GROUP_PRIV_NUM,
- SMB_DR_GROUP_PRIV_LIST,
- SMB_DR_GROUP_PRIV_GET,
- SMB_DR_GROUP_PRIV_SET,
- SMB_DR_GROUP_LIST,
- SMB_DR_GROUP_MEMBER_LIST,
- SMB_DR_GROUP_MEMBER_COUNT
+ SMB_DR_LOOKUP_SID,
+ SMB_DR_LOOKUP_NAME
};
enum smb_kdr_opcode_t {
diff --git a/usr/src/uts/common/smbsrv/smb_fsops.h b/usr/src/uts/common/smbsrv/smb_fsops.h
index afed8b6637..07e825c24d 100644
--- a/usr/src/uts/common/smbsrv/smb_fsops.h
+++ b/usr/src/uts/common/smbsrv/smb_fsops.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -36,11 +36,15 @@
#include <smbsrv/smbinfo.h>
#include <smbsrv/smb_vops.h>
#include <smbsrv/smbvar.h>
+#include <sys/callb.h>
+#include <sys/flock.h>
#ifdef __cplusplus
extern "C" {
#endif
+extern caller_context_t smb_ct;
+
int smb_fsop_open(smb_ofile_t *of);
int smb_fsop_close(smb_ofile_t *of);
@@ -119,7 +123,13 @@ int smb_fsop_sdread(smb_request_t *, cred_t *, smb_node_t *, smb_fssd_t *);
int smb_fsop_sdwrite(smb_request_t *, cred_t *, smb_node_t *, smb_fssd_t *,
int);
-void smb_get_caller_context(smb_request_t *sr, caller_context_t *ct);
+uint32_t smb_fsop_shrlock(cred_t *cr, smb_node_t *node, uint32_t uniq_fid,
+ uint32_t desired_access, uint32_t share_access);
+
+void smb_fsop_unshrlock(cred_t *cr, smb_node_t *node, uint32_t uniq_fid);
+
+int smb_fsop_frlock(smb_request_t *sr, smb_node_t *node, smb_lock_t *lock,
+ boolean_t unlock);
/*
* Lookup-related flags
diff --git a/usr/src/uts/common/smbsrv/smb_kproto.h b/usr/src/uts/common/smbsrv/smb_kproto.h
index 0b9442bed1..a23b42572c 100644
--- a/usr/src/uts/common/smbsrv/smb_kproto.h
+++ b/usr/src/uts/common/smbsrv/smb_kproto.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -101,10 +101,12 @@ void smb_release_oplock(struct smb_ofile *file, int reason);
uint32_t smb_unlock_range(struct smb_request *, struct smb_node *,
uint64_t, uint64_t);
-void smb_unlock_range_raise_error(smb_request_t *sr, uint32_t ntstatus);
uint32_t smb_lock_range(struct smb_request *, struct smb_ofile *,
uint64_t, uint64_t, uint32_t, uint32_t);
-void smb_lock_range_raise_error(smb_request_t *sr, uint32_t ntstatus);
+void smb_lock_range_error(smb_request_t *, uint32_t);
+
+DWORD smb_range_check(smb_request_t *, cred_t *, smb_node_t *,
+ uint64_t, uint64_t, boolean_t);
int smb_mangle_name(ino64_t fileid, char *name, char *shortname,
char *name83, int force);
@@ -149,31 +151,17 @@ void smbsr_decode_error(struct smb_request *);
void smbsr_encode_error(struct smb_request *);
void smbsr_encode_empty_result(struct smb_request *sr);
-#pragma does_not_return(smbsr_decode_error)
-#pragma does_not_return(smbsr_encode_error)
-
int smbsr_decode_vwv(struct smb_request *sr, char *fmt, ...);
int smbsr_decode_data(struct smb_request *sr, char *fmt, ...);
void smbsr_encode_result(struct smb_request *, int, int, char *, ...);
smb_xa_t *smbsr_lookup_xa(smb_request_t *sr);
void smbsr_send_reply(struct smb_request *);
-void smbsr_raise_cifs_error(struct smb_request *sr, DWORD status,
- int error_class, int error_code);
-
-int smbsr_set_errno(struct smb_request *, int);
-void smbsr_raise_errno(struct smb_request *, int);
-void smbsr_raise_error(struct smb_request *, int, int);
-void smbsr_raise_nt_error(struct smb_request *sr, uint32_t);
-
-#pragma does_not_return(smbsr_raise_cifs_error)
-#pragma does_not_return(smbsr_raise_error)
-#pragma does_not_return(smbsr_raise_nt_error)
-#pragma does_not_return(smbsr_raise_errno)
-
-void smbsr_setup_nt_status(struct smb_request *sr,
- uint32_t severity,
- uint32_t nt_status);
+void smbsr_map_errno(int, smb_error_t *);
+void smbsr_set_error(smb_request_t *, smb_error_t *);
+void smbsr_errno(struct smb_request *, int);
+void smbsr_warn(struct smb_request *, DWORD, uint16_t, uint16_t);
+void smbsr_error(struct smb_request *, DWORD, uint16_t, uint16_t);
int smb_mbc_encode(struct mbuf_chain *mbc, char *fmt, va_list ap);
int smb_mbc_decode(struct mbuf_chain *mbc, char *fmt, va_list ap);
@@ -202,7 +190,7 @@ int smb_component_match(struct smb_request *sr, ino64_t fileid,
struct smb_odir *od, smb_odir_context_t *pc);
int smb_lock_range_access(struct smb_request *, struct smb_node *,
- uint64_t, uint64_t, uint32_t desired_access);
+ uint64_t, uint64_t, boolean_t);
uint32_t smb_decode_sd(struct smb_xa *, smb_sd_t *);
@@ -247,6 +235,17 @@ void smb_node_root_fini();
void smb_node_add_lock(smb_node_t *node, smb_lock_t *lock);
void smb_node_destroy_lock(smb_node_t *node, smb_lock_t *lock);
void smb_node_destroy_lock_by_ofile(smb_node_t *node, smb_ofile_t *file);
+void smb_node_start_crit(smb_node_t *node, krw_t mode);
+void smb_node_end_crit(smb_node_t *node);
+int smb_node_in_crit(smb_node_t *node);
+
+uint32_t smb_node_open_check(smb_node_t *, cred_t *,
+ uint32_t, uint32_t);
+uint32_t smb_node_share_check(smb_node_t *, cred_t *,
+ uint32_t, uint32_t, smb_ofile_t *);
+DWORD smb_node_rename_check(smb_node_t *);
+DWORD smb_node_delete_check(smb_node_t *);
+
uint64_t smb_node_get_size(smb_node_t *node, smb_attr_t *attr);
void smb_node_set_time(struct smb_node *node, timestruc_t *crtime,
timestruc_t *mtime, timestruc_t *atime,
@@ -359,7 +358,6 @@ int smb_stream_parse_name(char *name, char *u_stream_name,
uint32_t smb_get_gmtoff(void);
void smb_set_gmtoff(uint32_t);
-void smb_errmap_unix2smb(int en, smb_error_t *smberr);
DWORD smb_trans2_set_information(struct smb_request *sr,
smb_trans2_setinfo_t *info,
smb_error_t *smberr);
@@ -398,7 +396,8 @@ void smb_session_disconnect_volume(fs_desc_t *);
smb_ofile_t *smb_ofile_lookup_by_fid(smb_tree_t *tree, uint16_t fid);
smb_ofile_t *smb_ofile_open(smb_tree_t *tree, smb_node_t *node, uint16_t pid,
uint32_t access_granted, uint32_t create_options, uint32_t share_access,
- uint16_t ftype, char *pipe_name, uint32_t rpc_fid, smb_error_t *err);
+ uint16_t ftype, char *pipe_name, uint32_t rpc_fid, uint32_t uniqid,
+ smb_error_t *err);
int smb_ofile_close(smb_ofile_t *ofile, uint32_t last_wtime);
uint32_t smb_ofile_access(smb_ofile_t *ofile, cred_t *cr, uint32_t access);
int smb_ofile_seek(smb_ofile_t *of, ushort_t mode, int32_t off,
diff --git a/usr/src/uts/common/smbsrv/smb_privilege.h b/usr/src/uts/common/smbsrv/smb_privilege.h
index c03455d469..9fad667938 100644
--- a/usr/src/uts/common/smbsrv/smb_privilege.h
+++ b/usr/src/uts/common/smbsrv/smb_privilege.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -98,6 +98,7 @@ extern "C" {
#define SE_CHANGE_NOTIFY_NAME "SeChangeNotifyPrivilege"
#define SE_REMOTE_SHUTDOWN_NAME "SeRemoteShutdownPrivilege"
+#define SE_MIN_LUID 2
#define SE_CREATE_TOKEN_LUID 2
#define SE_ASSIGNPRIMARYTOKEN_LUID 3
#define SE_LOCK_MEMORY_LUID 4
@@ -121,6 +122,7 @@ extern "C" {
#define SE_SYSTEM_ENVIRONMENT_LUID 22
#define SE_CHANGE_NOTIFY_LUID 23
#define SE_REMOTE_SHUTDOWN_LUID 24
+#define SE_MAX_LUID 24
/*
* Privilege attributes
@@ -181,6 +183,7 @@ int smb_privset_size();
void smb_privset_init(smb_privset_t *privset);
void smb_privset_free(smb_privset_t *privset);
void smb_privset_copy(smb_privset_t *dst, smb_privset_t *src);
+void smb_privset_merge(smb_privset_t *dst, smb_privset_t *src);
void smb_privset_enable(smb_privset_t *privset, uint32_t id);
int smb_privset_query(smb_privset_t *privset, uint32_t id);
void smb_privset_log(smb_privset_t *privset);
diff --git a/usr/src/uts/common/smbsrv/smb_vops.h b/usr/src/uts/common/smbsrv/smb_vops.h
index 3b09c99b63..0f98b41be5 100644
--- a/usr/src/uts/common/smbsrv/smb_vops.h
+++ b/usr/src/uts/common/smbsrv/smb_vops.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -318,67 +318,53 @@ struct fs_stream_info {
int fhopen(const struct smb_node *, int);
-extern int smb_vop_open(vnode_t **vpp, int mode, cred_t *cred,
- caller_context_t *ct);
-extern int smb_vop_close(vnode_t *vp, int flag, cred_t *cred,
- caller_context_t *ct);
-extern int smb_vop_read(vnode_t *vp, uio_t *uiop, cred_t *cr,
- caller_context_t *ct);
-extern int smb_vop_write(vnode_t *vp, uio_t *uiop, unsigned int *flag,
- uint32_t *lcount, cred_t *cr, caller_context_t *ct);
-extern int smb_vop_getattr(vnode_t *vp, vnode_t *unnamed_vp,
- smb_attr_t *ret_attr, int flags, cred_t *cr, caller_context_t *ct);
-extern int smb_vop_setattr(vnode_t *vp, vnode_t *unnamed_vp,
- smb_attr_t *set_attr, int flags, cred_t *cr, boolean_t no_xvattr,
- caller_context_t *ct);
-extern int smb_vop_access(vnode_t *vp, int mode, int flags, vnode_t *dir_vp,
- cred_t *cr);
-extern void smb_vop_eaccess(vnode_t *vp, int *mode, int flags, vnode_t *dir_vp,
- cred_t *cr);
-extern int smb_vop_lookup(vnode_t *dvp, char *name, vnode_t **vpp,
- char *od_name, int flags, vnode_t *rootvp, cred_t *cr,
- caller_context_t *ct);
-extern int smb_vop_create(vnode_t *dvp, char *name, smb_attr_t *attr,
- vnode_t **vpp, int flags, cred_t *cr, caller_context_t *ct,
- vsecattr_t *vsap);
-extern int smb_vop_remove(vnode_t *dvp, char *name, int flags, cred_t *cr,
- caller_context_t *ct);
-extern int smb_vop_rename(vnode_t *from_dvp, char *from_name, vnode_t *to_dvp,
- char *to_name, int flags, cred_t *cr, caller_context_t *ct);
-extern int smb_vop_mkdir(vnode_t *dvp, char *name, smb_attr_t *attr,
- vnode_t **vpp, int flags, cred_t *cr, caller_context_t *ct,
- vsecattr_t *vsap);
-extern int smb_vop_rmdir(vnode_t *dvp, char *name, int flags, cred_t *cr,
- caller_context_t *ct);
-extern int smb_vop_readdir(vnode_t *dvp, uint32_t *cookiep, char *name,
- int *namelen, ino64_t *inop, vnode_t **vpp, char *od_name, int flags,
- cred_t *cr, caller_context_t *ct);
-extern int smb_vop_commit(vnode_t *vp, cred_t *cr, caller_context_t *ct);
-extern int smb_vop_getdents(struct smb_node *dir_snode, uint32_t *cookiep,
- uint64_t *verifierp, int32_t *dircountp, char *arg, char *pattern,
- uint32_t flags, struct smb_request *sr, cred_t *cr,
- caller_context_t *ct);
-extern int smb_vop_statfs(vnode_t *vp, struct statvfs64 *statp, cred_t *cr);
-extern int smb_vop_stream_lookup(vnode_t *fvp, char *stream_name,
- vnode_t **vpp, char *name, vnode_t **xattrdirvpp, int flags,
- vnode_t *rootvp, cred_t *cr, caller_context_t *ct);
-extern int smb_vop_stream_create(vnode_t *fvp, char *stream_name,
- smb_attr_t *attr, vnode_t **vpp, vnode_t **xattrdirvpp, int flags,
- cred_t *cr, caller_context_t *ct);
-extern int smb_vop_stream_remove(vnode_t *vp, char *stream_name, int flags,
- cred_t *cr, caller_context_t *ct);
-extern int smb_vop_stream_readdir(vnode_t *fvp, uint32_t *cookiep,
- struct fs_stream_info *stream_info, vnode_t **vpp, vnode_t **xattrdirvp,
- int flags, cred_t *cr, caller_context_t *ct);
-extern int smb_vop_lookup_xattrdir(vnode_t *fvp, vnode_t **xattrdirvpp,
- int flags, cred_t *cr, caller_context_t *ct);
-extern int smb_vop_traverse_check(vnode_t **vpp);
-
-int smb_vop_acl_read(vnode_t *vp, acl_t **aclp, int flags, acl_type_t acl_type,
- cred_t *cr, caller_context_t *ct);
-int smb_vop_acl_write(vnode_t *vp, acl_t *aclp, int flags, cred_t *cr,
- caller_context_t *ct);
-acl_type_t smb_vop_acl_type(vnode_t *vp);
+extern void smb_vop_start(void);
+extern int smb_vop_open(vnode_t **, int, cred_t *);
+extern int smb_vop_close(vnode_t *, int, cred_t *);
+extern int smb_vop_read(vnode_t *, uio_t *, cred_t *);
+extern int smb_vop_write(vnode_t *, uio_t *, unsigned int *,
+ uint32_t *, cred_t *);
+extern int smb_vop_getattr(vnode_t *, vnode_t *,
+ smb_attr_t *, int, cred_t *);
+extern int smb_vop_setattr(vnode_t *, vnode_t *,
+ smb_attr_t *, int, cred_t *, boolean_t);
+extern int smb_vop_access(vnode_t *, int, int, vnode_t *,
+ cred_t *);
+extern void smb_vop_eaccess(vnode_t *, int *, int, vnode_t *,
+ cred_t *);
+extern int smb_vop_lookup(vnode_t *, char *, vnode_t **,
+ char *, int, vnode_t *, cred_t *);
+extern int smb_vop_create(vnode_t *, char *, smb_attr_t *,
+ vnode_t **, int, cred_t *, vsecattr_t *);
+extern int smb_vop_remove(vnode_t *, char *, int, cred_t *);
+extern int smb_vop_rename(vnode_t *, char *, vnode_t *,
+ char *, int, cred_t *);
+extern int smb_vop_mkdir(vnode_t *, char *, smb_attr_t *,
+ vnode_t **, int, cred_t *, vsecattr_t *);
+extern int smb_vop_rmdir(vnode_t *, char *, int, cred_t *);
+extern int smb_vop_readdir(vnode_t *, uint32_t *, char *,
+ int *, ino64_t *, vnode_t **, char *, int, cred_t *);
+extern int smb_vop_commit(vnode_t *, cred_t *);
+extern int smb_vop_getdents(struct smb_node *, uint32_t *,
+ uint64_t *, int32_t *, char *, char *,
+ uint32_t, struct smb_request *, cred_t *);
+extern int smb_vop_statfs(vnode_t *, struct statvfs64 *, cred_t *);
+extern int smb_vop_stream_lookup(vnode_t *, char *,
+ vnode_t **, char *, vnode_t **, int, vnode_t *, cred_t *);
+extern int smb_vop_stream_create(vnode_t *, char *,
+ smb_attr_t *, vnode_t **, vnode_t **, int, cred_t *);
+extern int smb_vop_stream_remove(vnode_t *, char *, int, cred_t *);
+extern int smb_vop_stream_readdir(vnode_t *, uint32_t *,
+ struct fs_stream_info *, vnode_t **, vnode_t **, int, cred_t *);
+extern int smb_vop_lookup_xattrdir(vnode_t *, vnode_t **, int, cred_t *);
+extern int smb_vop_traverse_check(vnode_t **);
+
+int smb_vop_acl_read(vnode_t *, acl_t **, int, acl_type_t, cred_t *);
+int smb_vop_acl_write(vnode_t *, acl_t *, int, cred_t *);
+acl_type_t smb_vop_acl_type(vnode_t *);
+
+int smb_vop_shrlock(vnode_t *, uint32_t, uint32_t, uint32_t, cred_t *);
+int smb_vop_unshrlock(vnode_t *, uint32_t, cred_t *);
#ifdef __cplusplus
}
diff --git a/usr/src/uts/common/smbsrv/smbinfo.h b/usr/src/uts/common/smbsrv/smbinfo.h
index 2426b54b61..01404f3a55 100644
--- a/usr/src/uts/common/smbsrv/smbinfo.h
+++ b/usr/src/uts/common/smbsrv/smbinfo.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -127,18 +127,17 @@ typedef struct smb_kmod_cfg {
uint32_t skc_maxworkers;
uint32_t skc_maxconnections;
uint32_t skc_keepalive;
- uint32_t skc_restrict_anon;
- uint32_t skc_signing_enable;
- uint32_t skc_signing_required;
- uint32_t skc_signing_check;
- uint32_t skc_oplock_enable;
uint32_t skc_oplock_timeout;
- uint32_t skc_flush_required;
- uint32_t skc_sync_enable;
- uint32_t skc_dirsymlink_enable;
- uint32_t skc_announce_quota;
- uint32_t skc_secmode;
- uint32_t skc_lmlevel;
+ int32_t skc_restrict_anon;
+ int32_t skc_signing_enable;
+ int32_t skc_signing_required;
+ int32_t skc_signing_check;
+ int32_t skc_oplock_enable;
+ int32_t skc_flush_required;
+ int32_t skc_sync_enable;
+ int32_t skc_dirsymlink_enable;
+ int32_t skc_announce_quota;
+ int32_t skc_secmode;
char skc_resource_domain[SMB_PI_MAX_DOMAIN];
char skc_hostname[SMB_PI_MAX_HOST];
@@ -173,7 +172,6 @@ int smbnative_pdc_value(char *native_lm);
#define SMBD_DOOR_PARAM_GET 2
#define SMBD_DOOR_PARAM_SET 3
#define SMBD_DOOR_NETBIOS_RECONFIG 4
-#define SMBD_DOOR_ADS_DOMAIN_CHANGED 5
#ifdef __cplusplus
}
diff --git a/usr/src/uts/common/smbsrv/smbvar.h b/usr/src/uts/common/smbsrv/smbvar.h
index edcfbe7187..f4e11582a0 100644
--- a/usr/src/uts/common/smbsrv/smbvar.h
+++ b/usr/src/uts/common/smbsrv/smbvar.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -389,6 +389,7 @@ typedef enum {
typedef struct smb_node {
uint32_t n_magic;
smb_rwx_t n_lock;
+ krwlock_t n_share_lock;
list_node_t n_lnd;
smb_node_state_t n_state;
uint32_t n_refcnt;
@@ -835,6 +836,7 @@ typedef struct smb_ofile {
mlsvc_pipe_t *f_pipe_info;
+ uint32_t f_uniqid;
uint32_t f_refcnt;
uint64_t f_seek_pos;
uint32_t f_flags;
@@ -1198,11 +1200,8 @@ struct smb_request {
label_t exjb;
cred_t *user_cr;
- caller_context_t ct;
};
-caller_context_t local_ct;
-
#define SMB_READ_PROTOCOL(smb_nh_ptr) \
LE_IN32(((smb_nethdr_t *)(smb_nh_ptr))->sh_protocol)
@@ -1317,6 +1316,7 @@ typedef struct smb_info {
volatile uint64_t si_global_kid;
volatile uint32_t si_gmtoff;
+ volatile uint32_t si_uniq_fid;
smb_thread_t si_nbt_daemon;
smb_thread_t si_tcp_daemon;
@@ -1354,11 +1354,13 @@ typedef struct smb_info {
#define SMB_INFO_ENCRYPT_PASSWORDS 0x80000000
#define SMB_NEW_KID() atomic_inc_64_nv(&smb_info.si_global_kid)
+#define SMB_UNIQ_FID() atomic_inc_32_nv(&smb_info.si_uniq_fid)
typedef struct {
+ uint32_t severity;
+ uint32_t status;
uint16_t errcls;
uint16_t errcode;
- DWORD status;
} smb_error_t;
/*