summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpcmd.y16
-rw-r--r--usr/src/cmd/oamuser/lib/Makefile5
-rw-r--r--usr/src/cmd/oamuser/lib/get_ngm.c46
-rw-r--r--usr/src/cmd/oamuser/user/val_lgrp.c23
-rw-r--r--usr/src/cmd/perl/5.8.4/distrib/doio.c20
-rw-r--r--usr/src/cmd/perl/5.8.4/distrib/mg.c22
-rw-r--r--usr/src/cmd/praudit/token.c2
-rw-r--r--usr/src/cmd/print/lpset/lpset.c16
-rw-r--r--usr/src/cmd/smserverd/myaudit.c29
-rw-r--r--usr/src/cmd/ssh/libssh/common/uidswap.c16
-rw-r--r--usr/src/cmd/ssh/sshd/groupaccess.c29
-rw-r--r--usr/src/head/rpcsvc/svc_dg_priv.h14
-rw-r--r--usr/src/lib/libbsm/common/adt_token.c7
-rw-r--r--usr/src/lib/libbsm/common/au_to.c2
-rw-r--r--usr/src/lib/libbsm/common/audit_allocate.c14
-rw-r--r--usr/src/lib/libbsm/common/generic.c19
-rw-r--r--usr/src/lib/libc/port/gen/sysconf.c9
-rw-r--r--usr/src/lib/libnsl/nsl/_utility.c34
-rw-r--r--usr/src/lib/libnsl/nsl/t_alloc.c58
-rw-r--r--usr/src/lib/libnsl/rpc/auth_sys.c42
-rw-r--r--usr/src/lib/libnsl/rpc/netnamer.c15
-rw-r--r--usr/src/lib/libnsl/rpc/svc_dg.c11
-rw-r--r--usr/src/lib/libnsl/rpc/svc_door.c11
-rw-r--r--usr/src/lib/libnsl/rpc/svcauth_des.c28
-rw-r--r--usr/src/lib/libsocket/inet/rcmd.c10
-rw-r--r--usr/src/ucbcmd/groups/groups.c18
-rw-r--r--usr/src/uts/common/brand/lx/procfs/lx_proc.h7
-rw-r--r--usr/src/uts/common/c2/audit.c6
-rw-r--r--usr/src/uts/common/c2/audit_start.c4
-rw-r--r--usr/src/uts/common/c2/audit_syscalls.c2
-rw-r--r--usr/src/uts/common/conf/param.c13
-rw-r--r--usr/src/uts/common/fs/dev/sdev_vnops.c1
-rw-r--r--usr/src/uts/common/fs/nfs/nfs_subr.c2
-rw-r--r--usr/src/uts/common/fs/smbclnt/netsmb/smb_conn.c1
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_tree.c4
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_vnops.c2
-rw-r--r--usr/src/uts/common/inet/ip/conn_opt.c6
-rw-r--r--usr/src/uts/common/inet/ipf/ip_fil_solaris.c9
-rw-r--r--usr/src/uts/common/inet/udp/udp.c2
-rw-r--r--usr/src/uts/common/inet/udp/udp_opt_data.c9
-rw-r--r--usr/src/uts/common/io/tl.c73
-rw-r--r--usr/src/uts/common/os/cred.c231
-rw-r--r--usr/src/uts/common/rpc/auth_sys.h14
-rw-r--r--usr/src/uts/common/rpc/sec/auth_kern.c11
-rw-r--r--usr/src/uts/common/rpc/sec/authu_prot.c17
-rw-r--r--usr/src/uts/common/rpc/sec/svcauthdes.c16
-rw-r--r--usr/src/uts/common/sys/cred.h8
-rw-r--r--usr/src/uts/common/sys/cred_impl.h8
-rw-r--r--usr/src/uts/common/sys/param.h5
-rw-r--r--usr/src/uts/common/sys/ucred.h20
-rw-r--r--usr/src/uts/common/syscall/groups.c41
51 files changed, 627 insertions, 401 deletions
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpcmd.y b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpcmd.y
index 90cc538e81..cde2ccab4b 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpcmd.y
+++ b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpcmd.y
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,8 +34,6 @@
*/
%{
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "config.h"
#include <sys/param.h>
#include <sys/types.h>
@@ -60,6 +58,7 @@
#include <stdlib.h>
#include <string.h>
#include <limits.h>
+#include <alloca.h>
#include "extensions.h"
#include "pathnames.h"
#include "proto.h"
@@ -2495,10 +2494,15 @@ void cdpath(void)
void print_groups(void)
{
- gid_t groups[NGROUPS_MAX];
- int ngroups = 0;
+ gid_t *groups;
+ int ngroups;
+ int maxgrp;
+
+ maxgrp = getgroups(0, NULL);
+
+ groups = alloca(maxgrp * sizeof (gid_t));
- if ((ngroups = getgroups(NGROUPS_MAX, groups)) < 0) {
+ if ((ngroups = getgroups(maxgrp, groups)) < 0) {
return;
}
diff --git a/usr/src/cmd/oamuser/lib/Makefile b/usr/src/cmd/oamuser/lib/Makefile
index 3f6475621b..b431c2f5c8 100644
--- a/usr/src/cmd/oamuser/lib/Makefile
+++ b/usr/src/cmd/oamuser/lib/Makefile
@@ -19,11 +19,9 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
LIBRARY= lib.a
@@ -38,7 +36,6 @@ OBJECTS= putgrent.o \
vgname.o \
vgroup.o \
vuid.o \
- get_ngm.o \
vlogin.o \
vproj.o \
dates.o \
diff --git a/usr/src/cmd/oamuser/lib/get_ngm.c b/usr/src/cmd/oamuser/lib/get_ngm.c
deleted file mode 100644
index 409d7bd74f..0000000000
--- a/usr/src/cmd/oamuser/lib/get_ngm.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (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 1996 Sun Microsystems, Inc. All rights reserved. */
-/* Use is subject to license terms. */
-
-/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/param.h>
-#include <unistd.h>
-
-/*
- * read the value of NGROUPS_MAX from the kernel
- */
-int
-get_ngm(void)
-{
- static int ngm = -1;
-
- if (ngm == -1 &&
- (ngm = (int)sysconf(_SC_NGROUPS_MAX)) == -1)
- ngm = NGROUPS_UMAX;
-
- return (ngm);
-}
diff --git a/usr/src/cmd/oamuser/user/val_lgrp.c b/usr/src/cmd/oamuser/user/val_lgrp.c
index db7c0c0903..2ad9d38efb 100644
--- a/usr/src/cmd/oamuser/user/val_lgrp.c
+++ b/usr/src/cmd/oamuser/user/val_lgrp.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * 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.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -28,20 +27,19 @@
/* All Rights Reserved */
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <stdio.h>
+#include <stdlib.h>
#include <sys/param.h>
+#include <unistd.h>
#include <users.h>
#include <userdefs.h>
#include "messages.h"
-extern int get_ngm();
extern void exit();
extern char *strtok();
-static gid_t grplist[ NGROUPS_UMAX + 1 ];
+static gid_t *grplist;
static int ngroups_max = 0;
/* Validate a list of groups */
@@ -57,6 +55,11 @@ valid_lgroup(char *list, gid_t gid)
if( !list || !*list )
return( (int **) NULL );
+ if (ngroups_max == 0) {
+ ngroups_max = sysconf(_SC_NGROUPS_MAX);
+ grplist = malloc((ngroups_max + 1) * sizeof (gid_t));
+ }
+
while (ptr = strtok(((i || n_invalid || dup_prim)? NULL: list), ",")) {
switch (valid_group(ptr, &g_ptr, &warning)) {
@@ -98,10 +101,6 @@ valid_lgroup(char *list, gid_t gid)
if (warning)
warningmsg(warning, ptr);
- if( !ngroups_max )
- ngroups_max = get_ngm();
-
-
if( i >= ngroups_max ) {
errmsg( M_MAXGROUPS, ngroups_max );
break;
diff --git a/usr/src/cmd/perl/5.8.4/distrib/doio.c b/usr/src/cmd/perl/5.8.4/distrib/doio.c
index e452bc3a4e..e4fdd87266 100644
--- a/usr/src/cmd/perl/5.8.4/distrib/doio.c
+++ b/usr/src/cmd/perl/5.8.4/distrib/doio.c
@@ -1,3 +1,7 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
/* doio.c
*
* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
@@ -34,6 +38,10 @@
#endif
#endif
+#if defined(HAS_GETGROUPS) && defined(__sun)
+#include <alloca.h>
+#endif
+
#ifdef I_UTIME
# if defined(_MSC_VER) || defined(__MINGW32__)
# include <sys/utime.h>
@@ -1877,13 +1885,21 @@ Perl_ingroup(pTHX_ Gid_t testgid, Uid_t effective)
return TRUE;
#ifdef HAS_GETGROUPS
#ifndef NGROUPS
-#define NGROUPS 32
+#define NGROUPS 32
#endif
{
- Groups_t gary[NGROUPS];
I32 anum;
+#ifdef __sun
+ int maxgrp = getgroups(0, NULL);
+ Groups_t *gary = alloca(maxgrp * sizeof (Groups_t));
+
+ anum = getgroups(maxgrp,gary);
+#else
+ Groups_t gary[NGROUPS];
anum = getgroups(NGROUPS,gary);
+#endif
+
while (--anum >= 0)
if (gary[anum] == testgid)
return TRUE;
diff --git a/usr/src/cmd/perl/5.8.4/distrib/mg.c b/usr/src/cmd/perl/5.8.4/distrib/mg.c
index 76ef523323..8dd7ef239c 100644
--- a/usr/src/cmd/perl/5.8.4/distrib/mg.c
+++ b/usr/src/cmd/perl/5.8.4/distrib/mg.c
@@ -1,3 +1,7 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
/* mg.c
*
* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
@@ -28,6 +32,10 @@
# ifdef I_GRP
# include <grp.h>
# endif
+#ifdef __sun
+#include <alloca.h>
+#include <unistd.h>
+#endif
#endif
#ifdef __hpux
@@ -891,8 +899,14 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
add_groups:
#ifdef HAS_GETGROUPS
{
+#ifdef __sun
+ int maxgrp = getgroups(0, NULL);
+ Groups_t *gary = alloca(maxgrp * sizeof (Groups_t));
+ i = getgroups(maxgrp,gary);
+#else
Groups_t gary[NGROUPS];
i = getgroups(NGROUPS,gary);
+#endif
while (--i >= 0)
Perl_sv_catpvf(aTHX_ sv, " %"Gid_t_f, gary[i]);
}
@@ -2368,12 +2382,18 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg)
#ifdef HAS_SETGROUPS
{
char *p = SvPV(sv, len);
+#ifdef _SC_NGROUPS_MAX
+ int maxgrp = sysconf(_SC_NGROUPS_MAX);
+ Groups_t *gary = alloca(maxgrp * sizeof (Groups_t));
+#else
+ int maxgrp = NGROUPS;
Groups_t gary[NGROUPS];
+#endif
while (isSPACE(*p))
++p;
PL_egid = Atol(p);
- for (i = 0; i < NGROUPS; ++i) {
+ for (i = 0; i < maxgrp; ++i) {
while (*p && !isSPACE(*p))
++p;
while (isSPACE(*p))
diff --git a/usr/src/cmd/praudit/token.c b/usr/src/cmd/praudit/token.c
index 4c1c0ba02b..f52291d8d6 100644
--- a/usr/src/cmd/praudit/token.c
+++ b/usr/src/cmd/praudit/token.c
@@ -1808,6 +1808,8 @@ attribute64_token(pr_context_t *context)
* return codes : -1 - error
* : 0 - successful
* NOTE: At the time of call, the group token id has been retrieved
+ * NOTE: This token is obsolete; it supports exactly NGROUPS_MAX
+ * groups.
*
* Format of group token:
* group token id adr_char
diff --git a/usr/src/cmd/print/lpset/lpset.c b/usr/src/cmd/print/lpset/lpset.c
index d0a765caea..04b0cc7677 100644
--- a/usr/src/cmd/print/lpset/lpset.c
+++ b/usr/src/cmd/print/lpset/lpset.c
@@ -19,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
@@ -39,6 +37,7 @@
#include <libintl.h>
#endif
#include <pwd.h>
+#include <alloca.h>
#include <ns.h>
#include <list.h>
@@ -54,8 +53,9 @@ authorized()
{
struct passwd *pw;
uid_t uid;
- gid_t list[NGROUPS_MAX];
+ gid_t *list;
int len;
+ int maxgrp;
if ((uid = getuid()) == 0)
return (1); /* "root" is authorized */
@@ -69,8 +69,12 @@ authorized()
if (chkauthattr("solaris.print.admin", pw->pw_name) == 1)
return (1); /* "solaris.print.admin" is authorized */
- if ((len = getgroups(sizeof (list), list)) != -1)
- for (; len >= 0; len--)
+ /* How many supplemental groups do we have? */
+ maxgrp = getgroups(0, NULL);
+ list = alloca(maxgrp * sizeof (gid_t));
+
+ if ((len = getgroups(maxgrp, list)) != -1)
+ while (len-- > 0)
if (list[len] == 14)
return (1); /* group 14 is authorized */
diff --git a/usr/src/cmd/smserverd/myaudit.c b/usr/src/cmd/smserverd/myaudit.c
index ecc0227c6d..845f53fe8b 100644
--- a/usr/src/cmd/smserverd/myaudit.c
+++ b/usr/src/cmd/smserverd/myaudit.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -36,6 +36,7 @@
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
+#include <alloca.h>
#include <sys/smedia.h>
#include <tsol/label.h>
#include "smserver.h"
@@ -129,7 +130,7 @@ audit_save_me(door_data_t *door_dp)
return (ret_val);
door_dp->audit_ap.ap_pid = client_cred.dc_pid;
ret_val = auditon(A_GETPINFO_ADDR, (caddr_t)&door_dp->audit_ap,
- sizeof (door_dp->audit_ap));
+ sizeof (door_dp->audit_ap));
if (ret_val == -1)
return (ret_val);
@@ -144,7 +145,7 @@ audit_save_me(door_data_t *door_dp)
door_dp->audit_tid.at_type = door_dp->audit_ap.ap_termid.at_type;
for (i = 0; i < (door_dp->audit_ap.ap_termid.at_type/4); i++)
door_dp->audit_tid.at_addr[i] =
- door_dp->audit_ap.ap_termid.at_addr[i];
+ door_dp->audit_ap.ap_termid.at_addr[i];
(void) audit_save_policy(door_dp);
return (0);
}
@@ -205,19 +206,19 @@ audit_audit(door_data_t *door_dp)
}
(void) au_write(ad, au_to_subject_ex(door_dp->audit_auid,
- door_dp->audit_euid,
- door_dp->audit_egid,
- door_dp->audit_uid, door_dp->audit_gid, door_dp->audit_pid,
- door_dp->audit_asid, &door_dp->audit_tid));
+ door_dp->audit_euid,
+ door_dp->audit_egid,
+ door_dp->audit_uid, door_dp->audit_gid, door_dp->audit_pid,
+ door_dp->audit_asid, &door_dp->audit_tid));
if (is_system_labeled())
(void) au_write(ad, au_to_mylabel());
if (door_dp->audit_policy & AUDIT_GROUP) {
int ng;
- gid_t grplst[NGROUPS_MAX];
+ int maxgrp = getgroups(0, NULL);
+ gid_t *grplst = alloca(maxgrp * sizeof (gid_t));
- (void) memset(grplst, 0, sizeof (grplst));
- if ((ng = getgroups(NGROUPS_UMAX, grplst))) {
+ if ((ng = getgroups(maxgrp, grplst))) {
(void) au_write(ad, au_to_newgroups(ng, grplst));
}
}
@@ -232,10 +233,10 @@ audit_audit(door_data_t *door_dp)
}
#ifdef _LP64
(void) au_write(ad, au_to_return64((door_dp->audit_sorf == 0) ? 0 : -1,
- (int64_t)door_dp->audit_sorf));
+ (int64_t)door_dp->audit_sorf));
#else
(void) au_write(ad, au_to_return32((door_dp->audit_sorf == 0) ? 0 : -1,
- (int32_t)door_dp->audit_sorf));
+ (int32_t)door_dp->audit_sorf));
#endif
if (au_close(ad, 1, door_dp->audit_event) < 0) {
(void) au_close(ad, 0, 0);
@@ -253,7 +254,7 @@ audit_na_selected(door_data_t *door_dp)
}
return (selected(door_dp->audit_event,
- &door_dp->audit_namask, door_dp->audit_sorf));
+ &door_dp->audit_namask, door_dp->audit_sorf));
}
static int
@@ -266,7 +267,7 @@ audit_selected(door_data_t *door_dp)
}
return (selected(door_dp->audit_event,
- &door_dp->audit_ap.ap_mask, door_dp->audit_sorf));
+ &door_dp->audit_ap.ap_mask, door_dp->audit_sorf));
}
static int
diff --git a/usr/src/cmd/ssh/libssh/common/uidswap.c b/usr/src/cmd/ssh/libssh/common/uidswap.c
index 32256b4718..942b22a749 100644
--- a/usr/src/cmd/ssh/libssh/common/uidswap.c
+++ b/usr/src/cmd/ssh/libssh/common/uidswap.c
@@ -46,7 +46,8 @@ static gid_t saved_egid = 0;
/* Saved effective uid. */
static int privileged = 0;
static int temporarily_use_uid_effective = 0;
-static gid_t saved_egroups[NGROUPS_UMAX], user_groups[NGROUPS_UMAX];
+static int ngroups_max = -1;
+static gid_t *saved_egroups, *user_groups;
static int saved_egroupslen = -1, user_groupslen = -1;
/*
@@ -76,7 +77,16 @@ temporarily_use_uid(struct passwd *pw)
privileged = 1;
temporarily_use_uid_effective = 1;
- saved_egroupslen = getgroups(NGROUPS_UMAX, saved_egroups);
+
+ if (ngroups_max < 0) {
+ ngroups_max = sysconf(_SC_NGROUPS_MAX);
+ saved_egroups = malloc(ngroups_max * sizeof (gid_t));
+ user_groups = malloc(ngroups_max * sizeof (gid_t));
+ if (saved_egroups == NULL || user_groups == NULL)
+ fatal("malloc(gid array): %.100s", strerror(errno));
+ }
+
+ saved_egroupslen = getgroups(ngroups_max, saved_egroups);
if (saved_egroupslen < 0)
fatal("getgroups: %.100s", strerror(errno));
@@ -85,7 +95,7 @@ temporarily_use_uid(struct passwd *pw)
if (initgroups(pw->pw_name, pw->pw_gid) < 0)
fatal("initgroups: %s: %.100s", pw->pw_name,
strerror(errno));
- user_groupslen = getgroups(NGROUPS_UMAX, user_groups);
+ user_groupslen = getgroups(ngroups_max, user_groups);
if (user_groupslen < 0)
fatal("getgroups: %.100s", strerror(errno));
}
diff --git a/usr/src/cmd/ssh/sshd/groupaccess.c b/usr/src/cmd/ssh/sshd/groupaccess.c
index 2d8aa3ca80..2239832e1b 100644
--- a/usr/src/cmd/ssh/sshd/groupaccess.c
+++ b/usr/src/cmd/ssh/sshd/groupaccess.c
@@ -1,4 +1,8 @@
/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
* Copyright (c) 2001 Kevin Steves. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,9 +33,10 @@ RCSID("$OpenBSD: groupaccess.c,v 1.5 2002/03/04 17:27:39 stevesk Exp $");
#include "xmalloc.h"
#include "match.h"
#include "log.h"
+#include <alloca.h>
-static int ngroups;
-static char *groups_byname[NGROUPS_UMAX + 1]; /* +1 for base/primary group */
+static int ngroups, ngroups_lim;
+static char **groups_byname;
/*
* Initialize group access list for user with primary (base) and
@@ -40,14 +45,20 @@ static char *groups_byname[NGROUPS_UMAX + 1]; /* +1 for base/primary group */
int
ga_init(const char *user, gid_t base)
{
- gid_t groups_bygid[NGROUPS_UMAX + 1];
+ gid_t *groups_bygid;
int i, j;
struct group *gr;
- if (ngroups > 0)
+ if (ngroups_lim == 0) {
+ /* Add one for the base gid */
+ ngroups_lim = sysconf(_SC_NGROUPS_MAX) + 1;
+ groups_byname = malloc(sizeof (char *) * ngroups_lim);
+ } else if (ngroups > 0)
ga_free();
- ngroups = sizeof(groups_bygid) / sizeof(gid_t);
+ groups_bygid = alloca(ngroups_lim * sizeof (gid_t));
+
+ ngroups = ngroups_lim;
if (getgrouplist(user, base, groups_bygid, &ngroups) == -1)
log("getgrouplist: groups list too small");
for (i = 0, j = 0; i < ngroups; i++)
@@ -68,8 +79,8 @@ ga_match(char * const *groups, int n)
for (i = 0; i < ngroups; i++)
for (j = 0; j < n; j++)
if (match_pattern(groups_byname[i], groups[j]))
- return 1;
- return 0;
+ return (1);
+ return (0);
}
/*
@@ -86,14 +97,14 @@ ga_match_pattern_list(const char *group_pattern)
switch (match_pattern_list(groups_byname[i],
group_pattern, len, 0)) {
case -1:
- return 0; /* Negated match wins */
+ return (0); /* Negated match wins */
case 0:
continue;
case 1:
found = 1;
}
}
- return found;
+ return (found);
}
/*
diff --git a/usr/src/head/rpcsvc/svc_dg_priv.h b/usr/src/head/rpcsvc/svc_dg_priv.h
index 9db92bb5a6..80d2294f73 100644
--- a/usr/src/head/rpcsvc/svc_dg_priv.h
+++ b/usr/src/head/rpcsvc/svc_dg_priv.h
@@ -20,15 +20,13 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SVC_DG_PRIV_H
#define _SVC_DG_PRIV_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* The svc_dg_data private datastructure shared by some services
* for nefarious reasons. THIS IS NOT AN INTERFACE. DO NOT USE.
@@ -38,7 +36,13 @@
extern "C" {
#endif
-#define MAX_OPT_WORDS 128 /* needs to fit a ucred */
+/*
+ * The size of the option header should include sufficient space for
+ * a ucred; we reserve 32 words as before we had ucreds and we allocate
+ * sizeof (svc_dg_data) + ucred_size(). Of course, opts must be declared
+ * last so it can use the additional memory.
+ */
+#define MAX_OPT_WORDS 32
/*
* kept in xprt->xp_p2
@@ -46,13 +50,13 @@ extern "C" {
struct svc_dg_data {
/* Note: optbuf must be the first field, used by ti_opts.c code */
struct netbuf optbuf; /* netbuf for options */
- int opts[MAX_OPT_WORDS]; /* options */
uint_t su_iosz; /* size of send.recv buffer */
uint32_t su_xid; /* transaction id */
XDR su_xdrs; /* XDR handle */
char su_verfbody[MAX_AUTH_BYTES]; /* verifier body */
char *su_cache; /* cached data, NULL if none */
struct t_unitdata su_tudata; /* tu_data for recv */
+ int opts[MAX_OPT_WORDS]; /* options: MUST BE LAST */
};
#define get_svc_dg_data(xprt) ((struct svc_dg_data *)((xprt)->xp_p2))
diff --git a/usr/src/lib/libbsm/common/adt_token.c b/usr/src/lib/libbsm/common/adt_token.c
index fcb537e3f5..f217e6737e 100644
--- a/usr/src/lib/libbsm/common/adt_token.c
+++ b/usr/src/lib/libbsm/common/adt_token.c
@@ -32,6 +32,7 @@
#include <bsm/audit.h>
#include <adt_xlate.h>
+#include <alloca.h>
#include <assert.h>
#include <netdb.h>
#include <priv.h>
@@ -598,10 +599,10 @@ adt_to_subject(datadef *def, void *p_data, int required,
if (sp->as_session_model == ADT_PROCESS_MODEL) {
if (sp->as_kernel_audit_policy & AUDIT_GROUP) {
int group_count;
- gid_t grouplist[NGROUPS_MAX];
+ int maxgrp = getgroups(0, NULL);
+ gid_t *grouplist = alloca(maxgrp * sizeof (gid_t));
- if ((group_count = getgroups(NGROUPS_UMAX,
- grouplist)) > 0) {
+ if ((group_count = getgroups(maxgrp, grouplist)) > 0) {
(void) au_write(event->ae_event_handle,
au_to_newgroups(group_count, grouplist));
}
diff --git a/usr/src/lib/libbsm/common/au_to.c b/usr/src/lib/libbsm/common/au_to.c
index c31ed8ba41..9ee2dd7b7a 100644
--- a/usr/src/lib/libbsm/common/au_to.c
+++ b/usr/src/lib/libbsm/common/au_to.c
@@ -1090,7 +1090,7 @@ au_to_newgroups(int n, gid_t *groups)
char data_header = AUT_NEWGROUPS; /* header for this token */
short n_groups;
- if (n < NGROUPS_UMIN || n > NGROUPS_UMAX || groups == NULL)
+ if (n < 0 || n > SHRT_MAX || groups == NULL)
return (NULL);
token = get_token(sizeof (char) + sizeof (short) + n * sizeof (gid_t));
if (token == NULL)
diff --git a/usr/src/lib/libbsm/common/audit_allocate.c b/usr/src/lib/libbsm/common/audit_allocate.c
index 3dfbf3ef65..6bae7be18f 100644
--- a/usr/src/lib/libbsm/common/audit_allocate.c
+++ b/usr/src/lib/libbsm/common/audit_allocate.c
@@ -19,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <tsol/label.h>
#include <bsm/audit.h>
@@ -35,6 +33,7 @@
#include <bsm/audit_uevents.h>
#include <generic.h>
#include <stdlib.h>
+#include <alloca.h>
static int s_audit; /* successful audit event */
static int f_audit; /* failure audit event */
@@ -92,7 +91,6 @@ audit_allocate_record(status)
au_event_t event; /* audit event number */
int policy; /* audit policy */
int ng; /* number of groups in process */
- gid_t grplst[NGROUPS_UMAX];
#ifdef DEBUG
printf(("audit_allocate_record(%d)\n", status));
@@ -130,8 +128,12 @@ audit_allocate_record(status)
(void) au_write(ad, au_to_mylabel());
if (policy & AUDIT_GROUP) { /* add optional group token */
- (void) memset(grplst, 0, sizeof (grplst));
- if ((ng = getgroups(NGROUPS_UMAX, grplst)) < 0) {
+ gid_t *grplst;
+ int maxgrp = getgroups(0, NULL);
+
+ grplst = alloca(maxgrp * sizeof (gid_t));
+
+ if ((ng = getgroups(maxgrp, grplst)) < 0) {
(void) au_close(ad, 0, 0);
if (!status)
return (1);
diff --git a/usr/src/lib/libbsm/common/generic.c b/usr/src/lib/libbsm/common/generic.c
index 5e59bcd1ce..e1d1929070 100644
--- a/usr/src/lib/libbsm/common/generic.c
+++ b/usr/src/lib/libbsm/common/generic.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,6 +34,7 @@
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
+#include <alloca.h>
#include <stdlib.h>
#include <tsol/label.h>
#include <bsm/audit.h>
@@ -174,14 +175,14 @@ aug_get_machine(const char *hostname, uint32_t *buf, uint32_t *type)
case AF_INET:
/* LINTED */
p = &((struct sockaddr_in *)ai->ai_addr)->sin_addr,
- (void) memcpy(buf, p,
+ (void) memcpy(buf, p,
sizeof (((struct sockaddr_in *)0)->sin_addr));
*type = AU_IPv4;
break;
case AF_INET6:
/* LINTED */
p = &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr,
- (void) memcpy(buf, p,
+ (void) memcpy(buf, p,
sizeof (((struct sockaddr_in6 *)0)->sin6_addr));
*type = AU_IPv6;
break;
@@ -280,8 +281,8 @@ aug_save_me(void)
aug_save_pid(getpid());
aug_save_asid(ai.ai_asid);
aug_save_tid_ex(ai.ai_termid.at_port,
- ai.ai_termid.at_addr,
- ai.ai_termid.at_type);
+ ai.ai_termid.at_addr,
+ ai.ai_termid.at_type);
return (0);
}
@@ -414,15 +415,15 @@ aug_audit(void)
}
(void) au_write(ad, au_to_subject_ex(aug_auid, aug_euid, aug_egid,
- aug_uid, aug_gid, aug_pid, aug_asid, &aug_tid));
+ aug_uid, aug_gid, aug_pid, aug_asid, &aug_tid));
if (is_system_labeled())
(void) au_write(ad, au_to_mylabel());
if (aug_policy & AUDIT_GROUP) {
int ng;
- gid_t grplst[NGROUPS_UMAX];
+ int maxgrp = getgroups(0, NULL);
+ gid_t *grplst = alloca(maxgrp * sizeof (gid_t));
- (void) memset(grplst, 0, sizeof (grplst));
- if ((ng = getgroups(NGROUPS_UMAX, grplst))) {
+ if ((ng = getgroups(maxgrp, grplst)) > 0) {
(void) au_write(ad, au_to_newgroups(ng, grplst));
}
}
diff --git a/usr/src/lib/libc/port/gen/sysconf.c b/usr/src/lib/libc/port/gen/sysconf.c
index 26415015c3..8c2e6f4eb2 100644
--- a/usr/src/lib/libc/port/gen/sysconf.c
+++ b/usr/src/lib/libc/port/gen/sysconf.c
@@ -20,15 +20,13 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* sysconf(3C) - returns system configuration information */
#pragma weak _sysconf = sysconf
@@ -57,6 +55,7 @@ sysconf(int name)
static int _hz = 0;
static pid_t _maxpid = 0;
static int _stackprot = 0;
+ static int _ngroups_max;
extern int __xpg4;
switch (name) {
@@ -82,7 +81,9 @@ sysconf(int name)
return (_sysconfig(_CONFIG_CHILD_MAX));
case _SC_NGROUPS_MAX:
- return (_sysconfig(_CONFIG_NGROUPS));
+ if (_ngroups_max <= 0)
+ _ngroups_max = _sysconfig(_CONFIG_NGROUPS);
+ return (_ngroups_max);
case _SC_OPEN_MAX:
return (_sysconfig(_CONFIG_OPEN_FILES));
diff --git a/usr/src/lib/libnsl/nsl/_utility.c b/usr/src/lib/libnsl/nsl/_utility.c
index 4f366a8978..f01cea5c6e 100644
--- a/usr/src/lib/libnsl/nsl/_utility.c
+++ b/usr/src/lib/libnsl/nsl/_utility.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * 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.
@@ -24,12 +23,10 @@
/* All Rights Reserved */
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "mt.h"
#include <stdlib.h>
#include <string.h>
@@ -48,6 +45,7 @@
#include <assert.h>
#include <syslog.h>
#include <limits.h>
+#include <ucred.h>
#include "tx.h"
#define DEFSIZE 2048
@@ -61,7 +59,7 @@
static struct _ti_user *find_tilink(int s);
static struct _ti_user *add_tilink(int s);
static void _t_free_lookbufs(struct _ti_user *tiptr);
-static unsigned int _t_setsize(t_scalar_t infosize);
+static unsigned int _t_setsize(t_scalar_t infosize, boolean_t option);
static int _t_cbuf_alloc(struct _ti_user *tiptr, char **retbuf);
static int _t_rbuf_alloc(struct _ti_user *tiptr, char **retbuf);
static int _t_adjust_state(int fd, int instate);
@@ -510,8 +508,8 @@ _t_alloc_bufs(int fd, struct _ti_user *tiptr, struct T_info_ack *tsap)
char *ctlbuf, *rcvbuf;
char *lookdbuf, *lookcbuf;
- csize = _t_setsize(tsap->CDATA_size);
- dsize = _t_setsize(tsap->DDATA_size);
+ csize = _t_setsize(tsap->CDATA_size, B_FALSE);
+ dsize = _t_setsize(tsap->DDATA_size, B_FALSE);
size1 = _T_MAX(csize, dsize);
@@ -527,13 +525,13 @@ _t_alloc_bufs(int fd, struct _ti_user *tiptr, struct T_info_ack *tsap)
lookdbuf = NULL;
}
- asize = _t_setsize(tsap->ADDR_size);
+ asize = _t_setsize(tsap->ADDR_size, B_FALSE);
if (tsap->OPT_size >= 0)
/* compensate for XTI level options */
optsize = tsap->OPT_size + TX_XTI_LEVEL_MAX_OPTBUF;
else
optsize = tsap->OPT_size;
- osize = _t_setsize(optsize);
+ osize = _t_setsize(optsize, B_TRUE);
/*
* We compute the largest buffer size needed for this provider by
@@ -593,10 +591,22 @@ _t_alloc_bufs(int fd, struct _ti_user *tiptr, struct T_info_ack *tsap)
* set sizes of buffers
*/
static unsigned int
-_t_setsize(t_scalar_t infosize)
+_t_setsize(t_scalar_t infosize, boolean_t option)
{
+ static size_t optinfsize;
+
switch (infosize) {
case T_INFINITE /* -1 */:
+ if (option) {
+ if (optinfsize == 0) {
+ size_t uc = ucred_size();
+ if (uc < DEFSIZE/2)
+ optinfsize = DEFSIZE;
+ else
+ optinfsize = ucred_size() + DEFSIZE/2;
+ }
+ return ((unsigned int)optinfsize);
+ }
return (DEFSIZE);
case T_INVALID /* -2 */:
return (0);
diff --git a/usr/src/lib/libnsl/nsl/t_alloc.c b/usr/src/lib/libnsl/nsl/t_alloc.c
index a8e05bc2d9..67d1204afc 100644
--- a/usr/src/lib/libnsl/nsl/t_alloc.c
+++ b/usr/src/lib/libnsl/nsl/t_alloc.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * 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.
@@ -24,12 +23,10 @@
/* All Rights Reserved */
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.4.1.2 */
-
#include "mt.h"
#include <stdlib.h>
#include <unistd.h>
@@ -41,6 +38,7 @@
#include <xti.h>
#include <stdio.h>
#include <errno.h>
+#include <ucred.h>
#include <signal.h>
#include "tx.h"
@@ -48,7 +46,7 @@
* Function protoypes
*/
static int _alloc_buf(struct netbuf *buf, t_scalar_t n, int fields,
- int api_semantics);
+ int api_semantics, boolean_t option);
char *
_tx_alloc(int fd, int struct_type, int fields, int api_semantics)
@@ -115,7 +113,7 @@ _tx_alloc(int fd, int struct_type, int fields, int api_semantics)
if (fields & T_ADDR) {
if (_alloc_buf(&p.bind->addr,
info.ADDR_size,
- fields, api_semantics) < 0)
+ fields, api_semantics, B_FALSE) < 0)
goto errout;
}
sig_mutex_unlock(&tiptr->ti_lock);
@@ -127,7 +125,7 @@ _tx_alloc(int fd, int struct_type, int fields, int api_semantics)
if (fields & T_ADDR) {
if (_alloc_buf(&p.call->addr,
info.ADDR_size,
- fields, api_semantics) < 0)
+ fields, api_semantics, B_FALSE) < 0)
goto errout;
}
if (fields & T_OPT) {
@@ -138,14 +136,14 @@ _tx_alloc(int fd, int struct_type, int fields, int api_semantics)
else
optsize = info.OPT_size;
if (_alloc_buf(&p.call->opt, optsize,
- fields, api_semantics) < 0)
+ fields, api_semantics, B_TRUE) < 0)
goto errout;
}
if (fields & T_UDATA) {
dsize = _T_MAX((int)info.CDATA_size,
- (int)info.DDATA_size);
+ (int)info.DDATA_size);
if (_alloc_buf(&p.call->udata, (t_scalar_t)dsize,
- fields, api_semantics) < 0)
+ fields, api_semantics, B_FALSE) < 0)
goto errout;
}
sig_mutex_unlock(&tiptr->ti_lock);
@@ -162,7 +160,7 @@ _tx_alloc(int fd, int struct_type, int fields, int api_semantics)
else
optsize = info.OPT_size;
if (_alloc_buf(&p.opt->opt, optsize,
- fields, api_semantics) < 0)
+ fields, api_semantics, B_TRUE) < 0)
goto errout;
}
sig_mutex_unlock(&tiptr->ti_lock);
@@ -173,7 +171,7 @@ _tx_alloc(int fd, int struct_type, int fields, int api_semantics)
goto errout;
if (fields & T_UDATA) {
if (_alloc_buf(&p.dis->udata, info.DDATA_size,
- fields, api_semantics) < 0)
+ fields, api_semantics, B_FALSE) < 0)
goto errout;
}
sig_mutex_unlock(&tiptr->ti_lock);
@@ -184,7 +182,7 @@ _tx_alloc(int fd, int struct_type, int fields, int api_semantics)
goto errout;
if (fields & T_ADDR) {
if (_alloc_buf(&p.udata->addr, info.ADDR_size,
- fields, api_semantics) < 0)
+ fields, api_semantics, B_FALSE) < 0)
goto errout;
}
if (fields & T_OPT) {
@@ -195,12 +193,12 @@ _tx_alloc(int fd, int struct_type, int fields, int api_semantics)
else
optsize = info.OPT_size;
if (_alloc_buf(&p.udata->opt, optsize,
- fields, api_semantics) < 0)
+ fields, api_semantics, B_TRUE) < 0)
goto errout;
}
if (fields & T_UDATA) {
if (_alloc_buf(&p.udata->udata, info.TSDU_size,
- fields, api_semantics) < 0)
+ fields, api_semantics, B_FALSE) < 0)
goto errout;
}
sig_mutex_unlock(&tiptr->ti_lock);
@@ -211,7 +209,7 @@ _tx_alloc(int fd, int struct_type, int fields, int api_semantics)
goto errout;
if (fields & T_ADDR) {
if (_alloc_buf(&p.uderr->addr, info.ADDR_size,
- fields, api_semantics) < 0)
+ fields, api_semantics, B_FALSE) < 0)
goto errout;
}
if (fields & T_OPT) {
@@ -222,7 +220,7 @@ _tx_alloc(int fd, int struct_type, int fields, int api_semantics)
else
optsize = info.OPT_size;
if (_alloc_buf(&p.uderr->opt, optsize,
- fields, api_semantics) < 0)
+ fields, api_semantics, B_FALSE) < 0)
goto errout;
}
sig_mutex_unlock(&tiptr->ti_lock);
@@ -262,7 +260,8 @@ errout:
}
static int
-_alloc_buf(struct netbuf *buf, t_scalar_t n, int fields, int api_semantics)
+_alloc_buf(struct netbuf *buf, t_scalar_t n, int fields, int api_semantics,
+ boolean_t option)
{
switch (n) {
case T_INFINITE /* -1 */:
@@ -277,6 +276,25 @@ _alloc_buf(struct netbuf *buf, t_scalar_t n, int fields, int api_semantics)
errno = EINVAL;
return (-1);
}
+ } else if (option) { /* TX_TLI_API */
+ static size_t infalloc;
+
+ /*
+ * retain TLI behavior; ucred_t can vary in size,
+ * we need to make sure that we can receive one.
+ */
+ if (infalloc == 0) {
+ size_t uc = ucred_size();
+ if (uc < 1024/2)
+ infalloc = 1024;
+ else
+ infalloc = uc + 1024/2;
+ }
+ if ((buf->buf = calloc(1, infalloc)) == NULL) {
+ errno = ENOMEM;
+ return (-1);
+ } else
+ buf->maxlen = infalloc;
} else { /* TX_TLI_API */
/*
* retain TLI behavior
diff --git a/usr/src/lib/libnsl/rpc/auth_sys.c b/usr/src/lib/libnsl/rpc/auth_sys.c
index 4b6485bbfa..8ec507bc07 100644
--- a/usr/src/lib/libnsl/rpc/auth_sys.c
+++ b/usr/src/lib/libnsl/rpc/auth_sys.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * 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.
@@ -21,7 +20,7 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
@@ -32,8 +31,6 @@
* California.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* auth_sys.c, Implements UNIX (system) style authentication parameters.
*
@@ -45,6 +42,7 @@
*/
#include "mt.h"
#include "rpc_mt.h"
+#include <alloca.h>
#include <stdio.h>
#include <syslog.h>
#include <stdlib.h>
@@ -100,13 +98,13 @@ authsys_create(const char *machname, const uid_t uid, const gid_t gid,
auth = malloc(sizeof (*auth));
if (auth == NULL) {
(void) syslog(LOG_ERR, auth_sys_str, authsys_create_str,
- __no_mem_auth);
+ __no_mem_auth);
return (NULL);
}
au = malloc(sizeof (*au));
if (au == NULL) {
(void) syslog(LOG_ERR, auth_sys_str, authsys_create_str,
- __no_mem_auth);
+ __no_mem_auth);
free(auth);
return (NULL);
}
@@ -132,21 +130,21 @@ authsys_create(const char *machname, const uid_t uid, const gid_t gid,
xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE);
if (!xdr_authsys_parms(&xdrs, &aup)) {
(void) syslog(LOG_ERR, auth_sys_str, authsys_create_str,
- ": xdr_authsys_parms failed");
+ ": xdr_authsys_parms failed");
return (NULL);
}
au->au_origcred.oa_length = XDR_GETPOS(&xdrs);
au->au_origcred.oa_flavor = AUTH_SYS;
if ((au->au_origcred.oa_base = malloc(au->au_origcred.oa_length)) ==
- NULL) {
+ NULL) {
(void) syslog(LOG_ERR, auth_sys_str, authsys_create_str,
- __no_mem_auth);
+ __no_mem_auth);
free(au);
free(auth);
return (NULL);
}
(void) memcpy(au->au_origcred.oa_base, mymem,
- (size_t)au->au_origcred.oa_length);
+ (size_t)au->au_origcred.oa_length);
/*
* set auth handle to reflect new cred.
@@ -173,7 +171,8 @@ authsys_create_default(void)
char machname[MAX_MACHINE_NAME + 1];
uid_t uid;
gid_t gid;
- gid_t gids[NGRPS];
+ int maxgrp = getgroups(0, NULL);
+ gid_t *gids = alloca(maxgrp * sizeof (gid_t));
if (gethostname(machname, MAX_MACHINE_NAME) == -1) {
(void) syslog(LOG_ERR, authsys_def_str, "hostname");
@@ -182,10 +181,12 @@ authsys_create_default(void)
machname[MAX_MACHINE_NAME] = 0;
uid = geteuid();
gid = getegid();
- if ((len = getgroups(NGRPS, gids)) < 0) {
+ if ((len = getgroups(maxgrp, gids)) < 0) {
(void) syslog(LOG_ERR, authsys_def_str, "groups");
return (NULL);
}
+ if (len > NGRPS)
+ len = NGRPS;
return (authsys_create(machname, uid, gid, len, gids));
}
@@ -205,22 +206,25 @@ authsys_create_ruid(void)
char machname[MAX_MACHINE_NAME + 1];
uid_t uid;
gid_t gid;
- gid_t gids[NGRPS];
+ int maxgrp = getgroups(0, NULL);
+ gid_t *gids = alloca(maxgrp * sizeof (gid_t));
AUTH *res;
if (gethostname(machname, MAX_MACHINE_NAME) == -1) {
(void) syslog(LOG_ERR,
- "authsys_create_ruid:gethostname failed");
+ "authsys_create_ruid:gethostname failed");
return (NULL);
}
machname[MAX_MACHINE_NAME] = 0;
uid = getuid();
gid = getgid();
- if ((len = getgroups(NGRPS, gids)) < 0) {
+ if ((len = getgroups(maxgrp, gids)) < 0) {
(void) syslog(LOG_ERR,
- "authsys_create_ruid:getgroups failed");
+ "authsys_create_ruid:getgroups failed");
return (NULL);
}
+ if (len > NGRPS)
+ len = NGRPS;
res = authsys_create(machname, uid, gid, len, gids);
return (res);
}
@@ -255,7 +259,7 @@ authsys_validate(AUTH *auth, struct opaque_auth *verf)
/* LINTED pointer alignment */
au = AUTH_PRIVATE(auth);
xdrmem_create(&xdrs, verf->oa_base,
- verf->oa_length, XDR_DECODE);
+ verf->oa_length, XDR_DECODE);
if (au->au_shcred.oa_base != NULL) {
free(au->au_shcred.oa_base);
diff --git a/usr/src/lib/libnsl/rpc/netnamer.c b/usr/src/lib/libnsl/rpc/netnamer.c
index f20434eb48..1748937088 100644
--- a/usr/src/lib/libnsl/rpc/netnamer.c
+++ b/usr/src/lib/libnsl/rpc/netnamer.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
@@ -37,8 +37,6 @@
* Well, at least the API doesn't involve pointers-to-static.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* netname utility routines convert from netnames to unix names (uid, gid)
*
@@ -52,6 +50,8 @@
#include "rpc_mt.h"
#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
+#include <alloca.h>
#include <sys/types.h>
#include <ctype.h>
#include <grp.h>
@@ -72,10 +72,6 @@ static const char PKTABLE[] = "cred.org_dir";
#define PKTABLE_LEN 12
#define OPSYS_LEN 4
-#ifndef NGROUPS
-#define NGROUPS 16
-#endif
-
extern int _getgroupsbymember(const char *, gid_t[], int, int);
/*
@@ -505,7 +501,8 @@ netname2user_ldap(int *err, char *netname, struct netid_userdata *argp)
int ngroups = 0;
int count;
char pwbuf[NSS_LINELEN_PASSWD];
- gid_t groups[NGROUPS_MAX];
+ int maxgrp = sysconf(_SC_NGROUPS_MAX);
+ gid_t *groups = alloca(maxgrp * sizeof (gid_t));
if (strlcpy(buf, netname, NSS_LINELEN_PASSWD) >= NSS_LINELEN_PASSWD) {
*err = __NSW_UNAVAIL;
@@ -539,7 +536,7 @@ netname2user_ldap(int *err, char *netname, struct netid_userdata *argp)
groups[0] = pw.pw_gid;
- ngroups = _getgroupsbymember(pw.pw_name, groups, NGROUPS_MAX,
+ ngroups = _getgroupsbymember(pw.pw_name, groups, maxgrp,
(pw.pw_gid <= MAXUID) ? 1 : 0);
if (ngroups < 0) {
diff --git a/usr/src/lib/libnsl/rpc/svc_dg.c b/usr/src/lib/libnsl/rpc/svc_dg.c
index 2785e12cef..030a1e52b1 100644
--- a/usr/src/lib/libnsl/rpc/svc_dg.c
+++ b/usr/src/lib/libnsl/rpc/svc_dg.c
@@ -48,6 +48,7 @@
#include <syslog.h>
#include <stdlib.h>
#include <string.h>
+#include <ucred.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -121,6 +122,7 @@ svc_dg_create_private(int fd, uint_t sendsize, uint_t recvsize)
SVCXPRT *xprt;
struct svc_dg_data *su = NULL;
struct t_info tinfo;
+ size_t ucred_sz = ucred_size();
if (RPC_FD_NOTIN_FDSET(fd)) {
errno = EBADF;
@@ -148,7 +150,7 @@ svc_dg_create_private(int fd, uint_t sendsize, uint_t recvsize)
/* LINTED pointer alignment */
svc_flags(xprt) |= SVC_DGRAM;
- su = malloc(sizeof (*su));
+ su = malloc(sizeof (*su) + ucred_sz);
if (su == NULL)
goto freedata;
su->su_iosz = ((MAX(sendsize, recvsize) + 3) / 4) * 4;
@@ -167,7 +169,7 @@ svc_dg_create_private(int fd, uint_t sendsize, uint_t recvsize)
su->su_tudata.udata.buf = (char *)rpc_buffer(xprt);
su->su_tudata.opt.buf = (char *)su->opts;
su->su_tudata.udata.maxlen = su->su_iosz;
- su->su_tudata.opt.maxlen = MAX_OPT_WORDS << 2; /* no of bytes */
+ su->su_tudata.opt.maxlen = MAX_OPT_WORDS * sizeof (int) + ucred_sz;
/* LINTED pointer alignment */
SVC_XP_AUTH(xprt).svc_ah_ops = svc_auth_any_ops;
/* LINTED pointer alignment */
@@ -195,6 +197,7 @@ svc_dg_xprtcopy(SVCXPRT *parent)
{
SVCXPRT *xprt;
struct svc_dg_data *su;
+ size_t ucred_sz = ucred_size();
if ((xprt = svc_xprt_alloc()) == NULL)
return (NULL);
@@ -237,7 +240,7 @@ svc_dg_xprtcopy(SVCXPRT *parent)
xprt->xp_rtaddr.maxlen);
xprt->xp_type = parent->xp_type;
- if ((su = malloc(sizeof (struct svc_dg_data))) == NULL) {
+ if ((su = malloc(sizeof (struct svc_dg_data) + ucred_sz)) == NULL) {
svc_dg_xprtfree(xprt);
return (NULL);
}
@@ -255,7 +258,7 @@ svc_dg_xprtcopy(SVCXPRT *parent)
su->su_tudata.udata.buf = (char *)rpc_buffer(xprt);
su->su_tudata.opt.buf = (char *)su->opts;
su->su_tudata.udata.maxlen = su->su_iosz;
- su->su_tudata.opt.maxlen = MAX_OPT_WORDS << 2; /* no of bytes */
+ su->su_tudata.opt.maxlen = MAX_OPT_WORDS * sizeof (int) + ucred_sz;
xprt->xp_p2 = (caddr_t)su; /* get_svc_dg_data(xprt) = su */
xprt->xp_verf.oa_base = su->su_verfbody;
diff --git a/usr/src/lib/libnsl/rpc/svc_door.c b/usr/src/lib/libnsl/rpc/svc_door.c
index d5f3d7c675..480e28b4c3 100644
--- a/usr/src/lib/libnsl/rpc/svc_door.c
+++ b/usr/src/lib/libnsl/rpc/svc_door.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * 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.
@@ -21,12 +20,10 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* svc_door.c, Server side for doors IPC based RPC.
*/
@@ -56,8 +53,6 @@ int __rpc_min_door_buf_size = 1000;
static struct xp_ops *svc_door_ops();
-#define MAX_OPT_WORDS 32
-
mutex_t svc_door_mutex = DEFAULTMUTEX;
cond_t svc_door_waitcv = DEFAULTCV;
int svc_ndoorfds = 0;
diff --git a/usr/src/lib/libnsl/rpc/svcauth_des.c b/usr/src/lib/libnsl/rpc/svcauth_des.c
index b437457052..fd0b9abbb5 100644
--- a/usr/src/lib/libnsl/rpc/svcauth_des.c
+++ b/usr/src/lib/libnsl/rpc/svcauth_des.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * 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.
@@ -21,7 +20,7 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
@@ -32,8 +31,6 @@
* California.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* svcauth_des.c, server-side des authentication
*
@@ -54,6 +51,7 @@
#include <rpc/des_crypt.h>
#include <rpc/rpc.h>
#include <sys/types.h>
+#include <sys/param.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
@@ -63,10 +61,6 @@
extern int key_decryptsession_pk(const char *, netobj *, des_block *);
-#ifndef NGROUPS
-#define NGROUPS 16
-#endif
-
#define USEC_PER_SEC ((ulong_t)1000000L)
#define BEFORE(t1, t2) timercmp(t1, t2, < /* EMPTY */)
@@ -611,7 +605,7 @@ struct bsdcred {
uid_t uid; /* cached uid */
gid_t gid; /* cached gid */
short grouplen; /* length of cached groups */
- short groups[NGROUPS]; /* cached groups */
+ gid_t groups[1]; /* cached groups allocate _SC_NGROUPS_MAX */
};
static void
@@ -649,7 +643,13 @@ authdes_getucred(const struct authdes_cred *adc, uid_t *uid, gid_t *gid,
/* LINTED pointer cast */
cred = (struct bsdcred *)_rpc_authdes_cache[sid].localcred;
if (cred == NULL) {
- cred = malloc(sizeof (struct bsdcred));
+ static size_t bsdcred_sz;
+
+ if (bsdcred_sz == 0) {
+ bsdcred_sz = sizeof (struct bsdcred) +
+ (sysconf(_SC_NGROUPS_MAX) - 1) * sizeof (gid_t);
+ }
+ cred = malloc(bsdcred_sz);
if (cred == NULL) {
__msgout2(__getucredstr, "out of memory");
(void) mutex_unlock(&authdes_lock);
@@ -675,7 +675,7 @@ authdes_getucred(const struct authdes_cred *adc, uid_t *uid, gid_t *gid,
*gid = cred->gid = i_gid;
*grouplen = cred->grouplen = i_grouplen;
for (i = i_grouplen - 1; i >= 0; i--) {
- cred->groups[i] = groups[i]; /* int to short */
+ cred->groups[i] = groups[i];
}
(void) mutex_unlock(&authdes_lock);
return (1);
@@ -695,7 +695,7 @@ authdes_getucred(const struct authdes_cred *adc, uid_t *uid, gid_t *gid,
*gid = cred->gid;
*grouplen = cred->grouplen;
for (i = cred->grouplen - 1; i >= 0; i--) {
- groups[i] = cred->groups[i]; /* short to int */
+ groups[i] = cred->groups[i];
}
(void) mutex_unlock(&authdes_lock);
return (1);
diff --git a/usr/src/lib/libsocket/inet/rcmd.c b/usr/src/lib/libsocket/inet/rcmd.c
index 6a0edcac5b..d1fdcd2418 100644
--- a/usr/src/lib/libsocket/inet/rcmd.c
+++ b/usr/src/lib/libsocket/inet/rcmd.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -37,8 +37,6 @@
* contributors.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <limits.h>
#include <stdio.h>
#include <ctype.h>
@@ -62,6 +60,7 @@
#include <string.h>
#include <stdlib.h>
#include <grp.h>
+#include <alloca.h>
#include <arpa/inet.h>
#include <priv_utils.h>
@@ -565,7 +564,8 @@ ruserok(const char *rhost, int superuser, const char *ruser, const char *luser)
char pbuf[MAXPATHLEN];
uid_t uid = (uid_t)-1;
gid_t gid = (gid_t)-1;
- gid_t grouplist[NGROUPS_MAX];
+ int maxgrp = getgroups(0, NULL);
+ gid_t *grouplist = alloca(maxgrp * sizeof (gid_t));
int ngroups;
sp = rhost;
@@ -605,7 +605,7 @@ ruserok(const char *rhost, int superuser, const char *ruser, const char *luser)
*/
gid = getegid();
uid = geteuid();
- if ((ngroups = getgroups(NGROUPS_MAX, grouplist)) == -1)
+ if ((ngroups = getgroups(maxgrp, grouplist)) == -1)
return (-1);
(void) setegid(pwd->pw_gid);
diff --git a/usr/src/ucbcmd/groups/groups.c b/usr/src/ucbcmd/groups/groups.c
index 396e69f744..26b0d618a8 100644
--- a/usr/src/ucbcmd/groups/groups.c
+++ b/usr/src/ucbcmd/groups/groups.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -13,14 +13,13 @@
* specifies the terms and conditions for redistribution.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* groups
*/
#include <sys/types.h>
#include <sys/param.h>
+#include <alloca.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
@@ -36,7 +35,10 @@ main(int argc, char *argv[])
int ngroups, i;
char *sep = "";
struct group *gr;
- gid_t groups[NGROUPS_UMAX];
+ gid_t *groups;
+ int maxgrp = sysconf(_SC_NGROUPS_MAX);
+
+ groups = alloca(maxgrp * sizeof (gid_t));
if (argc > 1) {
for (i = 1; i < argc; i++)
@@ -44,7 +46,7 @@ main(int argc, char *argv[])
exit(0);
}
- ngroups = getgroups(NGROUPS_UMAX, groups);
+ ngroups = getgroups(maxgrp, groups);
if (getpwuid(getuid()) == NULL) {
(void) fprintf(stderr, "groups: could not find passwd entry\n");
exit(1);
@@ -86,9 +88,9 @@ showgroups(char *user)
* To avoid duplicate group entries
*/
if (pwgid_printed == 0) {
- (void) printf("%s%s", sep, gr->gr_name);
- sep = " ";
- pwgid_printed = 1;
+ (void) printf("%s%s", sep, gr->gr_name);
+ sep = " ";
+ pwgid_printed = 1;
}
continue;
}
diff --git a/usr/src/uts/common/brand/lx/procfs/lx_proc.h b/usr/src/uts/common/brand/lx/procfs/lx_proc.h
index c79e3fa590..a2bd74a817 100644
--- a/usr/src/uts/common/brand/lx/procfs/lx_proc.h
+++ b/usr/src/uts/common/brand/lx/procfs/lx_proc.h
@@ -19,15 +19,13 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _LXPROC_H
#define _LXPROC_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -52,7 +50,8 @@ extern "C" {
#include <sys/user.h>
#include <sys/t_lock.h>
#include <sys/sysmacros.h>
-#include <sys/cred_impl.h>
+#include <sys/cred.h>
+#include <sys/priv.h>
#include <sys/vnode.h>
#include <sys/vfs.h>
#include <sys/statvfs.h>
diff --git a/usr/src/uts/common/c2/audit.c b/usr/src/uts/common/c2/audit.c
index eb02448ed2..a39d9b86e3 100644
--- a/usr/src/uts/common/c2/audit.c
+++ b/usr/src/uts/common/c2/audit.c
@@ -60,7 +60,7 @@
#include <sys/disp.h> /* for servicing_interrupt() */
#include <sys/devpolicy.h>
#include <sys/crypto/ioctladmin.h>
-#include <sys/cred_impl.h>
+#include <sys/cred.h>
#include <inet/kssl/kssl.h>
#include <net/pfpolicy.h>
@@ -2405,8 +2405,8 @@ audit_pf_policy(int cmd, cred_t *cred, netstack_t *ns, char *tun,
nszone = zone_find_by_id(netstackid_to_zoneid(
ns->netstack_stackid));
if (nszone != NULL) {
- if (strncmp(cred->cr_zone->zone_name, nszone->zone_name,
- ZONENAME_MAX) != 0) {
+ if (strncmp(crgetzone(cred)->zone_name,
+ nszone->zone_name, ZONENAME_MAX) != 0) {
token_t *ztoken;
ztoken = au_to_zonename(0, nszone);
diff --git a/usr/src/uts/common/c2/audit_start.c b/usr/src/uts/common/c2/audit_start.c
index 98fe62f823..7f9471c1ff 100644
--- a/usr/src/uts/common/c2/audit_start.c
+++ b/usr/src/uts/common/c2/audit_start.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -39,7 +39,7 @@
#include <sys/systm.h>
#include <sys/pathname.h>
#include <sys/debug.h>
-#include <sys/cred_impl.h>
+#include <sys/cred.h>
#include <sys/zone.h>
#include <c2/audit.h>
#include <c2/audit_kernel.h>
diff --git a/usr/src/uts/common/c2/audit_syscalls.c b/usr/src/uts/common/c2/audit_syscalls.c
index 2e930f12b3..87c0c50d48 100644
--- a/usr/src/uts/common/c2/audit_syscalls.c
+++ b/usr/src/uts/common/c2/audit_syscalls.c
@@ -36,7 +36,7 @@
#include <sys/vfs.h>
#include <sys/session.h> /* for session structure (auditctl(2) */
#include <sys/kmem.h> /* for KM_SLEEP */
-#include <sys/cred_impl.h>
+#include <sys/cred.h>
#include <sys/types.h>
#include <sys/proc.h>
#include <sys/uio.h>
diff --git a/usr/src/uts/common/conf/param.c b/usr/src/uts/common/conf/param.c
index ac5d99a76f..e6d77020a6 100644
--- a/usr/src/uts/common/conf/param.c
+++ b/usr/src/uts/common/conf/param.c
@@ -713,8 +713,17 @@ param_check(void)
physmem = original_physmem;
}
#endif
- if (ngroups_max < NGROUPS_UMIN || ngroups_max > NGROUPS_UMAX)
- ngroups_max = NGROUPS_MAX_DEFAULT;
+ if (ngroups_max < NGROUPS_UMIN)
+ ngroups_max = NGROUPS_UMIN;
+ if (ngroups_max > NGROUPS_UMAX)
+ ngroups_max = NGROUPS_UMAX;
+
+ /* If we have many groups then the ucred proto message also grows. */
+ if (ngroups_max > NGROUPS_OLDMAX &&
+ strctlsz < (ngroups_max - NGROUPS_OLDMAX) * sizeof (gid_t) + 1024) {
+ strctlsz = (ngroups_max - NGROUPS_OLDMAX) * sizeof (gid_t) +
+ 1024;
+ }
if (autoup <= 0) {
autoup = DEFAULT_AUTOUP;
diff --git a/usr/src/uts/common/fs/dev/sdev_vnops.c b/usr/src/uts/common/fs/dev/sdev_vnops.c
index 51db9fd51f..6519dd32ca 100644
--- a/usr/src/uts/common/fs/dev/sdev_vnops.c
+++ b/usr/src/uts/common/fs/dev/sdev_vnops.c
@@ -51,7 +51,6 @@
#include <sys/errno.h>
#include <sys/stat.h>
#include <sys/cred.h>
-#include <sys/cred_impl.h>
#include <sys/dirent.h>
#include <sys/pathname.h>
#include <sys/cmn_err.h>
diff --git a/usr/src/uts/common/fs/nfs/nfs_subr.c b/usr/src/uts/common/fs/nfs/nfs_subr.c
index f38854ab54..bad4e8be77 100644
--- a/usr/src/uts/common/fs/nfs/nfs_subr.c
+++ b/usr/src/uts/common/fs/nfs/nfs_subr.c
@@ -26,7 +26,7 @@
#include <sys/param.h>
#include <sys/types.h>
#include <sys/systm.h>
-#include <sys/cred_impl.h>
+#include <sys/cred.h>
#include <sys/proc.h>
#include <sys/user.h>
#include <sys/time.h>
diff --git a/usr/src/uts/common/fs/smbclnt/netsmb/smb_conn.c b/usr/src/uts/common/fs/smbclnt/netsmb/smb_conn.c
index 102b57fe28..f1dcd57ea3 100644
--- a/usr/src/uts/common/fs/smbclnt/netsmb/smb_conn.c
+++ b/usr/src/uts/common/fs/smbclnt/netsmb/smb_conn.c
@@ -50,7 +50,6 @@
#include <sys/stropts.h>
#include <sys/socketvar.h>
#include <sys/cred.h>
-#include <sys/cred_impl.h>
#include <netinet/in.h>
#include <inet/ip.h>
#include <inet/ip6.h>
diff --git a/usr/src/uts/common/fs/smbsrv/smb_tree.c b/usr/src/uts/common/fs/smbsrv/smb_tree.c
index 48e412345e..cc9ede2048 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_tree.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_tree.c
@@ -169,7 +169,7 @@
#include <sys/vfs.h>
#include <sys/stat.h>
#include <sys/varargs.h>
-#include <sys/cred_impl.h>
+#include <sys/cred.h>
#include <smbsrv/smb_kproto.h>
#include <smbsrv/lmerr.h>
#include <smbsrv/smb_fsops.h>
@@ -1268,7 +1268,7 @@ smb_tree_set_execsub_info(smb_tree_t *tree, smb_execsub_info_t *subs)
subs->e_srv_ipaddr = tree->t_session->local_ipaddr;
subs->e_cli_ipaddr = tree->t_session->ipaddr;
subs->e_cli_netbiosname = tree->t_session->workstation;
- subs->e_uid = tree->t_user->u_cred->cr_uid;
+ subs->e_uid = crgetuid(tree->t_user->u_cred);
}
/*
diff --git a/usr/src/uts/common/fs/zfs/zfs_vnops.c b/usr/src/uts/common/fs/zfs/zfs_vnops.c
index d0d571e519..69516d041c 100644
--- a/usr/src/uts/common/fs/zfs/zfs_vnops.c
+++ b/usr/src/uts/common/fs/zfs/zfs_vnops.c
@@ -73,7 +73,7 @@
#include <sys/zfs_rlock.h>
#include <sys/extdirent.h>
#include <sys/kidmap.h>
-#include <sys/cred_impl.h>
+#include <sys/cred.h>
#include <sys/attr.h>
/*
diff --git a/usr/src/uts/common/inet/ip/conn_opt.c b/usr/src/uts/common/inet/ip/conn_opt.c
index 2b4cd6a951..b94c7b8dbd 100644
--- a/usr/src/uts/common/inet/ip/conn_opt.c
+++ b/usr/src/uts/common/inet/ip/conn_opt.c
@@ -221,7 +221,8 @@ conn_recvancillary_size(conn_t *connp, crb_t recv_ancillary,
IP_STAT(ipst, conn_in_recvdstopts);
}
if (recv_ancillary.crb_recvucred && ira->ira_cred != NULL) {
- ancil_size += sizeof (struct T_opthdr) + ucredsize;
+ ancil_size += sizeof (struct T_opthdr) +
+ ucredminsize(ira->ira_cred);
IP_STAT(ipst, conn_in_recvucred);
}
@@ -527,7 +528,8 @@ conn_recvancillary_add(conn_t *connp, crb_t recv_ancillary,
toh = (struct T_opthdr *)ancil_buf;
toh->level = SOL_SOCKET;
toh->name = SCM_UCRED;
- toh->len = sizeof (struct T_opthdr) + ucredsize;
+ toh->len = sizeof (struct T_opthdr) +
+ ucredminsize(ira->ira_cred);
toh->status = 0;
(void) cred2ucred(ira->ira_cred, ira->ira_cpid, &toh[1], rcr);
ancil_buf += toh->len;
diff --git a/usr/src/uts/common/inet/ipf/ip_fil_solaris.c b/usr/src/uts/common/inet/ipf/ip_fil_solaris.c
index 69a064b327..bd3884b53e 100644
--- a/usr/src/uts/common/inet/ipf/ip_fil_solaris.c
+++ b/usr/src/uts/common/inet/ipf/ip_fil_solaris.c
@@ -22,7 +22,6 @@ static const char rcsid[] = "@(#)$Id: ip_fil_solaris.c,v 2.62.2.19 2005/07/13 21
#include <sys/systm.h>
#include <sys/strsubr.h>
#include <sys/cred.h>
-#include <sys/cred_impl.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/ksynch.h>
@@ -554,7 +553,7 @@ int *rp;
return EBUSY;
}
- error = fr_ioctlswitch(unit, (caddr_t)data, cmd, mode, cp->cr_uid,
+ error = fr_ioctlswitch(unit, (caddr_t)data, cmd, mode, crgetuid(cp),
curproc, ifs);
if (error != -1) {
RWLOCK_EXIT(&ifs->ifs_ipf_global);
@@ -759,12 +758,12 @@ int *rp;
#endif
break;
case SIOCIPFITER :
- error = ipf_frruleiter((caddr_t)data, cp->cr_uid,
+ error = ipf_frruleiter((caddr_t)data, crgetuid(cp),
curproc, ifs);
break;
case SIOCGENITER :
- error = ipf_genericiter((caddr_t)data, cp->cr_uid,
+ error = ipf_genericiter((caddr_t)data, crgetuid(cp),
curproc, ifs);
break;
@@ -773,7 +772,7 @@ int *rp;
if (error != 0) {
error = EFAULT;
} else {
- error = ipf_deltoken(tmp, cp->cr_uid, curproc, ifs);
+ error = ipf_deltoken(tmp, crgetuid(cp), curproc, ifs);
}
break;
diff --git a/usr/src/uts/common/inet/udp/udp.c b/usr/src/uts/common/inet/udp/udp.c
index de54c3a5ab..545eb7771a 100644
--- a/usr/src/uts/common/inet/udp/udp.c
+++ b/usr/src/uts/common/inet/udp/udp.c
@@ -1779,7 +1779,7 @@ udp_do_opt_set(conn_opt_arg_t *coa, int level, int name,
break;
ucr = (struct ucred_s *)invalp;
- if (inlen != ucredsize ||
+ if (inlen < sizeof (*ucr) + sizeof (bslabel_t) ||
ucr->uc_labeloff < sizeof (*ucr) ||
ucr->uc_labeloff + sizeof (bslabel_t) > inlen)
return (EINVAL);
diff --git a/usr/src/uts/common/inet/udp/udp_opt_data.c b/usr/src/uts/common/inet/udp/udp_opt_data.c
index 2e22317413..c279bb4a21 100644
--- a/usr/src/uts/common/inet/udp/udp_opt_data.c
+++ b/usr/src/uts/common/inet/udp/udp_opt_data.c
@@ -84,7 +84,14 @@ opdes_t udp_opt_arr[] = {
0 },
{ SO_MAC_IMPLICIT, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int),
0 },
-{ SCM_UCRED, SOL_SOCKET, OA_W, OA_W, OP_NP, OP_VARLEN|OP_NODEFAULT, 512, 0 },
+/*
+ * The maximum size reported here depends on the maximum value for
+ * ucredsize; unfortunately, we can't add ucredsize here so we need
+ * to estimate here. Before it was 512 or 384 + NGROUPS_UMAX * sizeof (gid_t);
+ * as we're changing NGROUPS_UMAX we now codify this here using NGROUPS_UMAX.
+ */
+{ SCM_UCRED, SOL_SOCKET, OA_W, OA_W, OP_NP, OP_VARLEN|OP_NODEFAULT,
+ 384 + NGROUPS_UMAX * sizeof (gid_t), 0 },
{ SO_EXCLBIND, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
{ SO_DOMAIN, SOL_SOCKET, OA_R, OA_R, OP_NP, 0, sizeof (int), 0 },
{ SO_PROTOTYPE, SOL_SOCKET, OA_R, OA_R, OP_NP, 0, sizeof (int), 0 },
diff --git a/usr/src/uts/common/io/tl.c b/usr/src/uts/common/io/tl.c
index 83f8cf6944..353d536daf 100644
--- a/usr/src/uts/common/io/tl.c
+++ b/usr/src/uts/common/io/tl.c
@@ -3059,6 +3059,8 @@ tl_conn_req_ser(mblk_t *mp, tl_endpt_t *tep)
t_scalar_t ooff = creq->OPT_offset;
size_t ci_msz;
size_t size;
+ cred_t *cr = NULL;
+ pid_t cpid;
if (tep->te_closing) {
TL_UNCONNECT(tep->te_oconp);
@@ -3100,16 +3102,20 @@ tl_conn_req_ser(mblk_t *mp, tl_endpt_t *tep)
/*
* calculate length of T_CONN_IND message
*/
- if (peer_tep->te_flag & TL_SETCRED) {
- ooff = 0;
- olen = (t_scalar_t) sizeof (struct opthdr) +
- OPTLEN(sizeof (tl_credopt_t));
- /* 1 option only */
- } else if (peer_tep->te_flag & TL_SETUCRED) {
- ooff = 0;
- olen = (t_scalar_t)sizeof (struct opthdr) +
- OPTLEN(ucredsize);
- /* 1 option only */
+ if (peer_tep->te_flag & (TL_SETCRED|TL_SETUCRED)) {
+ cr = msg_getcred(mp, &cpid);
+ ASSERT(cr != NULL);
+ if (peer_tep->te_flag & TL_SETCRED) {
+ ooff = 0;
+ olen = (t_scalar_t) sizeof (struct opthdr) +
+ OPTLEN(sizeof (tl_credopt_t));
+ /* 1 option only */
+ } else {
+ ooff = 0;
+ olen = (t_scalar_t)sizeof (struct opthdr) +
+ OPTLEN(ucredminsize(cr));
+ /* 1 option only */
+ }
}
ci_msz = sizeof (struct T_conn_ind) + tep->te_alen;
ci_msz = T_ALIGN(ci_msz) + olen;
@@ -3247,14 +3253,10 @@ tl_conn_req_ser(mblk_t *mp, tl_endpt_t *tep)
addr_startp = cimp->b_rptr + ci->SRC_offset;
bcopy(tep->te_abuf, addr_startp, tep->te_alen);
if (peer_tep->te_flag & (TL_SETCRED|TL_SETUCRED)) {
- cred_t *cr;
- pid_t cpid;
ci->OPT_offset = (t_scalar_t)T_ALIGN(ci->SRC_offset +
ci->SRC_length);
ci->OPT_length = olen; /* because only 1 option */
- cr = msg_getcred(cimp, &cpid);
- ASSERT(cr != NULL);
tl_fill_option(cimp->b_rptr + ci->OPT_offset,
cr, cpid,
peer_tep->te_flag, peer_tep->te_credp);
@@ -3591,7 +3593,7 @@ tl_conn_res(mblk_t *mp, tl_endpt_t *tep)
OPTLEN(sizeof (tl_credopt_t));
} else if (cl_ep->te_flag & TL_SETUCRED) {
olen = (t_scalar_t)sizeof (struct opthdr) +
- OPTLEN(ucredsize);
+ OPTLEN(ucredminsize(acc_ep->te_credp));
}
size = T_ALIGN(sizeof (struct T_conn_con) +
acc_ep->te_alen) + olen;
@@ -4989,6 +4991,8 @@ tl_unitdata(mblk_t *mp, tl_endpt_t *tep)
ssize_t msz, ui_sz;
t_scalar_t alen, aoff, olen, ooff;
t_scalar_t oldolen = 0;
+ cred_t *cr = NULL;
+ pid_t cpid;
udreq = (struct T_unitdata_req *)mp->b_rptr;
msz = MBLKL(mp);
@@ -5159,19 +5163,25 @@ tl_unitdata(mblk_t *mp, tl_endpt_t *tep)
/*
* calculate length of message
*/
- if (peer_tep->te_flag & TL_SETCRED) {
- ASSERT(olen == 0);
- olen = (t_scalar_t)sizeof (struct opthdr) +
- OPTLEN(sizeof (tl_credopt_t));
- /* 1 option only */
- } else if (peer_tep->te_flag & TL_SETUCRED) {
- ASSERT(olen == 0);
- olen = (t_scalar_t)sizeof (struct opthdr) + OPTLEN(ucredsize);
- /* 1 option only */
- } else if (peer_tep->te_flag & TL_SOCKUCRED) {
- /* Possibly more than one option */
- olen += (t_scalar_t)sizeof (struct T_opthdr) +
- OPTLEN(ucredsize);
+ if (peer_tep->te_flag & (TL_SETCRED|TL_SETUCRED|TL_SOCKUCRED)) {
+ cr = msg_getcred(mp, &cpid);
+ ASSERT(cr != NULL);
+
+ if (peer_tep->te_flag & TL_SETCRED) {
+ ASSERT(olen == 0);
+ olen = (t_scalar_t)sizeof (struct opthdr) +
+ OPTLEN(sizeof (tl_credopt_t));
+ /* 1 option only */
+ } else if (peer_tep->te_flag & TL_SETUCRED) {
+ ASSERT(olen == 0);
+ olen = (t_scalar_t)sizeof (struct opthdr) +
+ OPTLEN(ucredminsize(cr));
+ /* 1 option only */
+ } else {
+ /* Possibly more than one option */
+ olen += (t_scalar_t)sizeof (struct T_opthdr) +
+ OPTLEN(ucredminsize(cr));
+ }
}
ui_sz = T_ALIGN(sizeof (struct T_unitdata_ind) + tep->te_alen) +
@@ -5217,8 +5227,6 @@ tl_unitdata(mblk_t *mp, tl_endpt_t *tep)
(t_scalar_t)T_ALIGN(udind->SRC_offset + udind->SRC_length);
udind->OPT_length = olen;
if (peer_tep->te_flag & (TL_SETCRED|TL_SETUCRED|TL_SOCKUCRED)) {
- cred_t *cr;
- pid_t cpid;
if (oldolen != 0) {
bcopy((void *)((uintptr_t)udreq + ooff),
@@ -5226,7 +5234,6 @@ tl_unitdata(mblk_t *mp, tl_endpt_t *tep)
udind->OPT_offset),
oldolen);
}
- cr = msg_getcred(mp, &cpid);
ASSERT(cr != NULL);
tl_fill_option(ui_mp->b_rptr + udind->OPT_offset +
@@ -5981,7 +5988,7 @@ tl_fill_option(uchar_t *buf, cred_t *cr, pid_t cpid, int flag, cred_t *pcr)
opt->level = TL_PROT_LEVEL;
opt->name = TL_OPT_PEER_UCRED;
- opt->len = (t_uscalar_t)OPTLEN(ucredsize);
+ opt->len = (t_uscalar_t)OPTLEN(ucredminsize(cr));
(void) cred2ucred(cr, cpid, (void *)(opt + 1), pcr);
} else {
@@ -5990,7 +5997,7 @@ tl_fill_option(uchar_t *buf, cred_t *cr, pid_t cpid, int flag, cred_t *pcr)
topt->level = SOL_SOCKET;
topt->name = SCM_UCRED;
- topt->len = ucredsize + sizeof (*topt);
+ topt->len = ucredminsize(cr) + sizeof (*topt);
topt->status = 0;
(void) cred2ucred(cr, cpid, (void *)(topt + 1), pcr);
}
diff --git a/usr/src/uts/common/os/cred.c b/usr/src/uts/common/os/cred.c
index 205ae32756..7a208b331e 100644
--- a/usr/src/uts/common/os/cred.c
+++ b/usr/src/uts/common/os/cred.c
@@ -62,6 +62,7 @@
#include <sys/idmap.h>
#include <sys/klpd.h>
#include <sys/varargs.h>
+#include <util/qsort.h>
/* Ephemeral IDs Zones specific data */
@@ -74,6 +75,16 @@ typedef struct ephemeral_zsd {
cred_t *eph_nobody;
} ephemeral_zsd_t;
+/* Supplemental groups list. */
+typedef struct credgrp {
+ uint_t crg_ref;
+ uint_t crg_ngroups;
+ gid_t crg_groups[1];
+} credgrp_t;
+
+static void crgrphold(credgrp_t *);
+
+#define CREDGRPSZ(ngrp) (sizeof (credgrp_t) + ((ngrp - 1) * sizeof (gid_t)))
static kmutex_t ephemeral_zone_mutex;
static zone_key_t ephemeral_zone_key;
@@ -94,6 +105,7 @@ static int get_c2audit_load(void);
#define REMOTE_PEER_CRED(c) ((c)->cr_gid == -1)
+#define BIN_GROUP_SEARCH_CUTOFF 16
static boolean_t hasephids = B_FALSE;
@@ -160,11 +172,7 @@ cred_init(void)
{
priv_init();
- crsize = sizeof (cred_t) + sizeof (gid_t) * (ngroups_max - 1);
- /*
- * Make sure it's word-aligned.
- */
- crsize = (crsize + sizeof (int) - 1) & ~(sizeof (int) - 1);
+ crsize = sizeof (cred_t);
if (get_c2audit_load() > 0) {
#ifdef _LP64
@@ -251,6 +259,7 @@ cralloc_flags(int flgs)
cr->cr_label = NULL;
cr->cr_ksid = NULL;
cr->cr_klpd = NULL;
+ cr->cr_grps = NULL;
return (cr);
}
@@ -287,6 +296,7 @@ crget(void)
if (cr->cr_label)
label_hold(cr->cr_label);
ASSERT(cr->cr_klpd == NULL);
+ ASSERT(cr->cr_grps == NULL);
return (cr);
}
@@ -357,6 +367,9 @@ crfree(cred_t *cr)
zone_cred_rele(cr->cr_zone);
if (cr->cr_ksid)
kcrsid_rele(cr->cr_ksid);
+ if (cr->cr_grps)
+ crgrprele(cr->cr_grps);
+
kmem_cache_free(cred_cache, cr);
}
}
@@ -381,6 +394,8 @@ crcopy(cred_t *cr)
kcrsid_hold(newcr->cr_ksid);
if (newcr->cr_klpd)
crklpd_hold(newcr->cr_klpd);
+ if (newcr->cr_grps)
+ crgrphold(newcr->cr_grps);
crfree(cr);
newcr->cr_ref = 2; /* caller gets two references */
return (newcr);
@@ -405,6 +420,8 @@ crcopy_to(cred_t *oldcr, cred_t *newcr)
label_hold(newcr->cr_label);
if (newcr->cr_klpd)
crklpd_hold(newcr->cr_klpd);
+ if (newcr->cr_grps)
+ crgrphold(newcr->cr_grps);
if (nkcr) {
newcr->cr_ksid = nkcr;
kcrsidcopy_to(oldcr->cr_ksid, newcr->cr_ksid);
@@ -437,6 +454,8 @@ crdup_flags(const cred_t *cr, int flgs)
crklpd_hold(newcr->cr_klpd);
if (newcr->cr_ksid)
kcrsid_hold(newcr->cr_ksid);
+ if (newcr->cr_grps)
+ crgrphold(newcr->cr_grps);
newcr->cr_ref = 1;
return (newcr);
}
@@ -465,6 +484,8 @@ crdup_to(cred_t *oldcr, cred_t *newcr)
label_hold(newcr->cr_label);
if (newcr->cr_klpd)
crklpd_hold(newcr->cr_klpd);
+ if (newcr->cr_grps)
+ crgrphold(newcr->cr_grps);
if (nkcr) {
newcr->cr_ksid = nkcr;
kcrsidcopy_to(oldcr->cr_ksid, newcr->cr_ksid);
@@ -519,12 +540,38 @@ groupmember(gid_t gid, const cred_t *cr)
int
supgroupmember(gid_t gid, const cred_t *cr)
{
+ int hi, lo;
+ credgrp_t *grps = cr->cr_grps;
const gid_t *gp, *endgp;
- endgp = &cr->cr_groups[cr->cr_ngroups];
- for (gp = cr->cr_groups; gp < endgp; gp++)
- if (*gp == gid)
+ if (grps == NULL)
+ return (0);
+
+ /* For a small number of groups, use sequentials search. */
+ if (grps->crg_ngroups <= BIN_GROUP_SEARCH_CUTOFF) {
+ endgp = &grps->crg_groups[grps->crg_ngroups];
+ for (gp = grps->crg_groups; gp < endgp; gp++)
+ if (*gp == gid)
+ return (1);
+ return (0);
+ }
+
+ /* We use binary search when we have many groups. */
+ lo = 0;
+ hi = grps->crg_ngroups - 1;
+ gp = grps->crg_groups;
+
+ do {
+ int m = (lo + hi) / 2;
+
+ if (gid > gp[m])
+ lo = m + 1;
+ else if (gid < gp[m])
+ hi = m - 1;
+ else
return (1);
+ } while (lo <= hi);
+
return (0);
}
@@ -603,6 +650,7 @@ prochasprocperm(proc_t *tp, proc_t *sp, const cred_t *scrp)
int
crcmp(const cred_t *cr1, const cred_t *cr2)
{
+ credgrp_t *grp1, *grp2;
if (cr1 == cr2)
return (0);
@@ -611,10 +659,12 @@ crcmp(const cred_t *cr1, const cred_t *cr2)
cr1->cr_gid == cr2->cr_gid &&
cr1->cr_ruid == cr2->cr_ruid &&
cr1->cr_rgid == cr2->cr_rgid &&
- cr1->cr_ngroups == cr2->cr_ngroups &&
cr1->cr_zone == cr2->cr_zone &&
- bcmp(cr1->cr_groups, cr2->cr_groups,
- cr1->cr_ngroups * sizeof (gid_t)) == 0) {
+ ((grp1 = cr1->cr_grps) == (grp2 = cr2->cr_grps) ||
+ (grp1 != NULL && grp2 != NULL &&
+ grp1->crg_ngroups == grp2->crg_ngroups &&
+ bcmp(grp1->crg_groups, grp2->crg_groups,
+ grp1->crg_ngroups * sizeof (gid_t)) == 0))) {
return (!priv_isequalset(&CR_OEPRIV(cr1), &CR_OEPRIV(cr2)));
}
return (1);
@@ -764,6 +814,20 @@ crsetugid(cred_t *cr, uid_t uid, gid_t gid)
return (0);
}
+static int
+gidcmp(const void *v1, const void *v2)
+{
+ gid_t g1 = *(gid_t *)v1;
+ gid_t g2 = *(gid_t *)v2;
+
+ if (g1 < g2)
+ return (-1);
+ else if (g1 > g2)
+ return (1);
+ else
+ return (0);
+}
+
int
crsetgroups(cred_t *cr, int n, gid_t *grp)
{
@@ -772,10 +836,18 @@ crsetgroups(cred_t *cr, int n, gid_t *grp)
if (n > ngroups_max || n < 0)
return (-1);
- cr->cr_ngroups = n;
+ if (cr->cr_grps != NULL)
+ crgrprele(cr->cr_grps);
- if (n > 0)
- bcopy(grp, cr->cr_groups, n * sizeof (gid_t));
+ if (n > 0) {
+ cr->cr_grps = kmem_alloc(CREDGRPSZ(n), KM_SLEEP);
+ bcopy(grp, cr->cr_grps->crg_groups, n * sizeof (gid_t));
+ cr->cr_grps->crg_ref = 1;
+ cr->cr_grps->crg_ngroups = n;
+ qsort(cr->cr_grps->crg_groups, n, sizeof (gid_t), gidcmp);
+ } else {
+ cr->cr_grps = NULL;
+ }
return (0);
}
@@ -788,19 +860,21 @@ crsetprojid(cred_t *cr, projid_t projid)
}
/*
- * This routine returns the pointer to the first element of the cr_groups
+ * This routine returns the pointer to the first element of the crg_groups
* array. It can move around in an implementation defined way.
+ * Note that when we have no grouplist, we return one element but the
+ * caller should never reference it.
*/
const gid_t *
crgetgroups(const cred_t *cr)
{
- return (cr->cr_groups);
+ return (cr->cr_grps == NULL ? &cr->cr_gid : cr->cr_grps->crg_groups);
}
int
crgetngroups(const cred_t *cr)
{
- return (cr->cr_ngroups);
+ return (cr->cr_grps == NULL ? 0 : cr->cr_grps->crg_ngroups);
}
void
@@ -812,12 +886,12 @@ cred2prcred(const cred_t *cr, prcred_t *pcrp)
pcrp->pr_egid = cr->cr_gid;
pcrp->pr_rgid = cr->cr_rgid;
pcrp->pr_sgid = cr->cr_sgid;
- pcrp->pr_ngroups = MIN(cr->cr_ngroups, (uint_t)ngroups_max);
- pcrp->pr_groups[0] = 0; /* in case ngroups == 0 */
+ pcrp->pr_groups[0] = 0; /* in case ngroups == 0 */
+ pcrp->pr_ngroups = cr->cr_grps == NULL ? 0 : cr->cr_grps->crg_ngroups;
if (pcrp->pr_ngroups != 0)
- bcopy(cr->cr_groups, pcrp->pr_groups,
- sizeof (gid_t) * cr->cr_ngroups);
+ bcopy(cr->cr_grps->crg_groups, pcrp->pr_groups,
+ sizeof (gid_t) * pcrp->pr_ngroups);
}
static int
@@ -867,49 +941,77 @@ struct ucred_s *
cred2ucred(const cred_t *cr, pid_t pid, void *buf, const cred_t *rcr)
{
struct ucred_s *uc;
+ uint32_t realsz = ucredminsize(cr);
+ ts_label_t *tslp = is_system_labeled() ? crgetlabel(cr) : NULL;
/* The structure isn't always completely filled in, so zero it */
if (buf == NULL) {
- uc = kmem_zalloc(ucredsize, KM_SLEEP);
+ uc = kmem_zalloc(realsz, KM_SLEEP);
} else {
- bzero(buf, ucredsize);
+ bzero(buf, realsz);
uc = buf;
}
- uc->uc_size = ucredsize;
- uc->uc_credoff = UCRED_CRED_OFF;
- uc->uc_privoff = UCRED_PRIV_OFF;
- uc->uc_audoff = UCRED_AUD_OFF;
- uc->uc_labeloff = UCRED_LABEL_OFF;
+ uc->uc_size = realsz;
uc->uc_pid = pid;
uc->uc_projid = cr->cr_projid;
uc->uc_zoneid = crgetzoneid(cr);
- /*
- * Note that cred2uclabel() call should not be factored out
- * to the bottom of the if-else. UCXXX() macros depend on
- * uc_xxxoff values to work correctly.
- */
if (REMOTE_PEER_CRED(cr)) {
/*
- * other than label, the rest of cred info about a
- * remote peer isn't available.
+ * Other than label, the rest of cred info about a
+ * remote peer isn't available. Copy the label directly
+ * after the header where we generally copy the prcred.
+ * That's why we use sizeof (struct ucred_s). The other
+ * offset fields are initialized to 0.
*/
- cred2uclabel(cr, UCLABEL(uc));
- uc->uc_credoff = 0;
- uc->uc_privoff = 0;
- uc->uc_audoff = 0;
+ uc->uc_labeloff = tslp == NULL ? 0 : sizeof (struct ucred_s);
} else {
+ uc->uc_credoff = UCRED_CRED_OFF;
+ uc->uc_privoff = UCRED_PRIV_OFF;
+ uc->uc_audoff = UCRED_AUD_OFF;
+ uc->uc_labeloff = tslp == NULL ? 0 : UCRED_LABEL_OFF;
+
cred2prcred(cr, UCCRED(uc));
cred2prpriv(cr, UCPRIV(uc));
+
if (audoff == 0 || cred2ucaud(cr, UCAUD(uc), rcr) != 0)
uc->uc_audoff = 0;
- cred2uclabel(cr, UCLABEL(uc));
}
+ if (tslp != NULL)
+ bcopy(&tslp->tsl_label, UCLABEL(uc), sizeof (bslabel_t));
return (uc);
}
/*
+ * Don't allocate the non-needed group entries. Note: this function
+ * must match the code in cred2ucred; they must agree about the
+ * minimal size of the ucred.
+ */
+uint32_t
+ucredminsize(const cred_t *cr)
+{
+ int ndiff;
+
+ if (cr == NULL)
+ return (ucredsize);
+
+ if (REMOTE_PEER_CRED(cr)) {
+ if (is_system_labeled())
+ return (sizeof (struct ucred_s) + sizeof (bslabel_t));
+ else
+ return (sizeof (struct ucred_s));
+ }
+
+ if (cr->cr_grps == NULL)
+ ndiff = ngroups_max - 1; /* Needs one for prcred_t */
+ else
+ ndiff = ngroups_max - cr->cr_grps->crg_ngroups;
+
+ return (ucredsize - ndiff * sizeof (gid_t));
+}
+
+/*
* Get the "ucred" of a process.
*/
struct ucred_s *
@@ -1326,3 +1428,52 @@ crsetcrklpd(cred_t *cr, struct credklpd *crklpd)
crklpd_rele(cr->cr_klpd);
cr->cr_klpd = crklpd;
}
+
+credgrp_t *
+crgrpcopyin(int n, gid_t *gidset)
+{
+ credgrp_t *mem;
+ size_t sz = CREDGRPSZ(n);
+
+ ASSERT(n > 0);
+
+ mem = kmem_alloc(sz, KM_SLEEP);
+
+ if (copyin(gidset, mem->crg_groups, sizeof (gid_t) * n)) {
+ kmem_free(mem, sz);
+ return (NULL);
+ }
+ mem->crg_ref = 1;
+ mem->crg_ngroups = n;
+ return (mem);
+}
+
+const gid_t *
+crgetggroups(const credgrp_t *grps)
+{
+ return (grps->crg_groups);
+}
+
+void
+crsetcredgrp(cred_t *cr, credgrp_t *grps)
+{
+ ASSERT(cr->cr_ref <= 2);
+
+ if (cr->cr_grps != NULL)
+ crgrprele(cr->cr_grps);
+
+ cr->cr_grps = grps;
+}
+
+void
+crgrprele(credgrp_t *grps)
+{
+ if (atomic_add_32_nv(&grps->crg_ref, -1) == 0)
+ kmem_free(grps, CREDGRPSZ(grps->crg_ngroups));
+}
+
+static void
+crgrphold(credgrp_t *grps)
+{
+ atomic_add_32(&grps->crg_ref, 1);
+}
diff --git a/usr/src/uts/common/rpc/auth_sys.h b/usr/src/uts/common/rpc/auth_sys.h
index e3e8c1534a..214c781bac 100644
--- a/usr/src/uts/common/rpc/auth_sys.h
+++ b/usr/src/uts/common/rpc/auth_sys.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * 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.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
@@ -38,8 +37,6 @@
#ifndef _RPC_AUTH_SYS_H
#define _RPC_AUTH_SYS_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* The system is very weak. The client uses no encryption for it
* credentials and only sends null verifiers. The server sends backs
@@ -48,6 +45,7 @@
*/
#include <sys/types.h>
+#include <sys/param.h>
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
@@ -62,8 +60,8 @@ extern "C" {
/* gids compose part of a credential; there may not be more than 16 of them */
#define NGRPS 16
-/* gids compose part of a credential; there may not be more than 64 of them */
-#define NGRPS_LOOPBACK 64
+/* gids compose part of a credential */
+#define NGRPS_LOOPBACK NGROUPS_UMAX
/*
* "sys" (Old UNIX) style credentials.
diff --git a/usr/src/uts/common/rpc/sec/auth_kern.c b/usr/src/uts/common/rpc/sec/auth_kern.c
index d7c0571515..e045c1c08f 100644
--- a/usr/src/uts/common/rpc/sec/auth_kern.c
+++ b/usr/src/uts/common/rpc/sec/auth_kern.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * 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.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -32,8 +31,6 @@
* under license from the Regents of the University of California.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* auth_kern.c, implements UNIX style authentication parameters in the kernel.
* Interfaces with svc_auth_unix on the server. See auth_unix.c for the user
@@ -137,7 +134,7 @@ authkern_marshal(AUTH *auth, XDR *xdrs, struct cred *cr)
gp = crgetgroups(cr);
gidlen = crgetngroups(cr);
if (gidlen > NGRPS)
- return (FALSE);
+ gidlen = NGRPS;
gpend = &gp[gidlen-1];
namelen = (int)strlen(nodename);
diff --git a/usr/src/uts/common/rpc/sec/authu_prot.c b/usr/src/uts/common/rpc/sec/authu_prot.c
index 2dd53219d4..dbc719e03c 100644
--- a/usr/src/uts/common/rpc/sec/authu_prot.c
+++ b/usr/src/uts/common/rpc/sec/authu_prot.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * 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.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -32,8 +31,6 @@
* under license from the Regents of the University of California.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* authunix_prot.c
* XDR for UNIX style authentication parameters for RPC
@@ -64,8 +61,8 @@ xdr_authunix_parms(XDR *xdrs, struct authunix_parms *p)
xdr_int(xdrs, (int *)&(p->aup_uid)) &&
xdr_int(xdrs, (int *)&(p->aup_gid)) &&
xdr_array(xdrs, (caddr_t *)&(p->aup_gids),
- &(p->aup_len), NGRPS, sizeof (int),
- (xdrproc_t)xdr_int)) {
+ &(p->aup_len), NGRPS, sizeof (int),
+ (xdrproc_t)xdr_int)) {
return (TRUE);
}
return (FALSE);
@@ -130,6 +127,10 @@ xdr_authkern(XDR *xdrs)
uid = crgetuid(cr);
gid = crgetgid(cr);
len = crgetngroups(cr);
+
+ if (len > NGRPS)
+ len = NGRPS;
+
groups = (caddr_t)crgetgroups(cr);
now = gethrestime_sec();
if (xdr_uint32(xdrs, (uint32_t *)&now) &&
diff --git a/usr/src/uts/common/rpc/sec/svcauthdes.c b/usr/src/uts/common/rpc/sec/svcauthdes.c
index 67cd471c4b..a2dfa41c29 100644
--- a/usr/src/uts/common/rpc/sec/svcauthdes.c
+++ b/usr/src/uts/common/rpc/sec/svcauthdes.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,8 +31,6 @@
* under license from the Regents of the University of California.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* svcauth_des.c, server-side des authentication
*
@@ -416,7 +414,7 @@ struct bsdcred {
gid_t gid; /* cached gid */
short valid; /* valid creds */
short grouplen; /* length of cached groups */
- gid_t groups[NGROUPS_UMAX]; /* cached groups */
+ gid_t groups[1]; /* cached groups - allocate ngroups_max */
};
/*
@@ -508,8 +506,8 @@ authdes_cache_new(char *fullname, des_block *sessionkey, uint32_t window) {
return (NULL);
}
- if (!(ucred = (struct bsdcred *)kmem_alloc(sizeof (struct bsdcred),
- KM_NOSLEEP))) {
+ if (!(ucred = kmem_alloc(sizeof (struct bsdcred) +
+ (ngroups_max - 1) * sizeof (gid_t), KM_NOSLEEP))) {
kmem_free(new->rname, strlen(fullname) + 1);
kmem_cache_free(authdes_cache_handle, new);
return (NULL);
@@ -619,7 +617,8 @@ authdes_cache_reclaim(void *pdata) {
lru_last = p->lru_prev;
kmem_free(p->rname, strlen(p->rname) + 1);
- kmem_free(p->localcred, sizeof (struct bsdcred));
+ kmem_free(p->localcred, sizeof (struct bsdcred) +
+ (ngroups_max - 1) * sizeof (gid_t));
mutex_destroy(&p->lock);
kmem_cache_free(authdes_cache_handle, p);
@@ -667,7 +666,8 @@ sweep_cache() {
lru_last = p->lru_prev;
kmem_free(p->rname, strlen(p->rname) + 1);
- kmem_free(p->localcred, sizeof (struct bsdcred));
+ kmem_free(p->localcred, sizeof (struct bsdcred) +
+ (ngroups_max - 1) * sizeof (gid_t));
mutex_destroy(&p->lock);
kmem_cache_free(authdes_cache_handle, p);
diff --git a/usr/src/uts/common/sys/cred.h b/usr/src/uts/common/sys/cred.h
index 1b07a5d6f3..5056f9a511 100644
--- a/usr/src/uts/common/sys/cred.h
+++ b/usr/src/uts/common/sys/cred.h
@@ -56,6 +56,7 @@ struct prcred;
struct ksid;
struct ksidlist;
struct credklpd;
+struct credgrp;
struct auditinfo_addr; /* cred.h is included in audit.h */
@@ -103,6 +104,7 @@ extern struct auditinfo_addr *crgetauinfo_modifiable(cred_t *);
extern uint_t crgetref(const cred_t *);
extern const gid_t *crgetgroups(const cred_t *);
+extern const gid_t *crgetggroups(const struct credgrp *);
extern int crgetngroups(const cred_t *);
@@ -119,7 +121,13 @@ extern int crsetresgid(cred_t *, gid_t, gid_t, gid_t);
*/
extern int crsetugid(cred_t *, uid_t, gid_t);
+/*
+ * Functions to handle the supplemental group list.
+ */
extern int crsetgroups(cred_t *, int, gid_t *);
+extern struct credgrp *crgrpcopyin(int, gid_t *);
+extern void crgrprele(struct credgrp *);
+extern void crsetcredgrp(cred_t *, struct credgrp *);
/*
* Private interface for setting zone association of credential.
diff --git a/usr/src/uts/common/sys/cred_impl.h b/usr/src/uts/common/sys/cred_impl.h
index ad70ffd868..fc2fa34e43 100644
--- a/usr/src/uts/common/sys/cred_impl.h
+++ b/usr/src/uts/common/sys/cred_impl.h
@@ -19,15 +19,13 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_CRED_IMPL_H
#define _SYS_CRED_IMPL_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <sys/cred.h>
#include <sys/priv_impl.h>
@@ -74,15 +72,13 @@ struct cred {
gid_t cr_rgid; /* real group id */
uid_t cr_suid; /* "saved" user id (from exec) */
gid_t cr_sgid; /* "saved" group id (from exec) */
- uint_t cr_ngroups; /* number of groups returned by */
- /* crgroups() */
cred_priv_t cr_priv; /* privileges */
projid_t cr_projid; /* project */
struct zone *cr_zone; /* pointer to per-zone structure */
struct ts_label_s *cr_label; /* pointer to the effective label */
struct credklpd *cr_klpd; /* pointer to the cred's klpd */
credsid_t *cr_ksid; /* pointer to SIDs */
- gid_t cr_groups[1]; /* cr_groups size not fixed */
+ struct credgrp *cr_grps; /* supplemental groups */
/* audit info is defined dynamically */
/* and valid only when audit enabled */
/* auditinfo_addr_t cr_auinfo; audit info */
diff --git a/usr/src/uts/common/sys/param.h b/usr/src/uts/common/sys/param.h
index 0279968fc8..2c3f632811 100644
--- a/usr/src/uts/common/sys/param.h
+++ b/usr/src/uts/common/sys/param.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -119,7 +119,8 @@ extern "C" {
* configurable parameter NGROUPS_MAX.
*/
#define NGROUPS_UMIN 0
-#define NGROUPS_UMAX 32
+#define NGROUPS_UMAX 1024
+#define NGROUPS_OLDMAX 32
/*
* NGROUPS_MAX_DEFAULT: *MUST* match NGROUPS_MAX value in limits.h.
diff --git a/usr/src/uts/common/sys/ucred.h b/usr/src/uts/common/sys/ucred.h
index c7247baafa..6f8f77832b 100644
--- a/usr/src/uts/common/sys/ucred.h
+++ b/usr/src/uts/common/sys/ucred.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* File with private definitions for the ucred structure for use by the
@@ -29,8 +29,6 @@
#ifndef _SYS_UCRED_H
#define _SYS_UCRED_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <sys/procfs.h>
#include <sys/cred.h>
@@ -88,8 +86,6 @@ struct ucred_s {
#define UCLABEL(uc) (bslabel_t *)(((uc)->uc_labeloff == 0) ? NULL : \
((char *)(uc)) + (uc)->uc_labeloff)
-#define UCRED_CRED_OFF (sizeof (struct ucred_s))
-
#endif /* _KERNEL || _STRUCTURED_PROC != 0 */
/*
@@ -100,13 +96,19 @@ struct ucred_s {
#ifdef _KERNEL
-extern uint32_t ucredsize;
+extern uint32_t ucredminsize(const cred_t *);
-#define UCRED_PRIV_OFF (UCRED_CRED_OFF + sizeof (prcred_t) + \
- (ngroups_max - 1) * sizeof (gid_t))
+#define UCRED_PRIV_OFF (sizeof (struct ucred_s))
#define UCRED_AUD_OFF (UCRED_PRIV_OFF + priv_prgetprivsize(NULL))
#define UCRED_LABEL_OFF (UCRED_AUD_OFF + get_audit_ucrsize())
-#define UCRED_SIZE (UCRED_LABEL_OFF + sizeof (bslabel_t))
+
+/* The prcred_t has a variable size; it should be last. */
+#define UCRED_CRED_OFF (UCRED_LABEL_OFF + \
+ (is_system_labeled() ? sizeof (bslabel_t) : 0))
+
+#define UCRED_SIZE (UCRED_CRED_OFF + sizeof (prcred_t) + \
+ (ngroups_max - 1) * sizeof (gid_t))
+
struct proc;
diff --git a/usr/src/uts/common/syscall/groups.c b/usr/src/uts/common/syscall/groups.c
index 3a46812f8a..17434ff36d 100644
--- a/usr/src/uts/common/syscall/groups.c
+++ b/usr/src/uts/common/syscall/groups.c
@@ -20,18 +20,17 @@
*/
/*
* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI" /* from SVr4.0 1.78 */
-
#include <sys/param.h>
#include <sys/types.h>
#include <sys/sysmacros.h>
#include <sys/systm.h>
-#include <sys/cred_impl.h>
+#include <sys/cred.h>
+#include <sys/sid.h>
#include <sys/errno.h>
#include <sys/proc.h>
#include <sys/debug.h>
@@ -45,11 +44,11 @@ setgroups(int gidsetsize, gid_t *gidset)
cred_t *cr, *newcr;
int i;
int n = gidsetsize;
- gid_t *groups = NULL;
int error;
int scnt = 0;
ksidlist_t *ksl = NULL;
zone_t *zone;
+ struct credgrp *grps = NULL;
/* Perform the cheapest tests before grabbing p_crlock */
if (n > ngroups_max || n < 0)
@@ -57,25 +56,27 @@ setgroups(int gidsetsize, gid_t *gidset)
zone = crgetzone(CRED());
if (n != 0) {
- groups = kmem_alloc(n * sizeof (gid_t), KM_SLEEP);
+ const gid_t *groups;
+
+ grps = crgrpcopyin(n, gidset);
- if (copyin(gidset, groups, n * sizeof (gid_t)) != 0) {
- kmem_free(groups, n * sizeof (gid_t));
+ if (grps == NULL)
return (set_errno(EFAULT));
- }
+
+ groups = crgetggroups(grps);
for (i = 0; i < n; i++) {
if (!VALID_GID(groups[i], zone)) {
- kmem_free(groups, n * sizeof (gid_t));
+ crgrprele(grps);
return (set_errno(EINVAL));
}
if (groups[i] > MAXUID)
scnt++;
}
if (scnt > 0) {
- ksl = kcrsid_gidstosids(zone, n, groups);
+ ksl = kcrsid_gidstosids(zone, n, (gid_t *)groups);
if (ksl == NULL) {
- kmem_free(groups, n * sizeof (gid_t));
+ crgrprele(grps);
return (set_errno(EINVAL));
}
}
@@ -95,8 +96,8 @@ retry:
mutex_exit(&p->p_crlock);
if ((error = secpolicy_allow_setid(cr, -1, B_FALSE)) != 0) {
- if (groups != NULL)
- kmem_free(groups, n * sizeof (gid_t));
+ if (grps != NULL)
+ crgrprele(grps);
if (ksl != NULL)
ksidlist_rele(ksl);
crfree(newcr);
@@ -110,13 +111,7 @@ retry:
crdup_to(cr, newcr);
crsetsidlist(newcr, ksl);
-
- if (n != 0) {
- bcopy(groups, newcr->cr_groups, n * sizeof (gid_t));
- kmem_free(groups, n * sizeof (gid_t));
- }
-
- newcr->cr_ngroups = n;
+ crsetcredgrp(newcr, grps);
p->p_cred = newcr;
crhold(newcr); /* hold for the current thread */
@@ -138,12 +133,12 @@ getgroups(int gidsetsize, gid_t *gidset)
int n;
cr = curthread->t_cred;
- n = (int)cr->cr_ngroups;
+ n = crgetngroups(cr);
if (gidsetsize != 0) {
if (gidsetsize < n)
return (set_errno(EINVAL));
- if (copyout(cr->cr_groups, gidset, n * sizeof (gid_t)))
+ if (copyout(crgetgroups(cr), gidset, n * sizeof (gid_t)))
return (set_errno(EFAULT));
}