Example #1
0
// destructor
SecurityContext::~SecurityContext()
{
	// remove all user references
	for (UserMap::Iterator it = fUsers->GetIterator(); it.HasNext();) {
		User* user = it.Next().value;
		user->RemoveReference();
	}

	// remove all share references
	for (ShareMap::Iterator it = fShares->GetIterator(); it.HasNext();) {
		Share* share = it.Next().value;
		share->RemoveReference();
	}

	delete fUsers;
	delete fShares;
	delete fPermissions;
	delete fNode2Path;
	delete fPath2Node;
}
Example #2
0
// MessageReceived
void
NetFSServer::MessageReceived(BMessage* message)
{
	switch (message->what) {
		case NETFS_REQUEST_GET_MESSENGER:
		{
			// for the time being we process all requests here
			BMessage reply;
			reply.AddMessenger("messenger", be_app_messenger);
			_SendReply(message, &reply);
			break;
		}

		case NETFS_REQUEST_ADD_USER:
		{
			// get user name and password
			const char* user;
			const char* password;
			if (message->FindString("user", &user) != B_OK) {
				_SendReply(message, B_BAD_VALUE);
				break;
			}
			if (message->FindString("password", &password) != B_OK)
				password = NULL;

			// add the user
			status_t error = fSecurityContext->AddUser(user, password);
			_SendReply(message, error);
			break;
		}

		case NETFS_REQUEST_REMOVE_USER:
		{
			// get user name
			const char* userName;
			if (message->FindString("user", &userName) != B_OK) {
				_SendReply(message, B_BAD_VALUE);
				break;
			}

			// remove the user
			User* user;
			status_t error = fSecurityContext->RemoveUser(userName, &user);
			if (error == B_OK) {
				// propagate the information to the client connections
				AutoLocker<Locker> _(fLock);
				for (int32 i = 0;
					 ClientConnection* connection
					 	= (ClientConnection*)fClientConnections.ItemAt(i);
					 i++) {
					connection->UserRemoved(user);
				}

				user->RemoveReference();
			}

			_SendReply(message, error);
			break;
		}

		case NETFS_REQUEST_GET_USERS:
		{
			// get the users
			BMessage reply;
			BMessage users;
			status_t error = fSecurityContext->GetUsers(&users);
			if (error == B_OK)
				error = reply.AddMessage("users", &users);

			if (error == B_OK)
				_SendReply(message, &reply);
			else
				_SendReply(message, error);
			break;
		}

		case NETFS_REQUEST_GET_USER_STATISTICS:
		{
			// get user name
			const char* userName;
			if (message->FindString("user", &userName) != B_OK) {
				_SendReply(message, B_BAD_VALUE);
				break;
			}

			// get the user
			User* user = fSecurityContext->FindUser(userName);
			if (!user) {
				_SendReply(message, B_ENTRY_NOT_FOUND);
				break;
			}
			Reference<User> userReference(user, true);

			// get the statistics
			BMessage statistics;
			status_t error = StatisticsManager::GetDefault()
				->GetUserStatistics(user, &statistics);

			// prepare the reply
			BMessage reply;
			if (error == B_OK)
				error = reply.AddMessage("statistics", &statistics);

			// send the reply
			if (error == B_OK)
				_SendReply(message, &reply);
			else
				_SendReply(message, error);
			break;
		}

		case NETFS_REQUEST_ADD_SHARE:
		{
			// get share name and path
			const char* share;
			const char* path;
			if (message->FindString("share", &share) != B_OK
				|| message->FindString("path", &path) != B_OK) {
				_SendReply(message, B_BAD_VALUE);
				break;
			}

			// add the share
			status_t error = fSecurityContext->AddShare(share, path);

			if (error == B_OK)
				_ServerInfoUpdated();

			_SendReply(message, error);
			break;
		}

		case NETFS_REQUEST_REMOVE_SHARE:
		{
			// get share name
			const char* shareName;
			if (message->FindString("share", &shareName) != B_OK) {
				_SendReply(message, B_BAD_VALUE);
				break;
			}

			// remove the share
			Share* share;
			status_t error = fSecurityContext->RemoveShare(shareName, &share);
			if (error == B_OK) {
				// propagate the information to the client connections
				AutoLocker<Locker> _(fLock);
				for (int32 i = 0;
					 ClientConnection* connection
					 	= (ClientConnection*)fClientConnections.ItemAt(i);
					 i++) {
					connection->ShareRemoved(share);
				}

				share->RemoveReference();
			}

			if (error == B_OK)
				_ServerInfoUpdated();

			_SendReply(message, error);
			break;
		}

		case NETFS_REQUEST_GET_SHARES:
		{
			// get the shares
			BMessage reply;
			BMessage shares;
			status_t error = fSecurityContext->GetShares(&shares);
			if (error == B_OK)
				error = reply.AddMessage("shares", &shares);

			if (error == B_OK)
				_SendReply(message, &reply);
			else
				_SendReply(message, error);
			break;
		}

		case NETFS_REQUEST_GET_SHARE_USERS:
		{
			// get share name
			const char* shareName;
			if (message->FindString("share", &shareName) != B_OK) {
				_SendReply(message, B_BAD_VALUE);
				break;
			}

			AutoLocker<Locker> securityContextLocker(fSecurityContext);

			// get the share
			Share* share = fSecurityContext->FindShare(shareName);
			if (!share) {
				_SendReply(message, B_ENTRY_NOT_FOUND);
				break;
			}
			Reference<Share> shareReference(share, true);

			// get all users
			BMessage allUsers;
			status_t error = fSecurityContext->GetUsers(&allUsers);
			if (error != B_OK) {
				_SendReply(message, error);
				break;
			}

			// filter the users with mount permission
			BMessage users;
			const char* userName;
			for (int32 i = 0;
				 allUsers.FindString("users", i, &userName) == B_OK;
				 i++) {
				if (User* user = fSecurityContext->FindUser(userName)) {
					// get the user's permissions
					Permissions permissions = fSecurityContext
						->GetNodePermissions(share->GetPath(), user);
					user->RemoveReference();

					// add the user, if they have the permission to mount the
					// share
					if (permissions.ImpliesMountSharePermission()) {
						error = users.AddString("users", userName);
						if (error != B_OK) {
							_SendReply(message, error);
							break;
						}
					}
				}
			}

			securityContextLocker.Unlock();

			// prepare the reply
			BMessage reply;
			if (error == B_OK)
				error = reply.AddMessage("users", &users);

			// send the reply
			if (error == B_OK)
				_SendReply(message, &reply);
			else
				_SendReply(message, error);
			break;
		}

		case NETFS_REQUEST_GET_SHARE_STATISTICS:
		{
			// get share name
			const char* shareName;
			if (message->FindString("share", &shareName) != B_OK) {
				_SendReply(message, B_BAD_VALUE);
				break;
			}

			// get the share
			Share* share = fSecurityContext->FindShare(shareName);
			if (!share) {
				_SendReply(message, B_ENTRY_NOT_FOUND);
				break;
			}
			Reference<Share> shareReference(share, true);

			// get the statistics
			BMessage statistics;
			status_t error = StatisticsManager::GetDefault()
				->GetShareStatistics(share, &statistics);

			// prepare the reply
			BMessage reply;
			if (error == B_OK)
				error = reply.AddMessage("statistics", &statistics);

			// send the reply
			if (error == B_OK)
				_SendReply(message, &reply);
			else
				_SendReply(message, error);
			break;
		}

		case NETFS_REQUEST_SET_USER_PERMISSIONS:
		{
			// get share and user name, and the permissions
			const char* shareName;
			const char* userName;
			uint32 permissions;
			if (message->FindString("share", &shareName) != B_OK
				|| message->FindString("user", &userName) != B_OK
				|| message->FindInt32("permissions", (int32*)&permissions)
					!= B_OK) {
				_SendReply(message, B_BAD_VALUE);
				break;
			}

			// get the share and the user
			Share* share = fSecurityContext->FindShare(shareName);
			User* user = fSecurityContext->FindUser(userName);
			Reference<Share> shareReference(share);
			Reference<User> userReference(user);
			if (!share || !user) {
				_SendReply(message, B_ENTRY_NOT_FOUND);
				break;
			}

			// set the permissions
			status_t error = B_OK;
			if (permissions == 0) {
				fSecurityContext->ClearNodePermissions(share->GetPath(), user);
			} else {
				error = fSecurityContext->SetNodePermissions(share->GetPath(),
					user, permissions);
			}

			if (error == B_OK) {
				// propagate the information to the client connections
				AutoLocker<Locker> _(fLock);
				for (int32 i = 0;
					 ClientConnection* connection
					 	= (ClientConnection*)fClientConnections.ItemAt(i);
					 i++) {
					connection->UserPermissionsChanged(share, user,
						permissions);
				}
			}

			_SendReply(message, error);
			break;
		}

		case NETFS_REQUEST_GET_USER_PERMISSIONS:
		{
			// get share and user name
			const char* shareName;
			const char* userName;
			if (message->FindString("share", &shareName) != B_OK
				|| message->FindString("user", &userName) != B_OK) {
				_SendReply(message, B_BAD_VALUE);
				break;
			}

			// get the share and the user
			Share* share = fSecurityContext->FindShare(shareName);
			User* user = fSecurityContext->FindUser(userName);
			Reference<Share> shareReference(share);
			Reference<User> userReference(user);
			if (!share || !user) {
				_SendReply(message, B_ENTRY_NOT_FOUND);
				break;
			}

			// get the permissions
			Permissions permissions = fSecurityContext->GetNodePermissions(
				share->GetPath(), user);

			// prepare the reply
			BMessage reply;
			status_t error = reply.AddInt32("permissions",
				(int32)permissions.GetPermissions());

			// send it
			if (error == B_OK)
				_SendReply(message, &reply);
			else
				_SendReply(message, error);
			break;
		}

		case NETFS_REQUEST_SAVE_SETTINGS:
		{
			status_t error = _SaveSettings();

			// send a reply
			_SendReply(message, error);
			break;
		}
	}
}