Ejemplo n.º 1
0
int principal2uid(char *principal, uid_t * puid)
{
#ifdef _USE_NFSIDMAP
  gid_t gss_gid;
  uid_t gss_uid;
  int rc;

  if(uidmap_get(principal, (unsigned long *)&gss_uid) != ID_MAPPER_SUCCESS)
    {
      if(!nfsidmap_set_conf())
        {
          LogCrit(COMPONENT_IDMAPPER,
                  "principal2uid: nfsidmap_set_conf failed");
          return 0;
        }

      /* nfs4_gss_princ_to_ids required to extract uid/gid from gss creds */
      LogFullDebug(COMPONENT_IDMAPPER,
                   "calling nfs4_gss_princ_to_ids() to map principal to uid/gid");
      rc = nfs4_gss_princ_to_ids("krb5", principal, &gss_uid, &gss_gid);
      if(rc)
        {
          LogFullDebug(COMPONENT_IDMAPPER,
                       "principal2uid: nfs4_gss_princ_to_ids %s failed %d (%s)",
                       principal, -rc, strerror(-rc));
          return 0;
        }
      if(uidmap_add(principal, gss_uid) != ID_MAPPER_SUCCESS)
	{
	  LogCrit(COMPONENT_IDMAPPER,
		  "principal2uid: uidmap_add %s %d failed",
		  principal, gss_uid);
	  return 0;
	}
      if(uidgidmap_add(gss_uid, gss_gid) != ID_MAPPER_SUCCESS)
        {
          LogCrit(COMPONENT_IDMAPPER,
                  "principal2uid: uidgidmap_add gss_uid %d gss_gid %d failed",
                  gss_uid, gss_gid);
          return 0;
        }
    }

  LogFullDebug(COMPONENT_IDMAPPER,
               "principal2uid: uidmap_get mapped %s to uid= %d",
               principal, gss_uid);
  *puid = gss_uid;

  return 1;
#else
  return 0 ;
#endif /* _USE_NFSIDMAP */
}                               /* principal2uid */
Ejemplo n.º 2
0
/**
 *
 * name2uid: convert a name to a uid
 *
 * convert a name to a uid
 *
 * @param name [IN]  the name of the user
 * @param puid [OUT] the resulting uid
 *
 * return 1 if successful, 0 otherwise
 *
 */
