getnetgrent.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* 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
* 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 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <syslog.h>
#include "ldap_common.h"
/* netgroup attributes filters */
#define _N_NAME "cn"
#define _N_TRIPLE "nisnetgrouptriple"
#define _N_MEMBER "membernisnetgroup"
#define MAX_NETGR_NAME_LEN 256
#define MAX_DOMAIN_LEN 1024
MAX_DOMAIN_LEN + 5)
#define _F_GETNETGR_TRIPLE \
"(&(objectClass=nisNetGroup)" \
"(|(nisnetgrouptriple=(%s,%s,*))(nisnetgrouptriple=(%s,,*))" \
"(nisnetgrouptriple=(,%s,*))(nisnetgrouptriple=(,,*))))"
#define _F_GETNETGR_TRIPLE_SSD \
"(&(%%s)(|(nisnetgrouptriple=(%s,%s,*))(nisnetgrouptriple=(%s,,*))" \
"(nisnetgrouptriple=(,%s,*))(nisnetgrouptriple=(,,*))))"
#define _F_GETNETGR_TRIPLE_MACHINE \
"(&(objectClass=nisNetGroup)" \
"(|(nisnetgrouptriple=(%s,*,*))(nisnetgrouptriple=(,*,*))))"
#define _F_GETNETGR_TRIPLE_MACHINE_SSD \
"(&(%%s)(|(nisnetgrouptriple=(%s,*,*))(nisnetgrouptriple=(,*,*))))"
#define _F_GETNETGRENT \
"(&(objectClass=nisNetGroup)(nisnetgrouptriple=(%s,%s,%s)))"
#define _F_GETNETGRENT_SSD \
"(&(%%s)(nisnetgrouptriple=(%s,%s,%s)))"
/*
* Although the filter should include the test for (*,,*), this leads to
* an unindexed search. To support this, a plugin should be the directory
* server.
*/
#define _F_GETNETGR_TRIPLE_USER \
"(&(objectClass=nisNetGroup)(nisnetgrouptriple=(*,%s,*)))"
#define _F_GETNETGR_TRIPLE_USER_SSD \
"(&(%%s)(nisnetgrouptriple=(*,%s,*)))"
#define _F_GETMEMBERGRENT \
"(&(objectClass=nisNetGroup)(membernisnetgroup=%s))"
#define _F_GETMEMBERGRENT_SSD \
"(&(%%s)(membernisnetgroup=%s))"
#define _F_ISMEMBERGRENT \
"(&(objectClass=nisNetGroup)(cn=%s)(membernisnetgroup=%s))"
#define _F_ISMEMBERGRENT_SSD \
"(&(%%s)(cn=%s)(membernisnetgroup=%s))"
#define _F_GETMEMBER \
"(&(objectClass=nisNetGroup)(membernisnetgroup=%s))"
#define _F_GETMEMBER_SSD "(&(%%s)(membernisnetgroup=%s))"
#define _F_SETMEMBER "(&(objectClass=nisNetGroup)(cn=%s))"
#define _F_SETMEMBER_SSD "(&(%%s)(cn=%s))"
#define N_HASH 257
static const char *netgrent_attrs[] = {
(char *)NULL
};
static const char *netgr_name_attrs[] = {
(char *)NULL
};
static const char *netgr_leaf_attrs[] = {
(char *)NULL
};
static const char *netgr_node_attrs[] = {
(char *)NULL
};
typedef struct netgroup_name {
char *name;
struct netgroup_name *next;
struct netgroup_name *next_hash;
typedef struct {
typedef struct {
char **attrs;
void *cookie;
char *netgroup;
typedef struct {
struct nss_innetgr_args *ia;
const char *ssd_filter;
const char *netgrname;
const char *membername;
typedef unsigned int hash_t;
static hash_t
get_hash(const char *s)
{
unsigned int sum = 0;
unsigned int i;
for (i = 0; s[i] != '\0'; i++)
sum += ((unsigned char *)s)[i];
}
static netgroup_name_t *
{
hash_t h;
return (NULL);
break;
}
return (ret);
}
/*
* Adds a name to the netgroup table
*
* Returns
* 0 if successfully added or already present
* -1 if memory allocation error
*/
static int
{
hash_t h;
return (NULL);
break;
}
ng_new = (netgroup_name_t *)
return (-1);
return (-1);
}
}
return (0);
}
static netgroup_name_t *
{
return (NULL);
}
return (ng);
}
static void
{
return;
}
}
}
/*
* domain comparing routine
* n1: See if n1 is n2 or an ancestor of it
* n2: (in string terms, n1 is a suffix of n2)
* Returns ZERO for success, -1 for failure.
*/
static int
{
#define PASS 0
#define FAIL -1
return (FAIL);
/* Turn a blind eye to the presence or absence of trailing periods */
--l1;
}
--l2;
}
return (FAIL);
} else if (l1 == 0) { /* Trivially a suffix; */
/* (do we want this case?) */
return (PASS);
}
/* So 0 < l1 <= l2 */
return (FAIL);
}
return (PASS);
} else {
return (FAIL);
}
}
static int
{
int i, syntax_err;
char *splittriple[3];
char *p = triple;
#ifdef DEBUG
#endif /* DEBUG */
return (-1);
p++;
syntax_err = 0;
for (i = 0; i < 3; i++) {
char *start;
char *limit;
const char *terminators = ",) \t";
if (i == 2) {
/* Don't allow comma */
terminators++;
}
while (isspace(*p)) {
p++;
}
start = p;
if (limit == 0) {
syntax_err++;
break;
}
p = limit;
while (isspace(*p)) {
p++;
}
if (*p == terminators[0]) {
/*
* Successfully parsed this name and
* the separator after it (comma or
* right paren); leave p ready for
* next parse.
*/
p++;
/* Wildcard */
splittriple[i] = NULL;
} else {
*limit = '\0';
splittriple[i] = start;
}
} else {
syntax_err++;
break;
}
}
if (syntax_err != 0)
return (-1);
*hostname = splittriple[0];
return (0);
}
/*
* check the domain part of the triples.
* -1 = fails to match, 0 = match
*/
static int
{
int ndomains;
char **pdomains;
int nhost;
char **phost;
int nusers;
char **pusers;
char **attr;
char triple[MAX_TRIPLE_LEN];
int i;
nhost = 0;
nusers = 0;
ndomains = 0;
return (0);
continue;
continue;
for (i = 0; i < nhost; i++)
break;
if (i == nhost)
continue;
}
for (i = 0; i < nusers; i++)
break;
if (i == nusers)
continue;
}
for (i = 0; i < ndomains; i++)
break;
if (i == ndomains)
continue;
}
return (1);
}
return (0);
}
static int
{
return (1);
return (0);
}
static int
{
char **attrs;
char **a;
return (0);
do {
a--;
if (add_netgroup_name(*a, tab) != 0)
return (-1);
} while (a > attrs);
return (0);
}
static int
{
int ret = 0;
if (ret != 0)
break;
}
return (ret);
}
/*
* top_down_search checks only checks the netgroup specified in netgrname
*/
static nss_status_t
{
char searchfilter[SEARCHFILTERLEN];
char name[SEARCHFILTERLEN];
char userdata[SEARCHFILTERLEN];
int rc;
int ret;
return ((nss_status_t)NSS_NOTFOUND);
break;
name);
break;
break;
(void) __ns_ldap_freeError(&error);
/* We found a match */
break;
}
(void) __ns_ldap_freeResult(&result);
if (rc != NS_LDAP_SUCCESS)
break;
(void) __ns_ldap_freeError(&error);
}
(void) __ns_ldap_freeResult(&result);
(void) __ns_ldap_freeError(&error);
if (status == NSS_SUCCESS ||
break;
}
(void) __ns_ldap_freeResult(&result);
(void) __ns_ldap_freeError(&error);
return (status);
}
static int
const void *userdata)
{
}
const void *userdata);
/* return 1 when done, 0 otherwise */
static int
{
char name[MAX_GETMEM_FILTER_LEN];
char ssd_filter[MAX_GETMEM_FILTER_LEN];
int ret;
#ifdef DEBUG
#endif /* DEBUG */
return (0);
return (0);
return (0);
(void) __ns_ldap_freeResult(&result);
(void) __ns_ldap_freeError(&error);
}
/* Use the server's matching rule if not a case exact match */
static int
{
char searchfilter[MAX_ISMEM_FILTER_LEN];
char netgrname[MAX_ISMEM_FILTER_LEN];
char membername[MAX_ISMEM_FILTER_LEN];
char ssd_filter[MAX_ISMEM_FILTER_LEN];
int rc;
int ret;
sizeof (netgrname)) != 0)
return (0);
sizeof (membername)) != 0)
return (0);
return (0);
return (0);
(void) __ns_ldap_freeResult(&result);
(void) __ns_ldap_freeError(&error);
return (rc == NS_LDAP_SUCCESS);
}
static int
{
char **a, **attr;
return (NS_LDAP_CB_NEXT);
for (a = attr; *a; a++) {
#ifdef DEBUG
*a);
#endif /* DEBUG */
server_match(cookie)) {
return (NS_LDAP_CB_DONE);
}
}
}
for (a = attr; *a; a++) {
/* check if we have already visited this node */
continue;
return (NS_LDAP_CB_DONE);
}
return (NS_LDAP_CB_DONE);
}
return (NS_LDAP_CB_NEXT);
}
static int
{
/* Check to see if this entry matches the triple */
return (NS_LDAP_CB_NEXT);
}
/*
* __netgr_in checks only checks the netgroup specified in ngroup
*/
static nss_status_t
__netgr_in(void *a, char *netgrname)
{
char ssd_filter[MAX_INNETGR_FILTER_LEN];
char mach[MAX_INNETGR_FILTER_LEN];
char user[MAX_INNETGR_FILTER_LEN];
int rc;
int ret;
#ifdef DEBUG
"argc[%d]='%s',\n\tdomain:argc[%d]='%s' "
"netgroup: argc[%d]='%s'\n",
#endif /* DEBUG */
return (status);
return ((nss_status_t)NSS_NOTFOUND);
return ((nss_status_t)NSS_NOTFOUND);
return ((nss_status_t)NSS_NOTFOUND);
return ((nss_status_t)NSS_NOTFOUND);
return ((nss_status_t)NSS_NOTFOUND);
return ((nss_status_t)NSS_NOTFOUND);
return ((nss_status_t)NSS_NOTFOUND);
return ((nss_status_t)NSS_NOTFOUND);
} else {
}
(void) __ns_ldap_freeResult(&result);
(void) __ns_ldap_freeError(&error);
return (status);
}
/*ARGSUSED0*/
static nss_status_t
{
int i;
return (NSS_SUCCESS);
}
return (rc);
}
/*
*
*/
static nss_status_t
{
const char *netgroup = (const char *) a;
#ifdef DEBUG
#endif /* DEBUG */
/* is this another set on the same netgroup */
return ((nss_status_t)NSS_SUCCESS);
}
return (NSS_NOTFOUND);
}
static void
{
getnetgrent_cookie_t *p = *cookie;
#ifdef DEBUG
#endif /* DEBUG */
if (p == NULL)
return;
(void) __ns_ldap_freeResult(&p->results);
(void) __ns_ldap_freeError(&error);
free_netgroup_table(&p->tab);
free(p);
}
/*ARGSUSED1*/
static nss_status_t
{
#ifdef DEBUG
#endif /* DEBUG */
return ((nss_status_t)NSS_NOTFOUND);
}
/*ARGSUSED1*/
static nss_status_t
{
#ifdef DEBUG
#endif /* DEBUG */
return ((nss_status_t)NSS_NOTFOUND);
}
static nss_status_t
{
struct nss_getnetgrent_args *args;
char searchfilter[SEARCHFILTERLEN];
char userdata[SEARCHFILTERLEN];
char name[SEARCHFILTERLEN];
int rc;
char **attrs;
char *buffer;
int ret;
#ifdef DEBUG
#endif /* DEBUG */
args = (struct nss_getnetgrent_args *)a;
if (p == NULL)
return ((nss_status_t)NSS_SUCCESS);
for (;;) {
break;
break;
_F_SETMEMBER, name);
break;
name);
break;
(void) __ns_ldap_freeError(&error);
break;
}
(void) __ns_ldap_freeResult(&result);
(void) __ns_ldap_freeError(&error);
}
break;
(void) __ns_ldap_freeError(&error);
else {
(void) __ns_ldap_freeResult(&result);
(void) __ns_ldap_freeError(&error);
}
}
continue;
continue;
}
break;
}
attrs++;
else
if (rc == 0) {
break;
}
}
if (rc != 0) {
break;
}
(void) __ns_ldap_freeResult(&p->results);
break;
}
}
return (status);
}
static ldap_backend_op_t getnetgroup_ops[] = {
};
/*
*
*/
static nss_status_t
{
struct nss_setnetgrent_args *args =
(struct nss_setnetgrent_args *)a;
#ifdef DEBUG
#endif /* DEBUG */
return ((nss_status_t)NSS_NOTFOUND);
if (p == NULL)
return ((nss_status_t)NSS_NOTFOUND);
free(p);
return ((nss_status_t)NSS_NOTFOUND);
}
return ((nss_status_t)NSS_NOTFOUND);
}
/* now allocate and return iteration backend structure */
return (NSS_UNAVAIL);
get_be->netgroup_cookie = p;
return (NSS_SUCCESS);
}
/*ARGSUSED1*/
static nss_status_t
{
#ifdef DEBUG
#endif /* DEBUG */
(void) _clean_ldap_backend(be);
return ((nss_status_t)NSS_NOTFOUND);
}
static ldap_backend_op_t netgroup_ops[] = {
0,
0,
0,
netgr_in, /* innetgr() */
netgr_set /* setnetgrent() */
};
/*
* _nss_ldap_netgroup_constr is where life begins. This function calls the
* generic ldap constructor function to define and build the abstract data
* types required to support ldap operations.
*/
/*ARGSUSED0*/
const char *dummy3)
{
#ifdef DEBUG
"\n[getnetgrent.c: _nss_ldap_netgroup_constr]\n");
#endif /* DEBUG */
netgrent_attrs, NULL));
}