1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
4 * This file is part of tlm (Tiny Login Manager)
6 * Copyright (C) 2013 Intel Corporation.
8 * Contact: Amarnath Valluri <amarnath.valluri@linux.intel.com>
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
35 #include "tzplatform_config.h"
37 #include "tlm-account-plugin-default.h"
41 * SECTION:tlm-account-plugin-default
42 * @short_description: an default plugin for user account operation
44 * #TlmAccountPluginDefault provides a default implementation of user account
46 * - setting up guest account is performed by running 'useradd'
47 * - cleaning up guest account is performed by running 'rm -rf' on the account's
49 * - check the account validity is done using getpwnam().
51 * It is recommended to use a GUM plugin instead: see #TlmAccountPluginGumd.
56 * TlmAccountPluginDefault:
58 * Opaque data structure
61 * TlmAccountPluginDefaultClass:
62 * @parent_class: a reference to a parent class
64 * The class structure for the #TlmAccountPluginDefault objects,
72 struct _TlmAccountPluginDefault
80 _setup_guest_account (TlmAccountPlugin *plugin, const gchar *user_name)
85 g_return_val_if_fail (plugin, FALSE);
86 g_return_val_if_fail (TLM_IS_ACCOUNT_PLUGIN_DEFAULT(plugin), FALSE);
87 g_return_val_if_fail (user_name && user_name[0], FALSE);
90 if (0 == pid) { //child process
92 const gchar *path = tzplatform_getenv(TZ_SYS_SBIN);
94 args = g_new0 (gchar *, 3);
98 args[0] = g_strdup_printf("%s/useradd", path);
99 args[1] = g_strdup(user_name);
102 execv(args[0], args);
107 else if (-1 != pid) { // parent process
110 while ((ret = waitpid(pid, &status, WNOHANG))== 0) {
113 if ((ret == pid) && (WIFEXITED(status)))
114 res = WEXITSTATUS(status);
119 return ((res != -1) && (res != EXIT_FAILURE));
122 gboolean delete_sub_files(const gchar* dir)
125 struct dirent *result;
126 struct stat file_stat;
128 gboolean ret = FALSE;
131 max_path = pathconf("/", _PC_PATH_MAX);
132 if (0 >= max_path) max_path=1025;
134 if ((dirp = opendir(dir)) == NULL)
137 file = g_malloc(max_path);
144 while ((result = readdir(dirp)) != NULL)
146 if ((0 == strcmp(".", result->d_name)) || (0 == strcmp("..", result->d_name)))
149 snprintf(file, max_path, "%s/%s", dir, result->d_name);
150 lstat(file, &file_stat);
151 if (S_ISDIR(file_stat.st_mode)) {
152 if (!delete_sub_files(file)) {
155 if(0 != rmdir(file)) {
156 DBG("Could not delete directory '%s', error : %s", file, strerror(errno));
161 if (0 != unlink(file)) {
162 DBG("Could not delete file '%s', error : %s", file, strerror(errno));
176 _cleanup_guest_user (TlmAccountPlugin *plugin,
177 const gchar *user_name,
180 struct passwd *pwd_entry = NULL;
181 struct passwd buf_pwd;
183 gchar *buf = NULL, *tmp = NULL;
185 glong pw_size_max = sysconf(_SC_GETPW_R_SIZE_MAX);
186 if (pw_size_max <= sizeof(struct passwd))
193 g_return_val_if_fail (plugin, FALSE);
194 g_return_val_if_fail (TLM_IS_ACCOUNT_PLUGIN_DEFAULT(plugin), FALSE);
195 g_return_val_if_fail (user_name && user_name[0], FALSE);
200 for (; NULL != (tmp = realloc(buf, size)); size*=2)
204 if (ERANGE == getpwnam_r(user_name, &buf_pwd, buf, size, &pwd_entry))
210 DBG("Could not get info for user '%s', error : %s",
211 user_name, strerror(errno));
219 if (!pwd_entry->pw_dir) {
220 DBG("No home folder entry found for user '%s'", user_name);
228 res = delete_sub_files(pwd_entry->pw_dir);
237 _is_valid_user (TlmAccountPlugin *plugin, const gchar *user_name)
239 struct passwd *pwd_entry = NULL;
240 struct passwd pwd_buf;
241 gchar *buf = NULL, *tmp = NULL;
243 glong pw_size_max = sysconf(_SC_GETPW_R_SIZE_MAX);
244 if (pw_size_max <= sizeof(struct passwd))
249 g_return_val_if_fail (plugin, FALSE);
250 g_return_val_if_fail (TLM_IS_ACCOUNT_PLUGIN_DEFAULT(plugin), FALSE);
251 g_return_val_if_fail (user_name && user_name[0], FALSE);
256 for (; NULL != (tmp = realloc(buf, size)); size*=2)
260 if (ERANGE == getpwnam_r(user_name, &pwd_buf, buf, size, &pwd_entry))
266 gchar strerr_buf[MAX_STRERROR_LEN] = {0,};
267 strerror_r(errno, strerr_buf, MAX_STRERROR_LEN);
268 DBG("Could not get info for user '%s', error : %s",
269 user_name, strerr_buf);
282 _plugin_interface_init (TlmAccountPluginInterface *iface)
284 iface->setup_guest_user_account = _setup_guest_account;
285 iface->cleanup_guest_user = _cleanup_guest_user;
286 iface->is_valid_user = _is_valid_user;
289 G_DEFINE_TYPE_WITH_CODE (TlmAccountPluginDefault, tlm_account_plugin_default,
291 G_IMPLEMENT_INTERFACE (TLM_TYPE_ACCOUNT_PLUGIN,
292 _plugin_interface_init));
296 _plugin_finalize (GObject *self)
298 TlmAccountPluginDefault *plugin = TLM_ACCOUNT_PLUGIN_DEFAULT(self);
300 if (plugin->config) g_hash_table_unref (plugin->config);
302 G_OBJECT_CLASS (tlm_account_plugin_default_parent_class)->finalize(self);
306 _plugin_set_property (GObject *object,
311 TlmAccountPluginDefault *self = TLM_ACCOUNT_PLUGIN_DEFAULT (object);
315 gpointer p = g_value_get_boxed (value);
317 self->config = g_hash_table_ref ((GHashTable *)p);
321 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
327 _plugin_get_property (GObject *object,
332 TlmAccountPluginDefault *self = TLM_ACCOUNT_PLUGIN_DEFAULT (object);
336 g_value_set_boxed (value, self->config);
339 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
345 tlm_account_plugin_default_class_init (TlmAccountPluginDefaultClass *kls)
347 GObjectClass *g_class = G_OBJECT_CLASS (kls);
349 g_class->set_property = _plugin_set_property;
350 g_class->get_property = _plugin_get_property;
351 g_class->finalize = _plugin_finalize;
353 g_object_class_override_property (g_class, PROP_CONFIG, "config");
357 tlm_account_plugin_default_init (TlmAccountPluginDefault *self)
359 tlm_log_init(G_LOG_DOMAIN);