/*
* 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.
*/
#include <syslog.h>
#include "ldap_common.h"
/* netgroup attributes filters */
MAX_DOMAIN_LEN + 5)
static const char *netgrent_attrs[] = {
(char *)NULL
};
typedef struct netgroup_name {
char *name;
typedef struct {
typedef struct {
char **attrs;
char *netgroup;
typedef struct {
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];
}
/*
* Adds a name to the netgroup table
*
* Returns
* 0 if successfully added or already present
* -1 if memory allocation error or NULL netgroup_table_t
* from caller.
*/
static int
{
hash_t h;
/*
* Should never happen. But if it does,
* that's an error condition.
*/
return (-1);
}
/* no name to add means success */
return (0);
}
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
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 *p = triple;
#ifdef DEBUG
#endif /* DEBUG */
return (-1);
p++;
syntax_err = 0;
for (i = 0; i < 3; i++) {
char *start;
char *limit;
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);
}
/*
* Test membership in triple
* return 0 = no match
* return 1 = match
*/
static int
{
int ndomains;
char **pdomains;
int nhost;
char **phost;
int nusers;
char **pusers;
char **attr;
int i;
nhost = 0;
} else {
#ifdef DEBUG
#endif
}
nusers = 0;
} else {
#ifdef DEBUG
#endif
}
ndomains = 0;
#ifdef DEBUG
else
#endif
return (0);
#ifdef DEBUG
"(nusers: %d, nhost:%d, ndomains: %d)",
#endif
/* Special cases for speedup */
/* Special case for finding a single user in a netgroup */
/* jump to first comma and check next character */
#ifdef DEBUG
"current is: %s", current);
#endif
continue;
current++;
/* skip whitespaces */
current++;
/* if user part is null, then treat as wildcard */
return (1);
/* compare first character */
continue;
/* limit username to COMMA */
continue;
*limit = '\0';
/* remove blanks before COMMA */
*limit = '\0';
/* compare size of username */
continue;
}
/* do actual compare */
return (1);
} else {
continue;
}
}
/* Special case for finding a single host in a netgroup */
/* jump to first character and check */
#ifdef DEBUG
"current is: %s", current);
#endif
current++;
/* skip whitespaces */
current++;
/* if host part is null, then treat as wildcard */
return (1);
/* limit hostname to COMMA */
continue;
*limit = '\0';
/* remove blanks before COMMA */
*limit = '\0';
/* compare size of hostname */
continue;
}
/* do actual compare */
return (1);
} else {
continue;
}
}
} else {
continue;
#ifdef DEBUG
"triple is: %s", triple);
#endif
continue;
for (i = 0; i < nhost; i++)
break;
if (i == nhost)
continue;
}
for (i = 0; i < nusers; i++)
break;
if (i == nusers)
continue;
}
ndomains != 0) {
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
{
int rc;
int ret;
return ((nss_status_t)NSS_NOTFOUND);
#ifdef DEBUG
#endif
break;
_F_SETMEMBER, name);
break;
name);
break;
/* searching for current netgroup name entry */
if (status1 == NSS_TRYAGAIN) {
(void) __ns_ldap_freeError(&error);
return (status1);
}
}
(void) __ns_ldap_freeError(&error);
if (rc == NS_LDAP_SUCCESS) {
/* We found a match */
#ifdef DEBUG
"found match");
#endif
break;
}
/*
* No match found. Check for membernisnetgroup
* in result and if yes, start again with those.
*/
if (rc != 0)
break;
} else if (rc != NS_LDAP_NOTFOUND) {
break;
}
(void) __ns_ldap_freeResult(&result);
}
(void) __ns_ldap_freeResult(&result);
return (status);
}
/*
* __netgr_in checks only checks the netgroup specified in ngroup
*/
static nss_status_t
{
#ifdef DEBUG
"argc[%d]='%s',\n\tdomain:argc[%d]='%s' "
"netgroup: argc[%d]='%s'\n",
#endif /* DEBUG */
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);
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
{
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 (;;) {
/*
* Search through each netgroup consecutively: only search
* next netgroup when results from previous netgroup are
* processed.
* Needed for nested netgroup (memberNisNetgroup attributes).
*/
sizeof (name)) != 0)
break;
sizeof (searchfilter),
_F_SETMEMBER, name);
break;
#ifdef DEBUG
"getnetgr_ldap_getent: "
"netgroup name: %s", name);
#endif
break;
(void) __ns_ldap_freeError(&error);
} else {
#ifdef DEBUG
"getnetgr_ldap_getent: "
"__ns_ldap_list() returned %d "
#endif
/*
* Will exit when no more netgroup
* to search and no more p->results
* to process.
*/
(void) __ns_ldap_freeResult(&result);
}
} else { /* no more netgroup to process */
/*
* If no more results to process, and since
* there's no more netgroup to process either,
* then it's time to break and exit the for
* loop.
*/
#ifdef DEBUG
"getnetgr_ldap_getent: no more netgroup "
"to process, p->results: 0x%x",
p->results);
#endif
break;
}
}
continue;
continue;
}
break;
}
&domain);
attrs++;
else
if (rc == 0) {
#ifdef DEBUG
"getnetgr_ldap_getent: found triple "
"(%s, %s, %s), 0x%x to process",
p->attrs);
#endif
break;
}
}
if (rc != 0) {
break;
}
(void) __ns_ldap_freeResult(&p->results);
break;
}
}
return (status);
}
};
/*
*
*/
static nss_status_t
{
(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);
}
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));
}