Пример #1
0
// AddShare
//
// The caller gets a reference, if _share is not NULL.
status_t
SecurityContext::AddShare(const char* name, const char* path, Share** _share)
{
	if (!name)
		return B_BAD_VALUE;

	// check, if the share does already exist
	ContextLocker _(this);
	if (fShares->Get(name))
		return B_BAD_VALUE;

	// create a the share
	Share* share = new(std::nothrow) Share;
	if (!share)
		return B_NO_MEMORY;
	Reference<Share> shareReference(share, true);
	status_t error = share->Init(name, path);
	if (error != B_OK)
		return error;

	// add the share
	error = fShares->Put(name, share);
	if (error != B_OK)
		return error;

	shareReference.Detach();
	if (_share) {
		*_share = share;
		share->AddReference();
	}
	return B_OK;
}
Пример #2
0
// RemoveShare
//
// The caller gets a reference, if _share is not NULL.
status_t
SecurityContext::RemoveShare(const char* name, Share** _share)
{
	if (!name)
		return B_BAD_VALUE;

	ContextLocker _(this);

	// get the share
	Share* share = FindShare(name);
	if (!share)
		return B_ENTRY_NOT_FOUND;
	Reference<Share> shareReference(share, true);

	// remove it
	status_t error = RemoveShare(share);
	if (error == B_OK && _share) {
		*_share = share;
		share->AddReference();
	}

	return error;
}
Пример #3
0
// _LoadSecurityContext
status_t
NetFSServer::_LoadSecurityContext(SecurityContext** _securityContext)
{
	// create a security context
	SecurityContext* securityContext = new(std::nothrow) SecurityContext;
	if (!securityContext)
		return B_NO_MEMORY;
	status_t error = securityContext->InitCheck();
	if (error != B_OK) {
		delete securityContext;
		return error;
	}
	ObjectDeleter<SecurityContext> securityContextDeleter(securityContext);

	// load from driver settings for the time being
	DriverSettings settings;
	error = settings.Load("netfs-server");
	if (error != B_OK)
		return error;

	// load users
	DriverParameter parameter;
	for (DriverParameterIterator it = settings.GetParameterIterator("user");
		 it.GetNext(&parameter);) {
		const char* userName = parameter.ValueAt(0);
		const char* password = parameter.GetParameterValue("password");
		if (!userName) {
			WARN("Skipping nameless user settings entry.\n");
			continue;
		}
//		PRINT(("user: %s, password: %s\n", parameter.ValueAt(0),
//			parameter.GetParameterValue("password")));
		error = securityContext->AddUser(userName, password);
		if (error != B_OK)
			ERROR("ERROR: Failed to add user `%s'\n", userName);
	}

	// load shares
	for (DriverParameterIterator it = settings.GetParameterIterator("share");
		 it.GetNext(&parameter);) {
		const char* shareName = parameter.ValueAt(0);
		const char* path = parameter.GetParameterValue("path");
		if (!shareName || !path) {
			WARN("settings: Skipping invalid share settings entry (no name"
				" or no path).\n");
			continue;
		}
//		PRINT(("share: %s, path: %s\n", parameter.ValueAt(0),
//			parameter.GetParameterValue("path")));
		Share* share;
		error = securityContext->AddShare(shareName, path, &share);
		if (error != B_OK) {
			ERROR("ERROR: Failed to add share `%s'\n", shareName);
			continue;
		}
		Reference<Share> shareReference(share, true);
		DriverParameter userParameter;
		// iterate through the share users
		for (DriverParameterIterator userIt
				= parameter.GetParameterIterator("user");
			 userIt.GetNext(&userParameter);) {
			const char* userName = userParameter.ValueAt(0);
//			PRINT(("  user: %s\n", userName));
			User* user = securityContext->FindUser(userName);
			if (!user) {
				ERROR("ERROR: Undefined user `%s'.\n", userName);
				continue;
			}
			Reference<User> userReference(user, true);
			DriverParameter permissionsParameter;
			if (!userParameter.FindParameter("permissions",
					&permissionsParameter)) {
				continue;
			}
			Permissions permissions;
			for (int32 i = 0; i < permissionsParameter.CountValues(); i++) {
				const char* permission = permissionsParameter.ValueAt(i);
//				PRINT(("    permission: %s\n", permission));
				if (strcmp(permission, "mount") == 0) {
					permissions.AddPermissions(MOUNT_SHARE_PERMISSION);
				} else if (strcmp(permission, "query") == 0) {
					permissions.AddPermissions(QUERY_SHARE_PERMISSION);
				} else if (strcmp(permission, "read") == 0) {
					permissions.AddPermissions(READ_PERMISSION
						| READ_DIR_PERMISSION | RESOLVE_DIR_ENTRY_PERMISSION);
				} else if (strcmp(permission, "write") == 0) {
					permissions.AddPermissions(WRITE_PERMISSION
						| WRITE_DIR_PERMISSION);
				} else if (strcmp(permission, "all") == 0) {
					permissions.AddPermissions(ALL_PERMISSIONS);
				}
			}
			error = securityContext->SetNodePermissions(share->GetPath(), user,
				permissions);
			if (error != B_OK) {
				ERROR("ERROR: Failed to set permissions for share `%s'\n",
					share->GetName());
			}
		}
	}

	securityContextDeleter.Detach();
	*_securityContext = securityContext;
	return B_OK;
}
Пример #4
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;
		}
	}
}