summaryrefslogtreecommitdiff
path: root/usr/src/lib
diff options
context:
space:
mode:
authorAlan Wright <amw@Sun.COM>2009-10-05 11:03:34 -0700
committerAlan Wright <amw@Sun.COM>2009-10-05 11:03:34 -0700
commita0aa776e20803c84edd153d9cb584fd67163aef3 (patch)
treef72052300c24a23ddce016aed02794a33cf3f7a7 /usr/src/lib
parent5dfbf9be7aa351a2746b8259a906f60caf81fdcf (diff)
downloadillumos-gate-a0aa776e20803c84edd153d9cb584fd67163aef3.tar.gz
6612607 CIFS ADS client should use ldap_sasl_interactive_bind_s API
6877755 smbd should not route stderr, stdout to /dev/null 6882701 Wrong error message for attempt to map local user to Windows group, or vice versa 6885105 Potential for deadlock in smb_node_set_delete_on_close() 6881928 smbd core generated when running a script to join domain, set abe properties 6885538 Reduce dependencies on libsmbrdr 6820325 cifs service can't start on multi vlan+ipmp configuration
Diffstat (limited to 'usr/src/lib')
-rw-r--r--usr/src/lib/smbsrv/libmlrpc/common/ndr_process.c8
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/dssetup_clnt.c5
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h18
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/lsalib.c55
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/lsalib.h8
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/lsar_lookup.c26
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/lsar_open.c5
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers2
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c212
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mlsvc_domain.c131
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c2
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mlsvc_lsa.c12
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mlsvc_sam.c42
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c30
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c12
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c14
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/samlib.c34
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/samr_open.c67
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/smb_logon.c6
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/srvsvc_clnt.c53
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/libsmb.h89
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/mapfile-vers34
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_domain.c214
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_info.c114
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_sam.c18
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/libsmbns.h7
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/mapfile-vers3
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c361
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c126
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_krb.c512
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_krb.h23
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.c481
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.h80
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_cache.c135
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_datagram.c250
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_name.c2934
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_netlogon.c15
-rw-r--r--usr/src/lib/smbsrv/libsmbrdr/Makefile.com5
-rw-r--r--usr/src/lib/smbsrv/libsmbrdr/common/libsmbrdr.h28
-rw-r--r--usr/src/lib/smbsrv/libsmbrdr/common/mapfile-vers13
-rw-r--r--usr/src/lib/smbsrv/libsmbrdr/common/smbrdr.h2
-rw-r--r--usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_ipc_util.c170
-rw-r--r--usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_ipc_util.h58
-rw-r--r--usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_logon.c11
-rw-r--r--usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_netbios.c6
-rw-r--r--usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_rpcpipe.c18
-rw-r--r--usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_session.c68
47 files changed, 1843 insertions, 4674 deletions
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/ndr_process.c b/usr/src/lib/smbsrv/libmlrpc/common/ndr_process.c
index cba8a45c42..6147d684ab 100644
--- a/usr/src/lib/smbsrv/libmlrpc/common/ndr_process.c
+++ b/usr/src/lib/smbsrv/libmlrpc/common/ndr_process.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -1186,10 +1186,8 @@ ndr_outer_string(ndr_ref_t *outer_ref)
if (ti == &ndt_s_wchar) {
/*
- * size_is is the number of characters in the string,
- * including the null. We assume valp is UTF-8 encoded.
- * We can use mts_wcequiv_strlen for ASCII, extended
- * ASCII or Unicode (UCS-2).
+ * size_is is the number of characters in the
+ * (multibyte) string, including the null.
*/
size_is = (mts_wcequiv_strlen(valp) /
sizeof (mts_wchar_t)) + 1;
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/dssetup_clnt.c b/usr/src/lib/smbsrv/libmlsvc/common/dssetup_clnt.c
index 5848096254..9c36e26f91 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/dssetup_clnt.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/dssetup_clnt.c
@@ -31,7 +31,6 @@
#include <strings.h>
#include <smbsrv/wintypes.h>
#include <smbsrv/libsmb.h>
-#include <smbsrv/libsmbrdr.h>
#include <smbsrv/ndl/dssetup.ndl>
#include <smbsrv/libmlsvc.h>
@@ -40,7 +39,7 @@ dssetup_get_domain_info(ds_primary_domain_info_t *ds_info)
{
dssetup_DsRoleGetPrimaryDomainInfo_t arg;
struct dssetup_DsRolePrimaryDomInfo1 *info;
- smb_domain_t di;
+ smb_domainex_t di;
mlsvc_handle_t handle;
int opnum;
int rc;
@@ -48,7 +47,7 @@ dssetup_get_domain_info(ds_primary_domain_info_t *ds_info)
if (!smb_domain_getinfo(&di))
return (-1);
- if (ndr_rpc_bind(&handle, di.d_dc, di.d_info.di_nbname,
+ if (ndr_rpc_bind(&handle, di.d_dc, di.d_primary.di_nbname,
MLSVC_ANON_USER, "DSSETUP") != 0)
return (-1);
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h b/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h
index 176bde8ca1..f0491e4c17 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h
+++ b/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h
@@ -42,7 +42,6 @@
#include <smbsrv/smb_share.h>
#include <smbsrv/smb_xdr.h>
#include <smbsrv/libsmb.h>
-#include <smbsrv/libsmbrdr.h>
#include <smbsrv/libmlrpc.h>
#include <smbsrv/ndl/lsarpc.ndl>
@@ -58,15 +57,15 @@ extern uint32_t mlsvc_lookup_sid(smb_sid_t *, char **);
* information.
*/
-extern boolean_t smb_locate_dc(char *, char *, smb_domain_t *);
-extern boolean_t smb_domain_getinfo(smb_domain_t *);
-
+extern boolean_t smb_locate_dc(char *, char *, smb_domainex_t *);
extern void dssetup_clear_domain_info(void);
+extern void mlsvc_disconnect(const char *);
extern int mlsvc_init(void);
extern void mlsvc_fini(void);
+extern int mlsvc_ping(const char *);
extern DWORD mlsvc_netlogon(char *, char *);
-extern DWORD mlsvc_join(smb_domain_t *, char *, char *);
+extern DWORD mlsvc_join(smb_domainex_t *, char *, char *);
/*
@@ -136,6 +135,7 @@ typedef struct srvsvc_server_info {
uint32_t sv_version_minor;
uint32_t sv_type;
char *sv_comment;
+ uint32_t sv_os;
} srvsvc_server_info_t;
int srvsvc_net_server_getinfo(char *, char *, srvsvc_server_info_t *);
@@ -151,16 +151,16 @@ int srvsvc_net_server_getinfo(char *, char *, srvsvc_server_info_t *);
typedef struct mlsvc_handle {
ndr_hdid_t handle;
ndr_client_t *clnt;
- int remote_os;
+ uint32_t remote_os;
srvsvc_server_info_t svinfo;
} mlsvc_handle_t;
+void ndr_rpc_init(void);
+void ndr_rpc_fini(void);
int ndr_rpc_bind(mlsvc_handle_t *, char *, char *, char *, const char *);
void ndr_rpc_unbind(mlsvc_handle_t *);
int ndr_rpc_call(mlsvc_handle_t *, int, void *);
-void ndr_rpc_server_setinfo(mlsvc_handle_t *, const srvsvc_server_info_t *);
-void ndr_rpc_server_getinfo(mlsvc_handle_t *, srvsvc_server_info_t *);
-int ndr_rpc_server_os(mlsvc_handle_t *);
+uint32_t ndr_rpc_server_os(mlsvc_handle_t *);
int ndr_rpc_get_ssnkey(mlsvc_handle_t *, unsigned char *, size_t);
void *ndr_rpc_malloc(mlsvc_handle_t *, size_t);
ndr_heap_t *ndr_rpc_get_heap(mlsvc_handle_t *);
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/lsalib.c b/usr/src/lib/smbsrv/libmlsvc/common/lsalib.c
index 166f26828e..c58b5d36f3 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/lsalib.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/lsalib.c
@@ -32,7 +32,6 @@
#include <smbsrv/libsmb.h>
#include <smbsrv/libmlsvc.h>
-#include <smbsrv/libsmbrdr.h>
#include <smbsrv/ntstatus.h>
#include <smbsrv/smbinfo.h>
#include <smbsrv/smb_token.h>
@@ -139,11 +138,13 @@ lsa_lookup_sid(smb_sid_t *sid, smb_account_t *info)
*/
DWORD
lsa_query_primary_domain_info(char *server, char *domain,
- nt_domain_t *info)
+ smb_domain_t *info)
{
mlsvc_handle_t domain_handle;
DWORD status;
- char *user = smbrdr_ipc_get_user();
+ char user[SMB_USERNAME_MAXLEN];
+
+ smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
if ((lsar_open(server, domain, user, &domain_handle)) != 0)
return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
@@ -165,11 +166,13 @@ lsa_query_primary_domain_info(char *server, char *domain,
*/
DWORD
lsa_query_account_domain_info(char *server, char *domain,
- nt_domain_t *info)
+ smb_domain_t *info)
{
mlsvc_handle_t domain_handle;
DWORD status;
- char *user = smbrdr_ipc_get_user();
+ char user[SMB_USERNAME_MAXLEN];
+
+ smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
if ((lsar_open(server, domain, user, &domain_handle)) != 0)
return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
@@ -192,11 +195,13 @@ lsa_query_account_domain_info(char *server, char *domain,
* Returns NT status codes.
*/
DWORD
-lsa_query_dns_domain_info(char *server, char *domain, nt_domain_t *info)
+lsa_query_dns_domain_info(char *server, char *domain, smb_domain_t *info)
{
mlsvc_handle_t domain_handle;
DWORD status;
- char *user = smbrdr_ipc_get_user();
+ char user[SMB_USERNAME_MAXLEN];
+
+ smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
if ((lsar_open(server, domain, user, &domain_handle)) != 0)
return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
@@ -224,7 +229,9 @@ lsa_enum_trusted_domains(char *server, char *domain,
mlsvc_handle_t domain_handle;
DWORD enum_context;
DWORD status;
- char *user = smbrdr_ipc_get_user();
+ char user[SMB_USERNAME_MAXLEN];
+
+ smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
if ((lsar_open(server, domain, user, &domain_handle)) != 0)
return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
@@ -261,7 +268,9 @@ lsa_enum_trusted_domains_ex(char *server, char *domain,
mlsvc_handle_t domain_handle;
DWORD enum_context;
DWORD status;
- char *user = smbrdr_ipc_get_user();
+ char user[SMB_USERNAME_MAXLEN];
+
+ smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
if ((lsar_open(server, domain, user, &domain_handle)) != 0)
return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
@@ -335,14 +344,16 @@ static uint32_t
lsa_lookup_name_domain(char *account_name, smb_account_t *info)
{
mlsvc_handle_t domain_handle;
- smb_domain_t dinfo;
- char *user = smbrdr_ipc_get_user();
+ smb_domainex_t dinfo;
uint32_t status;
+ char user[SMB_USERNAME_MAXLEN];
+
+ smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
if (!smb_domain_getinfo(&dinfo))
return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
- if (lsar_open(dinfo.d_dc, dinfo.d_info.di_nbname, user,
+ if (lsar_open(dinfo.d_dc, dinfo.d_primary.di_nbname, user,
&domain_handle) != 0)
return (NT_STATUS_INVALID_PARAMETER);
@@ -378,13 +389,15 @@ lsa_lookup_privs(char *account_name, char *target_name, smb_account_t *ainfo)
{
mlsvc_handle_t domain_handle;
int rc;
- char *user = smbrdr_ipc_get_user();
- smb_domain_t dinfo;
+ smb_domainex_t dinfo;
+ char user[SMB_USERNAME_MAXLEN];
+
+ smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
if (!smb_domain_getinfo(&dinfo))
return (-1);
- if ((lsar_open(dinfo.d_dc, dinfo.d_info.di_nbname, user,
+ if ((lsar_open(dinfo.d_dc, dinfo.d_primary.di_nbname, user,
&domain_handle)) != 0)
return (-1);
@@ -409,7 +422,9 @@ lsa_list_privs(char *server, char *domain)
mlsvc_handle_t domain_handle;
int rc;
int i;
- char *user = smbrdr_ipc_get_user();
+ char user[SMB_USERNAME_MAXLEN];
+
+ smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
rc = lsar_open(server, domain, user, &domain_handle);
if (rc != 0)
@@ -519,14 +534,16 @@ static uint32_t
lsa_lookup_sid_domain(smb_sid_t *sid, smb_account_t *ainfo)
{
mlsvc_handle_t domain_handle;
- char *user = smbrdr_ipc_get_user();
uint32_t status;
- smb_domain_t dinfo;
+ smb_domainex_t dinfo;
+ char user[SMB_USERNAME_MAXLEN];
+
+ smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
if (!smb_domain_getinfo(&dinfo))
return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
- if (lsar_open(dinfo.d_dc, dinfo.d_info.di_nbname, user,
+ if (lsar_open(dinfo.d_dc, dinfo.d_primary.di_nbname, user,
&domain_handle) != 0)
return (NT_STATUS_INVALID_PARAMETER);
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/lsalib.h b/usr/src/lib/smbsrv/libmlsvc/common/lsalib.h
index 7d9c90edfd..afbf685bc5 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/lsalib.h
+++ b/usr/src/lib/smbsrv/libmlsvc/common/lsalib.h
@@ -50,9 +50,9 @@ extern "C" {
*/
uint32_t lsa_lookup_name(char *, uint16_t, smb_account_t *);
uint32_t lsa_lookup_sid(smb_sid_t *, smb_account_t *);
-DWORD lsa_query_primary_domain_info(char *, char *, nt_domain_t *);
-DWORD lsa_query_account_domain_info(char *, char *, nt_domain_t *);
-DWORD lsa_query_dns_domain_info(char *, char *, nt_domain_t *);
+DWORD lsa_query_primary_domain_info(char *, char *, smb_domain_t *);
+DWORD lsa_query_account_domain_info(char *, char *, smb_domain_t *);
+DWORD lsa_query_dns_domain_info(char *, char *, smb_domain_t *);
DWORD lsa_enum_trusted_domains(char *, char *, smb_trusted_domains_t *);
DWORD lsa_enum_trusted_domains_ex(char *, char *, smb_trusted_domains_t *);
@@ -68,7 +68,7 @@ int lsar_close(mlsvc_handle_t *);
* lsar_lookup.c
*/
int lsar_query_security_desc(mlsvc_handle_t *);
-DWORD lsar_query_info_policy(mlsvc_handle_t *, WORD, nt_domain_t *);
+DWORD lsar_query_info_policy(mlsvc_handle_t *, WORD, smb_domain_t *);
uint32_t lsar_lookup_names(mlsvc_handle_t *, char *, smb_account_t *);
uint32_t lsar_lookup_names2(mlsvc_handle_t *, char *, smb_account_t *);
uint32_t lsar_lookup_sids(mlsvc_handle_t *, struct mslsa_sid *,
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/lsar_lookup.c b/usr/src/lib/smbsrv/libmlsvc/common/lsar_lookup.c
index 6e92f7cc8c..127f2b4cbe 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/lsar_lookup.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/lsar_lookup.c
@@ -103,7 +103,7 @@ lsar_query_security_desc(mlsvc_handle_t *lsa_handle)
*/
DWORD
lsar_query_info_policy(mlsvc_handle_t *lsa_handle, WORD infoClass,
- nt_domain_t *info)
+ smb_domain_t *info)
{
struct mslsa_QueryInfoPolicy arg;
struct mslsa_PrimaryDomainInfo *pd_info;
@@ -119,7 +119,7 @@ lsar_query_info_policy(mlsvc_handle_t *lsa_handle, WORD infoClass,
opnum = LSARPC_OPNUM_QueryInfoPolicy;
- bzero(info, sizeof (nt_domain_t));
+ bzero(info, sizeof (smb_domain_t));
bzero(&arg, sizeof (struct mslsa_QueryInfoPolicy));
(void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t));
@@ -137,8 +137,8 @@ lsar_query_info_policy(mlsvc_handle_t *lsa_handle, WORD infoClass,
pd_info = &arg.ru.pd_info;
smb_sid_tostr((smb_sid_t *)pd_info->sid, sidstr);
- info->di_type = NT_DOMAIN_PRIMARY;
- nt_domain_set_basic_info(sidstr,
+ info->di_type = SMB_DOMAIN_PRIMARY;
+ smb_domain_set_basic_info(sidstr,
(char *)pd_info->name.str, "", info);
status = NT_STATUS_SUCCESS;
@@ -148,8 +148,8 @@ lsar_query_info_policy(mlsvc_handle_t *lsa_handle, WORD infoClass,
ad_info = &arg.ru.ad_info;
smb_sid_tostr((smb_sid_t *)ad_info->sid, sidstr);
- info->di_type = NT_DOMAIN_ACCOUNT;
- nt_domain_set_basic_info(sidstr,
+ info->di_type = SMB_DOMAIN_ACCOUNT;
+ smb_domain_set_basic_info(sidstr,
(char *)ad_info->name.str, "", info);
status = NT_STATUS_SUCCESS;
@@ -161,8 +161,8 @@ lsar_query_info_policy(mlsvc_handle_t *lsa_handle, WORD infoClass,
guid_str);
smb_sid_tostr((smb_sid_t *)dns_info->sid, sidstr);
- info->di_type = NT_DOMAIN_PRIMARY;
- nt_domain_set_dns_info(sidstr,
+ info->di_type = SMB_DOMAIN_PRIMARY;
+ smb_domain_set_dns_info(sidstr,
(char *)dns_info->nb_domain.str,
(char *)dns_info->dns_domain.str,
(char *)dns_info->forest.str,
@@ -884,7 +884,8 @@ lsar_set_trusted_domains_ex(struct mslsa_EnumTrustedDomainBufEx *enum_buf,
return;
list->td_num = 0;
- list->td_domains = calloc(enum_buf->entries_read, sizeof (nt_domain_t));
+ list->td_domains = calloc(enum_buf->entries_read,
+ sizeof (smb_domain_t));
if (list->td_domains == NULL)
return;
@@ -892,7 +893,7 @@ lsar_set_trusted_domains_ex(struct mslsa_EnumTrustedDomainBufEx *enum_buf,
list->td_num = enum_buf->entries_read;
for (i = 0; i < list->td_num; i++) {
smb_sid_tostr((smb_sid_t *)enum_buf->info[i].sid, sidstr);
- nt_domain_set_trust_info(
+ smb_domain_set_trust_info(
sidstr,
(char *)enum_buf->info[i].nb_name.str,
(char *)enum_buf->info[i].dns_name.str,
@@ -914,7 +915,8 @@ lsar_set_trusted_domains(struct mslsa_EnumTrustedDomainBuf *enum_buf,
return;
list->td_num = 0;
- list->td_domains = calloc(enum_buf->entries_read, sizeof (nt_domain_t));
+ list->td_domains = calloc(enum_buf->entries_read,
+ sizeof (smb_domain_t));
if (list->td_domains == NULL)
return;
@@ -922,7 +924,7 @@ lsar_set_trusted_domains(struct mslsa_EnumTrustedDomainBuf *enum_buf,
list->td_num = enum_buf->entries_read;
for (i = 0; i < list->td_num; i++) {
smb_sid_tostr((smb_sid_t *)enum_buf->info[i].sid, sidstr);
- nt_domain_set_trust_info(
+ smb_domain_set_trust_info(
sidstr, (char *)enum_buf->info[i].name.str,
"", 0, 0, 0, &list->td_domains[i]);
}
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/lsar_open.c b/usr/src/lib/smbsrv/libmlsvc/common/lsar_open.c
index 94a7b57ae5..aefb2723e8 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/lsar_open.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/lsar_open.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -32,7 +32,6 @@
#include <strings.h>
#include <smbsrv/libsmb.h>
-#include <smbsrv/libsmbrdr.h>
#include <smbsrv/libmlsvc.h>
#include <smbsrv/smbinfo.h>
#include <smbsrv/ntaccess.h>
@@ -104,7 +103,7 @@ lsar_open_policy2(char *server, char *domain, char *username,
(void) snprintf((char *)arg.servername, len, "\\\\%s", server);
arg.attributes.length = sizeof (struct mslsa_object_attributes);
- if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_NT5_0) {
+ if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000) {
arg.desiredAccess = MAXIMUM_ALLOWED;
} else {
arg.desiredAccess = GENERIC_EXECUTE
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers b/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers
index 2841f705be..59bd319ef3 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers
@@ -41,6 +41,7 @@
SUNWprivate {
global:
dssetup_clear_domain_info;
+ mlsvc_disconnect;
mlsvc_fini;
mlsvc_init;
mlsvc_join;
@@ -49,7 +50,6 @@ SUNWprivate {
mlsvc_netlogon;
smb_autohome_add;
smb_autohome_remove;
- smb_domain_getinfo;
smb_locate_dc;
smb_logon;
smb_shr_add;
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c
index 1929213c4d..11569ef97b 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c
@@ -27,14 +27,39 @@
* Client NDR RPC interface.
*/
+#include <sys/types.h>
#include <sys/errno.h>
+#include <time.h>
#include <strings.h>
#include <assert.h>
+#include <thread.h>
+#include <synch.h>
#include <smbsrv/libsmb.h>
#include <smbsrv/libsmbrdr.h>
#include <smbsrv/libmlrpc.h>
#include <smbsrv/libmlsvc.h>
+/*
+ * Server info cache entry expiration in seconds.
+ */
+#define NDR_SVINFO_TIMEOUT 1800
+
+typedef struct ndr_svinfo {
+ list_node_t svi_lnd;
+ time_t svi_tcached;
+ char svi_server[MAXNAMELEN];
+ char svi_domain[MAXNAMELEN];
+ srvsvc_server_info_t svi_svinfo;
+} ndr_svinfo_t;
+
+typedef struct ndr_svlist {
+ list_t svl_list;
+ mutex_t svl_mtx;
+ boolean_t svl_init;
+} ndr_svlist_t;
+
+static ndr_svlist_t ndr_svlist;
+
static int ndr_xa_init(ndr_client_t *, ndr_xa_t *);
static int ndr_xa_exchange(ndr_client_t *, ndr_xa_t *);
static int ndr_xa_read(ndr_client_t *, ndr_xa_t *);
@@ -42,6 +67,54 @@ static void ndr_xa_preserve(ndr_client_t *, ndr_xa_t *);
static void ndr_xa_destruct(ndr_client_t *, ndr_xa_t *);
static void ndr_xa_release(ndr_client_t *);
+static int ndr_svinfo_lookup(char *, char *, srvsvc_server_info_t *);
+static boolean_t ndr_svinfo_match(const char *, const char *, const
+ ndr_svinfo_t *);
+static boolean_t ndr_svinfo_expired(ndr_svinfo_t *);
+
+/*
+ * Initialize the RPC client interface: create the server info cache.
+ */
+void
+ndr_rpc_init(void)
+{
+ (void) mutex_lock(&ndr_svlist.svl_mtx);
+
+ if (!ndr_svlist.svl_init) {
+ list_create(&ndr_svlist.svl_list, sizeof (ndr_svinfo_t),
+ offsetof(ndr_svinfo_t, svi_lnd));
+ ndr_svlist.svl_init = B_TRUE;
+ }
+
+ (void) mutex_unlock(&ndr_svlist.svl_mtx);
+}
+
+/*
+ * Terminate the RPC client interface: flush and destroy the server info
+ * cache.
+ */
+void
+ndr_rpc_fini(void)
+{
+ ndr_svinfo_t *svi;
+
+ (void) mutex_lock(&ndr_svlist.svl_mtx);
+
+ if (ndr_svlist.svl_init) {
+ while ((svi = list_head(&ndr_svlist.svl_list)) != NULL) {
+ list_remove(&ndr_svlist.svl_list, svi);
+ free(svi->svi_svinfo.sv_name);
+ free(svi->svi_svinfo.sv_comment);
+ free(svi);
+ }
+
+ list_destroy(&ndr_svlist.svl_list);
+ ndr_svlist.svl_init = B_FALSE;
+ }
+
+ (void) mutex_unlock(&ndr_svlist.svl_mtx);
+}
+
/*
* This call must be made to initialize an RPC client structure and bind
* to the remote service before any RPCs can be exchanged with that service.
@@ -61,7 +134,8 @@ ndr_rpc_bind(mlsvc_handle_t *handle, char *server, char *domain,
{
ndr_client_t *clnt;
ndr_service_t *svc;
- smbrdr_session_info_t si;
+ srvsvc_server_info_t svinfo;
+ int remote_os;
int fid;
int rc;
@@ -72,6 +146,20 @@ ndr_rpc_bind(mlsvc_handle_t *handle, char *server, char *domain,
if ((svc = ndr_svc_lookup_name(service)) == NULL)
return (-1);
+ /*
+ * Set the default based on the assumption that most
+ * servers will be Windows 2000 or later.
+ * Don't lookup the svinfo if this is a SRVSVC request
+ * because the SRVSVC is used to get the server info.
+ * None of the SRVSVC calls depend on the remote OS.
+ */
+ remote_os = NATIVE_OS_WIN2000;
+
+ if (strcasecmp(service, "SRVSVC") != 0) {
+ if (ndr_svinfo_lookup(server, domain, &svinfo) == 0)
+ remote_os = svinfo.sv_os;
+ }
+
if ((clnt = malloc(sizeof (ndr_client_t))) == NULL)
return (-1);
@@ -95,10 +183,9 @@ ndr_rpc_bind(mlsvc_handle_t *handle, char *server, char *domain,
clnt->xa_destruct = ndr_xa_destruct;
clnt->xa_release = ndr_xa_release;
- (void) smbrdr_session_info(fid, &si);
bzero(&handle->handle, sizeof (ndr_hdid_t));
handle->clnt = clnt;
- handle->remote_os = si.si_server_os;
+ handle->remote_os = remote_os;
if (ndr_rpc_get_heap(handle) == NULL) {
free(clnt);
@@ -170,39 +257,9 @@ ndr_rpc_call(mlsvc_handle_t *handle, int opnum, void *params)
}
/*
- * Set information about the remote RPC server in the handle.
- */
-void
-ndr_rpc_server_setinfo(mlsvc_handle_t *handle,
- const srvsvc_server_info_t *svinfo)
-{
- bcopy(svinfo, &handle->svinfo, sizeof (srvsvc_server_info_t));
- handle->svinfo.sv_name = NULL;
- handle->svinfo.sv_comment = NULL;
-
- if (svinfo->sv_version_major > 4)
- handle->remote_os = NATIVE_OS_WIN2000;
- else
- handle->remote_os = NATIVE_OS_WINNT;
-
- smb_tracef("NdrRpcServerSetInfo: %s (version %d.%d)",
- svinfo->sv_name ? svinfo->sv_name : "<unknown>",
- svinfo->sv_version_major, svinfo->sv_version_minor);
-}
-
-/*
- * Get information about the remote RPC server from the handle.
- */
-void
-ndr_rpc_server_getinfo(mlsvc_handle_t *handle, srvsvc_server_info_t *svinfo)
-{
- bcopy(&handle->svinfo, svinfo, sizeof (srvsvc_server_info_t));
-}
-
-/*
* Returns the Native-OS of the RPC server.
*/
-int
+uint32_t
ndr_rpc_server_os(mlsvc_handle_t *handle)
{
return (handle->remote_os);
@@ -468,3 +525,90 @@ ndr_xa_release(ndr_client_t *clnt)
clnt->heap_preserved = B_FALSE;
}
}
+
+/*
+ * Lookup platform, type and version information about a server.
+ * If the cache doesn't already contain the data, contact the server and
+ * cache the response before returning the server info to the caller.
+ */
+static int
+ndr_svinfo_lookup(char *server, char *domain, srvsvc_server_info_t *svinfo)
+{
+ ndr_svinfo_t *svi;
+
+ (void) mutex_lock(&ndr_svlist.svl_mtx);
+ assert(ndr_svlist.svl_init == B_TRUE);
+
+ svi = list_head(&ndr_svlist.svl_list);
+ while (svi != NULL) {
+ if (ndr_svinfo_expired(svi)) {
+ svi = list_head(&ndr_svlist.svl_list);
+ continue;
+ }
+
+ if (ndr_svinfo_match(server, domain, svi)) {
+ bcopy(&svi->svi_svinfo, svinfo,
+ sizeof (srvsvc_server_info_t));
+ (void) mutex_unlock(&ndr_svlist.svl_mtx);
+ return (0);
+ }
+
+ svi = list_next(&ndr_svlist.svl_list, svi);
+ }
+
+ if ((svi = malloc(sizeof (ndr_svinfo_t))) == NULL) {
+ (void) mutex_unlock(&ndr_svlist.svl_mtx);
+ return (-1);
+ }
+
+ if (srvsvc_net_server_getinfo(server, domain, &svi->svi_svinfo) < 0) {
+ (void) mutex_unlock(&ndr_svlist.svl_mtx);
+ free(svi);
+ return (-1);
+ }
+
+ (void) time(&svi->svi_tcached);
+ (void) strlcpy(svi->svi_server, server, MAXNAMELEN);
+ (void) strlcpy(svi->svi_domain, domain, MAXNAMELEN);
+ list_insert_tail(&ndr_svlist.svl_list, svi);
+ bcopy(&svi->svi_svinfo, svinfo, sizeof (srvsvc_server_info_t));
+ (void) mutex_unlock(&ndr_svlist.svl_mtx);
+ return (0);
+}
+
+static boolean_t
+ndr_svinfo_match(const char *server, const char *domain,
+ const ndr_svinfo_t *svi)
+{
+ if ((utf8_strcasecmp(server, svi->svi_server) == 0) &&
+ (utf8_strcasecmp(domain, svi->svi_domain) == 0)) {
+ return (B_TRUE);
+ }
+
+ return (B_FALSE);
+}
+
+/*
+ * If the server info in the cache has expired, discard it and return true.
+ * Otherwise return false.
+ *
+ * This is a private function to support ndr_svinfo_lookup() that assumes
+ * the list mutex is held.
+ */
+static boolean_t
+ndr_svinfo_expired(ndr_svinfo_t *svi)
+{
+ time_t tnow;
+
+ (void) time(&tnow);
+
+ if (difftime(tnow, svi->svi_tcached) > NDR_SVINFO_TIMEOUT) {
+ list_remove(&ndr_svlist.svl_list, svi);
+ free(svi->svi_svinfo.sv_name);
+ free(svi->svi_svinfo.sv_comment);
+ free(svi);
+ return (B_TRUE);
+ }
+
+ return (B_FALSE);
+}
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_domain.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_domain.c
index b035847da6..a18e07fefa 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_domain.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_domain.c
@@ -38,7 +38,6 @@
#include <assert.h>
#include <smbsrv/libsmb.h>
-#include <smbsrv/libsmbrdr.h>
#include <smbsrv/libsmbns.h>
#include <smbsrv/libmlsvc.h>
@@ -49,7 +48,7 @@
/*
* DC Locator
*/
-#define SMB_DCLOCATOR_TIMEOUT 45
+#define SMB_DCLOCATOR_TIMEOUT 45 /* seconds */
#define SMB_IS_FQDN(domain) (strchr(domain, '.') != NULL)
typedef struct smb_dclocator {
@@ -64,15 +63,15 @@ typedef struct smb_dclocator {
static smb_dclocator_t smb_dclocator;
static pthread_t smb_dclocator_thr;
-static void *smb_dclocator_main(void *);
-static void smb_domain_update(char *, char *);
-static boolean_t smb_domain_query_dns(char *, char *, smb_domain_t *);
-static boolean_t smb_domain_query_nbt(char *, char *, smb_domain_t *);
-static boolean_t smb_domain_match(char *, char *, uint32_t);
-static uint32_t smb_domain_query(char *, char *, smb_domain_t *);
-static void smb_domain_enum_trusted(char *, char *, smb_trusted_domains_t *);
-static uint32_t smb_domain_use_config(char *, nt_domain_t *);
-static void smb_domain_free(smb_domain_t *di);
+static void *smb_ddiscover_service(void *);
+static void smb_ddiscover_main(char *, char *);
+static boolean_t smb_ddiscover_dns(char *, char *, smb_domainex_t *);
+static boolean_t smb_ddiscover_nbt(char *, char *, smb_domainex_t *);
+static boolean_t smb_ddiscover_domain_match(char *, char *, uint32_t);
+static uint32_t smb_ddiscover_qinfo(char *, char *, smb_domainex_t *);
+static void smb_ddiscover_enum_trusted(char *, char *, smb_domainex_t *);
+static uint32_t smb_ddiscover_use_config(char *, smb_domainex_t *);
+static void smb_domainex_free(smb_domainex_t *);
/*
* ===================================================================
@@ -82,8 +81,6 @@ static void smb_domain_free(smb_domain_t *di);
*/
/*
- * smb_dclocator_init
- *
* Initialization of the DC locator thread.
* Returns 0 on success, an error number if thread creation fails.
*/
@@ -96,14 +93,12 @@ smb_dclocator_init(void)
(void) pthread_attr_init(&tattr);
(void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
rc = pthread_create(&smb_dclocator_thr, &tattr,
- smb_dclocator_main, 0);
+ smb_ddiscover_service, 0);
(void) pthread_attr_destroy(&tattr);
return (rc);
}
/*
- * smb_locate_dc
- *
* This is the entry point for discovering a domain controller for the
* specified domain.
*
@@ -121,11 +116,11 @@ smb_dclocator_init(void)
* Returns B_TRUE if the DC/domain info is available.
*/
boolean_t
-smb_locate_dc(char *domain, char *dc, smb_domain_t *dp)
+smb_locate_dc(char *domain, char *dc, smb_domainex_t *dp)
{
int rc;
timestruc_t to;
- smb_domain_t domain_info;
+ smb_domainex_t domain_info;
if (domain == NULL || *domain == '\0')
return (B_FALSE);
@@ -160,31 +155,21 @@ smb_locate_dc(char *domain, char *dc, smb_domain_t *dp)
}
/*
- * Returns a copy of primary domain information plus
- * the selected domain controller
- */
-boolean_t
-smb_domain_getinfo(smb_domain_t *dp)
-{
- return (nt_domain_get_primary(dp));
-}
-
-/*
* ==========================================================
* DC discovery functions
* ==========================================================
*/
/*
- * This is the DC discovery thread: it gets woken up whenever someone
- * wants to locate a domain controller.
+ * This is the domain and DC discovery service: it gets woken up whenever
+ * there is need to locate a domain controller.
*
* Upon success, the SMB domain cache will be populated with the discovered
* DC and domain info.
*/
/*ARGSUSED*/
static void *
-smb_dclocator_main(void *arg)
+smb_ddiscover_service(void *arg)
{
char domain[SMB_PI_MAX_DOMAIN];
char sought_dc[MAXHOSTNAMELEN];
@@ -201,7 +186,7 @@ smb_dclocator_main(void *arg)
(void) strlcpy(sought_dc, smb_dclocator.sdl_dc, MAXHOSTNAMELEN);
(void) mutex_unlock(&smb_dclocator.sdl_mtx);
- smb_domain_update(domain, sought_dc);
+ smb_ddiscover_main(domain, sought_dc);
(void) mutex_lock(&smb_dclocator.sdl_mtx);
smb_dclocator.sdl_locate = B_FALSE;
@@ -223,29 +208,30 @@ smb_dclocator_main(void *arg)
* obtained information.
*/
static void
-smb_domain_update(char *domain, char *server)
+smb_ddiscover_main(char *domain, char *server)
{
- smb_domain_t di;
- boolean_t query_ok;
+ smb_domainex_t dxi;
+ boolean_t discovered;
- bzero(&di, sizeof (smb_domain_t));
+ bzero(&dxi, sizeof (smb_domainex_t));
- nt_domain_start_update();
+ if (smb_domain_start_update() != SMB_DOMAIN_SUCCESS)
+ return;
if (SMB_IS_FQDN(domain))
- query_ok = smb_domain_query_dns(domain, server, &di);
+ discovered = smb_ddiscover_dns(domain, server, &dxi);
else
- query_ok = smb_domain_query_nbt(domain, server, &di);
+ discovered = smb_ddiscover_nbt(domain, server, &dxi);
- if (query_ok)
- nt_domain_update(&di);
+ if (discovered)
+ smb_domain_update(&dxi);
- nt_domain_end_update();
+ smb_domain_end_update();
- smb_domain_free(&di);
+ smb_domainex_free(&dxi);
- if (query_ok)
- nt_domain_save();
+ if (discovered)
+ smb_domain_save();
}
/*
@@ -253,13 +239,14 @@ smb_domain_update(char *domain, char *server)
* primary and trusted domains information will be queried.
*/
static boolean_t
-smb_domain_query_dns(char *domain, char *server, smb_domain_t *di)
+smb_ddiscover_dns(char *domain, char *server, smb_domainex_t *dxi)
{
uint32_t status;
- if (!smb_ads_lookup_msdcs(domain, server, di->d_dc, MAXHOSTNAMELEN))
+
+ if (!smb_ads_lookup_msdcs(domain, server, dxi->d_dc, MAXHOSTNAMELEN))
return (B_FALSE);
- status = smb_domain_query(domain, di->d_dc, di);
+ status = smb_ddiscover_qinfo(domain, dxi->d_dc, dxi);
return (status == NT_STATUS_SUCCESS);
}
@@ -277,30 +264,30 @@ smb_domain_query_dns(char *domain, char *server, smb_domain_t *di)
* actually for another domain, whose first label of its FQDN somehow
* matches with the NetBIOS name of the domain we're interested in.
*/
-
static boolean_t
-smb_domain_query_nbt(char *domain, char *server, smb_domain_t *di)
+smb_ddiscover_nbt(char *domain, char *server, smb_domainex_t *dxi)
{
char dnsdomain[MAXHOSTNAMELEN];
uint32_t status;
*dnsdomain = '\0';
- if (!smb_browser_netlogon(domain, di->d_dc, MAXHOSTNAMELEN)) {
- if (!smb_domain_match(domain, dnsdomain, MAXHOSTNAMELEN))
+ if (!smb_browser_netlogon(domain, dxi->d_dc, MAXHOSTNAMELEN)) {
+ if (!smb_ddiscover_domain_match(domain, dnsdomain,
+ MAXHOSTNAMELEN))
return (B_FALSE);
- if (!smb_ads_lookup_msdcs(dnsdomain, server, di->d_dc,
+ if (!smb_ads_lookup_msdcs(dnsdomain, server, dxi->d_dc,
MAXHOSTNAMELEN))
return (B_FALSE);
}
- status = smb_domain_query(domain, di->d_dc, di);
+ status = smb_ddiscover_qinfo(domain, dxi->d_dc, dxi);
if (status != NT_STATUS_SUCCESS)
return (B_FALSE);
if ((*dnsdomain != '\0') &&
- utf8_strcasecmp(domain, di->d_info.di_nbname))
+ utf8_strcasecmp(domain, dxi->d_primary.di_nbname))
return (B_FALSE);
/*
@@ -309,8 +296,8 @@ smb_domain_query_nbt(char *domain, char *server, smb_domain_t *di)
* if we previously locate a DC via NetBIOS. On success,
* ADS cache will be populated.
*/
- if (smb_ads_lookup_msdcs(di->d_info.di_fqname, server,
- di->d_dc, MAXHOSTNAMELEN) == 0)
+ if (smb_ads_lookup_msdcs(dxi->d_primary.di_fqname, server,
+ dxi->d_dc, MAXHOSTNAMELEN) == 0)
return (B_FALSE);
return (B_TRUE);
@@ -322,7 +309,7 @@ smb_domain_query_nbt(char *domain, char *server, smb_domain_t *di)
* If a match is found, it'll be returned in the passed buffer.
*/
static boolean_t
-smb_domain_match(char *nb_domain, char *buf, uint32_t len)
+smb_ddiscover_domain_match(char *nb_domain, char *buf, uint32_t len)
{
struct __res_state res_state;
int i;
@@ -373,22 +360,22 @@ smb_domain_match(char *nb_domain, char *buf, uint32_t len)
* domain - either NetBIOS or fully-qualified domain name
*/
static uint32_t
-smb_domain_query(char *domain, char *server, smb_domain_t *di)
+smb_ddiscover_qinfo(char *domain, char *server, smb_domainex_t *dxi)
{
uint32_t status;
mlsvc_disconnect(server);
- status = lsa_query_dns_domain_info(server, domain, &di->d_info);
+ status = lsa_query_dns_domain_info(server, domain, &dxi->d_primary);
if (status != NT_STATUS_SUCCESS) {
- status = smb_domain_use_config(domain, &di->d_info);
+ status = smb_ddiscover_use_config(domain, dxi);
if (status != NT_STATUS_SUCCESS)
status = lsa_query_primary_domain_info(server, domain,
- &di->d_info);
+ &dxi->d_primary);
}
if (status == NT_STATUS_SUCCESS)
- smb_domain_enum_trusted(domain, server, &di->d_trusted);
+ smb_ddiscover_enum_trusted(domain, server, dxi);
return (status);
}
@@ -399,10 +386,12 @@ smb_domain_query(char *domain, char *server, smb_domain_t *di)
* domain - either NetBIOS or fully-qualified domain name.
*/
static void
-smb_domain_enum_trusted(char *domain, char *server, smb_trusted_domains_t *list)
+smb_ddiscover_enum_trusted(char *domain, char *server, smb_domainex_t *dxi)
{
+ smb_trusted_domains_t *list;
uint32_t status;
+ list = &dxi->d_trusted;
status = lsa_enum_trusted_domains_ex(server, domain, list);
if (status != NT_STATUS_SUCCESS)
(void) lsa_enum_trusted_domains(server, domain, list);
@@ -410,15 +399,17 @@ smb_domain_enum_trusted(char *domain, char *server, smb_trusted_domains_t *list)
/*
* If the domain to be discovered matches the current domain (i.e the
- * value of either domain or fqdn configuration), the output parameter
- * 'dinfo' will be set to the information stored in SMF.
+ * value of either domain or fqdn configuration), then get the primary
+ * domain information from SMF.
*/
static uint32_t
-smb_domain_use_config(char *domain, nt_domain_t *dinfo)
+smb_ddiscover_use_config(char *domain, smb_domainex_t *dxi)
{
boolean_t use;
+ smb_domain_t *dinfo;
- bzero(dinfo, sizeof (nt_domain_t));
+ dinfo = &dxi->d_primary;
+ bzero(dinfo, sizeof (smb_domain_t));
if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN)
return (NT_STATUS_UNSUCCESSFUL);
@@ -440,7 +431,7 @@ smb_domain_use_config(char *domain, nt_domain_t *dinfo)
}
static void
-smb_domain_free(smb_domain_t *di)
+smb_domainex_free(smb_domainex_t *dxi)
{
- free(di->d_trusted.td_domains);
+ free(dxi->d_trusted.td_domains);
}
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c
index b48ba9b4e0..c418b59339 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c
@@ -60,6 +60,7 @@ mlsvc_init(void)
if ((rc = smb_dclocator_init()) != 0)
return (rc);
+ ndr_rpc_init();
srvsvc_initialize();
wkssvc_initialize();
lsarpc_initialize();
@@ -86,6 +87,7 @@ mlsvc_fini(void)
smb_logon_fini();
svcctl_finalize();
logr_finalize();
+ ndr_rpc_fini();
}
/*ARGSUSED*/
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_lsa.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_lsa.c
index 61082dc348..058811cb6e 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_lsa.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_lsa.c
@@ -520,7 +520,7 @@ lsarpc_s_GetConnectedUser(void *arg, ndr_xa_t *mxa)
struct mslsa_GetConnectedUser *param = arg;
smb_netuserinfo_t *user = &mxa->pipe->np_user;
DWORD status = NT_STATUS_SUCCESS;
- smb_domain_t di;
+ smb_domainex_t di;
int rc1;
int rc2;
@@ -638,16 +638,16 @@ static DWORD
lsarpc_s_PrimaryDomainInfo(struct mslsa_PrimaryDomainInfo *info,
ndr_xa_t *mxa)
{
- nt_domain_t di;
+ smb_domain_t di;
boolean_t found;
int rc;
bzero(info, sizeof (struct mslsa_PrimaryDomainInfo));
if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN)
- found = nt_domain_lookup_type(NT_DOMAIN_LOCAL, &di);
+ found = smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di);
else
- found = nt_domain_lookup_type(NT_DOMAIN_PRIMARY, &di);
+ found = smb_domain_lookup_type(SMB_DOMAIN_PRIMARY, &di);
if (!found)
return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
@@ -676,12 +676,12 @@ static DWORD
lsarpc_s_AccountDomainInfo(struct mslsa_AccountDomainInfo *info,
ndr_xa_t *mxa)
{
- nt_domain_t di;
+ smb_domain_t di;
int rc;
bzero(info, sizeof (struct mslsa_AccountDomainInfo));
- if (!nt_domain_lookup_type(NT_DOMAIN_LOCAL, &di))
+ if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di))
return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
rc = NDR_MSTRING(mxa, di.di_nbname, (ndr_mstring_t *)&info->name);
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_sam.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_sam.c
index b1d85eda0b..a56214954e 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_sam.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_sam.c
@@ -59,7 +59,7 @@ typedef enum {
typedef struct samr_keydata {
samr_key_t kd_key;
- nt_domain_type_t kd_type;
+ smb_domain_type_t kd_type;
DWORD kd_rid;
} samr_keydata_t;
@@ -93,7 +93,7 @@ typedef enum {
#define SAMR_SUPPORTED_DISPLEVEL(lvl) (lvl == DomainDisplayUser)
-static ndr_hdid_t *samr_hdalloc(ndr_xa_t *, samr_key_t, nt_domain_type_t,
+static ndr_hdid_t *samr_hdalloc(ndr_xa_t *, samr_key_t, smb_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);
@@ -147,7 +147,7 @@ samr_call_stub(ndr_xa_t *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,
+samr_hdalloc(ndr_xa_t *mxa, samr_key_t key, smb_domain_type_t domain_type,
DWORD rid)
{
samr_keydata_t *data;
@@ -213,7 +213,7 @@ samr_s_ConnectAnon(void *arg, ndr_xa_t *mxa)
struct samr_ConnectAnon *param = arg;
ndr_hdid_t *id;
- id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, NT_DOMAIN_NULL, 0);
+ id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0);
if (id) {
bcopy(id, &param->handle, sizeof (samr_handle_t));
param->status = 0;
@@ -257,7 +257,7 @@ samr_s_LookupDomain(void *arg, ndr_xa_t *mxa)
{
struct samr_LookupDomain *param = arg;
char *domain_name;
- nt_domain_t di;
+ smb_domain_t di;
if ((domain_name = (char *)param->domain_name.str) == NULL) {
bzero(param, sizeof (struct samr_LookupDomain));
@@ -265,7 +265,7 @@ samr_s_LookupDomain(void *arg, ndr_xa_t *mxa)
return (NDR_DRC_OK);
}
- if (!nt_domain_lookup_name(domain_name, &di)) {
+ if (!smb_domain_lookup_name(domain_name, &di)) {
bzero(param, sizeof (struct samr_LookupDomain));
param->status = NT_SC_ERROR(NT_STATUS_NO_SUCH_DOMAIN);
return (NDR_DRC_OK);
@@ -370,7 +370,7 @@ samr_s_OpenDomain(void *arg, ndr_xa_t *mxa)
{
struct samr_OpenDomain *param = arg;
ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
- nt_domain_t domain;
+ smb_domain_t domain;
if (samr_hdlookup(mxa, id, SAMR_KEY_CONNECT) == NULL) {
bzero(&param->domain_handle, sizeof (samr_handle_t));
@@ -378,14 +378,14 @@ samr_s_OpenDomain(void *arg, ndr_xa_t *mxa)
return (NDR_DRC_OK);
}
- if (!nt_domain_lookup_sid((smb_sid_t *)param->sid, &domain)) {
+ if (!smb_domain_lookup_sid((smb_sid_t *)param->sid, &domain)) {
bzero(&param->domain_handle, sizeof (samr_handle_t));
param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
return (NDR_DRC_OK);
}
- if ((domain.di_type != NT_DOMAIN_BUILTIN) &&
- (domain.di_type != NT_DOMAIN_LOCAL)) {
+ if ((domain.di_type != SMB_DOMAIN_BUILTIN) &&
+ (domain.di_type != SMB_DOMAIN_LOCAL)) {
bzero(&param->domain_handle, sizeof (samr_handle_t));
param->status = NT_SC_ERROR(NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
return (NDR_DRC_OK);
@@ -444,13 +444,13 @@ samr_s_QueryDomainInfo(void *arg, ndr_xa_t *mxa)
data = (samr_keydata_t *)hd->nh_data;
switch (data->kd_type) {
- case NT_DOMAIN_BUILTIN:
+ case SMB_DOMAIN_BUILTIN:
domain = "BUILTIN";
user_cnt = 0;
alias_cnt = smb_sam_grp_cnt(data->kd_type);
break;
- case NT_DOMAIN_LOCAL:
+ case SMB_DOMAIN_LOCAL:
rc = smb_getnetbiosname(hostname, sizeof (hostname));
if (rc == 0) {
domain = hostname;
@@ -560,7 +560,7 @@ samr_s_LookupNames(void *arg, ndr_xa_t *mxa)
data = (samr_keydata_t *)hd->nh_data;
switch (data->kd_type) {
- case NT_DOMAIN_BUILTIN:
+ case SMB_DOMAIN_BUILTIN:
wka = smb_wka_lookup_name((char *)param->name.str);
if (wka != NULL) {
param->rids.n_entry = 1;
@@ -573,7 +573,7 @@ samr_s_LookupNames(void *arg, ndr_xa_t *mxa)
}
break;
- case NT_DOMAIN_LOCAL:
+ case SMB_DOMAIN_LOCAL:
status = smb_sam_lookup_name(NULL, (char *)param->name.str,
SidTypeUnknown, &account);
if (status == NT_STATUS_SUCCESS) {
@@ -697,7 +697,7 @@ samr_s_QueryUserGroups(void *arg, ndr_xa_t *mxa)
smb_sid_t *user_sid = NULL;
smb_group_t grp;
smb_giter_t gi;
- nt_domain_t di;
+ smb_domain_t di;
uint32_t status;
int size;
int ngrp_max;
@@ -709,9 +709,9 @@ samr_s_QueryUserGroups(void *arg, ndr_xa_t *mxa)
data = (samr_keydata_t *)hd->nh_data;
switch (data->kd_type) {
- case NT_DOMAIN_BUILTIN:
- case NT_DOMAIN_LOCAL:
- if (!nt_domain_lookup_type(data->kd_type, &di)) {
+ case SMB_DOMAIN_BUILTIN:
+ case SMB_DOMAIN_LOCAL:
+ if (!smb_domain_lookup_type(data->kd_type, &di)) {
status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
goto query_error;
}
@@ -828,7 +828,7 @@ samr_s_Connect(void *arg, ndr_xa_t *mxa)
struct samr_Connect *param = arg;
ndr_hdid_t *id;
- id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, NT_DOMAIN_NULL, 0);
+ id = samr_hdalloc(mxa, SAMR_KEY_CONNECT, SMB_DOMAIN_NULL, 0);
if (id) {
bcopy(id, &param->handle, sizeof (samr_handle_t));
param->status = 0;
@@ -956,10 +956,10 @@ samr_s_QueryDispInfo(void *arg, ndr_xa_t *mxa)
data = (samr_keydata_t *)hd->nh_data;
switch (data->kd_type) {
- case NT_DOMAIN_BUILTIN:
+ case SMB_DOMAIN_BUILTIN:
goto no_info;
- case NT_DOMAIN_LOCAL:
+ case SMB_DOMAIN_LOCAL:
num_users = smb_sam_usr_cnt();
start_idx = param->start_idx;
if ((num_users == 0) || (start_idx >= num_users))
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c
index ee63914a1a..dd4a064e3a 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_util.c
@@ -38,9 +38,9 @@
#include <syslog.h>
#include <smbsrv/libsmb.h>
-#include <smbsrv/libsmbrdr.h>
#include <smbsrv/libsmbns.h>
#include <smbsrv/libmlsvc.h>
+#include <smbsrv/libsmbrdr.h>
#include <smbsrv/smbinfo.h>
#include <lsalib.h>
#include <samlib.h>
@@ -138,21 +138,21 @@ mlsvc_netlogon(char *server, char *domain)
* Returns NT status codes.
*/
DWORD
-mlsvc_join(smb_domain_t *dinfo, char *user, char *plain_text)
+mlsvc_join(smb_domainex_t *dxi, char *user, char *plain_text)
{
int erc;
DWORD status;
char machine_passwd[NETR_MACHINE_ACCT_PASSWD_MAX];
smb_adjoin_status_t err;
- nt_domain_t *domain;
+ smb_domain_t *domain;
machine_passwd[0] = '\0';
- domain = &dinfo->d_info;
+ domain = &dxi->d_primary;
- mlsvc_disconnect(dinfo->d_dc);
+ mlsvc_disconnect(dxi->d_dc);
- erc = mlsvc_logon(dinfo->d_dc, domain->di_nbname, user);
+ erc = smbrdr_logon(dxi->d_dc, domain->di_nbname, user);
if (erc == AUTH_USER_GRANT) {
if (mlsvc_ntjoin_support == B_FALSE) {
@@ -167,7 +167,7 @@ mlsvc_join(smb_domain_t *dinfo, char *user, char *plain_text)
}
} else {
- status = sam_create_trust_account(dinfo->d_dc,
+ status = sam_create_trust_account(dxi->d_dc,
domain->di_nbname);
if (status == NT_STATUS_SUCCESS) {
(void) smb_getnetbiosname(machine_passwd,
@@ -177,7 +177,7 @@ mlsvc_join(smb_domain_t *dinfo, char *user, char *plain_text)
}
if (status == NT_STATUS_SUCCESS) {
- erc = smb_setdomainprops(NULL, dinfo->d_dc,
+ erc = smb_setdomainprops(NULL, dxi->d_dc,
machine_passwd);
if (erc != 0) {
syslog(LOG_NOTICE, "Failed to update CIFS "
@@ -185,7 +185,7 @@ mlsvc_join(smb_domain_t *dinfo, char *user, char *plain_text)
return (NT_STATUS_UNSUCCESSFUL);
}
- status = mlsvc_netlogon(dinfo->d_dc, domain->di_nbname);
+ status = mlsvc_netlogon(dxi->d_dc, domain->di_nbname);
}
} else {
status = NT_STATUS_LOGON_FAILURE;
@@ -193,3 +193,15 @@ mlsvc_join(smb_domain_t *dinfo, char *user, char *plain_text)
return (status);
}
+
+int
+mlsvc_ping(const char *server)
+{
+ return (smbrdr_echo(server));
+}
+
+void
+mlsvc_disconnect(const char *server)
+{
+ smbrdr_disconnect(server);
+}
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c b/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c
index a8c6c92a0e..0df79c5044 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/netr_auth.c
@@ -40,7 +40,6 @@
#include <security/pkcs11.h>
#include <smbsrv/libsmb.h>
-#include <smbsrv/libsmbrdr.h>
#include <smbsrv/libsmbns.h>
#include <smbsrv/libmlsvc.h>
#include <smbsrv/ndl/netlogon.ndl>
@@ -127,18 +126,13 @@ netlogon_auth(char *server, mlsvc_handle_t *netr_handle, DWORD flags)
int
netr_open(char *server, char *domain, mlsvc_handle_t *netr_handle)
{
- srvsvc_server_info_t svinfo;
- char *user = smbrdr_ipc_get_user();
+ char user[SMB_USERNAME_MAXLEN];
- if (srvsvc_net_server_getinfo(server, domain, &svinfo) < 0)
- return (-1);
+ smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
if (ndr_rpc_bind(netr_handle, server, domain, user, "NETR") < 0)
return (-1);
- ndr_rpc_server_setinfo(netr_handle, &svinfo);
- free(svinfo.sv_name);
- free(svinfo.sv_comment);
return (0);
}
@@ -214,7 +208,7 @@ netr_server_authenticate2(mlsvc_handle_t *netr_handle, netr_info_t *netr_info)
arg.hostname = (unsigned char *)netr_info->hostname;
arg.negotiate_flags = NETR_NEGOTIATE_BASE_FLAGS;
- if (ndr_rpc_server_os(netr_handle) != NATIVE_OS_WINNT) {
+ if (ndr_rpc_server_os(netr_handle) == NATIVE_OS_WIN2000) {
arg.negotiate_flags |= NETR_NEGOTIATE_STRONGKEY_FLAG;
if (netr_gen_skey128(netr_info) != SMBAUTH_SUCCESS)
return (-1);
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c b/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c
index 05cb6d9663..1948ccfade 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c
@@ -37,7 +37,6 @@
#include <thread.h>
#include <smbsrv/libsmb.h>
-#include <smbsrv/libsmbrdr.h>
#include <smbsrv/libmlrpc.h>
#include <smbsrv/libmlsvc.h>
#include <smbsrv/ndl/netlogon.ndl>
@@ -104,7 +103,7 @@ netlogon_logon_private(netr_client_t *clnt, smb_token_t *token)
char resource_domain[SMB_PI_MAX_DOMAIN];
char server[NETBIOS_NAME_SZ * 2];
mlsvc_handle_t netr_handle;
- smb_domain_t di;
+ smb_domainex_t di;
uint32_t status;
int retries = 0, server_changed = 0;
@@ -113,7 +112,7 @@ netlogon_logon_private(netr_client_t *clnt, smb_token_t *token)
if (!smb_domain_getinfo(&di))
return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
- if ((mlsvc_echo(di.d_dc)) < 0) {
+ if (mlsvc_ping(di.d_dc) < 0) {
/*
* We had a session to the DC but it's not responding.
* So drop the credential chain.
@@ -123,7 +122,8 @@ netlogon_logon_private(netr_client_t *clnt, smb_token_t *token)
}
do {
- if (netr_open(di.d_dc, di.d_info.di_nbname, &netr_handle) != 0)
+ if (netr_open(di.d_dc, di.d_primary.di_nbname, &netr_handle)
+ != 0)
return (NT_STATUS_OPEN_FAILED);
if (di.d_dc && (*netr_global_info.server != '\0')) {
@@ -677,13 +677,13 @@ netr_setup_domain_groups(struct netr_validation_info3 *info3, smb_ids_t *gids)
static boolean_t
netr_isadmin(struct netr_validation_info3 *info3)
{
- nt_domain_t di;
+ smb_domain_t di;
int i;
- if (!nt_domain_lookup_sid((smb_sid_t *)info3->LogonDomainId, &di))
+ if (!smb_domain_lookup_sid((smb_sid_t *)info3->LogonDomainId, &di))
return (B_FALSE);
- if (di.di_type != NT_DOMAIN_PRIMARY)
+ if (di.di_type != SMB_DOMAIN_PRIMARY)
return (B_FALSE);
if ((info3->UserId == DOMAIN_USER_RID_ADMIN) ||
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/samlib.c b/usr/src/lib/smbsrv/libmlsvc/common/samlib.c
index 18b69c89bc..0383bdc8cb 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/samlib.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/samlib.c
@@ -31,7 +31,6 @@
#include <alloca.h>
#include <smbsrv/libsmb.h>
-#include <smbsrv/libsmbrdr.h>
#include <smbsrv/libmlsvc.h>
#include <smbsrv/ntstatus.h>
@@ -114,7 +113,9 @@ sam_create_account(char *server, char *domain_name, char *account_name,
DWORD rid;
DWORD status;
int rc;
- char *user = smbrdr_ipc_get_user();
+ char user[SMB_USERNAME_MAXLEN];
+
+ smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
rc = samr_open(server, domain_name, user, SAM_CONNECT_CREATE_ACCOUNT,
&samr_handle);
@@ -199,7 +200,9 @@ sam_delete_account(char *server, char *domain_name, char *account_name)
DWORD access_mask;
DWORD status;
int rc;
- char *user = smbrdr_ipc_get_user();
+ char user[SMB_USERNAME_MAXLEN];
+
+ smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
rc = samr_open(server, domain_name, user, SAM_LOOKUP_INFORMATION,
&samr_handle);
@@ -250,7 +253,9 @@ sam_check_user(char *server, char *domain_name, char *account_name)
DWORD access_mask;
DWORD status;
int rc;
- char *user = smbrdr_ipc_get_user();
+ char user[SMB_USERNAME_MAXLEN];
+
+ smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
rc = samr_open(server, domain_name, user, SAM_LOOKUP_INFORMATION,
&samr_handle);
@@ -306,7 +311,9 @@ sam_lookup_name(char *server, char *domain_name, char *account_name,
struct samr_sid *domain_sid;
int rc;
DWORD status;
- char *user = smbrdr_ipc_get_user();
+ char user[SMB_USERNAME_MAXLEN];
+
+ smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
*rid_ret = 0;
@@ -352,7 +359,9 @@ sam_get_local_domains(char *server, char *domain_name)
mlsvc_handle_t samr_handle;
DWORD status;
int rc;
- char *user = smbrdr_ipc_get_user();
+ char user[SMB_USERNAME_MAXLEN];
+
+ smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
rc = samr_open(server, domain_name, user, SAM_ENUM_LOCAL_DOMAIN,
&samr_handle);
@@ -399,21 +408,20 @@ sam_oem_password(oem_password_t *oem_password, unsigned char *new_password,
static struct samr_sid *
sam_get_domain_sid(mlsvc_handle_t *samr_handle, char *server, char *domain_name)
{
- struct samr_sid *sid = NULL;
- smb_domain_t domain;
+ smb_sid_t *sid = NULL;
+ smb_domainex_t domain;
if (ndr_rpc_server_os(samr_handle) == NATIVE_OS_WIN2000) {
if (!smb_domain_getinfo(&domain)) {
if (lsa_query_account_domain_info(server, domain_name,
- &domain.d_info) != NT_STATUS_SUCCESS)
+ &domain.d_primary) != NT_STATUS_SUCCESS)
return (NULL);
}
- sid = (struct samr_sid *)smb_sid_fromstr(domain.d_info.di_sid);
+ sid = smb_sid_fromstr(domain.d_primary.di_sid);
} else {
- sid = (struct samr_sid *)samr_lookup_domain(samr_handle,
- domain_name);
+ sid = samr_lookup_domain(samr_handle, domain_name);
}
- return (sid);
+ return ((struct samr_sid *)sid);
}
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/samr_open.c b/usr/src/lib/smbsrv/libmlsvc/common/samr_open.c
index c3e29d2e7b..d29e7d3d64 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/samr_open.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/samr_open.c
@@ -41,7 +41,6 @@
#include <sys/param.h>
#include <smbsrv/libsmb.h>
-#include <smbsrv/libsmbrdr.h>
#include <smbsrv/libmlrpc.h>
#include <smbsrv/libmlsvc.h>
#include <smbsrv/smbinfo.h>
@@ -55,6 +54,9 @@ static DWORD samr_connect2(char *, char *, char *, DWORD, mlsvc_handle_t *);
static DWORD samr_connect3(char *, char *, char *, DWORD, mlsvc_handle_t *);
static DWORD samr_connect4(char *, char *, char *, DWORD, mlsvc_handle_t *);
+typedef DWORD (*samr_connop_t)(char *, char *, char *, DWORD,
+ mlsvc_handle_t *);
+
/*
* samr_open
*
@@ -71,7 +73,7 @@ int
samr_open(char *server, char *domain, char *username, DWORD access_mask,
mlsvc_handle_t *samr_handle)
{
- smb_domain_t di;
+ smb_domainex_t di;
int rc;
if (server == NULL || domain == NULL) {
@@ -79,7 +81,7 @@ samr_open(char *server, char *domain, char *username, DWORD access_mask,
return (-1);
server = di.d_dc;
- domain = di.d_info.di_nbname;
+ domain = di.d_primary.di_nbname;
}
if (username == NULL)
@@ -93,38 +95,41 @@ samr_open(char *server, char *domain, char *username, DWORD access_mask,
/*
* samr_connect
*
- * Connect to the SAM on the specified server (domain controller).
- * This is the entry point for the various SAM connect calls. We do
- * parameter validation and open the samr named pipe here. The actual
- * RPC is based on the native OS of the server.
+ * Connect to the SAMR service on the specified server (domain controller).
+ * New SAM connect calls have been added to Windows over time:
*
- * Returns 0 on success. Otherwise returns a -ve error code.
+ * Windows NT3.x: SamrConnect
+ * Windows NT4.0: SamrConnect2
+ * Windows 2000: SamrConnect3
+ * Windows XP: SamrConnect4
+ *
+ * Try the calls from most recent to oldest until the server responds with
+ * something other than an RPC protocol error. We don't use the original
+ * connect call because all supported servers should support SamrConnect2.
*/
int
samr_connect(char *server, char *domain, char *username, DWORD access_mask,
mlsvc_handle_t *samr_handle)
{
- DWORD status;
+ static samr_connop_t samr_connop[] = {
+ samr_connect4,
+ samr_connect3,
+ samr_connect2
+ };
+
+ int n_op = (sizeof (samr_connop) / sizeof (samr_connop[0]));
+ DWORD status;
+ int i;
if (ndr_rpc_bind(samr_handle, server, domain, username, "SAMR") < 0)
return (-1);
- switch (ndr_rpc_server_os(samr_handle)) {
- case NATIVE_OS_NT5_1:
- status = samr_connect4(server, domain, username, access_mask,
- samr_handle);
- break;
-
- case NATIVE_OS_NT5_0:
- status = samr_connect3(server, domain, username, access_mask,
- samr_handle);
- break;
-
- case NATIVE_OS_NT4_0:
- default:
- status = samr_connect2(server, domain, username, access_mask,
- samr_handle);
- break;
+ for (i = 0; i < n_op; ++i) {
+ status = (*samr_connop[i])(server, domain, username,
+ access_mask, samr_handle);
+
+ if (status != NT_STATUS_UNSUCCESSFUL)
+ break;
}
if (status != NT_STATUS_SUCCESS) {
@@ -244,7 +249,7 @@ samr_connect3(char *server, char *domain, char *username, DWORD access_mask,
len = strlen(server) + 4;
arg.servername = ndr_rpc_malloc(samr_handle, len);
(void) snprintf((char *)arg.servername, len, "\\\\%s", server);
- arg.unknown_02 = 0x00000002;
+ arg.revision = SAMR_REVISION_2;
arg.access_mask = access_mask;
if (ndr_rpc_call(samr_handle, opnum, &arg) != 0) {
@@ -283,7 +288,7 @@ samr_connect4(char *server, char *domain, char *username, DWORD access_mask,
int len;
int opnum;
DWORD status;
- smb_domain_t dinfo;
+ smb_domainex_t dinfo;
bzero(&arg, sizeof (struct samr_Connect4));
opnum = SAMR_OPNUM_Connect;
@@ -292,12 +297,12 @@ samr_connect4(char *server, char *domain, char *username, DWORD access_mask,
if (!smb_domain_getinfo(&dinfo))
return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
- len = strlen(server) + strlen(dinfo.d_info.di_fqname) + 4;
+ len = strlen(server) + strlen(dinfo.d_primary.di_fqname) + 4;
arg.servername = ndr_rpc_malloc(samr_handle, len);
- if (*dinfo.d_info.di_fqname != '\0')
+ if (*dinfo.d_primary.di_fqname != '\0')
(void) snprintf((char *)arg.servername, len, "\\\\%s.%s",
- server, dinfo.d_info.di_fqname);
+ server, dinfo.d_primary.di_fqname);
else
(void) snprintf((char *)arg.servername, len, "\\\\%s", server);
@@ -572,7 +577,7 @@ samr_create_user(mlsvc_handle_t *domain_handle, char *username,
ndr_heap_mkvcs(heap, username, (ndr_vcstr_t *)&arg.username);
arg.account_flags = account_flags;
- arg.unknown_e00500b0 = 0xE00500B0;
+ arg.desired_access = 0xE00500B0;
rc = ndr_rpc_call(domain_handle, opnum, &arg);
if (rc != 0) {
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/smb_logon.c b/usr/src/lib/smbsrv/libmlsvc/common/smb_logon.c
index cca5528276..3a13d331d0 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/smb_logon.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/smb_logon.c
@@ -490,13 +490,13 @@ smb_logon_local(netr_client_t *clnt, smb_token_t *token)
char guest[SMB_USERNAME_MAXLEN];
smb_passwd_t smbpw;
uint32_t status;
- nt_domain_t domain;
+ smb_domain_t domain;
boolean_t isguest;
/* Make sure this is not a domain user */
if (smb_config_get_secmode() == SMB_SECMODE_DOMAIN) {
- if (nt_domain_lookup_name(clnt->e_domain, &domain)) {
- if (domain.di_type != NT_DOMAIN_LOCAL)
+ if (smb_domain_lookup_name(clnt->e_domain, &domain)) {
+ if (domain.di_type != SMB_DOMAIN_LOCAL)
return (NT_STATUS_INVALID_LOGON_TYPE);
}
}
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_clnt.c b/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_clnt.c
index 9a05c08956..e7d592e998 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_clnt.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_clnt.c
@@ -39,7 +39,6 @@
#include <time.h>
#include <smbsrv/libsmb.h>
-#include <smbsrv/libsmbrdr.h>
#include <smbsrv/libmlsvc.h>
#include <smbsrv/smbinfo.h>
#include <smbsrv/ntstatus.h>
@@ -61,14 +60,14 @@ static int srvsvc_net_remote_tod(char *, char *, struct timeval *, struct tm *);
static int
srvsvc_open(char *server, char *domain, char *username, mlsvc_handle_t *handle)
{
- smb_domain_t di;
+ smb_domainex_t di;
if (server == NULL || domain == NULL) {
if (!smb_domain_getinfo(&di))
return (-1);
server = di.d_dc;
- domain = di.d_info.di_nbname;
+ domain = di.d_primary.di_nbname;
}
if (username == NULL)
@@ -105,13 +104,13 @@ srvsvc_net_share_get_info(char *server, char *domain, char *netname)
struct mslm_NetShareInfo_1 *info1;
struct mslm_NetShareInfo_2 *info2;
int len;
- char *user = NULL;
+ char user[SMB_USERNAME_MAXLEN];
if (netname == NULL)
return (-1);
if (srvsvc_info_level == 2)
- user = smbrdr_ipc_get_user();
+ smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
if (srvsvc_open(server, domain, user, &handle) != 0)
return (-1);
@@ -195,11 +194,13 @@ srvsvc_net_session_enum(char *server, char *domain, char *netname)
struct mslm_infonres infonres;
struct mslm_SESSION_INFO_1 *nsi1;
int len;
- char *user = smbrdr_ipc_get_user();
+ char user[SMB_USERNAME_MAXLEN];
if (netname == NULL)
return (-1);
+ smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
+
rc = srvsvc_open(server, domain, user, &handle);
if (rc != 0)
return (-1);
@@ -260,11 +261,13 @@ srvsvc_net_connect_enum(char *server, char *domain, char *netname, int level)
struct mslm_NetConnectInfo0 info0;
struct mslm_NetConnectInfoBuf1 *cib1;
int len;
- char *user = smbrdr_ipc_get_user();
+ char user[SMB_USERNAME_MAXLEN];
if (netname == NULL)
return (-1);
+ smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
+
rc = srvsvc_open(server, domain, user, &handle);
if (rc != 0)
return (-1);
@@ -347,6 +350,10 @@ srvsvc_net_connect_enum(char *server, char *domain, char *netname, int level)
return (0);
}
+/*
+ * Windows 95+ and Windows NT4.0 both report the version as 4.0.
+ * Windows 2000+ reports the version as 5.x.
+ */
int
srvsvc_net_server_getinfo(char *server, char *domain,
srvsvc_server_info_t *svinfo)
@@ -355,7 +362,9 @@ srvsvc_net_server_getinfo(char *server, char *domain,
struct mslm_NetServerGetInfo arg;
struct mslm_SERVER_INFO_101 *sv101;
int len, opnum, rc;
- char *user = smbrdr_ipc_get_user();
+ char user[SMB_USERNAME_MAXLEN];
+
+ smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
if (srvsvc_open(server, domain, user, &handle) != 0)
return (-1);
@@ -389,6 +398,16 @@ srvsvc_net_server_getinfo(char *server, char *domain,
if (sv101->sv101_comment)
svinfo->sv_comment = strdup((char *)sv101->sv101_comment);
+ if (svinfo->sv_type & SV_TYPE_WFW)
+ svinfo->sv_os = NATIVE_OS_WIN95;
+ if (svinfo->sv_type & SV_TYPE_WINDOWS)
+ svinfo->sv_os = NATIVE_OS_WIN95;
+ if ((svinfo->sv_type & SV_TYPE_NT) ||
+ (svinfo->sv_type & SV_TYPE_SERVER_NT))
+ svinfo->sv_os = NATIVE_OS_WINNT;
+ if (svinfo->sv_version_major > 4)
+ svinfo->sv_os = NATIVE_OS_WIN2000;
+
srvsvc_close(&handle);
return (0);
}
@@ -399,7 +418,7 @@ srvsvc_net_server_getinfo(char *server, char *domain,
void
srvsvc_timesync(void)
{
- smb_domain_t di;
+ smb_domainex_t di;
struct timeval tv;
struct tm tm;
time_t tsecs;
@@ -407,7 +426,8 @@ srvsvc_timesync(void)
if (!smb_domain_getinfo(&di))
return;
- if (srvsvc_net_remote_tod(di.d_dc, di.d_info.di_nbname, &tv, &tm) != 0)
+ if (srvsvc_net_remote_tod(di.d_dc, di.d_primary.di_nbname, &tv, &tm)
+ != 0)
return;
if (settimeofday(&tv, 0))
@@ -424,14 +444,15 @@ srvsvc_timesync(void)
int
srvsvc_gettime(unsigned long *t)
{
- smb_domain_t di;
+ smb_domainex_t di;
struct timeval tv;
struct tm tm;
if (!smb_domain_getinfo(&di))
return (-1);
- if (srvsvc_net_remote_tod(di.d_dc, di.d_info.di_nbname, &tv, &tm) != 0)
+ if (srvsvc_net_remote_tod(di.d_dc, di.d_primary.di_nbname, &tv, &tm)
+ != 0)
return (-1);
*t = tv.tv_sec;
@@ -477,7 +498,9 @@ srvsvc_net_remote_tod(char *server, char *domain, struct timeval *tv,
int rc;
int opnum;
int len;
- char *user = smbrdr_ipc_get_user();
+ char user[SMB_USERNAME_MAXLEN];
+
+ smb_ipc_get_user(user, SMB_USERNAME_MAXLEN);
rc = srvsvc_open(server, domain, user, &handle);
if (rc != 0)
@@ -535,14 +558,14 @@ srvsvc_net_remote_tod(char *server, char *domain, struct timeval *tv,
void
srvsvc_net_test(char *server, char *domain, char *netname)
{
- smb_domain_t di;
+ smb_domainex_t di;
srvsvc_server_info_t svinfo;
(void) smb_tracef("%s %s %s", server, domain, netname);
if (smb_domain_getinfo(&di)) {
server = di.d_dc;
- domain = di.d_info.di_nbname;
+ domain = di.d_primary.di_nbname;
}
if (srvsvc_net_server_getinfo(server, domain, &svinfo) == 0) {
diff --git a/usr/src/lib/smbsrv/libsmb/common/libsmb.h b/usr/src/lib/smbsrv/libsmb/common/libsmb.h
index 32b54d2a65..029294f3a7 100644
--- a/usr/src/lib/smbsrv/libsmb/common/libsmb.h
+++ b/usr/src/lib/smbsrv/libsmb/common/libsmb.h
@@ -484,6 +484,16 @@ boolean_t smb_auth_validate_nt(unsigned char *, uint32_t, smb_passwd_t *,
unsigned char *, int, char *, char *, uchar_t *);
/*
+ * SMB authenticated IPC
+ */
+extern void smb_ipc_commit(void);
+extern void smb_ipc_get_user(char *, size_t);
+extern void smb_ipc_get_passwd(uint8_t *, size_t);
+extern void smb_ipc_init(void);
+extern void smb_ipc_rollback(void);
+extern void smb_ipc_set(char *, uint8_t *);
+
+/*
* SMB MAC Signing
*/
@@ -553,16 +563,16 @@ extern void smb_mac_dec_seqnum(smb_sign_ctx_t *sign_ctx);
* that the system joined. All other domains are either
* trusted or untrusted, as defined by the primary domain PDC.
*/
-typedef enum nt_domain_type {
- NT_DOMAIN_NULL,
- NT_DOMAIN_BUILTIN,
- NT_DOMAIN_LOCAL,
- NT_DOMAIN_PRIMARY,
- NT_DOMAIN_ACCOUNT,
- NT_DOMAIN_TRUSTED,
- NT_DOMAIN_UNTRUSTED,
- NT_DOMAIN_NUM_TYPES
-} nt_domain_type_t;
+typedef enum smb_domain_type {
+ SMB_DOMAIN_NULL,
+ SMB_DOMAIN_BUILTIN,
+ SMB_DOMAIN_LOCAL,
+ SMB_DOMAIN_PRIMARY,
+ SMB_DOMAIN_ACCOUNT,
+ SMB_DOMAIN_TRUSTED,
+ SMB_DOMAIN_UNTRUSTED,
+ SMB_DOMAIN_NUM_TYPES
+} smb_domain_type_t;
/*
* Information specific to trusted domains
@@ -586,9 +596,9 @@ typedef struct smb_domain_dns {
/*
* This is the information that is held about each domain.
*/
-typedef struct nt_domain {
+typedef struct smb_domain {
list_node_t di_lnd;
- nt_domain_type_t di_type;
+ smb_domain_type_t di_type;
char di_sid[SMB_SID_STRSZ];
char di_nbname[NETBIOS_NAME_SZ];
char di_fqname[MAXHOSTNAMELEN];
@@ -597,11 +607,11 @@ typedef struct nt_domain {
smb_domain_dns_t di_dns;
smb_domain_trust_t di_trust;
} di_u;
-} nt_domain_t;
+} smb_domain_t;
typedef struct smb_trusted_domains {
uint32_t td_num;
- nt_domain_t *td_domains;
+ smb_domain_t *td_domains;
} smb_trusted_domains_t;
#define SMB_DOMAIN_SUCCESS 0
@@ -611,29 +621,38 @@ typedef struct smb_trusted_domains {
#define SMB_DOMAIN_INTERNAL_ERR 4
#define SMB_DOMAIN_INVALID_ARG 5
#define SMB_DOMAIN_NO_MEMORY 6
+#define SMB_DOMAIN_NO_CACHE 7
-typedef struct smb_domain {
+/*
+ * This structure could contain information about
+ * the primary domain the name of selected domain controller
+ * for the primary domain and a list of trusted domains if
+ * any. The "ex" in the structure name stands for extended.
+ * This is to differentiate this structure from smb_domain_t
+ * which only contains information about a single domain.
+ */
+typedef struct smb_domainex {
char d_dc[MAXHOSTNAMELEN];
- nt_domain_t d_info;
+ smb_domain_t d_primary;
smb_trusted_domains_t d_trusted;
-} smb_domain_t;
-
-int nt_domain_init(uint32_t);
-void nt_domain_fini(void);
-void nt_domain_show(void);
-void nt_domain_save(void);
-boolean_t nt_domain_lookup_name(char *, nt_domain_t *);
-boolean_t nt_domain_lookup_sid(smb_sid_t *, nt_domain_t *);
-boolean_t nt_domain_lookup_type(nt_domain_type_t, nt_domain_t *);
-boolean_t nt_domain_get_primary(smb_domain_t *);
-void nt_domain_update(smb_domain_t *);
-void nt_domain_start_update(void);
-void nt_domain_end_update(void);
-void nt_domain_set_basic_info(char *, char *, char *, nt_domain_t *);
-void nt_domain_set_dns_info(char *, char *, char *, char *, char *,
- nt_domain_t *);
-void nt_domain_set_trust_info(char *, char *, char *,
- uint32_t, uint32_t, uint32_t, nt_domain_t *);
+} smb_domainex_t;
+
+int smb_domain_init(uint32_t);
+void smb_domain_fini(void);
+void smb_domain_show(void);
+void smb_domain_save(void);
+boolean_t smb_domain_lookup_name(char *, smb_domain_t *);
+boolean_t smb_domain_lookup_sid(smb_sid_t *, smb_domain_t *);
+boolean_t smb_domain_lookup_type(smb_domain_type_t, smb_domain_t *);
+boolean_t smb_domain_getinfo(smb_domainex_t *);
+void smb_domain_update(smb_domainex_t *);
+uint32_t smb_domain_start_update(void);
+void smb_domain_end_update(void);
+void smb_domain_set_basic_info(char *, char *, char *, smb_domain_t *);
+void smb_domain_set_dns_info(char *, char *, char *, char *, char *,
+ smb_domain_t *);
+void smb_domain_set_trust_info(char *, char *, char *,
+ uint32_t, uint32_t, uint32_t, smb_domain_t *);
typedef enum {
SMB_LGRP_BUILTIN = 1,
@@ -823,7 +842,7 @@ uint32_t smb_sam_lookup_name(char *, char *, uint16_t, smb_account_t *);
uint32_t smb_sam_lookup_sid(smb_sid_t *, smb_account_t *);
int smb_sam_usr_cnt(void);
uint32_t smb_sam_usr_groups(smb_sid_t *, smb_ids_t *);
-int smb_sam_grp_cnt(nt_domain_type_t);
+int smb_sam_grp_cnt(smb_domain_type_t);
void smb_account_free(smb_account_t *);
boolean_t smb_account_validate(smb_account_t *);
diff --git a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers
index 34281749c5..0f895b0654 100644
--- a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers
+++ b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers
@@ -84,20 +84,6 @@ SUNWprivate {
mts_wctomb;
netr_client_mkabsolute;
netr_client_xfree;
- nt_domain_end_update;
- nt_domain_fini;
- nt_domain_get_primary;
- nt_domain_init;
- nt_domain_lookup_name;
- nt_domain_lookup_sid;
- nt_domain_lookup_type;
- nt_domain_save;
- nt_domain_set_basic_info;
- nt_domain_set_dns_info;
- nt_domain_set_trust_info;
- nt_domain_show;
- nt_domain_start_update;
- nt_domain_update;
oem_get_smb_cpid;
oem_get_telnet_cpid;
oem_language_set;
@@ -149,6 +135,20 @@ SUNWprivate {
smb_ctxbuf_printf;
smb_dlclose;
smb_dlopen;
+ smb_domain_end_update;
+ smb_domain_fini;
+ smb_domain_getinfo;
+ smb_domain_init;
+ smb_domain_lookup_name;
+ smb_domain_lookup_sid;
+ smb_domain_lookup_type;
+ smb_domain_save;
+ smb_domain_set_basic_info;
+ smb_domain_set_dns_info;
+ smb_domain_set_trust_info;
+ smb_domain_show;
+ smb_domain_start_update;
+ smb_domain_update;
smb_dr_clnt_call;
smb_dr_clnt_cleanup;
smb_dr_clnt_setup;
@@ -220,6 +220,12 @@ SUNWprivate {
smb_inet_equal;
smb_inet_iszero;
smb_inet_ntop;
+ smb_ipc_set;
+ smb_ipc_commit;
+ smb_ipc_init;
+ smb_ipc_rollback;
+ smb_ipc_get_user;
+ smb_ipc_get_passwd;
smb_kmod_bind;
smb_kmod_enum;
smb_kmod_enum_init;
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_domain.c b/usr/src/lib/smbsrv/libsmb/common/smb_domain.c
index d448f6a665..42ff0657ac 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_domain.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_domain.c
@@ -77,21 +77,21 @@ typedef struct smb_domain_cache {
static smb_domain_cache_t smb_dcache;
-static uint32_t nt_domain_add(nt_domain_type_t, nt_domain_t *);
-static uint32_t nt_domain_add_local(void);
-static uint32_t nt_domain_add_primary(uint32_t);
-static void nt_domain_unlink(void);
+static uint32_t smb_domain_add(smb_domain_type_t, smb_domain_t *);
+static uint32_t smb_domain_add_local(void);
+static uint32_t smb_domain_add_primary(uint32_t);
+static void smb_domain_unlink(void);
static void smb_dcache_create(void);
static void smb_dcache_destroy(void);
static uint32_t smb_dcache_lock(int);
static void smb_dcache_unlock(void);
-static void smb_dcache_remove(nt_domain_t *);
-static uint32_t smb_dcache_add(nt_domain_t *);
+static void smb_dcache_remove(smb_domain_t *);
+static uint32_t smb_dcache_add(smb_domain_t *);
static void smb_dcache_getdc(char *, size_t);
static void smb_dcache_setdc(char *);
static boolean_t smb_dcache_wait(void);
-static void smb_dcache_updating(void);
+static uint32_t smb_dcache_updating(void);
static void smb_dcache_ready(void);
/*
@@ -101,30 +101,30 @@ static void smb_dcache_ready(void);
* Returns 0 on success and an error code on failure.
*/
int
-nt_domain_init(uint32_t secmode)
+smb_domain_init(uint32_t secmode)
{
- nt_domain_t di;
+ smb_domain_t di;
int rc;
smb_dcache_create();
- if ((rc = nt_domain_add_local()) != 0)
+ if ((rc = smb_domain_add_local()) != 0)
return (rc);
- nt_domain_set_basic_info(NT_BUILTIN_DOMAIN_SIDSTR, "BUILTIN", "", &di);
- (void) nt_domain_add(NT_DOMAIN_BUILTIN, &di);
+ smb_domain_set_basic_info(NT_BUILTIN_DOMAIN_SIDSTR, "BUILTIN", "", &di);
+ (void) smb_domain_add(SMB_DOMAIN_BUILTIN, &di);
- return (nt_domain_add_primary(secmode));
+ return (smb_domain_add_primary(secmode));
}
/*
* Destroys the cache upon service termination
*/
void
-nt_domain_fini(void)
+smb_domain_fini(void)
{
smb_dcache_destroy();
- nt_domain_unlink();
+ smb_domain_unlink();
}
/*
@@ -132,7 +132,7 @@ nt_domain_fini(void)
* for duplicates.
*/
static uint32_t
-nt_domain_add(nt_domain_type_t type, nt_domain_t *di)
+smb_domain_add(smb_domain_type_t type, smb_domain_t *di)
{
uint32_t res;
@@ -160,13 +160,13 @@ nt_domain_add(nt_domain_type_t type, nt_domain_t *di)
* If the domain is not in the cache B_FALSE is returned.
*/
boolean_t
-nt_domain_lookup_name(char *name, nt_domain_t *di)
+smb_domain_lookup_name(char *name, smb_domain_t *di)
{
boolean_t found = B_FALSE;
- nt_domain_t *dcnode;
+ smb_domain_t *dcnode;
char *p;
- bzero(di, sizeof (nt_domain_t));
+ bzero(di, sizeof (smb_domain_t));
if (name == NULL || *name == '\0')
return (B_FALSE);
@@ -214,13 +214,13 @@ nt_domain_lookup_name(char *name, nt_domain_t *di)
* If the domain is not in the cache B_FALSE is returned.
*/
boolean_t
-nt_domain_lookup_sid(smb_sid_t *sid, nt_domain_t *di)
+smb_domain_lookup_sid(smb_sid_t *sid, smb_domain_t *di)
{
boolean_t found = B_FALSE;
- nt_domain_t *dcnode;
+ smb_domain_t *dcnode;
char sidstr[SMB_SID_STRSZ];
- bzero(di, sizeof (nt_domain_t));
+ bzero(di, sizeof (smb_domain_t));
if (sid == NULL)
return (B_FALSE);
@@ -257,12 +257,12 @@ nt_domain_lookup_sid(smb_sid_t *sid, nt_domain_t *di)
* If the domain is not in the cache B_FALSE is returned.
*/
boolean_t
-nt_domain_lookup_type(nt_domain_type_t type, nt_domain_t *di)
+smb_domain_lookup_type(smb_domain_type_t type, smb_domain_t *di)
{
boolean_t found = B_FALSE;
- nt_domain_t *dcnode;
+ smb_domain_t *dcnode;
- bzero(di, sizeof (nt_domain_t));
+ bzero(di, sizeof (smb_domain_t));
if (smb_dcache_lock(SMB_DCACHE_RDLOCK) != SMB_DOMAIN_SUCCESS)
return (B_FALSE);
@@ -288,13 +288,13 @@ nt_domain_lookup_type(nt_domain_type_t type, nt_domain_t *di)
* the selected domain controller.
*/
boolean_t
-nt_domain_get_primary(smb_domain_t *domain)
+smb_domain_getinfo(smb_domainex_t *dxi)
{
boolean_t success;
- success = nt_domain_lookup_type(NT_DOMAIN_PRIMARY, &domain->d_info);
+ success = smb_domain_lookup_type(SMB_DOMAIN_PRIMARY, &dxi->d_primary);
if (success)
- smb_dcache_getdc(domain->d_dc, sizeof (domain->d_dc));
+ smb_dcache_getdc(dxi->d_dc, sizeof (dxi->d_dc));
return (success);
}
@@ -304,17 +304,17 @@ nt_domain_get_primary(smb_domain_t *domain)
* In this state any request for reading the cache would
* be blocked until the update is finished.
*/
-void
-nt_domain_start_update(void)
+uint32_t
+smb_domain_start_update(void)
{
- smb_dcache_updating();
+ return (smb_dcache_updating());
}
/*
* Transfer the cache from updating to ready state.
*/
void
-nt_domain_end_update(void)
+smb_domain_end_update(void)
{
smb_dcache_ready();
}
@@ -328,9 +328,9 @@ nt_domain_end_update(void)
* primary and trusted will be removed from cache.
*/
void
-nt_domain_update(smb_domain_t *domain)
+smb_domain_update(smb_domainex_t *dxi)
{
- nt_domain_t *dcnode;
+ smb_domain_t *dcnode;
int i;
if (smb_dcache_lock(SMB_DCACHE_WRLOCK) != SMB_DOMAIN_SUCCESS)
@@ -338,8 +338,8 @@ nt_domain_update(smb_domain_t *domain)
dcnode = list_head(&smb_dcache.dc_cache);
while (dcnode) {
- if ((dcnode->di_type == NT_DOMAIN_PRIMARY) ||
- (dcnode->di_type == NT_DOMAIN_TRUSTED)) {
+ if ((dcnode->di_type == SMB_DOMAIN_PRIMARY) ||
+ (dcnode->di_type == SMB_DOMAIN_TRUSTED)) {
smb_dcache_remove(dcnode);
dcnode = list_head(&smb_dcache.dc_cache);
} else {
@@ -347,11 +347,11 @@ nt_domain_update(smb_domain_t *domain)
}
}
- if (smb_dcache_add(&domain->d_info) == SMB_DOMAIN_SUCCESS) {
- for (i = 0; i < domain->d_trusted.td_num; i++)
- (void) smb_dcache_add(&domain->d_trusted.td_domains[i]);
+ if (smb_dcache_add(&dxi->d_primary) == SMB_DOMAIN_SUCCESS) {
+ for (i = 0; i < dxi->d_trusted.td_num; i++)
+ (void) smb_dcache_add(&dxi->d_trusted.td_domains[i]);
- smb_dcache_setdc(domain->d_dc);
+ smb_dcache_setdc(dxi->d_dc);
}
smb_dcache_unlock();
@@ -361,11 +361,11 @@ nt_domain_update(smb_domain_t *domain)
* Write the list of domains to /var/run/smb/domains.
*/
void
-nt_domain_save(void)
+smb_domain_save(void)
{
char fname[MAXPATHLEN];
char tag;
- nt_domain_t *domain;
+ smb_domain_t *domain;
FILE *fp;
struct passwd *pwd;
struct group *grp;
@@ -393,16 +393,16 @@ nt_domain_save(void)
domain = list_head(&smb_dcache.dc_cache);
while (domain) {
switch (domain->di_type) {
- case NT_DOMAIN_PRIMARY:
+ case SMB_DOMAIN_PRIMARY:
tag = '*';
break;
- case NT_DOMAIN_TRUSTED:
- case NT_DOMAIN_UNTRUSTED:
+ case SMB_DOMAIN_TRUSTED:
+ case SMB_DOMAIN_UNTRUSTED:
tag = '-';
break;
- case NT_DOMAIN_LOCAL:
+ case SMB_DOMAIN_LOCAL:
tag = '.';
break;
default:
@@ -425,7 +425,7 @@ nt_domain_save(void)
* List the domains in /var/run/smb/domains.
*/
void
-nt_domain_show(void)
+smb_domain_show(void)
{
char buf[MAXPATHLEN];
char *p;
@@ -449,8 +449,8 @@ nt_domain_show(void)
}
void
-nt_domain_set_basic_info(char *sid, char *nb_domain, char *fq_domain,
- nt_domain_t *di)
+smb_domain_set_basic_info(char *sid, char *nb_domain, char *fq_domain,
+ smb_domain_t *di)
{
if (sid == NULL || nb_domain == NULL || fq_domain == NULL ||
di == NULL)
@@ -464,31 +464,31 @@ nt_domain_set_basic_info(char *sid, char *nb_domain, char *fq_domain,
}
void
-nt_domain_set_dns_info(char *sid, char *nb_domain, char *fq_domain,
- char *forest, char *guid, nt_domain_t *di)
+smb_domain_set_dns_info(char *sid, char *nb_domain, char *fq_domain,
+ char *forest, char *guid, smb_domain_t *di)
{
if (di == NULL || forest == NULL || guid == NULL)
return;
- nt_domain_set_basic_info(sid, nb_domain, fq_domain, di);
+ smb_domain_set_basic_info(sid, nb_domain, fq_domain, di);
(void) strlcpy(di->di_u.di_dns.ddi_forest, forest, MAXHOSTNAMELEN);
(void) strlcpy(di->di_u.di_dns.ddi_guid, guid,
UUID_PRINTABLE_STRING_LENGTH);
}
void
-nt_domain_set_trust_info(char *sid, char *nb_domain, char *fq_domain,
+smb_domain_set_trust_info(char *sid, char *nb_domain, char *fq_domain,
uint32_t trust_dir, uint32_t trust_type, uint32_t trust_attrs,
- nt_domain_t *di)
+ smb_domain_t *di)
{
smb_domain_trust_t *ti;
if (di == NULL)
return;
- di->di_type = NT_DOMAIN_TRUSTED;
+ di->di_type = SMB_DOMAIN_TRUSTED;
ti = &di->di_u.di_trust;
- nt_domain_set_basic_info(sid, nb_domain, fq_domain, di);
+ smb_domain_set_basic_info(sid, nb_domain, fq_domain, di);
ti->dti_trust_direction = trust_dir;
ti->dti_trust_type = trust_type;
ti->dti_trust_attrs = trust_attrs;
@@ -498,7 +498,7 @@ nt_domain_set_trust_info(char *sid, char *nb_domain, char *fq_domain,
* Remove the /var/run/smb/domains file.
*/
static void
-nt_domain_unlink(void)
+smb_domain_unlink(void)
{
char fname[MAXPATHLEN];
@@ -511,12 +511,12 @@ nt_domain_unlink(void)
* Add an entry for the local domain to the domain cache
*/
static uint32_t
-nt_domain_add_local(void)
+smb_domain_add_local(void)
{
char *lsidstr;
char hostname[NETBIOS_NAME_SZ];
char fq_name[MAXHOSTNAMELEN];
- nt_domain_t di;
+ smb_domain_t di;
if ((lsidstr = smb_config_get_localsid()) == NULL)
return (SMB_DOMAIN_NOMACHINE_SID);
@@ -528,8 +528,8 @@ nt_domain_add_local(void)
*fq_name = '\0';
(void) smb_getfqhostname(fq_name, MAXHOSTNAMELEN);
- nt_domain_set_basic_info(lsidstr, hostname, fq_name, &di);
- (void) nt_domain_add(NT_DOMAIN_LOCAL, &di);
+ smb_domain_set_basic_info(lsidstr, hostname, fq_name, &di);
+ (void) smb_domain_add(SMB_DOMAIN_LOCAL, &di);
free(lsidstr);
return (SMB_DOMAIN_SUCCESS);
@@ -539,12 +539,12 @@ nt_domain_add_local(void)
* Add an entry for the primary domain to the domain cache
*/
static uint32_t
-nt_domain_add_primary(uint32_t secmode)
+smb_domain_add_primary(uint32_t secmode)
{
char sidstr[SMB_SID_STRSZ];
char fq_name[MAXHOSTNAMELEN];
char nb_name[NETBIOS_NAME_SZ];
- nt_domain_t di;
+ smb_domain_t di;
int rc;
if (secmode != SMB_SECMODE_DOMAIN)
@@ -559,8 +559,8 @@ nt_domain_add_primary(uint32_t secmode)
return (SMB_DOMAIN_NODOMAIN_NAME);
(void) smb_getfqdomainname(fq_name, MAXHOSTNAMELEN);
- nt_domain_set_basic_info(sidstr, nb_name, fq_name, &di);
- (void) nt_domain_add(NT_DOMAIN_PRIMARY, &di);
+ smb_domain_set_basic_info(sidstr, nb_name, fq_name, &di);
+ (void) smb_domain_add(SMB_DOMAIN_PRIMARY, &di);
return (SMB_DOMAIN_SUCCESS);
}
@@ -577,8 +577,8 @@ smb_dcache_create(void)
return;
}
- list_create(&smb_dcache.dc_cache, sizeof (nt_domain_t),
- offsetof(nt_domain_t, di_lnd));
+ list_create(&smb_dcache.dc_cache, sizeof (smb_domain_t),
+ offsetof(smb_domain_t, di_lnd));
smb_dcache.dc_nops = 0;
*smb_dcache.dc_server = '\0';
@@ -592,7 +592,7 @@ smb_dcache_create(void)
static void
smb_dcache_flush(void)
{
- nt_domain_t *di;
+ smb_domain_t *di;
(void) rw_wrlock(&smb_dcache.dc_cache_lck);
while ((di = list_head(&smb_dcache.dc_cache)) != NULL)
@@ -687,11 +687,11 @@ smb_dcache_unlock(void)
}
static uint32_t
-smb_dcache_add(nt_domain_t *di)
+smb_dcache_add(smb_domain_t *di)
{
- nt_domain_t *dcnode;
+ smb_domain_t *dcnode;
- if ((dcnode = malloc(sizeof (nt_domain_t))) == NULL)
+ if ((dcnode = malloc(sizeof (smb_domain_t))) == NULL)
return (SMB_DOMAIN_NO_MEMORY);
*dcnode = *di;
@@ -706,7 +706,7 @@ smb_dcache_add(nt_domain_t *di)
}
static void
-smb_dcache_remove(nt_domain_t *di)
+smb_dcache_remove(smb_domain_t *di)
{
list_remove(&smb_dcache.dc_cache, di);
smb_sid_free(di->di_binsid);
@@ -729,6 +729,11 @@ smb_dcache_getdc(char *buf, size_t buflen)
(void) mutex_unlock(&smb_dcache.dc_mtx);
}
+/*
+ * Waits for SMB_DCACHE_UPDATE_WAIT seconds if cache is in
+ * UPDATING state. Upon wake up returns true if cache is
+ * ready to be used, otherwise it returns false.
+ */
static boolean_t
smb_dcache_wait(void)
{
@@ -747,24 +752,77 @@ smb_dcache_wait(void)
return (smb_dcache.dc_state == SMB_DCACHE_STATE_READY);
}
-static void
+/*
+ * Transfers the cache into UPDATING state, this will ensure
+ * any read access to the cache will be stalled until the
+ * update is finished. This is to avoid providing incomplete,
+ * inconsistent or stale information.
+ *
+ * If another thread is already updating the cache, other
+ * callers will wait until cache is no longer in UPDATING
+ * state. The return code is decided based on the new
+ * state of the cache.
+ */
+static uint32_t
smb_dcache_updating(void)
{
+ uint32_t rc;
+
(void) mutex_lock(&smb_dcache.dc_mtx);
- if (smb_dcache.dc_state == SMB_DCACHE_STATE_READY)
+ switch (smb_dcache.dc_state) {
+ case SMB_DCACHE_STATE_READY:
smb_dcache.dc_state = SMB_DCACHE_STATE_UPDATING;
- else
- assert(0);
+ rc = SMB_DOMAIN_SUCCESS;
+ break;
+
+ case SMB_DCACHE_STATE_UPDATING:
+ while (smb_dcache.dc_state == SMB_DCACHE_STATE_UPDATING)
+ (void) cond_wait(&smb_dcache.dc_cv,
+ &smb_dcache.dc_mtx);
+
+ if (smb_dcache.dc_state == SMB_DCACHE_STATE_READY) {
+ smb_dcache.dc_state = SMB_DCACHE_STATE_UPDATING;
+ rc = SMB_DOMAIN_SUCCESS;
+ } else {
+ rc = SMB_DOMAIN_NO_CACHE;
+ }
+ break;
+
+ case SMB_DCACHE_STATE_NONE:
+ case SMB_DCACHE_STATE_DESTROYING:
+ rc = SMB_DOMAIN_NO_CACHE;
+ break;
+
+ default:
+ break;
+ }
+
(void) mutex_unlock(&smb_dcache.dc_mtx);
+ return (rc);
}
+/*
+ * Transfers the cache from UPDATING to READY state.
+ *
+ * Nothing will happen if the cache is no longer available
+ * or it is being destroyed.
+ */
static void
smb_dcache_ready(void)
{
(void) mutex_lock(&smb_dcache.dc_mtx);
- if (smb_dcache.dc_state == SMB_DCACHE_STATE_UPDATING)
+ switch (smb_dcache.dc_state) {
+ case SMB_DCACHE_STATE_UPDATING:
smb_dcache.dc_state = SMB_DCACHE_STATE_READY;
- else
+ (void) cond_broadcast(&smb_dcache.dc_cv);
+ break;
+
+ case SMB_DCACHE_STATE_NONE:
+ case SMB_DCACHE_STATE_DESTROYING:
+ break;
+
+ default:
assert(0);
+ }
(void) mutex_unlock(&smb_dcache.dc_mtx);
}
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_info.c b/usr/src/lib/smbsrv/libsmb/common/smb_info.c
index 7168dcd84c..691d2e99ed 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_info.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_info.c
@@ -48,6 +48,18 @@
static mutex_t seqnum_mtx;
/*
+ * IPC connection information that may be passed to the SMB Redirector.
+ */
+typedef struct {
+ char user[SMB_USERNAME_MAXLEN];
+ uint8_t passwd[SMBAUTH_HASH_SZ];
+} smb_ipc_t;
+
+static smb_ipc_t ipc_info;
+static smb_ipc_t ipc_orig_info;
+static rwlock_t smb_ipc_lock;
+
+/*
* Some older clients (Windows 98) only handle the low byte
* of the max workers value. If the low byte is less than
* SMB_PI_MAX_WORKERS_MIN set it to SMB_PI_MAX_WORKERS_MIN.
@@ -282,6 +294,108 @@ smb_set_machine_passwd(char *passwd)
return (rc);
}
+static int
+smb_get_machine_passwd(uint8_t *buf, size_t buflen)
+{
+ char pwd[SMB_PASSWD_MAXLEN + 1];
+ int rc;
+
+ if (buflen < SMBAUTH_HASH_SZ)
+ return (-1);
+
+ 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(pwd, buf) != 0)
+ return (-1);
+
+ return (rc);
+}
+
+/*
+ * Set up IPC connection credentials.
+ */
+void
+smb_ipc_init(void)
+{
+ int rc;
+
+ (void) rw_wrlock(&smb_ipc_lock);
+ bzero(&ipc_info, sizeof (smb_ipc_t));
+ bzero(&ipc_orig_info, sizeof (smb_ipc_t));
+
+ (void) smb_getsamaccount(ipc_info.user, SMB_USERNAME_MAXLEN);
+ rc = smb_get_machine_passwd(ipc_info.passwd, SMBAUTH_HASH_SZ);
+ if (rc != 0)
+ *ipc_info.passwd = 0;
+ (void) rw_unlock(&smb_ipc_lock);
+
+}
+
+/*
+ * Set the IPC username and password hash in memory. If the domain
+ * join succeeds, the credentials will be committed for use with
+ * authenticated IPC. Otherwise, they should be rolled back.
+ */
+void
+smb_ipc_set(char *plain_user, uint8_t *passwd_hash)
+{
+ (void) rw_wrlock(&smb_ipc_lock);
+ (void) strlcpy(ipc_info.user, plain_user, sizeof (ipc_info.user));
+ (void) memcpy(ipc_info.passwd, passwd_hash, SMBAUTH_HASH_SZ);
+ (void) rw_unlock(&smb_ipc_lock);
+
+}
+
+/*
+ * Save the host credentials to be used for authenticated IPC.
+ * The credentials are also saved to the original IPC info as
+ * rollback data in case the join domain process fails later.
+ */
+void
+smb_ipc_commit(void)
+{
+ (void) rw_wrlock(&smb_ipc_lock);
+ (void) smb_getsamaccount(ipc_info.user, SMB_USERNAME_MAXLEN);
+ (void) smb_get_machine_passwd(ipc_info.passwd, SMBAUTH_HASH_SZ);
+ (void) memcpy(&ipc_orig_info, &ipc_info, sizeof (smb_ipc_t));
+ (void) rw_unlock(&smb_ipc_lock);
+}
+
+/*
+ * Restore the original credentials
+ */
+void
+smb_ipc_rollback(void)
+{
+ (void) rw_wrlock(&smb_ipc_lock);
+ (void) strlcpy(ipc_info.user, ipc_orig_info.user,
+ sizeof (ipc_info.user));
+ (void) memcpy(ipc_info.passwd, ipc_orig_info.passwd,
+ sizeof (ipc_info.passwd));
+ (void) rw_unlock(&smb_ipc_lock);
+}
+
+void
+smb_ipc_get_user(char *buf, size_t buflen)
+{
+ (void) rw_rdlock(&smb_ipc_lock);
+ (void) strlcpy(buf, ipc_info.user, buflen);
+ (void) rw_unlock(&smb_ipc_lock);
+}
+
+void
+smb_ipc_get_passwd(uint8_t *buf, size_t buflen)
+{
+ if (buflen < SMBAUTH_HASH_SZ)
+ return;
+
+ (void) rw_rdlock(&smb_ipc_lock);
+ (void) memcpy(buf, ipc_info.passwd, SMBAUTH_HASH_SZ);
+ (void) rw_unlock(&smb_ipc_lock);
+}
+
/*
* smb_match_netlogon_seqnum
*
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_sam.c b/usr/src/lib/smbsrv/libsmb/common/smb_sam.c
index 4c4721239a..9c92ad6a60 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_sam.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_sam.c
@@ -96,7 +96,7 @@ uint32_t
smb_sam_lookup_name(char *domain, char *name, uint16_t type,
smb_account_t *account)
{
- nt_domain_t di;
+ smb_domain_t di;
smb_sid_t *sid;
uint32_t status;
smb_lwka_t *lwka;
@@ -104,15 +104,15 @@ smb_sam_lookup_name(char *domain, char *name, uint16_t type,
bzero(account, sizeof (smb_account_t));
if (domain != NULL) {
- if (!nt_domain_lookup_name(domain, &di) ||
- (di.di_type != NT_DOMAIN_LOCAL))
+ if (!smb_domain_lookup_name(domain, &di) ||
+ (di.di_type != SMB_DOMAIN_LOCAL))
return (NT_STATUS_NOT_FOUND);
/* Only Netbios hostname is accepted */
if (utf8_strcasecmp(domain, di.di_nbname) != 0)
return (NT_STATUS_NONE_MAPPED);
} else {
- if (!nt_domain_lookup_type(NT_DOMAIN_LOCAL, &di))
+ if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di))
return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
}
@@ -209,7 +209,7 @@ smb_sam_lookup_sid(smb_sid_t *sid, smb_account_t *account)
smb_passwd_t smbpw;
smb_group_t grp;
smb_lwka_t *lwka;
- nt_domain_t di;
+ smb_domain_t di;
uint32_t rid;
uid_t id;
int id_type;
@@ -217,7 +217,7 @@ smb_sam_lookup_sid(smb_sid_t *sid, smb_account_t *account)
bzero(account, sizeof (smb_account_t));
- if (!nt_domain_lookup_type(NT_DOMAIN_LOCAL, &di))
+ if (!smb_domain_lookup_type(SMB_DOMAIN_LOCAL, &di))
return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO);
if (smb_sid_cmp(sid, di.di_binsid)) {
@@ -362,17 +362,17 @@ smb_sam_usr_groups(smb_sid_t *user_sid, smb_ids_t *gids)
* in /var/smb/smbgroup.db
*/
int
-smb_sam_grp_cnt(nt_domain_type_t dtype)
+smb_sam_grp_cnt(smb_domain_type_t dtype)
{
int grpcnt;
int rc;
switch (dtype) {
- case NT_DOMAIN_BUILTIN:
+ case SMB_DOMAIN_BUILTIN:
rc = smb_lgrp_numbydomain(SMB_LGRP_BUILTIN, &grpcnt);
break;
- case NT_DOMAIN_LOCAL:
+ case SMB_DOMAIN_LOCAL:
rc = smb_lgrp_numbydomain(SMB_LGRP_LOCAL, &grpcnt);
break;
diff --git a/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h b/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h
index 985f90fe7b..2493700e17 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h
+++ b/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h
@@ -37,8 +37,6 @@ extern "C" {
typedef struct smb_ads_handle {
- char *user; /* admin user to create share in ADS */
- char *pwd; /* user password */
char *domain; /* ADS domain */
char *domain_dn; /* domain in Distinquish Name format */
char *ip_addr; /* ip addr in string format */
@@ -103,14 +101,13 @@ extern int dyndns_update(char *);
extern void dyndns_update_zones(void);
extern void dyndns_clear_zones(void);
-/* Kerberos initialization function */
-extern int smb_kinit(char *, char *);
+/* Kerberos cache management function */
extern int smb_ccache_init(char *, char *);
extern void smb_ccache_remove(char *);
/* NETBIOS Functions */
extern int smb_netbios_start(void);
-extern void smb_netbios_shutdown(void);
+extern void smb_netbios_stop(void);
extern void smb_netbios_name_reconfig(void);
/* Browser Functions */
diff --git a/usr/src/lib/smbsrv/libsmbns/common/mapfile-vers b/usr/src/lib/smbsrv/libsmbns/common/mapfile-vers
index d41645ca0c..0840c08192 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/mapfile-vers
+++ b/usr/src/lib/smbsrv/libsmbns/common/mapfile-vers
@@ -62,10 +62,9 @@ SUNWprivate {
smb_browser_reconfig;
smb_ccache_init;
smb_ccache_remove;
- smb_kinit;
smb_netbios_name_reconfig;
smb_netbios_start;
- smb_netbios_shutdown;
+ smb_netbios_stop;
local:
*;
};
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c
index e971ae1ab2..13005345fb 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c
@@ -26,7 +26,6 @@
#include <sys/param.h>
#include <ldap.h>
#include <stdlib.h>
-#include <gssapi/gssapi.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -44,6 +43,8 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <assert.h>
+#include <sasl/sasl.h>
+#include <note.h>
#include <smbsrv/libsmbns.h>
#include <smbns_dyndns.h>
@@ -176,7 +177,6 @@ typedef struct smb_ads_host_list {
} smb_ads_host_list_t;
static smb_ads_handle_t *smb_ads_open_main(char *, char *, char *);
-static int smb_ads_bind(smb_ads_handle_t *);
static int smb_ads_add_computer(smb_ads_handle_t *, int, char *);
static int smb_ads_modify_computer(smb_ads_handle_t *, int, char *);
static int smb_ads_computer_op(smb_ads_handle_t *, int, int, char *);
@@ -595,7 +595,7 @@ smb_ads_dup_host_info(smb_ads_host_info_t *ads_host)
/*
* smb_ads_hlist_alloc
*/
-smb_ads_host_list_t *
+static smb_ads_host_list_t *
smb_ads_hlist_alloc(int count)
{
int size;
@@ -1034,6 +1034,24 @@ smb_ads_open(void)
return (smb_ads_open_main(domain, NULL, NULL));
}
+static int
+smb_ads_saslcallback(LDAP *ld, unsigned flags, void *defaults, void *prompts)
+{
+ NOTE(ARGUNUSED(ld, defaults));
+ sasl_interact_t *interact;
+
+ if (prompts == NULL || flags != LDAP_SASL_INTERACTIVE)
+ return (LDAP_PARAM_ERROR);
+
+ /* There should be no extra arguemnts for SASL/GSSAPI authentication */
+ for (interact = prompts; interact->id != SASL_CB_LIST_END;
+ interact++) {
+ interact->result = NULL;
+ interact->len = 0;
+ }
+ return (LDAP_SUCCESS);
+}
+
/*
* smb_ads_open_main
* Open a LDAP connection to an ADS server.
@@ -1048,7 +1066,7 @@ smb_ads_open(void)
* After the LDAP connection, the LDAP version will be set to 3 using
* ldap_set_option().
*
- * The smb_ads_bind() routine is also called before the ADS handle is returned.
+ * The LDAP connection is bound before the ADS handle is returned.
* Parameters:
* domain - fully-qualified domain name
* user - the user account for whom the Kerberos TGT ticket and ADS
@@ -1066,6 +1084,14 @@ smb_ads_open_main(char *domain, char *user, char *password)
LDAP *ld;
int version = 3;
smb_ads_host_info_t *ads_host = NULL;
+ int rc;
+
+ if (user != NULL) {
+ if (smb_kinit(user, password) == 0)
+ return (NULL);
+ user = NULL;
+ password = NULL;
+ }
ads_host = smb_ads_find_host(domain, NULL);
if (ads_host == NULL)
@@ -1097,8 +1123,6 @@ smb_ads_open_main(char *domain, char *user, char *password)
(void) ldap_set_option(ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
ah->ld = ld;
- ah->user = (user) ? strdup(user) : NULL;
- ah->pwd = (password) ? strdup(password) : NULL;
ah->domain = strdup(domain);
if (ah->domain == NULL) {
@@ -1133,7 +1157,11 @@ smb_ads_open_main(char *domain, char *user, char *password)
}
(void) mutex_unlock(&smb_ads_cfg.c_mtx);
- if (smb_ads_bind(ah) == -1) {
+ rc = ldap_sasl_interactive_bind_s(ah->ld, "", "GSSAPI", NULL, NULL,
+ LDAP_SASL_INTERACTIVE, &smb_ads_saslcallback, NULL);
+ if (rc != LDAP_SUCCESS) {
+ syslog(LOG_ERR, "ldal_sasl_interactive_bind_s failed (%s)",
+ ldap_err2string(rc));
smb_ads_close(ah);
free(ads_host);
return (NULL);
@@ -1155,22 +1183,12 @@ smb_ads_open_main(char *domain, char *user, char *password)
void
smb_ads_close(smb_ads_handle_t *ah)
{
- int len;
-
if (ah == NULL)
return;
/* close and free connection resources */
if (ah->ld)
(void) ldap_unbind(ah->ld);
- free(ah->user);
- if (ah->pwd) {
- len = strlen(ah->pwd);
- /* zero out the memory that contains user's password */
- if (len > 0)
- bzero(ah->pwd, len);
- free(ah->pwd);
- }
free(ah->domain);
free(ah->domain_dn);
free(ah->hostname);
@@ -1179,31 +1197,6 @@ smb_ads_close(smb_ads_handle_t *ah)
}
/*
- * smb_ads_display_stat
- * Display error message for GSS-API routines.
- * Parameters:
- * maj: GSS major status
- * min: GSS minor status
- * Returns:
- * None
- */
-static void
-smb_ads_display_stat(OM_uint32 maj, OM_uint32 min)
-{
- gss_buffer_desc msg;
- OM_uint32 msg_ctx = 0;
- OM_uint32 min2;
- (void) gss_display_status(&min2, maj, GSS_C_GSS_CODE, GSS_C_NULL_OID,
- &msg_ctx, &msg);
- smb_tracef("major status: %s", (char *)msg.value);
- (void) gss_release_buffer(&min2, &msg);
- (void) gss_display_status(&min2, min, GSS_C_MECH_CODE, GSS_C_NULL_OID,
- &msg_ctx, &msg);
- smb_tracef("minor status: %s", (char *)msg.value);
- (void) gss_release_buffer(&min2, &msg);
-}
-
-/*
* smb_ads_alloc_attr
*
* Since the attrs is a null-terminated array, all elements
@@ -1282,290 +1275,6 @@ smb_ads_free_spnset(char **spn_set)
}
/*
- * smb_ads_acquire_cred
- * Called by smb_ads_bind() to get a handle to administrative user's credential
- * stored locally on the system. The credential is the TGT. If the attempt at
- * getting handle fails then a second attempt will be made after getting a
- * new TGT.
- * Please look at smb_ads_bind() for more information.
- *
- * Paramters:
- * ah : handle to ADS server
- * kinit_retry: if 0 then a second attempt will be made to get handle to the
- * credential if the first attempt fails
- * Returns:
- * cred_handle: handle to the administrative user's credential (TGT)
- * oid : contains Kerberos 5 object identifier
- * kinit_retry: A 1 indicates that a second attempt has been made to get
- * handle to the credential and no further attempts can be made
- * -1 : error
- * 0 : success
- */
-static int
-smb_ads_acquire_cred(smb_ads_handle_t *ah, gss_cred_id_t *cred_handle,
- gss_OID *oid, int *kinit_retry)
-{
- return (krb5_acquire_cred_kinit(ah->user, ah->pwd, cred_handle, oid,
- kinit_retry, "ads"));
-}
-
-/*
- * smb_ads_establish_sec_context
- * Called by smb_ads_bind() to establish a security context to an LDAP service
- * on an ADS server. If the attempt at establishing the security context fails
- * then a second attempt will be made by smb_ads_bind() if a new TGT has not
- * been already obtained in ads_acquire_cred. The second attempt, if allowed,
- * will obtained a new TGT here and a new handle to the credential will also be
- * obtained in ads_acquire_cred. LDAP SASL bind is used to send and receive
- * the GSS tokens to and from the ADS server.
- * Please look at ads_bind for more information.
- * Paramters:
- * ah : handle to ADS server
- * cred_handle : handle to administrative user's credential (TGT)
- * oid : Kerberos 5 object identifier
- * kinit_retry : if 0 then a second attempt can be made to establish a
- * security context with ADS server if first attempt fails
- * Returns:
- * gss_context : security context to ADS server
- * sercred : encrypted ADS server's supported security layers
- * do_acquire_cred: if 1 then a second attempt will be made to establish a
- * security context with ADS server after getting a new
- * handle to the user's credential
- * kinit_retry : if 1 then a second attempt will be made to establish a
- * a security context and no further attempts can be made
- * -1 : error
- * 0 : success
- */
-static int
-smb_ads_establish_sec_context(smb_ads_handle_t *ah, gss_ctx_id_t *gss_context,
- gss_cred_id_t cred_handle, gss_OID oid, struct berval **sercred,
- int *kinit_retry, int *do_acquire_cred)
-{
- OM_uint32 maj, min, time_rec;
- char service_name[SMB_ADS_MAXBUFLEN];
- gss_buffer_desc send_tok, service_buf;
- gss_name_t target_name;
- gss_buffer_desc input;
- gss_buffer_desc *inputptr;
- struct berval cred;
- OM_uint32 ret_flags;
- int stat;
- int gss_flags;
-
- (void) snprintf(service_name, SMB_ADS_MAXBUFLEN, "ldap@%s",
- ah->hostname);
- service_buf.value = service_name;
- service_buf.length = strlen(service_name)+1;
- if ((maj = gss_import_name(&min, &service_buf,
- (gss_OID) gss_nt_service_name,
- &target_name)) != GSS_S_COMPLETE) {
- smb_ads_display_stat(maj, min);
- if (oid != GSS_C_NO_OID)
- (void) gss_release_oid(&min, &oid);
- return (-1);
- }
-
- *gss_context = GSS_C_NO_CONTEXT;
- *sercred = NULL;
- inputptr = GSS_C_NO_BUFFER;
- gss_flags = GSS_C_MUTUAL_FLAG;
- do {
- if (krb5_establish_sec_ctx_kinit(ah->user, ah->pwd,
- cred_handle, gss_context, target_name, oid,
- gss_flags, inputptr, &send_tok,
- &ret_flags, &time_rec, kinit_retry,
- do_acquire_cred, &maj, "ads") == -1) {
- if (oid != GSS_C_NO_OID)
- (void) gss_release_oid(&min, &oid);
- (void) gss_release_name(&min, &target_name);
- return (-1);
- }
-
- cred.bv_val = send_tok.value;
- cred.bv_len = send_tok.length;
- if (*sercred) {
- ber_bvfree(*sercred);
- *sercred = NULL;
- }
- stat = ldap_sasl_bind_s(ah->ld, NULL, "GSSAPI",
- &cred, NULL, NULL, sercred);
- if (stat != LDAP_SUCCESS &&
- stat != LDAP_SASL_BIND_IN_PROGRESS) {
- syslog(LOG_NOTICE, "ldap_sasl_bind: %s",
- ldap_err2string(stat));
- if (oid != GSS_C_NO_OID)
- (void) gss_release_oid(&min, &oid);
- (void) gss_release_name(&min, &target_name);
- (void) gss_release_buffer(&min, &send_tok);
- return (-1);
- }
- input.value = (*sercred)->bv_val;
- input.length = (*sercred)->bv_len;
- inputptr = &input;
- if (send_tok.length > 0)
- (void) gss_release_buffer(&min, &send_tok);
- } while (maj != GSS_S_COMPLETE);
-
- if (oid != GSS_C_NO_OID)
- (void) gss_release_oid(&min, &oid);
- (void) gss_release_name(&min, &target_name);
-
- return (0);
-}
-
-/*
- * smb_ads_negotiate_sec_layer
- * Call by smb_ads_bind() to negotiate additional security layer for further
- * communication after security context establishment. No additional security
- * is needed so a "no security layer" is negotiated. The security layer is
- * described in the SASL RFC 2478 and this step is needed for secure LDAP
- * binding. LDAP SASL bind is used to send and receive the GSS tokens to and
- * from the ADS server.
- * Please look at smb_ads_bind for more information.
- *
- * Paramters:
- * ah : handle to ADS server
- * gss_context: security context to ADS server
- * sercred : encrypted ADS server's supported security layers
- * Returns:
- * -1 : error
- * 0 : success
- */
-static int
-smb_ads_negotiate_sec_layer(smb_ads_handle_t *ah, gss_ctx_id_t gss_context,
- struct berval *sercred)
-{
- OM_uint32 maj, min;
- gss_buffer_desc unwrap_inbuf, unwrap_outbuf;
- gss_buffer_desc wrap_inbuf, wrap_outbuf;
- int conf_state, sec_layer;
- char auth_id[5];
- struct berval cred;
- int stat;
- gss_qop_t qt;
-
- /* check for server supported security layer */
- unwrap_inbuf.value = sercred->bv_val;
- unwrap_inbuf.length = sercred->bv_len;
- if ((maj = gss_unwrap(&min, gss_context,
- &unwrap_inbuf, &unwrap_outbuf,
- &conf_state, &qt)) != GSS_S_COMPLETE) {
- smb_ads_display_stat(maj, min);
- if (sercred)
- ber_bvfree(sercred);
- return (-1);
- }
- sec_layer = *((char *)unwrap_outbuf.value);
- (void) gss_release_buffer(&min, &unwrap_outbuf);
- if (!(sec_layer & 1)) {
- if (sercred)
- ber_bvfree(sercred);
- return (-1);
- }
- if (sercred) ber_bvfree(sercred);
-
- /* no security layer needed after successful binding */
- auth_id[0] = 0x01;
-
- /* byte 2-4: max client recv size in network byte order */
- auth_id[1] = 0x00;
- auth_id[2] = 0x40;
- auth_id[3] = 0x00;
- wrap_inbuf.value = auth_id;
- wrap_inbuf.length = 4;
- conf_state = 0;
- if ((maj = gss_wrap(&min, gss_context, conf_state, 0, &wrap_inbuf,
- &conf_state, &wrap_outbuf)) != GSS_S_COMPLETE) {
- smb_ads_display_stat(maj, min);
- return (-1);
- }
-
- cred.bv_val = wrap_outbuf.value;
- cred.bv_len = wrap_outbuf.length;
- sercred = NULL;
- stat = ldap_sasl_bind_s(ah->ld, NULL, "GSSAPI", &cred, NULL, NULL,
- &sercred);
- if (stat != LDAP_SUCCESS && stat != LDAP_SASL_BIND_IN_PROGRESS) {
- syslog(LOG_NOTICE, "ldap_sasl_bind: %s",
- ldap_err2string(stat));
- (void) gss_release_buffer(&min, &wrap_outbuf);
- return (-1);
- }
-
- (void) gss_release_buffer(&min, &wrap_outbuf);
- if (sercred)
- ber_bvfree(sercred);
-
- return (0);
-}
-
-/*
- * smb_ads_bind
- * Use secure binding to bind to ADS server.
- * Use GSS-API with Kerberos 5 as the security mechanism and LDAP SASL with
- * Kerberos 5 as the security mechanisn to authenticate, obtain a security
- * context, and securely bind an administrative user so that other LDAP
- * commands can be used, i.e. add and delete.
- *
- * To obtain the security context, a Kerberos ticket-granting ticket (TGT)
- * for the user is needed to obtain a ticket for the LDAP service. To get
- * a TGT for the user, the username and password is needed. Once a TGT is
- * obtained then it will be stored locally and used until it is expired.
- * This routine will automatically obtained a TGT for the first time or when
- * it expired. LDAP SASL bind is then finally used to send GSS tokens to
- * obtain a security context for the LDAP service on the ADS server. If
- * there is any problem getting the security context then a new TGT will be
- * obtain to try getting the security context once more.
- *
- * After the security context is obtain and established, the LDAP SASL bind
- * is used to negotiate an additional security layer. No further security is
- * needed so a "no security layer" is negotiated. After this the security
- * context can be deleted and further LDAP commands can be sent to the ADS
- * server until a LDAP unbind command is issued to the ADS server.
- * Paramaters:
- * ah: handle to ADS server
- * Returns:
- * -1: error
- * 0: success
- */
-static int
-smb_ads_bind(smb_ads_handle_t *ah)
-{
- OM_uint32 min;
- gss_cred_id_t cred_handle;
- gss_ctx_id_t gss_context;
- gss_OID oid;
- struct berval *sercred;
- int kinit_retry, do_acquire_cred;
- int rc = 0;
-
- kinit_retry = 0;
- do_acquire_cred = 0;
-
-acquire_cred:
-
- if (smb_ads_acquire_cred(ah, &cred_handle, &oid, &kinit_retry))
- return (-1);
-
- if (smb_ads_establish_sec_context(ah, &gss_context, cred_handle,
- oid, &sercred, &kinit_retry, &do_acquire_cred)) {
- (void) gss_release_cred(&min, &cred_handle);
- if (do_acquire_cred) {
- do_acquire_cred = 0;
- goto acquire_cred;
- }
- return (-1);
- }
- rc = smb_ads_negotiate_sec_layer(ah, gss_context, sercred);
-
- if (cred_handle != GSS_C_NO_CREDENTIAL)
- (void) gss_release_cred(&min, &cred_handle);
- (void) gss_delete_sec_context(&min, &gss_context, NULL);
-
- return ((rc) ? -1 : 0);
-}
-
-/*
* smb_ads_add_share
* Call by smb_ads_publish_share to create share object in ADS.
* This routine specifies the attributes of an ADS LDAP share object. The first
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c
index 9d9970ba3b..c98aa6d661 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c
@@ -23,6 +23,7 @@
* Use is subject to license terms.
*/
+#include <sys/tzfile.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
@@ -38,10 +39,8 @@
#include <smbsrv/libsmb.h>
#include <smbsrv/libsmbns.h>
-
#include <smbsrv/cifs.h>
#include <smbsrv/mailslot.h>
-
#include <smbns_browser.h>
#include <smbns_netbios.h>
@@ -83,8 +82,6 @@ static void smb_browser_infoterm(void);
static void smb_browser_infofree(void);
-
-
void
smb_browser_reconfig(void)
{
@@ -653,7 +650,7 @@ smb_browser_addr_of_subnet(struct name_entry *name, smb_hostinfo_t *hinfo,
struct name_entry *result)
{
uint32_t ipaddr, mask, saddr;
- struct addr_entry *addr;
+ addr_entry_t *addr;
if (name == NULL)
return (-1);
@@ -692,7 +689,7 @@ smb_browser_bcast_addr_of_subnet(struct name_entry *name, uint32_t bcast,
result->addr_list.sin.sin_family = AF_INET;
result->addr_list.sinlen = sizeof (result->addr_list.sin);
result->addr_list.sin.sin_addr.s_addr = bcast;
- result->addr_list.sin.sin_port = htons(DGM_SRVC_UDP_PORT);
+ result->addr_list.sin.sin_port = htons(IPPORT_NETBIOS_DGM);
result->addr_list.forw = result->addr_list.back = &result->addr_list;
return (0);
}
@@ -772,7 +769,7 @@ smb_browser_bcast_addr_of_subnet(struct name_entry *name, uint32_t bcast,
static void
smb_browser_send_HostAnnouncement(smb_hostinfo_t *hinfo,
uint32_t next_announcement, boolean_t remove,
- struct addr_entry *addr, char suffix)
+ addr_entry_t *addr, char suffix)
{
smb_msgbuf_t mb;
int offset, announce_len, data_length;
@@ -801,9 +798,9 @@ smb_browser_send_HostAnnouncement(smb_hostinfo_t *hinfo,
}
/* give some extra room */
- buffer = (unsigned char *)malloc(MAX_DATAGRAM_LENGTH * 2);
- if (buffer == 0) {
- syslog(LOG_ERR, "HostAnnouncement: resource shortage");
+ buffer = malloc(MAX_DATAGRAM_LENGTH * 2);
+ if (buffer == NULL) {
+ syslog(LOG_DEBUG, "smb browser: HostAnnouncement: %m");
return;
}
@@ -824,7 +821,7 @@ smb_browser_send_HostAnnouncement(smb_hostinfo_t *hinfo,
* specifying a type of 0 just prior to shutting down, to allow it to
* quickly be removed from the list of available servers.
*/
- if (remove || (nb_status.state & NETBIOS_SHUTTING_DOWN))
+ if (remove || (!smb_netbios_running()))
type = 0;
else
type = hinfo->hi_type;
@@ -860,11 +857,11 @@ smb_browser_process_AnnouncementRequest(struct datagram *datagram,
boolean_t h_found = B_FALSE;
if (strcmp(mailbox, MAILSLOT_LANMAN) != 0) {
- syslog(LOG_DEBUG, "smb_browse: Wrong Mailbox (%s)", mailbox);
+ syslog(LOG_DEBUG, "smb browser: wrong mailbox (%s)", mailbox);
return;
}
- (void) sleep(delay);
+ smb_netbios_sleep(delay);
(void) rw_rdlock(&smb_binfo.bi_hlist_rwl);
hinfo = list_head(&smb_binfo.bi_hlist);
@@ -882,7 +879,7 @@ smb_browser_process_AnnouncementRequest(struct datagram *datagram,
if (h_found) {
next_announcement = hinfo->hi_nextannouce * 60 * 1000;
smb_browser_send_HostAnnouncement(hinfo, next_announcement,
- B_FALSE, &datagram->src.addr_list, 0x1D);
+ B_FALSE, &datagram->src.addr_list, NBT_MB);
}
(void) rw_unlock(&smb_binfo.bi_hlist_rwl);
}
@@ -915,7 +912,7 @@ smb_browser_dispatch(void *arg)
unsigned char *data;
int datalen;
- syslog(LOG_DEBUG, "smb_browse: packet_received");
+ syslog(LOG_DEBUG, "smb browser: packet received");
smb_msgbuf_init(&mb, datagram->data, datagram->data_length, 0);
rc = smb_msgbuf_decode(&mb, "Mb27.bwwwwb.w6.wwwwb.wwwws",
@@ -939,7 +936,7 @@ smb_browser_dispatch(void *arg)
&mailbox); /* Mailbox address */
if (rc < 0) {
- syslog(LOG_ERR, "smb_browser_dispatch: decode error");
+ syslog(LOG_ERR, "smb browser: decode error");
smb_msgbuf_term(&mb);
free(datagram);
return (0);
@@ -972,7 +969,7 @@ smb_browser_dispatch(void *arg)
break;
default:
- syslog(LOG_DEBUG, "smb_browse: invalid message_type(%d, %x)",
+ syslog(LOG_DEBUG, "smb browser: invalid message type(%d, %x)",
message_type, message_type);
break;
}
@@ -1064,7 +1061,7 @@ smb_browser_config(void)
(void) utf8_strupr(resource_domain);
/* domain<00> */
- smb_init_name_struct((unsigned char *)resource_domain, 0x00,
+ smb_init_name_struct((unsigned char *)resource_domain, NBT_WKSTA,
0, 0, 0, 0, 0, &name);
entry = smb_name_find_name(&name);
smb_name_unlock_name(entry);
@@ -1072,9 +1069,9 @@ smb_browser_config(void)
(void) rw_rdlock(&smb_binfo.bi_hlist_rwl);
hinfo = list_head(&smb_binfo.bi_hlist);
while (hinfo) {
- smb_init_name_struct((unsigned char *)resource_domain, 0x00, 0,
- hinfo->hi_nic.nic_ip.a_ipv4,
- htons(DGM_SRVC_UDP_PORT), NAME_ATTR_GROUP,
+ smb_init_name_struct((unsigned char *)resource_domain,
+ NBT_WKSTA, 0, hinfo->hi_nic.nic_ip.a_ipv4,
+ htons(IPPORT_NETBIOS_DGM), NAME_ATTR_GROUP,
NAME_ATTR_LOCAL, &name);
(void) smb_name_add_name(&name);
@@ -1083,7 +1080,7 @@ smb_browser_config(void)
(void) rw_unlock(&smb_binfo.bi_hlist_rwl);
/* All our local master browsers */
- smb_init_name_struct((unsigned char *)resource_domain, 0x1D,
+ smb_init_name_struct((unsigned char *)resource_domain, NBT_MB,
0, 0, 0, 0, 0, &dest);
entry = smb_name_find_name(&dest);
@@ -1094,7 +1091,7 @@ smb_browser_config(void)
rc = smb_browser_addr_of_subnet(entry, hinfo, &master);
if (rc == 0) {
syslog(LOG_DEBUG,
- "smbd: Master browser found at %s",
+ "smb browser: master browser found at %s",
inet_ntoa(master.addr_list.sin.sin_addr));
}
hinfo = list_next(&smb_binfo.bi_hlist, hinfo);
@@ -1106,10 +1103,11 @@ smb_browser_config(void)
/* Domain master browser */
smb_init_name_struct((unsigned char *)resource_domain,
- 0x1B, 0, 0, 0, 0, 0, &dest);
+ NBT_DMB, 0, 0, 0, 0, 0, &dest);
if ((entry = smb_name_find_name(&dest)) != 0) {
- syslog(LOG_DEBUG, "smbd: Domain Master browser for %s is %s",
+ syslog(LOG_DEBUG,
+ "smb browser: domain master browser for %s is %s",
resource_domain,
inet_ntoa(entry->addr_list.sin.sin_addr));
smb_name_unlock_name(entry);
@@ -1161,8 +1159,9 @@ smb_browser_init(void)
(void) utf8_strupr(hinfo->hi_nbname);
/* 0x20: file server service */
smb_init_name_struct((unsigned char *)hinfo->hi_nbname,
- 0x20, 0, hinfo->hi_nic.nic_ip.a_ipv4,
- htons(DGM_SRVC_UDP_PORT), NAME_ATTR_UNIQUE, NAME_ATTR_LOCAL,
+ NBT_SERVER, 0, hinfo->hi_nic.nic_ip.a_ipv4,
+ htons(IPPORT_NETBIOS_DGM),
+ NAME_ATTR_UNIQUE, NAME_ATTR_LOCAL,
&hinfo->hi_netname);
list_insert_tail(&smb_binfo.bi_hlist, hinfo);
@@ -1186,17 +1185,17 @@ smb_browser_non_master_duties(smb_hostinfo_t *hinfo, boolean_t remove)
{
struct name_entry name;
struct name_entry *dest;
- struct addr_entry addr;
+ addr_entry_t addr;
char resource_domain[SMB_PI_MAX_DOMAIN];
smb_browser_send_HostAnnouncement(hinfo, hinfo->hi_interval,
- remove, 0, 0x1D);
+ remove, 0, NBT_MB);
if (smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN) != 0)
return;
(void) utf8_strupr(resource_domain);
- smb_init_name_struct((unsigned char *)resource_domain, 0x1D,
+ smb_init_name_struct((unsigned char *)resource_domain, NBT_MB,
0, 0, 0, 0, 0, &name);
if ((dest = smb_name_find_name(&name))) {
@@ -1204,16 +1203,16 @@ smb_browser_non_master_duties(smb_hostinfo_t *hinfo, boolean_t remove)
addr.forw = addr.back = &addr;
smb_name_unlock_name(dest);
smb_browser_send_HostAnnouncement(hinfo, hinfo->hi_interval,
- remove, &addr, 0x1D);
+ remove, &addr, NBT_MB);
} else {
- smb_init_name_struct((unsigned char *)resource_domain, 0x1B,
- 0, 0, 0, 0, 0, &name);
+ smb_init_name_struct((unsigned char *)resource_domain,
+ NBT_DMB, 0, 0, 0, 0, 0, &name);
if ((dest = smb_name_find_name(&name))) {
addr = dest->addr_list;
addr.forw = addr.back = &addr;
smb_name_unlock_name(dest);
smb_browser_send_HostAnnouncement(hinfo,
- remove, hinfo->hi_interval, &addr, 0x1B);
+ remove, hinfo->hi_interval, &addr, NBT_DMB);
}
}
@@ -1235,61 +1234,24 @@ smb_browser_non_master_duties(smb_hostinfo_t *hinfo, boolean_t remove)
/*
- * smb_browser_sleep
- *
- * Put browser in 1 minute sleep if netbios services are not
- * shutting down and both name and datagram services are still
- * running. It'll wake up after 1 minute or if one of the above
- * conditions go false. It checks the conditions again and return
- * 1 if everything is ok or 0 if browser shouldn't continue
- * running.
- */
-static boolean_t
-smb_browser_sleep(void)
-{
- boolean_t slept = B_FALSE;
- timestruc_t to;
-
- (void) mutex_lock(&nb_status.mtx);
- while (((nb_status.state & NETBIOS_SHUTTING_DOWN) == 0) &&
- (nb_status.state & NETBIOS_NAME_SVC_RUNNING) &&
- (nb_status.state & NETBIOS_DATAGRAM_SVC_RUNNING)) {
-
- if (slept) {
- (void) mutex_unlock(&nb_status.mtx);
- return (B_TRUE);
- }
-
- to.tv_sec = 60; /* 1 minute */
- to.tv_nsec = 0;
- (void) cond_reltimedwait(&nb_status.cv, &nb_status.mtx, &to);
- slept = B_TRUE;
- }
- (void) mutex_unlock(&nb_status.mtx);
-
- return (B_FALSE);
-}
-
-/*
- * smb_browser_daemon
- *
- * Smb Netbios browser daemon.
+ * SMB NetBIOS Browser Service
*/
/*ARGSUSED*/
void *
-smb_browser_daemon(void *arg)
+smb_browser_service(void *arg)
{
smb_hostinfo_t *hinfo;
smb_browser_infoinit();
smb_browser_config();
- smb_netbios_chg_status(NETBIOS_BROWSER_RUNNING, 1);
+ smb_netbios_event(NETBIOS_EVENT_BROWSER_START);
restart:
do {
(void) rw_rdlock(&smb_binfo.bi_hlist_rwl);
hinfo = list_head(&smb_binfo.bi_hlist);
+
while (hinfo) {
if (--hinfo->hi_nextannouce > 0 ||
hinfo->hi_nic.nic_bcast == 0) {
@@ -1312,11 +1274,13 @@ restart:
hinfo = list_next(&smb_binfo.bi_hlist, hinfo);
}
+
(void) rw_unlock(&smb_binfo.bi_hlist_rwl);
- } while (smb_browser_sleep());
+ smb_netbios_sleep(SECSPERMIN); /* 1 minute */
+ } while (smb_netbios_running());
smb_browser_infoterm();
- smb_netbios_chg_status(NETBIOS_BROWSER_RUNNING, 0);
+ smb_netbios_event(NETBIOS_EVENT_BROWSER_STOP);
return (0);
}
@@ -1367,8 +1331,8 @@ smb_browser_netlogon(char *domain, char *dc, uint32_t dc_len)
/*
* smb_browser_infoinit
*
- * This function is called only once when browser daemon starts
- * to initialize global smb_binfo structure
+ * This function is called only once when the browser starts
+ * to initialize the global smb_binfo structure.
*/
static void
smb_browser_infoinit(void)
@@ -1391,8 +1355,8 @@ smb_browser_infoinit(void)
/*
* smb_browser_infoterm
*
- * This function is called only once when browser daemon stops
- * to destruct smb_binfo structure
+ * This function is called only once when the browser stops
+ * to destroy the smb_binfo structure.
*/
static void
smb_browser_infoterm(void)
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_krb.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_krb.c
index 12b910f605..5afd6f3258 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_krb.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_krb.c
@@ -51,500 +51,100 @@
#include <kerberosv5/krb5.h>
#include <kerberosv5/com_err.h>
#include <assert.h>
-#include <string.h>
#include <stdio.h>
-#include <time.h>
-#include <netdb.h>
#include <syslog.h>
-#include <locale.h>
-#include <strings.h>
#include <errno.h>
-#include <sys/synch.h>
-#include <gssapi/gssapi.h>
#include <smbsrv/libsmbns.h>
-
#include <smbns_krb.h>
-static int krb5_acquire_cred_kinit_main();
-
-typedef enum { INIT_PW, INIT_KT, RENEW, VALIDATE } action_type;
-
-struct k_opts {
- /* in seconds */
- krb5_deltat starttime;
- krb5_deltat lifetime;
- krb5_deltat rlife;
-
- int forwardable;
- int proxiable;
- int addresses;
-
- int not_forwardable;
- int not_proxiable;
- int no_addresses;
-
- int verbose;
-
- char *principal_name;
- char *principal_passwd;
- char *service_name;
- char *keytab_name;
- char *k5_cache_name;
- char *k4_cache_name;
-
- action_type action;
-};
-
-struct k5_data {
- krb5_context ctx;
- krb5_ccache cc;
- krb5_principal me;
- char *name;
-};
-
-static int
-k5_begin(struct k_opts *opts, struct k5_data *k5)
-{
- int code;
- code = krb5_init_context(&k5->ctx);
- if (code) {
- return (code);
- }
-
- if ((code = krb5_cc_default(k5->ctx, &k5->cc))) {
- return (code);
- }
-
- /* Use specified name */
- if ((code = krb5_parse_name(k5->ctx, opts->principal_name, &k5->me))) {
- return (code);
- }
-
- code = krb5_unparse_name(k5->ctx, k5->me, &k5->name);
- if (code) {
- return (code);
- }
- opts->principal_name = k5->name;
-
- return (0);
-}
-
-static void
-k5_end(struct k5_data *k5)
-{
- if (k5->name)
- krb5_free_unparsed_name(k5->ctx, k5->name);
- if (k5->me)
- krb5_free_principal(k5->ctx, k5->me);
- if (k5->cc)
- krb5_cc_close(k5->ctx, k5->cc);
- if (k5->ctx)
- krb5_free_context(k5->ctx);
- (void) memset(k5, 0, sizeof (*k5));
-}
-
-static int
-k5_kinit(struct k_opts *opts, struct k5_data *k5)
+int
+smb_kinit(char *principal_name, char *principal_passwd)
{
- int notix = 1;
- krb5_keytab keytab = 0;
+ krb5_context ctx = NULL;
+ krb5_ccache cc = NULL;
+ krb5_principal me = NULL;
krb5_creds my_creds;
- krb5_error_code code = 0;
- krb5_get_init_creds_opt options;
- const char *errmsg;
+ krb5_error_code code;
+ const char *errmsg = NULL;
+ const char *doing = NULL;
+
+ assert(principal_name != NULL);
+ assert(principal_passwd != NULL);
- krb5_get_init_creds_opt_init(&options);
(void) memset(&my_creds, 0, sizeof (my_creds));
/*
- * From this point on, we can goto cleanup because my_creds is
- * initialized.
+ * From this point on, we can goto cleanup because the key variables
+ * are initialized.
*/
- if (opts->lifetime)
- krb5_get_init_creds_opt_set_tkt_life(&options, opts->lifetime);
- if (opts->rlife)
- krb5_get_init_creds_opt_set_renew_life(&options, opts->rlife);
- if (opts->forwardable)
- krb5_get_init_creds_opt_set_forwardable(&options, 1);
- if (opts->not_forwardable)
- krb5_get_init_creds_opt_set_forwardable(&options, 0);
- if (opts->proxiable)
- krb5_get_init_creds_opt_set_proxiable(&options, 1);
- if (opts->not_proxiable)
- krb5_get_init_creds_opt_set_proxiable(&options, 0);
- if (opts->addresses) {
- krb5_address **addresses = NULL;
- code = krb5_os_localaddr(k5->ctx, &addresses);
- if (code != 0) {
- errmsg = error_message(code);
- syslog(LOG_ERR, "k5_kinit: getting local addresses "
- "(%s)", errmsg);
- goto cleanup;
- }
- krb5_get_init_creds_opt_set_address_list(&options, addresses);
- }
- if (opts->no_addresses)
- krb5_get_init_creds_opt_set_address_list(&options, NULL);
-
- if ((opts->action == INIT_KT) && opts->keytab_name) {
- code = krb5_kt_resolve(k5->ctx, opts->keytab_name, &keytab);
- if (code != 0) {
- errmsg = error_message(code);
- syslog(LOG_ERR, "k5_kinit: resolving keytab %s (%s)",
- errmsg, opts->keytab_name);
- goto cleanup;
- }
- }
-
- switch (opts->action) {
- case INIT_PW:
- code = krb5_get_init_creds_password(k5->ctx, &my_creds, k5->me,
- opts->principal_passwd, NULL, 0, opts->starttime,
- opts->service_name, &options);
- break;
- case INIT_KT:
- code = krb5_get_init_creds_keytab(k5->ctx, &my_creds, k5->me,
- keytab, opts->starttime, opts->service_name, &options);
- break;
- case VALIDATE:
- code = krb5_get_validated_creds(k5->ctx, &my_creds, k5->me,
- k5->cc, opts->service_name);
- break;
- case RENEW:
- code = krb5_get_renewed_creds(k5->ctx, &my_creds, k5->me,
- k5->cc, opts->service_name);
- break;
- }
+ code = krb5_init_context(&ctx);
if (code) {
- char *doing = 0;
- switch (opts->action) {
- case INIT_PW:
- case INIT_KT:
- doing = "k5_kinit: getting initial credentials";
- break;
- case VALIDATE:
- doing = "k5_kinit: validating credentials";
- break;
- case RENEW:
- doing = "k5_kinit: renewing credentials";
- break;
- }
-
- /*
- * If got code == KRB5_AP_ERR_V4_REPLY && got_k4, we should
- * let the user know that maybe he/she wants -4.
- */
- if (code == KRB5KRB_AP_ERR_V4_REPLY) {
- syslog(LOG_ERR, "%s\n"
- "The KDC doesn't support v5. "
- "You may want the -4 option in the future", doing);
- return (1);
- } else if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
- syslog(LOG_ERR, "%s (Password incorrect)", doing);
- } else {
- errmsg = error_message(code);
- syslog(LOG_ERR, "%s (%s)", doing, errmsg);
- }
+ doing = "initializing context";
goto cleanup;
}
- if (!opts->lifetime) {
- /* We need to figure out what lifetime to use for Kerberos 4. */
- opts->lifetime = my_creds.times.endtime -
- my_creds.times.authtime;
- }
-
- code = krb5_cc_initialize(k5->ctx, k5->cc, k5->me);
- if (code) {
- errmsg = error_message(code);
- syslog(LOG_ERR, "k5_kinit: initializing cache %s (%s)",
- opts->k5_cache_name ? opts->k5_cache_name : "", errmsg);
+ code = krb5_cc_default(ctx, &cc);
+ if (code != 0) {
+ doing = "resolve default credentials cache";
goto cleanup;
}
- code = krb5_cc_store_cred(k5->ctx, k5->cc, &my_creds);
- if (code) {
- errmsg = error_message(code);
- syslog(LOG_ERR, "k5_kinit: storing credentials (%s)", errmsg);
+ /* Use specified name */
+ code = krb5_parse_name(ctx, principal_name, &me);
+ if (code != 0) {
+ doing = "parsing principal name";
goto cleanup;
}
- notix = 0;
+ code = krb5_get_init_creds_password(ctx, &my_creds, me,
+ principal_passwd, NULL, 0, (krb5_deltat)0,
+ NULL, NULL);
+ if (code != 0) {
+ doing = "getting initial credentials";
- cleanup:
- if (my_creds.client == k5->me) {
- my_creds.client = 0;
+ if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
+ errmsg = "Password incorrect";
}
- krb5_free_cred_contents(k5->ctx, &my_creds);
- if (keytab)
- krb5_kt_close(k5->ctx, keytab);
- return (notix?0:1);
-}
-
-int
-smb_kinit(char *user, char *passwd)
-{
- struct k_opts opts;
- struct k5_data k5;
- int authed_k5 = 0;
-
- assert(user);
- assert(passwd);
-
- (void) memset(&opts, 0, sizeof (opts));
- opts.action = INIT_PW;
- opts.principal_name = user;
- opts.principal_passwd = passwd;
- (void) memset(&k5, 0, sizeof (k5));
-
- if (k5_begin(&opts, &k5) != 0) {
- syslog(LOG_ERR, "NOT authenticated with Kerberos v5. "
- "k5_begin failed\n");
- return (0);
- }
-
- authed_k5 = k5_kinit(&opts, &k5);
- if (authed_k5)
- syslog(LOG_DEBUG, "Authenticated with Kerberos v5\n");
- else
- syslog(LOG_DEBUG, "NOT authenticated with Kerberos v5\n");
-
- k5_end(&k5);
-
- return (authed_k5);
-}
-
-/*
- * krb5_display_stat
- * Display error message for GSS-API routines.
- * Parameters:
- * maj : GSS major status
- * min : GSS minor status
- * caller_mod: module name that calls this routine so that the module name
- * can be displayed with the error messages
- * Returns:
- * None
- */
-static void
-krb5_display_stat(OM_uint32 maj, OM_uint32 min, char *caller_mod)
-{
- gss_buffer_desc msg;
- OM_uint32 msg_ctx = 0;
- OM_uint32 min2;
- (void) gss_display_status(&min2, maj, GSS_C_GSS_CODE, GSS_C_NULL_OID,
- &msg_ctx, &msg);
- syslog(LOG_ERR, "%s: major status error: %s\n",
- caller_mod, (char *)msg.value);
- (void) gss_release_buffer(&min2, &msg);
-
- (void) gss_display_status(&min2, min, GSS_C_MECH_CODE, GSS_C_NULL_OID,
- &msg_ctx, &msg);
- syslog(LOG_ERR, "%s: minor status error: %s\n",
- caller_mod, (char *)msg.value);
- (void) gss_release_buffer(&min2, &msg);
-}
-
-/*
- * krb5_acquire_cred_kinit
- *
- * Wrapper for krb5_acquire_cred_kinit_main with mutex to protect credential
- * cache file when calling krb5_acquire_cred or kinit.
- */
-
-int
-krb5_acquire_cred_kinit(char *user, char *pwd, gss_cred_id_t *cred_handle,
- gss_OID *oid, int *kinit_retry, char *caller_mod)
-{
- int ret;
-
- ret = krb5_acquire_cred_kinit_main(user, pwd,
- cred_handle, oid, kinit_retry, caller_mod);
- return (ret);
-}
-
-/*
- * krb5_acquire_cred_kinit_main
- *
- * This routine is called by ADS module to get a handle to administrative
- * user's credential stored locally on the system. The credential is the TGT.
- * If the attempt at getting handle fails then a second attempt will be made
- * after getting a new TGT.
- *
- * If there's no username then we must be using host credentials and we don't
- * bother trying to acquire a credential for GSS_C_NO_NAME (which should be
- * equivalent to using GSS_C_NO_CREDENTIAL, but it isn't in a very subtle way
- * because mech_krb5 isn't so smart). Specifically mech_krb5 will try hard
- * to get a non-expired TGT using the keytab if we're running as root (or fake
- * it, using the special app_krb5_user_uid() function), but only when we use
- * the default credential, as opposed to a credential for the default principal.
- *
- * Paramters:
- * user : username to retrieve a handle to its credential
- * pwd : password of username in case obtaining a new TGT is needed
- * kinit_retry: if 0 then a second attempt will be made to get handle to the
- * credential if the first attempt fails
- * caller_mod : name of module that call this routine so that the module name
- * can be included with error messages
- * Returns:
- * cred_handle: handle to the administrative user's credential (TGT)
- * oid : contains Kerberos 5 object identifier
- * kinit_retry: A 1 indicates that a second attempt has been made to get
- * handle to the credential and no further attempts can be made
- * -1 : error
- * 0 : success
- */
-static int
-krb5_acquire_cred_kinit_main(char *user, char *pwd, gss_cred_id_t *cred_handle,
- gss_OID *oid, int *kinit_retry, char *caller_mod)
-{
- OM_uint32 maj, min;
- gss_name_t desired_name = GSS_C_NO_NAME;
- gss_OID_set desired_mechs;
- gss_buffer_desc oidstr, name_buf;
- char str[50], user_name[50];
-
- *cred_handle = GSS_C_NO_CREDENTIAL;
- *oid = GSS_C_NO_OID;
- if (user == NULL || *user == '\0')
- return (0);
-
- /* Object Identifier for Kerberos 5 */
- (void) strcpy(str, "{ 1 2 840 113554 1 2 2 }");
- oidstr.value = str;
- oidstr.length = strlen(str);
- if ((maj = gss_str_to_oid(&min, &oidstr, oid)) != GSS_S_COMPLETE) {
- krb5_display_stat(maj, min, caller_mod);
- return (-1);
- }
- if ((maj = gss_create_empty_oid_set(&min, &desired_mechs))
- != GSS_S_COMPLETE) {
- krb5_display_stat(maj, min, caller_mod);
- (void) gss_release_oid(&min, oid);
- return (-1);
- }
- if ((maj = gss_add_oid_set_member(&min, *oid, &desired_mechs))
- != GSS_S_COMPLETE) {
- krb5_display_stat(maj, min, caller_mod);
- (void) gss_release_oid(&min, oid);
- (void) gss_release_oid_set(&min, &desired_mechs);
- return (-1);
+ goto cleanup;
}
- (void) strcpy(user_name, user);
- name_buf.value = user_name;
- name_buf.length = strlen(user_name)+1;
- if ((maj = gss_import_name(&min, &name_buf, GSS_C_NT_USER_NAME,
- &desired_name)) != GSS_S_COMPLETE) {
- krb5_display_stat(maj, min, caller_mod);
- (void) gss_release_oid(&min, oid);
- (void) gss_release_oid_set(&min, &desired_mechs);
- return (-1);
+ code = krb5_cc_initialize(ctx, cc, me);
+ if (code != 0) {
+ doing = "initializing cache";
+ goto cleanup;
}
-acquire_cred:
- if ((maj = gss_acquire_cred(&min, desired_name, 0, desired_mechs,
- GSS_C_INITIATE, cred_handle, NULL, NULL)) != GSS_S_COMPLETE) {
- if (!*kinit_retry && pwd != NULL && *pwd != '\0') {
- (void) smb_kinit(user, pwd);
- *kinit_retry = 1;
- goto acquire_cred;
- } else {
- krb5_display_stat(maj, min, caller_mod);
- (void) gss_release_oid(&min, oid);
- (void) gss_release_oid_set(&min, &desired_mechs);
- (void) gss_release_name(&min, &desired_name);
- if (pwd == NULL || *pwd == '\0') {
- /* See above */
- *cred_handle = GSS_C_NO_CREDENTIAL;
- return (0);
- }
- return (-1);
- }
+ code = krb5_cc_store_cred(ctx, cc, &my_creds);
+ if (code != 0) {
+ doing = "storing credentials";
+ goto cleanup;
}
- (void) gss_release_oid_set(&min, &desired_mechs);
- (void) gss_release_name(&min, &desired_name);
+ /* SUCCESS! */
- return (0);
-}
+cleanup:
+ if (code != 0) {
+ if (errmsg == NULL)
+ errmsg = error_message(code);
+ syslog(LOG_ERR, "k5_kinit: %s (%s)", doing, errmsg);
+ }
-/*
- * krb5_establish_sec_ctx_kinit
- *
- * This routine is called by the ADS module to establish a security
- * context before ADS updates are allowed. If establishing a security context
- * fails for any reason, a second attempt will be made after a new TGT is
- * obtained. This routine is called many time as needed until a security
- * context is established.
- *
- * The resources use for the security context must be released if security
- * context establishment process fails.
- * Parameters:
- * user : user used in establishing a security context for. Is used for
- * obtaining a new TGT for a second attempt at establishing
- * security context
- * pwd : password of above user
- * cred_handle: a handle to the user credential (TGT) stored locally
- * gss_context: initially set to GSS_C_NO_CONTEXT but will contain a handle
- * to a security context
- * target_name: contains service name to establish a security context with,
- * ie ldap or dns
- * gss_flags : flags used in establishing security context
- * inputptr : initially set to GSS_C_NO_BUFFER but will be token data
- * received from service's server to be processed to generate
- * further token to be sent back to service's server during
- * security context establishment
- * kinit_retry: if 0 then a second attempt will be made to get handle to the
- * credential if the first attempt fails
- * caller_mod : name of module that call this routine so that the module name
- * can be included with error messages
- * Returns:
- * gss_context : a handle to a security context
- * out_tok : token data to be sent to service's server to establish
- * security context
- * ret_flags : return flags
- * time_rec : valid time for security context, not currently used
- * kinit_retry : A 1 indicates that a second attempt has been made to get
- * handle to the credential and no further attempts can be
- * made
- * do_acquire_cred: A 1 indicates that a new handle to the local credential
- * is needed for second attempt at security context
- * establishment
- * maj : major status code used if determining is security context
- * establishment is successful
- */
-int
-krb5_establish_sec_ctx_kinit(char *user, char *pwd,
- gss_cred_id_t cred_handle, gss_ctx_id_t *gss_context,
- gss_name_t target_name, gss_OID oid, int gss_flags,
- gss_buffer_desc *inputptr, gss_buffer_desc* out_tok,
- OM_uint32 *ret_flags, OM_uint32 *time_rec,
- int *kinit_retry, int *do_acquire_cred,
- OM_uint32 *maj, char *caller_mod)
-{
- OM_uint32 min;
+ if (my_creds.client == me) {
+ my_creds.client = NULL;
+ }
+ krb5_free_cred_contents(ctx, &my_creds);
- *maj = gss_init_sec_context(&min, cred_handle, gss_context,
- target_name, oid, gss_flags, 0, NULL, inputptr, NULL,
- out_tok, ret_flags, time_rec);
- if (*maj != GSS_S_COMPLETE && *maj != GSS_S_CONTINUE_NEEDED) {
- if (*gss_context != NULL)
- (void) gss_delete_sec_context(&min, gss_context, NULL);
+ if (me)
+ krb5_free_principal(ctx, me);
+ if (cc)
+ krb5_cc_close(ctx, cc);
+ if (ctx)
+ krb5_free_context(ctx);
- if ((user != NULL) && (pwd != NULL) && !*kinit_retry) {
- (void) smb_kinit(user, pwd);
- *kinit_retry = 1;
- *do_acquire_cred = 1;
- return (-1);
- } else {
- krb5_display_stat(*maj, min, caller_mod);
- return (-1);
- }
- }
- return (0);
+ return (code == 0);
}
/*
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_krb.h b/usr/src/lib/smbsrv/libsmbns/common/smbns_krb.h
index bdc1d46bc1..ad8b247dcf 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_krb.h
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_krb.h
@@ -19,14 +19,13 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#ifndef _SMBSRV_SMB_KRB5_H
-#define _SMBSRV_SMB_KRB5_H
+#ifndef _SMBSRV_SMB_KRB_H
+#define _SMBSRV_SMB_KRB_H
-#include <gssapi/gssapi.h>
#include <kerberosv5/krb5.h>
#ifdef __cplusplus
@@ -45,19 +44,7 @@ typedef enum smb_krb5_spn_idx {
SMBKRB5_SPN_IDX_MAX
} smb_krb5_spn_idx_t;
-extern gss_OID gss_nt_user_name;
-extern gss_OID gss_nt_machine_uid_name;
-extern gss_OID gss_nt_string_uid_name;
-extern gss_OID gss_nt_service_name;
-extern gss_OID gss_nt_exported_name;
-extern gss_OID gss_nt_service_name_v2;
-
-int krb5_acquire_cred_kinit(char *, char *, gss_cred_id_t *,
- gss_OID *, int *, char *);
-int krb5_establish_sec_ctx_kinit(char *, char *, gss_cred_id_t,
- gss_ctx_id_t *, gss_name_t, gss_OID, int, gss_buffer_desc *,
- gss_buffer_desc *, OM_uint32 *, OM_uint32 *, int *,
- int *, OM_uint32 *, char *);
+int smb_kinit(char *, char *);
char *smb_krb5_get_spn(smb_krb5_spn_idx_t idx, char *fqhost);
char *smb_krb5_get_upn(char *spn, char *domain);
int smb_krb5_ctx_init(krb5_context *ctx);
@@ -76,4 +63,4 @@ boolean_t smb_krb5_find_keytab_entries(const char *fqhn, char *fname);
}
#endif
-#endif /* _SMBSRV_SMB_KRB5_H */
+#endif /* _SMBSRV_SMB_KRB_H */
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.c
index 0f9380c114..2b6117edc5 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.c
@@ -19,175 +19,162 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Main startup code for SMB/NETBIOS and some utility routines
* for the NETBIOS layer.
*/
+#include <sys/tzfile.h>
+#include <assert.h>
#include <synch.h>
#include <unistd.h>
#include <syslog.h>
#include <string.h>
#include <strings.h>
#include <sys/socket.h>
-
+#include <stdio.h>
+#include <pwd.h>
+#include <grp.h>
#include <smbns_netbios.h>
-netbios_status_t nb_status;
+#define SMB_NETBIOS_DUMP_FILE "netbios"
-static pthread_t smb_nbns_thr; /* name service */
-static pthread_t smb_nbds_thr; /* dgram service */
-static pthread_t smb_nbts_thr; /* timer */
-static pthread_t smb_nbbs_thr; /* browser */
+static netbios_service_t nbtd;
-static void *smb_netbios_timer(void *);
+static void smb_netbios_shutdown(void);
+static void *smb_netbios_service(void *);
+static void smb_netbios_dump(void);
-void
-smb_netbios_chg_status(uint32_t status, int set)
+/*
+ * Start the NetBIOS services
+ */
+int
+smb_netbios_start(void)
{
- (void) mutex_lock(&nb_status.mtx);
- if (set)
- nb_status.state |= status;
- else
- nb_status.state &= ~status;
- (void) cond_broadcast(&nb_status.cv);
- (void) mutex_unlock(&nb_status.mtx);
+ pthread_t tid;
+ pthread_attr_t attr;
+ int rc;
+
+ if (smb_netbios_cache_init() < 0)
+ return (-1);
+
+ (void) pthread_attr_init(&attr);
+ (void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ rc = pthread_create(&tid, &attr, smb_netbios_service, NULL);
+ (void) pthread_attr_destroy(&attr);
+ return (rc);
}
+/*
+ * Stop the NetBIOS services
+ */
void
-smb_netbios_shutdown(void)
+smb_netbios_stop(void)
{
- smb_netbios_chg_status(NETBIOS_SHUTTING_DOWN, 1);
+ char fname[MAXPATHLEN];
- (void) pthread_join(smb_nbts_thr, 0);
- (void) pthread_join(smb_nbbs_thr, 0);
- (void) pthread_join(smb_nbns_thr, 0);
- (void) pthread_join(smb_nbds_thr, 0);
+ smb_netbios_event(NETBIOS_EVENT_STOP);
+
+ (void) snprintf(fname, MAXPATHLEN, "%s/%s",
+ SMB_VARRUN_DIR, SMB_NETBIOS_DUMP_FILE);
+ (void) unlink(fname);
- nb_status.state = NETBIOS_SHUT_DOWN;
}
-int
-smb_netbios_start(void)
+/*
+ * Launch the NetBIOS Name Service, Datagram and Browser services
+ * and then sit in a loop providing a 1 second resolution timer.
+ * The timer will:
+ * - update the netbios stats file every 10 minutes
+ * - clean the cache every 10 minutes
+ */
+/*ARGSUSED*/
+static void *
+smb_netbios_service(void *arg)
{
- int rc;
- mutex_t *mp;
- cond_t *cvp;
-
- /* Startup Netbios named; port 137 */
- rc = pthread_create(&smb_nbns_thr, 0,
- smb_netbios_name_service_daemon, 0);
- if (rc)
- return (-1);
+ static uint32_t ticks = 0;
+ pthread_t tid;
+ int rc;
- mp = &nb_status.mtx;
- cvp = &nb_status.cv;
+ smb_netbios_event(NETBIOS_EVENT_START);
- (void) mutex_lock(mp);
- while (!(nb_status.state & (NETBIOS_NAME_SVC_RUNNING |
- NETBIOS_NAME_SVC_FAILED))) {
- (void) cond_wait(cvp, mp);
+ rc = pthread_create(&tid, NULL, smb_netbios_name_service, NULL);
+ if (rc != 0) {
+ smb_netbios_shutdown();
+ return (NULL);
}
- if (nb_status.state & NETBIOS_NAME_SVC_FAILED) {
- (void) mutex_unlock(mp);
+ smb_netbios_wait(NETBIOS_EVENT_NS_START);
+ if (smb_netbios_error()) {
smb_netbios_shutdown();
- return (-1);
+ return (NULL);
}
- (void) mutex_unlock(mp);
smb_netbios_name_config();
- /* Startup Netbios datagram service; port 138 */
- rc = pthread_create(&smb_nbds_thr, 0,
- smb_netbios_datagram_service_daemon, 0);
+ rc = pthread_create(&tid, NULL, smb_netbios_datagram_service, NULL);
if (rc != 0) {
smb_netbios_shutdown();
- return (-1);
- }
-
- (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);
- smb_netbios_shutdown();
- return (-1);
+ return (NULL);
}
- (void) mutex_unlock(mp);
- /* Startup Netbios browser service */
- rc = pthread_create(&smb_nbbs_thr, 0, smb_browser_daemon, 0);
- if (rc) {
+ smb_netbios_wait(NETBIOS_EVENT_DGM_START);
+ if (smb_netbios_error()) {
smb_netbios_shutdown();
- return (-1);
+ return (NULL);
}
- /* Startup Our internal, 1 second resolution, timer */
- rc = pthread_create(&smb_nbts_thr, 0, smb_netbios_timer, 0);
+ rc = pthread_create(&tid, NULL, smb_browser_service, NULL);
if (rc != 0) {
smb_netbios_shutdown();
- return (-1);
+ return (NULL);
}
- (void) mutex_lock(mp);
- while (!(nb_status.state & (NETBIOS_TIMER_RUNNING |
- NETBIOS_TIMER_FAILED))) {
- (void) cond_wait(cvp, mp);
- }
+ smb_netbios_event(NETBIOS_EVENT_TIMER_START);
- if (nb_status.state & NETBIOS_TIMER_FAILED) {
- (void) mutex_unlock(mp);
- smb_netbios_shutdown();
- return (-1);
- }
- (void) mutex_unlock(mp);
-
- return (0);
-}
-
-/*ARGSUSED*/
-static void *
-smb_netbios_timer(void *arg)
-{
- static unsigned int ticks = 0;
-
- smb_netbios_chg_status(NETBIOS_TIMER_RUNNING, 1);
-
- while ((nb_status.state & NETBIOS_SHUTTING_DOWN) == 0) {
+ for (;;) {
(void) sleep(1);
ticks++;
- if ((nb_status.state & NETBIOS_DATAGRAM_SVC_RUNNING) == 0)
- break;
-
- if ((nb_status.state & NETBIOS_NAME_SVC_RUNNING) == 0)
+ if (!smb_netbios_running())
break;
smb_netbios_datagram_tick();
smb_netbios_name_tick();
- /* every 10 minutes */
- if ((ticks % 600) == 0)
+ if ((ticks % 600) == 0) {
+ smb_netbios_event(NETBIOS_EVENT_DUMP);
smb_netbios_cache_clean();
+ }
}
- nb_status.state &= ~NETBIOS_TIMER_RUNNING;
- if ((nb_status.state & NETBIOS_SHUTTING_DOWN) == 0) {
- /* either name or datagram service has failed */
- smb_netbios_shutdown();
- }
+ smb_netbios_event(NETBIOS_EVENT_TIMER_STOP);
+ smb_netbios_shutdown();
+ return (NULL);
+}
+
+static void
+smb_netbios_shutdown(void)
+{
+ (void) pthread_join(nbtd.nbs_browser.s_tid, 0);
+ (void) pthread_join(nbtd.nbs_dgm.s_tid, 0);
+ (void) pthread_join(nbtd.nbs_ns.s_tid, 0);
- return (0);
+ nbtd.nbs_browser.s_tid = 0;
+ nbtd.nbs_dgm.s_tid = 0;
+ nbtd.nbs_ns.s_tid = 0;
+
+ smb_netbios_cache_fini();
+
+ if (smb_netbios_error()) {
+ smb_netbios_event(NETBIOS_EVENT_RESET);
+ if (smb_netbios_start() != 0)
+ syslog(LOG_ERR, "netbios: restart failed");
+ }
}
int
@@ -264,3 +251,283 @@ smb_init_name_struct(unsigned char *name, char suffix, unsigned char *scope,
dest->addr_list.attributes = addr_attr;
dest->addr_list.forw = dest->addr_list.back = &dest->addr_list;
}
+
+void
+smb_netbios_event(netbios_event_t event)
+{
+ static char *event_msg[] = {
+ "startup",
+ "shutdown",
+ "restart",
+ "name service started",
+ "name service stopped",
+ "datagram service started",
+ "datagram service stopped",
+ "browser service started",
+ "browser service stopped",
+ "timer service started",
+ "timer service stopped",
+ "error",
+ "dump"
+ };
+
+ (void) mutex_lock(&nbtd.nbs_mtx);
+
+ if (event == NETBIOS_EVENT_DUMP) {
+ if (nbtd.nbs_last_event == NULL)
+ nbtd.nbs_last_event = event_msg[event];
+ smb_netbios_dump();
+ (void) mutex_unlock(&nbtd.nbs_mtx);
+ return;
+ }
+
+ nbtd.nbs_last_event = event_msg[event];
+ syslog(LOG_DEBUG, "netbios: %s", nbtd.nbs_last_event);
+
+ switch (nbtd.nbs_state) {
+ case NETBIOS_STATE_INIT:
+ if (event == NETBIOS_EVENT_START)
+ nbtd.nbs_state = NETBIOS_STATE_RUNNING;
+ break;
+
+ case NETBIOS_STATE_RUNNING:
+ switch (event) {
+ case NETBIOS_EVENT_NS_START:
+ nbtd.nbs_ns.s_tid = pthread_self();
+ nbtd.nbs_ns.s_up = B_TRUE;
+ break;
+ case NETBIOS_EVENT_NS_STOP:
+ nbtd.nbs_ns.s_up = B_FALSE;
+ break;
+ case NETBIOS_EVENT_DGM_START:
+ nbtd.nbs_dgm.s_tid = pthread_self();
+ nbtd.nbs_dgm.s_up = B_TRUE;
+ break;
+ case NETBIOS_EVENT_DGM_STOP:
+ nbtd.nbs_dgm.s_up = B_FALSE;
+ break;
+ case NETBIOS_EVENT_BROWSER_START:
+ nbtd.nbs_browser.s_tid = pthread_self();
+ nbtd.nbs_browser.s_up = B_TRUE;
+ break;
+ case NETBIOS_EVENT_BROWSER_STOP:
+ nbtd.nbs_browser.s_up = B_FALSE;
+ break;
+ case NETBIOS_EVENT_TIMER_START:
+ nbtd.nbs_timer.s_tid = pthread_self();
+ nbtd.nbs_timer.s_up = B_TRUE;
+ break;
+ case NETBIOS_EVENT_TIMER_STOP:
+ nbtd.nbs_timer.s_up = B_FALSE;
+ break;
+ case NETBIOS_EVENT_STOP:
+ nbtd.nbs_state = NETBIOS_STATE_CLOSING;
+ break;
+ case NETBIOS_EVENT_ERROR:
+ nbtd.nbs_state = NETBIOS_STATE_ERROR;
+ ++nbtd.nbs_errors;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case NETBIOS_STATE_CLOSING:
+ case NETBIOS_STATE_ERROR:
+ default:
+ switch (event) {
+ case NETBIOS_EVENT_NS_STOP:
+ nbtd.nbs_ns.s_up = B_FALSE;
+ break;
+ case NETBIOS_EVENT_DGM_STOP:
+ nbtd.nbs_dgm.s_up = B_FALSE;
+ break;
+ case NETBIOS_EVENT_BROWSER_STOP:
+ nbtd.nbs_browser.s_up = B_FALSE;
+ break;
+ case NETBIOS_EVENT_TIMER_STOP:
+ nbtd.nbs_timer.s_up = B_FALSE;
+ break;
+ case NETBIOS_EVENT_STOP:
+ nbtd.nbs_state = NETBIOS_STATE_CLOSING;
+ break;
+ case NETBIOS_EVENT_RESET:
+ nbtd.nbs_state = NETBIOS_STATE_INIT;
+ break;
+ case NETBIOS_EVENT_ERROR:
+ ++nbtd.nbs_errors;
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+
+ smb_netbios_dump();
+ (void) cond_broadcast(&nbtd.nbs_cv);
+ (void) mutex_unlock(&nbtd.nbs_mtx);
+}
+
+void
+smb_netbios_wait(netbios_event_t event)
+{
+ boolean_t *svc = NULL;
+ boolean_t desired_state;
+
+ (void) mutex_lock(&nbtd.nbs_mtx);
+
+ switch (event) {
+ case NETBIOS_EVENT_NS_START:
+ case NETBIOS_EVENT_NS_STOP:
+ svc = &nbtd.nbs_ns.s_up;
+ desired_state =
+ (event == NETBIOS_EVENT_NS_START) ? B_TRUE : B_FALSE;
+ break;
+ case NETBIOS_EVENT_DGM_START:
+ case NETBIOS_EVENT_DGM_STOP:
+ svc = &nbtd.nbs_dgm.s_up;
+ desired_state =
+ (event == NETBIOS_EVENT_DGM_START) ? B_TRUE : B_FALSE;
+ break;
+ case NETBIOS_EVENT_BROWSER_START:
+ case NETBIOS_EVENT_BROWSER_STOP:
+ svc = &nbtd.nbs_browser.s_up;
+ desired_state =
+ (event == NETBIOS_EVENT_BROWSER_START) ? B_TRUE : B_FALSE;
+ break;
+ default:
+ (void) mutex_unlock(&nbtd.nbs_mtx);
+ return;
+ }
+
+ while (*svc != desired_state) {
+ if (nbtd.nbs_state != NETBIOS_STATE_RUNNING)
+ break;
+
+ (void) cond_wait(&nbtd.nbs_cv, &nbtd.nbs_mtx);
+ }
+
+ (void) mutex_unlock(&nbtd.nbs_mtx);
+}
+
+void
+smb_netbios_sleep(time_t seconds)
+{
+ timestruc_t reltimeout;
+
+ (void) mutex_lock(&nbtd.nbs_mtx);
+
+ if (nbtd.nbs_state == NETBIOS_STATE_RUNNING) {
+ if (seconds == 0)
+ seconds = 1;
+ reltimeout.tv_sec = seconds;
+ reltimeout.tv_nsec = 0;
+
+ (void) cond_reltimedwait(&nbtd.nbs_cv,
+ &nbtd.nbs_mtx, &reltimeout);
+ }
+
+ (void) mutex_unlock(&nbtd.nbs_mtx);
+}
+
+boolean_t
+smb_netbios_running(void)
+{
+ boolean_t is_running;
+
+ (void) mutex_lock(&nbtd.nbs_mtx);
+
+ if (nbtd.nbs_state == NETBIOS_STATE_RUNNING)
+ is_running = B_TRUE;
+ else
+ is_running = B_FALSE;
+
+ (void) mutex_unlock(&nbtd.nbs_mtx);
+ return (is_running);
+}
+
+boolean_t
+smb_netbios_error(void)
+{
+ boolean_t error;
+
+ (void) mutex_lock(&nbtd.nbs_mtx);
+
+ if (nbtd.nbs_state == NETBIOS_STATE_ERROR)
+ error = B_TRUE;
+ else
+ error = B_FALSE;
+
+ (void) mutex_unlock(&nbtd.nbs_mtx);
+ return (error);
+}
+
+/*
+ * Write the service state to /var/run/smb/netbios.
+ *
+ * This is a private interface. To update the file use:
+ * smb_netbios_event(NETBIOS_EVENT_DUMP);
+ */
+static void
+smb_netbios_dump(void)
+{
+ static struct {
+ netbios_state_t state;
+ char *text;
+ } sm[] = {
+ { NETBIOS_STATE_INIT, "init" },
+ { NETBIOS_STATE_RUNNING, "running" },
+ { NETBIOS_STATE_CLOSING, "closing" },
+ { NETBIOS_STATE_ERROR, "error" }
+ };
+
+ char fname[MAXPATHLEN];
+ FILE *fp;
+ struct passwd *pwd;
+ struct group *grp;
+ uid_t uid;
+ gid_t gid;
+ char *last_event = "none";
+ int i;
+
+ (void) snprintf(fname, MAXPATHLEN, "%s/%s",
+ SMB_VARRUN_DIR, SMB_NETBIOS_DUMP_FILE);
+
+ if ((fp = fopen(fname, "w")) == NULL)
+ return;
+
+ pwd = getpwnam("root");
+ grp = getgrnam("sys");
+ uid = (pwd == NULL) ? 0 : pwd->pw_uid;
+ gid = (grp == NULL) ? 3 : grp->gr_gid;
+
+ (void) lockf(fileno(fp), F_LOCK, 0);
+ (void) fchmod(fileno(fp), 0600);
+ (void) fchown(fileno(fp), uid, gid);
+
+ if (nbtd.nbs_last_event)
+ last_event = nbtd.nbs_last_event;
+
+ for (i = 0; i < sizeof (sm) / sizeof (sm[0]); ++i) {
+ if (nbtd.nbs_state == sm[i].state) {
+ (void) fprintf(fp,
+ "State %s (event: %s, errors: %u)\n",
+ sm[i].text, last_event, nbtd.nbs_errors);
+ break;
+ }
+ }
+
+ (void) fprintf(fp, "Name Service %-7s (%u)\n",
+ nbtd.nbs_ns.s_up ? "up" : "down", nbtd.nbs_ns.s_tid);
+ (void) fprintf(fp, "Datagram Service %-7s (%u)\n",
+ nbtd.nbs_dgm.s_up ? "up" : "down", nbtd.nbs_dgm.s_tid);
+ (void) fprintf(fp, "Browser Service %-7s (%u)\n",
+ nbtd.nbs_browser.s_up ? "up" : "down", nbtd.nbs_browser.s_tid);
+ (void) fprintf(fp, "Timer Service %-7s (%u)\n",
+ nbtd.nbs_timer.s_up ? "up" : "down", nbtd.nbs_timer.s_tid);
+
+ smb_netbios_cache_dump(fp);
+
+ (void) lockf(fileno(fp), F_ULOCK, 0);
+ (void) fclose(fp);
+}
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.h b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.h
index 223e527a7d..9ab53e1ac0 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.h
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios.h
@@ -49,24 +49,45 @@
(e)->forw = 0; \
(e)->back = 0;
-#define NETBIOS_NAME_SVC_LAUNCHED 0x00001
-#define NETBIOS_NAME_SVC_RUNNING 0x00002
-#define NETBIOS_NAME_SVC_FAILED 0x00004
+typedef enum {
+ NETBIOS_EVENT_START = 0,
+ NETBIOS_EVENT_STOP,
+ NETBIOS_EVENT_RESET,
+ NETBIOS_EVENT_NS_START,
+ NETBIOS_EVENT_NS_STOP,
+ NETBIOS_EVENT_DGM_START,
+ NETBIOS_EVENT_DGM_STOP,
+ NETBIOS_EVENT_BROWSER_START,
+ NETBIOS_EVENT_BROWSER_STOP,
+ NETBIOS_EVENT_TIMER_START,
+ NETBIOS_EVENT_TIMER_STOP,
+ NETBIOS_EVENT_ERROR,
+ NETBIOS_EVENT_DUMP
+} netbios_event_t;
+
+typedef enum {
+ NETBIOS_STATE_INIT = 0,
+ NETBIOS_STATE_RUNNING,
+ NETBIOS_STATE_CLOSING,
+ NETBIOS_STATE_ERROR
+} netbios_state_t;
-#define NETBIOS_DATAGRAM_SVC_LAUNCHED 0x00010
-#define NETBIOS_DATAGRAM_SVC_RUNNING 0x00020
-#define NETBIOS_DATAGRAM_SVC_FAILED 0x00040
-
-#define NETBIOS_TIMER_LAUNCHED 0x00100
-#define NETBIOS_TIMER_RUNNING 0x00200
-#define NETBIOS_TIMER_FAILED 0x00400
-
-#define NETBIOS_BROWSER_LAUNCHED 0x01000
-#define NETBIOS_BROWSER_RUNNING 0x02000
-#define NETBIOS_BROWSER_FAILED 0x04000
+typedef struct {
+ pthread_t s_tid;
+ boolean_t s_up;
+} netbios_svc_t;
-#define NETBIOS_SHUTTING_DOWN 0x10000
-#define NETBIOS_SHUT_DOWN 0x20000
+typedef struct {
+ mutex_t nbs_mtx;
+ cond_t nbs_cv;
+ netbios_svc_t nbs_ns;
+ netbios_svc_t nbs_dgm;
+ netbios_svc_t nbs_browser;
+ netbios_svc_t nbs_timer;
+ netbios_state_t nbs_state;
+ uint32_t nbs_errors;
+ char *nbs_last_event;
+} netbios_service_t;
char smb_node_type;
@@ -75,13 +96,6 @@ char smb_node_type;
#define SMB_NODETYPE_M 'M'
#define SMB_NODETYPE_H 'H'
-typedef struct {
- mutex_t mtx;
- cond_t cv;
- uint32_t state;
-} netbios_status_t;
-extern netbios_status_t nb_status;
-
/*
* NAME service definitions
*/
@@ -614,14 +628,22 @@ typedef struct nbcache_iter {
#define NETBIOS_NAME_IS_STAR(name) \
(bcmp(name, "*\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", NETBIOS_NAME_SZ) == 0)
-void smb_netbios_chg_status(uint32_t status, int set);
+
+/*
+ * NetBIOS service state machine interface
+ */
+void smb_netbios_event(netbios_event_t);
+void smb_netbios_wait(netbios_event_t);
+void smb_netbios_sleep(time_t);
+boolean_t smb_netbios_running(void);
+boolean_t smb_netbios_error(void);
/*
* Name Cache Functions
*/
int smb_netbios_cache_init(void);
void smb_netbios_cache_fini(void);
-void smb_netbios_cache_dump(void);
+void smb_netbios_cache_dump(FILE *fp);
int smb_netbios_cache_count(void);
void smb_netbios_cache_clean(void);
void smb_netbios_cache_reset_ttl(void);
@@ -640,13 +662,13 @@ unsigned char *smb_netbios_cache_status(unsigned char *, int, unsigned char *);
int smb_netbios_cache_getfirst(nbcache_iter_t *);
int smb_netbios_cache_getnext(nbcache_iter_t *);
-void smb_netbios_name_dump(struct name_entry *entry);
+void smb_netbios_name_dump(FILE *fp, struct name_entry *entry);
void smb_netbios_name_logf(struct name_entry *entry);
void smb_netbios_name_freeaddrs(struct name_entry *entry);
struct name_entry *smb_netbios_name_dup(struct name_entry *, int);
/* Name service functions */
-void *smb_netbios_name_service_daemon(void *);
+void *smb_netbios_name_service(void *);
void smb_init_name_struct(unsigned char *, char, unsigned char *, uint32_t,
unsigned short, uint32_t, uint32_t, struct name_entry *);
@@ -665,14 +687,14 @@ void smb_encode_netbios_name(unsigned char *, char, unsigned char *,
struct name_entry *);
/* Datagram service functions */
-void *smb_netbios_datagram_service_daemon(void *);
+void *smb_netbios_datagram_service(void *);
int smb_netbios_datagram_send(struct name_entry *,
struct name_entry *, unsigned char *, int);
void smb_netbios_datagram_tick(void);
/* browser functions */
void *smb_browser_dispatch(void *arg);
-void *smb_browser_daemon(void *);
+void *smb_browser_service(void *);
int smb_browser_load_transact_header(unsigned char *, int, int, int, char *);
/* Netlogon function */
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 dae42d4d7f..e5d1bf74b1 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_cache.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_cache.c
@@ -19,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 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 <syslog.h>
@@ -38,42 +36,37 @@
#define NETBIOS_HTAB_SZ 128
#define NETBIOS_HKEY_SZ (NETBIOS_NAME_SZ + NETBIOS_DOMAIN_NAME_MAX)
-#define NETBIOS_NAMEBUF char namebuf[20]
-
#define NETBIOS_SAME_IP(addr1, addr2) \
((addr1)->sin.sin_addr.s_addr == (addr2)->sin.sin_addr.s_addr)
-int smb_netbios_name_debug = 0;
-
typedef char nb_key_t[NETBIOS_HKEY_SZ];
static HT_HANDLE *smb_netbios_cache = 0;
static rwlock_t nb_cache_lock;
-static char *smb_strname(struct name_entry *name, char *buf, int bufsize);
+static void smb_strname(struct name_entry *name, char *buf, int bufsize);
static void hash_callback(HT_ITEM *item);
static int smb_netbios_match(const char *key1, const char *key2, size_t n);
static void smb_netbios_cache_key(char *key, unsigned char *name,
unsigned char *scope);
int
-smb_netbios_cache_init()
+smb_netbios_cache_init(void)
{
(void) rw_wrlock(&nb_cache_lock);
- if (smb_netbios_cache == 0) {
+ if (smb_netbios_cache == NULL) {
smb_netbios_cache = ht_create_table(NETBIOS_HTAB_SZ,
NETBIOS_HKEY_SZ, HTHF_FIXED_KEY);
- if (smb_netbios_cache == 0) {
- syslog(LOG_ERR,
- "smbd: cannot create NetBIOS name cache");
+ if (smb_netbios_cache == NULL) {
+ syslog(LOG_ERR, "nbns: cannot create name cache");
(void) rw_unlock(&nb_cache_lock);
- return (0);
+ return (-1);
}
(void) ht_register_callback(smb_netbios_cache, hash_callback);
ht_set_cmpfn(smb_netbios_cache, smb_netbios_match);
}
(void) rw_unlock(&nb_cache_lock);
- return (1);
+ return (0);
}
void
@@ -81,7 +74,7 @@ smb_netbios_cache_fini(void)
{
(void) rw_wrlock(&nb_cache_lock);
ht_destroy_table(smb_netbios_cache);
- smb_netbios_cache = 0;
+ smb_netbios_cache = NULL;
(void) rw_unlock(&nb_cache_lock);
}
@@ -201,8 +194,8 @@ struct name_entry *
smb_netbios_cache_lookup_addr(struct name_entry *name)
{
struct name_entry *entry = 0;
- struct addr_entry *addr;
- struct addr_entry *name_addr;
+ addr_entry_t *addr;
+ addr_entry_t *name_addr;
HT_ITEM *item;
nb_key_t key;
@@ -234,8 +227,8 @@ int
smb_netbios_cache_insert(struct name_entry *name)
{
struct name_entry *entry;
- struct addr_entry *addr;
- struct addr_entry *name_addr;
+ addr_entry_t *addr;
+ addr_entry_t *name_addr;
HT_ITEM *item;
nb_key_t key;
int rc;
@@ -275,7 +268,7 @@ smb_netbios_cache_insert(struct name_entry *name)
}
}
- if ((addr = malloc(sizeof (struct addr_entry))) != NULL) {
+ if ((addr = malloc(sizeof (addr_entry_t))) != NULL) {
*addr = name->addr_list;
entry->attributes |= addr->attributes;
QUEUE_INSERT_TAIL(&entry->addr_list, addr);
@@ -337,7 +330,7 @@ int
smb_netbios_cache_insert_list(struct name_entry *name)
{
struct name_entry entry;
- struct addr_entry *addr;
+ addr_entry_t *addr;
addr = &name->addr_list;
do {
@@ -361,8 +354,8 @@ void
smb_netbios_cache_update_entry(struct name_entry *entry,
struct name_entry *name)
{
- struct addr_entry *addr;
- struct addr_entry *name_addr;
+ addr_entry_t *addr;
+ addr_entry_t *name_addr;
addr = &entry->addr_list;
name_addr = &name->addr_list;
@@ -442,7 +435,7 @@ smb_netbios_cache_status(unsigned char *buf, int bufsize, unsigned char *scope)
void
smb_netbios_cache_reset_ttl()
{
- struct addr_entry *addr;
+ addr_entry_t *addr;
struct name_entry *name;
HT_ITERATOR hti;
HT_ITEM *item;
@@ -524,7 +517,7 @@ void
smb_netbios_cache_refresh(name_queue_t *refq)
{
struct name_entry *name;
- struct addr_entry *addr;
+ addr_entry_t *addr;
HT_ITERATOR hti;
HT_ITEM *item;
@@ -608,7 +601,7 @@ smb_netbios_cache_delete_locals(name_queue_t *delq)
void
smb_netbios_name_freeaddrs(struct name_entry *entry)
{
- struct addr_entry *addr;
+ addr_entry_t *addr;
if (entry == 0)
return;
@@ -637,19 +630,28 @@ smb_netbios_cache_count()
}
void
-smb_netbios_cache_dump(void)
+smb_netbios_cache_dump(FILE *fp)
{
struct name_entry *name;
HT_ITERATOR hti;
HT_ITEM *item;
(void) rw_rdlock(&nb_cache_lock);
+
+ if (ht_get_total_items(smb_netbios_cache) != 0) {
+ (void) fprintf(fp, "\n%-22s %-16s %-16s %s\n",
+ "Name", "Type", "Address", "TTL");
+ (void) fprintf(fp, "%s%s\n",
+ "-------------------------------",
+ "------------------------------");
+ }
+
item = ht_findfirst(smb_netbios_cache, &hti);
while (item) {
if (item->hi_data) {
name = (struct name_entry *)item->hi_data;
(void) mutex_lock(&name->mtx);
- smb_netbios_name_dump(name);
+ smb_netbios_name_dump(fp, name);
(void) mutex_unlock(&name->mtx);
}
item = ht_findnext(&hti);
@@ -658,29 +660,28 @@ smb_netbios_cache_dump(void)
}
void
-smb_netbios_name_dump(struct name_entry *entry)
+smb_netbios_name_dump(FILE *fp, struct name_entry *entry)
{
- struct addr_entry *addr;
- int count = 0;
+ char buf[MAXHOSTNAMELEN];
+ addr_entry_t *addr;
+ char *type;
+ int count = 0;
- if (smb_netbios_name_debug == 0)
- return;
+ smb_strname(entry, buf, sizeof (buf));
+ type = (IS_UNIQUE(entry->attributes)) ? "UNIQUE" : "GROUP";
+
+ (void) fprintf(fp, "%s %-6s (0x%04x) ", buf, type, entry->attributes);
- syslog(LOG_DEBUG, "name='%15.15s<%02X>' scope='%s' attr=0x%x",
- entry->name, entry->name[15],
- entry->scope, entry->attributes);
addr = &entry->addr_list;
do {
- syslog(LOG_DEBUG, "addr_list[%d]:", count++);
- syslog(LOG_DEBUG, " attributes = 0x%x", addr->attributes);
- syslog(LOG_DEBUG, " conflict_timer = %d",
- addr->conflict_timer);
- syslog(LOG_DEBUG, " refresh_ttl = %d", addr->refresh_ttl);
- syslog(LOG_DEBUG, " ttl = %d", addr->ttl);
- syslog(LOG_DEBUG, " sin.sin_addr = %s",
- inet_ntoa(addr->sin.sin_addr));
- syslog(LOG_DEBUG, " sin.sin_port = %d", addr->sin.sin_port);
- syslog(LOG_DEBUG, " sin.sinlen = %d", addr->sinlen);
+ if (count == 0)
+ (void) fprintf(fp, "%-16s %d\n",
+ inet_ntoa(addr->sin.sin_addr), addr->ttl);
+ else
+ (void) fprintf(fp, "%-28s (0x%04x) %-16s %d\n",
+ " ", addr->attributes,
+ inet_ntoa(addr->sin.sin_addr), addr->ttl);
+ ++count;
addr = addr->forw;
} while (addr != &entry->addr_list);
}
@@ -688,16 +689,17 @@ smb_netbios_name_dump(struct name_entry *entry)
void
smb_netbios_name_logf(struct name_entry *entry)
{
- struct addr_entry *addr;
- NETBIOS_NAMEBUF;
+ char namebuf[MAXHOSTNAMELEN];
+ addr_entry_t *addr;
- (void) smb_strname(entry, namebuf, sizeof (namebuf));
+ smb_strname(entry, namebuf, sizeof (namebuf));
syslog(LOG_DEBUG, "%s flags=0x%x\n", namebuf, entry->attributes);
addr = &entry->addr_list;
do {
- syslog(LOG_DEBUG, " %s ttl=%d flags=0x%x",
+ syslog(LOG_DEBUG, " %s ttl=%d flags=0x%x port=%d",
inet_ntoa(addr->sin.sin_addr),
- addr->ttl, addr->attributes);
+ addr->ttl, addr->attributes,
+ addr->sin.sin_port);
addr = addr->forw;
} while (addr && (addr != &entry->addr_list));
}
@@ -716,8 +718,8 @@ smb_netbios_name_logf(struct name_entry *entry)
struct name_entry *
smb_netbios_name_dup(struct name_entry *entry, int alladdr)
{
- struct addr_entry *addr;
- struct addr_entry *dup_addr;
+ addr_entry_t *addr;
+ addr_entry_t *dup_addr;
struct name_entry *dup;
int addr_cnt = 0;
int size = 0;
@@ -731,7 +733,7 @@ smb_netbios_name_dup(struct name_entry *entry, int alladdr)
}
size = sizeof (struct name_entry) +
- (addr_cnt * sizeof (struct addr_entry));
+ (addr_cnt * sizeof (addr_entry_t));
dup = (struct name_entry *)malloc(size);
if (dup == 0)
return (0);
@@ -750,7 +752,7 @@ smb_netbios_name_dup(struct name_entry *entry, int alladdr)
return (dup);
/* LINTED - E_BAD_PTR_CAST_ALIGN */
- dup_addr = (struct addr_entry *)((unsigned char *)dup +
+ dup_addr = (addr_entry_t *)((unsigned char *)dup +
sizeof (struct name_entry));
addr = entry->addr_list.forw;
@@ -764,17 +766,22 @@ smb_netbios_name_dup(struct name_entry *entry, int alladdr)
return (dup);
}
-static char *
-smb_strname(struct name_entry *name, char *buf, int bufsize)
+static void
+smb_strname(struct name_entry *entry, char *buf, int bufsize)
{
- char *p;
+ char tmp[MAXHOSTNAMELEN];
+ char *p;
+
+ (void) snprintf(tmp, MAXHOSTNAMELEN, "%15.15s", entry->name);
+ if ((p = strchr(tmp, ' ')) != NULL)
+ *p = '\0';
- (void) snprintf(buf, bufsize, "%15.15s", name->name);
- p = strchr(buf, ' ');
- if (p)
- (void) snprintf(p, 5, "<%02X>", name->name[15]);
+ if (entry->scope[0] != '\0') {
+ (void) strlcat(tmp, ".", MAXHOSTNAMELEN);
+ (void) strlcat(tmp, (char *)entry->scope, MAXHOSTNAMELEN);
+ }
- return (buf);
+ (void) snprintf(buf, bufsize, "%-16s <%02X>", tmp, entry->name[15]);
}
static void
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_datagram.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_datagram.c
index ad6d18f649..6ec737281a 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_datagram.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_datagram.c
@@ -55,7 +55,7 @@
* The following are Defined Constants for the NetBIOS Datagram
* Service:
*
- * - DGM_SRVC_UDP_PORT: the globally well-known UDP port allocated
+ * - IPPORT_NETBIOS_DGM: the globally well-known UDP port allocated
* where the NetBIOS Datagram Service receives UDP packets. See
* section 6, "Defined Constants", for its value.
*/
@@ -103,11 +103,12 @@
*
* DATAGRAM SERVICE:
*
- * DGM_SRVC_UDP_PORT 138 (decimal)
+ * IPPORT_NETBIOS_DGM 138 (decimal)
*
* FRAGMENT_TO 2 seconds (default)
*/
+#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
@@ -210,7 +211,7 @@ smb_netbios_datagram_fini()
* half-ASCII, biased encoded name;
* SOURCE_NAME = cat(source, SCOPE_ID);
* SOURCE_IP = this nodes IP address;
- * SOURCE_PORT = DGM_SRVC_UDP_PORT;
+ * SOURCE_PORT = IPPORT_NETBIOS_DGM;
*
* IF NetBIOS broadcast THEN
* BEGIN
@@ -318,7 +319,7 @@ smb_netbios_datagram_send(struct name_entry *src, struct name_entry *dest,
{
smb_inaddr_t ipaddr;
size_t count, srclen, destlen, sinlen;
- struct addr_entry *addr;
+ addr_entry_t *addr;
struct sockaddr_in sin;
char *buffer;
char ha_source[NETBIOS_DOMAIN_NAME_MAX];
@@ -333,9 +334,8 @@ smb_netbios_datagram_send(struct name_entry *src, struct name_entry *dest,
destlen = strlen(ha_dest) + 1;
/* give some extra room */
- buffer = (char *)malloc(MAX_DATAGRAM_LENGTH * 4);
- if (buffer == 0) {
- syslog(LOG_ERR, "netbios: datagram send (resource shortage)");
+ if ((buffer = malloc(MAX_DATAGRAM_LENGTH * 4)) == NULL) {
+ syslog(LOG_ERR, "nbt datagram: send: %m");
return (-1);
}
@@ -399,7 +399,7 @@ smb_netbios_datagram_send_to_net(struct name_entry *src,
{
smb_inaddr_t ipaddr;
size_t count, srclen, destlen, sinlen;
- struct addr_entry *addr;
+ addr_entry_t *addr;
struct sockaddr_in sin;
char *buffer;
char ha_source[NETBIOS_DOMAIN_NAME_MAX];
@@ -414,9 +414,8 @@ smb_netbios_datagram_send_to_net(struct name_entry *src,
destlen = strlen(ha_dest) + 1;
/* give some extra room */
- buffer = (char *)malloc(MAX_DATAGRAM_LENGTH * 4);
- if (buffer == 0) {
- syslog(LOG_ERR, "netbios: datagram send (resource shortage)");
+ if ((buffer = malloc(MAX_DATAGRAM_LENGTH * 4)) == NULL) {
+ syslog(LOG_ERR, "nbt datagram: send_to_net: %m");
return (-1);
}
@@ -570,7 +569,7 @@ smb_netbios_datagram_error(unsigned char *buf)
/*
* Function: int smb_netbios_process_BPM_datagram(unsigned char *packet,
- * struct addr_entry *addr)
+ * addr_entry_t *addr)
*
* Description from rfc1002:
*
@@ -797,7 +796,7 @@ process_datagram:
(void) memcpy(&datagram->rawbuf[4],
&datagram->src.addr_list.sin.sin_addr.s_addr,
sizeof (uint32_t));
- BE_OUT16(&datagram->rawbuf[8], DGM_SRVC_UDP_PORT);
+ BE_OUT16(&datagram->rawbuf[8], IPPORT_NETBIOS_DGM);
(void) sendto(datagram_sock, datagram->rawbuf,
datagram->rawbytes, 0,
@@ -812,180 +811,12 @@ process_datagram:
free(datagram);
}
-
-/*
- * smb_netbios_process_NBDD_datagram
- *
- * Description from rfc1002:
- *
- *
- * 5.3.4. PROTOCOLS FOR THE NBDD
- *
- * The key to NetBIOS Datagram forwarding service is the packet
- * delivered to the destination end node must have the same NetBIOS
- * header as if the source end node sent the packet directly to the
- * destination end node. Consequently, the NBDD does not reassemble
- * NetBIOS Datagrams. It forwards the UDP packet as is.
- *
- * PROCEDURE datagram_packet(packet)
- *
- * (*
- * * processing initiated by a incoming datagram service
- * * packet on a NBDD node.
- * *)
- *
- * BEGIN
- * CASE packet type OF
- *
- * DATAGRAM SERVICE:
- * BEGIN
- * IF packet was sent as a directed
- * NetBIOS datagram THEN
- * BEGIN
- * (*
- * * provide group forwarding service
- * *
- * * Forward datagram to each member of the
- * * group. Can forward via:
- * * 1) get list of group members and send
- * * the DATAGRAM SERVICE packet unicast
- * * to each
- * * 2) use Group Multicast, if available
- * * 3) combination of 1) and 2)
- * *)
- *
- * ...
- *
- * END
- *
- * ELSE
- * BEGIN
- * (*
- * * provide broadcast forwarding service
- * *
- * * Forward datagram to every node in the
- * * NetBIOS scope. Can forward via:
- * * 1) get list of group members and send
- * * the DATAGRAM SERVICE packet unicast
- * * to each
- * * 2) use Group Multicast, if available
- * * 3) combination of 1) and 2)
- * *)
- *
- * ...
- *
- * END
- * END (* datagram service *)
- *
- * DATAGRAM ERROR:
- * BEGIN
- * (*
- * * Should never receive these because Datagrams
- * * forwarded have source end node IP address and
- * * port in NetBIOS header.
- * *)
- *
- * send DELETE NAME REQUEST with incorrect name and
- * IP address to NetBIOS Name Server;
- *
- * END (* datagram error *)
- *
- * DATAGRAM QUERY REQUEST:
- * BEGIN
- * IF can send packet to DESTINATION_NAME THEN
- * BEGIN
- * (*
- * * NBDD is able to relay Datagrams for
- * * this name
- * *)
- *
- * send POSITIVE DATAGRAM QUERY RESPONSE to
- * REQUEST source IP address and UDP port
- * with requests DGM_ID;
- * END
- * ELSE
- * BEGIN
- * (*
- * * NBDD is NOT able to relay Datagrams for
- * * this name
- * *)
- *
- * send NEGATIVE DATAGRAM QUERY RESPONSE to
- * REQUEST source IP address and UDP port
- *
- * with requests DGM_ID;
- * END
- * END (* datagram query request *)
- *
- * END (* case *)
- * END (* procedure *)
- */
-
-
/*
- * Function: int smb_netbios_datagram_service_daemon(void)
- *
- * Description:
- *
- * 4.4. DATAGRAM SERVICE PACKETS
- *
- * 4.4.1. NetBIOS DATAGRAM HEADER
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | MSG_TYPE | FLAGS | DGM_ID |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | SOURCE_IP |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | SOURCE_PORT | DGM_LENGTH |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | PACKET_OFFSET |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * MSG_TYPE values (in hexidecimal):
- *
- * 10 - DIRECT_UNIQUE DATAGRAM
- * 11 - DIRECT_GROUP DATAGRAM
- * 12 - BROADCAST DATAGRAM
- * 13 - DATAGRAM ERROR
- * 14 - DATAGRAM QUERY REQUEST
- * 15 - DATAGRAM POSITIVE QUERY RESPONSE
- * 16 - DATAGRAM NEGATIVE QUERY RESPONSE
- *
- * Bit definitions of the FLAGS field:
- *
- * 0 1 2 3 4 5 6 7
- * +---+---+---+---+---+---+---+---+
- * | 0 | 0 | 0 | 0 | SNT | F | M |
- * +---+---+---+---+---+---+---+---+
- *
- * Symbol Bit(s) Description
- *
- * M 7 MORE flag, If set then more NetBIOS datagram
- * fragments follow.
- *
- * F 6 FIRST packet flag, If set then this is first
- * (and possibly only) fragment of NetBIOS
- * datagram
- *
- * SNT 4,5 Source End-Node type:
- * 00 = B node
- * 01 = P node
- * 10 = M node
- * 11 = NBDD
- * RESERVED 0-3 Reserved, must be zero (0)
- *
- * Inputs:
- * Nothing
- *
- * Returns:
- * int -> Description
+ * NetBIOS Datagram Service (port 138)
*/
-
/*ARGSUSED*/
void *
-smb_netbios_datagram_service_daemon(void *arg)
+smb_netbios_datagram_service(void *arg)
{
struct sockaddr_in sin;
struct datagram *datagram;
@@ -999,37 +830,40 @@ smb_netbios_datagram_service_daemon(void *arg)
(void) mutex_unlock(&smb_dgq_mtx);
if ((datagram_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- syslog(LOG_ERR,
- "smbd: Could not create AF_INET, SOCK_DGRAM, socket");
- smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_FAILED, 1);
- return (0);
+ syslog(LOG_ERR, "nbt datagram: socket failed: %m");
+ smb_netbios_event(NETBIOS_EVENT_ERROR);
+ return (NULL);
}
+ flag = 1;
+ (void) setsockopt(datagram_sock, SOL_SOCKET, SO_REUSEADDR, &flag,
+ sizeof (flag));
+
bzero(&sin, sizeof (sin));
sin.sin_family = AF_INET;
- sin.sin_port = htons(DGM_SRVC_UDP_PORT);
+ sin.sin_port = htons(IPPORT_NETBIOS_DGM);
if (bind(datagram_sock, (struct sockaddr *)&sin, sizeof (sin)) != 0) {
- syslog(LOG_ERR, "smbd: Bind to name service port %d failed",
- DGM_SRVC_UDP_PORT);
+ syslog(LOG_ERR, "nbt datagram: bind(%d) failed: %m",
+ IPPORT_NETBIOS_DGM);
(void) close(datagram_sock);
- smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_FAILED, 1);
- return (0);
+ smb_netbios_event(NETBIOS_EVENT_ERROR);
+ return (NULL);
}
+
+ flag = 1;
(void) setsockopt(datagram_sock, SOL_SOCKET, SO_BROADCAST, &flag,
sizeof (flag));
- smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_RUNNING, 1);
+ smb_netbios_event(NETBIOS_EVENT_DGM_START);
- while (((nb_status.state & NETBIOS_SHUTTING_DOWN) == 0) ||
- (nb_status.state & NETBIOS_BROWSER_RUNNING)) {
- if ((datagram = (struct datagram *)
- malloc(sizeof (struct datagram))) == 0) {
- /* Sleep for 10 sec and try again */
- (void) sleep(10);
+ while (smb_netbios_running()) {
+ if ((datagram = malloc(sizeof (struct datagram))) == NULL) {
+ /* Sleep for 10 seconds and try again */
+ smb_netbios_sleep(10);
continue;
}
-ignore: bzero(&datagram->inaddr, sizeof (struct addr_entry));
+ignore: bzero(&datagram->inaddr, sizeof (addr_entry_t));
datagram->inaddr.sinlen = sizeof (datagram->inaddr.sin);
datagram->inaddr.forw = datagram->inaddr.back =
&datagram->inaddr;
@@ -1038,9 +872,8 @@ ignore: bzero(&datagram->inaddr, sizeof (struct addr_entry));
MAX_DATAGRAM_LENGTH, 0,
(struct sockaddr *)&datagram->inaddr.sin,
&datagram->inaddr.sinlen)) < 0) {
- syslog(LOG_ERR,
- "smbd: NETBIOS datagram - recvfrom failed");
- smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_FAILED, 1);
+ syslog(LOG_ERR, "nbt datagram: recvfrom failed: %m");
+ smb_netbios_event(NETBIOS_EVENT_ERROR);
break;
}
@@ -1071,17 +904,12 @@ ignore: bzero(&datagram->inaddr, sizeof (struct addr_entry));
smb_netbios_BPM_datagram(datagram);
}
- smb_netbios_chg_status(NETBIOS_DATAGRAM_SVC_RUNNING, 0);
-
- (void) mutex_lock(&nb_status.mtx);
- while (nb_status.state & NETBIOS_BROWSER_RUNNING)
- (void) cond_wait(&nb_status.cv, &nb_status.mtx);
- (void) mutex_unlock(&nb_status.mtx);
+ smb_netbios_event(NETBIOS_EVENT_DGM_STOP);
+ (void) smb_netbios_wait(NETBIOS_EVENT_BROWSER_STOP);
(void) close(datagram_sock);
smb_netbios_datagram_fini();
- smb_tracef("smbd: Netbios Datagram Service is down\n");
- return (0);
+ return (NULL);
}
static char
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 16a07683cf..9cef0bf8dc 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_name.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_netbios_name.c
@@ -24,65 +24,42 @@
*/
/*
- * Description:
- *
- * Contains base code for netbios name service.
- *
- *
- * 6. DEFINED CONSTANTS AND VARIABLES
- *
- * GENERAL:
- *
- * SCOPE_ID The name of the NetBIOS scope.
- *
- * This is expressed as a character
- * string meeting the requirements of
- * the domain name system and without
- * a leading or trailing "dot".
- *
- * An implementation may elect to make
- * this a single global value for the
- * node or allow it to be specified
- * with each separate NetBIOS name
- * (thus permitting cross-scope
- * references.)
- *
- * BROADCAST_ADDRESS An IP address composed of the
- * nodes's network and subnetwork
- * numbers with all remaining bits set
- * to one.
- *
- * I.e. "Specific subnet" broadcast
- * addressing according to section 2.3
- * of RFC 950.
- *
- * BCAST_REQ_RETRY_TIMEOUT 250 milliseconds.
- * An adaptive timer may be used.
+ * NetBIOS name resolution node types.
*
- * BCAST_REQ_RETRY_COUNT 3
+ * A B-node (broadcast node) uses broadcasts for name registration
+ * and resolution. Routers typically do not forward broadcasts and
+ * only computers on the local subnet will respond.
*
- * UCAST_REQ_RETRY_TIMEOUT 5 seconds
- * An adaptive timer may be used.
+ * A P-node (peer-to-peer node) uses a NetBIOS name server (WINS)
+ * to resolve NetBIOS names, which allows it to work across routers.
+ * In order to function in a P-node environment, all computers must
+ * be configured to use the NetBIOS name server because P-nodes do
+ * not broadcast on the network.
*
- * UCAST_REQ_RETRY_COUNT 3
+ * A mixed node (M-node) behaves as a B-node by default. If it cannot
+ * resolve the name via broadcast then it tries a NetBIOS name server
+ * lookup (P-node).
*
- * MAX_DATAGRAM_LENGTH 576 bytes (default)
+ * A hybrid node (H-node) behaves as a P-node by default. If it cannot
+ * resolve the name using a NetBIOS name server then it resorts to
+ * broadcasts (B-node).
*
+ * NetBIOS Name Service Protocols
*
- * NAME SERVICE:
+ * A REQUEST packet is always sent to the well known UDP port 137.
+ * The destination address is normally either the IP broadcast address or
+ * the address of the NAME - the address of the NAME server it set up at
+ * initialization time. In rare cases, a request packet will be sent to
+ * an end node, e.g. a NAME QUERY REQUEST sent to "challenge" a node.
*
- * REFRESH_TIMER Negotiated with NAME for each name.
+ * A RESPONSE packet is always sent to the source UDP port and source IP
+ * address of the request packet.
*
- * CONFLICT_TIMER 1 second
- * Implementations may chose a longer
- * value.
+ * A DEMAND packet must always be sent to the well known UDP port 137.
+ * There is no restriction on the target IP address.
*
- *
- * NAME_SERVICE_TCP_PORT 137 (decimal)
- *
- * NAME_SERVICE_UDP_PORT 137 (decimal)
- *
- * INFINITE_TTL 0
+ * A transaction ID is a value composed from the requestor's IP address and
+ * a unique 16 bit value generated by the originator of the transaction.
*/
#include <unistd.h>
@@ -99,54 +76,113 @@
#include <smbsrv/libsmbns.h>
#include <smbns_netbios.h>
-#define NAME_HEADER_SIZE 12
+/*
+ * RFC 1002 4.2.1.1. HEADER
+ */
+#define QUESTION_TYPE_NETBIOS_GENERAL 0x20
+#define QUESTION_TYPE_NETBIOS_STATUS 0x21
+
+#define QUESTION_CLASS_INTERNET 0x0001
-typedef struct name_reply {
- struct name_reply *forw;
- struct name_reply *back;
- struct name_packet *packet;
- struct addr_entry *addr;
- unsigned short name_trn_id;
- unsigned short flags;
-} name_reply;
+/*
+ * RFC 1002 4.2.1.3. RESOURCE RECORD
+ */
+#define RR_TYPE_IP_ADDRESS_RESOURCE 0x0001
+#define RR_TYPE_NAME_SERVER_RESOURCE 0x0002
+#define RR_TYPE_NULL_RESOURCE 0x000A
+#define RR_TYPE_NETBIOS_RESOURCE 0x0020
+#define RR_TYPE_NETBIOS_STATUS 0x0021
+
+/*
+ *
+ * RESOURCE RECORD RR_CLASS field definitions
+ */
+#define RR_CLASS_INTERNET_CLASS 0x0001
+
+/*
+ * NB_FLAGS field of the RESOURCE RECORD RDATA field for RR_TYPE of NB.
+ */
+#define RR_FLAGS_NB_ONT_MASK 0x6000
+#define RR_FLAGS_NB_ONT_B_NODE 0x0000
+#define RR_FLAGS_NB_ONT_P_NODE 0x2000
+#define RR_FLAGS_NB_ONT_M_NODE 0x4000
+#define RR_FLAGS_NB_ONT_RESERVED 0x6000
+#define RR_FLAGS_NB_GROUP_NAME 0x8000
-static struct name_reply reply_queue;
+#define NAME_FLAGS_PERMANENT_NAME 0x0200
+#define NAME_FLAGS_ACTIVE_NAME 0x0400
+#define NAME_FLAGS_CONFLICT 0x0800
+#define NAME_FLAGS_DEREGISTER 0x1000
+#define NAME_FLAGS_ONT_MASK 0x6000
+#define NAME_FLAGS_ONT_B_NODE 0x0000
+#define NAME_FLAGS_ONT_P_NODE 0x2000
+#define NAME_FLAGS_ONT_M_NODE 0x4000
+#define NAME_FLAGS_ONT_RESERVED 0x6000
+#define NAME_FLAGS_GROUP_NAME 0x8000
+
+#define MAX_NETBIOS_REPLY_DATA_SIZE 500
+
+#define NAME_HEADER_SIZE 12
+
+typedef struct nbt_name_reply {
+ struct nbt_name_reply *forw;
+ struct nbt_name_reply *back;
+ struct name_packet *packet;
+ addr_entry_t *addr;
+ uint16_t name_trn_id;
+ boolean_t reply_ready;
+} nbt_name_reply_t;
+
+static nbt_name_reply_t reply_queue;
static mutex_t rq_mtx;
+static cond_t rq_cv;
-static mutex_t reply_mtx;
-static cond_t reply_cv;
+static mutex_t nbt_name_config_mtx;
static name_queue_t delete_queue;
static name_queue_t refresh_queue;
-/*
- * Flag to control whether or not NetBIOS name refresh requests
- * are logged. Set to non-zero to enable logging.
- */
-
-static unsigned short netbios_name_transcation_id = 1;
static int name_sock = 0;
static int bcast_num = 0;
static int nbns_num = 0;
-static struct addr_entry smb_bcast_list[SMB_PI_MAX_NETWORKS];
-static struct addr_entry smb_nbns[SMB_PI_MAX_WINS];
+static addr_entry_t smb_bcast_list[SMB_PI_MAX_NETWORKS];
+static addr_entry_t smb_nbns[SMB_PI_MAX_WINS];
-static int smb_netbios_process_response(unsigned short, struct addr_entry *,
+static int smb_netbios_process_response(uint16_t, addr_entry_t *,
struct name_packet *, uint32_t);
-static int smb_send_name_service_packet(struct addr_entry *addr,
+static int smb_send_name_service_packet(addr_entry_t *addr,
struct name_packet *packet);
+/*
+ * Allocate a transaction id.
+ */
+static uint16_t
+smb_netbios_name_trn_id(void)
+{
+ static uint16_t trn_id;
+ static mutex_t trn_id_mtx;
+
+ (void) mutex_lock(&trn_id_mtx);
+
+ do {
+ ++trn_id;
+ } while (trn_id == 0 || trn_id == (uint16_t)-1);
+
+ (void) mutex_unlock(&trn_id_mtx);
+ return (trn_id);
+}
+
static int
-smb_end_node_challenge(struct name_reply *reply_info)
+smb_end_node_challenge(nbt_name_reply_t *reply_info)
{
int rc;
uint32_t retry;
- unsigned short tid;
+ uint16_t tid;
struct resource_record *answer;
struct name_question question;
- struct addr_entry *addr;
+ addr_entry_t *addr;
struct name_entry *destination;
struct name_packet packet;
struct timespec st;
@@ -176,7 +212,7 @@ smb_end_node_challenge(struct name_reply *reply_info)
addr = &destination->addr_list;
for (retry = 0; retry < UCAST_REQ_RETRY_COUNT; retry++) {
- tid = netbios_name_transcation_id++;
+ tid = smb_netbios_name_trn_id();
packet.name_trn_id = tid;
if (smb_send_name_service_packet(addr, &packet) >= 0) {
if ((rc = smb_netbios_process_response(tid, addr,
@@ -191,21 +227,20 @@ smb_end_node_challenge(struct name_reply *reply_info)
return (0);
}
-
-static struct name_reply *
-smb_name_get_reply(unsigned short tid, uint32_t timeout)
+static nbt_name_reply_t *
+smb_name_get_reply(uint16_t tid, uint32_t timeout)
{
- unsigned short info;
+ uint16_t info;
struct resource_record *answer;
- struct name_reply *reply;
+ nbt_name_reply_t *reply;
uint32_t wait_time, to_save; /* in millisecond */
struct timeval wt;
timestruc_t to;
to_save = timeout;
- reply = (struct name_reply *)malloc(sizeof (struct name_reply));
- if (reply != 0) {
- reply->flags = 0;
+ reply = malloc(sizeof (nbt_name_reply_t));
+ if (reply != NULL) {
+ reply->reply_ready = B_FALSE;
reply->name_trn_id = tid;
(void) mutex_lock(&rq_mtx);
QUEUE_INSERT_TAIL(&reply_queue, reply);
@@ -215,13 +250,13 @@ smb_name_get_reply(unsigned short tid, uint32_t timeout)
(void) gettimeofday(&wt, 0);
wait_time = wt.tv_usec / 1000;
- (void) mutex_lock(&reply_mtx);
to.tv_sec = 0;
to.tv_nsec = timeout * 1000000;
- (void) cond_reltimedwait(&reply_cv, &reply_mtx, &to);
- (void) mutex_unlock(&reply_mtx);
+ (void) mutex_lock(&rq_mtx);
+ (void) cond_reltimedwait(&rq_cv, &rq_mtx, &to);
+ (void) mutex_unlock(&rq_mtx);
- if (reply->flags != 0) {
+ if (reply->reply_ready) {
info = reply->packet->info;
if (PACKET_TYPE(info) == WACK_RESPONSE) {
answer = reply->packet->answer;
@@ -231,7 +266,7 @@ smb_name_get_reply(unsigned short tid, uint32_t timeout)
free(reply->addr);
free(reply->packet);
timeout = to_save + wait_time;
- reply->flags = 0;
+ reply->reply_ready = B_FALSE;
reply->name_trn_id = tid;
(void) mutex_lock(&rq_mtx);
QUEUE_INSERT_TAIL(&reply_queue, reply);
@@ -257,9 +292,9 @@ smb_name_get_reply(unsigned short tid, uint32_t timeout)
}
static void
-smb_reply_ready(struct name_packet *packet, struct addr_entry *addr)
+smb_reply_ready(struct name_packet *packet, addr_entry_t *addr)
{
- struct name_reply *reply;
+ nbt_name_reply_t *reply;
struct resource_record *answer;
(void) mutex_lock(&rq_mtx);
@@ -267,16 +302,12 @@ smb_reply_ready(struct name_packet *packet, struct addr_entry *addr)
reply = reply->forw) {
if (reply->name_trn_id == packet->name_trn_id) {
QUEUE_CLIP(reply);
- (void) mutex_unlock(&rq_mtx);
reply->addr = addr;
reply->packet = packet;
-
- (void) mutex_lock(&reply_mtx);
- reply->flags |= 0x0001; /* reply ready */
- (void) cond_signal(&reply_cv);
- (void) mutex_unlock(&reply_mtx);
-
+ reply->reply_ready = B_TRUE;
+ (void) cond_signal(&rq_cv);
+ (void) mutex_unlock(&rq_mtx);
return;
}
}
@@ -292,12 +323,12 @@ smb_reply_ready(struct name_packet *packet, struct addr_entry *addr)
}
static int
-smb_netbios_process_response(unsigned short tid, struct addr_entry *addr,
+smb_netbios_process_response(uint16_t tid, addr_entry_t *addr,
struct name_packet *packet, uint32_t timeout)
{
int rc = 0;
- unsigned short info;
- struct name_reply *reply;
+ uint16_t info;
+ nbt_name_reply_t *reply;
struct resource_record *answer;
struct name_entry *name;
struct name_entry *entry;
@@ -322,13 +353,16 @@ smb_netbios_process_response(unsigned short tid, struct addr_entry *addr,
*/
addr->attributes &= ~NAME_ATTR_LOCAL;
- addr->refresh_ttl = addr->ttl =
- (answer && answer->ttl) ?
- (answer->ttl >> 1) :
- TO_SECONDS(DEFAULT_TTL);
+ if (answer->ttl)
+ addr->ttl = answer->ttl;
+ else
+ addr->ttl = DEFAULT_TTL;
+ addr->refresh_ttl = TO_SECONDS(addr->ttl);
+ addr->ttl = addr->refresh_ttl;
+
addr = addr->forw;
} while (addr != &answer->name->addr_list);
- smb_netbios_name_dump(answer->name);
+ smb_netbios_name_logf(answer->name);
(void) smb_netbios_cache_insert_list(answer->name);
rc = 1;
} else {
@@ -362,7 +396,7 @@ smb_netbios_process_response(unsigned short tid, struct addr_entry *addr,
*/
entry->attributes |= NAME_ATTR_CONFLICT;
syslog(LOG_DEBUG,
- "NETBIOS Name conflict: %15.15s",
+ "nbns: name conflict: %15.15s",
entry->name);
smb_netbios_cache_unlock_entry(entry);
}
@@ -377,8 +411,8 @@ smb_netbios_process_response(unsigned short tid, struct addr_entry *addr,
* TTL, for this name
*/
question = packet->question;
- ttl = (answer && answer->ttl) ? answer->ttl >> 1
- : TO_SECONDS(DEFAULT_TTL);
+ ttl = (answer && answer->ttl) ? answer->ttl : DEFAULT_TTL;
+ ttl = TO_SECONDS(ttl);
if ((entry = smb_netbios_cache_lookup(question->name)) != 0) {
addr = &entry->addr_list;
do {
@@ -442,13 +476,11 @@ smb_netbios_process_response(unsigned short tid, struct addr_entry *addr,
* -1 -> Hard error, can not possibly encode
* -2 -> Need more memory in buf -- it's too small
*/
-
static int
-smb_name_buf_from_packet(unsigned char *buf,
- int n_buf,
+smb_name_buf_from_packet(unsigned char *buf, int n_buf,
struct name_packet *npb)
{
- struct addr_entry *raddr;
+ addr_entry_t *raddr;
unsigned char *heap = buf;
unsigned char *end_heap = heap + n_buf;
unsigned char *dnptrs[32];
@@ -624,27 +656,15 @@ smb_netbios_getname(char *name, char *buf, char *buf_end)
return (name_len);
}
-
/*
* smb_name_buf_to_packet
*
- * Description:
- * Convert the bits and bytes that came from the wire
- * into a NetBIOS Name Server Packet Block (npb).
- * The "block" is used as a heap.
- *
- * Inputs:
- * char * buf -> Buffer, from the wire
- * int n_buf -> Length of 'buf'
- * name_packet *npb -> Packet block, decode into
- * int n_npb -> Max bytes in 'npb'
+ * Convert the bits and bytes that came from the wire into a NetBIOS
+ * Name Server Packet Block (npb). The "block" is used as a heap.
*
- * Returns:
- * >0 -> Decode (parse) successful, value is byte length of npb
- * -1 -> Hard error, can not possibly decode
- * -2 -> Need more memory in npb -- it's too small
+ * Returns a pointer to a name packet on success. Otherwise, returns
+ * a NULL pointer.
*/
-
static struct name_packet *
smb_name_buf_to_packet(char *buf, int n_buf)
{
@@ -655,16 +675,15 @@ smb_name_buf_to_packet(char *buf, int n_buf)
char name_buf[MAX_NAME_LENGTH];
struct resource_record *nrr = 0;
int rc, i, n, nn, ns;
- unsigned short name_trn_id, info;
- unsigned short qdcount, ancount, nscount, arcount;
- struct addr_entry *next;
+ uint16_t name_trn_id, info;
+ uint16_t qdcount, ancount, nscount, arcount;
+ addr_entry_t *next;
int name_len;
if (n_buf < NAME_HEADER_SIZE) {
/* truncated header */
- syslog(LOG_DEBUG, "SmbNBNS: packet is too short (%d)",
- n_buf);
- return (0);
+ syslog(LOG_DEBUG, "nbns: short packet (%d bytes)", n_buf);
+ return (NULL);
}
name_trn_id = BE_IN16(scan); scan += 2;
@@ -681,11 +700,10 @@ smb_name_buf_to_packet(char *buf, int n_buf)
((unsigned)nscount * (sizeof (struct resource_record) + ns)) +
((unsigned)arcount * (sizeof (struct resource_record) + ns));
- if ((npb = (struct name_packet *)malloc(n)) == 0) {
- return (0);
- }
- bzero(npb, n);
+ if ((npb = malloc(n)) == NULL)
+ return (NULL);
+ bzero(npb, n);
heap = npb->block_data;
npb->name_trn_id = name_trn_id;
npb->info = info;
@@ -748,7 +766,7 @@ smb_name_buf_to_packet(char *buf, int n_buf)
(char *)scan_end);
if (name_len <= 0) {
free(npb);
- return (0);
+ return (NULL);
}
smb_init_name_struct(NETBIOS_EMPTY_NAME, 0, 0, 0, 0, 0, 0,
@@ -758,14 +776,14 @@ smb_name_buf_to_packet(char *buf, int n_buf)
if (rc < 0) {
/* Couldn't decode the question name */
free(npb);
- return (0);
+ return (NULL);
}
scan += name_len;
if (scan + 4 > scan_end) {
/* no room for Question Type(2) and Class(2) fields */
free(npb);
- return (0);
+ return (NULL);
}
npb->question[i].question_type = BE_IN16(scan); scan += 2;
@@ -786,7 +804,7 @@ smb_name_buf_to_packet(char *buf, int n_buf)
(char *)scan_end);
if (name_len <= 0) {
free(npb);
- return (0);
+ return (NULL);
}
rc = name_len;
}
@@ -798,7 +816,7 @@ smb_name_buf_to_packet(char *buf, int n_buf)
* RDLENGTH (2) fields.
*/
free(npb);
- return (0);
+ return (NULL);
}
smb_init_name_struct(NETBIOS_EMPTY_NAME, 0, 0, 0, 0, 0, 0,
@@ -806,7 +824,7 @@ smb_name_buf_to_packet(char *buf, int n_buf)
if ((rc = smb_first_level_name_decode((unsigned char *)name_buf,
nrr[i].name)) < 0) {
free(npb);
- return (0);
+ return (NULL);
}
nrr[i].rr_type = BE_IN16(scan); scan += 2;
@@ -818,7 +836,7 @@ smb_name_buf_to_packet(char *buf, int n_buf)
if ((scan + n) > scan_end) {
/* no room for RDATA */
free(npb);
- return (0);
+ return (NULL);
}
bcopy(scan, heap, n);
@@ -829,13 +847,12 @@ smb_name_buf_to_packet(char *buf, int n_buf)
if (nn == 6)
next = &nrr[i].name->addr_list;
else {
- next = (struct addr_entry *)
- malloc(
- sizeof (struct addr_entry));
+ next = malloc(
+ sizeof (addr_entry_t));
if (next == 0) {
/* not enough memory */
free(npb);
- return (0);
+ return (NULL);
}
QUEUE_INSERT_TAIL(
&nrr[i].name->addr_list,
@@ -849,7 +866,7 @@ smb_name_buf_to_packet(char *buf, int n_buf)
&next->sin.sin_addr.s_addr,
scan + 2, sizeof (uint32_t));
next->sin.sin_port =
- htons(DGM_SRVC_UDP_PORT);
+ htons(IPPORT_NETBIOS_DGM);
nn -= 6;
scan += 6;
}
@@ -863,7 +880,6 @@ smb_name_buf_to_packet(char *buf, int n_buf)
return (npb);
}
-
/*
* smb_send_name_service_packet
*
@@ -879,10 +895,8 @@ smb_name_buf_to_packet(char *buf, int n_buf)
* success -> >0
* failure -> <=0
*/
-
static int
-smb_send_name_service_packet(struct addr_entry *addr,
- struct name_packet *packet)
+smb_send_name_service_packet(addr_entry_t *addr, struct name_packet *packet)
{
unsigned char buf[MAX_DATAGRAM_LENGTH];
int len;
@@ -897,293 +911,6 @@ smb_send_name_service_packet(struct addr_entry *addr,
}
/*
- * 4.2.1.1. HEADER
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID | OPCODE | NM_FLAGS | RCODE |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | QDCOUNT | ANCOUNT |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NSCOUNT | ARCOUNT |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * Field Description
- *
- * NAME_TRN_ID Transaction ID for Name Service Transaction.
- * Requester places a unique value for each active
- * transaction. Responder puts NAME_TRN_ID value
- * from request packet in response packet.
- *
- * OPCODE Packet type code, see table below.
- *
- * NM_FLAGS Flags for operation, see table below.
- *
- * RCODE Result codes of request. Table of RCODE values
- * for each response packet below.
- *
- * QDCOUNT Unsigned 16 bit integer specifying the number of
- * entries in the question section of a Name
- *
- * Service packet. Always zero (0) for responses.
- * Must be non-zero for all NetBIOS Name requests.
- *
- * ANCOUNT Unsigned 16 bit integer specifying the number of
- * resource records in the answer section of a Name
- * Service packet.
- *
- * NSCOUNT Unsigned 16 bit integer specifying the number of
- * resource records in the authority section of a
- * Name Service packet.
- *
- * ARCOUNT Unsigned 16 bit integer specifying the number of
- * resource records in the additional records
- * section of a Name Service packet.
- *
- * The OPCODE field is defined as:
- *
- * 0 1 2 3 4
- * +---+---+---+---+---+
- * | R | OPCODE |
- * +---+---+---+---+---+
- *
- * Symbol Bit(s) Description
- *
- * OPCODE 1-4 Operation specifier:
- * 0 = query
- * 5 = registration
- * 6 = release
- * 7 = WACK
- * 8 = refresh
- *
- * R 0 RESPONSE flag:
- * if bit == 0 then request packet
- * if bit == 1 then response packet.
- */
-
-
-/*
- * The NM_FLAGS field is defined as:
- *
- *
- * 0 1 2 3 4 5 6
- * +---+---+---+---+---+---+---+
- * |AA |TC |RD |RA | 0 | 0 | B |
- * +---+---+---+---+---+---+---+
- *
- * Symbol Bit(s) Description
- *
- * B 6 Broadcast Flag.
- * = 1: packet was broadcast or multicast
- * = 0: unicast
- *
- * RA 3 Recursion Available Flag.
- *
- * Only valid in responses from a NetBIOS Name
- * Server -- must be zero in all other
- * responses.
- *
- * If one (1) then the NAME supports recursive
- * query, registration, and release.
- *
- * If zero (0) then the end-node must iterate
- * for query and challenge for registration.
- *
- * RD 2 Recursion Desired Flag.
- *
- * May only be set on a request to a NetBIOS
- * Name Server.
- *
- * The NAME will copy its state into the
- * response packet.
- *
- * If one (1) the NAME will iterate on the
- * query, registration, or release.
- *
- * TC 1 Truncation Flag.
- *
- * Set if this message was truncated because the
- * datagram carrying it would be greater than
- * 576 bytes in length. Use TCP to get the
- * information from the NetBIOS Name Server.
- *
- * AA 0 Authoritative Answer flag.
- *
- * Must be zero (0) if R flag of OPCODE is zero
- * (0).
- *
- * If R flag is one (1) then if AA is one (1)
- * then the node responding is an authority for
- * the domain name.
- *
- * End nodes responding to queries always set
- * this bit in responses.
- *
- */
-
-/*
- * 4.2.1.2. QUESTION SECTION
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / QUESTION_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | QUESTION_TYPE | QUESTION_CLASS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * Field Description
- *
- * QUESTION_NAME The compressed name representation of the
- * NetBIOS name for the request.
- *
- * QUESTION_TYPE The type of request. The values for this field
- * are specified for each request.
- *
- * QUESTION_CLASS The class of the request. The values for this
- * field are specified for each request.
- *
- * QUESTION_TYPE is defined as:
- *
- * Symbol Value Description:
- *
- * NB 0x0020 NetBIOS general Name Service Resource Record
- * NBSTAT 0x0021 NetBIOS NODE STATUS Resource Record (See NODE
- * STATUS REQUEST)
- *
- * QUESTION_CLASS is defined as:
- *
- * Symbol Value Description:
- *
- * IN 0x0001 Internet class
- */
-
-#define QUESTION_TYPE_NETBIOS_GENERAL 0x20
-#define QUESTION_TYPE_NETBIOS_STATUS 0x21
-
-#define QUESTION_CLASS_INTERNET 0x0001
-
-/*
- *
- * 4.2.1.3. RESOURCE RECORD
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | RR_TYPE | RR_CLASS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | TTL |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | RDLENGTH | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- * / /
- * / RDATA /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * Field Description
- *
- * RR_NAME The compressed name representation of the
- * NetBIOS name corresponding to this resource
- * record.
- *
- * RR_TYPE Resource record type code
- *
- * RR_CLASS Resource record class code
- *
- * TTL The Time To Live of a the resource record's
- * name.
- *
- * RDLENGTH Unsigned 16 bit integer that specifies the
- * number of bytes in the RDATA field.
- *
- * RDATA RR_CLASS and RR_TYPE dependent field. Contains
- * the resource information for the NetBIOS name.
- *
- * RESOURCE RECORD RR_TYPE field definitions:
- *
- * Symbol Value Description:
- *
- * A 0x0001 IP address Resource Record (See REDIRECT NAME
- * QUERY RESPONSE)
- * NS 0x0002 Name Server Resource Record (See REDIRECT
- * NAME QUERY RESPONSE)
- * NULL 0x000A NULL Resource Record (See WAIT FOR
- * ACKNOWLEDGEMENT RESPONSE)
- * NB 0x0020 NetBIOS general Name Service Resource Record
- * (See NB_FLAGS and NB_ADDRESS, below)
- * NBSTAT 0x0021 NetBIOS NODE STATUS Resource Record (See NODE
- * STATUS RESPONSE)
- */
-
-#define RR_TYPE_IP_ADDRESS_RESOURCE 0x0001
-#define RR_TYPE_NAME_SERVER_RESOURCE 0x0002
-#define RR_TYPE_NULL_RESOURCE 0x000A
-#define RR_TYPE_NETBIOS_RESOURCE 0x0020
-#define RR_TYPE_NETBIOS_STATUS 0x0021
-
-/*
- *
- * RESOURCE RECORD RR_CLASS field definitions:
- *
- * Symbol Value Description:
- *
- * IN 0x0001 Internet class
- */
-#define RR_CLASS_INTERNET_CLASS 0x0001
-
-/*
- *
- * NB_FLAGS field of the RESOURCE RECORD RDATA field for RR_TYPE of
- * "NB":
- *
- * 1 1 1 1 1 1
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- * | G | ONT | RESERVED |
- * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- *
- * Symbol Bit(s) Description:
- *
- * RESERVED 3-15 Reserved for future use. Must be zero (0).
- * ONT 1,2 Owner Node Type:
- * 00 = B node
- * 01 = P node
- * 10 = M node
- * 11 = Reserved for future use
- * For registration requests this is the
- * claimant's type.
- * For responses this is the actual owner's
- * type.
- *
- * G 0 Group Name Flag.
- * If one (1) then the RR_NAME is a GROUP
- * NetBIOS name.
- * If zero (0) then the RR_NAME is a UNIQUE
- * NetBIOS name.
- *
- * The NB_ADDRESS field of the RESOURCE RECORD RDATA field for
- * RR_TYPE of "NB" is the IP address of the name's owner.
- *
- */
-#define RR_FLAGS_NB_ONT_MASK 0x6000
-#define RR_FLAGS_NB_ONT_B_NODE 0x0000
-#define RR_FLAGS_NB_ONT_P_NODE 0x2000
-#define RR_FLAGS_NB_ONT_M_NODE 0x4000
-#define RR_FLAGS_NB_ONT_RESERVED 0x6000
-
-#define RR_FLAGS_NB_GROUP_NAME 0x8000
-
-/*
* smb_netbios_send_rcv
*
* This function sends the given NetBIOS packet to the given
@@ -1195,12 +922,11 @@ smb_send_name_service_packet(struct addr_entry *addr,
* 1 Got reply
*/
static int
-smb_netbios_send_rcv(int bcast, struct addr_entry *destination,
- struct name_packet *packet,
- uint32_t retries, uint32_t timeout)
+smb_netbios_send_rcv(int bcast, addr_entry_t *destination,
+ struct name_packet *packet, uint32_t retries, uint32_t timeout)
{
uint32_t retry;
- unsigned short tid;
+ uint16_t tid;
struct timespec st;
int rc;
@@ -1208,7 +934,7 @@ smb_netbios_send_rcv(int bcast, struct addr_entry *destination,
if ((destination->flags & ADDR_FLAG_VALID) == 0)
return (0);
- tid = netbios_name_transcation_id++;
+ tid = smb_netbios_name_trn_id();
packet->name_trn_id = tid;
if (smb_send_name_service_packet(destination, packet) >= 0) {
rc = smb_netbios_process_response(tid, destination,
@@ -1230,45 +956,7 @@ smb_netbios_send_rcv(int bcast, struct addr_entry *destination,
}
/*
- * 4.2.2. NAME REGISTRATION REQUEST
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |0| 0x5 |0|0|1|0|0 0|B| 0x0 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0001 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0001 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / QUESTION_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | TTL |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0006 | NB_FLAGS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB_ADDRESS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * Since the RR_NAME is the same name as the QUESTION_NAME, the
- * RR_NAME representation must use pointers to the QUESTION_NAME
- * name's labels to guarantee the length of the datagram is less
- * than the maximum 576 bytes. See section above on name formats
- * and also page 31 and 32 of RFC 883, Domain Names - Implementation
- * and Specification, for a complete description of compressed name
- * label pointers.
+ * RFC 1002 4.2.2. NAME REGISTRATION REQUEST
*/
static int
smb_send_name_registration_request(int bcast, struct name_question *question,
@@ -1277,15 +965,15 @@ smb_send_name_registration_request(int bcast, struct name_question *question,
int gotreply = 0;
uint32_t retries;
uint32_t timeout;
- struct addr_entry *destination;
+ addr_entry_t *destination;
struct name_packet packet;
unsigned char type;
int i, addr_num, rc;
type = question->name->name[15];
- if ((type != 0x00) && (type != 0x20)) {
- syslog(LOG_ERR, "netbios: error trying to register"
- " non-local name");
+ if ((type != NBT_WKSTA) && (type != NBT_SERVER)) {
+ syslog(LOG_DEBUG, "nbns: name registration bad type (0x%02x)",
+ type);
smb_netbios_name_logf(question->name);
question->name->attributes &= ~NAME_ATTR_LOCAL;
return (-1);
@@ -1340,38 +1028,7 @@ smb_send_name_registration_request(int bcast, struct name_question *question,
}
/*
- *
- * 4.2.4. NAME REFRESH REQUEST
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |0| 0x8 |0|0|0|0|0 0|B| 0x0 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0001 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0001 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / QUESTION_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | TTL |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0006 | NB_FLAGS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB_ADDRESS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * RFC 1002 4.2.4. NAME REFRESH REQUEST
*/
/*ARGSUSED*/
static int
@@ -1382,15 +1039,15 @@ smb_send_name_refresh_request(int bcast, struct name_question *question,
int gotreply = 0;
uint32_t retries;
uint32_t timeout;
- struct addr_entry *addr;
- struct addr_entry *destination;
+ addr_entry_t *addr;
+ addr_entry_t *destination;
struct name_packet packet;
unsigned char type;
int i, addr_num, q_addrs = 0;
type = question->name->name[15];
- if ((type != 0x00) && (type != 0x20)) {
- syslog(LOG_ERR, "attempt to refresh non-local name");
+ if ((type != NBT_WKSTA) && (type != NBT_SERVER)) {
+ syslog(LOG_DEBUG, "nbns: name refresh bad type (0x%02x)", type);
smb_netbios_name_logf(question->name);
question->name->attributes &= ~NAME_ATTR_LOCAL;
return (-1);
@@ -1471,78 +1128,12 @@ special_process:
}
/*
- * 4.2.5. POSITIVE NAME REGISTRATION RESPONSE
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |1| 0x5 |1|0|1|1|0 0|0| 0x0 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0001 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | TTL |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0006 | NB_FLAGS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB_ADDRESS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- *
- *
- * 4.2.6. NEGATIVE NAME REGISTRATION RESPONSE
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |1| 0x5 |1|0|1|1|0 0|0| RCODE |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0001 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | TTL |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0006 | NB_FLAGS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB_ADDRESS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * RCODE field values:
- *
- * Symbol Value Description:
- *
- * FMT_ERR 0x1 Format Error. Request was invalidly
- * formatted.
- * SRV_ERR 0x2 Server failure. Problem with NAME, cannot
- * process name.
- * IMP_ERR 0x4 Unsupported request error. Allowable only
- * for challenging NAME when gets an Update type
- * registration request.
- * RFS_ERR 0x5 Refused error. For policy reasons server
- * will not register this name from this host.
- * ACT_ERR 0x6 Active error. Name is owned by another node.
- * CFT_ERR 0x7 Name in conflict error. A UNIQUE name is
- * owned by more than one node.
+ * RFC 1002 4.2.5. POSITIVE NAME REGISTRATION RESPONSE
+ * RFC 1002 4.2.6. NEGATIVE NAME REGISTRATION RESPONSE
*/
static int
-smb_send_name_registration_response(struct addr_entry *addr,
- struct name_packet *original_packet, unsigned short rcode)
+smb_send_name_registration_response(addr_entry_t *addr,
+ struct name_packet *original_packet, uint16_t rcode)
{
struct name_packet packet;
struct resource_record answer;
@@ -1573,43 +1164,7 @@ smb_send_name_registration_response(struct addr_entry *addr,
}
/*
- * 4.2.9. NAME RELEASE REQUEST & DEMAND
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |0| 0x6 |0|0|0|0|0 0|B| 0x0 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0001 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0001 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / QUESTION_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x00000000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0006 | NB_FLAGS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB_ADDRESS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * Since the RR_NAME is the same name as the QUESTION_NAME, the
- * RR_NAME representation must use label string pointers to the
- * QUESTION_NAME labels to guarantee the length of the datagram is
- * less than the maximum 576 bytes. This is the same condition as
- * with the NAME REGISTRATION REQUEST.
+ * RFC 1002 4.2.9. NAME RELEASE REQUEST & DEMAND
*/
static int
smb_send_name_release_request_and_demand(int bcast,
@@ -1620,7 +1175,7 @@ smb_send_name_release_request_and_demand(int bcast,
int addr_num;
uint32_t retries;
uint32_t timeout;
- struct addr_entry *destination;
+ addr_entry_t *destination;
struct name_packet packet;
if (bcast == BROADCAST) {
@@ -1661,81 +1216,13 @@ smb_send_name_release_request_and_demand(int bcast,
}
/*
- * 4.2.10. POSITIVE NAME RELEASE RESPONSE
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |1| 0x6 |1|0|0|0|0 0|0| 0x0 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0001 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | TTL |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0006 | NB_FLAGS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB_ADDRESS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- *
- * 4.2.11. NEGATIVE NAME RELEASE RESPONSE
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |1| 0x6 |1|0|0|0|0 0|0| RCODE |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0001 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | TTL |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0006 | NB_FLAGS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB_ADDRESS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * RCODE field values:
- *
- * Symbol Value Description:
- *
- * FMT_ERR 0x1 Format Error. Request was invalidly
- * formatted.
- *
- * SRV_ERR 0x2 Server failure. Problem with NAME, cannot
- * process name.
- *
- * RFS_ERR 0x5 Refused error. For policy reasons server
- * will not release this name from this host.
- *
- * ACT_ERR 0x6 Active error. Name is owned by another node.
- * Only that node may release it. A NetBIOS
- * Name Server can optionally allow a node to
- * release a name it does not own. This would
- * facilitate detection of inactive names for
- * nodes that went down silently.
+ * RFC 1002 4.2.10. POSITIVE NAME RELEASE RESPONSE
+ * RFC 1002 4.2.11. NEGATIVE NAME RELEASE RESPONSE
*/
static int
/* LINTED - E_STATIC_UNUSED */
-smb_send_name_release_response(struct addr_entry *addr,
- struct name_packet *original_packet, unsigned short rcode)
+smb_send_name_release_response(addr_entry_t *addr,
+ struct name_packet *original_packet, uint16_t rcode)
{
struct name_packet packet;
struct resource_record answer;
@@ -1765,25 +1252,7 @@ smb_send_name_release_response(struct addr_entry *addr,
}
/*
- *
- * 4.2.12. NAME QUERY REQUEST
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |0| 0x0 |0|0|1|0|0 0|B| 0x0 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0001 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / QUESTION_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * RFC 1002 4.2.12. NAME QUERY REQUEST
*/
static int
smb_send_name_query_request(int bcast, struct name_question *question)
@@ -1791,8 +1260,8 @@ smb_send_name_query_request(int bcast, struct name_question *question)
int rc = 0;
uint32_t retry, retries;
uint32_t timeout;
- unsigned short tid;
- struct addr_entry *destination;
+ uint16_t tid;
+ addr_entry_t *destination;
struct name_packet packet;
int i, addr_num;
struct timespec st;
@@ -1825,9 +1294,9 @@ smb_send_name_query_request(int bcast, struct name_question *question)
for (i = 0; i < addr_num; i++) {
for (retry = 0; retry < retries; retry++) {
- if ((destination->flags & ADDR_FLAG_VALID) == 0)
+ if ((destination[i].flags & ADDR_FLAG_VALID) == 0)
break;
- tid = netbios_name_transcation_id++;
+ tid = smb_netbios_name_trn_id();
packet.name_trn_id = tid;
if (smb_send_name_service_packet(&destination[i],
@@ -1846,101 +1315,19 @@ smb_send_name_query_request(int bcast, struct name_question *question)
return (rc);
}
-
/*
- *
- * 4.2.13. POSITIVE NAME QUERY RESPONSE
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |1| 0x0 |1|T|1|?|0 0|0| 0x0 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0001 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB (0x0020) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | TTL |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | RDLENGTH | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- * | |
- * / ADDR_ENTRY ARRAY /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * The ADDR_ENTRY ARRAY a sequence of zero or more ADDR_ENTRY
- * records. Each ADDR_ENTRY record represents an owner of a name.
- * For group names there may be multiple entries. However, the list
- * may be incomplete due to packet size limitations. Bit 22, "T",
- * will be set to indicate truncated data.
- *
- * Each ADDR_ENTRY has the following format:
- *
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB_FLAGS | NB_ADDRESS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NB_ADDRESS (continued) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- *
- *
- * 4.2.14. NEGATIVE NAME QUERY RESPONSE
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |1| 0x0 |1|0|1|?|0 0|0| RCODE |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * / /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NULL (0x000A) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x00000000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * RCODE field values:
- *
- * Symbol Value Description
- *
- * FMT_ERR 0x1 Format Error. Request was invalidly
- * formatted.
- * SRV_ERR 0x2 Server failure. Problem with NAME, cannot
- * process name.
- * NAM_ERR 0x3 Name Error. The name requested does not
- * exist.
- * IMP_ERR 0x4 Unsupported request error. Allowable only
- * for challenging NAME when gets an Update type
- * registration request.
- * RFS_ERR 0x5 Refused error. For policy reasons server
- * will not register this name from this host.
+ * RFC 1002 4.2.13. POSITIVE NAME QUERY RESPONSE
+ * RFC 1002 4.2.14. NEGATIVE NAME QUERY RESPONSE
*/
static int
-smb_send_name_query_response(struct addr_entry *addr,
+smb_send_name_query_response(addr_entry_t *addr,
struct name_packet *original_packet, struct name_entry *entry,
- unsigned short rcode)
+ uint16_t rcode)
{
- struct addr_entry *raddr;
+ addr_entry_t *raddr;
struct name_packet packet;
struct resource_record answer;
- unsigned short attr;
+ uint16_t attr;
unsigned char data[MAX_DATAGRAM_LENGTH];
unsigned char *scan = data;
uint32_t ret_addr;
@@ -1989,141 +1376,10 @@ smb_send_name_query_response(struct addr_entry *addr,
}
/*
- * 4.2.18. NODE STATUS RESPONSE
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_TRN_ID |1| 0x0 |1|0|0|0|0 0|0| 0x0 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0001 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x0000 | 0x0000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * / RR_NAME /
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NBSTAT (0x0021) | IN (0x0001) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | 0x00000000 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | RDLENGTH | NUM_NAMES | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
- * | |
- * + +
- * / NODE_NAME ARRAY /
- * + +
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * + +
- * / STATISTICS /
- * + +
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * The NODE_NAME ARRAY is an array of zero or more NUM_NAMES entries
- * of NODE_NAME records. Each NODE_NAME entry represents an active
- * name in the same NetBIOS scope as the requesting name in the
- * local name table of the responder. RR_NAME is the requesting
- * name.
- *
- * NODE_NAME Entry:
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | |
- * +--- ---+
- * | |
- * +--- NETBIOS FORMAT NAME ---+
- * | |
- * +--- ---+
- * | |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NAME_FLAGS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- *
- * The NAME_FLAGS field:
- *
- * 1 1 1 1 1 1
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- * | G | ONT |DRG|CNF|ACT|PRM| RESERVED |
- * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- *
- * The NAME_FLAGS field is defined as:
- *
- * Symbol Bit(s) Description:
- *
- * RESERVED 7-15 Reserved for future use. Must be zero (0).
- * PRM 6 Permanent Name Flag. If one (1) then entry
- * is for the permanent node name. Flag is zero
- * (0) for all other names.
- * ACT 5 Active Name Flag. All entries have this flag
- * set to one (1).
- * CNF 4 Conflict Flag. If one (1) then name on this
- * node is in conflict.
- * DRG 3 Deregister Flag. If one (1) then this name
- * is in the process of being deleted.
- * ONT 1,2 Owner Node Type:
- * 00 = B node
- * 01 = P node
- * 10 = M node
- * 11 = Reserved for future use
- * G 0 Group Name Flag.
- * If one (1) then the name is a GROUP NetBIOS
- * name.
- * If zero (0) then it is a UNIQUE NetBIOS name.
- */
-#define NAME_FLAGS_PERMANENT_NAME 0x0200
-#define NAME_FLAGS_ACTIVE_NAME 0x0400
-#define NAME_FLAGS_CONFLICT 0x0800
-#define NAME_FLAGS_DEREGISTER 0x1000
-#define NAME_FLAGS_ONT_MASK 0x6000
-#define NAME_FLAGS_ONT_B_NODE 0x0000
-#define NAME_FLAGS_ONT_P_NODE 0x2000
-#define NAME_FLAGS_ONT_M_NODE 0x4000
-#define NAME_FLAGS_ONT_RESERVED 0x6000
-#define NAME_FLAGS_GROUP_NAME 0x8000
-
-
-/*
- * STATISTICS Field of the NODE STATUS RESPONSE:
- *
- * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | UNIT_ID (Unique unit ID) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | UNIT_ID,continued | JUMPERS | TEST_RESULT |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | VERSION_NUMBER | PERIOD_OF_STATISTICS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NUMBER_OF_CRCs | NUMBER_ALIGNMENT_ERRORS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NUMBER_OF_COLLISIONS | NUMBER_SEND_ABORTS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NUMBER_GOOD_SENDS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NUMBER_GOOD_RECEIVES |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NUMBER_RETRANSMITS | NUMBER_NO_RESOURCE_CONDITIONS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | NUMBER_FREE_COMMAND_BLOCKS | TOTAL_NUMBER_COMMAND_BLOCKS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * |MAX_TOTAL_NUMBER_COMMAND_BLOCKS| NUMBER_PENDING_SESSIONS |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | MAX_NUMBER_PENDING_SESSIONS | MAX_TOTAL_SESSIONS_POSSIBLE |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | SESSION_DATA_PACKET_SIZE |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * RFC 1002 4.2.18. NODE STATUS RESPONSE
*/
-#define MAX_NETBIOS_REPLY_DATA_SIZE 500
-
static int
-smb_send_node_status_response(struct addr_entry *addr,
+smb_send_node_status_response(addr_entry_t *addr,
struct name_packet *original_packet)
{
uint32_t net_ipaddr;
@@ -2265,152 +1521,14 @@ smb_send_node_status_response(struct addr_entry *addr,
return (smb_send_name_service_packet(addr, &packet));
}
-/*
- *
- * 5.1. NAME SERVICE PROTOCOLS
- *
- * A REQUEST packet is always sent to the well known UDP port -
- * NAME_SERVICE_UDP_PORT. The destination address is normally
- * either the IP broadcast address or the address of the NAME - the
- * address of the NAME server it set up at initialization time. In
- * rare cases, a request packet will be sent to an end node, e.g. a
- * NAME QUERY REQUEST sent to "challenge" a node.
- *
- * A RESPONSE packet is always sent to the source UDP port and
- * source IP address of the request packet.
- *
- * A DEMAND packet must always be sent to the well known UDP port -
- * NAME_SERVICE_UDP_PORT. There is no restriction on the target IP
- * address.
- *
- * Terms used in this section:
- *
- * tid - Transaction ID. This is a value composed from
- * the requestor's IP address and a unique 16 bit
- * value generated by the originator of the
- * transaction.
- */
-
-
-/*
- *
- * 5.1.1. B-NODE ACTIVITY
- *
- * 5.1.1.1. B-NODE ADD NAME
- *
- * PROCEDURE add_name(name)
- *
- * (*
- * * Host initiated processing for a B node
- * *)
- * BEGIN
- *
- * REPEAT
- *
- * (* build name service packet *)
- *
- * ONT = B_NODE; (* broadcast node *)
- * G = UNIQUE; (* unique name *)
- * TTL = 0;
- *
- * broadcast NAME REGISTRATION REQUEST packet;
- *
- * (*
- * * remote node(s) will send response packet
- * * if applicable
- * *)
- * pause(BCAST_REQ_RETRY_TIMEOUT);
- *
- * UNTIL response packet is received or
- * retransmit count has been exceeded
- *
- * IF no response packet was received THEN
- * BEGIN (* no response *)
- * (*
- * * Build packet
- * *)
- *
- * ONT = B_NODE; (* broadcast node *)
- * G = UNIQUE; (* unique name *)
- * TTL = 0;
- *
- * (*
- * * Let other nodes known you have the name
- * *)
- *
- * broadcast NAME UPDATE REQUEST packet;
- * (* name can be added to local name table *)
- * return success;
- * END (* no response *)
- * ELSE
- * BEGIN (* got response *)
- *
- * (*
- * * Match return transaction id
- * * against tid sent in request
- * *)
- *
- * IF NOT response tid = request tid THEN
- * BEGIN
- * ignore response packet;
- * END
- * ELSE
- * CASE packet type OF
- *
- * NEGATIVE NAME REGISTRATION RESPONSE:
- *
- * return failure; (* name cannot be added *)
- *
- * POSITIVE NAME REGISTRATION RESPONSE:
- * END-NODE CHALLENGE NAME REGISTRATION RESPONSE:
- *
- * (*
- * * B nodes should normally not get this
- * * response.
- * *)
- *
- * ignore packet;
- * END (* case *);
- * END (* got response *)
- * END (* procedure *)
- *
- *
- *
- * 5.1.1.2. B-NODE ADD_GROUP NAME
- *
- * PROCEDURE add_group_name(name)
- *
- * (*
- * * Host initiated processing for a B node
- * *)
- *
- * BEGIN
- * (*
- * * same as for a unique name with the
- * * exception that the group bit (G) must
- * * be set in the request packets.
- * *)
- *
- * ...
- * G = GROUP;
- * ...
- * ...
- *
- * (*
- * * broadcast request ...
- * *)
- *
- *
- * END
- */
static int
smb_name_Bnode_add_name(struct name_entry *name)
{
struct name_question question;
struct resource_record additional;
unsigned char data[8];
- unsigned short attr;
- struct addr_entry *addr;
+ uint16_t attr;
+ addr_entry_t *addr;
int rc = 0;
addr = &name->addr_list;
@@ -2447,68 +1565,6 @@ smb_name_Bnode_add_name(struct name_entry *name)
return (rc);
}
-/*
- * 5.1.1.3. B-NODE FIND_NAME
- *
- * PROCEDURE find_name(name)
- *
- * (*
- * * Host initiated processing for a B node
- * *)
- *
- * BEGIN
- *
- * REPEAT
- * (*
- * * build packet
- * *)
- * ONT = B;
- * TTL = 0;
- * G = DONT CARE;
- * raddr = raddr->forw;
- *
- * broadcast NAME QUERY REQUEST packet;
- * (*
- * * a node might send response packet
- * *)
- *
- * pause(BCAST_REQ_RETRY_TIMEOUT);
- * UNTIL response packet received OR
- * max transmit threshold exceeded
- *
- * IF no response packet received THEN
- * return failure;
- * ELSE
- * IF NOT response tid = request tid THEN
- * ignore packet;
- * ELSE
- * CASE packet type OF
- * POSITIVE NAME QUERY RESPONSE:
- * (*
- * * Start a timer to detect conflict.
- * *
- * * Be prepared to detect conflict if
- * * any more response packets are received.
- * *
- * *)
- *
- * save response as authoritative response;
- * start_timer(CONFLICT_TIMER);
- * return success;
- *
- * NEGATIVE NAME QUERY RESPONSE:
- * REDIRECT NAME QUERY RESPONSE:
- *
- * (*
- * * B Node should normally not get either
- * * response.
- * *)
- *
- * ignore response packet;
- *
- * END (* case *)
- * END (* procedure *)
- */
static int
smb_name_Bnode_find_name(struct name_entry *name)
{
@@ -2521,42 +1577,14 @@ smb_name_Bnode_find_name(struct name_entry *name)
return (smb_send_name_query_request(BROADCAST, &question));
}
-/*
- * 5.1.1.4. B NODE NAME RELEASE
- *
- * PROCEDURE delete_name (name)
- * BEGIN
- *
- * REPEAT
- *
- * (*
- * * build packet
- * *)
- * ...
- *
- * (*
- * * send request
- * *)
- *
- * broadcast NAME RELEASE REQUEST packet;
- *
- * (*
- * * no response packet expected
- * *)
- *
- * pause(BCAST_REQ_RETRY_TIMEOUT);
- *
- * UNTIL retransmit count has been exceeded
- * END (* procedure *)
- */
static int
smb_name_Bnode_delete_name(struct name_entry *name)
{
struct name_question question;
struct resource_record additional;
- struct addr_entry *raddr;
- unsigned char data[MAX_DATAGRAM_LENGTH];
- unsigned char *scan = data;
+ addr_entry_t *raddr;
+ unsigned char data[MAX_DATAGRAM_LENGTH];
+ unsigned char *scan = data;
uint32_t attr;
uint32_t ret_addr;
@@ -2591,212 +1619,14 @@ smb_name_Bnode_delete_name(struct name_entry *name)
&question, &additional));
}
-/*
- *
- * 5.1.2. P-NODE ACTIVITY
- *
- * All packets sent or received by P nodes are unicast UDP packets.
- * A P node sends name service requests to the NAME node that is
- * specified in the P-node configuration.
- *
- * 5.1.2.1. P-NODE ADD_NAME
- *
- * PROCEDURE add_name(name)
- *
- * (*
- * * Host initiated processing for a P node
- * *)
- *
- * BEGIN
- *
- * REPEAT
- * (*
- * * build packet
- * *)
- *
- * ONT = P;
- * G = UNIQUE;
- * ...
- *
- * (*
- * * send request
- * *)
- *
- * unicast NAME REGISTRATION REQUEST packet;
- *
- * (*
- * * NAME will send response packet
- * *)
- *
- * IF receive a WACK RESPONSE THEN
- * pause(time from TTL field of response);
- * ELSE
- * pause(UCAST_REQ_RETRY_TIMEOUT);
- * UNTIL response packet is received OR
- * retransmit count has been exceeded
- *
- * IF no response packet was received THEN
- * BEGIN (* no response *)
- * (*
- * * NAME is down. Cannot claim name.
- * *)
- *
- * return failure; (* name cannot be claimed *)
- * END (* no response *)
- * ELSE
- * BEGIN (* response *)
- * IF NOT response tid = request tid THEN
- * BEGIN
- * (* Packet may belong to another transaction *)
- * ignore response packet;
- * END
- * ELSE
- * CASE packet type OF
- *
- * POSITIVE NAME REGISTRATION RESPONSE:
- *
- * (*
- * * name can be added
- * *)
- *
- * adjust refresh timeout value, TTL, for this name;
- * return success; (* name can be added *)
- *
- * NEGATIVE NAME REGISTRATION RESPONSE:
- * return failure; (* name cannot be added *)
- *
- * END-NODE CHALLENGE REGISTRATION REQUEST:
- * BEGIN (* end node challenge *)
- *
- * (*
- * * The response packet has in it the
- * * address of the presumed owner of the
- * * name. Challenge that owner.
- * * If owner either does not
- * * respond or indicates that he no longer
- * * owns the name, claim the name.
- * * Otherwise, the name cannot be claimed.
- * *
- * *)
- *
- * REPEAT
- * (*
- * * build packet
- * *)
- * ...
- *
- * unicast NAME QUERY REQUEST packet to the
- * address contained in the END NODE
- * CHALLENGE RESPONSE packet;
- *
- * (*
- * * remote node may send response packet
- * *)
- *
- * pause(UCAST_REQ_RETRY_TIMEOUT);
- *
- * UNTIL response packet is received or
- * retransmit count has been exceeded
- * IF no response packet is received OR
- * NEGATIVE NAME QUERY RESPONSE packet
- * received THEN
- * BEGIN (* update *)
- *
- * (*
- * * name can be claimed
- * *)
- *
- * REPEAT
- *
- * (*
- * * build packet
- * *)
- * ...
- *
- * unicast NAME UPDATE REQUEST to NAME;
- *
- * (*
- * * NAME node will send response packet
- * *)
- *
- * IF receive a WACK RESPONSE THEN
- * pause(time from TTL field of response);
- * ELSE
- * pause(UCAST_REQ_RETRY_TIMEOUT);
- * UNTIL response packet is received or
- * retransmit count has been exceeded
- * IF no response packet received THEN
- * BEGIN (* no response *)
- *
- * (*
- * * name could not be claimed
- * *)
- *
- * return failure;
- * END (* no response *)
- * ELSE
- * CASE packet type OF
- * POSITIVE NAME REGISTRATION RESPONSE:
- * (*
- * * add name
- * *)
- * return success;
- * NEGATIVE NAME REGISTRATION RESPONSE:
- *
- * (*
- * * you lose ...
- * *)
- * return failure;
- * END (* case *)
- * END (* update *)
- * ELSE
- *
- * (*
- * * received a positive response to the "challenge"
- * * Remote node still has name
- * *)
- *
- * return failure;
- * END (* end node challenge *)
- * END (* response *)
- * END (* procedure *)
- *
- *
- * 5.1.2.2. P-NODE ADD GROUP NAME
- *
- * PROCEDURE add_group_name(name)
- *
- * (*
- * * Host initiated processing for a P node
- * *)
- *
- * BEGIN
- * (*
- * * same as for a unique name, except that the
- * * request packet must indicate that a
- * * group name claim is being made.
- * *)
- *
- * ...
- * G = GROUP;
- * ...
- *
- * (*
- * * send packet
- * *)
- * ...
- *
- *
- * END
- */
static int
smb_name_Pnode_add_name(struct name_entry *name)
{
struct name_question question;
struct resource_record additional;
unsigned char data[8];
- unsigned short attr;
- struct addr_entry *addr;
+ uint16_t attr;
+ addr_entry_t *addr;
int rc = 0;
/* build packet */
@@ -2835,8 +1665,8 @@ smb_name_Pnode_refresh_name(struct name_entry *name)
struct name_question question;
struct resource_record additional;
unsigned char data[8];
- unsigned short attr;
- struct addr_entry *addr;
+ uint16_t attr;
+ addr_entry_t *addr;
int rc = 0;
/* build packet */
@@ -2868,63 +1698,6 @@ smb_name_Pnode_refresh_name(struct name_entry *name)
return (rc);
}
-/*
- * 5.1.2.3. P-NODE FIND NAME
- *
- * PROCEDURE find_name(name)
- *
- * (*
- * * Host initiated processing for a P node
- * *)
- *
- * BEGIN
- * REPEAT
- * (*
- * * build packet
- * *)
- *
- * ONT = P;
- * G = DONT CARE;
- *
- * unicast NAME QUERY REQUEST packet;
- *
- * (*
- * * a NAME node might send response packet
- * *)
- *
- * IF receive a WACK RESPONSE THEN
- * pause(time from TTL field of response);
- * ELSE
- * pause(UCAST_REQ_RETRY_TIMEOUT);
- * UNTIL response packet received OR
- * max transmit threshold exceeded
- *
- * IF no response packet received THEN
- * return failure;
- * ELSE
- * IF NOT response tid = request tid THEN
- * ignore packet;
- * ELSE
- * CASE packet type OF
- * POSITIVE NAME QUERY RESPONSE:
- * return success;
- *
- * REDIRECT NAME QUERY RESPONSE:
- *
- * (*
- * * NAME node wants this end node
- * * to use some other NAME node
- * * to resolve the query.
- * *)
- *
- * repeat query with NAME address
- * in the response packet;
- * NEGATIVE NAME QUERY RESPONSE:
- * return failure;
- *
- * END (* case *)
- * END (* procedure *)
- */
static int
smb_name_Pnode_find_name(struct name_entry *name)
{
@@ -2941,59 +1714,14 @@ smb_name_Pnode_find_name(struct name_entry *name)
return (smb_send_name_query_request(UNICAST, &question));
}
-/*
- * 5.1.2.4. P-NODE DELETE_NAME
- *
- * PROCEDURE delete_name (name)
- *
- * (*
- * * Host initiated processing for a P node
- * *)
- *
- * BEGIN
- *
- * REPEAT
- *
- * (*
- * * build packet
- * *)
- * ...
- *
- * (*
- * * send request
- * *)
- *
- * unicast NAME RELEASE REQUEST packet;
- * IF receive a WACK RESPONSE THEN
- * pause(time from TTL field of response);
- * ELSE
- * pause(UCAST_REQ_RETRY_TIMEOUT);
- * UNTIL retransmit count has been exceeded
- * or response been received
- *
- * IF response has been received THEN
- * CASE packet type OF
- * POSITIVE NAME RELEASE RESPONSE:
- * return success;
- * NEGATIVE NAME RELEASE RESPONSE:
- *
- * (*
- * * NAME does want node to delete this
- * * name !!!
- * *)
- *
- * return failure;
- * END (* case *)
- * END (* procedure *)
- */
static int
smb_name_Pnode_delete_name(struct name_entry *name)
{
struct name_question question;
struct resource_record additional;
- struct addr_entry *raddr;
- unsigned char data[MAX_DATAGRAM_LENGTH];
- unsigned char *scan = data;
+ addr_entry_t *raddr;
+ unsigned char data[MAX_DATAGRAM_LENGTH];
+ unsigned char *scan = data;
uint32_t attr;
uint32_t ret_addr;
@@ -3031,254 +1759,6 @@ smb_name_Pnode_delete_name(struct name_entry *name)
return (1);
}
-/*
- * 5.1.3. M-NODE ACTIVITY
- *
- * M nodes behavior is similar to that of P nodes with the addition
- * of some B node-like broadcast actions. M node name service
- * proceeds in two steps:
- *
- * 1.Use broadcast UDP based name service. Depending on the
- * operation, goto step 2.
- *
- * 2.Use directed UDP name service.
- *
- * The following code for M nodes is exactly the same as for a P
- * node, with the exception that broadcast operations are done
- * before P type operation is attempted.
- *
- * 5.1.3.1. M-NODE ADD NAME
- *
- * PROCEDURE add_name(name)
- *
- * (*
- * * Host initiated processing for a M node
- * *)
- *
- * BEGIN
- *
- * (*
- * * check if name exists on the
- * * broadcast area
- * *)
- * REPEAT
- * (* build packet *)
- *
- * ....
- * broadcast NAME REGISTRATION REQUEST packet;
- * pause(BCAST_REQ_RETRY_TIMEOUT);
- *
- * UNTIL response packet is received or
- * retransmit count has been exceeded
- *
- * IF valid response received THEN
- * BEGIN
- * (* cannot claim name *)
- *
- * return failure;
- * END
- *
- * (*
- * * No objections received within the
- * * broadcast area.
- * * Send request to name server.
- * *)
- *
- * REPEAT
- * (*
- * * build packet
- * *)
- *
- * ONT = M;
- * ...
- *
- * unicast NAME REGISTRATION REQUEST packet;
- *
- * (*
- * * remote NAME will send response packet
- * *)
- *
- * IF receive a WACK RESPONSE THEN
- * pause(time from TTL field of response);
- * ELSE
- * pause(UCAST_REQ_RETRY_TIMEOUT);
- *
- * UNTIL response packet is received or
- * retransmit count has been exceeded
- *
- * IF no response packet was received THEN
- * BEGIN (* no response *)
- * (*
- * * NAME is down. Cannot claim name.
- * *)
- * return failure; (* name cannot be claimed *)
- * END (* no response *)
- * ELSE
- * BEGIN (* response *)
- * IF NOT response tid = request tid THEN
- * BEGIN
- * ignore response packet;
- * END
- * ELSE
- * CASE packet type OF
- * POSITIVE NAME REGISTRATION RESPONSE:
- *
- * (*
- * * name can be added
- * *)
- *
- * adjust refresh timeout value, TTL;
- * return success; (* name can be added *)
- *
- * NEGATIVE NAME REGISTRATION RESPONSE:
- * return failure; (* name cannot be added *)
- *
- * END-NODE CHALLENGE REGISTRATION REQUEST:
- * BEGIN (* end node challenge *)
- *
- * (*
- * * The response packet has in it the
- * * address of the presumed owner of the
- * * name. Challenge that owner.
- * * If owner either does not
- * * respond or indicates that he no longer
- * * owns the name, claim the name.
- * * Otherwise, the name cannot be claimed.
- * *
- * *)
- *
- * REPEAT
- * (*
- * * build packet
- * *)
- * ...
- *
- * (*
- * * send packet to address contained in the
- * * response packet
- * *)
- *
- * unicast NAME QUERY REQUEST packet;
- *
- * (*
- * * remote node may send response packet
- * *)
- *
- * pause(UCAST_REQ_RETRY_TIMEOUT);
- *
- * UNTIL response packet is received or
- * retransmit count has been exceeded
- * IF no response packet is received THEN
- * BEGIN (* no response *)
- *
- * (*
- * * name can be claimed
- * *)
- * REPEAT
- *
- * (*
- * * build packet
- * *)
- * ...
- *
- * unicast NAME UPDATE REQUEST to NAME;
- *
- * (*
- * * NAME node will send response packet
- * *)
- *
- * IF receive a WACK RESPONSE THEN
- * pause(time from TTL field of response);
- * ELSE
- * pause(UCAST_REQ_RETRY_TIMEOUT);
- *
- * UNTIL response packet is received or
- * retransmit count has been exceeded
- * IF no response packet received THEN
- * BEGIN (* no response *)
- *
- * (*
- * * name could not be claimed
- * *)
- *
- * return failure;
- * END (* no response *)
- * ELSE
- * CASE packet type OF
- * POSITIVE NAME REGISTRATION RESPONSE:
- * (*
- * * add name
- * *)
- *
- * return success;
- * NEGATIVE NAME REGISTRATION RESPONSE:
- * (*
- * * you lose ...
- * *)
- *
- * return failure;
- * END (* case *)
- * END (* no response *)
- * ELSE
- * IF NOT response tid = request tid THEN
- * BEGIN
- * ignore response packet;
- * END
- *
- * (*
- * * received a response to the "challenge"
- * * packet
- * *)
- *
- * CASE packet type OF
- * POSITIVE NAME QUERY:
- *
- * (*
- * * remote node still has name.
- * *)
- *
- * return failure;
- * NEGATIVE NAME QUERY:
- *
- * (*
- * * remote node no longer has name
- * *)
- *
- * return success;
- * END (* case *)
- * END (* end node challenge *)
- * END (* case *)
- * END (* response *)
- * END (* procedure *)
- *
- *
- * 5.1.3.2. M-NODE ADD GROUP NAME
- *
- * PROCEDURE add_group_name(name)
- *
- * (*
- * * Host initiated processing for a P node
- * *)
- *
- * BEGIN
- * (*
- * * same as for a unique name, except that the
- * * request packet must indicate that a
- * * group name claim is being made.
- * *)
- *
- * ...
- * G = GROUP;
- * ...
- *
- * (*
- * * send packet
- * *)
- * ...
- *
- *
- * END
- */
static int
smb_name_Mnode_add_name(struct name_entry *name)
{
@@ -3302,89 +1782,6 @@ smb_name_Hnode_add_name(struct name_entry *name)
return (smb_name_Bnode_add_name(name));
}
-/*
- * 5.1.3.3. M-NODE FIND NAME
- *
- * PROCEDURE find_name(name)
- *
- * (*
- * * Host initiated processing for a M node
- * *)
- *
- * BEGIN
- * (*
- * * check if any node on the broadcast
- * * area has the name
- * *)
- *
- * REPEAT
- * (* build packet *)
- * ...
- *
- * broadcast NAME QUERY REQUEST packet;
- * pause(BCAST_REQ_RETRY_TIMEOUT);
- * UNTIL response packet received OR
- * max transmit threshold exceeded
- *
- * IF valid response received THEN
- * BEGIN
- * save response as authoritative response;
- * start_timer(CONFLICT_TIMER);
- * return success;
- * END
- *
- * (*
- * * no valid response on the b'cast segment.
- * * Try the name server.
- * *)
- *
- * REPEAT
- * (*
- * * build packet
- * *)
- *
- * ONT = M;
- * G = DONT CARE;
- *
- * unicast NAME QUERY REQUEST packet to NAME;
- *
- * (*
- * * a NAME node might send response packet
- * *)
- *
- * IF receive a WACK RESPONSE THEN
- * pause(time from TTL field of response);
- * ELSE
- * pause(UCAST_REQ_RETRY_TIMEOUT);
- * UNTIL response packet received OR
- * max transmit threshold exceeded
- *
- * IF no response packet received THEN
- * return failure;
- * ELSE
- * IF NOT response tid = request tid THEN
- * ignore packet;
- * ELSE
- * CASE packet type OF
- * POSITIVE NAME QUERY RESPONSE:
- * return success;
- *
- * REDIRECT NAME QUERY RESPONSE:
- *
- * (*
- * * NAME node wants this end node
- * * to use some other NAME node
- * * to resolve the query.
- * *)
- *
- * repeat query with NAME address
- * in the response packet;
- * NEGATIVE NAME QUERY RESPONSE:
- * return failure;
- *
- * END (* case *)
- * END (* procedure *)
- */
static int
smb_name_Mnode_find_name(struct name_entry *name)
{
@@ -3407,68 +1804,6 @@ smb_name_Hnode_find_name(struct name_entry *name)
return (smb_name_Bnode_find_name(name));
}
-/*
- * 5.1.3.4. M-NODE DELETE NAME
- *
- * PROCEDURE delete_name (name)
- *
- * (*
- * * Host initiated processing for a P node
- * *)
- *
- * BEGIN
- * (*
- * * First, delete name on NAME
- * *)
- *
- * REPEAT
- *
- * (*
- * * build packet
- * struct addr_entry *addr;
- * *)
- * ...
- *
- * (*
- * * send request
- * *)
- *
- * unicast NAME RELEASE REQUEST packet to NAME;
- *
- * IF receive a WACK RESPONSE THEN
- * pause(time from TTL field of response);
- * ELSE
- * pause(UCAST_REQ_RETRY_TIMEOUT);
- * UNTIL retransmit count has been exceeded
- * or response been received
- *
- * IF response has been received THEN
- * CASE packet type OF
- * POSITIVE NAME RELEASE RESPONSE:
- * (*
- * * Deletion of name on b'cast segment is deferred
- * * until after NAME has deleted the name
- * *)
- *
- * REPEAT
- * (* build packet *)
- *
- * ...
- * broadcast NAME RELEASE REQUEST;
- * pause(BCAST_REQ_RETRY_TIMEOUT);
- * UNTIL rexmt threshold exceeded
- *
- * return success;
- * NEGATIVE NAME RELEASE RESPONSE:
- *
- * (*
- * * NAME does want node to delete this
- * * name
- * *)
- * return failure;
- * END (* case *)
- * END (* procedure *)
- */
static int
smb_name_Mnode_delete_name(struct name_entry *name)
{
@@ -3493,146 +1828,8 @@ smb_name_Hnode_delete_name(struct name_entry *name)
return (smb_name_Bnode_delete_name(name));
}
-/*
- * 5.1.1.5. B-NODE INCOMING PACKET PROCESSING
- *
- * Following processing is done when broadcast or unicast packets
- * are received at the NAME_SERVICE_UDP_PORT.
- *
- * PROCEDURE process_incoming_packet(packet)
- *
- * (*
- * * Processing initiated by incoming packets for a B node
- * *)
- *
- * BEGIN
- * (*
- * * Note: response packets are always sent
- * * to:
- * * source IP address of request packet
- * * source UDP port of request packet
- * *)
- *
- * CASE packet type OF
- *
- * NAME REGISTRATION REQUEST (UNIQUE):
- * IF name exists in local name table THEN
- * send NEGATIVE_NAME_REGISTRATION_RESPONSE ;
- * NAME REGISTRATION REQUEST (GROUP):
- * IF name exists in local name table THEN
- * BEGIN
- * IF local entry is a unique name THEN
- * send NEGATIVE_NAME_REGISTRATION_RESPONSE ;
- * END
- * NAME QUERY REQUEST:
- * IF name exists in local name table THEN
- * BEGIN
- * build response packet;
- * send POSITIVE_NAME_QUERY_RESPONSE;
- * POSITIVE NAME QUERY RESPONSE:
- * IF name conflict timer is not active THEN
- * BEGIN
- * (*
- * * timer has expired already... ignore this
- * * packet
- * *)
- *
- * return;
- * END
- * ELSE (* timer is active *)
- * IF a response for this name has previously been
- * received THEN
- * BEGIN (* existing entry *)
- *
- * (*
- * * we sent out a request packet, and
- * * have already received (at least)
- * * one response
- * *
- * * Check if conflict exists.
- * * If so, send out a conflict packet.
- * *
- * * Note: detecting conflict does NOT
- * * affect any existing sessions.
- * *
- * *)
- *
- * (*
- * * Check for name conflict.
- * * See "Name Conflict" in Concepts and Methods
- * *)
- * check saved authoritative response against
- * information in this response packet;
- * IF conflict detected THEN
- * BEGIN
- * unicast NAME CONFLICT DEMAND packet;
- * IF entry exists in cache THEN
- * BEGIN
- * remove entry from cache;
- * END
- * END
- * END (* existing entry *)
- * ELSE
- * BEGIN
- * (*
- * * Note: If this was the first response
- * * to a name query, it would have been
- * * handled in the
- * * find_name() procedure.
- * *)
- *
- * ignore packet;
- * END
- * NAME CONFLICT DEMAND:
- * IF name exists in local name table THEN
- * BEGIN
- * mark name as conflict detected;
- *
- * (*
- * * a name in the state "conflict detected"
- * * does not "logically" exist on that node.
- * * No further session will be accepted on
- * * that name.
- * * No datagrams can be sent against that name.
- * * Such an entry will not be used for
- * * purposes of processing incoming request
- * * packets.
- * * The only valid user NetBIOS operation
- * * against such a name is DELETE NAME.
- * *)
- * END
- * NAME RELEASE REQUEST:
- * IF caching is being done THEN
- * BEGIN
- * remove entry from cache;
- * END
- * NAME UPDATE REQUEST:
- * IF caching is being done THEN
- * BEGIN
- * IF entry exists in cache already,
- * update cache;
- * ELSE IF name is "interesting" THEN
- * BEGIN
- * add entry to cache;
- * END
- * END
- *
- * NODE STATUS REQUEST:
- * IF name exists in local name table THEN
- * BEGIN
- * (*
- * * send only those names that are
- * * in the same scope as the scope
- * * field in the request packet
- * *)
- *
- * send NODE STATUS RESPONSE;
- * END
- * END
- */
static void
-smb_name_process_Bnode_packet(struct name_packet *packet,
- struct addr_entry *addr)
+smb_name_process_Bnode_packet(struct name_packet *packet, addr_entry_t *addr)
{
struct name_entry *name;
struct name_entry *entry;
@@ -3711,372 +1908,8 @@ smb_name_process_Bnode_packet(struct name_packet *packet,
}
}
-/*
- * 5.1.2.5. P-NODE INCOMING PACKET PROCESSING
- *
- * Processing initiated by reception of packets at a P node
- *
- * PROCEDURE process_incoming_packet(packet)
- *
- * (*
- * * Processing initiated by incoming packets at a P node
- * *)
- *
- * BEGIN
- * (*
- * * always ignore UDP broadcast packets
- * *)
- *
- * IF packet was sent as a broadcast THEN
- * BEGIN
- * ignore packet;
- * return;
- * END
- * CASE packet type of
- *
- * NAME CONFLICT DEMAND:
- * IF name exists in local name table THEN
- * mark name as in conflict;
- * return;
- *
- * NAME QUERY REQUEST:
- * IF name exists in local name table THEN
- * BEGIN (* name exists *)
- *
- * (*
- * * build packet
- * *)
- * ...
- *
- * (*
- * * send response to the IP address and port
- * * number from which the request was received.
- * *)
- *
- * send POSITIVE_NAME_QUERY_RESPONSE ;
- * return;
- * END (* exists *)
- * ELSE
- * BEGIN (* does not exist *)
- *
- * (*
- * * send response to the requestor
- * *)
- *
- * send NEGATIVE_NAME_QUERY_RESPONSE ;
- * return;
- * END (* does not exist *)
- * NODE STATUS REQUEST:
- * (*
- * * Name of "*" may be used for force node to
- * * divulge status for administrative purposes
- * *)
- * IF name in local name table OR name = "*" THEN
- * BEGIN
- * (*
- * * Build response packet and
- * * send to requestor node
- * * Send only those names that are
- * * in the same scope as the scope
- * * in the request packet.
- * *)
- *
- * send NODE_STATUS_RESPONSE;
- * END
- *
- * NAME RELEASE REQUEST:
- * (*
- * * This will be received if the NAME wants to flush the
- * * name from the local name table, or from the local
- * * cache.
- * *)
- *
- * IF name exists in the local name table THEN
- * BEGIN
- * delete name from local name table;
- * inform user that name has been deleted;
- * END
- * END (* case *)
- * END (* procedure *)
- *
- * (*
- * * Incoming packet processing on a NS node
- * *)
- *
- * BEGIN
- * IF packet was sent as a broadcast THEN
- * BEGIN
- * discard packet;
- * return;
- * END
- * CASE packet type of
- *
- * NAME REGISTRATION REQUEST (UNIQUE):
- * IF unique name exists in data base THEN
- * BEGIN (* unique name exists *)
- * (*
- * * NAME node may be a "passive"
- * * server in that it expects the
- * * end node to do the challenge
- * * server. Such a NAME node is
- * * called a "non-secure" server.
- * * A "secure" server will do the
- * * challenging before it sends
- * * back a response packet.
- * *)
- *
- * IF non-secure THEN
- * BEGIN
- * (*
- * * build response packet
- * *)
- * ...
- *
- *
- * (*
- * * let end node do the challenge
- * *)
- *
- * send END-NODE CHALLENGE NAME REGISTRATION
- * RESPONSE;
- * return;
- * END
- * ELSE
- * (*
- * * secure server - do the name
- * * challenge operation
- * *)
- *
- * REPEAT
- * send NAME QUERY REQUEST;
- * pause(UCAST_REQ_RETRY_TIMEOUT);
- * UNTIL response has been received or
- * retransmit count has been exceeded
- * IF no response was received THEN
- * BEGIN
- *
- * (* node down *)
- *
- * update data base - remove entry;
- * update data base - add new entry;
- * send POSITIVE NAME REGISTRATION RESPONSE;
- * return;
- * END
- * ELSE
- * BEGIN (* challenged node replied *)
- * (*
- * * challenged node replied with
- * * a response packet
- * *)
- *
- * CASE packet type
- *
- * POSITIVE NAME QUERY RESPONSE:
- *
- * (*
- * * name still owned by the
- * * challenged node
- * *
- * * build packet and send response
- * *)
- * ...
- *
- *
- * (*
- * * Note: The NAME will need to
- * * keep track (based on transaction id) of
- * * the IP address and port number
- * * of the original requestor.
- * *)
- *
- * send NEGATIVE NAME REGISTRATION RESPONSE;
- * return;
- * NEGATIVE NAME QUERY RESPONSE:
- *
- * update data base - remove entry;
- * update data base - add new entry;
- *
- * (*
- * * build response packet and send
- * * response
- * *)
- * send POSITIVE NAME REGISTRATION RESPONSE;
- * return;
- * END (* case *)
- * END (* challenged node replied *)
- * END (* unique name exists in data base *)
- * ELSE
- * IF group name exists in data base THEN
- * BEGIN (* group names exists *)
- *
- * (*
- * * Members of a group name are NOT
- * * challenged.
- * * Make the assumption that
- * * at least some of the group members
- * * are still alive.
- * * Refresh mechanism will
- * * allow the NAME to detect when all
- * * members of a group no longer use that
- * * name
- * *)
- *
- * send NEGATIVE NAME REGISTRATION RESPONSE;
- * END (* group name exists *)
- * ELSE
- * BEGIN (* name does not exist *)
- *
- * (*
- * * Name does not exist in data base
- * *
- * * This code applies to both non-secure
- * * and secure server.
- * *)
- *
- * update data base - add new entry;
- * send POSITIVE NAME REGISTRATION RESPONSE;
- * return;
- * END
- *
- * NAME QUERY REQUEST:
- * IF name exists in data base THEN
- * BEGIN
- * (*
- * * build response packet and send to
- * * requestor
- * *)
- * ...
- *
- * send POSITIVE NAME QUERY RESPONSE;
- * return;
- * ELSE
- * BEGIN
- * (*
- * * build response packet and send to
- * * requestor
- * *)
- * ...
- *
- * send NEGATIVE NAME QUERY RESPONSE;
- * return;
- * END
- *
- * NAME REGISTRATION REQUEST (GROUP):
- * IF name exists in data base THEN
- * BEGIN
- * IF local entry is a unique name THEN
- * BEGIN (* local is unique *)
- *
- * IF non-secure THEN
- * BEGIN
- * send END-NODE CHALLENGE NAME
- * REGISTRATION RESPONSE;
- * return;
- * END
- *
- * REPEAT
- * send NAME QUERY REQUEST;
- * pause(UCAST_REQ_RETRY_TIMEOUT);
- * UNTIL response received or
- * retransmit count exceeded
- * IF no response received or
- * NEGATIVE NAME QUERY RESPONSE
- * received THEN
- * BEGIN
- * update data base - remove entry;
- * update data base - add new entry;
- * send POSITIVE NAME REGISTRATION RESPONSE;
- * return;
- * END
- * ELSE
- * BEGIN
- * (*
- * * name still being held
- * * by challenged node
- * *)
- *
- * send NEGATIVE NAME REGISTRATION RESPONSE;
- * END
- * END (* local is unique *)
- * ELSE
- * BEGIN (* local is group *)
- * (*
- * * existing entry is a group name
- * *)
- *
- * update data base - remove entry;
- * update data base - add new entry;
- * send POSITIVE NAME REGISTRATION RESPONSE;
- * return;
- * END (* local is group *)
- * END (* names exists *)
- * ELSE
- * BEGIN (* does not exist *)
- *
- * (* name does not exist in data base *)
- *
- * update data base - add new entry;
- * send POSITIVE NAME REGISTRATION RESPONSE;
- * return;
- * END (* does not exist *)
- *
- * NAME RELEASE REQUEST:
- *
- * (*
- * * secure server may choose to disallow
- * * a node from deleting a name
- * *)
- *
- * update data base - remove entry;
- * send POSITIVE NAME RELEASE RESPONSE;
- * return;
- *
- * NAME UPDATE REQUEST:
- *
- * (*
- * * End-node completed a successful challenge,
- * * no update database
- * *)
- *
- * IF secure server THEN
- * send NEGATIVE NAME REGISTRATION RESPONSE;
- * ELSE
- * BEGIN (* new entry *)
- * IF entry already exists THEN
- * update data base - remove entry;
- * update data base - add new entry;
- * send POSITIVE NAME REGISTRATION RESPONSE;
- * start_timer(TTL);
- * END
- *
- * NAME REFRESH REQUEST:
- * check for consistency;
- *
- * IF node not allowed to have name THEN
- * BEGIN
- *
- * (*
- * * tell end node that it can't have name
- * *)
- * send NEGATIVE NAME REGISTRATION RESPONSE;
- * END
- * ELSE
- * BEGIN
- *
- * (*
- * * send confirmation response to the
- * * end node.
- * *)
- * send POSITIVE NAME REGISTRATION;
- * start_timer(TTL);
- * END
- * return;
- * END (* case *)
- * END (* procedure *)
- */
static void
-smb_name_process_Pnode_packet(struct name_packet *packet,
- struct addr_entry *addr)
+smb_name_process_Pnode_packet(struct name_packet *packet, addr_entry_t *addr)
{
struct name_entry *name;
struct name_entry *entry;
@@ -4174,102 +2007,8 @@ smb_name_process_Pnode_packet(struct name_packet *packet,
}
}
-/*
- * 5.1.3.5. M-NODE INCOMING PACKET PROCESSING
- *
- * Processing initiated by reception of packets at a M node
- *
- * PROCEDURE process_incoming_packet(packet)
- *
- * (*
- * * Processing initiated by incoming packets at a M node
- * *)
- *
- * BEGIN
- * CASE packet type of
- *
- * NAME CONFLICT DEMAND:
- * IF name exists in local name table THEN
- * mark name as in conflict;
- * return;
- *
- * NAME QUERY REQUEST:
- * IF name exists in local name table THEN
- * BEGIN (* name exists *)
- *
- * (*
- * * build packet
- * *)
- * ...
- *
- * (*
- * * send response to the IP address and port
- * * number from which the request was received.
- * *)
- *
- * send POSITIVE NAME QUERY RESPONSE ;
- * return;
- * END (* exists *)
- * ELSE
- * BEGIN (* does not exist *)
- *
- * (*
- * * send response to the requestor
- * *)
- *
- * IF request NOT broadcast THEN
- * (*
- * * Don't send negative responses to
- * * queries sent by B nodes
- * *)
- * send NEGATIVE NAME QUERY RESPONSE ;
- * return;
- * END (* does not exist *)
- * NODE STATUS REQUEST:
- * BEGIN
- * (*
- * * Name of "*" may be used to force node to
- * * divulge status for administrative purposes
- * *)
- * IF name in local name table OR name = "*" THEN
- * (*
- * * Build response packet and
- * * send to requestor node
- * * Send only those names that are
- * * in the same scope as the scope
- * * in the request packet.
- * *)
- *
- * send NODE STATUS RESPONSE;
- * END
- *
- * NAME RELEASE REQUEST:
- * (*
- * * This will be received if the NAME wants to flush the
- * * name from the local name table, or from the local
- * * cache.
- * *)
- *
- * IF name exists in the local name table THEN
- * BEGIN
- * delete name from local name table;
- * inform user that name has been deleted;
- * END
- * NAME REGISTRATION REQUEST (UNIQUE):
- * IF name exists in local name table THEN
- * send NEGATIVE NAME REGISTRATION RESPONSE ;
- * NAME REGISTRATION REQUEST (GROUP):
- * IF name exists in local name table THEN
- * BEGIN
- * IF local entry is a unique name THEN
- * send NEGATIVE NAME REGISTRATION RESPONSE ;
- * END
- * END (* case *)
- * END (* procedure *)
- */
static void
-smb_name_process_Mnode_packet(struct name_packet *packet,
- struct addr_entry *addr)
+smb_name_process_Mnode_packet(struct name_packet *packet, addr_entry_t *addr)
{
if (packet->info & NAME_NM_FLAGS_B)
smb_name_process_Bnode_packet(packet, addr);
@@ -4278,8 +2017,7 @@ smb_name_process_Mnode_packet(struct name_packet *packet,
}
static void
-smb_name_process_Hnode_packet(struct name_packet *packet,
- struct addr_entry *addr)
+smb_name_process_Hnode_packet(struct name_packet *packet, addr_entry_t *addr)
{
if (packet->info & NAME_NM_FLAGS_B)
smb_name_process_Bnode_packet(packet, addr);
@@ -4319,7 +2057,6 @@ smb_netbios_name_tick(void)
smb_netbios_cache_reset_ttl();
}
-
/*
* smb_name_find_name
*
@@ -4368,7 +2105,7 @@ smb_name_add_name(struct name_entry *name)
{
int rc = 1;
- smb_netbios_name_dump(name);
+ smb_netbios_name_logf(name);
switch (smb_node_type) {
case 'B':
@@ -4399,9 +2136,8 @@ smb_name_delete_name(struct name_entry *name)
unsigned char type;
type = name->name[15];
- if ((type != 0x00) && (type != 0x20)) {
- syslog(LOG_ERR,
- "netbios: error trying to delete non-local name");
+ if ((type != NBT_WKSTA) && (type != NBT_SERVER)) {
+ syslog(LOG_DEBUG, "nbns: name delete bad type (0x%02x)", type);
smb_netbios_name_logf(name);
name->attributes &= ~NAME_ATTR_LOCAL;
return (-1);
@@ -4432,7 +2168,7 @@ smb_name_delete_name(struct name_entry *name)
}
typedef struct {
- struct addr_entry *addr;
+ addr_entry_t *addr;
char *buf;
int length;
} worker_param_t;
@@ -4447,16 +2183,16 @@ void *
smb_netbios_worker(void *arg)
{
worker_param_t *p = (worker_param_t *)arg;
- struct addr_entry *addr = p->addr;
+ addr_entry_t *addr = p->addr;
struct name_packet *packet;
- if ((packet = smb_name_buf_to_packet(p->buf, p->length)) != 0) {
+ if ((packet = smb_name_buf_to_packet(p->buf, p->length)) != NULL) {
if (packet->info & NAME_OPCODE_R) {
/* Reply packet */
smb_reply_ready(packet, addr);
free(p->buf);
free(p);
- return (0);
+ return (NULL);
}
/* Request packet */
@@ -4480,29 +2216,48 @@ smb_netbios_worker(void *arg)
smb_netbios_name_freeaddrs(packet->answer->name);
free(packet);
} else {
- syslog(LOG_DEBUG, "SmbNBNS: error decoding received packet");
+ syslog(LOG_ERR, "nbns: packet decode failed");
}
free(addr);
free(p->buf);
free(p);
- return (0);
+ return (NULL);
}
+/*
+ * Configure the node type. If a WINS server has been specified,
+ * act like an H-node. Otherwise, behave like a B-node.
+ */
static void
-smb_netbios_wins_config(char *ip)
+smb_netbios_node_config(void)
{
- uint32_t ipaddr;
+ static smb_cfg_id_t wins[SMB_PI_MAX_WINS] = {
+ SMB_CI_WINS_SRV1,
+ SMB_CI_WINS_SRV2
+ };
+ char ipstr[16];
+ uint32_t ipaddr;
+ int i;
+
+ smb_node_type = SMB_NODETYPE_B;
+ nbns_num = 0;
+ bzero(smb_nbns, sizeof (addr_entry_t) * SMB_PI_MAX_WINS);
+
+ for (i = 0; i < SMB_PI_MAX_WINS; ++i) {
+ ipstr[0] = '\0';
+ (void) smb_config_getstr(wins[i], ipstr, sizeof (ipstr));
- ipaddr = inet_addr(ip);
- if (ipaddr != INADDR_NONE) {
+ if ((ipaddr = inet_addr(ipstr)) == INADDR_NONE)
+ continue;
+
+ smb_node_type = SMB_NODETYPE_H;
smb_nbns[nbns_num].flags = ADDR_FLAG_VALID;
smb_nbns[nbns_num].sinlen = sizeof (struct sockaddr_in);
smb_nbns[nbns_num].sin.sin_family = AF_INET;
smb_nbns[nbns_num].sin.sin_addr.s_addr = ipaddr;
- smb_nbns[nbns_num++].sin.sin_port =
- htons(NAME_SERVICE_UDP_PORT);
- smb_node_type = SMB_NODETYPE_H;
+ smb_nbns[nbns_num].sin.sin_port = htons(IPPORT_NETBIOS_NS);
+ nbns_num++;
}
}
@@ -4539,70 +2294,58 @@ smb_netbios_name_registration(void)
}
}
+/*
+ * Note that the node configuration must be setup before calling
+ * smb_init_name_struct().
+ */
void
smb_netbios_name_config(void)
{
- struct name_entry name;
- char wins_ip[16];
- smb_niciter_t ni;
- int rc;
+ addr_entry_t *bcast_entry;
+ struct name_entry name;
+ smb_niciter_t ni;
+ int rc;
+
+ (void) mutex_lock(&nbt_name_config_mtx);
+ smb_netbios_node_config();
- /* Start with no broadcast addresses */
bcast_num = 0;
bzero(smb_bcast_list, sizeof (addr_entry_t) * SMB_PI_MAX_NETWORKS);
- /* Add all of the broadcast addresses */
rc = smb_nic_getfirst(&ni);
while (rc == 0) {
- if (ni.ni_nic.nic_smbflags &
- (SMB_NICF_ALIAS | SMB_NICF_NBEXCL)) {
+ if ((ni.ni_nic.nic_smbflags & SMB_NICF_NBEXCL) ||
+ (ni.ni_nic.nic_smbflags & SMB_NICF_ALIAS)) {
rc = smb_nic_getnext(&ni);
continue;
}
- smb_bcast_list[bcast_num].flags = ADDR_FLAG_VALID;
- smb_bcast_list[bcast_num].attributes = NAME_ATTR_LOCAL;
- smb_bcast_list[bcast_num].sinlen = sizeof (struct sockaddr_in);
- smb_bcast_list[bcast_num].sin.sin_family = AF_INET;
- smb_bcast_list[bcast_num].sin.sin_port =
- htons(NAME_SERVICE_UDP_PORT);
- smb_bcast_list[bcast_num++].sin.sin_addr.s_addr =
- ni.ni_nic.nic_bcast;
- rc = smb_nic_getnext(&ni);
- }
- /* Start with no WINS */
- smb_node_type = SMB_NODETYPE_B;
- nbns_num = 0;
- bzero(smb_nbns, sizeof (addr_entry_t) * SMB_PI_MAX_WINS);
-
- /* add any configured WINS */
- (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);
-
- if (smb_nic_getfirst(&ni) != 0)
- return;
-
- do {
- if ((ni.ni_nic.nic_smbflags & SMB_NICF_NBEXCL) ||
- (ni.ni_nic.nic_smbflags & SMB_NICF_ALIAS))
- continue;
+ bcast_entry = &smb_bcast_list[bcast_num];
+ bcast_entry->flags = ADDR_FLAG_VALID;
+ bcast_entry->attributes = NAME_ATTR_LOCAL;
+ bcast_entry->sinlen = sizeof (struct sockaddr_in);
+ bcast_entry->sin.sin_family = AF_INET;
+ bcast_entry->sin.sin_port = htons(IPPORT_NETBIOS_NS);
+ bcast_entry->sin.sin_addr.s_addr = ni.ni_nic.nic_bcast;
+ bcast_num++;
smb_init_name_struct((unsigned char *)ni.ni_nic.nic_host,
- 0x00, 0, ni.ni_nic.nic_ip.a_ipv4,
- htons(DGM_SRVC_UDP_PORT),
+ NBT_WKSTA, 0, ni.ni_nic.nic_ip.a_ipv4,
+ htons(IPPORT_NETBIOS_DGM),
NAME_ATTR_UNIQUE, NAME_ATTR_LOCAL, &name);
(void) smb_netbios_cache_insert(&name);
smb_init_name_struct((unsigned char *)ni.ni_nic.nic_host,
- 0x20, 0, ni.ni_nic.nic_ip.a_ipv4,
- htons(DGM_SRVC_UDP_PORT),
+ NBT_SERVER, 0, ni.ni_nic.nic_ip.a_ipv4,
+ htons(IPPORT_NETBIOS_DGM),
NAME_ATTR_UNIQUE, NAME_ATTR_LOCAL, &name);
(void) smb_netbios_cache_insert(&name);
- } while (smb_nic_getnext(&ni) == 0);
+
+ rc = smb_nic_getnext(&ni);
+ }
smb_netbios_name_registration();
+ (void) mutex_unlock(&nbt_name_config_mtx);
}
void
@@ -4610,6 +2353,7 @@ smb_netbios_name_unconfig(void)
{
struct name_entry *name;
+ (void) mutex_lock(&nbt_name_config_mtx);
(void) mutex_lock(&delete_queue.mtx);
smb_netbios_cache_delete_locals(&delete_queue);
@@ -4619,6 +2363,7 @@ smb_netbios_name_unconfig(void)
free(name);
}
(void) mutex_unlock(&delete_queue.mtx);
+ (void) mutex_unlock(&nbt_name_config_mtx);
}
void
@@ -4629,27 +2374,17 @@ smb_netbios_name_reconfig(void)
}
/*
- * process_incoming Function: void smb_netbios_name_service_daemon(void)
- *
- * Description:
- *
- * Put test description here.
- *
- * Inputs:
- * Nothing
- *
- * Returns:
- * int -> Description
+ * NetBIOS Name Service (port 137)
*/
/*ARGSUSED*/
void *
-smb_netbios_name_service_daemon(void *arg)
+smb_netbios_name_service(void *arg)
{
struct sockaddr_in sin;
- struct addr_entry *addr;
+ addr_entry_t *addr;
int len;
int flag = 1;
- char *buf;
+ char *buf;
worker_param_t *worker_param;
smb_inaddr_t ipaddr;
@@ -4659,53 +2394,43 @@ smb_netbios_name_service_daemon(void *arg)
bzero(&reply_queue, sizeof (reply_queue));
reply_queue.forw = reply_queue.back = &reply_queue;
- if (!smb_netbios_cache_init())
- return (0);
-
- bcast_num = 0;
- bzero(smb_bcast_list, sizeof (addr_entry_t) * SMB_PI_MAX_NETWORKS);
-
if ((name_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- syslog(LOG_ERR,
- "smbd: Could not create AF_INET, SOCK_DGRAM, socket");
- smb_netbios_cache_fini();
- smb_netbios_chg_status(NETBIOS_NAME_SVC_FAILED, 1);
- return (0);
+ syslog(LOG_ERR, "nbns: socket failed: %m");
+ smb_netbios_event(NETBIOS_EVENT_ERROR);
+ return (NULL);
}
+ flag = 1;
+ (void) setsockopt(name_sock, SOL_SOCKET, SO_REUSEADDR, &flag,
+ sizeof (flag));
+ flag = 1;
(void) setsockopt(name_sock, SOL_SOCKET, SO_BROADCAST, &flag,
sizeof (flag));
bzero(&sin, sizeof (struct sockaddr_in));
sin.sin_family = AF_INET;
- sin.sin_port = htons(NAME_SERVICE_UDP_PORT);
+ sin.sin_port = htons(IPPORT_NETBIOS_NS);
if (bind(name_sock, (struct sockaddr *)&sin, sizeof (sin)) != 0) {
- syslog(LOG_ERR,
- "smbd: Bind to name service port %d failed (%d)",
- NAME_SERVICE_UDP_PORT, errno);
- smb_netbios_cache_fini();
+ syslog(LOG_ERR, "nbns: bind(%d) failed: %m",
+ IPPORT_NETBIOS_NS);
(void) close(name_sock);
- smb_netbios_chg_status(NETBIOS_NAME_SVC_FAILED, 1);
- return (0);
+ smb_netbios_event(NETBIOS_EVENT_ERROR);
+ return (NULL);
}
- smb_netbios_chg_status(NETBIOS_NAME_SVC_RUNNING, 1);
+ smb_netbios_event(NETBIOS_EVENT_NS_START);
- while (((nb_status.state & NETBIOS_SHUTTING_DOWN) == 0) ||
- (nb_status.state & NETBIOS_BROWSER_RUNNING)) {
- if ((buf = malloc(MAX_DATAGRAM_LENGTH)) == 0) {
- /* Sleep for 10 sec and try again */
- (void) sleep(10);
- continue;
- }
- if ((addr = (struct addr_entry *)
- malloc(sizeof (struct addr_entry))) == 0) {
- /* Sleep for 10 sec and try again */
+ while (smb_netbios_running()) {
+ buf = malloc(MAX_DATAGRAM_LENGTH);
+ addr = malloc(sizeof (addr_entry_t));
+ if ((buf == NULL) || (addr == NULL)) {
+ /* Sleep for 10 seconds and try again */
+ free(addr);
free(buf);
- (void) sleep(10);
+ smb_netbios_sleep(10);
continue;
}
-ignore: bzero(addr, sizeof (struct addr_entry));
+ignore: bzero(addr, sizeof (addr_entry_t));
addr->sinlen = sizeof (addr->sin);
addr->forw = addr->back = addr;
@@ -4713,17 +2438,16 @@ ignore: bzero(addr, sizeof (struct addr_entry));
0, (struct sockaddr *)&addr->sin, &addr->sinlen)) < 0) {
if (errno == ENOMEM || errno == ENFILE ||
errno == EMFILE) {
- /* Sleep for 10 sec and try again */
+ /* Sleep for 10 seconds and try again */
free(buf);
free(addr);
- (void) sleep(10);
+ smb_netbios_sleep(10);
continue;
}
- syslog(LOG_ERR,
- "smbd: NETBIOS name service - recvfrom failed");
+ syslog(LOG_ERR, "nbns: recvfrom failed: %m");
free(buf);
free(addr);
- smb_netbios_chg_status(NETBIOS_NAME_SVC_FAILED, 1);
+ smb_netbios_event(NETBIOS_EVENT_ERROR);
goto shutdown;
}
@@ -4737,8 +2461,7 @@ ignore: bzero(addr, sizeof (struct addr_entry));
/*
* Launch a netbios worker to process the received packet.
*/
- worker_param = (worker_param_t *)
- malloc(sizeof (worker_param_t));
+ worker_param = malloc(sizeof (worker_param_t));
if (worker_param) {
pthread_t worker;
pthread_attr_t tattr;
@@ -4757,23 +2480,12 @@ ignore: bzero(addr, sizeof (struct addr_entry));
}
shutdown:
- smb_netbios_chg_status(NETBIOS_NAME_SVC_RUNNING, 0);
-
- (void) mutex_lock(&nb_status.mtx);
- while (nb_status.state & NETBIOS_BROWSER_RUNNING)
- (void) cond_wait(&nb_status.cv, &nb_status.mtx);
- (void) mutex_unlock(&nb_status.mtx);
+ smb_netbios_event(NETBIOS_EVENT_NS_STOP);
+ smb_netbios_wait(NETBIOS_EVENT_BROWSER_STOP);
- if ((nb_status.state & NETBIOS_NAME_SVC_FAILED) == 0) {
- /* this might delay shutdown, do we want to do this? */
- /*
- * it'll send name release requests but nobody's waiting
- * for response and it'll eventually timeout.
- */
+ if (!smb_netbios_error())
smb_netbios_name_unconfig();
- }
+
(void) close(name_sock);
- smb_netbios_cache_fini();
- syslog(LOG_DEBUG, "smbd: Netbios Name Service is down\n");
- return (0);
+ return (NULL);
}
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_netlogon.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_netlogon.c
index 5d53d6e54d..e34270ce87 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_netlogon.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_netlogon.c
@@ -23,8 +23,6 @@
* Use is subject to license terms.
*/
-#pragma ident "@(#)smbns_netlogon.c 1.7 08/07/16 SMI"
-
/*
* This module handles the primary domain controller location protocol.
* The document claims to be version 1.15 of the browsing protocol. It also
@@ -81,7 +79,7 @@ extern cond_t ntdomain_cv;
void
smb_netlogon_request(struct name_entry *server, char *domain)
{
- nt_domain_t di;
+ smb_domain_t di;
smb_sid_t *sid = NULL;
int protocol = NETLOGON_PROTO_NETLOGON;
@@ -216,13 +214,13 @@ smb_netlogon_receive(struct datagram *datagram,
return;
}
- if (domain == 0 || primary == 0) {
+ if (domain == NULL || primary == NULL) {
syslog(LOG_ERR, "NetLogonResponse: malformed packet");
smb_msgbuf_term(&mb);
return;
}
- syslog(LOG_DEBUG, "DC Offer Dom=%s PDC=%s From=%s",
+ syslog(LOG_DEBUG, "DC Offer Domain=%s PDC=%s From=%s",
domain, primary, src_name);
(void) mutex_lock(&ntdomain_mtx);
@@ -449,8 +447,8 @@ smb_netlogon_send(struct name_entry *name,
smb_init_name_struct((unsigned char *)domain, suffix[i],
0, 0, 0, 0, 0, &dname);
- syslog(LOG_DEBUG, "smb_netlogon_send");
- smb_netbios_name_dump(&dname);
+ syslog(LOG_DEBUG, "SmbNetlogonSend");
+ smb_netbios_name_logf(&dname);
if ((dest = smb_name_find_name(&dname)) != 0) {
dest_dup = smb_netbios_name_dup(dest, 1);
smb_name_unlock_name(dest);
@@ -460,7 +458,8 @@ smb_netlogon_send(struct name_entry *name,
free(dest_dup);
}
} else {
- syslog(LOG_DEBUG, "smbd: NBNS couldn't find %s<0x%X>",
+ syslog(LOG_DEBUG,
+ "SmbNetlogonSend: could not find %s<0x%X>",
domain, suffix[i]);
}
}
diff --git a/usr/src/lib/smbsrv/libsmbrdr/Makefile.com b/usr/src/lib/smbsrv/libsmbrdr/Makefile.com
index 0586ba1034..9e3c531eeb 100644
--- a/usr/src/lib/smbsrv/libsmbrdr/Makefile.com
+++ b/usr/src/lib/smbsrv/libsmbrdr/Makefile.com
@@ -19,17 +19,14 @@
# CDDL HEADER END
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
LIBRARY = libsmbrdr.a
VERS = .1
OBJS_COMMON = \
- smbrdr_ipc_util.o \
smbrdr_lib.o \
smbrdr_logon.o \
smbrdr_netbios.o \
diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/libsmbrdr.h b/usr/src/lib/smbsrv/libsmbrdr/common/libsmbrdr.h
index 2ce1606254..6106339907 100644
--- a/usr/src/lib/smbsrv/libsmbrdr/common/libsmbrdr.h
+++ b/usr/src/lib/smbsrv/libsmbrdr/common/libsmbrdr.h
@@ -32,28 +32,8 @@
extern "C" {
#endif
-typedef struct smbrdr_session_info {
- int si_server_os;
- int si_server_lm;
- int si_dc_type;
-} smbrdr_session_info_t;
-
-/*
- * Redirector IPC functions
- *
- * The following functions are required by the mlsvc_join to
- * apply new authentication information for the authenticated IPC, rollback
- * or commit the changes to the original authentication information.
- */
-extern void smbrdr_ipc_set(char *, unsigned char *);
-extern void smbrdr_ipc_commit(void);
-extern void smbrdr_ipc_rollback(void);
-extern char *smbrdr_ipc_get_user(void);
-extern unsigned char *smbrdr_ipc_get_passwd(void);
-
-
/* Redirector LOGON function */
-extern int mlsvc_logon(char *, char *, char *);
+extern int smbrdr_logon(char *, char *, char *);
extern int smbrdr_get_ssnkey(int, unsigned char *, size_t);
/* Redirector named pipe functions */
@@ -63,10 +43,8 @@ extern int smbrdr_readx(int, char *, int);
extern int smbrdr_transact(int, char *, int, char *, int);
/* Redirector session functions */
-extern void smbrdr_init(void);
-extern int smbrdr_session_info(int, smbrdr_session_info_t *);
-extern int mlsvc_echo(char *);
-extern void mlsvc_disconnect(char *);
+extern int smbrdr_echo(const char *);
+extern void smbrdr_disconnect(const char *);
/* DEBUG functions */
extern void smbrdr_dump_ofiles(void);
diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/mapfile-vers b/usr/src/lib/smbsrv/libsmbrdr/common/mapfile-vers
index 18922e7328..af37a4252a 100644
--- a/usr/src/lib/smbsrv/libsmbrdr/common/mapfile-vers
+++ b/usr/src/lib/smbsrv/libsmbrdr/common/mapfile-vers
@@ -39,23 +39,16 @@
SUNWprivate {
global:
- mlsvc_disconnect;
- mlsvc_echo;
- mlsvc_logon;
smbrdr_close_pipe;
+ smbrdr_disconnect;
smbrdr_dump_netuse;
smbrdr_dump_ofiles;
smbrdr_dump_sessions;
+ smbrdr_echo;
smbrdr_get_ssnkey;
- smbrdr_init;
- smbrdr_ipc_commit;
- smbrdr_ipc_get_user;
- smbrdr_ipc_rollback;
- smbrdr_ipc_set;
- smbrdr_ipc_get_passwd;
+ smbrdr_logon;
smbrdr_open_pipe;
smbrdr_readx;
- smbrdr_session_info;
smbrdr_transact;
local:
*;
diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr.h b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr.h
index c4dfaa7a82..aa21a4a41f 100644
--- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr.h
+++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr.h
@@ -204,7 +204,7 @@ int nb_session_request(int, char *, char *, char *, char *);
* smbrdr_session.c
*/
int smbrdr_negotiate(char *, char *);
-struct sdb_session *smbrdr_session_lock(char *, char *, int);
+struct sdb_session *smbrdr_session_lock(const char *, const char *, int);
void smbrdr_session_unlock(struct sdb_session *);
/*
diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_ipc_util.c b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_ipc_util.c
deleted file mode 100644
index 6d3638d53e..0000000000
--- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_ipc_util.c
+++ /dev/null
@@ -1,170 +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 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
- * The IPC connection information is encapsulated within SMB Redirector.
- * Utility functions are defined here to allow other modules to get and
- * set the ipc configuration, as well as, to rollback or commit the
- * changes to the original authentication information.
- */
-
-#include <string.h>
-#include <strings.h>
-#include <synch.h>
-
-#include <smbsrv/libsmbrdr.h>
-#include <smbsrv/smbinfo.h>
-#include <smbrdr.h>
-#include <smbrdr_ipc_util.h>
-
-#define SMBRDR_IPC_GETDOMAIN_TIMEOUT 10000
-
-static rwlock_t smbrdr_ipc_lock;
-static smbrdr_ipc_t ipc_info;
-static smbrdr_ipc_t orig_ipc_info;
-
-static int
-smbrdr_get_machine_pwd_hash(unsigned char *hash)
-{
- char pwd[SMB_PASSWD_MAXLEN + 1];
- int rc = 0;
-
- 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(pwd, hash) != 0)
- rc = -1;
-
- return (rc);
-}
-
-/*
- * smbrdr_ipc_init
- *
- * Get system configuration regarding IPC connection
- * credentials and initialize related variables.
- * This function will normally be called at startup
- * (i.e. at the time smbrdr gets loaded).
- */
-void
-smbrdr_ipc_init(void)
-{
- int rc;
-
- (void) rw_wrlock(&smbrdr_ipc_lock);
- bzero(&ipc_info, sizeof (smbrdr_ipc_t));
- bzero(&orig_ipc_info, sizeof (smbrdr_ipc_t));
-
- (void) smb_getsamaccount(ipc_info.user, SMB_USERNAME_MAXLEN);
- rc = smbrdr_get_machine_pwd_hash(ipc_info.passwd);
- if (rc != 0)
- *ipc_info.passwd = 0;
- (void) rw_unlock(&smbrdr_ipc_lock);
-
-}
-
-/*
- * smbrdr_ipc_set
- *
- * The given username and password hash will be applied to the
- * ipc_info, which will be used for setting up the authenticated IPC
- * channel during join domain.
- *
- * If domain join operation succeeds, smbrdr_ipc_commit() should be
- * invoked to set the ipc_info with host credentials. Otherwise,
- * smbrdr_ipc_rollback() should be called to restore the previous
- * credentials.
- */
-void
-smbrdr_ipc_set(char *plain_user, unsigned char *passwd_hash)
-{
- (void) rw_wrlock(&smbrdr_ipc_lock);
- (void) strlcpy(ipc_info.user, plain_user, sizeof (ipc_info.user));
- (void) memcpy(ipc_info.passwd, passwd_hash, SMBAUTH_HASH_SZ);
- (void) rw_unlock(&smbrdr_ipc_lock);
-
-}
-
-/*
- * smbrdr_ipc_commit
- *
- * Save the host credentials, which will be used for any authenticated
- * IPC channel establishment after domain join.
- *
- * The host credentials is also saved to the original IPC info as
- * rollback data in case the join domain process fails in the future.
- */
-void
-smbrdr_ipc_commit()
-{
- (void) rw_wrlock(&smbrdr_ipc_lock);
- (void) smb_getsamaccount(ipc_info.user, SMB_USERNAME_MAXLEN);
- (void) smbrdr_get_machine_pwd_hash(ipc_info.passwd);
- (void) memcpy(&orig_ipc_info, &ipc_info, sizeof (smbrdr_ipc_t));
- (void) rw_unlock(&smbrdr_ipc_lock);
-}
-
-/*
- * smbrdr_ipc_rollback
- *
- * Restore the original credentials
- */
-void
-smbrdr_ipc_rollback()
-{
- (void) rw_wrlock(&smbrdr_ipc_lock);
- (void) strlcpy(ipc_info.user, orig_ipc_info.user,
- sizeof (ipc_info.user));
- (void) memcpy(ipc_info.passwd, orig_ipc_info.passwd,
- sizeof (ipc_info.passwd));
- (void) rw_unlock(&smbrdr_ipc_lock);
-}
-
-/*
- * Get & Set functions
- */
-char *
-smbrdr_ipc_get_user()
-{
- char *user;
-
- (void) rw_rdlock(&smbrdr_ipc_lock);
- user = ipc_info.user;
- (void) rw_unlock(&smbrdr_ipc_lock);
- return (user);
-}
-
-unsigned char *
-smbrdr_ipc_get_passwd()
-{
- unsigned char *passwd;
-
- (void) rw_rdlock(&smbrdr_ipc_lock);
- passwd = ipc_info.passwd;
- (void) rw_unlock(&smbrdr_ipc_lock);
- return (passwd);
-}
diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_ipc_util.h b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_ipc_util.h
deleted file mode 100644
index e053d6b066..0000000000
--- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_ipc_util.h
+++ /dev/null
@@ -1,58 +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 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _SMBSRV_IPC_UTIL_H
-#define _SMBSRV_IPC_UTIL_H
-
-/*
- * This file defines the data structure for the IPC connection and utility
- * function prototypes.
- */
-
-#include <smbsrv/libsmb.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * smbrdr_ipc_t
- *
- * This structure contains credentials for establishing authenticated
- * IPC connection.
- */
-typedef struct {
- char user[SMB_USERNAME_MAXLEN];
- unsigned char passwd[SMBAUTH_HASH_SZ];
-} smbrdr_ipc_t;
-
-
-void smbrdr_ipc_init(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SMBSRV_IPC_UTIL_H */
diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_logon.c b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_logon.c
index 5c9b73e9b1..8689ba446c 100644
--- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_logon.c
+++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_logon.c
@@ -37,7 +37,6 @@
#include <smbsrv/libsmbrdr.h>
#include <smbsrv/ntstatus.h>
#include <smbsrv/smb.h>
-#include <smbrdr_ipc_util.h>
#include <smbrdr.h>
#define SMBRDR_ANON_USER "IPC$"
@@ -53,14 +52,12 @@ static int smbrdr_logon_user(char *server, char *username, unsigned char *pwd);
static int smbrdr_authenticate(char *, char *, char *, unsigned char *);
/*
- * mlsvc_logon
- *
* If the username is SMBRDR_ANON_USER, an anonymous session will be
* established. Otherwise, an authenticated session will be established
* based on the specified credentials.
*/
int
-mlsvc_logon(char *domain_controller, char *domain, char *username)
+smbrdr_logon(char *domain_controller, char *domain, char *username)
{
int rc;
@@ -145,15 +142,15 @@ static int
smbrdr_auth_logon(char *domain_controller, char *domain_name, char *username)
{
int erc;
- unsigned char *pwd_hash = NULL;
+ uint8_t pwd_hash[SMBAUTH_HASH_SZ];
if (username == NULL || *username == 0) {
syslog(LOG_DEBUG, "smbrdr_auth_logon: no username");
return (-1);
}
- pwd_hash = smbrdr_ipc_get_passwd();
- if (!pwd_hash || *pwd_hash == 0) {
+ smb_ipc_get_passwd(pwd_hash, SMBAUTH_HASH_SZ);
+ if (*pwd_hash == 0) {
syslog(LOG_DEBUG, "smbrdr_auth_logon: no password");
return (-1);
}
diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_netbios.c b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_netbios.c
index 264ab996e0..675f00e5ae 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 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -43,7 +43,7 @@
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/time.h>
-
+#include <netinet/in.h>
#include <stdio.h>
#include <pthread.h>
@@ -124,7 +124,7 @@ nb_keep_alive(int fd, short port)
int nothing;
int rc;
- if (port == SMB_SRVC_TCP_PORT)
+ if (port == IPPORT_SMB)
return (0);
(void) mutex_lock(&nb_mutex);
diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_rpcpipe.c b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_rpcpipe.c
index 20fd3f4dd6..123dde8fe7 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 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -62,8 +62,8 @@ smbrdr_ofile_free(struct sdb_ofile *ofile)
*/
static struct sdb_ofile ofile_table[N_OFILE_TABLE];
-static int mlsvc_pipe_recon_wait = 50;
-static int mlsvc_pipe_recon_tries = 3;
+static int smbrdr_pipe_recon_wait = 50;
+static int smbrdr_pipe_recon_tries = 3;
/*
@@ -83,7 +83,7 @@ smbrdr_open_pipe(char *hostname, char *domain, char *username, char *pipename)
struct timespec st;
int i;
- if (mlsvc_logon(hostname, domain, username) != 0)
+ if (smbrdr_logon(hostname, domain, username) != 0)
return (-1);
/*
@@ -93,7 +93,7 @@ smbrdr_open_pipe(char *hostname, char *domain, char *username, char *pipename)
for (i = 0; i < 2; i++) {
status = smbrdr_tree_connect(hostname, username, "IPC$", &tid);
if (i == 0 && status == NT_STATUS_UNEXPECTED_NETWORK_ERROR) {
- if (mlsvc_logon(hostname, domain, username) != 0)
+ if (smbrdr_logon(hostname, domain, username) != 0)
return (-1);
continue;
}
@@ -128,7 +128,7 @@ smbrdr_open_pipe(char *hostname, char *domain, char *username, char *pipename)
status = NT_STATUS_OPEN_FAILED;
- for (retry = 0; retry < mlsvc_pipe_recon_tries; retry++) {
+ for (retry = 0; retry < smbrdr_pipe_recon_tries; retry++) {
status = smbrdr_ntcreatex(ofile);
switch (status) {
@@ -146,7 +146,7 @@ smbrdr_open_pipe(char *hostname, char *domain, char *username, char *pipename)
* the pipe becomes available.
*/
st.tv_sec = 0;
- st.tv_nsec = mlsvc_pipe_recon_wait * 1000000;
+ st.tv_nsec = smbrdr_pipe_recon_wait * 1000000;
(void) nanosleep(&st, 0);
break;
@@ -154,7 +154,7 @@ smbrdr_open_pipe(char *hostname, char *domain, char *username, char *pipename)
/*
* Something else went wrong: no more retries.
*/
- retry = mlsvc_pipe_recon_tries;
+ retry = smbrdr_pipe_recon_tries;
break;
}
}
@@ -259,7 +259,7 @@ smbrdr_ofile_get(int fid)
*
* This function can be used when closing a share to ensure that all
* ofiles resources are released. Don't call smbrdr_close_pipe because
- * that will call mlsvc_smb_tdcon and we don't know what state
+ * that will disconnect the tree and we don't know what state
* the share is in. The server will probably close all files anyway.
* We are more interested in releasing the ofile resources.
*/
diff --git a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_session.c b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_session.c
index 9e8d60d38c..1796230614 100644
--- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_session.c
+++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_session.c
@@ -47,13 +47,12 @@
#include <smbsrv/cifs.h>
#include <smbsrv/ntstatus.h>
#include <smbrdr.h>
-#include <smbrdr_ipc_util.h>
#define SMBRDR_DOMAIN_MAX 32
static uint16_t smbrdr_ports[] = {
- SMB_SRVC_TCP_PORT,
- SSN_SRVC_TCP_PORT
+ IPPORT_SMB,
+ IPPORT_NETBIOS_SSN
};
static int smbrdr_nports = sizeof (smbrdr_ports) / sizeof (smbrdr_ports[0]);
@@ -66,7 +65,7 @@ static struct sdb_session *smbrdr_session_init(char *, char *);
static int smbrdr_trnsprt_connect(struct sdb_session *, uint16_t);
static int smbrdr_session_connect(char *, char *);
static int smbrdr_smb_negotiate(struct sdb_session *);
-static int smbrdr_echo(struct sdb_session *);
+static int smbrdr_smb_echo(struct sdb_session *);
static void smbrdr_session_disconnect(struct sdb_session *, int);
@@ -77,21 +76,10 @@ smbrdr_session_clear(struct sdb_session *session)
}
/*
- * Entry pointy for smbrdr initialization.
- */
-void
-smbrdr_init(void)
-{
- smbrdr_ipc_init();
-}
-
-/*
- * mlsvc_disconnect
- *
* Disconnects the session with given server.
*/
void
-mlsvc_disconnect(char *server)
+smbrdr_disconnect(const char *server)
{
struct sdb_session *session;
@@ -282,7 +270,7 @@ smbrdr_trnsprt_connect(struct sdb_session *sess, uint16_t port)
* Otherwise, we're doing NetBIOS-less SMB, i.e. SMB over TCP,
* which is typically on port 445.
*/
- if (port == SSN_SRVC_TCP_PORT) {
+ if (port == IPPORT_NETBIOS_SSN) {
if (smb_getnetbiosname(hostname, MAXHOSTNAMELEN) != 0) {
syslog(LOG_DEBUG, "smbrdr: no hostname");
if (sock != 0)
@@ -532,7 +520,7 @@ smbrdr_session_unlock(struct sdb_session *session)
* the pointer.
*/
struct sdb_session *
-smbrdr_session_lock(char *server, char *username, int lmode)
+smbrdr_session_lock(const char *server, const char *username, int lmode)
{
struct sdb_session *session;
int i;
@@ -566,39 +554,6 @@ smbrdr_session_lock(char *server, char *username, int lmode)
}
/*
- * smbrdr_session_info
- *
- * Return session information related to the specified
- * named pipe (fid).
- */
-int
-smbrdr_session_info(int fid, smbrdr_session_info_t *si)
-{
- struct sdb_session *session;
- struct sdb_netuse *netuse;
- struct sdb_ofile *ofile;
-
- if (si == NULL)
- return (-1);
-
- if ((ofile = smbrdr_ofile_get(fid)) == NULL) {
- syslog(LOG_DEBUG,
- "smbrdr_session_info: unknown file (%d)", fid);
- return (-1);
- }
-
- netuse = ofile->netuse;
- session = netuse->session;
-
- si->si_server_os = session->remote_os;
- si->si_server_lm = session->remote_lm;
- si->si_dc_type = session->pdc_type;
-
- smbrdr_ofile_put(ofile);
- return (0);
-}
-
-/*
* smbrdr_dump_sessions
*
* Debug function to dump the session table.
@@ -635,11 +590,8 @@ smbrdr_dump_sessions(void)
}
}
-/*
- * mlsvc_echo
- */
int
-mlsvc_echo(char *server)
+smbrdr_echo(const char *server)
{
struct sdb_session *session;
int res = 0;
@@ -647,7 +599,7 @@ mlsvc_echo(char *server)
if ((session = smbrdr_session_lock(server, 0, SDB_SLCK_WRITE)) == 0)
return (1);
- if (smbrdr_echo(session) != 0) {
+ if (smbrdr_smb_echo(session) != 0) {
session->state = SDB_SSTATE_STALE;
res = -1;
}
@@ -657,8 +609,6 @@ mlsvc_echo(char *server)
}
/*
- * 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
* in the header, so this request when there are no tree connections.
@@ -667,7 +617,7 @@ mlsvc_echo(char *server)
* Return 0 on success. Otherwise return a -ve error code.
*/
static int
-smbrdr_echo(struct sdb_session *session)
+smbrdr_smb_echo(struct sdb_session *session)
{
static char *echo_str = "smbrdr";
smbrdr_handle_t srh;