summaryrefslogtreecommitdiff
path: root/usr/src/cmd
diff options
context:
space:
mode:
authorAlan Wright <amw@Sun.COM>2009-06-09 14:20:02 -0600
committerAlan Wright <amw@Sun.COM>2009-06-09 14:20:02 -0600
commit29bd28862cfb8abbd3a0f0a4b17e08bbc3652836 (patch)
treeea421b218a8132c096d7513e63e8174869463a72 /usr/src/cmd
parent08045defdf65ee890fef6e20510a093a17feb8fe (diff)
downloadillumos-gate-29bd28862cfb8abbd3a0f0a4b17e08bbc3652836.tar.gz
6803042 AUXILIARY tags in libsmb mapfile produce ELF noise and bloated binary
6663517 smb_auth_[nt]lm_hash and friends should take const arguments 6788664 Remove misleading debug messages at smbd startup 6828536 Allow manipulating ACLs on share from Windows client 6836556 smb_nic_addhost miscomputes buffer length 6766364 Add scripting support to Autohome PSARC 2009/184 SMB/CIFS Share Exec Properties 6837681 CIFS server ignores the preferred DC setting during DC discovery 6775827 cifs server should support guest access PSARC 2009/164 Support for guest access to CIFS/SMB shares 6744962 The daemon smbd doesn't go into maintenance state when the listeners cannot bind to the sockets. 6810419 For smb server on SPARC, NetBIOS name IP is backwards for Windows machine 6840864 Additional levels for srvsvc netshareinfo 6813129 Unable to map cifs share using fqdn and <userPrincipalName>@fqdn for authentication. 6742726 panic when trying to join domain with 1000 pre-existing shares 6842449 The ADS selection algorithm doesn't always pick the configured 'pdc'. 6840692 Setting pdc configuration requires smb/server restart 6832673 smb_ads_find_host() can return host from incorrect domain when host is cached 6840721 Unable to assign an IPv6 address to the 'pdc' property 6842462 FW needs an API for finding a domain controller in a multiple DC environment 6843140 CIFS service dumps core when security tab accessed with certain ACE combinations
Diffstat (limited to 'usr/src/cmd')
-rw-r--r--usr/src/cmd/smbsrv/smbd/Makefile1
-rw-r--r--usr/src/cmd/smbsrv/smbd/server.xml15
-rw-r--r--usr/src/cmd/smbsrv/smbd/smbd.h3
-rw-r--r--usr/src/cmd/smbsrv/smbd/smbd_door_ops.c132
-rw-r--r--usr/src/cmd/smbsrv/smbd/smbd_join.c65
-rw-r--r--usr/src/cmd/smbsrv/smbd/smbd_logon.c4
-rw-r--r--usr/src/cmd/smbsrv/smbd/smbd_main.c350
-rw-r--r--usr/src/cmd/smbsrv/smbd/smbd_net.c118
-rw-r--r--usr/src/cmd/smbsrv/smbd/smbd_share_doorsvc.c36
9 files changed, 385 insertions, 339 deletions
diff --git a/usr/src/cmd/smbsrv/smbd/Makefile b/usr/src/cmd/smbsrv/smbd/Makefile
index 0f1fda4524..dcd3040558 100644
--- a/usr/src/cmd/smbsrv/smbd/Makefile
+++ b/usr/src/cmd/smbsrv/smbd/Makefile
@@ -31,7 +31,6 @@ SRCS= \
smbd_join.c \
smbd_logon.c \
smbd_main.c \
- smbd_net.c \
smbd_opipe_doorsvc.c \
smbd_share_doorsvc.c \
smbd_vss.c
diff --git a/usr/src/cmd/smbsrv/smbd/server.xml b/usr/src/cmd/smbsrv/smbd/server.xml
index 68fbd131da..208a64d0d8 100644
--- a/usr/src/cmd/smbsrv/smbd/server.xml
+++ b/usr/src/cmd/smbsrv/smbd/server.xml
@@ -92,7 +92,7 @@ file.
<method_credential
user='root'
group='sys'
- privileges='basic,net_mac_aware,net_privaddr,proc_audit,sys_devices,sys_smb' />
+ privileges='all' />
</method_context>
</exec_method>
@@ -167,8 +167,6 @@ file.
value='' override='true'/>
<propval name='wins_exclude' type='astring'
value='' override='true'/>
- <propval name='srvsvc_sharesetinfo_enable' type='boolean'
- value='false' override='true'/>
<propval name='max_workers' type='integer'
value='1024' override='true'/>
<propval name='max_connections' type='integer'
@@ -209,6 +207,17 @@ file.
value='false' override='true'/>
</property_group>
+ <!-- SMB service-specific shares exec configuration defaults -->
+ <property_group name='exec' type='application'>
+ <stability value='Evolving' />
+ <propval name='map' type='astring'
+ value='' override='true'/>
+ <propval name='unmap' type='astring'
+ value='' override='true'/>
+ <propval name='disposition' type='astring'
+ value='' override='true'/>
+ </property_group>
+
<!-- 6. Identify faults to be ignored. -->
<!-- 7. Identify service model. Default service model is 'contract' -->
<!-- 8. Identify dependents.
diff --git a/usr/src/cmd/smbsrv/smbd/smbd.h b/usr/src/cmd/smbsrv/smbd/smbd.h
index 35786d5c49..e0192dcbee 100644
--- a/usr/src/cmd/smbsrv/smbd/smbd.h
+++ b/usr/src/cmd/smbsrv/smbd/smbd.h
@@ -51,7 +51,6 @@ extern void smbd_user_nonauth_logon(uint32_t);
extern void smbd_user_auth_logoff(uint32_t);
extern uint32_t smbd_join(smb_joininfo_t *);
-extern int smbd_ioctl(int, smb_io_t *);
extern void smbd_set_secmode(int);
extern int smbd_vss_get_count(const char *, uint32_t *);
@@ -66,7 +65,6 @@ typedef struct smbd {
uid_t s_uid; /* UID of current daemon */
gid_t s_gid; /* GID of current daemon */
int s_fg; /* Run in foreground */
- int s_drv_fd; /* Handle for SMB kernel driver */
boolean_t s_shutting_down; /* shutdown control */
volatile uint_t s_sigval;
volatile uint_t s_refreshes;
@@ -79,6 +77,7 @@ typedef struct smbd {
boolean_t s_tcp_listener_running;
pthread_t s_nbt_listener_id;
pthread_t s_tcp_listener_id;
+ boolean_t s_fatal_error;
} smbd_t;
#ifdef __cplusplus
diff --git a/usr/src/cmd/smbsrv/smbd/smbd_door_ops.c b/usr/src/cmd/smbsrv/smbd/smbd_door_ops.c
index 5222e7da4c..afe33181a7 100644
--- a/usr/src/cmd/smbsrv/smbd/smbd_door_ops.c
+++ b/usr/src/cmd/smbsrv/smbd/smbd_door_ops.c
@@ -32,10 +32,9 @@
#include <smbsrv/smb_common_door.h>
#include <smbsrv/smb_token.h>
#include <smbsrv/libmlsvc.h>
+#include <smbsrv/libsmbns.h>
#include "smbd.h"
-static char *smb_dop_set_downcall_fd(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err);
static char *smb_dop_user_auth_logon(char *argp, size_t arg_size,
door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err);
static char *smb_dop_user_nonauth_logon(char *argp, size_t arg_size,
@@ -43,11 +42,8 @@ static char *smb_dop_user_nonauth_logon(char *argp, size_t arg_size,
static char *smb_dop_user_auth_logoff(char *argp, size_t arg_size,
door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err);
-static char *smb_dop_user_list(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err);
-
-static char *smb_dop_lookup_sid(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err);
+static char *smb_dop_lookup_sid(char *, size_t, door_desc_t *, uint_t,
+ size_t *, int *);
static char *smb_dop_lookup_name(char *argp, size_t arg_size,
door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err);
static char *smb_dop_join(char *argp, size_t arg_size,
@@ -61,15 +57,15 @@ static char *smb_dop_vss_get_snapshots(char *argp, size_t arg_size,
door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err);
static char *smb_dop_vss_map_gmttoken(char *argp, size_t arg_size,
door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err);
+static char *smb_dop_ads_find_host(char *argp, size_t arg_size,
+ door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err);
/* SMB daemon's door operation table */
smb_dr_op_t smb_doorsrv_optab[] =
{
smb_dop_user_auth_logon,
- smb_dop_set_downcall_fd,
smb_dop_user_nonauth_logon,
smb_dop_user_auth_logoff,
- smb_dop_user_list,
smb_dop_lookup_sid,
smb_dop_lookup_name,
smb_dop_join,
@@ -77,6 +73,7 @@ smb_dr_op_t smb_doorsrv_optab[] =
smb_dop_vss_get_count,
smb_dop_vss_get_snapshots,
smb_dop_vss_map_gmttoken,
+ smb_dop_ads_find_host
};
/*ARGSUSED*/
@@ -183,86 +180,6 @@ smb_dop_user_auth_logon(char *argp, size_t arg_size, door_desc_t *dp,
return (buf);
}
-/*
- * Set the downcall file descriptor.
- */
-/*ARGSUSED*/
-static char *
-smb_dop_set_downcall_fd(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err)
-{
- char *buf = NULL;
- uint32_t stat;
-
- *rbufsize = 0;
- *err = 0;
-
- if (n_desc == 1) {
- mlsvc_set_door_fd(dp->d_data.d_desc.d_descriptor);
- stat = SMB_DR_OP_SUCCESS;
- } else {
- stat = SMB_DR_OP_ERR;
- }
-
- if ((buf = smb_dr_set_res_stat(stat, rbufsize)) == NULL) {
- *err = SMB_DR_OP_ERR_ENCODE;
- *rbufsize = 0;
- }
-
- return (buf);
-}
-
-/*
- * smb_dr_op_users
- *
- * This function will obtain information on the connected users
- * starting at the given offset by making a door down-call. The
- * information will then be returned to the user-space door client.
- *
- * At most 50 users (i.e. SMB_DR_MAX_USER) will be returned via this
- * function. The user-space door client might need to make multiple
- * calls to retrieve information on all connected users.
- */
-/*ARGSUSED*/
-char *
-smb_dop_user_list(char *argp, size_t arg_size,
- door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err)
-{
- smb_dr_ulist_t *ulist;
- uint32_t offset;
- char *rbuf = NULL;
- int cnt = 0;
-
- *err = SMB_DR_OP_SUCCESS;
- *rbufsize = 0;
- if (smb_dr_decode_common(argp, arg_size, xdr_uint32_t, &offset) != 0) {
- *err = SMB_DR_OP_ERR_DECODE;
- return (NULL);
- }
-
- ulist = malloc(sizeof (smb_dr_ulist_t));
- if (!ulist) {
- *err = SMB_DR_OP_ERR_EMPTYBUF;
- return (NULL);
- }
-
- cnt = mlsvc_get_user_list(offset, ulist);
- if (cnt < 0) {
- *err = SMB_DR_OP_ERR_EMPTYBUF;
- free(ulist);
- return (NULL);
- }
-
- if ((rbuf = smb_dr_encode_common(SMB_DR_OP_SUCCESS, ulist,
- xdr_smb_dr_ulist_t, rbufsize)) == NULL) {
- *err = SMB_DR_OP_ERR_ENCODE;
- *rbufsize = 0;
- }
-
- smb_dr_ulist_free(ulist);
- return (rbuf);
-}
-
/*ARGSUSED*/
static char *
smb_dop_lookup_name(char *argp, size_t arg_size,
@@ -538,3 +455,40 @@ smb_dop_vss_map_gmttoken(char *argp, size_t arg_size,
free(snapname);
return (rbuf);
}
+
+/*ARGSUSED*/
+static char *
+smb_dop_ads_find_host(char *argp, size_t arg_size,
+ door_desc_t *dp, uint_t n_desc, size_t *rbufsize, int *err)
+{
+ smb_ads_host_info_t *hinfo = NULL;
+ char *hostname;
+ char *fqdn = NULL;
+ char *rbuf = NULL;
+
+ *err = SMB_DR_OP_SUCCESS;
+ *rbufsize = 0;
+
+ /* Decode */
+ if ((fqdn = smb_dr_decode_string(argp, arg_size)) == 0) {
+ *err = SMB_DR_OP_ERR_DECODE;
+ return (NULL);
+ }
+
+ if ((hinfo = smb_ads_find_host(fqdn, NULL)) == NULL)
+ hostname = "";
+ else
+ hostname = hinfo->name;
+
+ xdr_free(xdr_string, (char *)&fqdn);
+
+ /* Encode the result and return */
+ if ((rbuf = smb_dr_encode_string(SMB_DR_OP_SUCCESS, hostname,
+ rbufsize)) == NULL) {
+ *err = SMB_DR_OP_ERR_ENCODE;
+ *rbufsize = 0;
+ }
+
+ free(hinfo);
+ return (rbuf);
+}
diff --git a/usr/src/cmd/smbsrv/smbd/smbd_join.c b/usr/src/cmd/smbsrv/smbd/smbd_join.c
index 440e927303..f19615189b 100644
--- a/usr/src/cmd/smbsrv/smbd/smbd_join.c
+++ b/usr/src/cmd/smbsrv/smbd/smbd_join.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -101,7 +101,8 @@ smbd_set_netlogon_cred(void)
char sam_acct[SMB_SAMACCT_MAXLEN];
char *ipc_usr, *dom;
boolean_t new_domain = B_FALSE;
- smb_domain_t dinfo;
+ smb_domain_t domain;
+ nt_domain_t *di;
if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN)
return (B_FALSE);
@@ -124,18 +125,19 @@ smbd_set_netlogon_cred(void)
if (utf8_strcasecmp(ipc_usr, sam_acct))
return (B_FALSE);
- if (!smb_domain_getinfo(&dinfo))
- (void) smb_getfqdomainname(dinfo.d_fqdomain, MAXHOSTNAMELEN);
+ di = &domain.d_info;
+ if (!smb_domain_getinfo(&domain))
+ (void) smb_getfqdomainname(di->di_fqname, MAXHOSTNAMELEN);
(void) smb_config_getstr(SMB_CI_KPASSWD_DOMAIN, kpasswd_domain,
sizeof (kpasswd_domain));
if (*kpasswd_domain != '\0' &&
- utf8_strcasecmp(kpasswd_domain, dinfo.d_fqdomain)) {
+ utf8_strcasecmp(kpasswd_domain, di->di_fqname)) {
dom = kpasswd_domain;
new_domain = B_TRUE;
} else {
- dom = dinfo.d_fqdomain;
+ dom = di->di_fqname;
}
/*
@@ -143,12 +145,12 @@ smbd_set_netlogon_cred(void)
* currently cached or the SMB daemon has previously discovered a DC
* that is different than the kpasswd server.
*/
- if (new_domain || utf8_strcasecmp(dinfo.d_dc, kpasswd_srv) != 0) {
- if (*dinfo.d_dc != '\0')
- mlsvc_disconnect(dinfo.d_dc);
+ if (new_domain || utf8_strcasecmp(domain.d_dc, kpasswd_srv) != 0) {
+ if (*domain.d_dc != '\0')
+ mlsvc_disconnect(domain.d_dc);
- if (!smb_locate_dc(dom, kpasswd_srv, &dinfo)) {
- if (!smb_locate_dc(dinfo.d_fqdomain, "", &dinfo)) {
+ if (!smb_locate_dc(dom, kpasswd_srv, &domain)) {
+ if (!smb_locate_dc(di->di_fqname, "", &domain)) {
smbrdr_ipc_commit();
return (B_FALSE);
}
@@ -156,14 +158,16 @@ smbd_set_netlogon_cred(void)
}
smbrdr_ipc_commit();
- if (mlsvc_netlogon(dinfo.d_dc, dinfo.d_nbdomain)) {
+ if (mlsvc_netlogon(domain.d_dc, di->di_nbname)) {
syslog(LOG_ERR,
"failed to establish NETLOGON credential chain");
return (B_TRUE);
} else {
if (new_domain) {
- smb_config_setdomaininfo(dinfo.d_nbdomain,
- dinfo.d_fqdomain, dinfo.d_forest, dinfo.d_guid);
+ smb_config_setdomaininfo(di->di_nbname, di->di_fqname,
+ di->di_sid,
+ di->di_u.di_dns.ddi_forest,
+ di->di_u.di_dns.ddi_guid);
(void) smb_config_setstr(SMB_CI_KPASSWD_DOMAIN, "");
}
}
@@ -205,7 +209,8 @@ static void *
smbd_locate_dc_thread(void *arg)
{
char domain[MAXHOSTNAMELEN];
- smb_domain_t new_dinfo;
+ smb_domain_t new_domain;
+ nt_domain_t *di;
if (!smb_match_netlogon_seqnum()) {
(void) smbd_set_netlogon_cred();
@@ -215,10 +220,13 @@ smbd_locate_dc_thread(void *arg)
(void) utf8_strupr(domain);
}
- if (smb_locate_dc(domain, "", &new_dinfo))
- smb_config_setdomaininfo(new_dinfo.d_nbdomain,
- new_dinfo.d_fqdomain, new_dinfo.d_forest,
- new_dinfo.d_guid);
+ if (smb_locate_dc(domain, "", &new_domain)) {
+ di = &new_domain.d_info;
+ smb_config_setdomaininfo(di->di_nbname, di->di_fqname,
+ di->di_sid,
+ di->di_u.di_dns.ddi_forest,
+ di->di_u.di_dns.ddi_guid);
+ }
}
return (NULL);
@@ -271,19 +279,12 @@ static uint32_t
smbd_join_workgroup(smb_joininfo_t *info)
{
char nb_domain[SMB_PI_MAX_DOMAIN];
- smb_domain_t dinfo;
(void) smb_config_getstr(SMB_CI_DOMAIN_NAME, nb_domain,
sizeof (nb_domain));
smbd_set_secmode(SMB_SECMODE_WORKGRP);
-
- bzero(&dinfo, sizeof (smb_domain_t));
- (void) strlcpy(dinfo.d_nbdomain, info->domain_name,
- sizeof (dinfo.d_nbdomain));
- smb_config_setdomaininfo(dinfo.d_nbdomain, dinfo.d_fqdomain,
- dinfo.d_forest, dinfo.d_guid);
-
+ smb_config_setdomaininfo(info->domain_name, "", "", "", "");
if (strcasecmp(nb_domain, info->domain_name))
smb_browser_reconfig();
@@ -298,6 +299,7 @@ smbd_join_domain(smb_joininfo_t *info)
unsigned char passwd_hash[SMBAUTH_HASH_SZ];
char dc[MAXHOSTNAMELEN];
smb_domain_t domain_info;
+ nt_domain_t *di;
/*
* Ensure that any previous membership of this domain has
@@ -320,15 +322,16 @@ smbd_join_domain(smb_joininfo_t *info)
(void) smbd_get_kpasswd_srv(dc, sizeof (dc));
/* info->domain_name could either be NetBIOS domain name or FQDN */
if (smb_locate_dc(info->domain_name, dc, &domain_info)) {
-
status = mlsvc_join(&domain_info, info->domain_username,
info->domain_passwd);
if (status == NT_STATUS_SUCCESS) {
+ di = &domain_info.d_info;
smbd_set_secmode(SMB_SECMODE_DOMAIN);
- smb_config_setdomaininfo(domain_info.d_nbdomain,
- domain_info.d_fqdomain, domain_info. d_forest,
- domain_info.d_guid);
+ smb_config_setdomaininfo(di->di_nbname, di->di_fqname,
+ di->di_sid,
+ di->di_u.di_dns.ddi_forest,
+ di->di_u.di_dns.ddi_guid);
smbrdr_ipc_commit();
return (status);
}
diff --git a/usr/src/cmd/smbsrv/smbd/smbd_logon.c b/usr/src/cmd/smbsrv/smbd/smbd_logon.c
index ebe04ba09a..a6a92ad913 100644
--- a/usr/src/cmd/smbsrv/smbd/smbd_logon.c
+++ b/usr/src/cmd/smbsrv/smbd/smbd_logon.c
@@ -96,8 +96,8 @@ smbd_user_auth_logon(netr_client_t *clnt)
uid = ADT_NO_ATTRIB;
gid = ADT_NO_ATTRIB;
sid = NT_NULL_SIDSTR;
- username = clnt->real_username;
- domain = clnt->real_domain;
+ username = clnt->e_username;
+ domain = clnt->e_domain;
status = ADT_FAILURE;
retval = ADT_FAIL_VALUE_AUTH;
} else {
diff --git a/usr/src/cmd/smbsrv/smbd/smbd_main.c b/usr/src/cmd/smbsrv/smbd/smbd_main.c
index 9f420d87cc..1161c0fa9c 100644
--- a/usr/src/cmd/smbsrv/smbd/smbd_main.c
+++ b/usr/src/cmd/smbsrv/smbd/smbd_main.c
@@ -26,6 +26,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioccom.h>
+#include <sys/corectl.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
@@ -60,11 +61,14 @@
#define DRV_DEVICE_PATH "/devices/pseudo/smbsrv@0:smbsrv"
#define SMB_DBDIR "/var/smb"
-extern void *smbd_nbt_listener(void *);
-extern void *smbd_tcp_listener(void *);
+static void *smbd_nbt_listener(void *);
+static void *smbd_tcp_listener(void *);
+static void *smbd_nbt_receiver(void *);
+static void *smbd_tcp_receiver(void *);
static int smbd_daemonize_init(void);
static void smbd_daemonize_fini(int, int);
+static int smb_init_daemon_priv(int, uid_t, gid_t);
static int smbd_kernel_bind(void);
static void smbd_kernel_unbind(void);
@@ -90,8 +94,17 @@ static void smbd_refresh_fini(void);
static void *smbd_refresh_monitor(void *);
static void smbd_refresh_dc(void);
+static void *smbd_nbt_receiver(void *);
+static void *smbd_nbt_listener(void *);
+
+static void *smbd_tcp_receiver(void *);
+static void *smbd_tcp_listener(void *);
+
static int smbd_start_listeners(void);
static void smbd_stop_listeners(void);
+static int smbd_kernel_start(void);
+
+static void smbd_fatal_error(const char *);
static pthread_t refresh_thr;
static pthread_cond_t refresh_cond;
@@ -209,7 +222,7 @@ main(int argc, char *argv[])
smbd_service_fini();
closelog();
- return (SMF_EXIT_OK);
+ return ((smbd.s_fatal_error) ? SMF_EXIT_ERR_FATAL : SMF_EXIT_OK);
}
/*
@@ -230,10 +243,7 @@ smbd_daemonize_init(void)
* Reset privileges to the minimum set required. We continue
* to run as root to create and access files in /var.
*/
- rc = __init_daemon_priv(PU_RESETGROUPS | PU_LIMITPRIVS,
- smbd.s_uid, smbd.s_gid,
- PRIV_NET_MAC_AWARE, PRIV_NET_PRIVADDR, PRIV_PROC_AUDIT,
- PRIV_SYS_DEVICES, PRIV_SYS_SMB, NULL);
+ rc = smb_init_daemon_priv(PU_RESETGROUPS, smbd.s_uid, smbd.s_gid);
if (rc != 0) {
smbd_report("insufficient privileges");
@@ -284,7 +294,6 @@ smbd_daemonize_init(void)
}
openlog(smbd.s_pname, LOG_PID | LOG_NOWAIT, LOG_DAEMON);
- smbd.s_pid = getpid();
(void) setsid();
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
(void) chdir("/");
@@ -294,9 +303,80 @@ smbd_daemonize_init(void)
return (pfds[1]);
}
+/*
+ * This function is based on __init_daemon_priv() and replaces
+ * __init_daemon_priv() since we want smbd to have all privileges so that it
+ * can execute map/unmap commands with all privileges during share
+ * connection/disconnection. Unused privileges are disabled until command
+ * execution. The permitted and the limit set contains all privileges. The
+ * inheritable set contains no privileges.
+ */
+
+static const char root_cp[] = "/core.%f.%t";
+static const char daemon_cp[] = "/var/tmp/core.%f.%t";
+
+static int
+smb_init_daemon_priv(int flags, uid_t uid, gid_t gid)
+{
+ priv_set_t *perm = NULL;
+ int ret = -1;
+ char buf[1024];
+
+ /*
+ * This is not a significant failure: it allows us to start programs
+ * with sufficient privileges and with the proper uid. We don't
+ * care enough about the extra groups in that case.
+ */
+ if (flags & PU_RESETGROUPS)
+ (void) setgroups(0, NULL);
+
+ if (gid != (gid_t)-1 && setgid(gid) != 0)
+ goto end;
+
+ perm = priv_allocset();
+ if (perm == NULL)
+ goto end;
+
+ /* E = P */
+ (void) getppriv(PRIV_PERMITTED, perm);
+ (void) setppriv(PRIV_SET, PRIV_EFFECTIVE, perm);
+
+ /* Now reset suid and euid */
+ if (uid != (uid_t)-1 && setreuid(uid, uid) != 0)
+ goto end;
+
+ /* I = 0 */
+ priv_emptyset(perm);
+ ret = setppriv(PRIV_SET, PRIV_INHERITABLE, perm);
+end:
+ priv_freeset(perm);
+
+ if (core_get_process_path(buf, sizeof (buf), getpid()) == 0 &&
+ strcmp(buf, "core") == 0) {
+
+ if ((uid == (uid_t)-1 ? geteuid() : uid) == 0) {
+ (void) core_set_process_path(root_cp, sizeof (root_cp),
+ getpid());
+ } else {
+ (void) core_set_process_path(daemon_cp,
+ sizeof (daemon_cp), getpid());
+ }
+ }
+ (void) setpflags(__PROC_PROTECT, 0);
+
+ return (ret);
+}
+
+/*
+ * Most privileges, except the ones that are required for smbd, are turn off
+ * in the effective set. They will be turn on when needed for command
+ * execution during share connection/disconnection.
+ */
static void
smbd_daemonize_fini(int fd, int exit_status)
{
+ priv_set_t *pset;
+
/*
* Now that we're running, if a pipe fd was specified, write an exit
* status to it to indicate that our parent process can safely detach.
@@ -314,8 +394,28 @@ smbd_daemonize_fini(int fd, int exit_status)
(void) close(fd);
}
- __fini_daemon_priv(PRIV_PROC_FORK, PRIV_PROC_EXEC, PRIV_PROC_SESSION,
- PRIV_FILE_LINK_ANY, PRIV_PROC_INFO, NULL);
+ pset = priv_allocset();
+ if (pset == NULL)
+ return;
+
+ priv_emptyset(pset);
+
+ /* list of privileges for smbd */
+ (void) priv_addset(pset, PRIV_NET_MAC_AWARE);
+ (void) priv_addset(pset, PRIV_NET_PRIVADDR);
+ (void) priv_addset(pset, PRIV_PROC_AUDIT);
+ (void) priv_addset(pset, PRIV_SYS_DEVICES);
+ (void) priv_addset(pset, PRIV_SYS_SMB);
+
+ priv_inverse(pset);
+
+ /* turn off unneeded privileges */
+ (void) setppriv(PRIV_OFF, PRIV_EFFECTIVE, pset);
+
+ priv_freeset(pset);
+
+ /* reenable core dumps */
+ __fini_daemon_priv(NULL);
}
/*
@@ -325,10 +425,8 @@ static int
smbd_service_init(void)
{
int rc;
- char nb_domain[NETBIOS_NAME_SZ];
-
- smbd.s_drv_fd = -1;
+ smbd.s_pid = getpid();
if ((mkdir(SMB_DBDIR, 0700) < 0) && (errno != EEXIST)) {
smbd_report("mkdir %s: %s", SMB_DBDIR, strerror(errno));
return (1);
@@ -362,9 +460,6 @@ smbd_service_init(void)
else
smbd_report("NetBIOS services started");
- (void) smb_getdomainname(nb_domain, NETBIOS_NAME_SZ);
- (void) utf8_strupr(nb_domain);
-
/* Get the ID map client handle */
if ((rc = smb_idmap_start()) != 0) {
smbd_report("no idmap handle");
@@ -372,7 +467,7 @@ smbd_service_init(void)
}
smbd.s_secmode = smb_config_get_secmode();
- if ((rc = nt_domain_init(nb_domain, smbd.s_secmode)) != 0) {
+ if ((rc = nt_domain_init(smbd.s_secmode)) != 0) {
if (rc == SMB_DOMAIN_NOMACHINE_SID) {
smbd_report(
"no machine SID: check idmap configuration");
@@ -457,7 +552,9 @@ smbd_service_fini(void)
smb_lgrp_stop();
smb_ccache_remove(SMB_CCACHE_PATH);
smb_pwd_fini();
- nt_domain_unlink();
+ nt_domain_fini();
+ mlsvc_fini();
+ smb_ads_fini();
}
@@ -514,9 +611,8 @@ smbd_refresh_fini()
static void *
smbd_refresh_monitor(void *arg)
{
- smb_io_t smb_io;
-
- bzero(&smb_io, sizeof (smb_io));
+ smb_kmod_cfg_t cfg;
+ int error;
while (!smbd.s_shutting_down) {
(void) pthread_mutex_lock(&refresh_mutex);
@@ -527,7 +623,8 @@ smbd_refresh_monitor(void *arg)
if (smbd.s_shutting_down) {
syslog(LOG_DEBUG, "shutting down");
- exit(SMF_EXIT_OK);
+ exit((smbd.s_fatal_error) ? SMF_EXIT_ERR_FATAL :
+ SMF_EXIT_OK);
}
/*
@@ -570,24 +667,24 @@ smbd_refresh_monitor(void *arg)
break;
}
- if (smbd.s_drv_fd == -1) {
- if (smbd_kernel_bind()) {
+ if (!smbd.s_kbound) {
+ error = smbd_kernel_bind();
+ if (error != 0)
smbd_report("kernel bind error: %s",
- strerror(errno));
- } else {
+ strerror(error));
+ else
(void) smb_shr_load();
- }
+
continue;
}
(void) smb_shr_load();
- smb_load_kconfig(&smb_io.sio_data.cfg);
-
- if (smbd_ioctl(SMB_IOC_CONFIG, &smb_io) < 0) {
- smbd_report("configuration update ioctl: %s",
- strerror(errno));
- }
+ smb_load_kconfig(&cfg);
+ error = smb_kmod_setcfg(&cfg);
+ if (error < 0)
+ smbd_report("configuration update failed: %s",
+ strerror(error));
}
return (NULL);
@@ -663,49 +760,46 @@ smbd_already_running(void)
static int
smbd_kernel_bind(void)
{
- smb_io_t smb_io;
- int rc;
-
- bzero(&smb_io, sizeof (smb_io));
+ int rc;
smbd_kernel_unbind();
- if ((smbd.s_drv_fd = open(DRV_DEVICE_PATH, 0)) < 0) {
- smbd.s_drv_fd = -1;
- return (errno);
+ rc = smb_kmod_bind();
+ if (rc == 0) {
+ rc = smbd_kernel_start();
+ if (rc != 0)
+ smb_kmod_unbind();
+ else
+ smbd.s_kbound = B_TRUE;
}
+ return (rc);
+}
- smb_load_kconfig(&smb_io.sio_data.cfg);
+static int
+smbd_kernel_start(void)
+{
+ smb_kmod_cfg_t cfg;
+ int rc;
- if (smbd_ioctl(SMB_IOC_CONFIG, &smb_io) < 0) {
- (void) close(smbd.s_drv_fd);
- smbd.s_drv_fd = -1;
- return (errno);
- }
- smb_io.sio_data.gmtoff = smbd_gmtoff();
- if (smbd_ioctl(SMB_IOC_GMTOFF, &smb_io) < 0) {
- (void) close(smbd.s_drv_fd);
- smbd.s_drv_fd = -1;
- return (errno);
- }
- smb_io.sio_data.start.opipe = smbd.s_door_opipe;
- smb_io.sio_data.start.lmshrd = smbd.s_door_lmshr;
- smb_io.sio_data.start.udoor = smbd.s_door_srv;
- if (smbd_ioctl(SMB_IOC_START, &smb_io) < 0) {
- (void) close(smbd.s_drv_fd);
- smbd.s_drv_fd = -1;
- return (errno);
- }
+ smb_load_kconfig(&cfg);
+ rc = smb_kmod_setcfg(&cfg);
+ if (rc != 0)
+ return (rc);
+
+ rc = smb_kmod_setgmtoff(smbd_gmtoff());
+ if (rc != 0)
+ return (rc);
+
+ rc = smb_kmod_start(smbd.s_door_opipe, smbd.s_door_lmshr,
+ smbd.s_door_srv);
+ if (rc != 0)
+ return (rc);
rc = smbd_start_listeners();
- if (rc == 0) {
- smbd.s_kbound = B_TRUE;
- return (0);
- }
- smbd_stop_listeners();
- (void) close(smbd.s_drv_fd);
- smbd.s_drv_fd = -1;
- return (rc);
+ if (rc != 0)
+ return (rc);
+
+ return (0);
}
/*
@@ -714,22 +808,9 @@ smbd_kernel_bind(void)
static void
smbd_kernel_unbind(void)
{
- if (smbd.s_drv_fd != -1) {
- smbd_stop_listeners();
- (void) close(smbd.s_drv_fd);
- smbd.s_drv_fd = -1;
- smbd.s_kbound = B_FALSE;
- }
-}
-
-int
-smbd_ioctl(int cmd, smb_io_t *smb_io)
-{
- smb_io->sio_version = SMB_IOC_VERSION;
- smb_io->sio_crc = 0;
- smb_io->sio_crc = smb_crc_gen((uint8_t *)smb_io, sizeof (smb_io_t));
-
- return (ioctl(smbd.s_drv_fd, cmd, smb_io));
+ smbd_stop_listeners();
+ smb_kmod_unbind();
+ smbd.s_kbound = B_FALSE;
}
/*
@@ -763,23 +844,20 @@ smbd_localtime_init(void)
static void *
smbd_localtime_monitor(void *arg)
{
- smb_io_t smb_io;
struct tm local_tm;
time_t secs;
int32_t gmtoff, last_gmtoff = -1;
int timeout;
-
- bzero(&smb_io, sizeof (smb_io));
+ int error;
for (;;) {
gmtoff = smbd_gmtoff();
- if ((last_gmtoff != gmtoff) && (smbd.s_drv_fd != -1)) {
- smb_io.sio_data.gmtoff = gmtoff;
- if (smbd_ioctl(SMB_IOC_GMTOFF, &smb_io) < 0) {
- smbd_report("localtime ioctl: %s",
- strerror(errno));
- }
+ if ((last_gmtoff != gmtoff) && smbd.s_kbound) {
+ error = smb_kmod_setgmtoff(gmtoff);
+ if (error != 0)
+ smbd_report("localtime set failed: %s",
+ strerror(error));
}
/*
@@ -958,6 +1036,92 @@ smbd_stop_listeners(void)
}
/*
+ * Perform fatal error exit.
+ */
+static void
+smbd_fatal_error(const char *msg)
+{
+ if (msg == NULL)
+ msg = "Fatal error";
+
+ smbd_report("%s", msg);
+ smbd.s_fatal_error = B_TRUE;
+ (void) kill(smbd.s_pid, SIGTERM);
+}
+
+/*ARGSUSED*/
+static void *
+smbd_nbt_receiver(void *arg)
+{
+ (void) smb_kmod_nbtreceive();
+ return (NULL);
+}
+
+/*ARGSUSED*/
+static void *
+smbd_nbt_listener(void *arg)
+{
+ pthread_attr_t tattr;
+ sigset_t set;
+ sigset_t oset;
+ pthread_t tid;
+ int error = 0;
+
+ (void) sigfillset(&set);
+ (void) sigdelset(&set, SIGTERM);
+ (void) sigdelset(&set, SIGINT);
+ (void) pthread_sigmask(SIG_SETMASK, &set, &oset);
+ (void) pthread_attr_init(&tattr);
+ (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
+
+ while (smb_kmod_nbtlisten(error) == 0)
+ error = pthread_create(&tid, &tattr, smbd_nbt_receiver, NULL);
+
+ (void) pthread_attr_destroy(&tattr);
+
+ if (!smbd.s_shutting_down)
+ smbd_fatal_error("NBT listener thread terminated unexpectedly");
+
+ return (NULL);
+}
+
+/*ARGSUSED*/
+static void *
+smbd_tcp_receiver(void *arg)
+{
+ (void) smb_kmod_tcpreceive();
+ return (NULL);
+}
+
+/*ARGSUSED*/
+static void *
+smbd_tcp_listener(void *arg)
+{
+ pthread_attr_t tattr;
+ sigset_t set;
+ sigset_t oset;
+ pthread_t tid;
+ int error = 0;
+
+ (void) sigfillset(&set);
+ (void) sigdelset(&set, SIGTERM);
+ (void) sigdelset(&set, SIGINT);
+ (void) pthread_sigmask(SIG_SETMASK, &set, &oset);
+ (void) pthread_attr_init(&tattr);
+ (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
+
+ while (smb_kmod_tcplisten(error) == 0)
+ error = pthread_create(&tid, &tattr, smbd_tcp_receiver, NULL);
+
+ (void) pthread_attr_destroy(&tattr);
+
+ if (!smbd.s_shutting_down)
+ smbd_fatal_error("TCP listener thread terminated unexpectedly");
+
+ return (NULL);
+}
+
+/*
* Enable libumem debugging by default on DEBUG builds.
*/
#ifdef DEBUG
diff --git a/usr/src/cmd/smbsrv/smbd/smbd_net.c b/usr/src/cmd/smbsrv/smbd/smbd_net.c
deleted file mode 100644
index f47b2fbcdc..0000000000
--- a/usr/src/cmd/smbsrv/smbd/smbd_net.c
+++ /dev/null
@@ -1,118 +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.
- */
-
-/*
- * Structures and type definitions for the SMB module.
- */
-
-#include <sys/ioccom.h>
-#include <strings.h>
-#include <unistd.h>
-#include <pthread.h>
-#include <signal.h>
-
-#include <smbsrv/smb_ioctl.h>
-
-#include "smbd.h"
-
-/*ARGSUSED*/
-void *
-smbd_nbt_receiver(void *arg)
-{
- smb_io_t smb_io;
-
- bzero(&smb_io, sizeof (smb_io));
-
- (void) smbd_ioctl(SMB_IOC_NBT_RECEIVE, &smb_io);
- return (NULL);
-}
-
-/*ARGSUSED*/
-void *
-smbd_nbt_listener(void *arg)
-{
- pthread_attr_t tattr;
- sigset_t set;
- sigset_t oset;
- smb_io_t smb_io;
- pthread_t tid;
-
- (void) sigfillset(&set);
- (void) sigdelset(&set, SIGTERM);
- (void) sigdelset(&set, SIGINT);
- (void) pthread_sigmask(SIG_SETMASK, &set, &oset);
- (void) pthread_attr_init(&tattr);
- (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
-
- bzero(&smb_io, sizeof (smb_io));
-
- while (smbd_ioctl(SMB_IOC_NBT_LISTEN, &smb_io) == 0) {
- smb_io.sio_data.error = pthread_create(&tid, &tattr,
- smbd_nbt_receiver, NULL);
- }
- (void) pthread_attr_destroy(&tattr);
-
- return (NULL);
-}
-
-/*ARGSUSED*/
-void *
-smbd_tcp_receiver(void *arg)
-{
- smb_io_t smb_io;
-
- bzero(&smb_io, sizeof (smb_io));
-
- (void) smbd_ioctl(SMB_IOC_TCP_RECEIVE, &smb_io);
- return (NULL);
-}
-
-/*ARGSUSED*/
-void *
-smbd_tcp_listener(void *arg)
-{
- pthread_attr_t tattr;
- sigset_t set;
- sigset_t oset;
- smb_io_t smb_io;
- pthread_t tid;
-
- (void) sigfillset(&set);
- (void) sigdelset(&set, SIGTERM);
- (void) sigdelset(&set, SIGINT);
- (void) pthread_sigmask(SIG_SETMASK, &set, &oset);
- (void) pthread_attr_init(&tattr);
- (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
-
- bzero(&smb_io, sizeof (smb_io));
-
- while (smbd_ioctl(SMB_IOC_TCP_LISTEN, &smb_io) == 0) {
- smb_io.sio_data.error = pthread_create(&tid, &tattr,
- smbd_tcp_receiver, NULL);
- }
- (void) pthread_attr_destroy(&tattr);
-
- return (NULL);
-}
diff --git a/usr/src/cmd/smbsrv/smbd/smbd_share_doorsvc.c b/usr/src/cmd/smbsrv/smbd/smbd_share_doorsvc.c
index ea4a3d3da0..78d33dd1c4 100644
--- a/usr/src/cmd/smbsrv/smbd/smbd_share_doorsvc.c
+++ b/usr/src/cmd/smbsrv/smbd/smbd_share_doorsvc.c
@@ -152,6 +152,8 @@ smb_share_dsrv_dispatch(void *cookie, char *ptr, size_t size, door_desc_t *dp,
smb_enumshare_info_t esi;
int offset;
smb_inaddr_t ipaddr;
+ int exec_type;
+ smb_execsub_info_t subs;
if ((cookie != SMB_SHARE_DSRV_COOKIE) || (ptr == NULL) ||
(size < sizeof (uint32_t))) {
@@ -277,6 +279,40 @@ smb_share_dsrv_dispatch(void *cookie, char *ptr, size_t size, door_desc_t *dp,
}
break;
+ case SMB_SHROP_EXEC:
+ sharename = smb_dr_get_string(dec_ctx);
+ subs.e_winname = smb_dr_get_string(dec_ctx);
+ subs.e_userdom = smb_dr_get_string(dec_ctx);
+ (void) smb_dr_get_buf(dec_ctx,
+ (unsigned char *)&subs.e_srv_ipaddr, sizeof (smb_inaddr_t));
+ (void) smb_dr_get_buf(dec_ctx,
+ (unsigned char *)&subs.e_cli_ipaddr, sizeof (smb_inaddr_t));
+ subs.e_cli_netbiosname = smb_dr_get_string(dec_ctx);
+ subs.e_uid = smb_dr_get_int32(dec_ctx);
+ exec_type = smb_dr_get_int32(dec_ctx);
+ if ((dec_status = smb_dr_decode_finish(dec_ctx)) != 0) {
+ smb_dr_free_string(sharename);
+ smb_dr_free_string(subs.e_winname);
+ smb_dr_free_string(subs.e_userdom);
+ smb_dr_free_string(subs.e_cli_netbiosname);
+ goto decode_error;
+ }
+
+ rc = smb_shr_exec(sharename, &subs, exec_type);
+
+ if (rc != 0)
+ syslog(LOG_NOTICE, "Failed to execute %s" \
+ " command.\n",
+ (exec_type == SMB_SHR_UNMAP) ? "unmap" : "map");
+
+ smb_dr_put_int32(enc_ctx, SMB_SHARE_DSUCCESS);
+ smb_dr_put_uint32(enc_ctx, rc);
+ smb_dr_free_string(sharename);
+ smb_dr_free_string(subs.e_winname);
+ smb_dr_free_string(subs.e_userdom);
+ smb_dr_free_string(subs.e_cli_netbiosname);
+ break;
+
default:
dec_status = smb_dr_decode_finish(dec_ctx);
goto decode_error;