2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
2N/A */
2N/A
2N/A
2N/A/*
2N/A * libidmap API custom functions for NFSv4
2N/A *
2N/A * These should probably be merged back into the common functions, but
2N/A * we need to get NFSv4 behavior correct for release with minimum risk
2N/A * to other components.
2N/A */
2N/A
2N/A#include "idmap_impl.h"
2N/A#include "idmap_cache.h"
2N/A#include "sidutil.h"
2N/A
2N/A/*
2N/A * Get uid given SID.
2N/A */
2N/Aidmap_stat
2N/Aidmap_nfsv4_getuidbysid(const char *sid, int flag, uid_t *uid)
2N/A{
2N/A idmap_retcode rc;
2N/A int is_user = 1;
2N/A int is_wuser = -1;
2N/A int direction;
2N/A char sidprefix[SID_STRSZ + 1];
2N/A idmap_rid_t rid;
2N/A
2N/A if (!is_sidstr(sid))
2N/A return (IDMAP_ERR_NOMAPPING);
2N/A
2N/A if (flag & IDMAP_REQ_FLG_USE_CACHE) {
2N/A rc = idmap_cache_lookup_uidbywinname(sid, NULL, uid);
2N/A if (rc == IDMAP_SUCCESS)
2N/A return (rc);
2N/A if (rc != IDMAP_ERR_NOMAPPING)
2N/A return (rc);
2N/A }
2N/A
2N/A sid_splitstr(sidprefix, sizeof (sidprefix), &rid, sid);
2N/A rc = idmap_get_w2u_mapping(sidprefix, &rid, NULL, NULL, flag,
2N/A &is_user, &is_wuser, uid, NULL, &direction, NULL);
2N/A
2N/A if (rc == IDMAP_SUCCESS && (flag & IDMAP_REQ_FLG_USE_CACHE)) {
2N/A idmap_cache_add_winname2uid(sid, NULL, *uid, direction);
2N/A }
2N/A
2N/A return (rc);
2N/A}
2N/A
2N/A
2N/A/*
2N/A * Get gid given SID.
2N/A */
2N/Aidmap_stat
2N/Aidmap_nfsv4_getgidbysid(const char *sid, int flag, gid_t *gid)
2N/A{
2N/A idmap_retcode rc;
2N/A int is_user = 0;
2N/A int is_wuser = -1;
2N/A int direction;
2N/A char sidprefix[SID_STRSZ + 1];
2N/A idmap_rid_t rid;
2N/A
2N/A if (!is_sidstr(sid))
2N/A return (IDMAP_ERR_NOMAPPING);
2N/A
2N/A if (flag & IDMAP_REQ_FLG_USE_CACHE) {
2N/A rc = idmap_cache_lookup_gidbywinname(sid, NULL, gid);
2N/A if (rc == IDMAP_SUCCESS)
2N/A return (rc);
2N/A if (rc != IDMAP_ERR_NOMAPPING)
2N/A return (rc);
2N/A }
2N/A
2N/A sid_splitstr(sidprefix, sizeof (sidprefix), &rid, sid);
2N/A rc = idmap_get_w2u_mapping(sidprefix, &rid, NULL, NULL, flag,
2N/A &is_user, &is_wuser, gid, NULL, &direction, NULL);
2N/A
2N/A if (rc == IDMAP_SUCCESS && (flag & IDMAP_REQ_FLG_USE_CACHE)) {
2N/A idmap_cache_add_winname2gid(sid, NULL, *gid, direction);
2N/A }
2N/A
2N/A return (rc);
2N/A}
2N/A
2N/A
2N/A/*
2N/A * Get winname given pid
2N/A */
2N/Astatic idmap_retcode
2N/Aidmap_nfsv4_getwinnamebypid(uid_t pid, int is_user, int flag, char **name)
2N/A{
2N/A idmap_retcode rc;
2N/A char *winname = NULL;
2N/A char *windomain = NULL;
2N/A int direction;
2N/A char *sidprefix = NULL;
2N/A idmap_rid_t rid;
2N/A
2N/A if (flag & IDMAP_REQ_FLG_USE_CACHE) {
2N/A if (is_user)
2N/A rc = idmap_cache_lookup_winnamebyuid(&winname,
2N/A &windomain, pid);
2N/A else
2N/A rc = idmap_cache_lookup_winnamebygid(&winname,
2N/A &windomain, pid);
2N/A if (rc == IDMAP_SUCCESS)
2N/A goto out;
2N/A if (rc != IDMAP_ERR_NOMAPPING)
2N/A goto err;
2N/A }
2N/A
2N/A /* Get mapping */
2N/A rc = idmap_get_u2w_mapping(&pid, NULL, flag, is_user, NULL,
2N/A &sidprefix, &rid, &winname, &windomain, &direction, NULL);
2N/A
2N/A /* Return on error */
2N/A if (rc != IDMAP_SUCCESS)
2N/A goto err;
2N/A
2N/A /*
2N/A * The given PID may have been mapped to a SID with no
2N/A * proper name@domain name. In those cases, we use the SID.
2N/A */
2N/A if (winname == NULL || windomain == NULL) {
2N/A idmap_free(winname);
2N/A winname = NULL;
2N/A idmap_free(windomain);
2N/A windomain = NULL;
2N/A (void) asprintf(&winname, "%s-%u", sidprefix, rid);
2N/A if (winname == NULL) {
2N/A rc = IDMAP_ERR_MEMORY;
2N/A goto err;
2N/A }
2N/A }
2N/A
2N/A if (flag & IDMAP_REQ_FLG_USE_CACHE) {
2N/A if (is_user)
2N/A idmap_cache_add_winname2uid(winname, windomain,
2N/A pid, direction);
2N/A else
2N/A idmap_cache_add_winname2gid(winname, windomain,
2N/A pid, direction);
2N/A }
2N/A
2N/Aout:
2N/A if (windomain == NULL) {
2N/A *name = winname;
2N/A winname = NULL;
2N/A } else {
2N/A (void) asprintf(name, "%s@%s", winname, windomain);
2N/A if (name == NULL) {
2N/A rc = IDMAP_ERR_MEMORY;
2N/A goto err;
2N/A }
2N/A }
2N/A rc = IDMAP_SUCCESS;
2N/A
2N/Aerr:
2N/A idmap_free(winname);
2N/A idmap_free(windomain);
2N/A idmap_free(sidprefix);
2N/A
2N/A return (rc);
2N/A}
2N/A
2N/A
2N/A/*
2N/A * Get winname given uid
2N/A */
2N/Aidmap_stat
2N/Aidmap_nfsv4_getwinnamebyuid(uid_t uid, int flag, char **name)
2N/A{
2N/A return (idmap_nfsv4_getwinnamebypid(uid, 1, flag, name));
2N/A}
2N/A
2N/A
2N/A/*
2N/A * Get winname given gid
2N/A */
2N/Aidmap_stat
2N/Aidmap_nfsv4_getwinnamebygid(gid_t gid, int flag, char **name)
2N/A{
2N/A return (idmap_nfsv4_getwinnamebypid(gid, 0, flag, name));
2N/A}