}
/**
+ * gum_file_create_db_files:
+ * @file_path: (transfer none): the path to db file
+ * @error: (transfer none): the #GError which is set in case of an error
+ *
+ * Create @file_path. If file already exists, flushing all the data.
+ *
+ * Returns: TRUE if successful, FALSE otherwise and @error is set.
+ */
+gboolean
+gum_file_create_db_files (const gchar *file_path, GError **error)
+{
+ FILE *file = NULL;
+
+ if (!file_path)
+ return FALSE;
+
+ if (!(file = _open_file (file_path, "w"))) {
+ GUM_RETURN_WITH_ERROR(GUM_ERROR_FILE_OPEN, "Unable to open new file",
+ error, FALSE);
+ }
+
+ fclose(file);
+
+ if (!_set_smack64_attr (file_path,
+ GUM_CONFIG_GENERAL_SMACK64_NEW_FILES, FALSE)) {
+ g_remove(file_path);
+ GUM_RETURN_WITH_ERROR(GUM_ERROR_FILE_ATTRIBUTE,
+ "Unable to set smack file attributes", error, FALSE);
+ }
+
+ if (lchown(file_path, 0, 0) < 0) {
+ g_remove(file_path);
+ GUM_RETURN_WITH_ERROR(GUM_ERROR_FILE_WRITE,
+ "Unable to change file owner and group", error, FALSE);
+ }
+
+ return TRUE;
+}
+
+/**
* gum_file_update:
* @object: (transfer none): the instance of #GObject; can be NULL
* @op: (transfer none): the #GumOpType operation to be done on file entry
uid_t *uid,
GError **error)
{
+ const char *passwd_file = gum_config_get_string(self->priv->config,
+ GUM_CONFIG_GENERAL_PASSWD_FILE);
+ const char *shadow_file = gum_config_get_string (self->priv->config,
+ GUM_CONFIG_GENERAL_SHADOW_FILE);
+
DBG ("");
/* reset uid if set
GUM_CONFIG_GENERAL_SHELL));
}
+ if (!g_file_test(passwd_file, G_FILE_TEST_EXISTS)) {
+ if (!gum_file_create_db_files(passwd_file, error))
+ return FALSE;
+ }
+
+ if (!g_file_test(shadow_file, G_FILE_TEST_EXISTS)) {
+ if (!gum_file_create_db_files(shadow_file, error))
+ return FALSE;
+ }
+
if (!gum_lock_pwdf_lock ()) {
GUM_RETURN_WITH_ERROR (GUM_ERROR_DB_ALREADY_LOCKED,
"Database already locked", error, FALSE);
if (!gum_file_update (G_OBJECT (self), GUM_OPTYPE_ADD,
(GumFileUpdateCB)_update_passwd_entry,
- gum_config_get_string (self->priv->config,
- GUM_CONFIG_GENERAL_PASSWD_FILE), NULL, error) ||
+ passwd_file, NULL, error) ||
!gum_file_update (G_OBJECT (self), GUM_OPTYPE_ADD,
(GumFileUpdateCB)_update_shadow_entry,
- gum_config_get_string (self->priv->config,
- GUM_CONFIG_GENERAL_SHADOW_FILE), NULL, error)) {
+ shadow_file, NULL, error)) {
gum_lock_pwdf_unlock ();
return FALSE;
}
FILE *fpasswd = fopen("/etc/passwd", "r");
fn = gum_config_get_string (config, GUM_CONFIG_GENERAL_PASSWD_FILE);
- if (!fn || !fpasswd || !(fp = fopen (fn, "r"))) {
+ if (!fn || !fpasswd) {
gum_lock_pwdf_unlock ();
- if (fpasswd)
- fclose (fpasswd);
+ if (fpasswd)
+ fclose (fpasswd);
GUM_RETURN_WITH_ERROR (GUM_ERROR_FILE_OPEN,
"Opening passwd file failed", error, NULL);
}
+ fp = fopen(fn, "r");
+
sys_uid_min = (uid_t) gum_config_get_uint (config,
GUM_CONFIG_GENERAL_SYS_UID_MIN, GUM_USER_INVALID_UID);
FILE *fparr[] = {fpasswd, fp};
for (int i = 0; i < G_N_ELEMENTS(fparr); i++) {
- while ((pent = fgetpwent (fparr[i])) != NULL) {
+ while (fparr[i] && ((pent = fgetpwent (fparr[i])) != NULL)) {
/* If type is an empty string, all users are fetched. User type is
* first compared with usertype in gecos field. If gecos field for
* usertype does not exist, then all the users are considered as
}
users = g_variant_builder_end (&builder);
- fclose (fp);
+ if (fp)
+ fclose (fp);
fclose (fpasswd);
gum_lock_pwdf_unlock ();