summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorKeyur Desai <Keyur.Desai@Sun.COM>2010-04-02 15:07:12 -0600
committerKeyur Desai <Keyur.Desai@Sun.COM>2010-04-02 15:07:12 -0600
commitc586600796766c83eb9485c446886fd9ed2359a9 (patch)
treebe38c992d2fa6b7489bce2b0e6e81ad8dba9d3c2 /usr/src
parenta23420cf95f05ac67f2c299116a3225581e519d1 (diff)
downloadillumos-joyent-c586600796766c83eb9485c446886fd9ed2359a9.tar.gz
6932404 Autohome share does not show up when using sharemgr show -vp
6875358 NDR support for Serialization Types 6811350 Autohome wildcard rule fails with mixed case (or upper case) user name 6932967 Add local group manipulation functions to SAMR service 6801203 libidmap should not link with bunch of libraries 6928764 Diagnostic noise on "idmap get-namemap" and "idmap set-namemap" 6885923 idmapd loops infinitely, leaking memory 6936722 Sparc : Unable to destroy zpool, sharemgr locks up. 6937163 smbd door operations should initialize XDR decode data 6937814 Memory corruption while running stress test 6913525 smb_ads_decode_host_ip doesn't step over IPv6 address 6939430 queryfileinfo should only use vnodetopath for directory nodes 6938318 Unable to save files with Save As --HG-- rename : usr/src/lib/libidmap/common/namemaps.c => usr/src/cmd/idmap/idmap/namemaps.c rename : usr/src/lib/libidmap/common/idmap_priv.h => usr/src/cmd/idmap/idmap/namemaps.h
Diffstat (limited to 'usr/src')
-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;