int name2uid(char *name, uid_t * puid)
{
  struct passwd passwd;
  struct passwd *ppasswd;
  char buff[NFS4_MAX_DOMAIN_LEN];
  uid_t uid;
#ifdef _HAVE_GSSAPI
  gid_t gss_gid;
  uid_t gss_uid;
#endif
#ifdef _USE_NFSIDMAP
  char fqname[NFS4_MAX_DOMAIN_LEN];
  int rc;
#endif

  /* NFsv4 specific features: RPCSEC_GSS will provide user like nfs/<host>
   * choice is made to map them to root */
  if(!strncmp(name, "nfs/", 4))
    {
      /* This is a "root" request made from the hostbased nfs principal, use root */
      LogFullDebug(COMPONENT_IDMAPPER,
                   "name2uid: mapping %s to root (uid = 0)",
                   name);
      *puid = 0;

      return 1;
    }

  if(uidmap_get(name, (unsigned long *)&uid) == ID_MAPPER_SUCCESS)
    {
      LogFullDebug(COMPONENT_IDMAPPER,
                   "name2uid: uidmap_get mapped %s to uid= %d",
                   name, uid);
      *puid = uid;

      return 1 ;
    }
  else
    {
#ifdef _SOLARIS
      if(getpwnam_r(name, &passwd, buff, NFS4_MAX_DOMAIN_LEN) != 0)
#else
      if(getpwnam_r(name, &passwd, buff, NFS4_MAX_DOMAIN_LEN, &ppasswd) != 0)
#endif                          /* _SOLARIS */
        {
          LogFullDebug(COMPONENT_IDMAPPER,
                       "name2uid: getpwnam_r %s failed",
                       name);
          *puid = -1;
          return 0;
        }
      else
        {
          *puid = passwd.pw_uid;
#ifdef _HAVE_GSSAPI
          if(uidgidmap_add(passwd.pw_uid, passwd.pw_gid) != ID_MAPPER_SUCCESS)
            {
              LogCrit(COMPONENT_IDMAPPER,
                      "name2uid: uidgidmap_add gss_uid %d gss_gid %d failed",
                      gss_uid, gss_gid);
              return 0;
            }
#endif                          /* _HAVE_GSSAPI */
          if(uidmap_add(name, passwd.pw_uid) != ID_MAPPER_SUCCESS)
            {
              LogCrit(COMPONENT_IDMAPPER,
                      "name2uid: uidmap_add %s %d failed",
                      name, passwd.pw_uid);
              return 0;
            }

           return 1 ; /* Job is done */
        }

#ifdef _USE_NFSIDMAP
      if(!nfsidmap_set_conf())
        {
          LogCrit(COMPONENT_IDMAPPER,
                  "name2uid: nfsidmap_set_conf failed");
          return 0;
        }

      /* obtain fully qualified name */
      if(strchr(name, '@') == NULL)
        sprintf(fqname, "%s@%s", name, idmap_domain);
      else
        strncpy(fqname, name, NFS4_MAX_DOMAIN_LEN - 1);

      rc = nfs4_name_to_uid(fqname, puid);
      if(rc)
        {
          LogFullDebug(COMPONENT_IDMAPPER,
                       "name2uid: nfs4_name_to_uid %s failed %d (%s)",
                       fqname, -rc, strerror(-rc));
          return 0;
        }

      LogFullDebug(COMPONENT_IDMAPPER,
                   "name2uid: nfs4_name_to_uid %s returned %d",
                   fqname, *puid);

      if(uidmap_add(fqname, *puid) != ID_MAPPER_SUCCESS)
        {
          LogCrit(COMPONENT_IDMAPPER,
                  "name2uid: uidmap_add %s %d failed",
                  fqname, *puid);
          return 0;
        }

#ifdef _HAVE_GSSAPI
      /* nfs4_gss_princ_to_ids required to extract uid/gid from gss creds
       * XXX: currently uses unqualified name as per libnfsidmap comments */
      rc = nfs4_gss_princ_to_ids("krb5", name, &gss_uid, &gss_gid);
      if(rc)
        {
          LogFullDebug(COMPONENT_IDMAPPER,
                       "name2uid: nfs4_gss_princ_to_ids %s failed %d (%s)",
                       name, -rc, strerror(-rc));
          return 0;
        }

      if(uidgidmap_add(gss_uid, gss_gid) != ID_MAPPER_SUCCESS)
        {
          LogCrit(COMPONENT_IDMAPPER,
                  "name2uid: uidgidmap_add gss_uid %d gss_gid %d failed",
                  gss_uid, gss_gid);
          return 0;
        }
#endif                          /* _HAVE_GSSAPI */

#endif                           /* _USE_NFSIDMAP */

    }

  return 1;
}                               /* name2uid */
Ejemplo n.º 3
0
static int
get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred)
{
	u_int32_t	maj_stat, min_stat;
	gss_buffer_desc	name;
	char		*sname;
	int		res = -1;
	uid_t		uid, gid;
	gss_OID		name_type = GSS_C_NO_OID;
	char		*secname;

	maj_stat = gss_display_name(&min_stat, client_name, &name, &name_type);
	if (maj_stat != GSS_S_COMPLETE) {
		pgsserr("get_ids: gss_display_name",
			maj_stat, min_stat, mech);
		goto out;
	}
	if (name.length >= 0xffff || /* be certain name.length+1 doesn't overflow */
	    !(sname = calloc(name.length + 1, 1))) {
		printerr(0, "WARNING: get_ids: error allocating %d bytes "
			"for sname\n", name.length + 1);
		gss_release_buffer(&min_stat, &name);
		goto out;
	}
	memcpy(sname, name.value, name.length);
	printerr(1, "sname = %s\n", sname);
	gss_release_buffer(&min_stat, &name);

	res = -EINVAL;
	if ((secname = mech2file(mech)) == NULL) {
		printerr(0, "WARNING: get_ids: error mapping mech to "
			"file for name '%s'\n", sname);
		goto out_free;
	}
	nfs4_init_name_mapping(NULL); /* XXX: should only do this once */
	res = nfs4_gss_princ_to_ids(secname, sname, &uid, &gid);
	if (res < 0) {
		/*
		 * -ENOENT means there was no mapping, any other error
		 * value means there was an error trying to do the
		 * mapping.
		 * If there was no mapping, we send down the value -1
		 * to indicate that the anonuid/anongid for the export
		 * should be used.
		 */
		if (res == -ENOENT) {
			cred->cr_uid = -1;
			cred->cr_gid = -1;
			cred->cr_ngroups = 0;
			res = 0;
			goto out_free;
		}
		printerr(1, "WARNING: get_ids: failed to map name '%s' "
			"to uid/gid: %s\n", sname, strerror(-res));
		goto out_free;
	}
	cred->cr_uid = uid;
	cred->cr_gid = gid;
	add_supplementary_groups(secname, sname, cred);
	res = 0;
out_free:
	free(sname);
out:
	return res;
}
Ejemplo n.º 4
0
/**
 * @brief Convert a principal (as returned by @c gss_display_name) to a UID
 *
 * @param[in]     name The principal of the user
 * @param[out]    uid The resulting UID
 *
 * @return true if successful, false otherwise
 */
