diff --git a/src/add-ons/kernel/file_systems/nfs4/Jamfile b/src/add-ons/kernel/file_systems/nfs4/Jamfile index bf19a10fc1..f9d1a67401 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Jamfile +++ b/src/add-ons/kernel/file_systems/nfs4/Jamfile @@ -5,5 +5,7 @@ UsePrivateHeaders kernel ; KernelAddon nfs4 : Connection.cpp kernel_interface.cpp + RPCAuth.cpp + RPCCall.cpp XDR.cpp ; diff --git a/src/add-ons/kernel/file_systems/nfs4/RPCAuth.cpp b/src/add-ons/kernel/file_systems/nfs4/RPCAuth.cpp new file mode 100644 index 0000000000..f7f2a1f4c9 --- /dev/null +++ b/src/add-ons/kernel/file_systems/nfs4/RPCAuth.cpp @@ -0,0 +1,89 @@ +/* + * Copyright 2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Paweł Dziepak, pdziepak@quarnos.org + */ + + +#include "RPCAuth.h" + +#include +#include +#include + +#include +#include + + +using namespace RPC; + + +Auth::Auth() +{ +} + + +const Auth* +Auth::CreateNone() +{ + Auth* auth = new(std::nothrow) Auth; + if (auth == NULL) + return NULL; + + auth->fStream.AddInt(AUTH_NONE); + auth->fStream.AddOpaque(NULL, 0); + if (auth->fStream.GetError() != B_OK) { + delete auth; + return NULL; + } + + return auth; +} + + +const Auth* +Auth::CreateSys() +{ + Auth* auth = new(std::nothrow) Auth; + if (auth == NULL) + return NULL; + + XDR::WriteStream xdr; + xdr.AddUInt(time(NULL)); + + char hostname[255]; + //if (gethostname(hostname, 255) < 0) + strcpy(hostname, "unknown"); + xdr.AddString(hostname, 255); + + xdr.AddUInt(getuid()); + xdr.AddUInt(getgid()); + + int count = getgroups(0, NULL); + gid_t* groups = (gid_t*)malloc(count * sizeof(gid_t)); + int len = getgroups(count, groups); + if (len > 0) { + len = min_c(len, 16); + xdr.AddUInt(len); + for (int i = 0; i < len; i++) + xdr.AddUInt((uint32)groups[i]); + } else + xdr.AddUInt(0); + free(groups); + if (xdr.GetError() != B_OK) { + delete auth; + return NULL; + } + + auth->fStream.AddInt(AUTH_SYS); + auth->fStream.AddOpaque(xdr); + if (auth->fStream.GetError() != B_OK) { + delete auth; + return NULL; + } + + return auth; +} + diff --git a/src/add-ons/kernel/file_systems/nfs4/RPCAuth.h b/src/add-ons/kernel/file_systems/nfs4/RPCAuth.h new file mode 100644 index 0000000000..1e79e3dba1 --- /dev/null +++ b/src/add-ons/kernel/file_systems/nfs4/RPCAuth.h @@ -0,0 +1,46 @@ +/* + * Copyright 2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Paweł Dziepak, pdziepak@quarnos.org + */ +#ifndef RPCAUTH_H +#define RPCAUTH_H + + +#include "XDR.h" + + +namespace RPC { + +enum auth_flavour { + AUTH_NONE = 0, + AUTH_SYS = 1 +}; + +class Auth { +public: + inline const XDR::WriteStream& GetStream() const; + + static const Auth* CreateNone(); + static const Auth* CreateSys(); + +private: + Auth(); + + XDR::WriteStream fStream; +}; + + +inline const XDR::WriteStream& +Auth::GetStream() const +{ + return fStream; +} + +} // namespace RPC + + +#endif // RPCAUTH_H + diff --git a/src/add-ons/kernel/file_systems/nfs4/RPCCall.cpp b/src/add-ons/kernel/file_systems/nfs4/RPCCall.cpp new file mode 100644 index 0000000000..9800823659 --- /dev/null +++ b/src/add-ons/kernel/file_systems/nfs4/RPCCall.cpp @@ -0,0 +1,77 @@ +/* + * Copyright 2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Paweł Dziepak, pdziepak@quarnos.org + */ + + +#include "RPCCall.h" + +#include + + +using namespace RPC; + +enum { + CALL = 0 +}; + +#define VERSION 2 + +enum { + PROGRAM_NFS = 100003 +}; + +#define NFS_VERSION 4 + + +Call::Call() +{ +} + + +Call* +Call::Create(uint32 proc, const Auth* creds, const Auth* ver) +{ + Call* call = new(std::nothrow) Call; + if (call == NULL) + return NULL; + + // XID will be determined and set by RPC::Server + call->fXIDPosition = call->fStream.GetCurrent(); + call->fStream.AddUInt(0); + + call->fStream.AddInt(CALL); + call->fStream.AddUInt(VERSION); + call->fStream.AddUInt(PROGRAM_NFS); + call->fStream.AddUInt(NFS_VERSION); + call->fStream.AddUInt(proc); + + call->fStream.Append(creds->GetStream()); + delete creds; + + call->fStream.Append(ver->GetStream()); + delete ver; + + if (call->fStream.GetError() != B_OK) { + delete call; + return NULL; + } + + return call; +} + + +Call::~Call() +{ +} + + +void +Call::SetXID(uint32 xid) +{ + fStream.InsertUInt(fXIDPosition, xid); +} + diff --git a/src/add-ons/kernel/file_systems/nfs4/RPCCall.h b/src/add-ons/kernel/file_systems/nfs4/RPCCall.h new file mode 100644 index 0000000000..b5d92cebb3 --- /dev/null +++ b/src/add-ons/kernel/file_systems/nfs4/RPCCall.h @@ -0,0 +1,46 @@ +/* + * Copyright 2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Paweł Dziepak, pdziepak@quarnos.org + */ +#ifndef RPCCALL_H +#define RPCCALL_H + + +#include "RPCAuth.h" +#include "XDR.h" + + +namespace RPC { + +class Call { +public: + static Call* Create(uint32 proc, const Auth* creds, + const Auth* ver); + ~Call(); + + void SetXID(uint32 x); + + inline XDR::WriteStream& GetStream(); + +private: + Call(); + + XDR::Stream::Position fXIDPosition; + + XDR::WriteStream fStream; +}; + + +inline XDR::WriteStream& +Call::GetStream() +{ + return fStream; +} + +} // namespace RPC + + +#endif // RPCCALL_H