getgrent.c revision 36e852a172cba914383d7341c988128b2c667fbd
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* lib/nsswitch/compat/getgrent.c -- name-service-switch backend for getgrnam()
* group entries there that begin with "+" or "-", it consults other
* services. By default it uses NIS (YP), but the user can override this
* with a "group_compat" entry in /etc/nsswitch.conf, e.g.
* group_compat: ldap
*
* This code tries to produce the same results as the 4.x code, even when
* the latter seems ill thought-out. Bug-compatible, in other words.
* Though we do try to be more reasonable about the format of "+" and "-"
* entries here, i.e. you don't have to pad them with spurious colons and
*
* Caveats:
* - More than one source may be specified, with the usual switch semantics,
* but having multiple sources here is definitely odd.
* - People who recursively specify "compat" deserve what they get.
*/
#include <grp.h>
#include <stdlib.h>
#include <unistd.h> /* for GF_PATH */
#include <strings.h>
#include "compat_common.h"
static DEFINE_NSS_DB_ROOT(db_root);
static void
nss_db_params_t *p;
{
p->name = NSS_DBNAM_GROUP;
}
/*
* Validates group entry replacing gid > MAXUID by GID_NOBODY.
*/
int
{
return (NSS_STR_PARSE_SUCCESS);
continue;
continue;
return (NSS_STR_PARSE_PARSE);
return (NSS_STR_PARSE_PARSE);
return (NSS_STR_PARSE_SUCCESS);
return (NSS_STR_PARSE_ERANGE);
*linelenp = newlinelen;
return (NSS_STR_PARSE_SUCCESS);
}
static const char *
{
return (g->gr_name);
}
static int
{
}
static nss_status_t
void *a;
{
}
static int
{
}
static nss_status_t
void *a;
{
return (NSS_NOTFOUND);
}
static nss_status_t
getbymember(be, a)
void *a;
{
struct nss_XbyY_args grargs;
struct group *g;
/*
* Generic implementation: enumerate using getent(), then check each
* group returned by getent() to see whether it contains the user.
* There are much faster ways, but at least this one gets the right
* answer.
*/
/* full gid_array; nobody should have bothered to call us */
return (NSS_SUCCESS);
}
if (b == 0)
return (NSS_UNAVAIL);
(void) _nss_compat_setent(be, 0);
char **mem;
continue;
}
int i;
for (i = 0; i < numgids; i++) {
break;
}
}
if (i == numgids) {
/* filled the gid_array */
(void) _nss_compat_endent(be,
0);
NSS_XbyY_FREE(&gb);
return (NSS_SUCCESS);
}
/* Done with this group, try next */
break;
}
}
}
}
(void) _nss_compat_endent(be, 0);
NSS_XbyY_FREE(&gb);
return (NSS_NOTFOUND); /* Really means "gid_array not full yet" */
}
/*ARGSUSED*/
static int
const char **fields;
{
char *buf;
char *s;
int parsestat;
int dlen;
/*
* We're allowed to override the passwd (has anyone ever actually used
* the passwd in a group entry?) and the membership list, but not
* the groupname or the gid.
* That's what the SunOS 4.x code did; who are we to question it...
*
* Efficiency is heartlessly abandoned in the quest for simplicity.
*/
/* No legal overrides, leave *argp unscathed */
return (NSS_STR_PARSE_SUCCESS);
}
return (NSS_STR_PARSE_PARSE);
/* Really "out of memory", but PARSE_PARSE will have to do */
}
s = buf;
g->gr_name,
g->gr_gid);
s += strlen(s);
if (fields[3] != 0) {
s += strlen(s);
} else {
char **memp;
*s++ = ',';
}
s += len;
} else {
return (NSS_STR_PARSE_ERANGE);
}
}
}
/*
* if asked, return the data in /etc file format
*/
/* reset the result ptr to the original value */
} else {
}
} else {
}
return (parsestat);
}
static compat_backend_op_t group_ops[] = {
};
/*ARGSUSED*/
{
return (_nss_compat_constr(group_ops,
&db_root,
0,
merge_grents));
}