diff options
author | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2009-06-03 16:02:45 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2009-06-03 16:02:45 +0000 |
commit | 5e006585f6625087cf9b1b6aec4c0cba353a007c (patch) | |
tree | 38095539b7377a48b7d8eb761bce96015dee9565 | |
parent | d8ef56a7b9c8bde6f0559479aeacb00ff11ac8bf (diff) |
Take advantage of the surprise libc bump to bring in
YP group(5) exclusion, i.e. support -groupname:*:: in /etc/group.
Such groups will be excluded from later +:*::,
in just the same was as it is already done for passwd(5).
I have been running this since the autumn of 2008.
Discussed with several (including deraadt@, millert@, jmc@).
-rw-r--r-- | lib/libc/gen/getgrent.c | 30 | ||||
-rw-r--r-- | lib/libc/gen/getgrouplist.3 | 15 | ||||
-rw-r--r-- | lib/libc/gen/getgrouplist.c | 12 | ||||
-rw-r--r-- | lib/libc/gen/getpwent.c | 61 | ||||
-rw-r--r-- | lib/libc/yp/Makefile.inc | 3 | ||||
-rw-r--r-- | lib/libc/yp/ypexclude.c | 80 | ||||
-rw-r--r-- | lib/libc/yp/ypexclude.h | 41 | ||||
-rw-r--r-- | share/man/man5/group.5 | 15 |
8 files changed, 182 insertions, 75 deletions
diff --git a/lib/libc/gen/getgrent.c b/lib/libc/gen/getgrent.c index 7ae8a92a27e..9a332a987a8 100644 --- a/lib/libc/gen/getgrent.c +++ b/lib/libc/gen/getgrent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getgrent.c,v 1.26 2008/08/25 22:30:19 deraadt Exp $ */ +/* $OpenBSD: getgrent.c,v 1.27 2009/06/03 16:02:44 schwarze Exp $ */ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -41,6 +41,7 @@ #include <rpcsvc/yp.h> #include <rpcsvc/ypclnt.h> #include "ypinternal.h" +#include "ypexclude.h" #endif #include "thread_private.h" @@ -70,6 +71,7 @@ static struct group *getgrgid_gs(gid_t, struct group *, struct group_storage *); #ifdef YP +static struct _ypexclude *__ypexhead = NULL; enum _ypmode { YPMODE_NONE, YPMODE_FULL, YPMODE_NAME }; static enum _ypmode __ypmode; static char *__ypcurrent, *__ypdomain; @@ -198,6 +200,9 @@ start_gr(void) if (__ypcurrent) free(__ypcurrent); __ypcurrent = NULL; + if (__ypexhead) + __ypexclude_free(&__ypexhead); + __ypexhead = NULL; #endif return(1); } @@ -238,6 +243,9 @@ endgrent_basic(void) if (__ypcurrent) free(__ypcurrent); __ypcurrent = NULL; + if (__ypexhead) + __ypexclude_free(&__ypexhead); + __ypexhead = NULL; #endif } } @@ -394,6 +402,9 @@ grscan(int search, gid_t gid, const char *name, struct group *p_gr, line[datalen] = '\0'; bp = line; p_gr->gr_name = strsep(&bp, ":\n"); + if (__ypexclude_is(&__ypexhead, + p_gr->gr_name)) + continue; p_gr->gr_passwd = strsep(&bp, ":\n"); if (!(cp = strsep(&bp, ":\n"))) @@ -415,7 +426,9 @@ grscan(int search, gid_t gid, const char *name, struct group *p_gr, tptr = strsep(&bp, ":\n"); tptr++; - if (search && name && strcmp(tptr, name)) + if (search && name && + strcmp(tptr, name) || + __ypexclude_is(&__ypexhead, tptr)) continue; __ypmode = YPMODE_NAME; grname = strdup(tptr); @@ -423,12 +436,25 @@ grscan(int search, gid_t gid, const char *name, struct group *p_gr, } break; } + } else if (line[0] == '-') { + if(!__ypexclude_add(&__ypexhead, + strsep(&line, ":\n") + 1)) + if (foundyp) { + *foundyp = -1; + return (NULL); + } + continue; } parse: #endif p_gr->gr_name = strsep(&bp, ":\n"); if (search && name && strcmp(p_gr->gr_name, name)) continue; +#ifdef YP + if (__ypmode == YPMODE_FULL && + __ypexclude_is(&__ypexhead, p_gr->gr_name)) + continue; +#endif p_gr->gr_passwd = strsep(&bp, ":\n"); if (!(cp = strsep(&bp, ":\n"))) continue; diff --git a/lib/libc/gen/getgrouplist.3 b/lib/libc/gen/getgrouplist.3 index 363d68afd55..5f180ec314c 100644 --- a/lib/libc/gen/getgrouplist.3 +++ b/lib/libc/gen/getgrouplist.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: getgrouplist.3,v 1.14 2009/03/27 21:42:57 schwarze Exp $ +.\" $OpenBSD: getgrouplist.3,v 1.15 2009/06/03 16:02:44 schwarze Exp $ .\" .\" Copyright (c) 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -27,7 +27,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd $Mdocdate: March 27 2009 $ +.Dd $Mdocdate: June 3 2009 $ .Dt GETGROUPLIST 3 .Os .Sh NAME @@ -40,19 +40,24 @@ .Sh DESCRIPTION The .Fn getgrouplist -function reads through the group file and calculates -the group access list for the user specified in +function reads through the +.Xr group 5 +file and calculates the group access list for the user specified in .Fa name . The .Fa basegid is automatically included in the groups list. Typically this value is given as the group number from the password file. -If YP is active, the +.Pp +If YP is active and the group file contains no exclusions, the .Xr netid 5 file and the .Pa netid.byname YP map will be used in addition to the group file. +If the group file contains at least one exclusion, the +.Pa group.byname +YP map will be used in addition to the group file. .Pp The resulting group list is returned in the integer array pointed to by .Fa groups . diff --git a/lib/libc/gen/getgrouplist.c b/lib/libc/gen/getgrouplist.c index 846f0bc56cc..9b3d5fff649 100644 --- a/lib/libc/gen/getgrouplist.c +++ b/lib/libc/gen/getgrouplist.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getgrouplist.c,v 1.16 2009/03/27 12:31:31 schwarze Exp $ */ +/* $OpenBSD: getgrouplist.c,v 1.17 2009/06/03 16:02:44 schwarze Exp $ */ /* * Copyright (c) 2008 Ingo Schwarze <schwarze@usta.de> * Copyright (c) 1991, 1993 @@ -145,6 +145,7 @@ getgrouplist(const char *uname, gid_t agroup, gid_t *groups, int *grpcnt) { int i, ngroups = 0, ret = 0, maxgroups = *grpcnt, bail; int needyp = 0, foundyp = 0; + int *skipyp = &foundyp; extern struct group *_getgrent_yp(int *); struct group *grp; @@ -161,9 +162,12 @@ getgrouplist(const char *uname, gid_t agroup, gid_t *groups, int *grpcnt) * Scan the group file to find additional groups. */ setgrent(); - while ((grp = _getgrent_yp(&foundyp)) || foundyp) { + while ((grp = _getgrent_yp(skipyp)) || foundyp) { if (foundyp) { - needyp = 1; + if (foundyp > 0) + needyp = 1; + else + skipyp = NULL; foundyp = 0; continue; } @@ -190,7 +194,7 @@ getgrouplist(const char *uname, gid_t agroup, gid_t *groups, int *grpcnt) /* * If we were told that there is a YP marker, look at netid data. */ - if (needyp) { + if (skipyp && needyp) { char buf[MAXLINELENGTH], *ypdata = NULL, *key; static char *__ypdomain; struct passwd pwstore; diff --git a/lib/libc/gen/getpwent.c b/lib/libc/gen/getpwent.c index fed489674ec..247169e1753 100644 --- a/lib/libc/gen/getpwent.c +++ b/lib/libc/gen/getpwent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getpwent.c,v 1.39 2009/03/27 12:31:31 schwarze Exp $ */ +/* $OpenBSD: getpwent.c,v 1.40 2009/06/03 16:02:44 schwarze Exp $ */ /* * Copyright (c) 2008 Theo de Raadt * Copyright (c) 1988, 1993 @@ -48,6 +48,7 @@ #include <rpcsvc/yp.h> #include <rpcsvc/ypclnt.h> #include "ypinternal.h" +#include "ypexclude.h" #endif #include "thread_private.h" @@ -72,11 +73,6 @@ static struct passwd *_pwhashbyuid(uid_t uid, char *buf, #ifdef YP static char *__ypdomain; -struct _ypexclude { - const char *name; - struct _ypexclude *next; -}; - /* Following are used only by setpwent(), getpwent(), and endpwent() */ enum _ypmode { YPMODE_NONE, YPMODE_FULL, YPMODE_USER, YPMODE_NETGRP }; static enum _ypmode __ypmode; @@ -90,9 +86,6 @@ static struct _ypexclude *__ypexhead; static int __has_yppw(); static int __has_ypmaster(void); -static int __ypexclude_add(struct _ypexclude **, const char *); -static int __ypexclude_is(struct _ypexclude **, const char *); -static void __ypexclude_free(struct _ypexclude **); static void __ypproto_set(struct passwd *, long *, int, int *); static int __ypparse(struct passwd *pw, char *s, int); @@ -107,56 +100,6 @@ static struct passwd *__yppwlookup(int, char *, uid_t, struct passwd *, #define PASSWD_BYUID \ (__has_ypmaster() ? "master.passwd.byuid" : "passwd.byuid") -/* - * Using DB for this just wastes too damn much memory. - */ -static int -__ypexclude_add(struct _ypexclude **headp, const char *name) -{ - struct _ypexclude *new; - - if (name[0] == '\0') /* skip */ - return (0); - - new = (struct _ypexclude *)malloc(sizeof(struct _ypexclude)); - if (new == NULL) - return (1); - new->name = strdup(name); - if (new->name == NULL) { - free(new); - return (1); - } - - new->next = *headp; - *headp = new; - return (0); -} - -static int -__ypexclude_is(struct _ypexclude **headp, const char *name) -{ - struct _ypexclude *curr; - - for (curr = *headp; curr; curr = curr->next) { - if (strcmp(curr->name, name) == 0) - return (1); /* excluded */ - } - return (0); -} - -static void -__ypexclude_free(struct _ypexclude **headp) -{ - struct _ypexclude *curr, *next; - - for (curr = *headp; curr; curr = next) { - next = curr->next; - free((void *)curr->name); - free(curr); - } - *headp = NULL; -} - static void __ypproto_set(struct passwd *pw, long *buf, int flags, int *yp_pw_flagsp) { diff --git a/lib/libc/yp/Makefile.inc b/lib/libc/yp/Makefile.inc index 4de7389f84f..c650738caa7 100644 --- a/lib/libc/yp/Makefile.inc +++ b/lib/libc/yp/Makefile.inc @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.inc,v 1.5 2008/12/22 19:09:29 jmc Exp $ +# $OpenBSD: Makefile.inc,v 1.6 2009/06/03 16:02:44 schwarze Exp $ # yp sources .PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/yp ${LIBCSRCDIR}/yp @@ -6,6 +6,7 @@ SRCS+= ypmatch_cache.c yp_bind.c yp_get_default_domain.c \ yp_first.c yp_all.c yp_order.c \ yp_master.c yp_maplist.c yperr_string.c ypprot_err.c _yp_check.c \ + ypexclude.c \ xdr_domainname.c xdr_keydat.c xdr_mapname.c xdr_peername.c \ xdr_valdat.c xdr_ypbind_binding.c xdr_ypbind_resp.c \ xdr_ypbind_resptype.c xdr_ypbind_setdom.c xdr_ypmaplist.c \ diff --git a/lib/libc/yp/ypexclude.c b/lib/libc/yp/ypexclude.c new file mode 100644 index 00000000000..35f88ed533c --- /dev/null +++ b/lib/libc/yp/ypexclude.c @@ -0,0 +1,80 @@ +/* $OpenBSD: ypexclude.c,v 1.1 2009/06/03 16:02:44 schwarze Exp $ */ +/* + * Copyright (c) 2008 Theo de Raadt + * Copyright (c) 1995, 1996, Jason Downs. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University of California nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <stdlib.h> +#include <string.h> +#include "ypexclude.h" + +int +__ypexclude_add(struct _ypexclude **headp, const char *name) +{ + struct _ypexclude *new; + + if (name[0] == '\0') /* skip */ + return (0); + + new = (struct _ypexclude *)malloc(sizeof(struct _ypexclude)); + if (new == NULL) + return (1); + new->name = strdup(name); + if (new->name == NULL) { + free(new); + return (1); + } + + new->next = *headp; + *headp = new; + return (0); +} + +int +__ypexclude_is(struct _ypexclude **headp, const char *name) +{ + struct _ypexclude *curr; + + for (curr = *headp; curr; curr = curr->next) { + if (strcmp(curr->name, name) == 0) + return (1); /* excluded */ + } + return (0); +} + +void +__ypexclude_free(struct _ypexclude **headp) +{ + struct _ypexclude *curr, *next; + + for (curr = *headp; curr; curr = next) { + next = curr->next; + free((void *)curr->name); + free(curr); + } + *headp = NULL; +} diff --git a/lib/libc/yp/ypexclude.h b/lib/libc/yp/ypexclude.h new file mode 100644 index 00000000000..4ab5fabe1b2 --- /dev/null +++ b/lib/libc/yp/ypexclude.h @@ -0,0 +1,41 @@ +/* $OpenBSD: ypexclude.h,v 1.1 2009/06/03 16:02:44 schwarze Exp $ */ +/* + * Copyright (c) 1995, 1996, Jason Downs. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University of California nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Using DB for this just wastes too damn much memory. + */ + +struct _ypexclude { + const char *name; + struct _ypexclude *next; +}; + +int __ypexclude_add(struct _ypexclude **, const char *); +int __ypexclude_is(struct _ypexclude **, const char *); +void __ypexclude_free(struct _ypexclude **); diff --git a/share/man/man5/group.5 b/share/man/man5/group.5 index 302b80d88ac..dd2ea4065e6 100644 --- a/share/man/man5/group.5 +++ b/share/man/man5/group.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: group.5,v 1.13 2009/03/27 12:31:31 schwarze Exp $ +.\" $OpenBSD: group.5,v 1.14 2009/06/03 16:02:44 schwarze Exp $ .\" $NetBSD: group.5,v 1.4 1995/07/28 06:41:39 phil Exp $ .\" .\" Copyright (c) 1980, 1991, 1993 @@ -31,7 +31,7 @@ .\" .\" @(#)group.5 8.3 (Berkeley) 4/19/94 .\" -.Dd $Mdocdate: March 27 2009 $ +.Dd $Mdocdate: June 3 2009 $ .Dt GROUP 5 .Os .Sh NAME @@ -100,12 +100,19 @@ file. .Sh YP SUPPORT If YP is active, the .Nm -file may also contain lines of the format +file also supports YP exclusions and inclusions. +.Pp +Lines beginning with a +.Ql \&- +(minus sign) are entries marked as being excluded from any following +inclusions, which are marked with a `+' (plus sign). +.Pp +Lines of the format .Bd -literal -offset indent +name:*:: .Ed .Pp -which causes the specified group to be included from the +cause the specified group to be included from the .Pa group.byname YP map. If no group name is specified, or the |