Example #1
0
// AuthenticateUser
//
// The caller gets a reference.
status_t
SecurityContext::AuthenticateUser(const char* name, const char* password,
	User** _user)
{
	if (!_user)
		return B_BAD_VALUE;

	// find user
	ContextLocker _(this);
	User* user = FindUser(name);
	if (!user)
		return B_PERMISSION_DENIED;
	Reference<User> userReference(user, true);

	// check password
	if (user->GetPassword()) {
		if (!password || strcmp(user->GetPassword(), password) != 0)
			return B_PERMISSION_DENIED;
	} else if (password)
		return B_PERMISSION_DENIED;

	*_user = user;
	userReference.Detach();
	return B_OK;
}
Example #2
0
// AddUser
//
// The caller gets a reference, if _user is not NULL.
status_t
SecurityContext::AddUser(const char* name, const char* password, User** _user)
{
	if (!name)
		return B_BAD_VALUE;

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

	// create a the user
	User* user = new(std::nothrow) User;
	if (!user)
		return B_NO_MEMORY;
	Reference<User> userReference(user, true);
	status_t error = user->Init(name, password);
	if (error != B_OK)
		return error;

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

	userReference.Detach();
	if (_user) {
		*_user = user;
		user->AddReference();
	}
	return B_OK;
}
Example #3
0
// RemoveUser
//
// The caller gets a reference, if _user is not NULL.
status_t
SecurityContext::RemoveUser(const char* name, User** _user)
{
	if (!name)
		return B_BAD_VALUE;

	ContextLocker _(this);

	// get the user
	User* user = FindUser(name);
	if (!user)
		return B_ENTRY_NOT_FOUND;
	Reference<User> userReference(user, true);

	// remove it
	status_t error = RemoveUser(user);
	if (error == B_OK && _user) {
		*_user = user;
		user->AddReference();
	}

	return error;
}
Example #4
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;
}
Example #5
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;
		}
	}
}
Example #6
0
// constructor
SecurityContext::SecurityContext(BMessage* archive)
	: BArchivable(archive),
	  fUsers(new(std::nothrow) UserMap),
	  fShares(new(std::nothrow) ShareMap),
	  fPermissions(new(std::nothrow) PermissionMap),
	  fNode2Path(new(std::nothrow) NodePathMap),
	  fPath2Node(new(std::nothrow) PathNodeMap)
{
	if (InitCheck() != B_OK)
		return;
	status_t error = B_OK;

	// users
	BMessage userArchive;
	for (int32 i = 0;
		 archive->FindMessage("users", i, &userArchive) == B_OK;
		 i++) {
		User tmpUser;
		error = tmpUser.Unarchive(&userArchive);
		if (error != B_OK)
			return;
		error = AddUser(tmpUser.GetName(), tmpUser.GetPassword());
		if (error != B_OK)
			return;
	}

	// shares
	BMessage shareArchive;
	for (int32 i = 0;
		 archive->FindMessage("shares", i, &shareArchive) == B_OK;
		 i++) {
		Share tmpShare;
		error = tmpShare.Unarchive(&shareArchive);
		if (error != B_OK)
			return;
		error = AddShare(tmpShare.GetName(), tmpShare.GetPath());
		if (error != B_OK)
			return;
	}

	// permissions
	BMessage permissionsArchive;
	if (archive->FindMessage("permissions", &permissionsArchive) != B_OK)
		return;
	#ifdef ANTARES_TARGET_PLATFORM_DANO
		const char* userName;
	#else
		char* userName;
	#endif
	type_code type;
	for (int32 userIndex = 0;
		 permissionsArchive.GetInfo(B_MESSAGE_TYPE, userIndex, &userName, &type)
		 	== B_OK;
		 userIndex++) {
		User* user = FindUser(userName);
		if (!user)
			return;
		Reference<User> userReference(user, true);
		error = permissionsArchive.FindMessage(userName, &userArchive);
		if (error != B_OK)
			return;

		// got a user: iterate through its permissions
		#ifdef ANTARES_TARGET_PLATFORM_DANO
			const char* path;
		#else
			char* path;
		#endif
		for (int32 i = 0;
			 userArchive.GetInfo(B_INT32_TYPE, i, &path, &type) == B_OK;
			 i++) {
			uint32 permissions;
			error = userArchive.FindInt32(path, (int32*)&permissions);
			if (error == B_OK)
				error = SetNodePermissions(path, user, permissions);
		}
	}
}