summaryrefslogtreecommitdiff
path: root/usr/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib')
-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
86 files changed, 5855 insertions, 6767 deletions
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);
}