summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-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_handle.c179
-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_group_door_encdec.c337
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_group_xdr.c158
-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, 9564 deletions
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_handle.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_handle.c
deleted file mode 100644
index a13b7346f5..0000000000
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_handle.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * 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 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * This module provides the handles used in the various server-side
- * RPC functions. I don't think other systems care about the value in
- * the handle. It should be treated as an opaque data block. Handles
- * are issued when a service is opened and obsoleted when it is closed.
- * We should check incoming RPC requests to ensure that the handle
- * being used is associated with the particular service being accessed.
- */
-
-#include <strings.h>
-#include <unistd.h>
-#include <assert.h>
-
-#include <smbsrv/libsmb.h>
-#include <smbsrv/mlsvc_util.h>
-#include <smbsrv/ntsid.h>
-
-/*
- * Each time a handle is allocated it is added to the global handle
- * descriptor list because we need some way of identifying the
- * interface and domain to which the handle was assigned when it is
- * returned on a subsequent RPC.
- */
-ms_handle_t mlsvc_handle;
-ms_handle_desc_t *mlsvc_desc_list;
-
-/*
- * mlsvc_get_handle
- *
- * This function returns a handle for use with the server-side RPC
- * functions. Every time it is called it will increment the handle
- * value and return a pointer to it. On NT, handle[0] always seems
- * to be zero and handle[1] increments. The rest seems to be some
- * sort of unique value so the local domain SID should do.
- *
- * The handle is added to the global handle descriptor list with the
- * designated ifspec and key tag.
- */
-ms_handle_t *
-mlsvc_get_handle(ms_ifspec_t ifspec, char *key, DWORD discrim)
-{
- ms_handle_desc_t *desc;
- nt_sid_t *sid;
-
- if ((desc = malloc(sizeof (ms_handle_desc_t))) == NULL)
- assert(desc);
-
- sid = nt_domain_local_sid();
- if (mlsvc_handle.handle[1] == 0) {
- mlsvc_handle.handle[0] = 0;
- mlsvc_handle.handle[1] = 0;
- mlsvc_handle.handle[2] = sid->SubAuthority[1];
- mlsvc_handle.handle[3] = sid->SubAuthority[2];
- mlsvc_handle.handle[4] = sid->SubAuthority[3];
- }
-
- ++mlsvc_handle.handle[1];
-
- bcopy(&mlsvc_handle, &desc->handle, sizeof (ms_handle_t));
- desc->ifspec = ifspec;
- desc->discrim = discrim;
- desc->next = mlsvc_desc_list;
- mlsvc_desc_list = desc;
-
- if (key)
- (void) strlcpy(desc->key, key, MLSVC_HANDLE_KEY_MAX);
- else
- desc->key[0] = '\0';
-
- return (&mlsvc_handle);
-}
-
-
-/*
- * mlsvc_put_handle
- *
- * Remove a handle from the global handle descriptor list and free the
- * memory it was using. If the list contained the descriptor, a value
- * of 0 is returned. Otherwise -1 is returned.
- */
-int
-mlsvc_put_handle(ms_handle_t *handle)
-{
- ms_handle_desc_t *desc;
- ms_handle_desc_t **ppdesc = &mlsvc_desc_list;
-
- assert(handle);
-
- while (*ppdesc) {
- desc = *ppdesc;
-
- if (bcmp(&desc->handle, handle, sizeof (ms_handle_t)) == 0) {
- *ppdesc = desc->next;
- free(desc);
- return (0);
- }
-
- ppdesc = &(*ppdesc)->next;
- }
-
- return (-1);
-}
-
-
-/*
- * mlsvc_validate_handle
- *
- * Lookup a handle in the global handle descriptor list. If the handle
- * is in the list, a pointer to the descriptor is returned. Otherwise
- * a null pointer is returned.
- */
-int
-mlsvc_validate_handle(ms_handle_t *handle, char *key)
-{
- ms_handle_desc_t *desc;
-
- assert(handle);
- assert(key);
-
- if ((desc = mlsvc_lookup_handle(handle)) == 0)
- return (NULL);
-
- if (strcmp(desc->key, key))
- return (NULL);
-
- return (1);
-}
-
-
-/*
- * mlsvc_lookup_handle
- *
- * Lookup a handle in the global handle descriptor list. If the handle
- * is in the list, a pointer to the descriptor is returned. Otherwise
- * a null pointer is returned.
- */
-ms_handle_desc_t *
-mlsvc_lookup_handle(ms_handle_t *handle)
-{
- ms_handle_desc_t *desc = mlsvc_desc_list;
-
- assert(handle);
-
- while (desc) {
- if (bcmp(&desc->handle, handle, sizeof (ms_handle_t)) == 0)
- return (desc);
-
- desc = desc->next;
- }
-
- return (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_group_door_encdec.c b/usr/src/lib/smbsrv/libsmb/common/smb_group_door_encdec.c
deleted file mode 100644
index 0b29764926..0000000000
--- a/usr/src/lib/smbsrv/libsmb/common/smb_group_door_encdec.c
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * 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 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <strings.h>
-#include <smbsrv/libsmb.h>
-#include <smbsrv/smb_xdr.h>
-#include <smbsrv/smb_door_svc.h>
-
-/*
- * smb_grplist_mkselfrel
- *
- * encode: structure -> flat buffer (buffer size)
- * Pre-condition: obj is non-null.
- */
-static uint8_t *
-smb_grplist_mkselfrel(ntgrp_list_t *obj, uint32_t *len)
-{
- uint8_t *buf;
- XDR xdrs;
-
- if (!obj) {
- syslog(LOG_ERR, "smb_grplist_mkselfrel: invalid parameter");
- return (NULL);
- }
- *len = xdr_sizeof(xdr_ntgrp_list_t, obj);
- buf = (uint8_t *)malloc(*len);
-
- xdrmem_create(&xdrs, (const caddr_t)buf, *len, XDR_ENCODE);
-
- if (!xdr_ntgrp_list_t(&xdrs, obj)) {
- syslog(LOG_ERR, "smb_grplist_mkselfrel: XDR encode error");
- free(buf);
- *len = 0;
- buf = NULL;
- }
-
- xdr_destroy(&xdrs);
- return (buf);
-}
-
-/*
- * smb_grplist_mkabsolute
- *
- * decode: flat buffer -> structure
- */
-static ntgrp_list_t *
-smb_grplist_mkabsolute(uint8_t *buf, uint32_t len)
-{
- ntgrp_list_t *obj;
- XDR xdrs;
-
- xdrmem_create(&xdrs, (const caddr_t)buf, len, XDR_DECODE);
-
- if ((obj = (ntgrp_list_t *)
- malloc(sizeof (ntgrp_list_t))) == 0) {
- syslog(LOG_ERR, "smb_grplist_mkabsolute: resource shortage");
- xdr_destroy(&xdrs);
- return (NULL);
- }
- bzero(obj, sizeof (ntgrp_list_t));
- if (!xdr_ntgrp_list_t(&xdrs, obj)) {
- syslog(LOG_ERR, "smb_grplist_mkabsolute: XDR decode error");
- smb_group_free_list(obj, 1);
- obj = NULL;
- }
-
- xdr_destroy(&xdrs);
- return (obj);
-}
-
-/*
- * smb_grpmemberlist_mkselfrel
- *
- * encode: structure -> flat buffer (buffer size)
- * Pre-condition: obj is non-null.
- */
-static uint8_t *
-smb_grpmemberlist_mkselfrel(ntgrp_member_list_t *obj, uint32_t *len)
-{
- uint8_t *buf;
- XDR xdrs;
-
- if (!obj) {
- syslog(LOG_ERR,
- "smb_grpmemberlist_mkselfrel: invalid parameter");
- return (NULL);
- }
- *len = xdr_sizeof(xdr_ntgrp_member_list_t, obj);
- buf = (uint8_t *)malloc(*len);
- xdrmem_create(&xdrs, (const caddr_t)buf, *len, XDR_ENCODE);
- if (!xdr_ntgrp_member_list_t(&xdrs, obj)) {
- syslog(LOG_ERR,
- "smb_grpmemberlist_mkselfrel: XDR encode error");
- free(buf);
- *len = 0;
- buf = NULL;
- }
-
- xdr_destroy(&xdrs);
- return (buf);
-}
-
-/*
- * ntgrp_list_mkabsolute
- *
- * decode: flat buffer -> structure
- */
-static ntgrp_member_list_t *
-smb_grpmemberlist_mkabsolute(uint8_t *buf, uint32_t len)
-{
- ntgrp_member_list_t *obj = NULL;
- XDR xdrs;
-
- xdrmem_create(&xdrs, (const caddr_t)buf, len, XDR_DECODE);
-
- if ((obj = (ntgrp_member_list_t *)
- malloc(sizeof (ntgrp_member_list_t))) == 0) {
- xdr_destroy(&xdrs);
- syslog(LOG_ERR,
- "smb_grpmemberlist_mkabsolute: resource shortage");
- return (NULL);
- }
- bzero(obj, sizeof (ntgrp_member_list_t));
- bzero(obj->members, SMB_GROUP_PER_LIST * sizeof (members_list));
- if (!xdr_ntgrp_member_list_t(&xdrs, obj)) {
- syslog(LOG_ERR,
- "smb_grpmemberlist_mkabsolute: XDR decode error");
- smb_group_free_memberlist(obj, 1);
- obj = NULL;
- }
-
- xdr_destroy(&xdrs);
- return (obj);
-}
-
-/*
- * smb_privlist_mkselfrel
- *
- * encode: structure -> flat buffer (buffer size)
- * Pre-condition: obj is non-null.
- */
-static uint8_t *
-smb_grpprivlist_mkselfrel(ntpriv_list_t *obj, uint32_t *len)
-{
- uint8_t *buf;
- XDR xdrs;
-
- if (!obj) {
- syslog(LOG_ERR,
- "smb_grpprivlist_mkselfrel: invalid parameter");
- return (NULL);
- }
- *len = xdr_sizeof(xdr_ntpriv_list_t, obj);
- buf = (uint8_t *)malloc(*len);
- if (!buf) {
- syslog(LOG_ERR,
- "smb_grpprivlist_mkselfrel: resource shortage");
- return (NULL);
- }
- xdrmem_create(&xdrs, (const caddr_t)buf, *len, XDR_ENCODE);
- if (!xdr_ntpriv_list_t(&xdrs, obj)) {
- syslog(LOG_ERR,
- "smb_grpprivlist_mkselfrel: XDR encode error");
- *len = 0;
- free(buf);
- buf = NULL;
- }
- xdr_destroy(&xdrs);
- return (buf);
-}
-
-/*
- * smb_privlist_mkabsolute
- *
- * decode: flat buffer -> structure
- */
-static ntpriv_list_t *
-smb_grpprivlist_mkabsolute(uint8_t *buf, uint32_t len)
-{
- ntpriv_list_t *obj = NULL;
- XDR xdrs;
- uint32_t status;
- int length = 0, num_privs = 0;
-
- xdrmem_create(&xdrs, (const caddr_t)buf, len, XDR_DECODE);
- status = smb_group_priv_num(&num_privs);
- if (status != 0) {
- syslog(LOG_ERR,
- "smb_grpprivlist_mkabsolute: Cannot get privlist.");
- xdr_destroy(&xdrs);
- return (NULL);
- }
-
- if (num_privs > 0) {
- length = sizeof (int) + (num_privs * sizeof (privs_t));
- if ((obj = (ntpriv_list_t *)malloc(length)) == 0) {
- syslog(LOG_ERR,
- "smb_grpprivlist_mkabsolute: resource shortage");
- xdr_destroy(&xdrs);
- return (NULL);
- }
- }
- bzero(obj, sizeof (ntpriv_list_t));
- bzero(obj->privs, num_privs * sizeof (privs_t));
- if (!xdr_ntpriv_list_t(&xdrs, obj)) {
- syslog(LOG_ERR, "smb_grpprivlist_mkabsolute: XDR decode error");
- smb_group_free_privlist(obj, 1);
- obj = NULL;
- }
- xdr_destroy(&xdrs);
- return (obj);
-}
-
-char *
-smb_dr_encode_grp_list(uint32_t opcode, ntgrp_list_t *list,
- size_t *len)
-{
- char *buf;
- smb_dr_bytes_t arg;
-
- arg.bytes_val = smb_grplist_mkselfrel(list, &arg.bytes_len);
-
- buf = smb_dr_encode_common(opcode, &arg, xdr_smb_dr_bytes_t, len);
- free(arg.bytes_val);
- return (buf);
-}
-
-ntgrp_list_t *
-smb_dr_decode_grp_list(char *buf, size_t len)
-{
- smb_dr_bytes_t arg;
- ntgrp_list_t *list;
-
- bzero(&arg, sizeof (smb_dr_bytes_t));
- if (smb_dr_decode_common(buf, len, xdr_smb_dr_bytes_t, &arg)
- != 0) {
- syslog(LOG_ERR, "smb_dr_decode_grplist: XDR decode error");
- xdr_free(xdr_smb_dr_bytes_t, (char *)&arg);
- return (NULL);
- }
- list = smb_grplist_mkabsolute(arg.bytes_val, arg.bytes_len);
- xdr_free(xdr_smb_dr_bytes_t, (char *)&arg);
- return (list);
-}
-
-char *
-smb_dr_encode_grp_memberlist(uint32_t opcode,
- ntgrp_member_list_t *list, size_t *len)
-{
- char *buf;
- smb_dr_bytes_t arg;
-
- arg.bytes_val = smb_grpmemberlist_mkselfrel(list, &arg.bytes_len);
-
- buf = smb_dr_encode_common(opcode, &arg, xdr_smb_dr_bytes_t, len);
- free(arg.bytes_val);
- return (buf);
-}
-
-ntgrp_member_list_t *
-smb_dr_decode_grp_memberlist(char *buf, size_t len)
-{
- smb_dr_bytes_t arg;
- ntgrp_member_list_t *list;
-
- bzero(&arg, sizeof (smb_dr_bytes_t));
- if (smb_dr_decode_common(buf, len, xdr_smb_dr_bytes_t, &arg)
- != 0) {
- syslog(LOG_ERR,
- "smb_dr_decode_grpmemberlist: XDR decode error");
- xdr_free(xdr_smb_dr_bytes_t, (char *)&arg);
- return (NULL);
- }
- list = smb_grpmemberlist_mkabsolute(arg.bytes_val, arg.bytes_len);
- xdr_free(xdr_smb_dr_bytes_t, (char *)&arg);
- return (list);
-}
-
-char *
-smb_dr_encode_grp_privlist(uint32_t opcode,
- ntpriv_list_t *list, size_t *len)
-{
- char *buf;
- smb_dr_bytes_t arg;
-
- arg.bytes_val = smb_grpprivlist_mkselfrel(list, &arg.bytes_len);
-
- buf = smb_dr_encode_common(opcode, &arg, xdr_smb_dr_bytes_t, len);
- free(arg.bytes_val);
- return (buf);
-}
-
-ntpriv_list_t *
-smb_dr_decode_grp_privlist(char *buf, size_t len)
-{
- smb_dr_bytes_t arg;
- ntpriv_list_t *list;
-
- bzero(&arg, sizeof (smb_dr_bytes_t));
- if (smb_dr_decode_common(buf, len, xdr_smb_dr_bytes_t, &arg)
- != 0) {
- syslog(LOG_ERR, "smb_dr_decode_grp_privlist: XDR decode error");
- xdr_free(xdr_smb_dr_bytes_t, (char *)&arg);
- return (NULL);
- }
- list = smb_grpprivlist_mkabsolute(arg.bytes_val, arg.bytes_len);
- xdr_free(xdr_smb_dr_bytes_t, (char *)&arg);
- return (list);
-}
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_group_xdr.c b/usr/src/lib/smbsrv/libsmb/common/smb_group_xdr.c
deleted file mode 100644
index 723a6471f9..0000000000
--- a/usr/src/lib/smbsrv/libsmb/common/smb_group_xdr.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * 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 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <rpc/rpc.h>
-#include <smbsrv/libsmb.h>
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-/*
- * This file was originally generated using rpcgen.
- */
-
-bool_t
-xdr_ntgrp_dr_arg_t(xdrs, objp)
- XDR *xdrs;
- ntgrp_dr_arg_t *objp;
-{
- if (!xdr_string(xdrs, &objp->gname, ~0))
- return (FALSE);
- if (!xdr_string(xdrs, &objp->desc, ~0))
- return (FALSE);
- if (!xdr_string(xdrs, &objp->member, ~0))
- return (FALSE);
- if (!xdr_string(xdrs, &objp->newgname, ~0))
- return (FALSE);
- if (!xdr_uint32_t(xdrs, &objp->privid))
- return (FALSE);
- if (!xdr_uint32_t(xdrs, &objp->priv_attr))
- return (FALSE);
- if (!xdr_int(xdrs, &objp->offset))
- return (FALSE);
- if (!xdr_string(xdrs, &objp->scope, ~0))
- return (FALSE);
- if (!xdr_int(xdrs, &objp->type))
- return (FALSE);
- if (!xdr_int(xdrs, &objp->count))
- return (FALSE);
- if (!xdr_uint32_t(xdrs, &objp->ntstatus))
- return (FALSE);
- return (TRUE);
-}
-
-bool_t
-xdr_ntgrp_t(xdrs, objp)
- XDR *xdrs;
- ntgrp_t *objp;
-{
- if (!xdr_uint32_t(xdrs, &objp->rid))
- return (FALSE);
- if (!xdr_string(xdrs, &objp->name, ~0))
- return (FALSE);
- if (!xdr_string(xdrs, &objp->desc, ~0))
- return (FALSE);
- if (!xdr_string(xdrs, &objp->type, ~0))
- return (FALSE);
- if (!xdr_string(xdrs, &objp->sid, ~0))
- return (FALSE);
- if (!xdr_uint32_t(xdrs, &objp->attr))
- return (FALSE);
- return (TRUE);
-}
-
-bool_t
-xdr_ntgrp_list_t(xdrs, objp)
- XDR *xdrs;
- ntgrp_list_t *objp;
-{
- if (!xdr_int(xdrs, &objp->cnt))
- return (FALSE);
- if (!xdr_vector(xdrs, (char *)objp->groups, SMB_GROUP_PER_LIST,
- sizeof (ntgrp_t), (xdrproc_t)xdr_ntgrp_t))
- return (FALSE);
- return (TRUE);
-}
-
-bool_t
-xdr_members_list(xdrs, objp)
- XDR *xdrs;
- members_list *objp;
-{
- if (!xdr_string(xdrs, objp, ~0))
- return (FALSE);
- return (TRUE);
-}
-
-bool_t
-xdr_ntgrp_member_list_t(xdrs, objp)
- XDR *xdrs;
- ntgrp_member_list_t *objp;
-{
- if (!xdr_uint32_t(xdrs, &objp->rid))
- return (FALSE);
- if (!xdr_int(xdrs, &objp->cnt))
- return (FALSE);
- if (!xdr_vector(xdrs, (char *)objp->members, SMB_GROUP_PER_LIST,
- sizeof (members_list), (xdrproc_t)xdr_members_list))
- return (FALSE);
- return (TRUE);
-}
-
-bool_t
-xdr_ntpriv_t(xdrs, objp)
- XDR *xdrs;
- ntpriv_t *objp;
-{
- if (!xdr_uint32_t(xdrs, &objp->id))
- return (FALSE);
- if (!xdr_string(xdrs, &objp->name, ~0))
- return (FALSE);
- return (TRUE);
-}
-
-bool_t
-xdr_privs_t(xdrs, objp)
- XDR *xdrs;
- privs_t *objp;
-{
- if (!xdr_pointer(xdrs, (char **)objp, sizeof (ntpriv_t),
- (xdrproc_t)xdr_ntpriv_t))
- return (FALSE);
- return (TRUE);
-}
-
-bool_t
-xdr_ntpriv_list_t(xdrs, objp)
- XDR *xdrs;
- ntpriv_list_t *objp;
-{
- if (!xdr_int(xdrs, &objp->cnt))
- return (FALSE);
- if (!xdr_vector(xdrs, (char *)objp->privs, objp->cnt,
- sizeof (privs_t), (xdrproc_t)xdr_privs_t))
- return (FALSE);
- return (TRUE);
-}
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;
/*