bool principal2uid(char *principal, uid_t *uid, gid_t *gid)
#endif
{
#ifdef USE_NFSIDMAP
	uid_t gss_uid = ANON_UID;
	gid_t gss_gid = ANON_GID;
	const gid_t *gss_gidres = NULL;
	int rc;
	bool success;
	struct gsh_buffdesc princbuff = {
		.addr = principal,
		.len = strlen(principal)
	};
#endif

	if (nfs_param.nfsv4_param.use_getpwnam)
		return false;

#ifdef USE_NFSIDMAP
	PTHREAD_RWLOCK_rdlock(&idmapper_user_lock);
	success =
	    idmapper_lookup_by_uname(&princbuff, &gss_uid, &gss_gidres, true);
	if (success && gss_gidres)
		gss_gid = *gss_gidres;
	PTHREAD_RWLOCK_unlock(&idmapper_user_lock);
	if (unlikely(!success)) {
		if ((princbuff.len >= 4)
		    && (!memcmp(princbuff.addr, "nfs/", 4)
			|| !memcmp(princbuff.addr, "root/", 5)
			|| !memcmp(princbuff.addr, "host/", 5))) {
			/* NFSv4 specific features: RPCSEC_GSS will
			 * provide user like
			 *
			 * nfs/<host>
			 * root/<host>
			 * host/<host>
			 * choice is made to map them to root */
			/* This is a "root" request made from the
			   hostbased nfs principal, use root */
			*uid = 0;
			return true;
		}
		/* nfs4_gss_princ_to_ids required to extract uid/gid
		   from gss creds */
		rc = nfs4_gss_princ_to_ids("krb5", principal, &gss_uid,
					   &gss_gid);
		if (rc) {
#ifdef _MSPAC_SUPPORT
			bool found_uid = false;
			bool found_gid = false;

			if (gd->flags & SVC_RPC_GSS_FLAG_MSPAC) {
				struct wbcAuthUserParams params;
				wbcErr wbc_err;
				struct wbcAuthUserInfo *info;
				struct wbcAuthErrorInfo *error = NULL;

				memset(&params, 0, sizeof(params));
				params.level = WBC_AUTH_USER_LEVEL_PAC;
				params.password.pac.data =
				    (uint8_t *) gd->pac.ms_pac.value;
				params.password.pac.length =
				    gd->pac.ms_pac.length;

				wbc_err =
				    wbcAuthenticateUserEx(&params, &info,
							  &error);
				if (!WBC_ERROR_IS_OK(wbc_err)) {
					LogCrit(COMPONENT_IDMAPPER,
						"wbcAuthenticateUserEx returned %s",
						wbcErrorString(wbc_err));
					return false;
				}

				if (error) {
					LogCrit(COMPONENT_IDMAPPER,
						"nt_status: %s, display_string %s",
						error->nt_string,
						error->display_string);
					wbcFreeMemory(error);
					return false;
				}

				/* 1st SID is account sid, see wbclient.h */
				wbc_err =
				    wbcSidToUid(&info->sids[0].sid, &gss_uid);
				if (!WBC_ERROR_IS_OK(wbc_err)) {
					LogCrit(COMPONENT_IDMAPPER,
						"wbcSidToUid for uid returned %s",
						wbcErrorString(wbc_err));
					wbcFreeMemory(info);
					return false;
				}

				/* 2nd SID is primary_group sid, see
				   wbclient.h */
				wbc_err =
				    wbcSidToGid(&info->sids[1].sid, &gss_gid);
				if (!WBC_ERROR_IS_OK(wbc_err)) {
					LogCrit(COMPONENT_IDMAPPER,
						"wbcSidToUid for gid returned %s\n",
						wbcErrorString(wbc_err));
					wbcFreeMemory(info);
					return false;
				}
				wbcFreeMemory(info);
				found_uid = true;
				found_gid = true;
			}
#endif				/* _MSPAC_SUPPORT */
#ifdef _MSPAC_SUPPORT
			if ((found_uid == true) && (found_gid == true))
				goto principal_found;
#endif

			return false;
		}
#ifdef _MSPAC_SUPPORT
 principal_found:
#endif

		PTHREAD_RWLOCK_wrlock(&idmapper_user_lock);
		success =
		    idmapper_add_user(&princbuff, gss_uid, &gss_gid, true);
		PTHREAD_RWLOCK_unlock(&idmapper_user_lock);

		if (!success) {
			LogMajor(COMPONENT_IDMAPPER,
				 "idmapper_add_user(%s, %d, %d) failed",
				 principal, gss_uid, gss_gid);
		}
	}

	*uid = gss_uid;
	*gid = gss_gid;

	return true;
#else				/* !USE_NFSIDMAP */
	assert(!"prohibited by configuration");
	return false;
#endif
}