nfs4: Add id mapper
This commit is contained in:
@@ -106,7 +106,7 @@ PRIVATE_SYSTEM_LIBS =
|
||||
SYSTEM_SERVERS = app_server cddb_daemon debug_server input_server mail_daemon
|
||||
media_addon_server media_server midi_server mount_server net_server
|
||||
notification_server power_daemon print_server print_addon_server registrar syslog_daemon
|
||||
dns_resolver_server
|
||||
dns_resolver_server nfs4_idmapper_server
|
||||
;
|
||||
|
||||
SYSTEM_NETWORK_DEVICES = ethernet loopback ;
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright 2012 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Paweł Dziepak, [email protected]
|
||||
*/
|
||||
|
||||
|
||||
#include "IdMap.h"
|
||||
|
||||
#include <FindDirectory.h>
|
||||
#include <team.h>
|
||||
#include <util/AutoLock.h>
|
||||
|
||||
#include "idmapper/IdMapper.h"
|
||||
|
||||
|
||||
IdMap* gIdMapper = NULL;
|
||||
|
||||
|
||||
IdMap::IdMap()
|
||||
{
|
||||
mutex_init(&fLock, NULL);
|
||||
_Repair();
|
||||
}
|
||||
|
||||
|
||||
IdMap::~IdMap()
|
||||
{
|
||||
delete_port(fRequestPort);
|
||||
delete_port(fReplyPort);
|
||||
mutex_destroy(&fLock);
|
||||
}
|
||||
|
||||
|
||||
uid_t
|
||||
IdMap::GetUserId(const char* owner)
|
||||
{
|
||||
return _GetValue<uid_t>(owner, MsgNameToUID);
|
||||
}
|
||||
|
||||
|
||||
gid_t
|
||||
IdMap::GetGroupId(const char* ownerGroup)
|
||||
{
|
||||
return _GetValue<gid_t>(ownerGroup, MsgNameToGID);
|
||||
}
|
||||
|
||||
|
||||
char*
|
||||
IdMap::GetOwner(uid_t user)
|
||||
{
|
||||
return reinterpret_cast<char*>(_GetBuffer(user, MsgUIDToName));
|
||||
}
|
||||
|
||||
|
||||
char*
|
||||
IdMap::GetOwnerGroup(gid_t group)
|
||||
{
|
||||
return reinterpret_cast<char*>(_GetBuffer(group, MsgGIDToName));
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
T
|
||||
IdMap::_GetValue(const char* buffer, int32 code)
|
||||
{
|
||||
MutexLocker _(fLock);
|
||||
do {
|
||||
status_t result = write_port(fRequestPort, MsgNameToUID, buffer,
|
||||
strlen(buffer) + 1);
|
||||
if (result != B_OK) {
|
||||
if (_Repair() != B_OK)
|
||||
return 0;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
int32 code;
|
||||
T value;
|
||||
result = read_port(fReplyPort, &code, &value, sizeof(T));
|
||||
if (result < B_OK) {
|
||||
if (_Repair() != B_OK)
|
||||
return 0;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
if (code != MsgReply)
|
||||
return 0;
|
||||
else
|
||||
return value;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
void*
|
||||
IdMap::_GetBuffer(T value, int32 code)
|
||||
{
|
||||
MutexLocker _(fLock);
|
||||
do {
|
||||
status_t result = write_port(fRequestPort, code, &value, sizeof(value));
|
||||
if (result != B_OK) {
|
||||
if (_Repair() != B_OK)
|
||||
return NULL;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
ssize_t size = port_buffer_size(fReplyPort);
|
||||
if (size < B_OK) {
|
||||
if (_Repair() != B_OK)
|
||||
return NULL;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
int32 code;
|
||||
void* buffer = malloc(size);
|
||||
if (buffer == NULL)
|
||||
return NULL;
|
||||
|
||||
result = read_port(fReplyPort, &code, buffer, size);
|
||||
if (result < B_OK) {
|
||||
free(buffer);
|
||||
|
||||
if (_Repair() != B_OK)
|
||||
return 0;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
if (code != MsgReply) {
|
||||
free(buffer);
|
||||
return NULL;
|
||||
} else
|
||||
return buffer;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
IdMap::_Repair()
|
||||
{
|
||||
status_t result = B_OK;
|
||||
|
||||
fRequestPort = create_port(1, kRequestPortName);
|
||||
if (fRequestPort < B_OK)
|
||||
return fRequestPort;
|
||||
|
||||
fReplyPort = create_port(1, kReplyPortName);
|
||||
if (fReplyPort < B_OK) {
|
||||
delete_port(fRequestPort);
|
||||
return fReplyPort;
|
||||
}
|
||||
|
||||
char path[256];
|
||||
if (find_directory(B_SYSTEM_SERVERS_DIRECTORY, static_cast<dev_t>(-1),
|
||||
false, path, sizeof(path)) != B_OK) {
|
||||
delete_port(fReplyPort);
|
||||
delete_port(fRequestPort);
|
||||
return B_NAME_NOT_FOUND;
|
||||
}
|
||||
strlcat(path, "/nfs4_idmapper_server", sizeof(path));
|
||||
|
||||
const char* args[] = { path, NULL };
|
||||
thread_id thread = load_image_etc(1, args, NULL, B_NORMAL_PRIORITY,
|
||||
B_SYSTEM_TEAM, 0);
|
||||
if (thread < B_OK) {
|
||||
delete_port(fReplyPort);
|
||||
delete_port(fRequestPort);
|
||||
return thread;
|
||||
}
|
||||
|
||||
set_port_owner(fRequestPort, thread);
|
||||
set_port_owner(fReplyPort, thread);
|
||||
|
||||
result = resume_thread(thread);
|
||||
if (result != B_OK) {
|
||||
kill_thread(thread);
|
||||
delete_port(fReplyPort);
|
||||
delete_port(fRequestPort);
|
||||
return result;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2012 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Paweł Dziepak, [email protected]
|
||||
*/
|
||||
#ifndef IDMAP_H
|
||||
#define IDMAP_H
|
||||
|
||||
|
||||
#include <lock.h>
|
||||
#include <port.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
class IdMap {
|
||||
public:
|
||||
IdMap();
|
||||
~IdMap();
|
||||
|
||||
uid_t GetUserId(const char* owner);
|
||||
gid_t GetGroupId(const char* ownerGroup);
|
||||
|
||||
char* GetOwner(uid_t user);
|
||||
char* GetOwnerGroup(gid_t group);
|
||||
|
||||
private:
|
||||
status_t _Repair();
|
||||
|
||||
template<typename T>
|
||||
void* _GetBuffer(T value, int32 code);
|
||||
|
||||
template<typename T>
|
||||
T _GetValue(const char* buffer, int32 code);
|
||||
|
||||
mutex fLock;
|
||||
|
||||
port_id fRequestPort;
|
||||
port_id fReplyPort;
|
||||
};
|
||||
|
||||
extern IdMap* gIdMapper;
|
||||
|
||||
|
||||
#endif // IDMAP_H
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <NodeMonitor.h>
|
||||
|
||||
#include "IdMap.h"
|
||||
#include "Request.h"
|
||||
#include "RootInode.h"
|
||||
|
||||
@@ -345,11 +346,24 @@ Inode::CreateLink(const char* name, const char* path, int mode)
|
||||
|
||||
req.PutFH(fInfo.fHandle);
|
||||
|
||||
AttrValue attr;
|
||||
attr.fAttribute = FATTR4_MODE;
|
||||
attr.fFreePointer = false;
|
||||
attr.fData.fValue32 = mode;
|
||||
req.Create(NF4LNK, name, &attr, 1, path);
|
||||
uint32 i = 0;
|
||||
AttrValue cattr[3];
|
||||
cattr[i].fAttribute = FATTR4_MODE;
|
||||
cattr[i].fFreePointer = false;
|
||||
cattr[i].fData.fValue32 = mode;
|
||||
i++;
|
||||
|
||||
cattr[i].fAttribute = FATTR4_OWNER;
|
||||
cattr[i].fFreePointer = true;
|
||||
cattr[i].fData.fPointer = gIdMapper->GetOwner(getuid());
|
||||
i++;
|
||||
|
||||
cattr[i].fAttribute = FATTR4_OWNER_GROUP;
|
||||
cattr[i].fFreePointer = true;
|
||||
cattr[i].fData.fPointer = gIdMapper->GetOwnerGroup(getgid());
|
||||
i++;
|
||||
|
||||
req.Create(NF4LNK, name, cattr, i, path);
|
||||
|
||||
status_t result = request.Send();
|
||||
if (result != B_OK)
|
||||
@@ -460,6 +474,7 @@ Inode::Stat(struct stat* st)
|
||||
req.PutFH(fInfo.fHandle);
|
||||
|
||||
Attribute attr[] = { FATTR4_SIZE, FATTR4_MODE, FATTR4_NUMLINKS,
|
||||
FATTR4_OWNER, FATTR4_OWNER_GROUP,
|
||||
FATTR4_TIME_ACCESS, FATTR4_TIME_CREATE,
|
||||
FATTR4_TIME_METADATA, FATTR4_TIME_MODIFY };
|
||||
req.GetAttr(attr, sizeof(attr) / sizeof(Attribute));
|
||||
@@ -526,6 +541,20 @@ Inode::Stat(struct stat* st)
|
||||
} else
|
||||
st->st_nlink = 1;
|
||||
|
||||
if (count >= next && values[next].fAttribute == FATTR4_OWNER) {
|
||||
char* owner = reinterpret_cast<char*>(values[next].fData.fPointer);
|
||||
st->st_uid = gIdMapper->GetUserId(owner);
|
||||
next++;
|
||||
} else
|
||||
st->st_uid = 0;
|
||||
|
||||
if (count >= next && values[next].fAttribute == FATTR4_OWNER_GROUP) {
|
||||
char* group = reinterpret_cast<char*>(values[next].fData.fPointer);
|
||||
st->st_gid = gIdMapper->GetGroupId(group);
|
||||
next++;
|
||||
} else
|
||||
st->st_gid = 0;
|
||||
|
||||
if (count >= next && values[next].fAttribute == FATTR4_TIME_ACCESS) {
|
||||
memcpy(&st->st_atim, values[next].fData.fPointer, sizeof(timespec));
|
||||
next++;
|
||||
@@ -551,9 +580,6 @@ Inode::Stat(struct stat* st)
|
||||
} else
|
||||
memset(&st->st_mtim, 0, sizeof(timespec));
|
||||
|
||||
st->st_uid = 0;
|
||||
st->st_gid = 0;
|
||||
|
||||
delete[] values;
|
||||
return B_OK;
|
||||
} while (true);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "IdMap.h"
|
||||
#include "Request.h"
|
||||
#include "RootInode.h"
|
||||
|
||||
@@ -26,11 +27,24 @@ Inode::CreateDir(const char* name, int mode)
|
||||
|
||||
req.PutFH(fInfo.fHandle);
|
||||
|
||||
AttrValue attr;
|
||||
attr.fAttribute = FATTR4_MODE;
|
||||
attr.fFreePointer = false;
|
||||
attr.fData.fValue32 = mode;
|
||||
req.Create(NF4DIR, name, &attr, 1);
|
||||
uint32 i = 0;
|
||||
AttrValue cattr[3];
|
||||
cattr[i].fAttribute = FATTR4_MODE;
|
||||
cattr[i].fFreePointer = false;
|
||||
cattr[i].fData.fValue32 = mode;
|
||||
i++;
|
||||
|
||||
cattr[i].fAttribute = FATTR4_OWNER;
|
||||
cattr[i].fFreePointer = true;
|
||||
cattr[i].fData.fPointer = gIdMapper->GetOwner(getuid());
|
||||
i++;
|
||||
|
||||
cattr[i].fAttribute = FATTR4_OWNER_GROUP;
|
||||
cattr[i].fFreePointer = true;
|
||||
cattr[i].fData.fPointer = gIdMapper->GetOwnerGroup(getgid());
|
||||
i++;
|
||||
|
||||
req.Create(NF4DIR, name, cattr, i);
|
||||
|
||||
status_t result = request.Send();
|
||||
if (result != B_OK)
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <NodeMonitor.h>
|
||||
|
||||
#include "IdMap.h"
|
||||
#include "Request.h"
|
||||
|
||||
|
||||
@@ -77,7 +78,7 @@ Inode::Create(const char* name, int mode, int perms, OpenFileCookie* cookie,
|
||||
|
||||
req.PutFH(fInfo.fHandle);
|
||||
|
||||
AttrValue cattr[2];
|
||||
AttrValue cattr[4];
|
||||
uint32 i = 0;
|
||||
if ((mode & O_TRUNC) == O_TRUNC) {
|
||||
cattr[i].fAttribute = FATTR4_SIZE;
|
||||
@@ -88,9 +89,21 @@ Inode::Create(const char* name, int mode, int perms, OpenFileCookie* cookie,
|
||||
cattr[i].fAttribute = FATTR4_MODE;
|
||||
cattr[i].fFreePointer = false;
|
||||
cattr[i].fData.fValue32 = perms;
|
||||
i++;
|
||||
|
||||
cattr[i].fAttribute = FATTR4_OWNER;
|
||||
cattr[i].fFreePointer = true;
|
||||
cattr[i].fData.fPointer = gIdMapper->GetOwner(getuid());
|
||||
i++;
|
||||
|
||||
cattr[i].fAttribute = FATTR4_OWNER_GROUP;
|
||||
cattr[i].fFreePointer = true;
|
||||
cattr[i].fData.fPointer = gIdMapper->GetOwnerGroup(getgid());
|
||||
i++;
|
||||
|
||||
req.Open(CLAIM_NULL, cookie->fSequence++, sModeToAccess(mode),
|
||||
cookie->fClientId, OPEN4_CREATE, cookie->fOwnerId, name, cattr,
|
||||
i + 1, (mode & O_EXCL) == O_EXCL);
|
||||
i, (mode & O_EXCL) == O_EXCL);
|
||||
|
||||
req.GetFH();
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ KernelAddon nfs4 :
|
||||
Connection.cpp
|
||||
FileInfo.cpp
|
||||
Filesystem.cpp
|
||||
IdMap.cpp
|
||||
Inode.cpp
|
||||
InodeDir.cpp
|
||||
InodeRegular.cpp
|
||||
@@ -23,3 +24,6 @@ KernelAddon nfs4 :
|
||||
RPCServer.cpp
|
||||
XDR.cpp
|
||||
;
|
||||
|
||||
SubInclude HAIKU_TOP src add-ons kernel file_systems nfs4 idmapper ;
|
||||
|
||||
|
||||
@@ -614,6 +614,20 @@ ReplyInterpreter::_DecodeAttrs(XDR::ReadStream& str, AttrValue** attrs,
|
||||
current++;
|
||||
}
|
||||
|
||||
if (sIsAttrSet(FATTR4_OWNER, bitmap, bcount)) {
|
||||
values[current].fAttribute = FATTR4_OWNER;
|
||||
values[current].fFreePointer = true;
|
||||
values[current].fData.fPointer = stream.GetString();
|
||||
current++;
|
||||
}
|
||||
|
||||
if (sIsAttrSet(FATTR4_OWNER_GROUP, bitmap, bcount)) {
|
||||
values[current].fAttribute = FATTR4_OWNER_GROUP;
|
||||
values[current].fFreePointer = true;
|
||||
values[current].fData.fPointer = stream.GetString();
|
||||
current++;
|
||||
}
|
||||
|
||||
if (sIsAttrSet(FATTR4_SPACE_FREE, bitmap, bcount)) {
|
||||
values[current].fAttribute = FATTR4_SPACE_FREE;
|
||||
values[current].fData.fValue64 = stream.GetUHyper();
|
||||
|
||||
@@ -776,6 +776,16 @@ RequestBuilder::_EncodeAttrs(XDR::WriteStream& stream, AttrValue* attr,
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i < count && attr[i].fAttribute == FATTR4_OWNER) {
|
||||
str.AddString(reinterpret_cast<char*>(attr[i].fData.fPointer));
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i < count && attr[i].fAttribute == FATTR4_OWNER_GROUP) {
|
||||
str.AddString(reinterpret_cast<char*>(attr[i].fData.fPointer));
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i < count && attr[i].fAttribute == FATTR4_TIME_ACCESS_SET) {
|
||||
str.AddInt(1); // SET_TO_CLIENT_TIME4
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ ReadStream::GetUHyper()
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
char*
|
||||
ReadStream::GetString()
|
||||
{
|
||||
if (_PositionToSize() >= fSize) {
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
|
||||
inline bool GetBoolean();
|
||||
|
||||
const char* GetString();
|
||||
char* GetString();
|
||||
|
||||
const void* GetOpaque(uint32* size);
|
||||
|
||||
|
||||
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
* Copyright 2012 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Paweł Dziepak, pdziepak@quarnos.org
|
||||
*/
|
||||
|
||||
|
||||
#include "IdMapper.h"
|
||||
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <File.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <OS.h>
|
||||
#include <Path.h>
|
||||
|
||||
|
||||
port_id gRequestPort;
|
||||
port_id gReplyPort;
|
||||
|
||||
const char* kNobodyName = "nobody";
|
||||
uid_t gNobodyId;
|
||||
|
||||
const char* kNogroupName = "nobody";
|
||||
uid_t gNogroupId;
|
||||
|
||||
const char* gDomainName = "localdomain";
|
||||
|
||||
|
||||
status_t
|
||||
SendError(status_t error)
|
||||
{
|
||||
return write_port(gReplyPort, MsgError, &error, sizeof(error));
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MatchDomain(char* name)
|
||||
{
|
||||
char* domain = strchr(name, '@');
|
||||
if (domain == NULL)
|
||||
return B_MISMATCHED_VALUES;
|
||||
|
||||
if (strcmp(domain + 1, gDomainName) != 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
*domain = '\0';
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
char*
|
||||
AddDomain(const char* name)
|
||||
{
|
||||
uint32 fullLength = strlen(name) + strlen(gDomainName) + 2;
|
||||
char* fullName = reinterpret_cast<char*>(malloc(fullLength));
|
||||
|
||||
strcpy(fullName, name);
|
||||
strcat(fullName, "@");
|
||||
strcat(fullName, gDomainName);
|
||||
|
||||
return fullName;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
NameToUID(void* buffer)
|
||||
{
|
||||
char* userName = reinterpret_cast<char*>(buffer);
|
||||
|
||||
struct passwd* userInfo = NULL;
|
||||
|
||||
if (MatchDomain(userName) == B_OK)
|
||||
userInfo = getpwnam(userName);
|
||||
|
||||
if (userInfo == NULL)
|
||||
return write_port(gReplyPort, MsgReply, &gNobodyId, sizeof(gNobodyId));
|
||||
|
||||
return write_port(gReplyPort, MsgReply, &userInfo->pw_uid, sizeof(uid_t));
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
UIDToName(void* buffer)
|
||||
{
|
||||
uid_t userId = *reinterpret_cast<uid_t*>(buffer);
|
||||
|
||||
const char* fullName = kNobodyName;
|
||||
|
||||
struct passwd* userInfo = getpwuid(userId);
|
||||
if (userInfo != NULL) {
|
||||
const char* name = userInfo->pw_name;
|
||||
fullName = AddDomain(name);
|
||||
}
|
||||
|
||||
status_t result = write_port(gReplyPort, MsgReply, fullName,
|
||||
strlen(fullName) + 1);
|
||||
free(const_cast<char*>(fullName));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
NameToGID(void* buffer)
|
||||
{
|
||||
char* groupName = reinterpret_cast<char*>(buffer);
|
||||
|
||||
struct group* groupInfo = NULL;
|
||||
|
||||
if (MatchDomain(groupName) == B_OK)
|
||||
groupInfo = getgrnam(groupName);
|
||||
|
||||
if (groupInfo == NULL) {
|
||||
return write_port(gReplyPort, MsgReply, &gNogroupId,
|
||||
sizeof(gNogroupId));
|
||||
}
|
||||
|
||||
return write_port(gReplyPort, MsgReply, &groupInfo->gr_gid, sizeof(gid_t));
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
GIDToName(void* buffer)
|
||||
{
|
||||
gid_t groupId = *reinterpret_cast<gid_t*>(buffer);
|
||||
|
||||
const char* fullName = kNogroupName;
|
||||
|
||||
struct group* groupInfo = getgrgid(groupId);
|
||||
if (groupInfo != NULL) {
|
||||
const char* name = groupInfo->gr_name;
|
||||
fullName = AddDomain(name);
|
||||
}
|
||||
|
||||
status_t result = write_port(gReplyPort, MsgReply, fullName,
|
||||
strlen(fullName) + 1);
|
||||
free(const_cast<char*>(fullName));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ParseRequest(int32 code, void* buffer)
|
||||
{
|
||||
switch (code) {
|
||||
case MsgNameToUID:
|
||||
return NameToUID(buffer);
|
||||
|
||||
case MsgUIDToName:
|
||||
return UIDToName(buffer);
|
||||
|
||||
case MsgNameToGID:
|
||||
return NameToGID(buffer);
|
||||
|
||||
case MsgGIDToName:
|
||||
return GIDToName(buffer);
|
||||
|
||||
default:
|
||||
return SendError(B_BAD_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MainLoop()
|
||||
{
|
||||
do {
|
||||
ssize_t size = port_buffer_size(gRequestPort);
|
||||
if (size < B_OK)
|
||||
return 0;
|
||||
|
||||
void* buffer = malloc(size);
|
||||
if (buffer == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
int32 code;
|
||||
status_t result = read_port(gRequestPort, &code, buffer, size);
|
||||
if (size < B_OK) {
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
result = ParseRequest(code, buffer);
|
||||
free(buffer);
|
||||
|
||||
if (result == B_BAD_PORT_ID)
|
||||
return 0;
|
||||
|
||||
} while (true);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ReadSettings()
|
||||
{
|
||||
BPath path;
|
||||
status_t result = find_directory(B_COMMON_SETTINGS_DIRECTORY, &path);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
result = path.Append("nfs4_idmapper.conf");
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
BFile file(path.Path(), B_READ_ONLY);
|
||||
if (file.InitCheck() != B_OK)
|
||||
return file.InitCheck();
|
||||
|
||||
off_t size;
|
||||
result = file.GetSize(&size);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
void* buffer = malloc(size);
|
||||
if (buffer == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
file.Read(buffer, size);
|
||||
|
||||
gDomainName = reinterpret_cast<char*>(buffer);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
gRequestPort = find_port(kRequestPortName);
|
||||
if (gRequestPort == B_NAME_NOT_FOUND) {
|
||||
fprintf(stderr, "%s\n", strerror(gRequestPort));
|
||||
return gRequestPort;
|
||||
}
|
||||
|
||||
gReplyPort = find_port(kReplyPortName);
|
||||
if (gReplyPort == B_NAME_NOT_FOUND) {
|
||||
fprintf(stderr, "%s\n", strerror(gReplyPort));
|
||||
return gReplyPort;
|
||||
}
|
||||
|
||||
ReadSettings();
|
||||
|
||||
struct passwd* userInfo = getpwnam(kNobodyName);
|
||||
if (userInfo != NULL)
|
||||
gNobodyId = userInfo->pw_uid;
|
||||
else
|
||||
gNobodyId = 0;
|
||||
|
||||
struct group* groupInfo = getgrnam(kNogroupName);
|
||||
if (groupInfo != NULL)
|
||||
gNogroupId = groupInfo->gr_gid;
|
||||
else
|
||||
gNogroupId = 0;
|
||||
|
||||
return MainLoop();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2012 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Paweł Dziepak, pdziepak@quarnos.org
|
||||
*/
|
||||
#ifndef IDMAPPER_H
|
||||
#define IDMAPPER_H
|
||||
|
||||
|
||||
enum MsgCode {
|
||||
MsgError,
|
||||
MsgReply,
|
||||
MsgNameToUID,
|
||||
MsgUIDToName,
|
||||
MsgNameToGID,
|
||||
MsgGIDToName
|
||||
};
|
||||
|
||||
static const char* kRequestPortName = "nfs4idmap_request";
|
||||
static const char* kReplyPortName = "nfs4idmap_reply";
|
||||
|
||||
|
||||
#endif // IDMAPPER_H
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel file_systems nfs4 idmapper ;
|
||||
|
||||
Application nfs4_idmapper_server
|
||||
:
|
||||
IdMapper.cpp
|
||||
|
||||
:
|
||||
be
|
||||
$(TARGET_LIBSUPC++)
|
||||
|
||||
:
|
||||
nfs4_idmapper_server.rdef
|
||||
;
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* nfs4_idmapper_server.rdef
|
||||
*/
|
||||
|
||||
resource app_signature "application/x-vnd.Haiku-nfs4_idmapper-server";
|
||||
|
||||
resource app_flags B_EXCLUSIVE_LAUNCH | B_BACKGROUND_APP;
|
||||
|
||||
resource app_version {
|
||||
major = 1,
|
||||
middle = 0,
|
||||
minor = 0,
|
||||
|
||||
variety = B_APPV_ALPHA,
|
||||
internal = 0,
|
||||
|
||||
short_info = "nfs4_idmapper_server",
|
||||
long_info = "nfs4_idmapper_server ©2012 Haiku, Inc"
|
||||
};
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "Connection.h"
|
||||
#include "Filesystem.h"
|
||||
#include "IdMap.h"
|
||||
#include "Inode.h"
|
||||
#include "NFS4Defs.h"
|
||||
#include "RequestBuilder.h"
|
||||
@@ -546,6 +547,13 @@ nfs4_init()
|
||||
gRPCServerManager = new(std::nothrow) RPC::ServerManager;
|
||||
if (gRPCServerManager == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
gIdMapper = new(std::nothrow) IdMap;
|
||||
if (gIdMapper == NULL) {
|
||||
delete gRPCServerManager;
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -555,6 +563,7 @@ nfs4_uninit()
|
||||
{
|
||||
dprintf("NFS4 Uninit\n");
|
||||
|
||||
delete gIdMapper;
|
||||
delete gRPCServerManager;
|
||||
|
||||
return B_OK;
|
||||
|
||||
Reference in New Issue
Block a user