/*
* 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 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <grp.h>
#include "ldap_common.h"
#include <string.h>
/* String which may need to be removed from beginning of group password */
/* Group attributes filters */
/*
* Group membership can be defined by either username or DN, so when searching
* for groups by member we need to consider both. The first parameter in the
* filter is replaced by username, the second by DN.
*/
#define _F_GETGRMEM \
"(&(objectClass=posixGroup)(|(memberUid=%s)(memberUid=%s)))"
/*
* Copied from getpwnam.c, needed to look up user DN.
* Would it be better to move to ldap_common.h rather than duplicate?
*/
static const char *gr_attrs[] = {
(char *)NULL
};
/*
* _nss_ldap_group2str is the data marshaling method for the group getXbyY
* (e.g., getgrnam(), getgrgid(), getgrent()) backend processes. This method
* is called after a successful ldap search has been performed. This method
* will parse the ldap search values into the file format.
* e.g.
*
* adm::4:root,adm,daemon
*
*/
static int
{
int i;
int nss_result;
gid_nobody_v[0] = gid_nobody;
return (NSS_STR_PARSE_PARSE);
goto result_grp2str;
}
} else
goto result_grp2str;
}
/* group password could be NULL, replace it with "" */
} else {
/*
* Preen "{crypt}" if necessary.
* If the password does not include the {crypt} prefix
* then the password may be plain text. And thus
* perhaps crypt(3c) should be used to encrypt it.
* Currently the password is copied verbatim.
*/
else
}
goto result_grp2str;
}
/* Validate GID */
gid = gid_nobody_v;
/* no member is fine, skip processing the member list */
goto nomember;
}
for (i = 0; i < members->value_count; i++) {
goto result_grp2str;
}
/*
* If we find an '=' in the member attribute value, treat it as
* a DN, otherwise as a username.
*/
member_str++; /* skip over the '=' */
/* Fail if we can't pull a username out of the RDN */
",", &strtok_state))) {
goto result_grp2str;
}
} else {
}
if (*member_str != '\0') {
if (firstime) {
firstime = 0;
} else {
}
}
}
/* The front end marshaller doesn't need the trailing nulls */
return (nss_result);
}
/*
* getbynam gets a group entry by name. This function constructs an ldap
* search filter using the name invocation parameter and the getgrnam search
* filter defined. Once the filter is constructed, we searche for a matching
* entry and marshal the data results into struct group for the frontend
* process. The function _nss_ldap_group2ent performs the data marshaling.
*/
static nss_status_t
{
int ret;
0)
return ((nss_status_t)NSS_NOTFOUND);
return ((nss_status_t)NSS_NOTFOUND);
return ((nss_status_t)NSS_NOTFOUND);
}
/*
* getbygid gets a group entry by number. This function constructs an ldap
* search filter using the name invocation parameter and the getgrgid search
* filter defined. Once the filter is constructed, we searche for a matching
* entry and marshal the data results into struct group for the frontend
* process. The function _nss_ldap_group2ent performs the data marshaling.
*/
static nss_status_t
{
int ret;
return ((nss_status_t)NSS_NOTFOUND);
return ((nss_status_t)NSS_NOTFOUND);
return ((nss_status_t)NSS_NOTFOUND);
}
/*
* getbymember returns all groups a user is defined in. This function
* uses different architectural procedures than the other group backend
* system calls because it's a private interface. This function constructs
* an ldap search filter using the name invocation parameter. Once the
* filter is constructed, we search for all matching groups counting
* and storing each group name, gid, etc. Data marshaling is used for
* group processing. The function _nss_ldap_group2ent() performs the
* data marshaling.
*
* (const char *)argp->username; (size_t)strlen(argp->username);
* (gid_t)argp->gid_array; (int)argp->maxgids;
* (int)argp->numgids;
*/
static nss_status_t
{
int i, j, k;
int gcnt = (int)0;
char *strtok_state;
int ret;
return ((nss_status_t)NSS_NOTFOUND);
return ((nss_status_t)NSS_NOTFOUND);
return ((nss_status_t)NSS_NOTFOUND);
return ((nss_status_t)NSS_NOTFOUND);
/*
* Look up the user DN in ldap. If it's not found, search solely by
* username.
*/
return ((nss_status_t)lstat);
else
dn);
return ((nss_status_t)NSS_NOTFOUND);
dn);
return ((nss_status_t)NSS_NOTFOUND);
/*
* Free up resources from user DN search before performing group
* search.
*/
return ((nss_status_t)lstat);
return (NSS_NOTFOUND);
for (i = 0; i < result->entries_count; i++) {
if (membervalue) {
for (j = 0; membervalue[j]; j++) {
/*
* If we find an '=' in the member attribute
* value, treat it as a DN, otherwise as a
* username.
*/
member_str++; /* skip over the '=' */
&strtok_state);
} else {
member_str = membervalue[j];
}
if (member_str &&
"gidnumber");
(char **)NULL, 10);
k++) {
== gid)
/* already exists */
break;
}
= gid;
}
break;
}
}
}
}
return ((nss_status_t)NSS_NOTFOUND);
/*
* Return NSS_SUCCESS only if array is full.
* Explained in <nss_dbdefs.h>.
*/
: NSS_NOTFOUND));
}
};
/*ARGSUSED0*/
const char *dummy3)
{
}