Re: [PATCH] Add regex plugin for nfsidmap

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 3/31/20 5:02 AM, Stefan Walter wrote:
> The patch below adds a new nfsidmap plugin that uses regex to extract
> ids from NFSv4 names. Names are created from ids by pre- and appending
> static strings. It works with both idmapd on servers and nfsidmap on
> clients.
> 
> This plugin is especially useful in environments with Active Directory
> where distributed NFS servers use a mix of short (uname) and long
> (domain\uname) names. Combining it with the nsswitch plugin covers both
> variants.
> 
> Currently this plugin has its own git project on github but I think
> it could be helpful if it would be incorporated in the main nfs-utils
> plugin set.
Committed... (tag: nfs-utils-2-4-4-rc3)

steved.

> 
> ---
>  support/nfsidmap/Makefile.am   |   6 +-
>  support/nfsidmap/idmapd.conf.5 |  66 +++-
>  support/nfsidmap/regex.c       | 548 +++++++++++++++++++++++++++++++++
>  3 files changed, 617 insertions(+), 3 deletions(-)
>  create mode 100644 support/nfsidmap/regex.c
> 
> diff --git a/support/nfsidmap/Makefile.am b/support/nfsidmap/Makefile.am
> index 9c21fa34..35575a95 100644
> --- a/support/nfsidmap/Makefile.am
> +++ b/support/nfsidmap/Makefile.am
> @@ -15,7 +15,7 @@ else
>  GUMS_MAPPING_LIB =
>  endif
>  lib_LTLIBRARIES = libnfsidmap.la
> -pkgplugin_LTLIBRARIES = nsswitch.la static.la $(UMICH_LDAP_LIB) $(GUMS_MAPPING_LIB)
> +pkgplugin_LTLIBRARIES = nsswitch.la static.la regex.la $(UMICH_LDAP_LIB) $(GUMS_MAPPING_LIB)
>  
>  # Library versioning notes from:
>  #  http://sources.redhat.com/autobook/autobook/autobook_91.html
> @@ -41,6 +41,10 @@ static_la_SOURCES = static.c
>  static_la_LDFLAGS = -module -avoid-version
>  static_la_LIBADD = ../../support/nfs/libnfsconf.la
>  
> +regex_la_SOURCES = regex.c
> +regex_la_LDFLAGS = -module -avoid-version
> +regex_la_LIBADD = ../../support/nfs/libnfsconf.la
> +
>  umich_ldap_la_SOURCES = umich_ldap.c
>  umich_ldap_la_LDFLAGS = -module -avoid-version
>  umich_ldap_la_LIBADD = -lldap ../../support/nfs/libnfsconf.la
> diff --git a/support/nfsidmap/idmapd.conf.5 b/support/nfsidmap/idmapd.conf.5
> index 61fbb613..e554a44e 100644
> --- a/support/nfsidmap/idmapd.conf.5
> +++ b/support/nfsidmap/idmapd.conf.5
> @@ -151,6 +151,58 @@ names to local user names.  Entries in the list are of the form:
>  .fi
>  .\"
>  .\" -------------------------------------------------------------------
> +.\" The [REGEX] section
> +.\" -------------------------------------------------------------------
> +.\"
> +.SS "[REGEX] section variables"
> +.nf
> +
> +.fi
> +If the "regex" translation method is specified, the following
> +variables within the [REGEX] section are used to map between NFS4 names and local IDs.
> +.TP
> +.B User-Regex
> +Case-insensitive regular expression that extracts the local user name from an NFSv4 name. Multiple expressions may be concatenated with '|'. The first match will be used.
> +There is no default. A basic regular expression for domain DOMAIN.ORG and realm MY.DOMAIN.ORG would be:
> +.nf
> +^DOMAIN\\([^@]+)@MY.DOMAIN.ORG$
> +.fi
> +.TP
> +.B Group-Regex
> +Case-insensitive regular expression that extracts the local group name from an NFSv4 name. Multiple expressions may be concatenated with '|'. The first match will be used.
> +There is no default. A basic regular expression for domain DOMAIN.ORG and realm MY.DOMAIN.ORG would be:
> +.nf
> +^([^@]+)@DOMAIN.ORG@xxxxxxxxxxxxx$|^DOMAIN\\([^@]+)@MY.DOMAIN.ORG$
> +.fi
> +.TP
> +.B Prepend-Before-User
> +Constant string to put before a local user name when building an NFSv4 name. Usually this is the short domain name followed by '\'.
> +(Default: none)
> +.TP
> +.B Append-After-User
> +Constant string to put after a local user name when building an NFSv4 name. Usually this is '@' followed by the default realm.
> +(Default: none)
> +.TP
> +.B Prepend-Before-Group
> +Constant string to put before a local group name when building an NFSv4 name. Usually not used.
> +(Default: none)
> +.TP
> +.B Append-After-Group
> +Constant string to put before a local group name when building an NFSv4 name. Usually this is '@' followed by the domain name followed by another '@' and the default realm.
> +(Default: none)
> +.TP
> +.B Group-Name-Prefix
> +Constant string that is prepended to a local group name when converting it to an NFSv4 name. If an NFSv4 group name has this prefix it is removed when converting it to a local group name.
> +With this group names of a central directory can be shortened for an isolated organizational unit if all groups have a common prefix.
> +(Default: none)
> +.TP
> +.B Group-Name-No-Prefix-Regex
> +Case-insensitive regular expression to exclude groups from adding and removing the prefix set by
> +.B Group-Name-Prefix
> +. The regular expression must match both the remote and local group names. Multiple expressions may be concatenated with '|'.
> +(Default: none)
> +.\"
> +.\" -------------------------------------------------------------------
>  .\" The [UMICH_SCHEMA] section
>  .\" -------------------------------------------------------------------
>  .\"
> @@ -286,13 +338,23 @@ Nobody-Group = nfsnobody
>  
>  [Translation]
>  
> -Method = umich_ldap,nsswitch
> -GSS-Methods = umich_ldap,static
> +Method = umich_ldap,regex,nsswitch
> +GSS-Methods = umich_ldap,regex,static
>  
>  [Static]
>  
>  johndoe@xxxxxxxxxxxxxxxx = johnny
>  
> +[Regex]
> +
> +User-Regex = ^DOMAIN\\([^@]+)@DOMAIN.ORG$
> +Group-Regex = ^([^@]+)@DOMAIN.ORG@xxxxxxxxxx$|^DOMAIN\\([^@]+)@DOMAIN.ORG$
> +Prepend-Before-User = DOMAIN\ 
> +Append-After-User = @DOMAIN.ORG
> +Append-After-Group = @domain.org@xxxxxxxxxx
> +Group-Name-Prefix = sales-
> +Group-Name-No-Prefix-Regex = -personal-group$
> +
>  [UMICH_SCHEMA]
>  
>  LDAP_server = ldap.domain.org
> diff --git a/support/nfsidmap/regex.c b/support/nfsidmap/regex.c
> new file mode 100644
> index 00000000..3a793152
> --- /dev/null
> +++ b/support/nfsidmap/regex.c
> @@ -0,0 +1,548 @@
> +/*
> + *  regex.c
> + *
> + *  regex idmapping functions.
> + *
> + *  Copyright (c) 2017-2020 Stefan Walter <stefan.walter@xxxxxxxxxxx>.
> + *  Copyright (c) 2008 David Härdeman <david@xxxxxxxxxxx>.
> + *  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 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 ``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 <unistd.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <sys/types.h>
> +#include <pwd.h>
> +#include <grp.h>
> +#include <errno.h>
> +#include <err.h>
> +#include <regex.h>
> +
> +#include "nfsidmap.h"
> +#include "nfsidmap_plugin.h"
> +
> +#define CONFIG_GET_STRING nfsidmap_config_get
> +extern const char *nfsidmap_config_get(const char *, const char *);
> +
> +#define MAX_MATCHES 100
> +
> +regex_t group_re;
> +regex_t user_re;
> +regex_t gpx_re;
> +int use_gpx;
> +const char * group_prefix;
> +const char * group_name_prefix;
> +const char * group_suffix;
> +const char * user_prefix;
> +const char * user_suffix;
> +const char * group_map_file;
> +const char * group_map_section;
> +char empty = '\0';
> +size_t group_name_prefix_length;
> +
> +struct pwbuf {
> +        struct passwd pwbuf;
> +        char buf[1];
> +};
> +
> +struct grbuf {
> +        struct group grbuf;
> +        char buf[1];
> +};
> +
> +static char *get_default_domain(void)
> +{
> +        static char default_domain[NFS4_MAX_DOMAIN_LEN] = "";
> +        if (default_domain[0] == 0) {
> +                nfs4_get_default_domain(NULL, default_domain, NFS4_MAX_DOMAIN_LEN);
> +        }
> +        return default_domain;
> +}
> +
> +/*
> + * Regexp Translation Methods
> + *
> + */
> +
> +static struct passwd *regex_getpwnam(const char *name, const char *UNUSED(domain),
> +				      int *err_p)
> +{
> +	struct passwd *pw;
> +	struct pwbuf *buf;
> +	size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
> +	char *localname;
> +	size_t namelen;
> +	int err;
> +	int status;
> +	int index;
> +	regmatch_t matches[MAX_MATCHES];
> +
> +	buf = malloc(sizeof(*buf) + buflen);
> +	if (!buf) {
> +		err = ENOMEM;
> +		goto err;
> +	}
> +
> +	status = regexec(&user_re, name, MAX_MATCHES, matches, 0);
> +	if (status) {
> +		IDMAP_LOG(4, ("regexp_getpwnam: user '%s' did not match regex", name));
> +		err = ENOENT;
> +		goto err_free_buf;
> +	}
> +
> +	for (index = 1; index < MAX_MATCHES ; index++)
> +	{
> +		if (matches[index].rm_so >= 0)
> +			break;
> +	}
> +
> +	if (index == MAX_MATCHES) {
> +		IDMAP_LOG(4, ("regexp_getpwnam: user '%s' did not match regex", name));
> +		err = ENOENT;
> +		goto err_free_buf;
> +	}
> +
> +	namelen = matches[index].rm_eo - matches[index].rm_so;
> +	localname= malloc(namelen + 1);
> +	if (!localname)
> +	{
> +		err = ENOMEM;
> +		goto err_free_buf;
> +	}
> +	strncpy(localname, name+matches[index].rm_so, namelen);
> +	localname[namelen] = '\0';
> +
> +again:
> +	err = getpwnam_r(localname, &buf->pwbuf, buf->buf, buflen, &pw);
> +
> +	if (err == EINTR)
> +		goto again;
> +
> +	if (!pw) {
> +		if (err == 0)
> +			err = ENOENT;
> +
> +		IDMAP_LOG(4, ("regex_getpwnam: local user '%s' for '%s' not found",
> +		  localname, name));
> +
> +		goto err_free_name;
> +	}
> +
> +	IDMAP_LOG(4, ("regexp_getpwnam: name '%s' mapped to '%s'",
> +		  name, localname));
> +
> +	*err_p = 0;
> +	return pw;
> +
> +err_free_name:
> +	free(localname);
> +err_free_buf:
> +	free(buf);
> +err:
> +	*err_p = err;
> +	return NULL;
> +}
> +
> +static struct group *regex_getgrnam(const char *name, const char *UNUSED(domain),
> +				      int *err_p)
> +{
> +	struct group *gr;
> +	struct grbuf *buf;
> +	size_t buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
> +	char *localgroup;
> +	char *groupname;
> +	size_t namelen;
> +	int err = 0;
> +	int index;
> +	int status;
> +	regmatch_t matches[MAX_MATCHES];
> +
> +	buf = malloc(sizeof(*buf) + buflen);
> +	if (!buf) {
> +		err = ENOMEM;
> +		goto err;
> +	}
> +
> +	status = regexec(&group_re, name, MAX_MATCHES, matches, 0);
> +	if (status) {
> +		IDMAP_LOG(4, ("regexp_getgrnam: group '%s' did not match regex", name));
> +		err = ENOENT;
> +		goto err_free_buf;
> +	}
> +
> +	for (index = 1; index < MAX_MATCHES ; index++)
> +	{
> +		if (matches[index].rm_so >= 0)
> +			break;
> +	}
> +
> +	if (index == MAX_MATCHES) {
> +		IDMAP_LOG(4, ("regexp_getgrnam: group '%s' did not match regex", name));
> +		err = ENOENT;
> +		goto err_free_buf;
> +	}
> +
> +	namelen = matches[index].rm_eo - matches[index].rm_so;
> +	localgroup = malloc(namelen + 1);
> +	if (!localgroup)
> +	{
> +		err = ENOMEM;
> +		goto err_free_buf;
> +	}
> +	strncpy(localgroup, name+matches[index].rm_so, namelen);
> +	localgroup[namelen] = '\0';
> +
> +	IDMAP_LOG(4, ("regexp_getgrnam: group '%s' after match of regex", localgroup));
> +
> +        groupname = localgroup;
> +    	if (group_name_prefix_length && ! strncmp(group_name_prefix, localgroup, group_name_prefix_length))
> +	{
> +		err = 1;
> +		if (use_gpx)
> +			err = regexec(&gpx_re, localgroup, 0, NULL, 0);
> +
> +		if (err)
> +		{
> +			IDMAP_LOG(4, ("regexp_getgrnam: removing prefix '%s' (%d long) from group '%s'", group_name_prefix, group_name_prefix_length, localgroup));
> +				groupname += group_name_prefix_length;
> +		}
> +		else
> +		{
> +			IDMAP_LOG(4, ("regexp_getgrnam: not removing prefix from group '%s'", localgroup));
> +		}
> +	}
> +
> +	IDMAP_LOG(4, ("regexp_getgrnam: will use '%s'", groupname));
> +
> +again:
> +	err = getgrnam_r(groupname, &buf->grbuf, buf->buf, buflen, &gr);
> +
> +	if (err == EINTR)
> +		goto again;
> +
> +	if (!gr) {
> +		if (err == 0)
> +			err = ENOENT;
> +
> +		IDMAP_LOG(4, ("regex_getgrnam: local group '%s' for '%s' not found", groupname, name));
> +
> +		goto err_free_name;
> +	}
> +
> +	IDMAP_LOG(4, ("regex_getgrnam: group '%s' mapped to '%s'", name, groupname));
> +
> +	free(localgroup);
> +
> +	*err_p = 0;
> +	return gr;
> +
> +err_free_name:
> +	free(localgroup);
> +err_free_buf:
> +	free(buf);
> +err:
> +	*err_p = err;
> +	return NULL;
> +}
> +
> +static int regex_gss_princ_to_ids(char *secname, char *princ,
> +				   uid_t *uid, uid_t *gid,
> +				   extra_mapping_params **UNUSED(ex))
> +{
> +	struct passwd *pw;
> +	int err;
> +
> +	/* XXX: Is this necessary? */
> +	if (strcmp(secname, "krb5") != 0 && strcmp(secname, "spkm3") != 0)
> +		return -EINVAL;
> +
> +	pw = regex_getpwnam(princ, NULL, &err);
> +
> +	if (pw) {
> +		*uid = pw->pw_uid;
> +		*gid = pw->pw_gid;
> +		free(pw);
> +	}
> +
> +	return -err;
> +}
> +
> +static int regex_gss_princ_to_grouplist(char *secname, char *princ,
> +					 gid_t *groups, int *ngroups,
> +					 extra_mapping_params **UNUSED(ex))
> +{
> +	struct passwd *pw;
> +	int err;
> +
> +	/* XXX: Is this necessary? */
> +	if (strcmp(secname, "krb5") != 0 && strcmp(secname, "spkm3") != 0)
> +		return -EINVAL;
> +
> +	pw = regex_getpwnam(princ, NULL, &err);
> +
> +	if (pw) {
> +		if (getgrouplist(pw->pw_name, pw->pw_gid, groups, ngroups) < 0)
> +			err = -ERANGE;
> +		free(pw);
> +	}
> +
> +	return -err;
> +}
> +
> +static int regex_name_to_uid(char *name, uid_t *uid)
> +{
> +	struct passwd *pw;
> +	int err;
> +
> +	pw = regex_getpwnam(name, NULL, &err);
> +
> +	if (pw) {
> +		*uid = pw->pw_uid;
> +		free(pw);
> +	}
> +
> +	return -err;
> +}
> +
> +static int regex_name_to_gid(char *name, gid_t *gid)
> +{
> +	struct group *gr;
> +	int err;
> +
> +	gr = regex_getgrnam(name, NULL, &err);
> +
> +	if (gr) {
> +		*gid = gr->gr_gid;
> +		free(gr);
> +	}
> +
> +	return -err;
> +}
> +
> +static int write_name(char *dest, char *localname, const char* name_prefix, const char *prefix, const char *suffix, size_t len)
> +{
> +	if (strlen(localname) + strlen(name_prefix) + strlen(prefix) + strlen(suffix) + 1 > len) {
> +		return -ENOMEM; /* XXX: Is there an -ETOOLONG? */
> +	}
> +	strcpy(dest, prefix);
> +	strcat(dest, name_prefix);
> +	strcat(dest, localname);
> +	strcat(dest, suffix);
> +
> +   	IDMAP_LOG(4, ("write_name: will use '%s'", dest));
> +
> +	return 0;
> +}
> +
> +static int regex_uid_to_name(uid_t uid, char *domain, char *name, size_t len)
> +{
> +	struct passwd *pw = NULL;
> +	struct passwd pwbuf;
> +	char *buf;
> +	size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
> +	int err = -ENOMEM;
> +
> +	buf = malloc(buflen);
> +	if (!buf)
> +		goto out;
> +	if (domain == NULL)
> +		domain = get_default_domain();
> +	err = -getpwuid_r(uid, &pwbuf, buf, buflen, &pw);
> +	if (pw == NULL)
> +		err = -ENOENT;
> +	if (err)
> +		goto out_buf;
> +	err = write_name(name, pw->pw_name, &empty, user_prefix, user_suffix, len);
> +out_buf:
> +	free(buf);
> +out:
> +	return err;
> +}
> +
> +static int regex_gid_to_name(gid_t gid, char *UNUSED(domain), char *name, size_t len)
> +{
> +	struct group *gr = NULL;
> +	struct group grbuf;
> +	char *buf;
> +    const char *name_prefix;
> +	size_t buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
> +	int err;
> +    char * groupname = NULL;
> +
> +	do {
> +		err = -ENOMEM;
> +		buf = malloc(buflen);
> +		if (!buf)
> +			goto out;
> +		err = -getgrgid_r(gid, &grbuf, buf, buflen, &gr);
> +		if (gr == NULL && !err)
> +			err = -ENOENT;
> +		if (err == -ERANGE) {
> +			buflen *= 2;
> +			free(buf);
> +		}
> +	} while (err == -ERANGE);
> +
> +	if (err)
> +		goto out_buf;
> +
> +	groupname = gr->gr_name;
> +    	name_prefix = group_name_prefix;
> +    	if (group_name_prefix_length)
> +        {
> +            if(! strncmp(group_name_prefix, groupname, group_name_prefix_length))
> +            {
> +			    name_prefix = &empty;
> +            }
> +            else if (use_gpx)
> +            {
> +	            err = regexec(&gpx_re, groupname, 0, NULL, 0);
> +	            if (!err)
> +                {
> +   			        IDMAP_LOG(4, ("regex_gid_to_name: not adding prefix to group '%s'", groupname));
> +			        name_prefix = &empty;
> +                }
> +            }
> +	}
> +      
> +	err = write_name(name, groupname, name_prefix, group_prefix, group_suffix, len);
> +
> +out_buf:
> +	free(buf);
> +out:
> +	return err;
> +}
> +
> +static int regex_init(void) {	
> +	const char *string;
> +	int status;
> +
> +
> +        string = CONFIG_GET_STRING("Regex", "User-Regex");
> +	if (!string)
> +	{
> +		warnx("regex_init: regex for user mapping missing");
> +		goto error1;
> +	}
> +    
> +	status = regcomp(&user_re, string, REG_EXTENDED|REG_ICASE); 
> +	if (status)
> +	{
> +		warnx("regex_init: compiling regex for user mapping failed with status %u", status);
> +		goto error1;
> +	}
> +
> +	string = CONFIG_GET_STRING("Regex", "Group-Regex");
> +	if (!string)
> +	{
> +		warnx("regex_init: regex for group mapping missing");
> +		goto error2;
> +	}
> +    
> +    status = regcomp(&group_re, string, REG_EXTENDED|REG_ICASE); 
> +    if (status)
> +    {
> +		warnx("regex_init: compiling regex for group mapping failed with status %u", status);
> +		goto error2;
> +    }
> +
> +	group_name_prefix = CONFIG_GET_STRING("Regex", "Group-Name-Prefix");
> +    if (!group_name_prefix)
> +    {
> +        group_name_prefix = &empty;
> +    }
> +    group_name_prefix_length = strlen(group_name_prefix);
> +
> +    user_prefix = CONFIG_GET_STRING("Regex", "Prepend-Before-User");
> +    if (!user_prefix)
> +    {
> +        user_prefix = &empty;
> +    }
> +
> +    user_suffix = CONFIG_GET_STRING("Regex", "Append-After-User"); 
> +    if (!user_suffix)
> +    {
> +        user_suffix = &empty;
> +    }
> +
> +    group_prefix = CONFIG_GET_STRING("Regex", "Prepend-Before-Group"); 
> +    if (!group_prefix)
> +    {
> +        group_prefix = &empty;
> +    }
> +
> +    group_suffix = CONFIG_GET_STRING("Regex", "Append-After-Group"); 
> +    if (!group_suffix)
> +    {
> +        group_suffix = &empty;
> +    }
> +
> +    string = CONFIG_GET_STRING("Regex", "Group-Name-No-Prefix-Regex");
> +    use_gpx = 0;
> +    if (string)
> +    {
> +        status = regcomp(&gpx_re, string, REG_EXTENDED|REG_ICASE); 
> +
> +        if (status)
> +        {
> +	    	warnx("regex_init: compiling regex for group prefix exclusion failed with status %u", status);
> +		    goto error3;
> +        }
> +
> +        use_gpx = 1;
> +    }
> +
> +    return 0;
> +
> +error3:
> +	regfree(&group_re);
> +error2:
> +	regfree(&user_re);
> +error1:
> +	return 0;
> + /* return -EINVAL; */
> +}
> +
> +
> +struct trans_func regex_trans = {
> +	.name			= "regex",
> +	.init			= regex_init,
> +	.name_to_uid		= regex_name_to_uid,
> +	.name_to_gid		= regex_name_to_gid,
> +	.uid_to_name		= regex_uid_to_name,
> +	.gid_to_name		= regex_gid_to_name,
> +	.princ_to_ids		= regex_gss_princ_to_ids,
> +	.gss_princ_to_grouplist	= regex_gss_princ_to_grouplist,
> +};
> +
> +struct trans_func *libnfsidmap_plugin_init()
> +{
> +	return (&regex_trans);
> +}
> +
> 





[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux