return SECURITY_MANAGER_SUCCESS;
}
-static int pidToPuid(pid_t pid, uid_t &puid)
+static int pidToUid(pid_t pid, uid_t &puid)
{
struct stat st;
std::string path;
}
uid_t puid;
- int ret = pidToPuid(pid, puid);
+ int ret = pidToUid(pid, puid);
if (ret != SECURITY_MANAGER_SUCCESS) {
LogError("Could not find a PUID for the given PID: " << pid);
return ret;
return SECURITY_MANAGER_ERROR_INPUT_PARAM;
uid_t puid;
- int ret = pidToPuid(pid, puid);
+ int ret = pidToUid(pid, puid);
if (ret != SECURITY_MANAGER_SUCCESS) {
LogError("Could not find a PUID for the given PID: " << pid);
return ret;
});
}
+SECURITY_MANAGER_API
+int security_manager_get_app_full_credentials_from_pid(pid_t pid, uid_t *owner_uid,
+ char **pkg_id, char **app_id)
+{
+ if (!owner_uid || !pkg_id || !app_id)
+ return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+
+ uid_t puid;
+ int ret = pidToUid(pid, puid);
+ if (ret != SECURITY_MANAGER_SUCCESS) {
+ LogError("Could not find uid for given PID: " << pid);
+ return ret;
+ }
+
+ if (smack_simple_check()) {
+ // no need to call daemon at all, all in-place, reading the label & uid from /proc
+ *owner_uid = puid;
+ return security_manager_identify_app_from_pid(pid, pkg_id, app_id);
+ } else {
+ // here we need to call the daemon to get all data in one call
+ using namespace SecurityManager;
+ return try_catch([&]() -> int {
+ ClientRequest request(SecurityModuleCall::APP_GET_FULL_CREDS);
+ request.send(puid);
+ if (!request.failed()) {
+ uid_t ownerId;
+ std::string appNameString, pkgNameString;
+
+ request.recv(ownerId, appNameString, pkgNameString);
+
+ if (appNameString.empty() && pkgNameString.empty()) {
+ LogError("Empty return from APP_GET_FULL_CREDS from server!");
+ return SECURITY_MANAGER_ERROR_UNKNOWN;
+ }
+
+ LogInfo("Received ownerId: " << ownerId << " appName: " << appNameString << " pkgName: " << pkgNameString << " for app PID " << pid);
+
+ *owner_uid = ownerId;
+
+ char *appName = nullptr;
+ if (!appNameString.empty() &&
+ !(appName = strdup(appNameString.c_str()))) {
+ LogError("Memory allocation in strdup failed.");
+ return SECURITY_MANAGER_ERROR_MEMORY;
+ }
+
+ char *pkgName = nullptr;
+
+ if (!(pkgName = strdup(pkgNameString.c_str()))) {
+ free(appName);
+ LogError("Memory allocation in strdup failed.");
+ return SECURITY_MANAGER_ERROR_MEMORY;
+ }
+ *pkg_id = pkgName;
+ *app_id = appName;
+ }
+ return request.getStatus();
+ });
+ }
+}
+
SECURITY_MANAGER_API
int security_manager_identify_app_from_cynara_client(const char *client, char **pkg_name,
char **app_name)
APP_GET_OWNER,
APP_GET_PKG_NAME,
APP_GET_PUID_AND_AGID,
+ APP_GET_FULL_CREDS,
APP_APPLY_PRIVATE_SHARING,
APP_DROP_PRIVATE_SHARING,
USER_ADD,
*/
int getAppOwner(pid_t pid, uid_t &ownerId);
+ /**
+ * Process a request to get an application's owner uid, pkgId and appId at once.
+ *
+ * @param[in] puid application process user identifier
+ * @param[in] pid application process identifier
+ * @param[out] ownerId returned application owner uid
+ * @param[out] appName returned application name
+ * @param[out] pkgName returned package name
+ *
+ * @return API return code, as defined in protocols.h
+ */
+ int getAppFullCreds(uid_t puid, pid_t pid, uid_t &ownerId, std::string &appName, std::string &pkgName);
+
/**
* Process package id query.
* Retrieves the package id associated with given application id.
return SECURITY_MANAGER_SUCCESS;
}
+int ServiceImpl::getAppFullCreds(uid_t puid, pid_t pid, uid_t &ownerId, std::string &appName, std::string &pkgName)
+{
+ try {
+ m_privilegeDb.GetAppNameAndPkg(puid, appName, pkgName);
+ if (pkgName.empty()) {
+ LogWarning("No app for PUID " << puid << " found in the database");
+ return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT;
+ }
+ LogInfo("appName: " << appName << ", pkgName: " << pkgName);
+
+ return getAppOwner(pid, ownerId);
+ } catch (const PrivilegeDb::Exception::Base &e) {
+ LogError("Error while getting app credentials from database: " << e.DumpToString());
+ return SECURITY_MANAGER_ERROR_SERVER_ERROR;
+ }
+
+ return SECURITY_MANAGER_SUCCESS;
+}
+
int ServiceImpl::getPkgName(const std::string &appName, std::string &pkgName)
{
LogDebug("appName: " << appName);
*/
int security_manager_identify_app_from_cynara_client(const char *client, char **pkg_id,
char **app_id);
+
+/**
+ * Returns the complete credentials of app identified with PID - this is:
+ * - UID of the app owner for which app is launched (same as from security_manager_get_app_owner_uid)
+ * - pkg_id & app_id (if its applicable) (same as from security_manager_identify_app_from_pid).
+ * pkg_id and app_id arguments are necessary (cannot be null), returned pointers have to be freed.
+ *
+ * The function is meant as a one-call replacement for above API calls (with one round-trip to daemon).
+ *
+ * \param[in] pid process ID of application
+ * \param[out] owner_uid the user ID of application user
+ * \param[out] pkg_id Package id of the application
+ * \param[out] app_id Application id of the application
+ * \return SECURITY_MANAGER_SUCCESS or error code
+ */
+int security_manager_get_app_full_credentials_from_pid(pid_t pid, uid_t *owner_uid,
+ char **pkg_id, char **app_id);
+
/**
* Check whether an application would have access to a privilege
*
*/
void processGetAppOwner(MessageBuffer &buffer, const Credentials &creds);
+ /**
+ * Process getting owner uid, pkgId & appId identifiers from an app puid
+ *
+ * @param buffer Input/output message buffer
+ * @param creds credentials of the requesting process
+ */
+ void processGetAppFullCreds(MessageBuffer &buffer, const Credentials &creds);
+
/**
* Process getting package identifier from an app identifier
*
LogDebug("call_type: SecurityModuleCall::APP_GET_OWNER");
processGetAppOwner(msg.buffer, msg.creds);
break;
+ case SecurityModuleCall::APP_GET_FULL_CREDS:
+ LogDebug("call_type: SecurityModuleCall::APP_GET_FULL_CREDS");
+ processGetAppFullCreds(msg.buffer, msg.creds);
+ break;
case SecurityModuleCall::APP_GET_PKG_NAME:
LogDebug("call_type: SecurityModuleCall::APP_GET_PKG_NAME");
processGetPkgName(msg.buffer);
Serialization::Serialize(buffer, ownerUid);
}
+void Service::processGetAppFullCreds(MessageBuffer &buffer, const Credentials &creds)
+{
+ uid_t puid, ownerUid;
+ std::string appName, pkgName;
+ Deserialization::Deserialize(buffer, puid);
+ int ret = m_serviceImpl.getAppFullCreds(puid, creds.pid, ownerUid, appName, pkgName);
+ buffer.ModeStreaming();
+ Serialization::Serialize(buffer, ret);
+ if (ret == SECURITY_MANAGER_SUCCESS)
+ Serialization::Serialize(buffer, ownerUid, appName, pkgName);
+}
+
void Service::processGetPkgName(MessageBuffer &buffer)
{
std::string appName;