summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/cmd/idmap/idmap/Makefile14
-rw-r--r--usr/src/cmd/idmap/idmap/idmap.c16
-rw-r--r--usr/src/cmd/idmap/idmap/namemaps.c (renamed from usr/src/lib/libidmap/common/namemaps.c)103
-rw-r--r--usr/src/cmd/idmap/idmap/namemaps.h62
-rw-r--r--usr/src/cmd/idmap/idmapd/idmap_config.c214
-rw-r--r--usr/src/cmd/idmap/idmapd/idmapd.c18
-rw-r--r--usr/src/cmd/smbsrv/smbd/smbd_doorsvc.c53
-rw-r--r--usr/src/cmd/smbsrv/smbd/smbd_logon.c17
-rw-r--r--usr/src/cmd/smbsrv/smbd/smbd_share_doorsvc.c15
-rw-r--r--usr/src/common/smbsrv/smb_xdr.c7
-rw-r--r--usr/src/lib/libadutils/common/addisc.c108
-rw-r--r--usr/src/lib/libadutils/common/addisc.h9
-rw-r--r--usr/src/lib/libadutils/common/mapfile-vers4
-rw-r--r--usr/src/lib/libidmap/Makefile.com11
-rw-r--r--usr/src/lib/libidmap/common/directory_helper.c4
-rw-r--r--usr/src/lib/libidmap/common/idmap.h7
-rw-r--r--usr/src/lib/libidmap/common/idmap_api.c19
-rw-r--r--usr/src/lib/libidmap/common/idmap_impl.h10
-rw-r--r--usr/src/lib/libidmap/common/idmap_priv.h31
-rw-r--r--usr/src/lib/libidmap/common/mapfile-vers10
-rw-r--r--usr/src/lib/libshare/smb/libshare_smb.c9
-rw-r--r--usr/src/lib/smbsrv/libmlrpc/common/libmlrpc.h13
-rw-r--r--usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c86
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c370
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/smb_autohome.c105
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/smb_quota.c11
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/smb_share.c105
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/srvsvc_svc.c27
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/libsmb.h4
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/mapfile-vers4
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c59
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c4
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_common_transact.c5
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_kshare.c8
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_kutil.c6
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_node.c72
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_ofile.c5
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_query_fileinfo.c11
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_server.c7
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_tree.c9
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_user.c10
-rw-r--r--usr/src/uts/common/smbsrv/ndl/rpcpdu.ndl165
-rw-r--r--usr/src/uts/common/smbsrv/ndl/samrpc.ndl68
-rw-r--r--usr/src/uts/common/smbsrv/smb_kproto.h5
-rw-r--r--usr/src/uts/common/smbsrv/smb_share.h8
-rw-r--r--usr/src/uts/common/smbsrv/smb_xdr.h6
46 files changed, 1382 insertions, 532 deletions
diff --git a/usr/src/cmd/idmap/idmap/Makefile b/usr/src/cmd/idmap/idmap/Makefile
index 44c2cf7dc7..fa12170f8a 100644
--- a/usr/src/cmd/idmap/idmap/Makefile
+++ b/usr/src/cmd/idmap/idmap/Makefile
@@ -19,12 +19,11 @@
# CDDL HEADER END
#
#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
#
PROG = idmap
-CLIENTOBJS = idmap.o idmap_engine.o
+CLIENTOBJS = idmap.o idmap_engine.o namemaps.o
# idmap_clnt.o
CLIENTSRCS = $(CLIENTOBJS:%.o=%.c)
POFILES = $(CLIENTOBJS:.o=.po)
@@ -35,11 +34,16 @@ IDMAP_PROT_DIR = $(SRC)/head/rpcsvc
include ../../Makefile.cmd
POFILE = $(PROG)_all.po
-LDLIBS += -lidmap
+LDLIBS += -lidmap -ladutils -lsldap -lldap
FILEMODE = 0555
-INCS += -I. -I../../../lib/libidmap/common -I$(IDMAP_PROT_DIR)
+INCS += -I. \
+ -I../../../lib/libidmap/common \
+ -I../../../lib/libadutils/common \
+ -I../../../lib/libsldap/common \
+ -I$(IDMAP_PROT_DIR)
+CFLAGS += $(CCVERBOSE)
$(OBJS) := CPPFLAGS += $(INCS) -D_REENTRANT
$(POFILE) := CPPFLAGS += $(INCS)
diff --git a/usr/src/cmd/idmap/idmap/idmap.c b/usr/src/cmd/idmap/idmap/idmap.c
index 7543f6acc9..57c6b3bfe5 100644
--- a/usr/src/cmd/idmap/idmap/idmap.c
+++ b/usr/src/cmd/idmap/idmap/idmap.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -35,6 +34,8 @@
#include <note.h>
#include "idmap_engine.h"
#include "idmap_priv.h"
+#include "namemaps.h"
+#include "libadutils.h"
/* Initialization values for pids/rids: */
@@ -3541,12 +3542,16 @@ cleanup:
/* printflike */
+static
void
-/* LINTED E_FUNC_ARG_UNUSED */
-logger(int pri, const char *format, ...)
+idmap_cli_logger(int pri, const char *format, ...)
{
+ NOTE(ARGUNUSED(pri))
va_list args;
+ if (pri == LOG_DEBUG)
+ return;
+
va_start(args, format);
(void) vfprintf(stderr, format, args);
@@ -3567,7 +3572,8 @@ main(int argc, char *argv[])
(void) textdomain(TEXT_DOMAIN);
/* Redirect logging */
- idmap_set_logger(logger);
+ idmap_set_logger(idmap_cli_logger);
+ adutils_set_logger(idmap_cli_logger);
/* idmap_engine determines the batch_mode: */
rc = engine_init(sizeof (commands) / sizeof (cmd_ops_t),
diff --git a/usr/src/lib/libidmap/common/namemaps.c b/usr/src/cmd/idmap/idmap/namemaps.c
index 95e47ddd6c..53c89f1554 100644
--- a/usr/src/lib/libidmap/common/namemaps.c
+++ b/usr/src/cmd/idmap/idmap/namemaps.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -30,27 +29,13 @@
#include <libintl.h>
#include <strings.h>
#include <syslog.h>
+#include <stdarg.h>
#include "addisc.h"
#include "libadutils.h"
-#include "idmap_impl.h"
+#include "idmap_priv.h"
#include "ns_sldap.h"
-
-/*
- * syslog is the default logger.
- * It can be overwritten by supplying a logger
- * with idmap_set_logger()
- */
-idmap_logger logger = syslog;
-
-
-void
-idmap_set_logger(idmap_logger funct)
-{
- logger = funct;
- adutils_set_logger(funct);
-}
-
+#include "namemaps.h"
/* From adutils.c: */
@@ -75,6 +60,19 @@ struct idmap_nm_handle {
ns_cred_t nsc;
};
+/* PRINTFLIKE1 */
+static
+void
+namemap_log(char *fmt, ...)
+{
+ va_list va;
+
+ va_start(va, fmt);
+ (void) vfprintf(stderr, fmt, va);
+ va_end(va);
+ (void) fprintf(stderr, "\n");
+}
+
static
idmap_stat
string2auth(const char *from, ns_auth_t *na)
@@ -125,7 +123,7 @@ string2auth(const char *from, ns_auth_t *na)
na->saslmech = NS_LDAP_SASL_DIGEST_MD5;
na->saslopt = NS_LDAP_SASLOPT_NONE;
} else {
- logger(LOG_ERR,
+ namemap_log(
gettext("Invalid authentication method \"%s\" specified\n"),
from);
return (IDMAP_ERR_ARG);
@@ -197,8 +195,9 @@ idmap_open_ad_conn(idmap_nm_handle_t *adh)
/* Open and bind an LDAP connection */
adh->ad = ldap_init(adh->ad_host, adh->ad_port);
if (adh->ad == NULL) {
- logger(LOG_INFO, "ldap_init() to server "
- "%s port %d failed. (%s)", CHECK_NULL(adh->ad_host),
+ namemap_log(
+ gettext("ldap_init() to server %s port %d failed. (%s)"),
+ CHECK_NULL(adh->ad_host),
adh->ad_port, strerror(errno));
rc = IDMAP_ERR_INTERNAL;
goto out;
@@ -217,8 +216,9 @@ idmap_open_ad_conn(idmap_nm_handle_t *adh)
if (ldap_rc != LDAP_SUCCESS) {
(void) ldap_unbind(adh->ad);
adh->ad = NULL;
- logger(LOG_INFO, "ldap_sasl_interactive_bind_s() to server "
- "%s port %d failed. (%s)", CHECK_NULL(adh->ad_host),
+ namemap_log(
+ gettext("ldap_sasl_interactive_bind_s() to server "
+ "%s port %d failed. (%s)"), CHECK_NULL(adh->ad_host),
adh->ad_port, ldap_err2string(ldap_rc));
rc = IDMAP_ERR_INTERNAL;
}
@@ -249,7 +249,7 @@ idmap_init_ad(idmap_nm_handle_t *p)
ad_ctx = ad_disc_init();
if (ad_ctx == NULL) {
- logger(LOG_ERR,
+ namemap_log(
gettext("AD autodiscovery initialization failed"));
return (IDMAP_ERR_INTERNAL);
}
@@ -259,7 +259,7 @@ idmap_init_ad(idmap_nm_handle_t *p)
/* Based on the supplied or default domain, find the proper AD: */
if (ad_disc_set_DomainName(ad_ctx, p->windomain)) {
rc = IDMAP_ERR_INTERNAL;
- logger(LOG_ERR,
+ namemap_log(
gettext("Setting a domain name \"%s\" for autodiscovery"
" failed, most likely not enough memory"), p->windomain);
goto cleanup;
@@ -268,7 +268,7 @@ idmap_init_ad(idmap_nm_handle_t *p)
dc = ad_disc_get_DomainController(ad_ctx, AD_DISC_GLOBAL, NULL);
if (dc == NULL) {
rc = IDMAP_ERR_ARG;
- logger(LOG_ERR,
+ namemap_log(
gettext("A domain controller for the "
"domain \"%s\" not found."), p->windomain);
goto cleanup;
@@ -365,7 +365,7 @@ idmap_init_namemaps(idmap_handle_t *handle, idmap_nm_handle_t **adh,
rc = idmap_get_prop_str(handle, PROP_DEFAULT_DOMAIN,
&p->default_domain);
if (rc != IDMAP_SUCCESS) {
- logger(LOG_ERR,
+ namemap_log(
gettext("Error obtaining default domain from idmapd (%s)"),
idmap_stat2string(NULL, rc));
goto cleanup;
@@ -374,7 +374,7 @@ idmap_init_namemaps(idmap_handle_t *handle, idmap_nm_handle_t **adh,
rc = idmap_get_prop_str(handle, PROP_AD_UNIXUSER_ATTR,
&p->ad_unixuser_attr);
if (rc != IDMAP_SUCCESS) {
- logger(LOG_ERR,
+ namemap_log(
gettext("Error obtaining AD unixuser attribute (%s)"),
idmap_stat2string(NULL, rc));
goto cleanup;
@@ -383,7 +383,7 @@ idmap_init_namemaps(idmap_handle_t *handle, idmap_nm_handle_t **adh,
rc = idmap_get_prop_str(handle, PROP_AD_UNIXGROUP_ATTR,
&p->ad_unixgroup_attr);
if (rc != IDMAP_SUCCESS) {
- logger(LOG_ERR,
+ namemap_log(
gettext("Error obtaining AD unixgroup attribute (%s)"),
idmap_stat2string(NULL, rc));
goto cleanup;
@@ -393,7 +393,7 @@ idmap_init_namemaps(idmap_handle_t *handle, idmap_nm_handle_t **adh,
rc = idmap_get_prop_str(handle, PROP_NLDAP_WINNAME_ATTR,
&p->nldap_winname_attr);
if (rc != IDMAP_SUCCESS) {
- logger(LOG_ERR,
+ namemap_log(
gettext("Error obtaining AD unixgroup attribute (%s)"),
idmap_stat2string(NULL, rc));
goto cleanup;
@@ -412,7 +412,7 @@ idmap_init_namemaps(idmap_handle_t *handle, idmap_nm_handle_t **adh,
goto cleanup;
}
} else if (direction == IDMAP_DIRECTION_W2U) {
- logger(LOG_ERR,
+ namemap_log(
gettext("Windows domain not given and idmapd daemon"
" didn't provide a default one"));
rc = IDMAP_ERR_ARG;
@@ -590,7 +590,7 @@ unixname2dn(idmap_nm_handle_t *p, char *unixname, int is_user, char **dn,
if (rc_ns == NS_LDAP_NOTFOUND) {
- logger(LOG_ERR, is_user ? gettext("User \"%s\" not found.")
+ namemap_log(is_user ? gettext("User %s not found.")
: gettext("Group %s not found."), unixname);
return (IDMAP_ERR_NOTFOUND);
} else if (rc_ns != NS_LDAP_SUCCESS) {
@@ -598,12 +598,12 @@ unixname2dn(idmap_nm_handle_t *p, char *unixname, int is_user, char **dn,
if (errorp != NULL) {
(void) __ns_ldap_err2str(errorp->status, &msg);
}
- logger(LOG_ERR, gettext("Ldap list failed (%s)."), msg);
+ namemap_log(gettext("Ldap list failed (%s)."), msg);
return (IDMAP_ERR_ARG);
}
if (res == NULL) {
- logger(LOG_ERR, gettext("User %s not found"), unixname);
+ namemap_log(gettext("User %s not found"), unixname);
return (IDMAP_ERR_ARG);
}
@@ -620,7 +620,7 @@ unixname2dn(idmap_nm_handle_t *p, char *unixname, int is_user, char **dn,
if (dn != NULL) {
attrs = __ns_ldap_getAttr(&res->entry[0], "dn");
if (attrs == NULL || attrs[0] == NULL) {
- logger(LOG_ERR, gettext("dn for %s not found"),
+ namemap_log(gettext("dn for %s not found"),
unixname);
return (IDMAP_ERR_ARG);
}
@@ -680,8 +680,8 @@ winname2dn(idmap_nm_handle_t *p, char *winname,
free(filter);
if (ldap_rc != LDAP_SUCCESS) {
- logger(LOG_ERR,
- "Ldap query to server %s port %d failed. (%s)",
+ namemap_log(
+ gettext("Ldap query to server %s port %d failed. (%s)"),
p->ad_host, p->ad_port, ldap_err2string(ldap_rc));
(void) ldap_msgfree(results);
return (IDMAP_ERR_OTHER);
@@ -727,7 +727,7 @@ winname2dn(idmap_nm_handle_t *p, char *winname,
}
if (*dn == NULL) {
- logger(LOG_ERR,
+ namemap_log(
*is_wuser == IDMAP_YES ? gettext("User %s@%s not found") :
*is_wuser == IDMAP_NO ? gettext("Group %s@%s not found") :
gettext("%s@%s not found"), winname, p->windomain);
@@ -771,8 +771,8 @@ idmap_ad_set(idmap_nm_handle_t *p, char *dn, char *attr, char *value)
ldap_rc = ldap_modify_s(p->ad, dn, mods);
if (ldap_rc != LDAP_SUCCESS) {
- logger(LOG_ERR,
- "Ldap modify of %s, attribute %s failed. (%s)",
+ namemap_log(
+ gettext("Ldap modify of %s, attribute %s failed. (%s)"),
dn, attr, ldap_err2string(ldap_rc));
rc = IDMAP_ERR_INTERNAL;
}
@@ -845,8 +845,9 @@ idmap_nldap_set(idmap_nm_handle_t *p, ns_cred_t *nsc, char *dn, char *attr,
if (errorp != NULL) {
(void) __ns_ldap_err2str(errorp->status, &msg);
}
- logger(LOG_ERR, gettext("__ns_ldap_addAttr/rep/delAttr"
- " failed (%s)"), msg);
+ namemap_log(
+ gettext("__ns_ldap_addAttr/rep/delAttr failed (%s)"),
+ msg);
return (IDMAP_ERR_ARG);
}
@@ -865,7 +866,7 @@ idmap_set_namemap(idmap_nm_handle_t *p, char *winname, char *unixname,
if (direction == IDMAP_DIRECTION_W2U) {
if (!p->is_ad) {
rc = IDMAP_ERR_ARG;
- logger(LOG_ERR,
+ namemap_log(
gettext("AD namemaps aren't set up."));
goto cleanup;
}
@@ -888,7 +889,7 @@ idmap_set_namemap(idmap_nm_handle_t *p, char *winname, char *unixname,
if (!p->is_nldap) {
rc = IDMAP_ERR_ARG;
- logger(LOG_ERR,
+ namemap_log(
gettext("Native ldap namemaps aren't set up."));
goto cleanup;
}
@@ -955,7 +956,7 @@ idmap_unset_namemap(idmap_nm_handle_t *p, char *winname, char *unixname,
if (direction == IDMAP_DIRECTION_W2U) {
if (!p->is_ad) {
rc = IDMAP_ERR_ARG;
- logger(LOG_ERR,
+ namemap_log(
gettext("AD namemaps aren't set up."));
goto cleanup;
}
@@ -973,7 +974,7 @@ idmap_unset_namemap(idmap_nm_handle_t *p, char *winname, char *unixname,
} else { /* direction == IDMAP_DIRECTION_U2W */
if (!p->is_nldap) {
rc = IDMAP_ERR_ARG;
- logger(LOG_ERR,
+ namemap_log(
gettext("Native ldap namemaps aren't set up."));
goto cleanup;
}
@@ -1012,7 +1013,7 @@ idmap_get_namemap(idmap_nm_handle_t *p, int *is_source_ad, char **winname,
if (p->is_ad == NULL) {
rc = IDMAP_ERR_ARG;
- logger(LOG_ERR,
+ namemap_log(
gettext("AD namemaps are not active."));
goto cleanup;
/* In future maybe resolve winname and try nldap? */
@@ -1021,7 +1022,7 @@ idmap_get_namemap(idmap_nm_handle_t *p, int *is_source_ad, char **winname,
rc = winname2dn(p, *winname, is_wuser, &dn, unixuser,
unixgroup);
if (rc != IDMAP_SUCCESS) {
- logger(LOG_ERR,
+ namemap_log(
gettext("Winname %s@%s not found in AD."),
*winname, p->windomain);
}
@@ -1033,7 +1034,7 @@ idmap_get_namemap(idmap_nm_handle_t *p, int *is_source_ad, char **winname,
if (p->is_nldap == NULL) {
rc = IDMAP_ERR_ARG;
- logger(LOG_ERR,
+ namemap_log(
gettext("Native ldap namemaps aren't active."));
goto cleanup;
/* In future maybe resolve unixname and try AD? */
@@ -1050,7 +1051,7 @@ idmap_get_namemap(idmap_nm_handle_t *p, int *is_source_ad, char **winname,
rc = unixname2dn(p, unixname, is_user, NULL, winname,
windomain);
if (rc != IDMAP_SUCCESS) {
- logger(LOG_ERR,
+ namemap_log(
gettext("%s %s not found in native ldap."),
is_user == IDMAP_YES ? "UNIX user" : "UNIX group",
unixname);
diff --git a/usr/src/cmd/idmap/idmap/namemaps.h b/usr/src/cmd/idmap/idmap/namemaps.h
new file mode 100644
index 0000000000..4587406d6c
--- /dev/null
+++ b/usr/src/cmd/idmap/idmap/namemaps.h
@@ -0,0 +1,62 @@
+/*
+ * 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 (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * Additional API for Identity Mapping Service
+ */
+
+#ifndef NAMEMAPS_H
+#define NAMEMAPS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Directory based name map API
+ */
+
+typedef struct idmap_nm_handle idmap_nm_handle_t;
+
+/* Set namemap */
+extern idmap_stat idmap_set_namemap(idmap_nm_handle_t *, char *, char *,
+ int, int, int);
+
+/* Unset namemap */
+extern idmap_stat idmap_unset_namemap(idmap_nm_handle_t *, char *, char *,
+ int, int, int);
+
+extern idmap_stat idmap_get_namemap(idmap_nm_handle_t *p, int *, char **,
+ char **, int *, char **, char **);
+
+extern void idmap_fini_namemaps(idmap_nm_handle_t *);
+
+extern idmap_stat idmap_init_namemaps(idmap_handle_t *, idmap_nm_handle_t **,
+ char *, char *, char *, char *, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NAMEMAPS_H */
diff --git a/usr/src/cmd/idmap/idmapd/idmap_config.c b/usr/src/cmd/idmap/idmapd/idmap_config.c
index e11d0f8d47..c25f6da2fc 100644
--- a/usr/src/cmd/idmap/idmapd/idmap_config.c
+++ b/usr/src/cmd/idmap/idmapd/idmap_config.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -50,6 +49,14 @@
#define RECONFIGURE 1
#define POKE_AUTO_DISCOVERY 2
+enum event_type {
+ EVENT_NOTHING, /* Woke up for no good reason */
+ EVENT_TIMEOUT, /* Timeout expired */
+ EVENT_ROUTING, /* An interesting routing event happened */
+ EVENT_DEGRADE, /* An error occurred in the mainline */
+ EVENT_REFRESH, /* SMF refresh */
+};
+
/*LINTLIBRARY*/
@@ -893,8 +900,6 @@ enum_lookup(int value, struct enum_lookup_map *map)
return ("(invalid)");
}
-#define MAX_CHECK_TIME (20 * 60)
-
/*
* Returns 1 if the PF_ROUTE socket event indicates that we should rescan the
* interfaces.
@@ -902,13 +907,13 @@ enum_lookup(int value, struct enum_lookup_map *map)
* Shamelessly based on smb_nics_changed() and other PF_ROUTE uses in ON.
*/
static
-int
+boolean_t
pfroute_event_is_interesting(int rt_sock)
{
int nbytes;
int64_t msg[2048 / 8];
struct rt_msghdr *rtm;
- int is_interesting = FALSE;
+ boolean_t is_interesting = B_FALSE;
for (;;) {
if ((nbytes = read(rt_sock, msg, sizeof (msg))) <= 0)
@@ -922,7 +927,7 @@ pfroute_event_is_interesting(int rt_sock)
case RTM_NEWADDR:
case RTM_DELADDR:
case RTM_IFINFO:
- is_interesting = TRUE;
+ is_interesting = B_TRUE;
break;
default:
break;
@@ -932,131 +937,161 @@ pfroute_event_is_interesting(int rt_sock)
}
/*
- * Returns 1 if SIGHUP has been received (see hup_handler() elsewhere) or if an
- * interface address was added or removed; otherwise it returns 0.
+ * Wait for an event, and report what kind of event occurred.
*
- * Note that port_get() does not update its timeout argument when EINTR, unlike
- * nanosleep(). We probably don't care very much here, but if we did care then
- * we could always use a timer event and associate it with the same event port,
- * then we could get accurate waiting regardless of EINTRs.
+ * Note that there are cases where we are awoken but don't care about
+ * the lower-level event. We can't just loop here because we can't
+ * readily calculate how long to sleep the next time. We return
+ * EVENT_NOTHING and let the caller loop.
*/
static
-int
-wait_for_event(int poke_is_interesting, struct timespec *timeoutp)
+enum event_type
+wait_for_event(struct timespec *timeoutp)
{
port_event_t pe;
-retry:
memset(&pe, 0, sizeof (pe));
if (port_get(idmapd_ev_port, &pe, timeoutp) != 0) {
switch (errno) {
case EINTR:
- goto retry;
+ return (EVENT_NOTHING);
case ETIME:
/* Timeout */
- return (FALSE);
+ return (EVENT_TIMEOUT);
default:
/* EBADF, EBADFD, EFAULT, EINVAL (end of time?)? */
idmapdlog(LOG_ERR, "Event port failed: %s",
strerror(errno));
exit(1);
/* NOTREACHED */
- break;
}
}
- if (pe.portev_source == PORT_SOURCE_USER &&
- pe.portev_events == POKE_AUTO_DISCOVERY)
- return (poke_is_interesting ? TRUE : FALSE);
- if (pe.portev_source == PORT_SOURCE_FD && pe.portev_object == rt_sock) {
- /* PF_ROUTE socket read event, re-associate fd, handle event */
- if (port_associate(idmapd_ev_port, PORT_SOURCE_FD, rt_sock,
- POLLIN, NULL) != 0) {
- idmapdlog(LOG_ERR, "Failed to re-associate the "
- "routing socket with the event port: %s",
- strerror(errno));
- exit(1);
- }
+ switch (pe.portev_source) {
+ case 0:
/*
- * The network configuration may still be in flux. No matter,
- * the resolver will re-transmit and timout if need be.
+ * This isn't documented, but seems to be what you get if
+ * the timeout is zero seconds and there are no events
+ * pending.
*/
- return (pfroute_event_is_interesting(rt_sock));
- }
+ return (EVENT_TIMEOUT);
- if (pe.portev_source == PORT_SOURCE_USER &&
- pe.portev_events == RECONFIGURE) {
- int rc;
+ case PORT_SOURCE_USER:
+ if (pe.portev_events == POKE_AUTO_DISCOVERY)
+ return (EVENT_DEGRADE);
+ if (pe.portev_events == RECONFIGURE)
+ return (EVENT_REFRESH);
+ break;
- /*
- * Blow away the ccache, we might have re-joined the
- * domain or joined a new one
- */
- (void) unlink(IDMAP_CACHEDIR "/ccache");
- /* HUP is the refresh method, so re-read SMF config */
- idmapdlog(LOG_INFO, "SMF refresh");
- rc = idmap_cfg_load(_idmapdstate.cfg, CFG_DISCOVER|CFG_LOG);
- if (rc < -1) {
- idmapdlog(LOG_ERR, "Fatal errors while reading "
- "SMF properties");
- exit(1);
- } else if (rc == -1) {
- idmapdlog(LOG_WARNING, "Various errors "
- "re-loading configuration may cause AD lookups "
- "to fail");
+ case PORT_SOURCE_FD:
+ if (pe.portev_object == rt_sock) {
+ /*
+ * PF_ROUTE socket read event:
+ * re-associate fd
+ * handle event
+ */
+ if (port_associate(idmapd_ev_port, PORT_SOURCE_FD,
+ rt_sock, POLLIN, NULL) != 0) {
+ idmapdlog(LOG_ERR, "Failed to re-associate the "
+ "routing socket with the event port: %s",
+ strerror(errno));
+ abort();
+ }
+ /*
+ * The network configuration may still be in flux.
+ * No matter, the resolver will re-transmit and
+ * timeout if need be.
+ */
+ if (pfroute_event_is_interesting(rt_sock)) {
+ idmapdlog(LOG_DEBUG,
+ "Interesting routing event");
+ return (EVENT_ROUTING);
+ } else {
+ idmapdlog(LOG_DEBUG,
+ "Boring routing event");
+ return (EVENT_NOTHING);
+ }
}
- return (FALSE);
+ /* Event on an FD other than the routing FD? Ignore it. */
+ break;
}
- return (FALSE);
+ return (EVENT_NOTHING);
}
void *
idmap_cfg_update_thread(void *arg)
{
- int ttl, changed, poke_is_interesting;
- idmap_cfg_handles_t *handles = &_idmapdstate.cfg->handles;
- ad_disc_t ad_ctx = handles->ad_ctx;
- struct timespec timeout, *timeoutp;
+ const ad_disc_t ad_ctx = _idmapdstate.cfg->handles.ad_ctx;
- poke_is_interesting = 1;
- for (ttl = 0, changed = TRUE; ; ttl = ad_disc_get_TTL(ad_ctx)) {
- /*
- * If ttl < 0 then we can wait for an event without timing out.
- * If idmapd needs to notice that the system has been joined to
- * a Windows domain then idmapd needs to be refreshed.
- */
- timeoutp = (ttl < 0) ? NULL : &timeout;
- if (ttl > MAX_CHECK_TIME)
- ttl = MAX_CHECK_TIME;
- timeout.tv_sec = ttl;
- timeout.tv_nsec = 0;
- changed = wait_for_event(poke_is_interesting, timeoutp);
-
- /*
- * If there are no interesting events, and this is not the first
- * time through the loop, and we haven't waited the most that
- * we're willing to wait, so do nothing but wait some more.
- */
- if (changed == FALSE && ttl > 0 && ttl < MAX_CHECK_TIME)
- continue;
+ for (;;) {
+ struct timespec timeout;
+ struct timespec *timeoutp;
+ int rc;
+ int ttl;
(void) ad_disc_SubnetChanged(ad_ctx);
- if (idmap_cfg_load(_idmapdstate.cfg, CFG_DISCOVER) < -1) {
+ rc = idmap_cfg_load(_idmapdstate.cfg, CFG_DISCOVER);
+ if (rc < -1) {
idmapdlog(LOG_ERR, "Fatal errors while reading "
"SMF properties");
exit(1);
+ } else if (rc == -1) {
+ idmapdlog(LOG_WARNING,
+ "Errors re-loading configuration may cause AD "
+ "lookups to fail");
}
- if (_idmapdstate.cfg->pgcfg.global_catalog == NULL ||
- _idmapdstate.cfg->pgcfg.global_catalog[0].host[0] == '\0')
- poke_is_interesting = 1;
- else
- poke_is_interesting = 0;
+ /*
+ * Wait for an interesting event. Note that we might get
+ * boring events between interesting events. If so, we loop.
+ */
+ for (;;) {
+ ttl = ad_disc_get_TTL(ad_ctx);
+
+ if (ttl < 0) {
+ timeoutp = NULL;
+ } else {
+ timeoutp = &timeout;
+ timeout.tv_sec = ttl;
+ timeout.tv_nsec = 0;
+ }
+
+ switch (wait_for_event(timeoutp)) {
+ case EVENT_NOTHING:
+ idmapdlog(LOG_DEBUG, "Boring event.");
+ continue;
+ case EVENT_REFRESH:
+ idmapdlog(LOG_INFO, "SMF refresh");
+ /*
+ * Blow away the ccache, we might have
+ * re-joined the domain or joined a new one
+ */
+ (void) unlink(IDMAP_CACHEDIR "/ccache");
+ break;
+ case EVENT_DEGRADE:
+ idmapdlog(LOG_DEBUG,
+ "Service degraded");
+ break;
+ case EVENT_TIMEOUT:
+ idmapdlog(LOG_DEBUG, "TTL expired");
+ break;
+ case EVENT_ROUTING:
+ /* Already logged to DEBUG */
+ break;
+ }
+ /* An interesting event! */
+ break;
+ }
}
+ /*
+ * Lint isn't happy with the concept of a function declared to
+ * return something, that doesn't return. Of course, merely adding
+ * the return isn't enough, because it's never reached...
+ */
/*NOTREACHED*/
return (NULL);
}
@@ -1356,6 +1391,8 @@ idmap_cfg_discover(idmap_cfg_handles_t *handles, idmap_pg_config_t *pgcfg)
idmap_trustedforest_t *trustedforests;
ad_disc_domainsinforest_t *domainsinforest;
+ idmapdlog(LOG_DEBUG, "Running discovery.");
+
ad_disc_refresh(ad_ctx);
if (pgcfg->default_domain == NULL)
@@ -1524,6 +1561,9 @@ idmap_cfg_discover(idmap_cfg_handles_t *handles, idmap_pg_config_t *pgcfg)
"unable to discover Domains in the Forest");
if (pgcfg->trusted_domains == NULL)
idmapdlog(LOG_DEBUG, "unable to discover Trusted Domains");
+
+ ad_disc_done(ad_ctx);
+ idmapdlog(LOG_DEBUG, "Discovery done.");
}
diff --git a/usr/src/cmd/idmap/idmapd/idmapd.c b/usr/src/cmd/idmap/idmapd/idmapd.c
index 720b209240..5ea3292acd 100644
--- a/usr/src/cmd/idmap/idmapd/idmapd.c
+++ b/usr/src/cmd/idmap/idmapd/idmapd.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -293,6 +292,7 @@ main(int argc, char **argv)
(void) textdomain(TEXT_DOMAIN);
idmap_set_logger(idmapdlog);
+ adutils_set_logger(idmapdlog);
idmap_log_syslog(B_TRUE);
idmap_log_stderr(_idmapdstate.daemon_mode ? -1 : LOG_DEBUG);
@@ -488,13 +488,6 @@ degrade_svc(int poke_discovery, const char *reason)
{
const char *fmri;
- /*
- * If the config update thread is in a state where auto-discovery could
- * be re-tried, then this will make it try it -- a sort of auto-refresh.
- */
- if (poke_discovery)
- idmap_cfg_poke_updates();
-
membar_consumer();
if (degraded)
return;
@@ -509,6 +502,13 @@ degrade_svc(int poke_discovery, const char *reason)
if ((fmri = get_fmri()) != NULL)
(void) smf_degrade_instance(fmri, 0);
+
+ /*
+ * If the config update thread is in a state where auto-discovery could
+ * be re-tried, then this will make it try it -- a sort of auto-refresh.
+ */
+ if (poke_discovery)
+ idmap_cfg_poke_updates();
}
void
diff --git a/usr/src/cmd/smbsrv/smbd/smbd_doorsvc.c b/usr/src/cmd/smbsrv/smbd/smbd_doorsvc.c
index 7dc3eef535..e936029edc 100644
--- a/usr/src/cmd/smbsrv/smbd/smbd_doorsvc.c
+++ b/usr/src/cmd/smbsrv/smbd/smbd_doorsvc.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <sys/list.h>
@@ -45,10 +44,13 @@
#include <smbsrv/libsmbns.h>
#include "smbd.h"
+#define SMBD_ARG_MAGIC 0x53415247 /* 'SARG' */
+
/*
* Parameter for door operations.
*/
typedef struct smbd_arg {
+ uint32_t magic;
list_node_t lnd;
smb_doorhdr_t hdr;
const char *opname;
@@ -56,6 +58,8 @@ typedef struct smbd_arg {
size_t datalen;
char *rbuf;
size_t rsize;
+ boolean_t response_ready;
+ boolean_t response_abort;
uint32_t status;
} smbd_arg_t;
@@ -254,7 +258,6 @@ smbd_door_dispatch(void *cookie, char *argp, size_t arg_size, door_desc_t *dp,
hdr->dh_door_rc = SMB_DOP_SUCCESS;
else
hdr->dh_door_rc = SMB_DOP_NOT_CALLED;
-
} else {
(void) smbd_door_dispatch_op(&dop_arg);
}
@@ -318,6 +321,7 @@ smbd_door_dispatch_async(smbd_arg_t *req_arg)
}
(void) mutex_lock(&smbd_doorsvc.sd_mutex);
+ arg->magic = SMBD_ARG_MAGIC;
list_insert_tail(&smbd_doorsvc.sd_async_list, arg);
++smbd_doorsvc.sd_async_count;
(void) mutex_unlock(&smbd_doorsvc.sd_mutex);
@@ -346,9 +350,13 @@ static void
smbd_door_release_async(smbd_arg_t *arg)
{
if (arg != NULL) {
+ assert(arg->magic == SMBD_ARG_MAGIC);
+ arg->magic = (uint32_t)~SMBD_ARG_MAGIC;
+
list_remove(&smbd_doorsvc.sd_async_list, arg);
--smbd_doorsvc.sd_async_count;
free(arg->data);
+ arg->data = NULL;
free(arg);
}
}
@@ -358,6 +366,10 @@ smbd_door_release_async(smbd_arg_t *arg)
* - synchronous calls are invoked by direct function call
* - asynchronous calls are invoked from a launched thread
*
+ * If the kernel has attempted to collect a response before the op
+ * has completed, the arg will have been marked as response_abort
+ * and we can discard the response data and release the arg.
+ *
* We send a notification when asynchronous (ASYNC) door calls
* from the kernel (SYSSPACE) have completed.
*/
@@ -385,6 +397,17 @@ smbd_door_dispatch_op(void *thread_arg)
if ((hdr->dh_flags & SMB_DF_SYSSPACE) &&
(hdr->dh_flags & SMB_DF_ASYNC)) {
assert(hdr->dh_op != SMB_DR_ASYNC_RESPONSE);
+
+ (void) mutex_lock(&smbd_doorsvc.sd_mutex);
+ if (arg->response_abort) {
+ free(arg->rbuf);
+ arg->rbuf = NULL;
+ smbd_door_release_async(arg);
+ } else {
+ arg->response_ready = B_TRUE;
+ }
+ (void) mutex_unlock(&smbd_doorsvc.sd_mutex);
+
(void) smb_kmod_event_notify(hdr->dh_txid);
}
@@ -484,6 +507,10 @@ smbd_dop_null(smbd_arg_t *arg)
* Async response handler: setup the rbuf and rsize for the specified
* transaction. This function is used by the kernel to collect the
* response half of an asynchronous door call.
+ *
+ * If a door client attempts to collect a response before the op has
+ * completed (!response_ready), mark the arg as response_abort and
+ * set an error. The response will be discarded when the op completes.
*/
static int
smbd_dop_async_response(smbd_arg_t *rsp_arg)
@@ -495,7 +522,17 @@ smbd_dop_async_response(smbd_arg_t *rsp_arg)
arg = list_head(arg_list);
while (arg != NULL) {
+ assert(arg->magic == SMBD_ARG_MAGIC);
+
if (arg->hdr.dh_txid == rsp_arg->hdr.dh_txid) {
+ if (!arg->response_ready) {
+ arg->response_abort = B_TRUE;
+ rsp_arg->hdr.dh_door_rc = SMB_DOP_NOT_CALLED;
+ syslog(LOG_NOTICE, "doorsvc[%s]: %u not ready",
+ arg->opname, arg->hdr.dh_txid);
+ break;
+ }
+
rsp_arg->rbuf = arg->rbuf;
rsp_arg->rsize = arg->rsize;
arg->rbuf = NULL;
@@ -514,7 +551,7 @@ smbd_dop_async_response(smbd_arg_t *rsp_arg)
static int
smbd_dop_user_nonauth_logon(smbd_arg_t *arg)
{
- uint32_t sid;
+ uint32_t sid = 0;
if (smb_common_decode(arg->data, arg->datalen,
xdr_uint32_t, &sid) != 0)
@@ -527,7 +564,7 @@ smbd_dop_user_nonauth_logon(smbd_arg_t *arg)
static int
smbd_dop_user_auth_logoff(smbd_arg_t *arg)
{
- uint32_t sid;
+ uint32_t sid = 0;
if (smb_common_decode(arg->data, arg->datalen,
xdr_uint32_t, &sid) != 0)
@@ -574,6 +611,8 @@ smbd_dop_lookup_name(smbd_arg_t *arg)
lsa_account_t acct;
char buf[MAXNAMELEN];
+ bzero(&acct, sizeof (lsa_account_t));
+
if (smb_common_decode(arg->data, arg->datalen,
lsa_account_xdr, &acct) != 0)
return (SMB_DOP_DECODE_ERROR);
@@ -617,6 +656,8 @@ smbd_dop_lookup_sid(smbd_arg_t *arg)
lsa_account_t acct;
smb_sid_t *sid;
+ bzero(&acct, sizeof (lsa_account_t));
+
if (smb_common_decode(arg->data, arg->datalen,
lsa_account_xdr, &acct) != 0)
return (SMB_DOP_DECODE_ERROR);
@@ -653,6 +694,8 @@ smbd_dop_join(smbd_arg_t *arg)
smb_joininfo_t jdi;
uint32_t status;
+ bzero(&jdi, sizeof (smb_joininfo_t));
+
if (smb_common_decode(arg->data, arg->datalen,
smb_joininfo_xdr, &jdi) != 0)
return (SMB_DOP_DECODE_ERROR);
diff --git a/usr/src/cmd/smbsrv/smbd/smbd_logon.c b/usr/src/cmd/smbsrv/smbd/smbd_logon.c
index 97f9e47b51..fe27e9cd7f 100644
--- a/usr/src/cmd/smbsrv/smbd/smbd_logon.c
+++ b/usr/src/cmd/smbsrv/smbd/smbd_logon.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <sys/types.h>
@@ -36,6 +35,9 @@
#include <bsm/adt.h>
#include <bsm/adt_event.h>
#include <bsm/audit_uevents.h>
+#include <pwd.h>
+#include <nss_dbdefs.h>
+#include <sys/idmap.h>
#include "smbd.h"
@@ -212,11 +214,20 @@ smbd_user_auth_logoff(uint32_t audit_sid)
smb_audit_t *entry;
adt_session_data_t *ah;
adt_event_data_t *event;
+ struct passwd pw;
+ char buf[NSS_LINELEN_PASSWD];
if ((entry = smbd_audit_unlink(audit_sid)) == NULL)
return;
- smb_autohome_remove(entry->sa_username);
+ if (IDMAP_ID_IS_EPHEMERAL(entry->sa_uid)) {
+ smb_autohome_remove(entry->sa_username);
+ } else {
+ if (getpwuid_r(entry->sa_uid, &pw, buf, sizeof (buf)) == NULL)
+ return;
+
+ smb_autohome_remove(pw.pw_name);
+ }
ah = entry->sa_handle;
diff --git a/usr/src/cmd/smbsrv/smbd/smbd_share_doorsvc.c b/usr/src/cmd/smbsrv/smbd/smbd_share_doorsvc.c
index 5ec93bd59f..3792e23853 100644
--- a/usr/src/cmd/smbsrv/smbd/smbd_share_doorsvc.c
+++ b/usr/src/cmd/smbsrv/smbd/smbd_share_doorsvc.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -257,16 +256,12 @@ smbd_share_dispatch(void *cookie, char *ptr, size_t size, door_desc_t *dp,
case SMB_SHROP_ENUM:
esi.es_bufsize = smb_dr_get_ushort(dec_ctx);
- esi.es_username = smb_dr_get_string(dec_ctx);
- if ((dec_status = smb_dr_decode_finish(dec_ctx)) != 0) {
- smb_dr_free_string(esi.es_username);
+ esi.es_posix_uid = smb_dr_get_uint32(dec_ctx);
+ if ((dec_status = smb_dr_decode_finish(dec_ctx)) != 0)
goto decode_error;
- }
rc = smbd_share_enum(&esi);
- smb_dr_free_string(esi.es_username);
-
smb_dr_put_int32(enc_ctx, SMB_SHARE_DSUCCESS);
smb_dr_put_uint32(enc_ctx, rc);
if (rc == NERR_Success) {
@@ -380,7 +375,7 @@ smbd_share_enum(smb_enumshare_info_t *esi)
continue;
if ((si->shr_flags & SMB_SHRF_AUTOHOME) && !autohome_added) {
- if (strcasecmp(esi->es_username, si->shr_name) == 0)
+ if (esi->es_posix_uid == si->shr_uid)
autohome_added = B_TRUE;
else
continue;
@@ -417,7 +412,7 @@ smbd_share_enum(smb_enumshare_info_t *esi)
continue;
if ((si->shr_flags & SMB_SHRF_AUTOHOME) && !autohome_added) {
- if (strcasecmp(esi->es_username, si->shr_name) == 0)
+ if (esi->es_posix_uid == si->shr_uid)
autohome_added = B_TRUE;
else
continue;
diff --git a/usr/src/common/smbsrv/smb_xdr.c b/usr/src/common/smbsrv/smb_xdr.c
index 43276d0910..46d2e2ca49 100644
--- a/usr/src/common/smbsrv/smb_xdr.c
+++ b/usr/src/common/smbsrv/smb_xdr.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <sys/sunddi.h>
@@ -236,7 +235,7 @@ smb_netuserinfo_xdr(XDR *xdrs, smb_netuserinfo_t *objp)
{
if (!xdr_uint64_t(xdrs, &objp->ui_session_id))
return (FALSE);
- if (!xdr_uint16_t(xdrs, &objp->ui_uid))
+ if (!xdr_uint16_t(xdrs, &objp->ui_smb_uid))
return (FALSE);
if (!xdr_uint16_t(xdrs, &objp->ui_domain_len))
return (FALSE);
@@ -246,6 +245,8 @@ smb_netuserinfo_xdr(XDR *xdrs, smb_netuserinfo_t *objp)
return (FALSE);
if (!xdr_string(xdrs, &objp->ui_account, ~0))
return (FALSE);
+ if (!xdr_uint32_t(xdrs, &objp->ui_posix_uid))
+ return (FALSE);
if (!xdr_uint16_t(xdrs, &objp->ui_workstation_len))
return (FALSE);
if (!xdr_string(xdrs, &objp->ui_workstation, ~0))
diff --git a/usr/src/lib/libadutils/common/addisc.c b/usr/src/lib/libadutils/common/addisc.c
index b32f9d7694..187981b5a2 100644
--- a/usr/src/lib/libadutils/common/addisc.c
+++ b/usr/src/lib/libadutils/common/addisc.c
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -103,6 +102,16 @@
#include "adutils_impl.h"
#include "addisc.h"
+/*
+ * These set some sanity policies for discovery. After a discovery
+ * cycle, we will consider the results (successful or unsuccessful)
+ * to be valid for at least MINIMUM_TTL seconds, and for at most
+ * MAXIMUM_TTL seconds. Note that the caller is free to request
+ * discovery cycles sooner than MINIMUM_TTL if it has reason to believe
+ * that the situation has changed.
+ */
+#define MINIMUM_TTL (5 * 60)
+#define MAXIMUM_TTL (20 * 60)
enum ad_item_state {
AD_STATE_INVALID = 0, /* The value is not valid */
@@ -127,7 +136,7 @@ typedef struct ad_item {
enum ad_item_state state;
enum ad_data_type type;
void *value;
- time_t ttl;
+ time_t expires;
unsigned int version; /* Version is only changed */
/* if the value changes */
#define PARAM1 0
@@ -144,6 +153,8 @@ typedef struct ad_disc {
ad_subnet_t *subnets;
boolean_t subnets_changed;
time_t subnets_last_check;
+ time_t expires_not_before;
+ time_t expires_not_after;
ad_item_t domain_name; /* DNS hostname string */
ad_item_t domain_controller; /* Directory hostname and */
/* port array */
@@ -216,7 +227,7 @@ is_valid(ad_item_t *item)
if (item->state == AD_STATE_FIXED)
return (B_TRUE);
if (item->state == AD_STATE_AUTO &&
- (item->ttl == 0 || item->ttl > time(NULL)))
+ (item->expires == 0 || item->expires > time(NULL)))
return (B_TRUE);
}
return (B_FALSE);
@@ -247,9 +258,9 @@ update_item(ad_item_t *item, void *value, enum ad_item_state state,
item->state = state;
if (ttl == 0)
- item->ttl = 0;
+ item->expires = 0;
else
- item->ttl = time(NULL) + ttl;
+ item->expires = time(NULL) + ttl;
}
@@ -593,26 +604,6 @@ DN_to_DNS(const char *dn_name)
}
-/* Format the DN of an AD LDAP subnet object for some subnet */
-static char *
-subnet_to_DN(const char *subnet, const char *baseDN)
-{
- char *result;
- int len;
-
- len = snprintf(NULL, 0,
- "CN=%s,CN=Subnets,CN=Sites,%s",
- subnet, baseDN) + 1;
-
- result = malloc(len);
- if (result != NULL)
- (void) snprintf(result, len,
- "CN=%s,CN=Subnets,CN=Sites,%s",
- subnet, baseDN);
- return (result);
-}
-
-
/* Make a list of subnet object DNs from a list of subnets */
static char **
subnets_to_DNs(ad_subnet_t *subnets, const char *base_dn)
@@ -628,8 +619,9 @@ subnets_to_DNs(ad_subnet_t *subnets, const char *base_dn)
return (NULL);
for (i = 0; subnets[i].subnet[0] != '\0'; i++) {
- if ((results[i] = subnet_to_DN(subnets[i].subnet, base_dn))
- == NULL) {
+ (void) asprintf(&results[i], "CN=%s,CN=Subnets,CN=Sites,%s",
+ subnets[i].subnet, base_dn);
+ if (results[i] == NULL) {
for (j = 0; j < i; j++)
free(results[j]);
free(results);
@@ -828,7 +820,8 @@ err:
* A utility function to bind to a Directory server
*/
-static LDAP*
+static
+LDAP *
ldap_lookup_init(idmap_ad_disc_ds_t *ds)
{
int i;
@@ -988,15 +981,17 @@ ldap_lookup_trusted_domains(LDAP **ld, idmap_ad_disc_ds_t *globalCatalog,
if (partner != NULL && direction != NULL) {
num++;
- trusted_domains = realloc(trusted_domains,
+ void *tmp = realloc(trusted_domains,
(num + 1) *
sizeof (ad_disc_trusteddomains_t));
- if (trusted_domains == NULL) {
+ if (tmp == NULL) {
+ free(trusted_domains);
ldap_value_free(partner);
ldap_value_free(direction);
ldap_msgfree(results);
return (NULL);
}
+ trusted_domains = tmp;
/* Last element should be zero */
memset(&trusted_domains[num], 0,
sizeof (ad_disc_trusteddomains_t));
@@ -1221,6 +1216,22 @@ ad_disc_refresh(ad_disc_t ctx)
}
+/*
+ * Called when the discovery cycle is done. Sets a master TTL
+ * that will avoid doing new time-based discoveries too soon after
+ * the last discovery cycle. Most interesting when the discovery
+ * cycle failed, because then the TTLs on the individual items will
+ * not be updated and may go stale.
+ */
+void
+ad_disc_done(ad_disc_t ctx)
+{
+ time_t now = time(NULL);
+
+ ctx->expires_not_before = now + MINIMUM_TTL;
+ ctx->expires_not_after = now + MAXIMUM_TTL;
+}
+
/* Discover joined Active Directory domainName */
static ad_item_t *
@@ -1425,12 +1436,13 @@ validate_SiteName(ad_disc_t ctx)
return (NULL);
if (!is_valid(&ctx->site_name) ||
- is_changed(&ctx->site_name, PARAM1, &ctx->domain_controller) ||
+ is_changed(&ctx->site_name, PARAM1, domain_controller_item) ||
ctx->subnets == NULL || ctx->subnets_changed) {
subnets = find_subnets();
ctx->subnets_last_check = time(NULL);
update_required = B_TRUE;
} else if (ctx->subnets_last_check + 60 < time(NULL)) {
+ /* NEEDSWORK magic constant 60 above */
subnets = find_subnets();
ctx->subnets_last_check = time(NULL);
if (cmpsubnets(ctx->subnets, subnets) != 0)
@@ -1471,6 +1483,8 @@ validate_SiteName(ad_disc_t ctx)
forest_name = DN_to_DNS(config_naming_context + len);
update_item(&ctx->forest_name, forest_name,
AD_STATE_AUTO, 0);
+ update_version(&ctx->forest_name, PARAM1,
+ domain_controller_item);
}
}
@@ -1495,6 +1509,8 @@ validate_SiteName(ad_disc_t ctx)
site_name[len] = '\0';
update_item(&ctx->site_name, site_name,
AD_STATE_AUTO, 0);
+ update_version(&ctx->site_name, PARAM1,
+ domain_controller_item);
}
}
@@ -1997,17 +2013,33 @@ ad_disc_unset(ad_disc_t ctx)
int
ad_disc_get_TTL(ad_disc_t ctx)
{
+ time_t expires;
int ttl;
- ttl = MIN_GT_ZERO(ctx->domain_controller.ttl, ctx->global_catalog.ttl);
- ttl = MIN_GT_ZERO(ttl, ctx->site_domain_controller.ttl);
- ttl = MIN_GT_ZERO(ttl, ctx->site_global_catalog.ttl);
+ expires = MIN_GT_ZERO(ctx->domain_controller.expires,
+ ctx->global_catalog.expires);
+ expires = MIN_GT_ZERO(expires, ctx->site_domain_controller.expires);
+ expires = MIN_GT_ZERO(expires, ctx->site_global_catalog.expires);
- if (ttl == -1)
+ if (expires == -1) {
return (-1);
- ttl -= time(NULL);
- if (ttl < 0)
+ }
+
+ if (ctx->expires_not_before != 0 &&
+ expires < ctx->expires_not_before) {
+ expires = ctx->expires_not_before;
+ }
+
+ if (ctx->expires_not_after != 0 &&
+ expires > ctx->expires_not_after) {
+ expires = ctx->expires_not_after;
+ }
+
+ ttl = expires - time(NULL);
+
+ if (ttl < 0) {
return (0);
+ }
return (ttl);
}
diff --git a/usr/src/lib/libadutils/common/addisc.h b/usr/src/lib/libadutils/common/addisc.h
index faf3393523..c8a3ca17d2 100644
--- a/usr/src/lib/libadutils/common/addisc.h
+++ b/usr/src/lib/libadutils/common/addisc.h
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _ADINFO_H
@@ -125,6 +124,12 @@ ad_disc_set_GlobalCatalog(ad_disc_t ctx,
*/
void ad_disc_refresh(ad_disc_t);
+/*
+ * This routine marks the end of a discovery cycle and sets
+ * the sanity limits on the time before the next cycle.
+ */
+void ad_disc_done(ad_disc_t);
+
/* This routine unsets all overridden values */
int ad_disc_unset(ad_disc_t ctx);
diff --git a/usr/src/lib/libadutils/common/mapfile-vers b/usr/src/lib/libadutils/common/mapfile-vers
index d7e1687ef2..e1e580bd9a 100644
--- a/usr/src/lib/libadutils/common/mapfile-vers
+++ b/usr/src/lib/libadutils/common/mapfile-vers
@@ -19,8 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
#
#
@@ -67,6 +66,7 @@ SUNWprivate {
ad_disc_compare_ds;
ad_disc_compare_trusteddomains;
ad_disc_compare_domainsinforest;
+ ad_disc_done;
ad_disc_SubnetChanged;
ad_disc_get_GlobalCatalog;
ad_disc_set_GlobalCatalog;
diff --git a/usr/src/lib/libidmap/Makefile.com b/usr/src/lib/libidmap/Makefile.com
index c38ff0bd02..5f5f3363b0 100644
--- a/usr/src/lib/libidmap/Makefile.com
+++ b/usr/src/lib/libidmap/Makefile.com
@@ -19,8 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
#
#
@@ -36,7 +35,6 @@ LINT_OBJECTS = \
idmap_api.o \
idmap_cache.o \
miscutils.o \
- namemaps.o \
utils.o
OBJECTS = $(LINT_OBJECTS) \
@@ -46,18 +44,15 @@ include ../../Makefile.lib
C99MODE = $(C99_ENABLE)
LIBS = $(DYNLIB) $(LINTLIB)
-LDLIBS += -lc -lldap -lsldap -lavl -ladutils -lnsl
-CPPFLAGS += -I$(SRC)/lib/libsldap/common
+LDLIBS += -lc -lavl -lnsl
SRCDIR = ../common
$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC)
IDMAP_PROT_X = $(SRC)/uts/common/rpcsvc/idmap_prot.x
-ADUTILS_DIR = $(SRC)/lib/libadutils/common
-
CFLAGS += $(CCVERBOSE)
-CPPFLAGS += -D_REENTRANT -I$(SRCDIR) -I$(ADUTILS_DIR)
+CPPFLAGS += -D_REENTRANT -I$(SRCDIR)
CLOBBERFILES += idmap_xdr.c
diff --git a/usr/src/lib/libidmap/common/directory_helper.c b/usr/src/lib/libidmap/common/directory_helper.c
index f98512d88e..a7c94f9aeb 100644
--- a/usr/src/lib/libidmap/common/directory_helper.c
+++ b/usr/src/lib/libidmap/common/directory_helper.c
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -34,7 +33,6 @@
#include <stdio.h>
#include <string.h>
-#include <libadutils.h>
#include <rpcsvc/idmap_prot.h>
#include "directory.h"
#include "directory_private.h"
diff --git a/usr/src/lib/libidmap/common/idmap.h b/usr/src/lib/libidmap/common/idmap.h
index f22fc43092..400f67c755 100644
--- a/usr/src/lib/libidmap/common/idmap.h
+++ b/usr/src/lib/libidmap/common/idmap.h
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -54,7 +53,7 @@ typedef struct idmap_handle idmap_handle_t;
typedef struct idmap_get_handle idmap_get_handle_t;
/* Logger prototype which is based on syslog */
-typedef void (*idmap_logger)(int, const char *, ...);
+typedef void (*idmap_logger_t)(int, const char *, ...);
/*
* Setup API
@@ -132,7 +131,7 @@ extern idmap_stat idmap_getgidbywinname(const char *, const char *,
/* Logger */
-extern void idmap_set_logger(idmap_logger funct);
+extern void idmap_set_logger(idmap_logger_t funct);
#ifdef __cplusplus
}
diff --git a/usr/src/lib/libidmap/common/idmap_api.c b/usr/src/lib/libidmap/common/idmap_api.c
index c58e2c00cd..6566de1db9 100644
--- a/usr/src/lib/libidmap/common/idmap_api.c
+++ b/usr/src/lib/libidmap/common/idmap_api.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -40,6 +39,7 @@
#include <dlfcn.h>
#include <libintl.h>
#include <ucontext.h>
+#include <syslog.h>
#include "idmap_impl.h"
#include "idmap_cache.h"
@@ -2581,3 +2581,18 @@ idmap_flush(idmap_handle_t *handle, idmap_flush_op op)
}
return (res);
}
+
+
+/*
+ * syslog is the default logger.
+ * It can be overwritten by supplying a logger
+ * with idmap_set_logger()
+ */
+idmap_logger_t logger = syslog;
+
+
+void
+idmap_set_logger(idmap_logger_t funct)
+{
+ logger = funct;
+}
diff --git a/usr/src/lib/libidmap/common/idmap_impl.h b/usr/src/lib/libidmap/common/idmap_impl.h
index 570b69834c..0c4aba0abb 100644
--- a/usr/src/lib/libidmap/common/idmap_impl.h
+++ b/usr/src/lib/libidmap/common/idmap_impl.h
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -129,12 +128,7 @@ extern idmap_stat _iter_get_next_list(int, idmap_iter_t *, void *,
uchar_t **, size_t, xdrproc_t, xdrproc_t);
extern idmap_stat _idmap_rpc2stat(CLIENT *);
-extern idmap_stat idmap_get_prop_ds(idmap_handle_t *, idmap_prop_type,
- idmap_ad_disc_ds_t *);
-extern idmap_stat idmap_get_prop_str(idmap_handle_t *, idmap_prop_type,
- char **);
-
-extern idmap_logger logger;
+extern idmap_logger_t logger;
#ifdef __cplusplus
}
diff --git a/usr/src/lib/libidmap/common/idmap_priv.h b/usr/src/lib/libidmap/common/idmap_priv.h
index d044225730..c3a68b76c9 100644
--- a/usr/src/lib/libidmap/common/idmap_priv.h
+++ b/usr/src/lib/libidmap/common/idmap_priv.h
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -65,29 +64,6 @@ typedef struct idmap_iter idmap_iter_t;
/*
- * Directory based name map API
- */
-
-typedef struct idmap_nm_handle idmap_nm_handle_t;
-
-/* Set namemap */
-extern idmap_stat idmap_set_namemap(idmap_nm_handle_t *, char *, char *,
- int, int, int);
-
-/* Unset namemap */
-extern idmap_stat idmap_unset_namemap(idmap_nm_handle_t *, char *, char *,
- int, int, int);
-
-extern idmap_stat idmap_get_namemap(idmap_nm_handle_t *p, int *, char **,
- char **, int *, char **, char **);
-
-extern void idmap_fini_namemaps(idmap_nm_handle_t *);
-
-extern idmap_stat idmap_init_namemaps(idmap_handle_t *, idmap_nm_handle_t **,
- char *, char *, char *, char *, int);
-
-
-/*
* Update API
*/
@@ -213,6 +189,11 @@ extern idmap_stat idmap_getext_sidbyuid(idmap_get_handle_t *, uid_t, int,
extern idmap_stat idmap_getext_sidbygid(idmap_get_handle_t *, gid_t, int,
char **, idmap_rid_t *, idmap_info *, idmap_stat *);
+/* Properties */
+extern idmap_stat idmap_get_prop_ds(idmap_handle_t *, idmap_prop_type,
+ idmap_ad_disc_ds_t *);
+extern idmap_stat idmap_get_prop_str(idmap_handle_t *, idmap_prop_type,
+ char **);
#ifdef __cplusplus
}
diff --git a/usr/src/lib/libidmap/common/mapfile-vers b/usr/src/lib/libidmap/common/mapfile-vers
index b0fc8c9cec..e52fa5da30 100644
--- a/usr/src/lib/libidmap/common/mapfile-vers
+++ b/usr/src/lib/libidmap/common/mapfile-vers
@@ -19,8 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
#
#
@@ -61,7 +60,6 @@ SUNWprivate {
directory_sid_from_user_name;
idmap_cache_get_data;
idmap_fini;
- idmap_fini_namemaps;
idmap_flush;
idmap_free;
idmap_getext_gidbysid;
@@ -77,8 +75,9 @@ SUNWprivate {
idmap_get_destroy;
idmap_get_gidbysid;
idmap_get_mappings;
- idmap_get_namemap;
idmap_get_pidbysid;
+ idmap_get_prop_ds;
+ idmap_get_prop_str;
idmap_get_sidbygid;
idmap_get_sidbyuid;
idmap_get_u2w_mapping;
@@ -88,7 +87,6 @@ SUNWprivate {
idmap_info_free;
idmap_info_mov;
idmap_init;
- idmap_init_namemaps;
idmap_iter_destroy;
idmap_iter_mappings;
idmap_iter_namerules;
@@ -96,7 +94,6 @@ SUNWprivate {
idmap_iter_next_namerule;
idmap_namerule_cpy;
idmap_set_logger;
- idmap_set_namemap;
idmap_stat2string;
idmap_stat4prot;
idmap_string2stat;
@@ -109,7 +106,6 @@ SUNWprivate {
idmap_udt_get_error_index;
idmap_udt_get_error_rule;
idmap_udt_rm_namerule;
- idmap_unset_namemap;
memdup;
sid_free;
sid_from_le;
diff --git a/usr/src/lib/libshare/smb/libshare_smb.c b/usr/src/lib/libshare/smb/libshare_smb.c
index 0994b48bb5..2fd55603fa 100644
--- a/usr/src/lib/libshare/smb/libshare_smb.c
+++ b/usr/src/lib/libshare/smb/libshare_smb.c
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -2312,6 +2311,9 @@ disposition_validator(int index, char *value)
* The properties are given as a list of name-value pair.
* The name argument should be the optionset property name and the value
* should be a valid value for the specified property.
+ *
+ * When calling this function for permanent shares, the caller must also
+ * call sa_commit_properties() to commit the changes to SMF.
*/
static int
smb_update_optionset_props(sa_handle_t handle, sa_resource_t resource,
@@ -2361,9 +2363,6 @@ smb_update_optionset_props(sa_handle_t handle, sa_resource_t resource,
cur = nvlist_next_nvpair(nvl, cur);
}
- if (err == SA_OK)
- err = sa_commit_properties(opts, 0);
-
return (err);
}
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/libmlrpc.h b/usr/src/lib/smbsrv/libmlrpc/common/libmlrpc.h
index 5ab647c0eb..7a5f3627f7 100644
--- a/usr/src/lib/smbsrv/libmlrpc/common/libmlrpc.h
+++ b/usr/src/lib/smbsrv/libmlrpc/common/libmlrpc.h
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _LIBMLRPC_H
@@ -159,18 +158,21 @@ extern "C" {
#define NDR_DRC_FAULT_OUT_OF_MEMORY 0xF000
/* RPCHDR */
+#define NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH 0x81FF
+#define NDR_DRC_FAULT_RPCHDR_RECEIVED_RUNT 0x83FF
+#define NDR_DRC_FAULT_RPCHDR_DECODE_FAILED 0x86FF
#define NDR_DRC_FAULT_RPCHDR_PTYPE_INVALID 0xC0FF /* PARAM_0_INVALID */
-#define NDR_DRC_FAULT_RPCHDR_PTYPE_UNIMPLEMENTED 0xD0FF /* PARAM_0_UNIMP */
+#define NDR_DRC_FAULT_RPCHDR_PTYPE_UNIMPLEMENTED 0xD0FF /* PARAM_0_UNIMP */
/* Request */
#define NDR_DRC_FAULT_REQUEST_PCONT_INVALID 0xC000 /* PARAM_0_INVALID */
#define NDR_DRC_FAULT_REQUEST_OPNUM_INVALID 0xC100 /* PARAM_1_INVALID */
/* Bind */
+#define NDR_DRC_BINDING_MADE 0x000B /* OK */
#define NDR_DRC_FAULT_BIND_PCONT_BUSY 0xC00B /* PARAM_0_INVALID */
#define NDR_DRC_FAULT_BIND_UNKNOWN_SERVICE 0xC10B /* PARAM_1_INVALID */
#define NDR_DRC_FAULT_BIND_NO_SLOTS 0x910B /* RESOURCE_1 */
-#define NDR_DRC_BINDING_MADE 0x000B /* OK */
/* API */
#define NDR_DRC_FAULT_API_SERVICE_INVALID 0xC0AA /* PARAM_0_INVALID */
@@ -502,7 +504,8 @@ void ndr_clnt_free_heap(ndr_client_t *);
/* ndr_marshal.c */
ndr_buf_t *ndr_buf_init(ndr_typeinfo_t *);
void ndr_buf_fini(ndr_buf_t *);
-int ndr_buf_decode(ndr_buf_t *, unsigned, const char *data, size_t, void *);
+int ndr_buf_decode(ndr_buf_t *, unsigned, unsigned, const char *data, size_t,
+ void *);
int ndr_decode_call(ndr_xa_t *, void *);
int ndr_encode_return(ndr_xa_t *, void *);
int ndr_encode_call(ndr_xa_t *, void *);
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c b/usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c
index 12fd0c0d52..a690dfb2e9 100644
--- a/usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c
+++ b/usr/src/lib/smbsrv/libmlrpc/common/ndr_marshal.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <assert.h>
@@ -37,6 +36,7 @@ static const int ndr_native_byte_order = NDR_REPLAB_INTG_LITTLE_ENDIAN;
#endif
static int ndr_decode_hdr_common(ndr_stream_t *, ndr_common_header_t *);
+static int ndr_decode_pac_hdr(ndr_stream_t *, ndr_pac_hdr_t *);
static int
ndr_encode_decode_common(ndr_stream_t *nds, unsigned opnum,
@@ -122,10 +122,11 @@ ndr_buf_fini(ndr_buf_t *nbuf)
* }
*/
int
-ndr_buf_decode(ndr_buf_t *nbuf, unsigned opnum, const char *data,
- size_t datalen, void *result)
+ndr_buf_decode(ndr_buf_t *nbuf, unsigned hdr_type, unsigned opnum,
+ const char *data, size_t datalen, void *result)
{
ndr_common_header_t hdr;
+ ndr_pac_hdr_t pac_hdr;
unsigned pdu_size_hint;
int rc;
@@ -145,12 +146,28 @@ ndr_buf_decode(ndr_buf_t *nbuf, unsigned opnum, const char *data,
bcopy(data, nbuf->nb_nds.pdu_base_addr, datalen);
- rc = ndr_decode_hdr_common(&nbuf->nb_nds, &hdr);
- if (NDR_DRC_IS_FAULT(rc))
- return (rc);
+ switch (hdr_type) {
+ case NDR_PTYPE_COMMON:
+ rc = ndr_decode_hdr_common(&nbuf->nb_nds, &hdr);
+ if (NDR_DRC_IS_FAULT(rc))
+ return (rc);
+
+ if (!NDR_IS_SINGLE_FRAG(hdr.pfc_flags))
+ return (NDR_DRC_FAULT_DECODE_FAILED);
+ break;
+
+ case NDR_PTYPE_PAC:
+ rc = ndr_decode_pac_hdr(&nbuf->nb_nds, &pac_hdr);
+ if (NDR_DRC_IS_FAULT(rc))
+ return (rc);
- if (!NDR_IS_SINGLE_FRAG(hdr.pfc_flags))
- return (NDR_DRC_FAULT_DECODE_FAILED);
+ if (pac_hdr.common_hdr.hdrlen != sizeof (ndr_serialtype1_hdr_t))
+ return (NDR_DRC_FAULT_DECODE_FAILED);
+ break;
+
+ default:
+ return (NDR_ERR_UNIMPLEMENTED);
+ }
rc = ndr_encode_decode_common(&nbuf->nb_nds, opnum, nbuf->nb_ti,
result);
@@ -244,7 +261,7 @@ ndr_decode_pdu_hdr(ndr_xa_t *mxa)
* Verify the protocol version.
*/
if ((hdr->rpc_vers != 5) || (hdr->rpc_vers_minor != 0))
- return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_DECODE_FAILED));
+ return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED);
mxa->ptype = hdr->ptype;
return (NDR_DRC_OK);
@@ -259,21 +276,21 @@ ndr_decode_hdr_common(ndr_stream_t *nds, ndr_common_header_t *hdr)
int byte_order;
if (nds->m_op != NDR_M_OP_UNMARSHALL)
- return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_MODE_MISMATCH));
+ return (NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH);
/*
* All PDU headers are at least this big
*/
rc = NDS_GROW_PDU(nds, sizeof (ndr_common_header_t), 0);
if (!rc)
- return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_RECEIVED_RUNT));
+ return (NDR_DRC_FAULT_RPCHDR_RECEIVED_RUNT);
/*
* Peek at the first eight bytes to figure out what we're doing.
*/
rc = NDS_GET_PDU(nds, 0, 8, (char *)hdr, 0, 0);
if (!rc)
- return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_DECODE_FAILED));
+ return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED);
/*
* Check for ASCII as the character set. This is an ASCII
@@ -281,7 +298,7 @@ ndr_decode_hdr_common(ndr_stream_t *nds, ndr_common_header_t *hdr)
*/
charset = hdr->packed_drep.intg_char_rep & NDR_REPLAB_CHAR_MASK;
if (charset != NDR_REPLAB_CHAR_ASCII)
- return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_DECODE_FAILED));
+ return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED);
/*
* Set the byte swap flag if the PDU byte-order
@@ -301,6 +318,45 @@ ndr_decode_hdr_common(ndr_stream_t *nds, ndr_common_header_t *hdr)
return (NDR_DRC_PTYPE_RPCHDR(rc));
}
+static int
+ndr_decode_pac_hdr(ndr_stream_t *nds, ndr_pac_hdr_t *hdr)
+{
+ int rc;
+
+ if (nds->m_op != NDR_M_OP_UNMARSHALL)
+ return (NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH);
+
+ /*
+ * All PDU headers are at least this big
+ */
+ rc = NDS_GROW_PDU(nds, sizeof (ndr_pac_hdr_t), 0);
+ if (!rc)
+ return (NDR_DRC_FAULT_RPCHDR_RECEIVED_RUNT);
+
+ /*
+ * Peek at the first eight bytes to figure out what we're doing.
+ */
+ rc = NDS_GET_PDU(nds, 0, 8, (char *)hdr, 0, 0);
+ if (!rc)
+ return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED);
+
+ /* Must be set to 1 to indicate type serialization version 1. */
+ if (hdr->common_hdr.version != 1)
+ return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED);
+
+ /*
+ * Set the byte swap flag if the PDU byte-order
+ * is different from the local byte-order.
+ */
+ nds->swap =
+ (hdr->common_hdr.endianness != ndr_native_byte_order) ? 1 : 0;
+
+ rc = ndr_encode_decode_common(nds, NDR_PTYPE_PAC,
+ &TYPEINFO(ndr_hdr), hdr);
+
+ return (NDR_DRC_PTYPE_RPCHDR(rc));
+}
+
/*
* Decode an RPC fragment header. Use ndr_decode_pdu_hdr() to process
* the first fragment header then this function to process additional
@@ -400,7 +456,7 @@ ndr_encode_pdu_hdr(ndr_xa_t *mxa)
int rc;
if (nds->m_op != NDR_M_OP_MARSHALL)
- return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_MODE_MISMATCH));
+ return (NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH);
ptype = hdr->ptype;
if (ptype == NDR_PTYPE_REQUEST &&
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c b/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c
index e4c1f50eae..109a29801f 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/samr_svc.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -37,7 +36,7 @@
#include <unistd.h>
#include <netdb.h>
#include <assert.h>
-
+#include <grp.h>
#include <smbsrv/libsmb.h>
#include <smbsrv/libmlrpc.h>
#include <smbsrv/libmlsvc.h>
@@ -897,6 +896,193 @@ samr_s_OpenGroup(void *arg, ndr_xa_t *mxa)
}
/*
+ * samr_s_AddAliasMember
+ *
+ * Add a member to a local SAM group.
+ * The caller must supply a valid group handle.
+ * The member is specified by the sid in the request.
+ */
+static int
+samr_s_AddAliasMember(void *arg, ndr_xa_t *mxa)
+{
+ struct samr_AddAliasMember *param = arg;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->alias_handle;
+ ndr_handle_t *hd;
+ samr_keydata_t *data;
+ smb_group_t grp;
+ uint32_t rc;
+ uint32_t status = NT_STATUS_SUCCESS;
+
+ if (param->sid == NULL) {
+ bzero(param, sizeof (struct samr_AddAliasMember));
+ param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
+ return (NDR_DRC_OK);
+ }
+
+ if (!ndr_is_admin(mxa)) {
+ bzero(param, sizeof (struct samr_AddAliasMember));
+ param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
+ return (NDR_DRC_OK);
+ }
+
+
+ if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) {
+ bzero(param, sizeof (struct samr_AddAliasMember));
+ param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
+ return (NDR_DRC_OK);
+ }
+
+ data = (samr_keydata_t *)hd->nh_data;
+ rc = smb_lgrp_getbyrid(data->kd_rid, data->kd_type, &grp);
+ if (rc != SMB_LGRP_SUCCESS) {
+ bzero(param, sizeof (struct samr_AddAliasMember));
+ status = smb_lgrp_err_to_ntstatus(rc);
+ param->status = NT_SC_ERROR(status);
+ return (NDR_DRC_OK);
+ }
+
+ rc = smb_lgrp_add_member(grp.sg_name,
+ (smb_sid_t *)param->sid, SidTypeUser);
+ if (rc != SMB_LGRP_SUCCESS) {
+ bzero(param, sizeof (struct samr_AddAliasMember));
+ status = smb_lgrp_err_to_ntstatus(rc);
+ param->status = NT_SC_ERROR(status);
+ }
+ smb_lgrp_free(&grp);
+
+ param->status = status;
+ return (NDR_DRC_OK);
+}
+
+/*
+ * samr_s_DeleteAliasMember
+ *
+ * Delete a member from a local SAM group.
+ * The caller must supply a valid group handle.
+ * The member is specified by the sid in the request.
+ */
+static int
+samr_s_DeleteAliasMember(void *arg, ndr_xa_t *mxa)
+{
+ struct samr_DeleteAliasMember *param = arg;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->alias_handle;
+ ndr_handle_t *hd;
+ samr_keydata_t *data;
+ smb_group_t grp;
+ uint32_t rc;
+ uint32_t status = NT_STATUS_SUCCESS;
+
+ if (param->sid == NULL) {
+ bzero(param, sizeof (struct samr_DeleteAliasMember));
+ param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
+ return (NDR_DRC_OK);
+ }
+
+ if (!ndr_is_admin(mxa)) {
+ bzero(param, sizeof (struct samr_DeleteAliasMember));
+ param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
+ return (NDR_DRC_OK);
+ }
+
+ if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) {
+ bzero(param, sizeof (struct samr_DeleteAliasMember));
+ param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
+ return (NDR_DRC_OK);
+ }
+
+ data = (samr_keydata_t *)hd->nh_data;
+ rc = smb_lgrp_getbyrid(data->kd_rid, data->kd_type, &grp);
+ if (rc != SMB_LGRP_SUCCESS) {
+ bzero(param, sizeof (struct samr_DeleteAliasMember));
+ status = smb_lgrp_err_to_ntstatus(rc);
+ param->status = NT_SC_ERROR(status);
+ return (NDR_DRC_OK);
+ }
+
+ rc = smb_lgrp_del_member(grp.sg_name,
+ (smb_sid_t *)param->sid, SidTypeUser);
+ if (rc != SMB_LGRP_SUCCESS) {
+ bzero(param, sizeof (struct samr_DeleteAliasMember));
+ status = smb_lgrp_err_to_ntstatus(rc);
+ param->status = NT_SC_ERROR(status);
+ }
+ smb_lgrp_free(&grp);
+
+ param->status = status;
+ return (NDR_DRC_OK);
+}
+
+/*
+ * samr_s_ListAliasMembers
+ *
+ * List members from a local SAM group.
+ * The caller must supply a valid group handle.
+ * A list of user SIDs in the specified group is returned to the caller.
+ */
+static int
+samr_s_ListAliasMembers(void *arg, ndr_xa_t *mxa)
+{
+ struct samr_ListAliasMembers *param = arg;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->alias_handle;
+ ndr_handle_t *hd;
+ samr_keydata_t *data;
+ smb_group_t grp;
+ smb_gsid_t *members;
+ struct samr_SidInfo info;
+ struct samr_SidList *user;
+ uint32_t num = 0, size;
+ int i;
+ uint32_t rc;
+ uint32_t status = NT_STATUS_SUCCESS;
+
+ if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) {
+ bzero(param, sizeof (struct samr_ListAliasMembers));
+ param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
+ return (NDR_DRC_OK);
+ }
+
+ bzero(&info, sizeof (struct samr_SidInfo));
+ data = (samr_keydata_t *)hd->nh_data;
+ rc = smb_lgrp_getbyrid(data->kd_rid, data->kd_type, &grp);
+ if (rc != SMB_LGRP_SUCCESS) {
+ bzero(param, sizeof (struct samr_ListAliasMembers));
+ status = smb_lgrp_err_to_ntstatus(rc);
+ param->status = NT_SC_ERROR(status);
+ return (NDR_DRC_OK);
+ }
+
+ num = grp.sg_nmembers;
+ members = grp.sg_members;
+ size = num * sizeof (struct samr_SidList);
+ info.sidlist = NDR_MALLOC(mxa, size);
+ if (info.sidlist == NULL) {
+ bzero(param, sizeof (struct samr_ListAliasMembers));
+ param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
+ smb_lgrp_free(&grp);
+ return (NDR_DRC_OK);
+ }
+
+ info.n_entry = num;
+ user = info.sidlist;
+ for (i = 0; i < num; i++) {
+ user->sid = (struct samr_sid *)NDR_SIDDUP(mxa,
+ members[i].gs_sid);
+ if (user->sid == NULL) {
+ bzero(param, sizeof (struct samr_ListAliasMembers));
+ param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
+ smb_lgrp_free(&grp);
+ return (NDR_DRC_OK);
+ }
+ user++;
+ }
+ smb_lgrp_free(&grp);
+
+ param->info = info;
+ param->status = status;
+ return (NDR_DRC_OK);
+}
+
+/*
* samr_s_Connect
*
* This is a request to connect to the local SAM database.
@@ -1220,7 +1406,7 @@ samr_s_OpenAlias(void *arg, ndr_xa_t *mxa)
goto open_alias_err;
}
- if (param->access_mask != SAMR_ALIAS_ACCESS_GET_INFO) {
+ if ((param->access_mask & SAMR_ALIAS_ACCESS_ALL_ACCESS) == 0) {
status = NT_STATUS_ACCESS_DENIED;
goto open_alias_err;
}
@@ -1278,70 +1464,75 @@ open_alias_err:
/*
* samr_s_CreateDomainAlias
*
- * Creates a local group in the security database, which is the
- * security accounts manager (SAM)
- * For more information you can look at MSDN page for NetLocalGroupAdd.
- * This RPC is used by CMC and right now it returns access denied.
- * The peice of code that creates a local group doesn't get compiled.
+ * Create a local group in the security accounts manager (SAM) database.
+ * A local SAM group can only be added if a Solaris group already exists
+ * with the same name. On success, a valid group handle is returned.
+ *
+ * The caller must have administrator rights to execute this function.
*/
-/*ARGSUSED*/
static int
samr_s_CreateDomainAlias(void *arg, ndr_xa_t *mxa)
{
struct samr_CreateDomainAlias *param = arg;
ndr_hdid_t *id = (ndr_hdid_t *)&param->alias_handle;
+ uint32_t status = NT_STATUS_SUCCESS;
+ smb_group_t grp;
+ uint32_t rc;
+ char *gname;
- if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) == NULL) {
+ if (samr_hdlookup(mxa, id, SAMR_KEY_DOMAIN) != NULL) {
bzero(param, sizeof (struct samr_CreateDomainAlias));
param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
return (NDR_DRC_OK);
}
- bzero(param, sizeof (struct samr_CreateDomainAlias));
- param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
- return (NDR_DRC_OK);
-
-#ifdef SAMR_SUPPORT_ADD_ALIAS
- DWORD status = NT_STATUS_SUCCESS;
- nt_group_t *grp;
- char *alias_name;
-
- alias_name = param->alias_name.str;
- if (alias_name == 0) {
- status = NT_STATUS_INVALID_PARAMETER;
- goto create_alias_err;
+ gname = (char *)param->alias_name.str;
+ if (gname == NULL) {
+ bzero(&param->alias_handle, sizeof (samr_handle_t));
+ param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
+ return (NDR_DRC_OK);
}
- /*
- * Check access mask. User should be member of
- * Administrators or Account Operators local group.
- */
- status = nt_group_add(alias_name, 0,
- NT_GROUP_AF_ADD | NT_GROUP_AF_LOCAL);
+ if ((!ndr_is_admin(mxa)) ||
+ ((param->access_mask & SAMR_ALIAS_ACCESS_WRITE_ACCOUNT) == 0)) {
+ bzero(&param->alias_handle, sizeof (samr_handle_t));
+ param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
+ return (NDR_DRC_OK);
+ }
- if (status != NT_STATUS_SUCCESS)
- goto create_alias_err;
+ if (getgrnam(gname) == NULL) {
+ bzero(&param->alias_handle, sizeof (samr_handle_t));
+ param->status = NT_SC_ERROR(NT_STATUS_INVALID_PARAMETER);
+ return (NDR_DRC_OK);
+ }
- grp = nt_group_getinfo(alias_name, RWLOCK_READER);
- if (grp == NULL) {
- status = NT_STATUS_INTERNAL_ERROR;
- goto create_alias_err;
+ rc = smb_lgrp_add(gname, "");
+ if (rc != SMB_LGRP_SUCCESS) {
+ bzero(&param->alias_handle, sizeof (samr_handle_t));
+ status = smb_lgrp_err_to_ntstatus(rc);
+ param->status = NT_SC_ERROR(status);
+ return (NDR_DRC_OK);
}
- (void) smb_sid_getrid(grp->sid, &param->rid);
- nt_group_putinfo(grp);
- handle = mlsvc_get_handle(MLSVC_IFSPEC_SAMR, SAMR_ALIAS_KEY,
- param->rid);
- bcopy(handle, &param->alias_handle, sizeof (samr_handle_t));
+ rc = smb_lgrp_getbyname((char *)gname, &grp);
+ if (rc != SMB_LGRP_SUCCESS) {
+ bzero(&param->alias_handle, sizeof (samr_handle_t));
+ status = smb_lgrp_err_to_ntstatus(rc);
+ param->status = NT_SC_ERROR(status);
+ return (NDR_DRC_OK);
+ }
- param->status = 0;
- return (NDR_DRC_OK);
+ id = samr_hdalloc(mxa, SAMR_KEY_ALIAS, SMB_DOMAIN_LOCAL, grp.sg_rid);
+ smb_lgrp_free(&grp);
+ if (id) {
+ bcopy(id, &param->alias_handle, sizeof (samr_handle_t));
+ param->status = status;
+ } else {
+ bzero(&param->alias_handle, sizeof (samr_handle_t));
+ param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
+ }
-create_alias_err:
- bzero(&param->alias_handle, sizeof (samr_handle_t));
- param->status = NT_SC_ERROR(status);
return (NDR_DRC_OK);
-#endif
}
/*
@@ -1471,60 +1662,72 @@ query_alias_err:
/*
* samr_s_DeleteDomainAlias
*
- * Deletes a local group account and all its members from the
- * security database, which is the security accounts manager (SAM) database.
- * Only members of the Administrators or Account Operators local group can
- * execute this function.
- * For more information you can look at MSDN page for NetLocalGroupSetInfo.
+ * Deletes a local group in the security database, which is the
+ * security accounts manager (SAM). A valid group handle is returned
+ * to the caller upon success.
*
- * This RPC is used by CMC and right now it returns access denied.
- * The peice of code that removes a local group doesn't get compiled.
+ * The caller must have administrator rights to execute this function.
*/
static int
samr_s_DeleteDomainAlias(void *arg, ndr_xa_t *mxa)
{
struct samr_DeleteDomainAlias *param = arg;
ndr_hdid_t *id = (ndr_hdid_t *)&param->alias_handle;
+ ndr_handle_t *hd;
+ smb_group_t grp;
+ samr_keydata_t *data;
+ smb_domain_type_t gd_type;
+ uint32_t rid;
+ uint32_t rc;
+ uint32_t status = NT_STATUS_SUCCESS;
- if (samr_hdlookup(mxa, id, SAMR_KEY_ALIAS) == NULL) {
+ if (!ndr_is_admin(mxa)) {
bzero(param, sizeof (struct samr_DeleteDomainAlias));
- param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
+ param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
return (NDR_DRC_OK);
}
- bzero(param, sizeof (struct samr_DeleteDomainAlias));
- param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
- return (NDR_DRC_OK);
+ if ((hd = samr_hdlookup(mxa, id, SAMR_KEY_ALIAS)) == NULL) {
+ bzero(param, sizeof (struct samr_DeleteDomainAlias));
+ param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
+ return (NDR_DRC_OK);
+ }
-#ifdef SAMR_SUPPORT_DEL_ALIAS
- nt_group_t *grp;
- char *alias_name;
- DWORD status;
+ data = (samr_keydata_t *)hd->nh_data;
+ gd_type = (smb_domain_type_t)data->kd_type;
+ rid = data->kd_rid;
- grp = nt_groups_lookup_rid(desc->discrim);
- if (grp == 0) {
- status = NT_STATUS_NO_SUCH_ALIAS;
- goto delete_alias_err;
- }
+ switch (gd_type) {
+ case SMB_DOMAIN_BUILTIN:
+ bzero(param, sizeof (struct samr_DeleteDomainAlias));
+ status = NT_SC_ERROR(NT_STATUS_NOT_SUPPORTED);
+ break;
- alias_name = strdup(grp->name);
- if (alias_name == 0) {
- status = NT_STATUS_NO_MEMORY;
- goto delete_alias_err;
- }
+ case SMB_DOMAIN_LOCAL:
+ rc = smb_lgrp_getbyrid(rid, gd_type, &grp);
+ if (rc != SMB_LGRP_SUCCESS) {
+ bzero(param, sizeof (struct samr_DeleteDomainAlias));
+ status = smb_lgrp_err_to_ntstatus(rc);
+ status = NT_SC_ERROR(status);
+ break;
+ }
- status = nt_group_delete(alias_name);
- free(alias_name);
- if (status != NT_STATUS_SUCCESS)
- goto delete_alias_err;
+ rc = smb_lgrp_delete(grp.sg_name);
+ if (rc != SMB_LGRP_SUCCESS) {
+ bzero(param, sizeof (struct samr_DeleteDomainAlias));
+ status = smb_lgrp_err_to_ntstatus(rc);
+ status = NT_SC_ERROR(status);
+ }
+ smb_lgrp_free(&grp);
+ break;
- param->status = 0;
- return (NDR_DRC_OK);
+ default:
+ bzero(param, sizeof (struct samr_DeleteDomainAlias));
+ status = NT_SC_ERROR(NT_STATUS_NO_SUCH_ALIAS);
+ }
-delete_alias_err:
- param->status = NT_SC_ERROR(status);
+ param->status = status;
return (NDR_DRC_OK);
-#endif
}
/*
@@ -1677,6 +1880,9 @@ static ndr_stub_table_t samr_stub_table[] = {
{ samr_s_DeleteDomainAlias, SAMR_OPNUM_DeleteDomainAlias },
{ samr_s_EnumDomainAliases, SAMR_OPNUM_EnumDomainAliases },
{ samr_s_EnumDomainGroups, SAMR_OPNUM_EnumDomainGroups },
+ { samr_s_AddAliasMember, SAMR_OPNUM_AddAliasMember },
+ { samr_s_DeleteAliasMember, SAMR_OPNUM_DeleteAliasMember },
+ { samr_s_ListAliasMembers, SAMR_OPNUM_ListAliasMembers },
{0}
};
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/smb_autohome.c b/usr/src/lib/smbsrv/libmlsvc/common/smb_autohome.c
index 47633a26d4..a82bbae956 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/smb_autohome.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/smb_autohome.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <sys/param.h>
@@ -28,9 +27,11 @@
#include <stdlib.h>
#include <stdio.h>
#include <pwd.h>
+#include <nss_dbdefs.h>
#include <assert.h>
#include <strings.h>
#include <sys/stat.h>
+#include <sys/idmap.h>
#include <smbsrv/libsmb.h>
#include <smbsrv/libmlsvc.h>
#include <smbsrv/smbinfo.h>
@@ -59,6 +60,7 @@ static void smb_autohome_setent(void);
static void smb_autohome_endent(void);
static smb_autohome_t *smb_autohome_getent(const char *);
static void smb_autohome_parse_options(smb_share_t *);
+static int smb_autohome_add_private(const char *, uid_t, gid_t);
/*
* Add an autohome share. See smb_autohome(4) for details.
@@ -73,32 +75,85 @@ static void smb_autohome_parse_options(smb_share_t *);
void
smb_autohome_add(const smb_token_t *token)
{
+
+ char *username;
+ struct passwd pw;
+ char buf[NSS_LINELEN_PASSWD];
+ uid_t uid;
+ gid_t gid;
+
+ uid = token->tkn_user.i_id;
+ gid = token->tkn_primary_grp.i_id;
+
+ if (IDMAP_ID_IS_EPHEMERAL(uid)) {
+ username = token->tkn_account_name;
+ assert(username);
+ } else {
+ if (getpwuid_r(uid, &pw, buf, sizeof (buf)) == NULL) {
+ syslog(LOG_ERR, "unable to determine name for " \
+ "UID: %u\n", uid);
+ return;
+ }
+ username = pw.pw_name;
+ }
+
+ if (smb_autohome_add_private(username, uid, gid) != NERR_Success) {
+ if (!smb_isstrlwr(username)) {
+ (void) smb_strlwr(username);
+ (void) smb_autohome_add_private(username, uid, gid);
+ }
+ }
+}
+
+/*
+ * Remove an autohome share.
+ */
+void
+smb_autohome_remove(const char *username)
+{
+ smb_share_t si;
+
+ assert(username);
+
+ if (smb_shr_get((char *)username, &si) == NERR_Success) {
+ if (si.shr_flags & SMB_SHRF_AUTOHOME)
+ (void) smb_shr_remove((char *)username);
+ }
+}
+
+/*
+ * An autohome share is not created if a static share using the same name
+ * already exists. Autohome shares will be added for each login attempt.
+ *
+ * Calling smb_shr_get() may return the first argument in all lower case so
+ * a copy is passed in instead.
+ *
+ * We need to serialize calls to smb_autohome_lookup because it
+ * operates on the global smb_ai structure.
+ */
+static int
+smb_autohome_add_private(const char *username, uid_t uid, gid_t gid)
+{
static mutex_t autohome_mutex;
smb_share_t si;
smb_autohome_t *ai;
- char *username = token->tkn_account_name;
+ char shr_name[MAXNAMELEN];
- assert(username);
+ (void) strlcpy(shr_name, username, sizeof (shr_name));
- if (smb_shr_get((char *)username, &si) == NERR_Success) {
- /*
- * A static share with this name already exists
- */
+ if (smb_shr_get(shr_name, &si) == NERR_Success) {
if ((si.shr_flags & SMB_SHRF_AUTOHOME) == 0)
- return;
+ return (NERR_Success);
- /*
- * autohome shares will be added for each login attempt
- */
(void) smb_shr_add(&si);
- return;
+ return (NERR_Success);
}
(void) mutex_lock(&autohome_mutex);
if ((ai = smb_autohome_lookup(username)) == NULL) {
(void) mutex_unlock(&autohome_mutex);
- return;
+ return (NERR_ItemNotFound);
}
bzero(&si, sizeof (smb_share_t));
@@ -110,28 +165,12 @@ smb_autohome_add(const smb_token_t *token)
(void) strlcpy(si.shr_cmnt, "Autohome", SMB_SHARE_CMNT_MAX);
smb_autohome_parse_options(&si);
si.shr_flags |= SMB_SHRF_TRANS | SMB_SHRF_AUTOHOME;
- si.shr_uid = token->tkn_user.i_id;
- si.shr_gid = token->tkn_primary_grp.i_id;
+ si.shr_uid = uid;
+ si.shr_gid = gid;
(void) mutex_unlock(&autohome_mutex);
- (void) smb_shr_add(&si);
-}
-
-/*
- * Remove an autohome share.
- */
-void
-smb_autohome_remove(const char *username)
-{
- smb_share_t si;
-
- assert(username);
-
- if (smb_shr_get((char *)username, &si) == NERR_Success) {
- if (si.shr_flags & SMB_SHRF_AUTOHOME)
- (void) smb_shr_remove((char *)username);
- }
+ return (smb_shr_add(&si));
}
/*
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/smb_quota.c b/usr/src/lib/smbsrv/libmlsvc/common/smb_quota.c
index 6d99db1764..9f3932d5d1 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/smb_quota.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/smb_quota.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <stdio.h>
#include <stdlib.h>
@@ -132,7 +131,7 @@ typedef struct smb_quota_tree {
static list_t smb_quota_fs_list;
static boolean_t smb_quota_list_init = B_FALSE;
static boolean_t smb_quota_shutdown = B_FALSE;
-static mutex_t smb_quota_list_mutex;
+static mutex_t smb_quota_list_mutex = DEFAULTMUTEX;
static cond_t smb_quota_list_condvar;
static uint32_t smb_quota_tree_cnt = 0;
static int smb_quota_fini_timeout = 1; /* seconds */
@@ -238,7 +237,7 @@ smb_quota_fini(void)
(void) cond_broadcast(&smb_quota_list_condvar);
- while (smb_quota_tree_cnt != 0) {
+ while (!list_is_empty(&smb_quota_fs_list)) {
qtree = list_head(&smb_quota_fs_list);
while (qtree != NULL) {
qtree_next = list_next(&smb_quota_fs_list, qtree);
@@ -257,7 +256,7 @@ smb_quota_fini(void)
qtree = qtree_next;
}
- if (smb_quota_tree_cnt != 0) {
+ if (!list_is_empty(&smb_quota_fs_list)) {
if (cond_reltimedwait(&smb_quota_list_condvar,
&smb_quota_list_mutex, &tswait) == ETIME) {
syslog(LOG_WARNING,
@@ -823,7 +822,7 @@ smb_quota_tree_create(const char *path)
assert(MUTEX_HELD(&smb_quota_list_mutex));
- qtree = malloc(sizeof (smb_quota_tree_t));
+ qtree = calloc(sizeof (smb_quota_tree_t), 1);
if (qtree == NULL)
return (NULL);
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/smb_share.c b/usr/src/lib/smbsrv/libmlsvc/common/smb_share.c
index a2ce2eb8c0..5c7154b82d 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/smb_share.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/smb_share.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -43,6 +42,7 @@
#include <unistd.h>
#include <pwd.h>
#include <signal.h>
+#include <dirent.h>
#include <smbsrv/libsmb.h>
#include <smbsrv/libsmbns.h>
@@ -55,6 +55,20 @@
#define SMB_SHR_ERROR_THRESHOLD 3
#define SMB_SHR_CSC_BUFSZ 64
+typedef struct smb_transient {
+ char *name;
+ char *cmnt;
+ char *path;
+ char drive;
+ boolean_t check;
+} smb_transient_t;
+
+static smb_transient_t tshare[] = {
+ { "IPC$", "Remote IPC", NULL, '\0', B_FALSE },
+ { "c$", "Default Share", SMB_CVOL, 'C', B_FALSE },
+ { "vss$", "VSS", SMB_VSS, 'V', B_TRUE }
+};
+
static struct {
char *value;
uint32_t flag;
@@ -117,6 +131,9 @@ static uint32_t smb_shr_cache_addent(smb_share_t *);
static void smb_shr_cache_delent(char *);
static void smb_shr_cache_freent(HT_ITEM *);
+static boolean_t smb_shr_is_empty(const char *);
+static boolean_t smb_shr_is_dot_or_dotdot(const char *);
+
/*
* sharemgr functions
*/
@@ -219,16 +236,9 @@ static sema_t smb_proc_sem = DEFAULTSEMA;
int
smb_shr_start(void)
{
- int i;
- static struct tshare {
- char *name;
- char *cmnt;
- char *path;
- } tshare[] = {
- { "IPC$", "Remote IPC", NULL },
- { "c$", "Default Share", SMB_CVOL },
- { "vss$", "VSS Share", SMB_VSS }
- };
+ smb_transient_t *ts;
+ uint32_t nerr;
+ int i;
(void) mutex_lock(&smb_sa_handle.sa_mtx);
smb_sa_handle.sa_in_service = B_TRUE;
@@ -238,8 +248,13 @@ smb_shr_start(void)
return (ENOMEM);
for (i = 0; i < sizeof (tshare)/sizeof (tshare[0]); ++i) {
- if (smb_shr_add_transient(tshare[i].name,
- tshare[i].cmnt, tshare[i].path) != NERR_Success)
+ ts = &tshare[i];
+
+ if (ts->check && smb_shr_is_empty(ts->path))
+ continue;
+
+ nerr = smb_shr_add_transient(ts->name, ts->cmnt, ts->path);
+ if (nerr != NERR_Success)
return (ENOMEM);
}
@@ -850,6 +865,68 @@ smb_shr_is_admin(char *sharename)
return (B_FALSE);
}
+char
+smb_shr_drive_letter(const char *path)
+{
+ smb_transient_t *ts;
+ int i;
+
+ if (path == NULL)
+ return ('\0');
+
+ for (i = 0; i < sizeof (tshare)/sizeof (tshare[0]); ++i) {
+ ts = &tshare[i];
+
+ if (ts->path == NULL)
+ continue;
+
+ if (strcasecmp(ts->path, path) == 0)
+ return (ts->drive);
+ }
+
+ return ('\0');
+}
+
+/*
+ * Returns true if the specified directory is empty,
+ * otherwise returns false.
+ */
+static boolean_t
+smb_shr_is_empty(const char *path)
+{
+ DIR *dirp;
+ struct dirent *dp;
+
+ if (path == NULL)
+ return (B_TRUE);
+
+ if ((dirp = opendir(path)) == NULL)
+ return (B_TRUE);
+
+ while ((dp = readdir(dirp)) != NULL) {
+ if (!smb_shr_is_dot_or_dotdot(dp->d_name))
+ return (B_FALSE);
+ }
+
+ (void) closedir(dirp);
+ return (B_TRUE);
+}
+
+/*
+ * Returns true if name is "." or "..", otherwise returns false.
+ */
+static boolean_t
+smb_shr_is_dot_or_dotdot(const char *name)
+{
+ if (*name != '.')
+ return (B_FALSE);
+
+ if ((name[1] == '\0') || (name[1] == '.' && name[2] == '\0'))
+ return (B_TRUE);
+
+ return (B_FALSE);
+}
+
/*
* smb_shr_get_realpath
*
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_svc.c b/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_svc.c
index 8aee0c09e9..dba55e7ffb 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_svc.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/srvsvc_svc.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -47,6 +46,9 @@
#include <arpa/inet.h>
#include <libshare.h>
#include <libnvpair.h>
+#include <sys/idmap.h>
+#include <pwd.h>
+#include <nss_dbdefs.h>
#include <smbsrv/libsmb.h>
#include <smbsrv/libmlsvc.h>
#include <smbsrv/lmerr.h>
@@ -2669,9 +2671,21 @@ static boolean_t
srvsvc_add_autohome(ndr_xa_t *mxa, smb_svcenum_t *se, void *infop)
{
smb_netuserinfo_t *user = &mxa->pipe->np_user;
- char *username = user->ui_account;
+ char *username;
smb_share_t si;
DWORD status;
+ struct passwd pw;
+ char buf[NSS_LINELEN_PASSWD];
+
+ if (IDMAP_ID_IS_EPHEMERAL(user->ui_posix_uid)) {
+ username = user->ui_account;
+ } else {
+ if (getpwuid_r(user->ui_posix_uid, &pw, buf, sizeof (buf)) ==
+ NULL)
+ return (B_FALSE);
+
+ username = pw.pw_name;
+ }
if (smb_shr_get(username, &si) != NERR_Success)
return (B_FALSE);
@@ -2706,10 +2720,17 @@ srvsvc_share_mkpath(ndr_xa_t *mxa, char *path)
{
char tmpbuf[MAXPATHLEN];
char *p;
+ char drive_letter;
if (strlen(path) == 0)
return (NDR_STRDUP(mxa, path));
+ drive_letter = smb_shr_drive_letter(path);
+ if (drive_letter != '\0') {
+ (void) snprintf(tmpbuf, MAXPATHLEN, "%c:\\", drive_letter);
+ return (NDR_STRDUP(mxa, tmpbuf));
+ }
+
/*
* Strip the volume name from the path (/vol1/home -> /home).
*/
diff --git a/usr/src/lib/smbsrv/libsmb/common/libsmb.h b/usr/src/lib/smbsrv/libsmb/common/libsmb.h
index 93a1371c07..a99b7eacf5 100644
--- a/usr/src/lib/smbsrv/libsmb/common/libsmb.h
+++ b/usr/src/lib/smbsrv/libsmb/common/libsmb.h
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _LIBSMB_H
@@ -696,6 +695,7 @@ int smb_lgrp_del_member(char *, smb_sid_t *, uint16_t);
int smb_lgrp_getbyname(char *, smb_group_t *);
int smb_lgrp_getbyrid(uint32_t, smb_domain_type_t, smb_group_t *);
void smb_lgrp_free(smb_group_t *);
+uint32_t smb_lgrp_err_to_ntstatus(uint32_t);
boolean_t smb_lgrp_is_member(smb_group_t *, smb_sid_t *);
char *smb_lgrp_strerror(int);
int smb_lgrp_iteropen(smb_giter_t *);
diff --git a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers
index 5c6075131c..cb103606f1 100644
--- a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers
+++ b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers
@@ -18,8 +18,7 @@
# CDDL HEADER END
#
#
-# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
#
#
@@ -248,6 +247,7 @@ SUNWprivate {
smb_lgrp_add_member;
smb_lgrp_delete;
smb_lgrp_del_member;
+ smb_lgrp_err_to_ntstatus;
smb_lgrp_free;
smb_lgrp_getbyname;
smb_lgrp_getbyrid;
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c b/usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c
index 257d23d33b..096526f20b 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_lgrp.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <stdlib.h>
@@ -937,6 +936,62 @@ smb_lgrp_strerror(int errnum)
}
/*
+ * smb_lgrp_err_to_ntstatus
+ *
+ * This routine maps Local group operation errors to NT Status error codes.
+ */
+uint32_t
+smb_lgrp_err_to_ntstatus(uint32_t lgrp_err)
+{
+ int i;
+ static struct err_map {
+ uint32_t lgrp_err;
+ uint32_t nt_status;
+ } err_map[] = {
+ { SMB_LGRP_SUCCESS, NT_STATUS_SUCCESS },
+ { SMB_LGRP_INVALID_ARG, NT_STATUS_INVALID_PARAMETER },
+ { SMB_LGRP_INVALID_MEMBER, NT_STATUS_INVALID_MEMBER },
+ { SMB_LGRP_INVALID_NAME, NT_STATUS_INVALID_PARAMETER },
+ { SMB_LGRP_NOT_FOUND, NT_STATUS_NO_SUCH_ALIAS },
+ { SMB_LGRP_EXISTS, NT_STATUS_ALIAS_EXISTS },
+ { SMB_LGRP_NO_SID, NT_STATUS_INVALID_SID },
+ { SMB_LGRP_NO_LOCAL_SID, NT_STATUS_INVALID_SID },
+ { SMB_LGRP_SID_NOTLOCAL, NT_STATUS_INVALID_SID },
+ { SMB_LGRP_WKSID, NT_STATUS_INVALID_SID },
+ { SMB_LGRP_NO_MEMORY, NT_STATUS_NO_MEMORY },
+ { SMB_LGRP_DB_ERROR, NT_STATUS_INTERNAL_DB_ERROR },
+ { SMB_LGRP_DBINIT_ERROR, NT_STATUS_INTERNAL_DB_ERROR },
+ { SMB_LGRP_INTERNAL_ERROR, NT_STATUS_INTERNAL_ERROR },
+ { SMB_LGRP_MEMBER_IN_GROUP, NT_STATUS_MEMBER_IN_ALIAS },
+ { SMB_LGRP_MEMBER_NOT_IN_GROUP, NT_STATUS_MEMBER_NOT_IN_ALIAS },
+ { SMB_LGRP_NO_SUCH_PRIV, NT_STATUS_NO_SUCH_PRIVILEGE },
+ { SMB_LGRP_NO_SUCH_DOMAIN, NT_STATUS_NO_SUCH_DOMAIN },
+ { SMB_LGRP_PRIV_HELD, NT_STATUS_SUCCESS },
+ { SMB_LGRP_PRIV_NOT_HELD, NT_STATUS_PRIVILEGE_NOT_HELD },
+ { SMB_LGRP_BAD_DATA, NT_STATUS_DATA_ERROR },
+ { SMB_LGRP_NO_MORE, NT_STATUS_NO_MORE_DATA },
+ { SMB_LGRP_DBOPEN_FAILED, NT_STATUS_INTERNAL_DB_ERROR },
+ { SMB_LGRP_DBEXEC_FAILED, NT_STATUS_INTERNAL_DB_ERROR },
+ { SMB_LGRP_DBINIT_FAILED, NT_STATUS_INTERNAL_DB_ERROR },
+ { SMB_LGRP_DOMLKP_FAILED, NT_STATUS_INTERNAL_DB_ERROR },
+ { SMB_LGRP_DOMINS_FAILED, NT_STATUS_INTERNAL_DB_ERROR },
+ { SMB_LGRP_INSERT_FAILED, NT_STATUS_INTERNAL_DB_ERROR },
+ { SMB_LGRP_DELETE_FAILED, NT_STATUS_INTERNAL_DB_ERROR },
+ { SMB_LGRP_UPDATE_FAILED, NT_STATUS_INTERNAL_DB_ERROR },
+ { SMB_LGRP_LOOKUP_FAILED, NT_STATUS_INTERNAL_DB_ERROR },
+ { SMB_LGRP_NOT_SUPPORTED, NT_STATUS_NOT_SUPPORTED },
+ { SMB_LGRP_OFFLINE, NT_STATUS_INTERNAL_ERROR }
+ };
+
+ for (i = 0; i < sizeof (err_map)/sizeof (err_map[0]); ++i) {
+ if (err_map[i].lgrp_err == lgrp_err)
+ return (err_map[i].nt_status);
+ }
+
+ return (NT_STATUS_INTERNAL_ERROR);
+}
+
+/*
* smb_lgrp_chkmember
*
* Determines valid account types for being member of
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c
index 9e211368b3..0a8d570b3a 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_ads.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <sys/param.h>
@@ -562,6 +561,7 @@ smb_ads_decode_host_ip(int addit_cnt, int ans_cnt, uchar_t **ptr,
[IN6ADDRSZ-1-i] = *(*ptr+i);
#endif
ipaddr.a_family = AF_INET6;
+ *ptr += size;
}
/*
diff --git a/usr/src/uts/common/fs/smbsrv/smb_common_transact.c b/usr/src/uts/common/fs/smbsrv/smb_common_transact.c
index 247fa4c646..1ac6ff079a 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_common_transact.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_common_transact.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <smbsrv/smb_kproto.h>
@@ -798,7 +797,7 @@ smb_trans_net_share_enum(struct smb_request *sr, struct smb_xa *xa)
}
esi.es_buf = kmem_zalloc(esi.es_bufsize, KM_SLEEP);
- esi.es_username = sr->uid_user->u_name;
+ esi.es_posix_uid = crgetuid(sr->uid_user->u_cred);
(void) smb_kshare_enum(dhdl, &esi);
/* client buffer size is not big enough to hold any shares */
diff --git a/usr/src/uts/common/fs/smbsrv/smb_kshare.c b/usr/src/uts/common/fs/smbsrv/smb_kshare.c
index c770143c52..c65f69e814 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_kshare.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_kshare.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -128,14 +127,13 @@ smb_kshare_enum(door_handle_t dhdl, smb_enumshare_info_t *enuminfo)
enuminfo->es_ntotal = enuminfo->es_nsent = 0;
- door_bufsz = enuminfo->es_bufsize + strlen(enuminfo->es_username)
- + sizeof (smb_enumshare_info_t);
+ door_bufsz = enuminfo->es_bufsize + sizeof (smb_enumshare_info_t);
door_buf = kmem_alloc(door_bufsz, KM_SLEEP);
enc_ctx = smb_dr_encode_start(door_buf, door_bufsz);
smb_dr_put_uint32(enc_ctx, opcode);
smb_dr_put_ushort(enc_ctx, enuminfo->es_bufsize);
- smb_dr_put_string(enc_ctx, enuminfo->es_username);
+ smb_dr_put_uint32(enc_ctx, enuminfo->es_posix_uid);
if (smb_dr_encode_finish(enc_ctx, &used) != 0) {
kmem_free(door_buf, door_bufsz);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_kutil.c b/usr/src/uts/common/fs/smbsrv/smb_kutil.c
index db15dec746..e6ddda8ef5 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_kutil.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_kutil.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <sys/param.h>
@@ -43,7 +42,6 @@
static kmem_cache_t *smb_dtor_cache;
static boolean_t smb_llist_initialized = B_FALSE;
-static void smb_llist_flush(smb_llist_t *);
static boolean_t smb_thread_continue_timedwait_locked(smb_thread_t *, int);
time_t tzh_leapcnt = 0;
@@ -558,7 +556,7 @@ smb_llist_exit(smb_llist_t *ll)
* call in case this leads to additional objects being posted to the delete
* queue.
*/
-static void
+void
smb_llist_flush(smb_llist_t *ll)
{
smb_dtor_t *dtor;
diff --git a/usr/src/uts/common/fs/smbsrv/smb_node.c b/usr/src/uts/common/fs/smbsrv/smb_node.c
index c2285bb818..c59b58a773 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_node.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_node.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
* SMB Node State Machine
@@ -1007,35 +1006,72 @@ smb_node_getmntpath(smb_node_t *node, char *buf, uint32_t buflen)
* Determine the absolute pathname of 'node' within the share (tree).
* For example if the node represents file "test1.txt" in directory
* "dir1" the pathname would be: \dir1\test1.txt
- *
- * If node represents a named stream, construct the pathname for the
- * associated unnamed stream then append the stream name.
*/
int
smb_node_getshrpath(smb_node_t *node, smb_tree_t *tree,
char *buf, uint32_t buflen)
{
int rc;
- vnode_t *vp;
- (void) bzero(buf, buflen);
+ ASSERT(node);
+ ASSERT(tree);
+ ASSERT(tree->t_snode);
- if (SMB_IS_STREAM(node))
- vp = node->n_unode->vp;
- else
- vp = node->vp;
+ rc = smb_node_getpath(node, tree->t_snode->vp, buf, buflen);
+ (void) strsubst(buf, '/', '\\');
+ return (rc);
+}
- if (vp == tree->t_snode->vp)
- return (0);
+/*
+ * smb_node_getpath
+ *
+ * Determine the absolute pathname of 'node' from 'rootvp'.
+ *
+ * Using vnodetopath is only reliable for directory nodes (due to
+ * its reliance on the DNLC for non-directory nodes). Thus, if node
+ * represents a file, construct the pathname for the parent dnode
+ * and append filename.
+ * If node represents a named stream, construct the pathname for the
+ * associated unnamed stream and append the stream name.
+ *
+ * The pathname returned in buf will be '/' separated.
+ */
+int
+smb_node_getpath(smb_node_t *node, vnode_t *rootvp, char *buf, uint32_t buflen)
+{
+ int rc;
+ vnode_t *vp;
+ smb_node_t *unode, *dnode;
+
+ unode = (SMB_IS_STREAM(node)) ? node->n_unode : node;
+ dnode = (smb_node_is_dir(unode)) ? unode : unode->n_dnode;
+
+ /* find path to directory node */
+ vp = dnode->vp;
+ VN_HOLD(vp);
+ if (rootvp) {
+ VN_HOLD(rootvp);
+ rc = vnodetopath(rootvp, vp, buf, buflen, kcred);
+ VN_RELE(rootvp);
+ } else {
+ rc = vnodetopath(NULL, vp, buf, buflen, kcred);
+ }
+ VN_RELE(vp);
- rc = vnodetopath(tree->t_snode->vp, vp, buf, buflen, kcred);
- if (rc == 0) {
- (void) strsubst(buf, '/', '\\');
+ if (rc != 0)
+ return (rc);
- if (SMB_IS_STREAM(node))
- (void) strlcat(buf, node->od_name, buflen);
+ /* append filename if necessary */
+ if (!smb_node_is_dir(unode)) {
+ if (buf[strlen(buf) - 1] != '/')
+ (void) strlcat(buf, "/", buflen);
+ (void) strlcat(buf, unode->od_name, buflen);
}
+ /* append named stream name if necessary */
+ if (SMB_IS_STREAM(node))
+ (void) strlcat(buf, node->od_name, buflen);
+
return (rc);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_ofile.c b/usr/src/uts/common/fs/smbsrv/smb_ofile.c
index 77e9df00a8..75e96791c1 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_ofile.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_ofile.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -928,7 +927,7 @@ smb_ofile_close_and_next(smb_ofile_t *of)
* Delete an ofile.
*
* Remove the ofile from the tree list before freeing resources
- * associated with the odir.
+ * associated with the ofile.
*/
void
smb_ofile_delete(void *arg)
diff --git a/usr/src/uts/common/fs/smbsrv/smb_query_fileinfo.c b/usr/src/uts/common/fs/smbsrv/smb_query_fileinfo.c
index e40de1c54f..4dc99479a2 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_query_fileinfo.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_query_fileinfo.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <smbsrv/smb_kproto.h>
@@ -722,7 +721,13 @@ smb_query_pathname(smb_tree_t *tree, smb_node_t *node, boolean_t include_share,
buflen -= len;
}
- rc = smb_node_getshrpath(node, tree, buf, buflen);
+ if (node == tree->t_snode) {
+ if (!include_share)
+ (void) strlcpy(buf, "\\", buflen);
+ return (0);
+ }
+
+ rc = smb_node_getshrpath(node, tree, buf, buflen);
return (rc);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_server.c b/usr/src/uts/common/fs/smbsrv/smb_server.c
index 9609a8d780..9c62e05092 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_server.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_server.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -232,8 +231,6 @@
#define SMB_EVENT_TIMEOUT 45 /* seconds */
-#define SMB_REAPER_RATE_DEFAULT 4
-
extern void smb_dispatch_kstat_init(void);
extern void smb_dispatch_kstat_fini(void);
extern void smb_reply_notify_change_request(smb_request_t *);
@@ -1948,7 +1945,7 @@ smb_event_wait(smb_event_t *event)
event->se_errno = 0;
while (!(event->se_notified)) {
- if (smb_event_debug && ((event->se_waittime % 10) == 0))
+ if (smb_event_debug && ((event->se_waittime % 30) == 0))
cmn_err(CE_NOTE, "smb_event_wait[%d] (%d sec)",
event->se_txid, event->se_waittime);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_tree.c b/usr/src/uts/common/fs/smbsrv/smb_tree.c
index 3b5ff81244..641a83d01b 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_tree.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_tree.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -330,6 +329,10 @@ smb_tree_release(
ASSERT(tree->t_refcnt);
tree->t_refcnt--;
+ /* flush the ofile and odir lists' delete queues */
+ smb_llist_flush(&tree->t_ofile_list);
+ smb_llist_flush(&tree->t_odir_list);
+
if (smb_tree_is_disconnected(tree) && (tree->t_refcnt == 0))
smb_user_post_tree(tree->t_user, tree);
@@ -474,7 +477,7 @@ smb_tree_acl_access(smb_request_t *sr, const smb_share_t *si, vnode_t *pathvp,
* An autohome share owner gets full access to the share.
* Everyone else is denied access.
*/
- if (smb_strcasecmp(si->shr_name, user->u_name, 0) != 0)
+ if (si->shr_uid != crgetuid(cred))
*access = 0;
return;
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_user.c b/usr/src/uts/common/fs/smbsrv/smb_user.c
index 6f57e1dadf..7217dedadb 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_user.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_user.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -364,6 +363,10 @@ smb_user_release(
mutex_enter(&user->u_mutex);
ASSERT(user->u_refcnt);
user->u_refcnt--;
+
+ /* flush the tree list's delete queue */
+ smb_llist_flush(&user->u_tree_list);
+
switch (user->u_state) {
case SMB_USER_STATE_LOGGED_OFF:
if (user->u_refcnt == 0)
@@ -892,9 +895,10 @@ smb_user_netinfo_init(smb_user_t *user, smb_netuserinfo_t *info)
info->ui_native_os = session->native_os;
info->ui_ipaddr = session->ipaddr;
info->ui_numopens = session->s_file_cnt;
- info->ui_uid = user->u_uid;
+ info->ui_smb_uid = user->u_uid;
info->ui_logon_time = user->u_logon_time;
info->ui_flags = user->u_flags;
+ info->ui_posix_uid = crgetuid(user->u_cred);
info->ui_domain_len = user->u_domain_len;
info->ui_domain = smb_mem_strdup(user->u_domain);
diff --git a/usr/src/uts/common/smbsrv/ndl/rpcpdu.ndl b/usr/src/uts/common/smbsrv/ndl/rpcpdu.ndl
index cda9f296e5..f1ea15cf00 100644
--- a/usr/src/uts/common/smbsrv/ndl/rpcpdu.ndl
+++ b/usr/src/uts/common/smbsrv/ndl/rpcpdu.ndl
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _RPCPDU_NDL_
@@ -129,10 +128,16 @@ typedef struct ndr_representation_label ndr_replab_t;
/*
* Flags in the RPC header for Connection-oriented PDU data types
* (X/Open CAE Spec 12.6.3.1)
+ *
+ * MS-RPCE 2.2.2.3 PFC_SUPPORT_HEADER_SIGN
+ * For PDU types bind, bind_ack, alter_context and alter_context_resp,
+ * 0x04 means PFC_SUPPORT_HEADER_SIGN.
+ * For other PDU types 0x04 means PFC_PENDING_CANCEL.
*/
#define NDR_PFC_FIRST_FRAG 0x01 /* First fragment */
#define NDR_PFC_LAST_FRAG 0x02 /* Last framgent */
#define NDR_PFC_PENDING_CANCEL 0x04 /* Cancel was pending@sender*/
+#define NDR_PFC_SUPPORT_HEADER_SIGN NDR_PFC_PENDING_CANCEL
#define NDR_PFC_RESERVED_1 0x08 /* */
#define NDR_PFC_CONC_MPX 0x10 /* supports concurrent muxing
* of single connection */
@@ -141,13 +146,42 @@ typedef struct ndr_representation_label ndr_replab_t;
#define NDR_PFC_MAYBE 0x40 /* "maybe" semantics req'ed*/
#define NDR_PFC_OBJECT_UUID 0x80 /* */
+/*
+ * Security Providers
+ * MS-RPCE 2.2.1.1.6
+ */
+#define NDR_C_AUTHN_NONE 0x00 /* No authentication */
+#define NDR_C_AUTHN_GSS_NEGOTIATE 0x09 /* SPNEGO */
+#define NDR_C_AUTHN_WINNT 0x0A /* NTLM */
+#define NDR_C_AUTHN_GSS_KERBEROS 0x10 /* Kerberos */
+#define NDR_C_AUTHN_GSS_NETLOGON 0x44 /* Netlogon */
+#define NDR_C_AUTHN_GSS_DEFAULT 0xFF /* Default is NTLM */
+
+/*
+ * Encoding protection levels
+ * X/Open CAE Spec 13.1.2.1
+ * MS-RPCE 2.2.1.1.7
+ */
+#define NDR_C_AUTHN_LEVEL_DEFAULT 0x00 /* Same as Connect */
+#define NDR_C_AUTHN_LEVEL_NONE 0x01
+#define NDR_C_AUTHN_LEVEL_CONNECT 0x02
+#define NDR_C_AUTHN_LEVEL_CALL 0x03
+#define NDR_C_AUTHN_LEVEL_PKT 0x04
+#define NDR_C_AUTHN_LEVEL_PKT_INTEGRITY 0x05
+#define NDR_C_AUTHN_LEVEL_PKT_PRIVACY 0x06
/*
* Header common to all Connection-oriented RPC PDUs
- ****************************************************************
* (X/Open CAE Spec 12.6.3.1)
*/
_NO_REORDER_
+struct ndr_p_syntax_id {
+ ndr_uuid_t if_uuid;
+ DWORD if_version;
+};
+typedef struct ndr_p_syntax_id ndr_p_syntax_id_t;
+
+_NO_REORDER_
struct ndr_common_header {
BYTE rpc_vers; /* 00:01 5 */
BYTE rpc_vers_minor; /* 01:01 0 */
@@ -163,19 +197,86 @@ struct ndr_common_header {
typedef struct ndr_common_header ndr_common_header_t;
EXTERNTYPEINFO(ndr_common_header)
+/*
+ * MS-RPCE 2.2.6 Type Serialization Version 1 extensions to IDL/+ pickle
+ * One header per serialization stream: the header must be little endian.
+ * The filler must be set to 0xcccccccc during marshaling and ignored
+ * during unmarshaling.
+ */
+_NO_REORDER_
+struct ndr_serialtype1_hdr {
+ BYTE version; /* 00:01 1 */
+ BYTE endianness; /* 01:01 0=big, 1=little */
+ WORD hdrlen; /* 02:02 8 */
+ DWORD filler; /* 04:04 0xcccccccc */
+ /* 8: */
+};
+typedef struct ndr_serialtype1_hdr ndr_serialtype1_hdr_t;
+EXTERNTYPEINFO(ndr_serialtype1_hdr)
/*
- * A plethora of supporting types, only defined the ones we need
- * (X/Open CAE Spec 12.6.3.1)
+ * Type Serialization Version 1 Private Header.
+ * A private header must precede a top-level NDR constructed type.
*/
-typedef WORD ndr_p_context_id_t;
+_NO_REORDER_
+struct ndr_serialtype1_priv_hdr {
+ DWORD buflen; /* 00:04 */
+ DWORD filler; /* 04:04 must be zero */
+ /* 8: */
+};
+typedef struct ndr_serialtype1_priv_hdr ndr_serialtype1_priv_hdr_t;
+EXTERNTYPEINFO(ndr_serialtype1_priv_hdr)
+/*
+ * MS-RPCE 2.2.7 Type Serialization Version 2 extensions Version 1 (2.2.6).
+ * The header must be little endian.
+ * The endianinfo and reserved fields must be set to 0xcccccccc during
+ * marshaling and ignored during unmarshaling.
+ */
_NO_REORDER_
-struct ndr_p_syntax_id {
- ndr_uuid_t if_uuid;
- DWORD if_version;
+struct ndr_serialtype2_hdr {
+ BYTE version; /* 00:01 1 */
+ BYTE endianness; /* 01:01 0=big, 1=little */
+ WORD hdrlen; /* 02:02 8 */
+ DWORD endianinfo; /* 04:04 0xcccccccc */
+ DWORD reserved[4]; /* 08:16 0xcccccccc */
+ ndr_p_syntax_id_t transfer_syntax; /* 24:20 */
+ ndr_p_syntax_id_t interface_id; /* 44:20 */
+ /* 64: */
};
-typedef struct ndr_p_syntax_id ndr_p_syntax_id_t;
+typedef struct ndr_serialtype2_hdr ndr_serialtype2_hdr_t;
+EXTERNTYPEINFO(ndr_serialtype2_hdr)
+
+/*
+ * Type Serialization Version 2 Private Header.
+ * A private header must precede a top-level NDR constructed type.
+ */
+_NO_REORDER_
+struct ndr_serialtype2_priv_hdr {
+ DWORD buflen; /* 00:04 */
+ DWORD filler[3]; /* 04:12 must be zero */
+ /* 16: */
+};
+typedef struct ndr_serialtype2_priv_hdr ndr_serialtype2_priv_hdr_t;
+EXTERNTYPEINFO(ndr_serialtype2_priv_hdr)
+
+/*
+ * This header comes before the NDR-encoded KERB_VALIDATION_INFO structure,
+ * which can be found in one of the info buffers of the PAC.
+ */
+_NO_REORDER_
+struct ndr_pac_hdr {
+ ndr_serialtype1_hdr_t common_hdr;
+ ndr_serialtype1_priv_hdr_t priv_hdr;
+ DWORD ref_pointer;
+};
+typedef struct ndr_pac_hdr ndr_pac_hdr_t;
+EXTERNTYPEINFO(ndr_pac_hdr)
+
+/*
+ * Supporting types (X/Open CAE Spec 12.6.3.1)
+ */
+typedef WORD ndr_p_context_id_t;
_NO_REORDER_
struct ndr_p_cont_elem {
@@ -205,19 +306,21 @@ typedef WORD ndr_p_cont_def_result_t;
#define NDR_PCDR_USER_REJECTION 1
#define NDR_PCDR_PROVIDER_REJECTION 2
+/*
+ * Reasons for provider rejection.
+ * X/Open CAE Spec 12.6.3.1
+ */
typedef WORD ndr_p_provider_reason_t;
-#define NDR_PPR_REASON_NOT_SPECIFIED 0
-#define NDR_PPR_ABSTRACT_SYNTAX_NOT_SUPPORTED 1
-#define NDR_PPR_PROPOSED_TRANSFER_SYNTAXES_NOT_SUPPORTED 2
-#define NDR_PPR_LOCAL_LIMIT_EXCEEDED 3
-
+#define NDR_PPR_REASON_NOT_SPECIFIED 0
+#define NDR_PPR_ABSTRACT_SYNTAX_NOT_SUPPORTED 1
+#define NDR_PPR_PROPOSED_TRANSFER_SYNTAXES_NOT_SUPPORTED 2
+#define NDR_PPR_LOCAL_LIMIT_EXCEEDED 3
_NO_REORDER_
struct ndr_p_result {
ndr_p_cont_def_result_t result; /* NDR_PCDR_... */
ndr_p_provider_reason_t reason; /* NDR_PPR_... */
- ndr_p_syntax_id_t transfer_syntax; /* 0-fill if
- * result!=ACCEPT*/
+ ndr_p_syntax_id_t transfer_syntax; /* 0-fill if result!=ACCEPT */
};
typedef struct ndr_p_result ndr_p_result_t;
EXTERNTYPEINFO(ndr_p_result)
@@ -245,6 +348,21 @@ struct ndr_port_any {
typedef struct ndr_port_any ndr_port_any_t;
EXTERNTYPEINFO(ndr_port_any)
+/*
+ * Reasons for rejecting an association in the bind_nak PDU.
+ * X/Open CAE Spec 12.6.3.1
+ * MS-RPCE 2.2.2.5
+ */
+#define NDR_REASON_NOT_SPECIFIED 0
+#define NDR_TEMPORARY_CONGESTION 1
+#define NDR_LOCAL_LIMIT_EXCEEDED 2
+#define NDR_CALLED_PADDR_UNKNOWN 3
+#define NDR_PROTOCOL_VERSION_NOT_SUPPORTED 4
+#define NDR_DEFAULT_CONTEXT_NOT_SUPPORTED 5
+#define NDR_USER_DATA_NOT_READABLE 6
+#define NDR_NO_PSAP_AVAILABLE 7
+#define NDR_AUTH_TYPE_NOT_RECOGNIZED 8
+#define NDR_INAVLID_CHECKSUM 9
/*
* Alter Context PDU (0x0E)
@@ -498,7 +616,9 @@ typedef struct ndr_fault_hdr ndr_fault_hdr_t;
#define NDR_PTYPE_COMMON 999
#define NDR_PTYPE_REQUEST_WITH 998
-
+#define NDR_PTYPE_SERIALTYPE_V1 997
+#define NDR_PTYPE_SERIALTYPE_V2 996
+#define NDR_PTYPE_PAC 995
INTERFACE(0)
union ndr_hdr {
@@ -526,6 +646,15 @@ union ndr_hdr {
CASE(NDR_PTYPE_ALTER_CONTEXT_RESP)
struct ndr_alter_context_rsp_hdr alter_context_rsp_hdr;
+ CASE(NDR_PTYPE_SERIALTYPE_V1)
+ struct ndr_serialtype1_hdr serialtype1_hdr;
+
+ CASE(NDR_PTYPE_SERIALTYPE_V2)
+ struct ndr_serialtype2_hdr serialtype2_hdr;
+
+ CASE(NDR_PTYPE_PAC)
+ struct ndr_pac_hdr pac_hdr;
+
CASE(NDR_PTYPE_FAULT)
struct ndr_fault_hdr fault_hdr;
};
diff --git a/usr/src/uts/common/smbsrv/ndl/samrpc.ndl b/usr/src/uts/common/smbsrv/ndl/samrpc.ndl
index e08b06e626..44d86dcb19 100644
--- a/usr/src/uts/common/smbsrv/ndl/samrpc.ndl
+++ b/usr/src/uts/common/smbsrv/ndl/samrpc.ndl
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _MLSVC_SAM_NDL_
@@ -66,7 +65,7 @@
#define SAMR_OPNUM_DeleteDomainAlias 0x1e
#define SAMR_OPNUM_AddAliasMember 0x1f
#define SAMR_OPNUM_DeleteAliasMember 0x20
-#define SAMR_OPNUM_QueryAliasMember 0x21
+#define SAMR_OPNUM_ListAliasMembers 0x21
#define SAMR_OPNUM_OpenUser 0x22
#define SAMR_OPNUM_DeleteUser 0x23
#define SAMR_OPNUM_QueryUserInfo 0x24
@@ -185,13 +184,17 @@
#define SAMR_USER_ALL_UNDEFINED_MASK 0xC0000000
/*
- * specific access rights which can be used in OpenAlias.
- * extracted from Ethereal network analyzer
+ * Alias Access Mask values for SAMR
+ * Section 2.2.1.6 of MS-SAMR
*/
-#define SAMR_ALIAS_ACCESS_SET_INFO 0x00000010
-#define SAMR_ALIAS_ACCESS_GET_INFO 0x00000008
-#define SAMR_ALIAS_ACCESS_GET_MEMBERS 0x00000004
-#define SAMR_ALIAS_ACCESS_DEL_MEMBER 0x00000002
+#define SAMR_ALIAS_ACCESS_EXECUTE 0x00020008
+#define SAMR_ALIAS_ACCESS_WRITE 0x00020013
+#define SAMR_ALIAS_ACCESS_READ 0x00020004
+#define SAMR_ALIAS_ACCESS_ALL_ACCESS 0x000F001F
+#define SAMR_ALIAS_ACCESS_WRITE_ACCOUNT 0x00000010
+#define SAMR_ALIAS_ACCESS_READ_INFO 0x00000008
+#define SAMR_ALIAS_ACCESS_LIST_MEMBERS 0x00000004
+#define SAMR_ALIAS_ACCESS_REMOVE_MEMBER 0x00000002
#define SAMR_ALIAS_ACCESS_ADD_MEMBER 0x00000001
#define SAMR_REVISION_1 1 /* Pre Windows 2000 */
@@ -669,7 +672,7 @@ struct samr_SetAliasInfo {
OPERATION(SAMR_OPNUM_DeleteDomainAlias)
struct samr_DeleteDomainAlias {
- IN samr_handle_t alias_handle;
+ INOUT samr_handle_t alias_handle;
OUT DWORD status;
};
@@ -1126,6 +1129,45 @@ struct samr_StoreGroupInfo {
OUT DWORD status;
};
+/*
+ * AddAliasMember
+ */
+OPERATION(SAMR_OPNUM_AddAliasMember)
+struct samr_AddAliasMember {
+ IN samr_handle_t alias_handle;
+ IN REFERENCE struct samr_sid *sid;
+ OUT DWORD status;
+};
+
+/*
+ * DeleteAliasMember
+ */
+OPERATION(SAMR_OPNUM_DeleteAliasMember)
+struct samr_DeleteAliasMember {
+ IN samr_handle_t alias_handle;
+ IN REFERENCE struct samr_sid *sid;
+ OUT DWORD status;
+};
+
+struct samr_SidList {
+ struct samr_sid *sid;
+};
+
+struct samr_SidInfo {
+ DWORD n_entry;
+ SIZE_IS(n_entry)
+ struct samr_SidList *sidlist;
+};
+
+/*
+ * ListAliasMembers
+ */
+OPERATION(SAMR_OPNUM_ListAliasMembers)
+struct samr_ListAliasMembers {
+ IN samr_handle_t alias_handle;
+ OUT struct samr_SidInfo info;
+ OUT DWORD status;
+};
/*
***********************************************************************
@@ -1410,6 +1452,12 @@ union samr_interface {
struct samr_QueryUserGroups QueryUserGroups;
CASE(SAMR_OPNUM_OpenGroup)
struct samr_OpenGroup OpenGroup;
+ CASE(SAMR_OPNUM_AddAliasMember)
+ struct samr_AddAliasMember AddAliasMember;
+ CASE(SAMR_OPNUM_DeleteAliasMember)
+ struct samr_DeleteAliasMember DeleteAliasMember;
+ CASE(SAMR_OPNUM_ListAliasMembers)
+ struct samr_ListAliasMembers ListAliasMembers;
CASE(SAMR_OPNUM_GetUserPwInfo)
struct samr_GetUserPwInfo GetUserPwInfo;
CASE(SAMR_OPNUM_CreateUser)
diff --git a/usr/src/uts/common/smbsrv/smb_kproto.h b/usr/src/uts/common/smbsrv/smb_kproto.h
index ae09a4d10e..b1bc982cf1 100644
--- a/usr/src/uts/common/smbsrv/smb_kproto.h
+++ b/usr/src/uts/common/smbsrv/smb_kproto.h
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -430,6 +429,7 @@ int smb_node_setattr(smb_request_t *, smb_node_t *, cred_t *,
int smb_node_set_delete_on_close(smb_node_t *, cred_t *, uint32_t);
void smb_node_reset_delete_on_close(smb_node_t *);
boolean_t smb_node_file_is_readonly(smb_node_t *);
+int smb_node_getpath(smb_node_t *, vnode_t *, char *, uint32_t);
int smb_node_getmntpath(smb_node_t *, char *, uint32_t);
int smb_node_getshrpath(smb_node_t *, smb_tree_t *, char *, uint32_t);
@@ -690,6 +690,7 @@ void smb_llist_constructor(smb_llist_t *, size_t, size_t);
void smb_llist_destructor(smb_llist_t *);
void smb_llist_exit(smb_llist_t *);
void smb_llist_post(smb_llist_t *, void *, smb_dtorproc_t);
+void smb_llist_flush(smb_llist_t *);
void smb_llist_insert_head(smb_llist_t *ll, void *obj);
void smb_llist_insert_tail(smb_llist_t *ll, void *obj);
void smb_llist_remove(smb_llist_t *ll, void *obj);
diff --git a/usr/src/uts/common/smbsrv/smb_share.h b/usr/src/uts/common/smbsrv/smb_share.h
index 1cc5ec87e2..679a740d81 100644
--- a/usr/src/uts/common/smbsrv/smb_share.h
+++ b/usr/src/uts/common/smbsrv/smb_share.h
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _SMB_SHARE_H
@@ -225,7 +224,7 @@ typedef struct smb_shrlist {
* This structure is a helper for building NetShareEnum response
* in user space and send it back down to kernel.
*
- * es_username name of the user requesting the shares list which
+ * es_posix_uid UID of the user requesting the shares list which
* is used to detect if the user has any autohome
* es_bufsize size of the response buffer
* es_buf pointer to the response buffer
@@ -236,7 +235,7 @@ typedef struct smb_shrlist {
* in the response buffer
*/
typedef struct smb_enumshare_info {
- char *es_username;
+ uid_t es_posix_uid;
uint16_t es_bufsize;
char *es_buf;
uint16_t es_ntotal;
@@ -286,6 +285,7 @@ boolean_t smb_shr_exists(char *);
int smb_shr_is_special(char *);
boolean_t smb_shr_is_restricted(char *);
boolean_t smb_shr_is_admin(char *);
+char smb_shr_drive_letter(const char *);
sa_handle_t smb_shr_sa_enter(void);
void smb_shr_sa_exit(void);
diff --git a/usr/src/uts/common/smbsrv/smb_xdr.h b/usr/src/uts/common/smbsrv/smb_xdr.h
index 61f62df661..cebedb39c4 100644
--- a/usr/src/uts/common/smbsrv/smb_xdr.h
+++ b/usr/src/uts/common/smbsrv/smb_xdr.h
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _SMBSRV_SMB_XDR_H
@@ -120,11 +119,12 @@ typedef struct smb_doorhdr {
typedef struct smb_netuserinfo {
uint64_t ui_session_id;
- uint16_t ui_uid;
+ uint16_t ui_smb_uid;
uint16_t ui_domain_len;
char *ui_domain;
uint16_t ui_account_len;
char *ui_account;
+ uid_t ui_posix_uid;
uint16_t ui_workstation_len;
char *ui_workstation;
smb_inaddr_t ui_ipaddr;