summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2017-06-14 11:46:02 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2017-06-14 11:46:02 +0000
commitcc3d7c4906f9242753f7514c92245cbe1612ea02 (patch)
tree182d5564411e3e3d3bfaf43a1c878eb835428d6d
parent4152d8858319048f89c6066931dfabeb820333e9 (diff)
parent2889ec41c05e9ffe1890b529b3111354da325aeb (diff)
downloadillumos-joyent-cc3d7c4906f9242753f7514c92245cbe1612ea02.tar.gz
[illumos-gate merge]
commit 2889ec41c05e9ffe1890b529b3111354da325aeb 8311 ZFS_READONLY is a little too strict commit 796b8631498f69a3e21b5c35aee280499f64420e 8332 krb5: misleading-indentation commit c1eb8ad45781fe675aa558a47a11345293533238 8204 Makefile changes in zfstest cannot cope with empty directories commit d5767f310a0330fcb172a1651b2c9301e53b9aef 8334 ipf: self-comparison always evaluates to false commit 843c2111b160463f014d325560ad4b051711928e 8375 Kernel memory leak in nvpair code commit 403a8da73c64ff9dfb6230ba045c765a242213fb 5220 L2ARC does not support devices that do not provide 512B access commit 4ec4134be29a3b00791f6d70074168a6a3ff4fb3 8317 ddi_periodic_add(9F) has wrong type for arg in summary commit 56849bc6aade3a04eb051dc383a2091c220385c4 8322 nl: misleading-indentation commit 6dd72a43d2e43185833c20e7f0c4cb88a4d37ec8 8106 authloopback_marshal() can violate the RPC specification 8109 Kernel AUTH_SYS and AUTH_LOOPBACK implementation can ignore provided credentials commit 1d8d40bd3f903c0d0fa71c26b4548d2d47260251 8354 sync regcomp(3C) with upstream (fix make catalog)
-rw-r--r--usr/src/cmd/ipf/tools/ipfcomp.c9
-rw-r--r--usr/src/cmd/krb5/kadmin/dbutil/dump.c4
-rw-r--r--usr/src/cmd/krb5/kadmin/server/server_stubs.c44
-rw-r--r--usr/src/cmd/krb5/klist/klist.c3
-rw-r--r--usr/src/cmd/krb5/krb5kdc/do_as_req.c18
-rw-r--r--usr/src/cmd/nl/nl.c90
-rw-r--r--usr/src/common/nvpair/nvpair.c6
-rw-r--r--usr/src/lib/libc/makelibccatalog.sh2
-rw-r--r--usr/src/man/man9f/ddi_periodic_add.9f2
-rw-r--r--usr/src/pkg/manifests/system-test-zfstest.mf2
-rw-r--r--usr/src/test/Makefile.com6
-rw-r--r--usr/src/test/zfs-tests/cmd/dos_ro/Makefile22
-rw-r--r--usr/src/test/zfs-tests/cmd/dos_ro/dos_ro.c143
-rw-r--r--usr/src/test/zfs-tests/include/commands.cfg1
-rw-r--r--usr/src/test/zfs-tests/runfiles/delphix.run3
-rw-r--r--usr/src/test/zfs-tests/runfiles/omnios.run3
-rw-r--r--usr/src/test/zfs-tests/runfiles/openindiana.run3
-rw-r--r--usr/src/test/zfs-tests/tests/functional/acl/cifs/cifs_attr_003_pos.ksh14
-rw-r--r--usr/src/test/zfs-tests/tests/functional/acl/cifs/cifs_attr_004_pos.ksh141
-rw-r--r--usr/src/uts/common/fs/zfs/arc.c69
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_acl.c28
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_vnops.c19
-rw-r--r--usr/src/uts/common/rpc/auth_sys.h4
-rw-r--r--usr/src/uts/common/rpc/sec/auth_kern.c105
-rw-r--r--usr/src/uts/common/rpc/sec/auth_loopb.c113
-rw-r--r--usr/src/uts/common/rpc/sec/authu_prot.c17
26 files changed, 655 insertions, 216 deletions
diff --git a/usr/src/cmd/ipf/tools/ipfcomp.c b/usr/src/cmd/ipf/tools/ipfcomp.c
index b99a6f8385..15405c1cd3 100644
--- a/usr/src/cmd/ipf/tools/ipfcomp.c
+++ b/usr/src/cmd/ipf/tools/ipfcomp.c
@@ -7,13 +7,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#if !defined(lint)
-static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipfcomp.c,v 1.24.2.2 2004/04/28 10:34:44 darrenr Exp $";
-#endif
-
#include "ipf.h"
@@ -391,7 +384,7 @@ extern frentry_t *ipfrule_match_out_%s __P((fr_info_t *, u_32_t *));\n\
extern frentry_t *ipf_rules_out_%s[%d];\n",
grp->fg_name, grp->fg_name, outcount);
- for (g = groups; g != g; g = g->fg_next)
+ for (g = groups; g != grp; g = g->fg_next)
if ((strncmp(g->fg_name, grp->fg_name,
FR_GROUPLEN) == 0) &&
g->fg_flags == grp->fg_flags)
diff --git a/usr/src/cmd/krb5/kadmin/dbutil/dump.c b/usr/src/cmd/krb5/kadmin/dbutil/dump.c
index a512d7527f..3f6b3b8f54 100644
--- a/usr/src/cmd/krb5/kadmin/dbutil/dump.c
+++ b/usr/src/cmd/krb5/kadmin/dbutil/dump.c
@@ -2833,9 +2833,9 @@ load_db(argc, argv)
exit_status++;
goto error;
}
- }
- else
+ } else {
db_locked = 1;
+ }
if (log_ctx && log_ctx->iproprole) {
if (add_update)
diff --git a/usr/src/cmd/krb5/kadmin/server/server_stubs.c b/usr/src/cmd/krb5/kadmin/server/server_stubs.c
index 76eef7227a..b90f5d54d1 100644
--- a/usr/src/cmd/krb5/kadmin/server/server_stubs.c
+++ b/usr/src/cmd/krb5/kadmin/server/server_stubs.c
@@ -554,42 +554,42 @@ create_principal_2_svc(cprinc_arg *arg, struct svc_req *rqstp)
log_unauth("kadm5_create_principal", prime_arg,
client_name, service_name, client_addr(rqstp, buf));
} else {
- ret.code = kadm5_create_principal((void *)handle,
+ ret.code = kadm5_create_principal((void *)handle,
&arg->rec, arg->mask,
arg->passwd);
/* Solaris Kerberos */
- if( ret.code != 0 )
+ if( ret.code != 0 )
errmsg = krb5_get_error_message(handle ? handle->context : NULL, ret.code);
- audit_kadmind_auth(rqstp->rq_xprt, l_port,
+ audit_kadmind_auth(rqstp->rq_xprt, l_port,
"kadm5_create_principal",
prime_arg, client_name, ret.code);
- log_done("kadm5_create_principal", prime_arg,
+ log_done("kadm5_create_principal", prime_arg,
errmsg ? errmsg : "success",
client_name, service_name, client_addr(rqstp, buf));
- if (errmsg != NULL)
+ if (errmsg != NULL)
krb5_free_error_message(handle ? handle->context : NULL, errmsg);
- if (policy_migrate && (ret.code == 0)) {
- arg->rec.policy = strdup("default");
- if ((arg->mask & KADM5_PW_EXPIRATION)) {
- arg->mask = 0;
- arg->mask |= KADM5_POLICY;
- arg->mask |= KADM5_PW_EXPIRATION;
- } else {
- arg->mask = 0;
- arg->mask |= KADM5_POLICY;
- }
-
- retval = kadm5_modify_principal((void *)handle,
- &arg->rec, arg->mask);
- log_done("kadm5_modify_principal",
- prime_arg, ((retval == 0) ? "success" :
- error_message(retval)), client_name,
- service_name, client_addr(rqstp, buf));
+ if (policy_migrate && (ret.code == 0)) {
+ arg->rec.policy = strdup("default");
+ if ((arg->mask & KADM5_PW_EXPIRATION)) {
+ arg->mask = 0;
+ arg->mask |= KADM5_POLICY;
+ arg->mask |= KADM5_PW_EXPIRATION;
+ } else {
+ arg->mask = 0;
+ arg->mask |= KADM5_POLICY;
}
+
+ retval = kadm5_modify_principal((void *)handle,
+ &arg->rec, arg->mask);
+ log_done("kadm5_modify_principal",
+ prime_arg, ((retval == 0) ? "success" :
+ error_message(retval)), client_name,
+ service_name, client_addr(rqstp, buf));
}
+ }
error:
if (name)
diff --git a/usr/src/cmd/krb5/klist/klist.c b/usr/src/cmd/krb5/klist/klist.c
index 22c9a152ef..00fa45cfe4 100644
--- a/usr/src/cmd/krb5/klist/klist.c
+++ b/usr/src/cmd/krb5/klist/klist.c
@@ -2,7 +2,6 @@
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
/*
* clients/klist/klist.c
@@ -632,7 +631,7 @@ show_credential(cred)
fputs("\t",stdout);
else
fputs(", ",stdout);
- fputs(gettext("renew until "), stdout);
+ fputs(gettext("renew until "), stdout);
printtime(cred->times.renew_till);
extra_field += 2;
}
diff --git a/usr/src/cmd/krb5/krb5kdc/do_as_req.c b/usr/src/cmd/krb5/krb5kdc/do_as_req.c
index 4c415006ad..ed7383aebc 100644
--- a/usr/src/cmd/krb5/krb5kdc/do_as_req.c
+++ b/usr/src/cmd/krb5/krb5kdc/do_as_req.c
@@ -477,19 +477,19 @@ errout:
free_padata_context(kdc_context, &pa_context);
if (status) {
- const char * emsg = 0;
+ const char *emsg = NULL;
if (errcode)
emsg = krb5_get_error_message (kdc_context, errcode);
- audit_krb5kdc_as_req(&from_in4, (in_port_t)from->port,
- 0, cname, sname, errcode);
+ audit_krb5kdc_as_req(&from_in4, (in_port_t)from->port,
+ 0, cname, sname, errcode);
krb5_klog_syslog(LOG_INFO, "AS_REQ (%s) %s: %s: %s for %s%s%s",
- ktypestr,
- fromstring, status,
- cname ? cname : "<unknown client>",
- sname ? sname : "<unknown server>",
- errcode ? ", " : "",
- errcode ? emsg : "");
+ ktypestr,
+ fromstring, status,
+ cname ? cname : "<unknown client>",
+ sname ? sname : "<unknown server>",
+ errcode ? ", " : "",
+ errcode ? emsg : "");
if (errcode)
krb5_free_error_message (kdc_context, emsg);
}
diff --git a/usr/src/cmd/nl/nl.c b/usr/src/cmd/nl/nl.c
index d927172e86..9c5a5f045f 100644
--- a/usr/src/cmd/nl/nl.c
+++ b/usr/src/cmd/nl/nl.c
@@ -28,8 +28,6 @@
/* All Rights Reserved */
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <locale.h>
#include <regexpr.h>
#include <stdio.h>
@@ -90,9 +88,7 @@ extern char *optarg; /* getopt support */
extern int optind;
int
-main(argc, argv)
-int argc;
-char *argv[];
+main(int argc, char *argv[])
{
register int j;
register int i = 0;
@@ -139,7 +135,7 @@ char *argv[];
while (argc > 0) {
while ((c = getopt(argc, argv,
- "pb:d:f:h:i:l:n:s:v:w:")) != EOF) {
+ "pb:d:f:h:i:l:n:s:v:w:")) != EOF) {
switch (c) {
case 'h':
@@ -157,7 +153,7 @@ char *argv[];
(void) strcpy(pat, optarg+1);
header = 'h';
hexpbuf =
- compile(pat, (char *)0, (char *)0);
+ compile(pat, NULL, NULL);
if (regerrno)
regerr(regerrno);
break;
@@ -183,7 +179,7 @@ char *argv[];
(void) strcpy(pat, optarg+1);
body = 'b';
bexpbuf =
- compile(pat, (char *)0, (char *)0);
+ compile(pat, NULL, NULL);
if (regerrno)
regerr(regerrno);
break;
@@ -209,7 +205,7 @@ char *argv[];
(void) strcpy(pat, optarg+1);
footer = 'f';
fexpbuf =
- compile(pat, (char *)0, (char *)0);
+ compile(pat, NULL, NULL);
if (regerrno)
regerr(regerrno);
break;
@@ -337,10 +333,10 @@ for (j = 1; j < argc; j++) {
}
pat[r] = '\0';
header = 'h';
- hexpbuf =
- compile(pat, (char *)0, (char *)0);
- if (regerrno)
- regerr(regerrno);
+ hexpbuf =
+ compile(pat, NULL, NULL);
+ if (regerrno)
+ regerr(regerrno);
break;
case '\0':
header = 'n';
@@ -371,10 +367,10 @@ for (j = 1; j < argc; j++) {
}
pat[r] = '\0';
body = 'b';
- bexpbuf =
- compile(pat, (char *)0, (char *)0);
- if (regerrno)
- regerr(regerrno);
+ bexpbuf =
+ compile(pat, NULL, NULL);
+ if (regerrno)
+ regerr(regerrno);
break;
case '\0':
body = 't';
@@ -405,10 +401,10 @@ for (j = 1; j < argc; j++) {
}
pat[r] = '\0';
footer = 'f';
- fexpbuf =
- compile(pat, (char *)0, (char *)0);
- if (regerrno)
- regerr(regerrno);
+ fexpbuf =
+ compile(pat, NULL, NULL);
+ if (regerrno)
+ regerr(regerrno);
break;
case '\0':
footer = 'n';
@@ -653,20 +649,17 @@ for (j = 1; j < argc; j++) {
/* REGEXP ERR ROUTINE */
static void
-regerr(c)
-int c;
+regerr(int c)
{
(void) fprintf(stderr, gettext(
- "nl: invalid regular expression: error code %d\n"), c);
+ "nl: invalid regular expression: error code %d\n"), c);
exit(1);
}
/* CALCULATE NUMBER ROUTINE */
static void
-pnum(n, sep)
-int n;
-char * sep;
+pnum(int n, char *sep)
{
register int i;
@@ -689,8 +682,7 @@ char * sep;
/* IF NUM > 10, THEN USE THIS CALCULATE ROUTINE */
static void
-num(v, p)
-int v, p;
+num(int v, int p)
{
if (v < 10)
nbuf[p] = v + '0';
@@ -705,9 +697,7 @@ int v, p;
#ifdef XPG4
static int
-convert(c, option_arg)
-int c;
-char *option_arg;
+convert(int c, char *option_arg)
{
s = option_arg;
q = r = 0;
@@ -726,23 +716,19 @@ char *option_arg;
#else
/* Solaris version */
static int
-convert(argv)
-char *argv;
+convert(char *argv)
{
s = (char *)argv;
q = 2;
r = 0;
while (s[q] != '\0') {
- if (s[q] >= '0' && s[q] <= '9')
- {
- s1[r] = s[q];
- r++;
- q++;
+ if (s[q] >= '0' && s[q] <= '9') {
+ s1[r] = s[q];
+ r++;
+ q++;
+ } else {
+ optmsg(argv);
}
- else
- {
- optmsg(argv);
- }
}
s1[r] = '\0';
k = atoi(s1);
@@ -753,9 +739,7 @@ char *argv;
/* CALCULATE NUM/TEXT SEPRATOR */
static void
-npad(width, sep)
- int width;
- char * sep;
+npad(int width, char *sep)
{
register int i;
@@ -764,19 +748,17 @@ npad(width, sep)
nbuf[i] = pad;
(void) printf("%s", nbuf);
- for (i = 0; i < (int) strlen(sep); i++)
+ for (i = 0; i < (int)strlen(sep); i++)
(void) printf(" ");
}
#ifdef XPG4
static void
-optmsg(option, option_arg)
-int option;
-char *option_arg;
+optmsg(int option, char *option_arg)
{
if (option_arg != (char *)NULL) {
(void) fprintf(stderr, gettext(
- "nl: invalid option (-%c %s)\n"), option, option_arg);
+ "nl: invalid option (-%c %s)\n"), option, option_arg);
}
/* else getopt() will print illegal option message */
usage();
@@ -784,11 +766,9 @@ char *option_arg;
#else
/* Solaris version */
static void
-optmsg(option)
-char *option;
+optmsg(char *option)
{
- (void) fprintf(stderr, gettext(
- "nl: invalid option (%s)\n"), option);
+ (void) fprintf(stderr, gettext("nl: invalid option (%s)\n"), option);
usage();
}
#endif
diff --git a/usr/src/common/nvpair/nvpair.c b/usr/src/common/nvpair/nvpair.c
index ca370b1874..5881ba54b7 100644
--- a/usr/src/common/nvpair/nvpair.c
+++ b/usr/src/common/nvpair/nvpair.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2015, 2016 by Delphix. All rights reserved.
+ * Copyright (c) 2015, 2017 by Delphix. All rights reserved.
*/
#include <sys/stropts.h>
@@ -2195,8 +2195,10 @@ nvs_embedded(nvstream_t *nvs, nvlist_t *embedded)
nvlist_init(embedded, embedded->nvl_nvflag, priv);
- if (nvs->nvs_recursion >= nvpair_max_recursion)
+ if (nvs->nvs_recursion >= nvpair_max_recursion) {
+ nvlist_free(embedded);
return (EINVAL);
+ }
nvs->nvs_recursion++;
if ((err = nvs_operation(nvs, embedded, NULL)) != 0)
nvlist_free(embedded);
diff --git a/usr/src/lib/libc/makelibccatalog.sh b/usr/src/lib/libc/makelibccatalog.sh
index 9f765532ad..3536f3af26 100644
--- a/usr/src/lib/libc/makelibccatalog.sh
+++ b/usr/src/lib/libc/makelibccatalog.sh
@@ -91,7 +91,7 @@ done
#
# Change Directory
#
- cd ../locale
+ cd ../regex
rm -f messages.po regerror.po
${XGETTEXT} -a regerror.c
diff --git a/usr/src/man/man9f/ddi_periodic_add.9f b/usr/src/man/man9f/ddi_periodic_add.9f
index 7b865acbb8..72b7430190 100644
--- a/usr/src/man/man9f/ddi_periodic_add.9f
+++ b/usr/src/man/man9f/ddi_periodic_add.9f
@@ -4,7 +4,7 @@
.\" 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]
-.TH DDI_PERIODIC_ADD 9F "Jul 23, 2013"
+.TH DDI_PERIODIC_ADD 9F "May 04, 2017"
.SH NAME
ddi_periodic_add \- request periodic function invocation
.SH SYNOPSIS
diff --git a/usr/src/pkg/manifests/system-test-zfstest.mf b/usr/src/pkg/manifests/system-test-zfstest.mf
index 7d2637a592..62cc59b17a 100644
--- a/usr/src/pkg/manifests/system-test-zfstest.mf
+++ b/usr/src/pkg/manifests/system-test-zfstest.mf
@@ -154,6 +154,7 @@ file path=opt/zfs-tests/README mode=0444
file path=opt/zfs-tests/bin/chg_usr_exec mode=0555
file path=opt/zfs-tests/bin/devname2devid mode=0555
file path=opt/zfs-tests/bin/dir_rd_update mode=0555
+file path=opt/zfs-tests/bin/dos_ro mode=0555
file path=opt/zfs-tests/bin/file_check mode=0555
file path=opt/zfs-tests/bin/file_trunc mode=0555
file path=opt/zfs-tests/bin/file_write mode=0555
@@ -186,6 +187,7 @@ file path=opt/zfs-tests/tests/functional/acl/cifs/cifs.kshlib mode=0444
file path=opt/zfs-tests/tests/functional/acl/cifs/cifs_attr_001_pos mode=0555
file path=opt/zfs-tests/tests/functional/acl/cifs/cifs_attr_002_pos mode=0555
file path=opt/zfs-tests/tests/functional/acl/cifs/cifs_attr_003_pos mode=0555
+file path=opt/zfs-tests/tests/functional/acl/cifs/cifs_attr_004_pos mode=0555
file path=opt/zfs-tests/tests/functional/acl/cifs/cleanup mode=0555
file path=opt/zfs-tests/tests/functional/acl/cifs/setup mode=0555
file path=opt/zfs-tests/tests/functional/acl/nontrivial/cleanup mode=0555
diff --git a/usr/src/test/Makefile.com b/usr/src/test/Makefile.com
index aabe39d22b..49e23dd496 100644
--- a/usr/src/test/Makefile.com
+++ b/usr/src/test/Makefile.com
@@ -30,6 +30,10 @@ lint_SRCS:
$(LINT.c) $(SRCS) $(LDLIBS)
$(SUBDIRS): FRC
- @cd $@; pwd; $(MAKE) $(TARGET)
+ @if [ -f $@/Makefile ]; then \
+ cd $@; pwd; $(MAKE) $(TARGET); \
+ else \
+ true; \
+ fi
FRC:
diff --git a/usr/src/test/zfs-tests/cmd/dos_ro/Makefile b/usr/src/test/zfs-tests/cmd/dos_ro/Makefile
new file mode 100644
index 0000000000..642de01e59
--- /dev/null
+++ b/usr/src/test/zfs-tests/cmd/dos_ro/Makefile
@@ -0,0 +1,22 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2017 Nexenta Systems, Inc. All rights reserved.
+#
+
+PROG = dos_ro
+
+include $(SRC)/cmd/Makefile.cmd
+
+LDLIBS += -lnvpair
+
+include ../Makefile.subdirs
diff --git a/usr/src/test/zfs-tests/cmd/dos_ro/dos_ro.c b/usr/src/test/zfs-tests/cmd/dos_ro/dos_ro.c
new file mode 100644
index 0000000000..4f0510f72b
--- /dev/null
+++ b/usr/src/test/zfs-tests/cmd/dos_ro/dos_ro.c
@@ -0,0 +1,143 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <attr.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <libnvpair.h>
+
+extern const char *__progname;
+
+int vflag = 0;
+
+static int
+dosattr_set_ro(int fildes, const char *fname)
+{
+ nvlist_t *nvl = NULL;
+ int err;
+
+ err = nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0);
+ if (err != 0)
+ return (err);
+
+ (void) nvlist_add_boolean_value(nvl, A_READONLY, 1);
+
+ if (fname == NULL) {
+ err = fsetattr(fildes, XATTR_VIEW_READWRITE, nvl);
+ } else {
+ err = setattrat(fildes, XATTR_VIEW_READWRITE, fname, nvl);
+ }
+ if (err < 0) {
+ err = errno;
+ if (vflag > 1) {
+ (void) fprintf(stderr,
+ "dosattr_set: setattrat (%s), err %d\n",
+ fname, err);
+ }
+ }
+
+ nvlist_free(nvl);
+
+ return (err);
+}
+
+void
+usage(void)
+{
+ (void) fprintf(stderr, "usage: %s [-v] file\n",
+ __progname);
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ char *fname;
+ int c, fd, n;
+
+ while ((c = getopt(argc, argv, "v")) != -1) {
+ switch (c) {
+ case 'v':
+ vflag++;
+ break;
+ case '?':
+ default:
+ usage();
+ break;
+ }
+ }
+
+ if (optind + 1 != argc)
+ usage();
+ fname = argv[optind];
+
+ fd = open(fname, O_CREAT | O_RDWR, 0644);
+ if (fd < 0) {
+ perror(fname);
+ exit(1);
+ }
+
+ if (vflag)
+ (void) fprintf(stderr, "Write 1 (mode 644)\n");
+ n = write(fd, "mode 644 OK\n", 12);
+ if (n != 12) {
+ (void) fprintf(stderr, "write mode 644, err=%d\n", errno);
+ exit(1);
+ }
+
+ if (vflag)
+ (void) fprintf(stderr, "Chmod 444\n");
+ n = fchmod(fd, 0444);
+ if (n < 0) {
+ (void) fprintf(stderr, "chmod 444, err=%d\n", errno);
+ exit(1);
+ }
+
+ if (vflag)
+ (void) fprintf(stderr, "Write 2 (mode 444)\n");
+ n = write(fd, "mode 444 OK\n", 12);
+ if (n != 12) {
+ (void) fprintf(stderr, "write mode 444, err=%d\n", errno);
+ exit(1);
+ }
+
+ if (vflag)
+ (void) fprintf(stderr, "Set DOS R/O\n");
+ n = dosattr_set_ro(fd, NULL /* fname? */);
+ if (n != 0) {
+ (void) fprintf(stderr, "Set R/O, err=%d\n", n);
+ exit(1);
+ }
+
+ /*
+ * This fails, but write on an already open handle should succeed
+ * the same as when we've set the mode to 444 after open.
+ */
+ if (vflag)
+ (void) fprintf(stderr, "Write 3 (DOS R/O)\n");
+ n = write(fd, "Write DOS RO?\n", 14);
+ if (n != 14) {
+ (void) fprintf(stderr, "write (DOS R/O), err=%d\n", errno);
+ exit(1);
+ }
+
+ return (0);
+}
diff --git a/usr/src/test/zfs-tests/include/commands.cfg b/usr/src/test/zfs-tests/include/commands.cfg
index afc3153e6e..462f0e55e3 100644
--- a/usr/src/test/zfs-tests/include/commands.cfg
+++ b/usr/src/test/zfs-tests/include/commands.cfg
@@ -172,6 +172,7 @@ export SBIN_FILES='fdisk
export ZFSTEST_FILES='chg_usr_exec
devname2devid
dir_rd_update
+ dos_ro
file_check
file_trunc
file_write
diff --git a/usr/src/test/zfs-tests/runfiles/delphix.run b/usr/src/test/zfs-tests/runfiles/delphix.run
index df1b6369b3..aaeb65de38 100644
--- a/usr/src/test/zfs-tests/runfiles/delphix.run
+++ b/usr/src/test/zfs-tests/runfiles/delphix.run
@@ -25,7 +25,8 @@ post = cleanup
outputdir = /var/tmp/test_results
[/opt/zfs-tests/tests/functional/acl/cifs]
-tests = ['cifs_attr_001_pos', 'cifs_attr_002_pos', 'cifs_attr_003_pos']
+tests = ['cifs_attr_001_pos', 'cifs_attr_002_pos', 'cifs_attr_003_pos',
+ 'cifs_attr_004_pos']
[/opt/zfs-tests/tests/functional/acl/nontrivial]
tests = ['zfs_acl_chmod_001_neg', 'zfs_acl_chmod_002_pos',
diff --git a/usr/src/test/zfs-tests/runfiles/omnios.run b/usr/src/test/zfs-tests/runfiles/omnios.run
index 952ab1503d..df7dbb2d0e 100644
--- a/usr/src/test/zfs-tests/runfiles/omnios.run
+++ b/usr/src/test/zfs-tests/runfiles/omnios.run
@@ -25,7 +25,8 @@ post = cleanup
outputdir = /var/tmp/test_results
[/opt/zfs-tests/tests/functional/acl/cifs]
-tests = ['cifs_attr_001_pos', 'cifs_attr_002_pos', 'cifs_attr_003_pos']
+tests = ['cifs_attr_001_pos', 'cifs_attr_002_pos', 'cifs_attr_003_pos',
+ 'cifs_attr_004_pos']
[/opt/zfs-tests/tests/functional/acl/nontrivial]
tests = ['zfs_acl_chmod_001_neg', 'zfs_acl_chmod_002_pos',
diff --git a/usr/src/test/zfs-tests/runfiles/openindiana.run b/usr/src/test/zfs-tests/runfiles/openindiana.run
index 407af74e57..81672aac69 100644
--- a/usr/src/test/zfs-tests/runfiles/openindiana.run
+++ b/usr/src/test/zfs-tests/runfiles/openindiana.run
@@ -25,7 +25,8 @@ post = cleanup
outputdir = /var/tmp/test_results
[/opt/zfs-tests/tests/functional/acl/cifs]
-tests = ['cifs_attr_001_pos', 'cifs_attr_002_pos', 'cifs_attr_003_pos']
+tests = ['cifs_attr_001_pos', 'cifs_attr_002_pos', 'cifs_attr_003_pos',
+ 'cifs_attr_004_pos']
[/opt/zfs-tests/tests/functional/acl/nontrivial]
tests = ['zfs_acl_chmod_001_neg', 'zfs_acl_chmod_002_pos',
diff --git a/usr/src/test/zfs-tests/tests/functional/acl/cifs/cifs_attr_003_pos.ksh b/usr/src/test/zfs-tests/tests/functional/acl/cifs/cifs_attr_003_pos.ksh
index a47ad0277b..09ddc4281a 100644
--- a/usr/src/test/zfs-tests/tests/functional/acl/cifs/cifs_attr_003_pos.ksh
+++ b/usr/src/test/zfs-tests/tests/functional/acl/cifs/cifs_attr_003_pos.ksh
@@ -376,6 +376,7 @@ function unit_writeacl
function test_readonly
{
typeset object=$1
+ typeset exp
if [[ -z $object ]]; then
log_fail "Object($object) not defined."
@@ -394,14 +395,21 @@ function test_readonly
log_must set_attribute $object "R"
- unit_writefile $object $user 1
+ # As with mode bits, root can bypass.
+ if [[ "$user" == "root" ]]; then
+ exp=0
+ else
+ exp=1
+ fi
+
+ unit_writefile $object $user $exp
unit_writedir $object $user
- unit_appenddata $object $user 1
+ unit_appenddata $object $user $exp
if [[ -d $object ]]; then
unit_writexattr $object $user
else
- unit_writexattr $object $user 1
+ unit_writexattr $object $user $exp
fi
unit_accesstime $object $user
diff --git a/usr/src/test/zfs-tests/tests/functional/acl/cifs/cifs_attr_004_pos.ksh b/usr/src/test/zfs-tests/tests/functional/acl/cifs/cifs_attr_004_pos.ksh
new file mode 100644
index 0000000000..b5055544b9
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/acl/cifs/cifs_attr_004_pos.ksh
@@ -0,0 +1,141 @@
+#!/bin/ksh -p
+#
+# 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 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+
+#
+# Copyright (c) 2012 by Delphix. All rights reserved.
+# Copyright 2017 Nexenta Systems, Inc. All rights reserved.
+#
+
+. $STF_SUITE/tests/functional/acl/acl_common.kshlib
+. $STF_SUITE/tests/functional/acl/cifs/cifs.kshlib
+
+#
+# DESCRIPTION:
+# Verify the ability to continue writing to a file
+# after opening the file read/write, and setting
+# the DOS Readonly flag on that file.
+#
+# STRATEGY:
+# Run the special program "dos_ro"
+
+verify_runnable "both"
+
+function cleanup
+{
+ if [[ -n $gobject ]]; then
+ destroy_object $gobject
+ fi
+
+ for fs in $TESTPOOL/$TESTFS $TESTPOOL ; do
+ mtpt=$(get_prop mountpoint $fs)
+ log_must rm -rf $mtpt/file.* $mtpt/dir.*
+ done
+
+ [[ -f $TESTFILE ]] && rm $TESTFILE
+}
+
+#
+# Set the special attribute to the given node
+#
+# $1: The given node (file/dir)
+# $2: The special attribute to be set
+#
+function set_attribute
+{
+ typeset object=$1
+ typeset attr=$2
+
+ if [[ -z $attr ]]; then
+ attr="AHRSadimu"
+ if [[ -f $object ]]; then
+ attr="${attr}q"
+ fi
+ fi
+ chmod S+c${attr} $object
+ return $?
+}
+
+#
+# Clear the special attribute to the given node
+#
+# $1: The given node (file/dir)
+# $2: The special attribute to be cleared
+#
+function clear_attribute
+{
+ typeset object=$1
+ typeset attr=$2
+
+ if [[ -z $attr ]]; then
+ if is_global_zone ; then
+ attr="AHRSadimu"
+ if [[ -f $object ]]; then
+ attr="${attr}q"
+ fi
+ else
+ attr="AHRS"
+ fi
+ fi
+
+ chmod S-c${attr} $object
+ return $?
+}
+
+FILES="file.0 file.1"
+FS="$TESTPOOL $TESTPOOL/$TESTFS"
+ATTRS="R"
+
+TESTFILE=/tmp/tfile
+TESTDIR=tdir
+TESTATTR=tattr
+TESTACL=user:$ZFS_ACL_OTHER1:write_data:allow
+TESTMODE=777
+TESTSTR="ZFS test suites"
+
+log_assert "Verify writable open handle still works after " \
+ "setting the DOS Readonly flag on a file."
+log_onexit cleanup
+
+echo "$TESTSTR" > $TESTFILE
+
+typeset gobject
+typeset gattr
+for fs in $FS ; do
+ mtpt=$(get_prop mountpoint $fs)
+ chmod 777 $mtpt
+ for user in root $ZFS_ACL_STAFF1; do
+ log_must set_cur_usr $user
+ for file in $FILES ; do
+ gobject=$mtpt/$file
+ create_object "file" $gobject $ZFS_ACL_CUR_USER
+ log_must dos_ro $gobject
+ destroy_object $gobject
+ done
+ done
+done
+
+log_pass "Writable handle OK after setting DOS R/O flag."
diff --git a/usr/src/uts/common/fs/zfs/arc.c b/usr/src/uts/common/fs/zfs/arc.c
index 58177cd7df..0acd1302fc 100644
--- a/usr/src/uts/common/fs/zfs/arc.c
+++ b/usr/src/uts/common/fs/zfs/arc.c
@@ -1076,6 +1076,7 @@ typedef struct l2arc_read_callback {
blkptr_t l2rcb_bp; /* original blkptr */
zbookmark_phys_t l2rcb_zb; /* original bookmark */
int l2rcb_flags; /* original flags */
+ abd_t *l2rcb_abd; /* temporary buffer */
} l2arc_read_callback_t;
typedef struct l2arc_write_callback {
@@ -5049,6 +5050,8 @@ top:
!HDR_L2_WRITING(hdr) && !HDR_L2_EVICTED(hdr) &&
!(l2arc_noprefetch && HDR_PREFETCH(hdr))) {
l2arc_read_callback_t *cb;
+ abd_t *abd;
+ uint64_t asize;
DTRACE_PROBE1(l2arc__hit, arc_buf_hdr_t *, hdr);
ARCSTAT_BUMP(arcstat_l2_hits);
@@ -5060,8 +5063,17 @@ top:
cb->l2rcb_zb = *zb;
cb->l2rcb_flags = zio_flags;
+ asize = vdev_psize_to_asize(vd, size);
+ if (asize != size) {
+ abd = abd_alloc_for_io(asize,
+ HDR_ISTYPE_METADATA(hdr));
+ cb->l2rcb_abd = abd;
+ } else {
+ abd = hdr->b_l1hdr.b_pabd;
+ }
+
ASSERT(addr >= VDEV_LABEL_START_SIZE &&
- addr + lsize < vd->vdev_psize -
+ addr + asize <= vd->vdev_psize -
VDEV_LABEL_END_SIZE);
/*
@@ -5073,7 +5085,7 @@ top:
ASSERT3U(HDR_GET_COMPRESS(hdr), !=,
ZIO_COMPRESS_EMPTY);
rzio = zio_read_phys(pio, vd, addr,
- size, hdr->b_l1hdr.b_pabd,
+ asize, abd,
ZIO_CHECKSUM_OFF,
l2arc_read_done, cb, priority,
zio_flags | ZIO_FLAG_DONT_CACHE |
@@ -6575,6 +6587,33 @@ l2arc_read_done(zio_t *zio)
mutex_enter(hash_lock);
ASSERT3P(hash_lock, ==, HDR_LOCK(hdr));
+ /*
+ * If the data was read into a temporary buffer,
+ * move it and free the buffer.
+ */
+ if (cb->l2rcb_abd != NULL) {
+ ASSERT3U(arc_hdr_size(hdr), <, zio->io_size);
+ if (zio->io_error == 0) {
+ abd_copy(hdr->b_l1hdr.b_pabd, cb->l2rcb_abd,
+ arc_hdr_size(hdr));
+ }
+
+ /*
+ * The following must be done regardless of whether
+ * there was an error:
+ * - free the temporary buffer
+ * - point zio to the real ARC buffer
+ * - set zio size accordingly
+ * These are required because zio is either re-used for
+ * an I/O of the block in the case of the error
+ * or the zio is passed to arc_read_done() and it
+ * needs real data.
+ */
+ abd_free(cb->l2rcb_abd);
+ zio->io_size = zio->io_orig_size = arc_hdr_size(hdr);
+ zio->io_abd = zio->io_orig_abd = hdr->b_l1hdr.b_pabd;
+ }
+
ASSERT3P(zio->io_abd, !=, NULL);
/*
@@ -6912,23 +6951,34 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
* Normally the L2ARC can use the hdr's data, but if
* we're sharing data between the hdr and one of its
* bufs, L2ARC needs its own copy of the data so that
- * the ZIO below can't race with the buf consumer. To
- * ensure that this copy will be available for the
+ * the ZIO below can't race with the buf consumer.
+ * Another case where we need to create a copy of the
+ * data is when the buffer size is not device-aligned
+ * and we need to pad the block to make it such.
+ * That also keeps the clock hand suitably aligned.
+ *
+ * To ensure that the copy will be available for the
* lifetime of the ZIO and be cleaned up afterwards, we
* add it to the l2arc_free_on_write queue.
*/
+ uint64_t asize = vdev_psize_to_asize(dev->l2ad_vdev,
+ size);
abd_t *to_write;
- if (!HDR_SHARED_DATA(hdr)) {
+ if (!HDR_SHARED_DATA(hdr) && size == asize) {
to_write = hdr->b_l1hdr.b_pabd;
} else {
- to_write = abd_alloc_for_io(size,
+ to_write = abd_alloc_for_io(asize,
HDR_ISTYPE_METADATA(hdr));
abd_copy(to_write, hdr->b_l1hdr.b_pabd, size);
+ if (asize != size) {
+ abd_zero_off(to_write, size,
+ asize - size);
+ }
l2arc_free_abd_on_write(to_write, size,
arc_buf_type(hdr));
}
wzio = zio_write_phys(pio, dev->l2ad_vdev,
- hdr->b_l2hdr.b_daddr, size, to_write,
+ hdr->b_l2hdr.b_daddr, asize, to_write,
ZIO_CHECKSUM_OFF, NULL, hdr,
ZIO_PRIORITY_ASYNC_WRITE,
ZIO_FLAG_CANFAIL, B_FALSE);
@@ -6938,11 +6988,6 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz)
zio_t *, wzio);
write_asize += size;
- /*
- * Keep the clock hand suitably device-aligned.
- */
- uint64_t asize = vdev_psize_to_asize(dev->l2ad_vdev,
- size);
write_psize += asize;
dev->l2ad_hand += asize;
diff --git a/usr/src/uts/common/fs/zfs/zfs_acl.c b/usr/src/uts/common/fs/zfs/zfs_acl.c
index f2ef7e5134..519b4355d5 100644
--- a/usr/src/uts/common/fs/zfs/zfs_acl.c
+++ b/usr/src/uts/common/fs/zfs/zfs_acl.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013 by Delphix. All rights reserved.
- * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/types.h>
@@ -2035,13 +2035,11 @@ zfs_zaccess_dataset_check(znode_t *zp, uint32_t v4_mode)
}
/*
- * Only check for READONLY on non-directories.
+ * Intentionally allow ZFS_READONLY through here.
+ * See zfs_zaccess_common().
*/
if ((v4_mode & WRITE_MASK_DATA) &&
- (((ZTOV(zp)->v_type != VDIR) &&
- (zp->z_pflags & (ZFS_READONLY | ZFS_IMMUTABLE))) ||
- (ZTOV(zp)->v_type == VDIR &&
- (zp->z_pflags & ZFS_IMMUTABLE)))) {
+ (zp->z_pflags & ZFS_IMMUTABLE)) {
return (SET_ERROR(EPERM));
}
@@ -2253,6 +2251,24 @@ zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode,
return (0);
}
+ /*
+ * Note: ZFS_READONLY represents the "DOS R/O" attribute.
+ * When that flag is set, we should behave as if write access
+ * were not granted by anything in the ACL. In particular:
+ * We _must_ allow writes after opening the file r/w, then
+ * setting the DOS R/O attribute, and writing some more.
+ * (Similar to how you can write after fchmod(fd, 0444).)
+ *
+ * Therefore ZFS_READONLY is ignored in the dataset check
+ * above, and checked here as if part of the ACL check.
+ * Also note: DOS R/O is ignored for directories.
+ */
+ if ((v4_mode & WRITE_MASK_DATA) &&
+ (ZTOV(zp)->v_type != VDIR) &&
+ (zp->z_pflags & ZFS_READONLY)) {
+ return (SET_ERROR(EPERM));
+ }
+
return (zfs_zaccess_aces_check(zp, working_mode, B_FALSE, cr));
}
diff --git a/usr/src/uts/common/fs/zfs/zfs_vnops.c b/usr/src/uts/common/fs/zfs/zfs_vnops.c
index efe36b7f10..cebd796a1f 100644
--- a/usr/src/uts/common/fs/zfs/zfs_vnops.c
+++ b/usr/src/uts/common/fs/zfs/zfs_vnops.c
@@ -719,9 +719,11 @@ zfs_write(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct)
}
/*
- * If immutable or not appending then return EPERM
+ * If immutable or not appending then return EPERM.
+ * Intentionally allow ZFS_READONLY through here.
+ * See zfs_zaccess_common()
*/
- if ((zp->z_pflags & (ZFS_IMMUTABLE | ZFS_READONLY)) ||
+ if ((zp->z_pflags & ZFS_IMMUTABLE) ||
((zp->z_pflags & ZFS_APPENDONLY) && !(ioflag & FAPPEND) &&
(uio->uio_loffset < zp->z_size))) {
ZFS_EXIT(zfsvfs);
@@ -2793,10 +2795,9 @@ zfs_setattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
return (SET_ERROR(EPERM));
}
- if ((mask & AT_SIZE) && (zp->z_pflags & ZFS_READONLY)) {
- ZFS_EXIT(zfsvfs);
- return (SET_ERROR(EPERM));
- }
+ /*
+ * Note: ZFS_READONLY is handled in zfs_zaccess_common.
+ */
/*
* Verify timestamps doesn't overflow 32 bits.
@@ -4701,8 +4702,12 @@ zfs_map(vnode_t *vp, offset_t off, struct as *as, caddr_t *addrp,
ZFS_ENTER(zfsvfs);
ZFS_VERIFY_ZP(zp);
+ /*
+ * Note: ZFS_READONLY is handled in zfs_zaccess_common.
+ */
+
if ((prot & PROT_WRITE) && (zp->z_pflags &
- (ZFS_IMMUTABLE | ZFS_READONLY | ZFS_APPENDONLY))) {
+ (ZFS_IMMUTABLE | ZFS_APPENDONLY))) {
ZFS_EXIT(zfsvfs);
return (SET_ERROR(EPERM));
}
diff --git a/usr/src/uts/common/rpc/auth_sys.h b/usr/src/uts/common/rpc/auth_sys.h
index 5f163d270b..ef66402245 100644
--- a/usr/src/uts/common/rpc/auth_sys.h
+++ b/usr/src/uts/common/rpc/auth_sys.h
@@ -116,8 +116,8 @@ extern bool_t xdr_gid_t(XDR *, gid_t *);
extern bool_t xdr_uid_t(XDR *, uid_t *);
#ifdef _KERNEL
-extern bool_t xdr_authkern(XDR *);
-extern bool_t xdr_authloopback(XDR *);
+extern bool_t xdr_authkern(XDR *, cred_t *);
+extern bool_t xdr_authloopback(XDR *, cred_t *);
extern enum auth_stat _svcauth_unix(struct svc_req *, struct rpc_msg *);
extern enum auth_stat _svcauth_short(struct svc_req *, struct rpc_msg *);
#endif
diff --git a/usr/src/uts/common/rpc/sec/auth_kern.c b/usr/src/uts/common/rpc/sec/auth_kern.c
index e045c1c08f..2c3286d35d 100644
--- a/usr/src/uts/common/rpc/sec/auth_kern.c
+++ b/usr/src/uts/common/rpc/sec/auth_kern.c
@@ -120,78 +120,117 @@ authkern_marshal(AUTH *auth, XDR *xdrs, struct cred *cr)
{
char *sercred;
XDR xdrm;
- struct opaque_auth *cred;
- bool_t ret = FALSE;
- const gid_t *gp, *gpend;
- int gidlen, credsize, namelen, rounded_namelen;
+ bool_t ret;
+ uint32_t gidlen, credsize, namelen, rounded_namelen;
int32_t *ptr;
char *nodename = uts_nodename();
+ uint_t startpos;
+
+ ASSERT(xdrs->x_op == XDR_ENCODE);
+ ASSERT(auth->ah_cred.oa_flavor == AUTH_SYS);
+ ASSERT(auth->ah_verf.oa_flavor == AUTH_NONE);
+ ASSERT(auth->ah_verf.oa_length == 0);
/*
* First we try a fast path to get through
* this very common operation.
*/
- gp = crgetgroups(cr);
+ namelen = (uint32_t)strlen(nodename);
+ if (namelen > MAX_MACHINE_NAME)
+ return (FALSE);
+ rounded_namelen = RNDUP(namelen);
+
+ /*
+ * NFIELDS is a number of the following fields we are going to encode:
+ * - stamp
+ * - strlen(machinename)
+ * - uid
+ * - gid
+ * - the number of gids
+ */
+#define NFIELDS 5
+ CTASSERT((NFIELDS + NGRPS) * BYTES_PER_XDR_UNIT +
+ RNDUP(MAX_MACHINE_NAME) <= MAX_AUTH_BYTES);
+
gidlen = crgetngroups(cr);
if (gidlen > NGRPS)
gidlen = NGRPS;
- gpend = &gp[gidlen-1];
- namelen = (int)strlen(nodename);
- rounded_namelen = RNDUP(namelen);
- credsize = 4 + 4 + rounded_namelen + 4 + 4 + 4 + gidlen * 4;
- ptr = XDR_INLINE(xdrs, 4 + 4 + credsize + 4 + 4);
- if (ptr) {
+ credsize = NFIELDS * BYTES_PER_XDR_UNIT + rounded_namelen +
+ gidlen * BYTES_PER_XDR_UNIT;
+ ASSERT(credsize <= MAX_AUTH_BYTES);
+#undef NFIELDS
+
+ /*
+ * We need to marshal both cred and verf parts of the rpc_msg body
+ * (call_body). For the cred part we need to inline the auth_flavor
+ * and the opaque auth body size. Then we inline the credsize bytes of
+ * the opaque auth body for the cred part. Finally we add the
+ * AUTH_NONE verifier (its auth_flavor and the opaque auth body size).
+ */
+ ptr = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT + credsize +
+ 2 * BYTES_PER_XDR_UNIT);
+ if (ptr != NULL) {
/*
* We can do the fast path.
*/
- IXDR_PUT_INT32(ptr, AUTH_UNIX); /* cred flavor */
- IXDR_PUT_INT32(ptr, credsize); /* cred len */
+ const gid_t *gp = crgetgroups(cr);
+
+ IXDR_PUT_U_INT32(ptr, AUTH_SYS); /* cred flavor */
+ IXDR_PUT_U_INT32(ptr, credsize); /* cred len */
+
IXDR_PUT_INT32(ptr, gethrestime_sec());
- IXDR_PUT_INT32(ptr, namelen);
- bcopy(nodename, (caddr_t)ptr, namelen);
- if (rounded_namelen - namelen)
- bzero(((caddr_t)ptr) + namelen,
- rounded_namelen - namelen);
+ IXDR_PUT_U_INT32(ptr, namelen);
+ bcopy(nodename, ptr, namelen);
+ if ((rounded_namelen - namelen) > 0)
+ bzero((char *)ptr + namelen, rounded_namelen - namelen);
ptr += rounded_namelen / BYTES_PER_XDR_UNIT;
- IXDR_PUT_INT32(ptr, crgetuid(cr));
- IXDR_PUT_INT32(ptr, crgetgid(cr));
- IXDR_PUT_INT32(ptr, gidlen);
- while (gp <= gpend) {
- IXDR_PUT_INT32(ptr, *gp++);
- }
- IXDR_PUT_INT32(ptr, AUTH_NULL); /* verf flavor */
- IXDR_PUT_INT32(ptr, 0); /* verf len */
+ IXDR_PUT_U_INT32(ptr, crgetuid(cr));
+ IXDR_PUT_U_INT32(ptr, crgetgid(cr));
+ IXDR_PUT_U_INT32(ptr, gidlen);
+ while (gidlen-- > 0)
+ IXDR_PUT_U_INT32(ptr, *gp++);
+
+ IXDR_PUT_U_INT32(ptr, AUTH_NULL); /* verf flavor */
+ IXDR_PUT_U_INT32(ptr, 0); /* verf len */
+
return (TRUE);
}
+
sercred = kmem_alloc(MAX_AUTH_BYTES, KM_SLEEP);
+
/*
- * serialize u struct stuff into sercred
+ * Serialize the auth body data into sercred.
*/
xdrmem_create(&xdrm, sercred, MAX_AUTH_BYTES, XDR_ENCODE);
- if (!xdr_authkern(&xdrm)) {
+ startpos = XDR_GETPOS(&xdrm);
+ if (!xdr_authkern(&xdrm, cr)) {
printf("authkern_marshal: xdr_authkern failed\n");
ret = FALSE;
goto done;
}
/*
- * Make opaque auth credentials that point at serialized u struct
+ * Make opaque auth credentials to point at the serialized auth body
+ * data.
*/
- cred = &(auth->ah_cred);
- cred->oa_length = XDR_GETPOS(&xdrm);
- cred->oa_base = sercred;
+ auth->ah_cred.oa_base = sercred;
+ auth->ah_cred.oa_length = XDR_GETPOS(&xdrm) - startpos;
+ ASSERT(auth->ah_cred.oa_length <= MAX_AUTH_BYTES);
/*
- * serialize credentials and verifiers (null)
+ * serialize credentials and verifier (null)
*/
if ((xdr_opaque_auth(xdrs, &(auth->ah_cred))) &&
(xdr_opaque_auth(xdrs, &(auth->ah_verf))))
ret = TRUE;
else
ret = FALSE;
+
done:
+ XDR_DESTROY(&xdrm);
kmem_free(sercred, MAX_AUTH_BYTES);
+
return (ret);
}
diff --git a/usr/src/uts/common/rpc/sec/auth_loopb.c b/usr/src/uts/common/rpc/sec/auth_loopb.c
index 8e4e4522ad..ab5318162b 100644
--- a/usr/src/uts/common/rpc/sec/auth_loopb.c
+++ b/usr/src/uts/common/rpc/sec/auth_loopb.c
@@ -32,8 +32,6 @@
* under license from the Regents of the University of California.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* auth_loopb.c, implements UNIX style authentication parameters in the
* kernel. Interfaces with svc_auth_loopback on the server. See
@@ -124,77 +122,120 @@ authloopback_marshal(AUTH *auth, XDR *xdrs, struct cred *cr)
{
char *sercred;
XDR xdrm;
- struct opaque_auth *cred;
- bool_t ret = FALSE;
- const gid_t *gp, *gpend;
- int gidlen, credsize, namelen, rounded_namelen;
+ bool_t ret;
+ uint32_t gidlen, credsize, namelen, rounded_namelen;
int32_t *ptr;
+ char *nodename = uts_nodename();
+ uint32_t maxgidlen;
+ uint_t startpos;
+
+ ASSERT(xdrs->x_op == XDR_ENCODE);
+ ASSERT(auth->ah_cred.oa_flavor == AUTH_LOOPBACK);
+ ASSERT(auth->ah_verf.oa_flavor == AUTH_NONE);
+ ASSERT(auth->ah_verf.oa_length == 0);
/*
* First we try a fast path to get through
* this very common operation.
*/
- gp = crgetgroups(cr);
+ namelen = (uint32_t)strlen(nodename);
+ if (namelen > MAX_MACHINE_NAME)
+ return (FALSE);
+ rounded_namelen = RNDUP(namelen);
+
+ /*
+ * NFIELDS is a number of the following fields we are going to encode:
+ * - stamp
+ * - strlen(machinename)
+ * - uid
+ * - gid
+ * - the number of gids
+ */
+#define NFIELDS 5
+ CTASSERT(NFIELDS * BYTES_PER_XDR_UNIT + RNDUP(MAX_MACHINE_NAME) <=
+ MAX_AUTH_BYTES);
+ maxgidlen = (MAX_AUTH_BYTES - NFIELDS * BYTES_PER_XDR_UNIT -
+ rounded_namelen) / BYTES_PER_XDR_UNIT;
+
gidlen = crgetngroups(cr);
- if (gidlen > NGRPS_LOOPBACK)
+ if (gidlen > maxgidlen)
return (FALSE);
- gpend = &gp[gidlen-1];
- namelen = (int)strlen(uts_nodename());
- rounded_namelen = RNDUP(namelen);
- credsize = 4 + 4 + rounded_namelen + 4 + 4 + 4 + gidlen * 4;
- ptr = XDR_INLINE(xdrs, 4 + 4 + credsize + 4 + 4);
- if (ptr) {
+ credsize = NFIELDS * BYTES_PER_XDR_UNIT + rounded_namelen +
+ gidlen * BYTES_PER_XDR_UNIT;
+ ASSERT(credsize <= MAX_AUTH_BYTES);
+#undef NFIELDS
+
+ /*
+ * We need to marshal both cred and verf parts of the rpc_msg body
+ * (call_body). For the cred part we need to inline the auth_flavor
+ * and the opaque auth body size. Then we inline the credsize bytes of
+ * the opaque auth body for the cred part. Finally we add the
+ * AUTH_NONE verifier (its auth_flavor and the opaque auth body size).
+ */
+ ptr = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT + credsize +
+ 2 * BYTES_PER_XDR_UNIT);
+ if (ptr != NULL) {
/*
* We can do the fast path.
*/
- IXDR_PUT_INT32(ptr, AUTH_LOOPBACK); /* cred flavor */
- IXDR_PUT_INT32(ptr, credsize); /* cred len */
+ const gid_t *gp = crgetgroups(cr);
+
+ IXDR_PUT_U_INT32(ptr, AUTH_LOOPBACK); /* cred flavor */
+ IXDR_PUT_U_INT32(ptr, credsize); /* cred len */
+
IXDR_PUT_INT32(ptr, gethrestime_sec());
- IXDR_PUT_INT32(ptr, namelen);
- bcopy(uts_nodename(), ptr, namelen);
- if (rounded_namelen - namelen)
- bzero(((caddr_t)ptr) + namelen,
- rounded_namelen - namelen);
+ IXDR_PUT_U_INT32(ptr, namelen);
+ bcopy(nodename, ptr, namelen);
+ if ((rounded_namelen - namelen) > 0)
+ bzero((char *)ptr + namelen, rounded_namelen - namelen);
ptr += rounded_namelen / BYTES_PER_XDR_UNIT;
- IXDR_PUT_INT32(ptr, crgetuid(cr));
- IXDR_PUT_INT32(ptr, crgetgid(cr));
- IXDR_PUT_INT32(ptr, gidlen);
- while (gp <= gpend) {
- IXDR_PUT_INT32(ptr, *gp++);
- }
- IXDR_PUT_INT32(ptr, AUTH_NULL); /* verf flavor */
- IXDR_PUT_INT32(ptr, 0); /* verf len */
+ IXDR_PUT_U_INT32(ptr, crgetuid(cr));
+ IXDR_PUT_U_INT32(ptr, crgetgid(cr));
+ IXDR_PUT_U_INT32(ptr, gidlen);
+ while (gidlen-- > 0)
+ IXDR_PUT_U_INT32(ptr, *gp++);
+
+ IXDR_PUT_U_INT32(ptr, AUTH_NONE); /* verf flavor */
+ IXDR_PUT_U_INT32(ptr, 0); /* verf len */
+
return (TRUE);
}
+
sercred = kmem_alloc(MAX_AUTH_BYTES, KM_SLEEP);
+
/*
- * serialize u struct stuff into sercred
+ * Serialize the auth body data into sercred.
*/
xdrmem_create(&xdrm, sercred, MAX_AUTH_BYTES, XDR_ENCODE);
- if (!xdr_authloopback(&xdrm)) {
+ startpos = XDR_GETPOS(&xdrm);
+ if (!xdr_authloopback(&xdrm, cr)) {
printf("authloopback_marshal: xdr_authloopback failed\n");
ret = FALSE;
goto done;
}
/*
- * Make opaque auth credentials that point at serialized u struct
+ * Make opaque auth credentials to point at the serialized auth body
+ * data.
*/
- cred = &(auth->ah_cred);
- cred->oa_length = XDR_GETPOS(&xdrm);
- cred->oa_base = sercred;
+ auth->ah_cred.oa_base = sercred;
+ auth->ah_cred.oa_length = XDR_GETPOS(&xdrm) - startpos;
+ ASSERT(auth->ah_cred.oa_length <= MAX_AUTH_BYTES);
/*
- * serialize credentials and verifiers (null)
+ * serialize credentials and verifier (null)
*/
if ((xdr_opaque_auth(xdrs, &(auth->ah_cred))) &&
(xdr_opaque_auth(xdrs, &(auth->ah_verf))))
ret = TRUE;
else
ret = FALSE;
+
done:
+ XDR_DESTROY(&xdrm);
kmem_free(sercred, MAX_AUTH_BYTES);
+
return (ret);
}
diff --git a/usr/src/uts/common/rpc/sec/authu_prot.c b/usr/src/uts/common/rpc/sec/authu_prot.c
index dbc719e03c..8b0bf90a5d 100644
--- a/usr/src/uts/common/rpc/sec/authu_prot.c
+++ b/usr/src/uts/common/rpc/sec/authu_prot.c
@@ -110,20 +110,18 @@ xdr_gid_t(XDR *xdrs, gid_t *ip)
* NOTE: this is an XDR_ENCODE only routine.
*/
bool_t
-xdr_authkern(XDR *xdrs)
+xdr_authkern(XDR *xdrs, cred_t *cr)
{
uid_t uid;
gid_t gid;
uint_t len;
caddr_t groups;
char *name = uts_nodename();
- struct cred *cr;
time_t now;
if (xdrs->x_op != XDR_ENCODE)
return (FALSE);
- cr = CRED();
uid = crgetuid(cr);
gid = crgetgid(cr);
len = crgetngroups(cr);
@@ -137,8 +135,7 @@ xdr_authkern(XDR *xdrs)
xdr_string(xdrs, &name, MAX_MACHINE_NAME) &&
xdr_uid_t(xdrs, &uid) &&
xdr_gid_t(xdrs, &gid) &&
- xdr_array(xdrs, &groups, &len, NGRPS, sizeof (int),
- (xdrproc_t)xdr_int))
+ xdr_array(xdrs, &groups, &len, NGRPS, sizeof (gid_t), xdr_gid_t))
return (TRUE);
return (FALSE);
}
@@ -148,20 +145,18 @@ xdr_authkern(XDR *xdrs)
* NOTE: this is an XDR_ENCODE only routine.
*/
bool_t
-xdr_authloopback(XDR *xdrs)
+xdr_authloopback(XDR *xdrs, cred_t *cr)
{
uid_t uid;
gid_t gid;
- int len;
+ uint_t len;
caddr_t groups;
char *name = uts_nodename();
- struct cred *cr;
time_t now;
if (xdrs->x_op != XDR_ENCODE)
return (FALSE);
- cr = CRED();
uid = crgetuid(cr);
gid = crgetgid(cr);
len = crgetngroups(cr);
@@ -171,8 +166,8 @@ xdr_authloopback(XDR *xdrs)
xdr_string(xdrs, &name, MAX_MACHINE_NAME) &&
xdr_uid_t(xdrs, &uid) &&
xdr_gid_t(xdrs, &gid) &&
- xdr_array(xdrs, &groups, (uint_t *)&len, NGRPS_LOOPBACK,
- sizeof (int), (xdrproc_t)xdr_int))
+ xdr_array(xdrs, &groups, &len, NGROUPS_UMAX, sizeof (gid_t),
+ xdr_gid_t))
return (TRUE);
return (FALSE);
}