static void write_files_item(GNode* node, gpointer data) { const GNode* content; const GNode* path; const GNode* permissions; const GNode* owner; gchar **tokens; guint tokens_size; mode_t mode; const gchar* username = ""; const gchar* groupname = ""; CLOUD_CONFIG_KEY(CONTENT, "content"); CLOUD_CONFIG_KEY(PATH, "path"); CLOUD_CONFIG_KEY(OWNER, "owner"); CLOUD_CONFIG_KEY(PERMISSIONS, "permissions"); content = cloud_config_find(node, CONTENT); if (!content) { LOG(MOD "Unable to write file without \"content\" value.\n"); return; } path = cloud_config_find(node, PATH); if (!path) { LOG(MOD "Unable to write file without \"path\" value.\n"); return; } permissions = cloud_config_find(node, PERMISSIONS); owner = cloud_config_find(node, OWNER); LOG(MOD "Writing to file %s: %s\n", (char*)path->data, (char*)content->data); const int fd = open(path->data, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); if (fd == -1) { LOG(MOD "Cannot open %s.\n", (char*)path->data); return; } write(fd, content->data, strlen(content->data)); if (permissions) { if (cloud_config_int_base(permissions, (int *)&mode, 8)) { fchmod(fd, mode); } } close(fd); if (owner) { tokens = g_strsplit_set(owner->data, ":.", 2); tokens_size = g_strv_length(tokens); if (tokens_size > 0) { username = tokens[0]; if (tokens_size > 1) { groupname = tokens[1]; } chown_path(path->data, username, groupname); } g_strfreev(tokens); } }
static void write_files_item(GNode* node, gpointer data) { const GNode* content; const GNode* path; const GNode* permissions; const GNode* owner; gchar **tokens; guint tokens_size; mode_t mode; const gchar* username = ""; const gchar* groupname = ""; CLOUD_CONFIG_KEY(CONTENT, "content"); CLOUD_CONFIG_KEY(PATH, "path"); CLOUD_CONFIG_KEY(OWNER, "owner"); CLOUD_CONFIG_KEY(PERMISSIONS, "permissions"); content = cloud_config_find(node, CONTENT); if (!content) { LOG(MOD "Unable to write file without \"content\" value.\n"); return; } path = cloud_config_find(node, PATH); if (!path) { LOG(MOD "Unable to write file without \"path\" value.\n"); return; } permissions = cloud_config_find(node, PERMISSIONS); owner = cloud_config_find(node, OWNER); /* assure the folder exists, and create if nexessary */ char* dir = strdup((char *)path->data); dir = dirname(dir); int r = access(dir, W_OK); if (r == -1) { if (errno & ENOENT) { LOG(MOD "Creating part or all of %s\n", dir); gchar command[LINE_MAX]; command[0] = 0; g_snprintf(command, LINE_MAX, "mkdir -p %s", dir); exec_task(command); } else { LOG(MOD "Path error: %s", strerror(errno)); free(dir); return; } } free(dir); LOG(MOD "Writing to file %s: %s\n", (char*)path->data, (char*)content->data); const int fd = open(path->data, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); if (fd == -1) { LOG(MOD "Cannot open %s.\n", (char*)path->data); return; } write(fd, content->data, strlen(content->data)); if (permissions) { if (cloud_config_int_base(permissions, (int *)&mode, 8)) { fchmod(fd, mode); } } close(fd); if (owner) { tokens = g_strsplit_set(owner->data, ":.", 2); tokens_size = g_strv_length(tokens); if (tokens_size > 0) { username = tokens[0]; if (tokens_size > 1) { groupname = tokens[1]; } chown_path(path->data, username, groupname); } g_strfreev(tokens); } }
static void users_item(GNode* node, gpointer data) { if (node->data) { /* to avoid bugs with key(gecos, etc) as username */ if (node->children) { for (size_t i = 0; users_options[i].key != NULL; ++i) { if (0 == g_strcmp0(node->data, users_options[i].key)) { if (users_options[i].func) { users_options[i].func(node->children, data, users_options[i].data); } return; } } LOG(MOD "No handler for %s.\n", (char*)node->data); return; } users_add_username(node, data, "%s"); } else { bool b; GString* sudo_directives; GString* ssh_keys; GString* command = g_string_new(USERADD_PATH " "); memset(users_current_username, 0, LOGIN_NAME_MAX); g_node_children_foreach(node, G_TRAVERSE_ALL, users_item, command); if (0 == strlen(users_current_username)) { LOG(MOD "Missing username.\n"); return; } LOG(MOD "Adding %s user...\n", users_current_username); exec_task(command->str); CLOUD_CONFIG_KEY(LOCK_PASSWD, "lock-passwd"); CLOUD_CONFIG_KEY(INACTIVE, "inactive"); CLOUD_CONFIG_KEY(SSH_AUTH_KEYS, "ssh-authorized-keys"); CLOUD_CONFIG_KEY(SUDO, "sudo"); GNode *item = cloud_config_find(node, LOCK_PASSWD); if (item) { cloud_config_bool(item, &b); if (b) { LOG(MOD "Locking %s user.\n", users_current_username); g_string_printf(command, PASSWD_PATH " -l '%s'", users_current_username); exec_task(command->str); } } item = cloud_config_find(node, INACTIVE); if (item) { cloud_config_bool(item, &b); if (b) { LOG(MOD "Deactivating %s user...\n", users_current_username); g_string_printf(command, USERMOD_PATH " --expiredate 1 '%s'", users_current_username); exec_task(command->str); } } g_string_free(command, true); item = cloud_config_find(node, SSH_AUTH_KEYS); if (item) { ssh_keys = g_string_new(""); g_node_traverse(item->parent, G_IN_ORDER, G_TRAVERSE_LEAVES, -1, users_ssh_key_item, ssh_keys); if (!write_ssh_keys(ssh_keys, users_current_username)) { LOG(MOD "Cannot write ssh keys\n"); } g_string_free(ssh_keys, true); } item = cloud_config_find(node, SUDO); if (item) { sudo_directives = g_string_new(""); g_string_printf(sudo_directives, "# Rules for %s user\n", users_current_username); g_node_traverse(item->parent, G_IN_ORDER, G_TRAVERSE_LEAVES, -1, users_sudo_item, sudo_directives); g_string_append(sudo_directives, "\n"); if (!write_sudo_directives(sudo_directives, "users-cloud-init", O_CREAT|O_APPEND|O_WRONLY)) { LOG(MOD "Cannot write sudo directives\n"); } g_string_free(sudo_directives, true); } } }