source:
proiecte/PPPP/gdm/debian/patches/16_gdmserver_user_manager.patch
@
141
Last change on this file since 141 was 134, checked in by , 14 years ago | |
---|---|
File size: 89.2 KB |
-
configure.ac
# # Description: Add org.gnome.DisplayManager.UserManager interface to gdmserver to be shared between greeter, configuration applet and FUSA applet # Ubuntu: https://bugs.launchpad.net/ubuntu/+source/gdm/+bug/423450 # Upstream: https://bugzilla.gnome.org/show_bug.cgi?id=593996 # From 35aa54f6fe3ff8fa8d6129f805ea243a6204aa65 Mon Sep 17 00:00:00 2001 From: Robert Ancell <robert.ancell@canonical.com> Date: Fri, 11 Sep 2009 16:01:30 +1000 Subject: [PATCH] Add org.gnome.DisplayManager.UserManager interface to gdmserver diff -Nur -x '*.orig' -x '*~' gdm-2.28.0/configure.ac gdm-2.28.0.new/configure.ac
old new 73 73 polkit-gobject-1 >= $POLKIT_GOBJECT_REQUIRED_VERSION 74 74 gobject-2.0 >= $GLIB_REQUIRED_VERSION 75 75 gio-2.0 >= $GLIB_REQUIRED_VERSION 76 gconf-2.0 >= $GCONF_REQUIRED_VERSION 76 77 hal 77 78 ) 78 79 AC_SUBST(DAEMON_CFLAGS) … … 949 950 fi 950 951 AC_SUBST(logdir, $GDM_LOG_DIR) 951 952 953 AC_ARG_WITH(cache-dir, 954 AS_HELP_STRING([--with-cache-dir=<file>], 955 [cache dir])) 956 957 if ! test -z "$with_cache_dir"; then 958 GDM_CACHE_DIR=$with_cache_dir 959 else 960 GDM_CACHE_DIR=/var/cache/gdm 961 fi 962 AC_SUBST(cachedir, $GDM_CACHE_DIR) 963 952 964 withval="" 953 965 AC_ARG_WITH(at-bindir, 954 966 AS_HELP_STRING([--with-at-bindir=<PATH>] -
daemon/gdm-user.c
diff -Nur -x '*.orig' -x '*~' gdm-2.28.0/daemon/gdm-user.c gdm-2.28.0.new/daemon/gdm-user.c
old new 1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- 2 * 3 * Copyright (C) 2004-2005 James M. Cape <jcape@ignore-your.tv>. 4 * Copyright (C) 2007-2008 William Jon McCann <mccann@jhu.edu> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 21 #include <config.h> 22 23 #include <float.h> 24 #include <string.h> 25 #include <sys/types.h> 26 #include <sys/stat.h> 27 #include <unistd.h> 28 29 #include <glib/gi18n.h> 30 #include <gio/gio.h> 31 32 #include "gdm-user-manager.h" 33 #include "gdm-user-private.h" 34 35 #define GDM_USER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDM_TYPE_USER, GdmUserClass)) 36 #define GDM_IS_USER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDM_TYPE_USER)) 37 #define GDM_USER_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS ((object), GDM_TYPE_USER, GdmUserClass)) 38 39 enum { 40 PROP_0, 41 PROP_REAL_NAME, 42 PROP_USER_NAME, 43 PROP_UID, 44 PROP_HOME_DIR, 45 PROP_SHELL, 46 PROP_ICON_URL, 47 PROP_LOGIN_FREQUENCY, 48 }; 49 50 enum { 51 ICON_CHANGED, 52 SESSIONS_CHANGED, 53 LAST_SIGNAL 54 }; 55 56 struct _GdmUser { 57 GObject parent; 58 59 uid_t uid; 60 char *user_name; 61 char *real_name; 62 char *home_dir; 63 char *shell; 64 char *icon_url; 65 GList *sessions; 66 gulong login_frequency; 67 68 GFileMonitor *icon_monitor; 69 }; 70 71 typedef struct _GdmUserClass 72 { 73 GObjectClass parent_class; 74 75 void (* icon_changed) (GdmUser *user); 76 void (* sessions_changed) (GdmUser *user); 77 } GdmUserClass; 78 79 static void gdm_user_finalize (GObject *object); 80 81 static guint signals[LAST_SIGNAL] = { 0 }; 82 83 G_DEFINE_TYPE (GdmUser, gdm_user, G_TYPE_OBJECT) 84 85 static int 86 session_compare (const char *a, 87 const char *b) 88 { 89 if (a == NULL) { 90 return 1; 91 } else if (b == NULL) { 92 return -1; 93 } 94 95 return strcmp (a, b); 96 } 97 98 void 99 _gdm_user_add_session (GdmUser *user, 100 const char *ssid) 101 { 102 GList *li; 103 104 g_return_if_fail (GDM_IS_USER (user)); 105 g_return_if_fail (ssid != NULL); 106 107 li = g_list_find_custom (user->sessions, ssid, (GCompareFunc)session_compare); 108 if (li == NULL) { 109 g_debug ("GdmUser: adding session %s", ssid); 110 user->sessions = g_list_prepend (user->sessions, g_strdup (ssid)); 111 g_signal_emit (user, signals[SESSIONS_CHANGED], 0); 112 } else { 113 g_debug ("GdmUser: session already present: %s", ssid); 114 } 115 } 116 117 void 118 _gdm_user_remove_session (GdmUser *user, 119 const char *ssid) 120 { 121 GList *li; 122 123 g_return_if_fail (GDM_IS_USER (user)); 124 g_return_if_fail (ssid != NULL); 125 126 li = g_list_find_custom (user->sessions, ssid, (GCompareFunc)session_compare); 127 if (li != NULL) { 128 g_debug ("GdmUser: removing session %s", ssid); 129 g_free (li->data); 130 user->sessions = g_list_delete_link (user->sessions, li); 131 g_signal_emit (user, signals[SESSIONS_CHANGED], 0); 132 } else { 133 g_debug ("GdmUser: session not found: %s", ssid); 134 } 135 } 136 137 guint 138 gdm_user_get_num_sessions (GdmUser *user) 139 { 140 return g_list_length (user->sessions); 141 } 142 143 GList * 144 gdm_user_get_sessions (GdmUser *user) 145 { 146 return user->sessions; 147 } 148 149 static void 150 gdm_user_set_property (GObject *object, 151 guint param_id, 152 const GValue *value, 153 GParamSpec *pspec) 154 { 155 GdmUser *user; 156 157 user = GDM_USER (object); 158 159 switch (param_id) { 160 case PROP_LOGIN_FREQUENCY: 161 user->login_frequency = g_value_get_ulong (value); 162 g_object_notify (G_OBJECT (user), "login-frequency"); 163 break; 164 default: 165 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); 166 break; 167 } 168 } 169 170 static void 171 gdm_user_get_property (GObject *object, 172 guint param_id, 173 GValue *value, 174 GParamSpec *pspec) 175 { 176 GdmUser *user; 177 178 user = GDM_USER (object); 179 180 switch (param_id) { 181 case PROP_USER_NAME: 182 g_value_set_string (value, user->user_name); 183 break; 184 case PROP_REAL_NAME: 185 g_value_set_string (value, user->real_name); 186 break; 187 case PROP_HOME_DIR: 188 g_value_set_string (value, user->home_dir); 189 break; 190 case PROP_UID: 191 g_value_set_ulong (value, user->uid); 192 break; 193 case PROP_SHELL: 194 g_value_set_string (value, user->shell); 195 break; 196 case PROP_ICON_URL: 197 g_value_set_string (value, user->icon_url); 198 break; 199 case PROP_LOGIN_FREQUENCY: 200 g_value_set_ulong (value, user->login_frequency); 201 break; 202 default: 203 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); 204 break; 205 } 206 } 207 208 static void 209 gdm_user_class_init (GdmUserClass *class) 210 { 211 GObjectClass *gobject_class; 212 213 gobject_class = G_OBJECT_CLASS (class); 214 215 gobject_class->set_property = gdm_user_set_property; 216 gobject_class->get_property = gdm_user_get_property; 217 gobject_class->finalize = gdm_user_finalize; 218 219 g_object_class_install_property (gobject_class, 220 PROP_REAL_NAME, 221 g_param_spec_string ("real-name", 222 "Real Name", 223 "The real name to display for this user.", 224 NULL, 225 G_PARAM_READABLE)); 226 227 g_object_class_install_property (gobject_class, 228 PROP_UID, 229 g_param_spec_ulong ("uid", 230 "User ID", 231 "The UID for this user.", 232 0, G_MAXULONG, 0, 233 G_PARAM_READABLE)); 234 g_object_class_install_property (gobject_class, 235 PROP_USER_NAME, 236 g_param_spec_string ("user-name", 237 "User Name", 238 "The login name for this user.", 239 NULL, 240 G_PARAM_READABLE)); 241 g_object_class_install_property (gobject_class, 242 PROP_HOME_DIR, 243 g_param_spec_string ("home-directory", 244 "Home Directory", 245 "The home directory for this user.", 246 NULL, 247 G_PARAM_READABLE)); 248 g_object_class_install_property (gobject_class, 249 PROP_SHELL, 250 g_param_spec_string ("shell", 251 "Shell", 252 "The shell for this user.", 253 NULL, 254 G_PARAM_READABLE)); 255 g_object_class_install_property (gobject_class, 256 PROP_SHELL, 257 g_param_spec_string ("icon-url", 258 "Icon URL", 259 "The icon for this user.", 260 NULL, 261 G_PARAM_READABLE)); 262 g_object_class_install_property (gobject_class, 263 PROP_LOGIN_FREQUENCY, 264 g_param_spec_ulong ("login-frequency", 265 "login frequency", 266 "login frequency", 267 0, 268 G_MAXULONG, 269 0, 270 G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); 271 272 signals [ICON_CHANGED] = 273 g_signal_new ("icon-changed", 274 G_TYPE_FROM_CLASS (class), 275 G_SIGNAL_RUN_LAST, 276 G_STRUCT_OFFSET (GdmUserClass, icon_changed), 277 NULL, NULL, 278 g_cclosure_marshal_VOID__VOID, 279 G_TYPE_NONE, 0); 280 signals [SESSIONS_CHANGED] = 281 g_signal_new ("sessions-changed", 282 G_TYPE_FROM_CLASS (class), 283 G_SIGNAL_RUN_LAST, 284 G_STRUCT_OFFSET (GdmUserClass, sessions_changed), 285 NULL, NULL, 286 g_cclosure_marshal_VOID__VOID, 287 G_TYPE_NONE, 0); 288 } 289 290 291 static void 292 on_icon_monitor_changed (GFileMonitor *monitor, 293 GFile *file, 294 GFile *other_file, 295 GFileMonitorEvent event_type, 296 GdmUser *user) 297 { 298 g_debug ("Icon changed: %d", event_type); 299 300 if (event_type != G_FILE_MONITOR_EVENT_CHANGED && 301 event_type != G_FILE_MONITOR_EVENT_CREATED) { 302 return; 303 } 304 305 g_signal_emit (user, signals[ICON_CHANGED], 0); 306 } 307 308 static void 309 update_icon_monitor (GdmUser *user) 310 { 311 GFile *file; 312 GError *error = NULL; 313 314 if (user->icon_url != NULL) { 315 g_free (user->icon_url); 316 user->icon_url = NULL; 317 } 318 if (user->home_dir != NULL) { 319 gchar *filename; 320 filename = g_build_filename (user->home_dir, ".face", NULL); 321 user->icon_url = g_strjoin(NULL, "file://", filename, NULL); 322 g_free (filename); 323 } 324 g_object_notify (G_OBJECT (user), "icon-url"); 325 326 if (user->icon_monitor != NULL) { 327 g_file_monitor_cancel (user->icon_monitor); 328 user->icon_monitor = NULL; 329 } 330 331 if (user->icon_url == NULL) { 332 return; 333 } 334 335 g_debug ("adding monitor for '%s'", user->icon_url); 336 file = g_file_new_for_uri (user->icon_url); 337 user->icon_monitor = g_file_monitor_file (file, 338 G_FILE_MONITOR_NONE, 339 NULL, 340 &error); 341 if (user->icon_monitor != NULL) { 342 g_signal_connect (user->icon_monitor, 343 "changed", 344 G_CALLBACK (on_icon_monitor_changed), 345 user); 346 } else { 347 g_warning ("Unable to monitor %s: %s", user->icon_url, error->message); 348 g_error_free (error); 349 } 350 g_object_unref (file); 351 } 352 353 static void 354 gdm_user_init (GdmUser *user) 355 { 356 user->user_name = NULL; 357 user->real_name = NULL; 358 user->sessions = NULL; 359 } 360 361 static void 362 gdm_user_finalize (GObject *object) 363 { 364 GdmUser *user; 365 366 user = GDM_USER (object); 367 368 g_file_monitor_cancel (user->icon_monitor); 369 370 g_free (user->user_name); 371 g_free (user->real_name); 372 373 if (G_OBJECT_CLASS (gdm_user_parent_class)->finalize) 374 (*G_OBJECT_CLASS (gdm_user_parent_class)->finalize) (object); 375 } 376 377 /** 378 * _gdm_user_update: 379 * @user: the user object to update. 380 * @pwent: the user data to use. 381 * 382 * Updates the properties of @user using the data in @pwent. 383 * 384 * Since: 1.0 385 **/ 386 void 387 _gdm_user_update (GdmUser *user, 388 const struct passwd *pwent) 389 { 390 gchar *real_name; 391 392 g_return_if_fail (GDM_IS_USER (user)); 393 g_return_if_fail (pwent != NULL); 394 395 g_object_freeze_notify (G_OBJECT (user)); 396 397 /* Display Name */ 398 if (pwent->pw_gecos && pwent->pw_gecos[0] != '\0') { 399 gchar *first_comma; 400 gchar *real_name_utf8; 401 402 real_name_utf8 = g_locale_to_utf8 (pwent->pw_gecos, -1, NULL, NULL, NULL); 403 404 first_comma = strchr (real_name_utf8, ','); 405 if (first_comma) { 406 real_name = g_strndup (real_name_utf8, first_comma - real_name_utf8); 407 g_free (real_name_utf8); 408 } else { 409 real_name = real_name_utf8; 410 } 411 412 if (real_name[0] == '\0') { 413 g_free (real_name); 414 real_name = NULL; 415 } 416 } else { 417 real_name = NULL; 418 } 419 420 if ((real_name && !user->real_name) || 421 (!real_name && user->real_name) || 422 (real_name && 423 user->real_name && 424 strcmp (real_name, user->real_name) != 0)) { 425 g_free (user->real_name); 426 user->real_name = real_name; 427 g_object_notify (G_OBJECT (user), "real-name"); 428 } else { 429 g_free (real_name); 430 } 431 432 /* UID */ 433 if (pwent->pw_uid != user->uid) { 434 user->uid = pwent->pw_uid; 435 g_object_notify (G_OBJECT (user), "uid"); 436 } 437 438 /* Username */ 439 if ((pwent->pw_name && !user->user_name) || 440 (!pwent->pw_name && user->user_name) || 441 (pwent->pw_name && 442 user->user_name && 443 strcmp (user->user_name, pwent->pw_name) != 0)) { 444 g_free (user->user_name); 445 user->user_name = g_strdup (pwent->pw_name); 446 g_object_notify (G_OBJECT (user), "user-name"); 447 } 448 449 /* Home Directory */ 450 if ((pwent->pw_dir && !user->home_dir) || 451 (!pwent->pw_dir && user->home_dir) || 452 strcmp (user->home_dir, pwent->pw_dir) != 0) { 453 g_free (user->home_dir); 454 user->home_dir = g_strdup (pwent->pw_dir); 455 g_object_notify (G_OBJECT (user), "home-directory"); 456 g_signal_emit (user, signals[ICON_CHANGED], 0); 457 } 458 459 /* Shell */ 460 if ((pwent->pw_shell && !user->shell) || 461 (!pwent->pw_shell && user->shell) || 462 (pwent->pw_shell && 463 user->shell && 464 strcmp (user->shell, pwent->pw_shell) != 0)) { 465 g_free (user->shell); 466 user->shell = g_strdup (pwent->pw_shell); 467 g_object_notify (G_OBJECT (user), "shell"); 468 } 469 470 update_icon_monitor (user); 471 472 g_object_thaw_notify (G_OBJECT (user)); 473 } 474 475 /** 476 * gdm_user_get_uid: 477 * @user: the user object to examine. 478 * 479 * Retrieves the ID of @user. 480 * 481 * Returns: a pointer to an array of characters which must not be modified or 482 * freed, or %NULL. 483 * 484 * Since: 1.0 485 **/ 486 487 uid_t 488 gdm_user_get_uid (GdmUser *user) 489 { 490 g_return_val_if_fail (GDM_IS_USER (user), -1); 491 492 return user->uid; 493 } 494 495 /** 496 * gdm_user_get_real_name: 497 * @user: the user object to examine. 498 * 499 * Retrieves the display name of @user. 500 * 501 * Returns: a pointer to an array of characters which must not be modified or 502 * freed, or %NULL. 503 * 504 * Since: 1.0 505 **/ 506 G_CONST_RETURN gchar * 507 gdm_user_get_real_name (GdmUser *user) 508 { 509 g_return_val_if_fail (GDM_IS_USER (user), NULL); 510 511 return (user->real_name ? user->real_name : user->user_name); 512 } 513 514 /** 515 * gdm_user_get_user_name: 516 * @user: the user object to examine. 517 * 518 * Retrieves the login name of @user. 519 * 520 * Returns: a pointer to an array of characters which must not be modified or 521 * freed, or %NULL. 522 * 523 * Since: 1.0 524 **/ 525 526 G_CONST_RETURN gchar * 527 gdm_user_get_user_name (GdmUser *user) 528 { 529 g_return_val_if_fail (GDM_IS_USER (user), NULL); 530 531 return user->user_name; 532 } 533 534 /** 535 * gdm_user_get_home_directory: 536 * @user: the user object to examine. 537 * 538 * Retrieves the home directory of @user. 539 * 540 * Returns: a pointer to an array of characters which must not be modified or 541 * freed, or %NULL. 542 * 543 * Since: 1.0 544 **/ 545 546 G_CONST_RETURN gchar * 547 gdm_user_get_home_directory (GdmUser *user) 548 { 549 g_return_val_if_fail (GDM_IS_USER (user), NULL); 550 551 return user->home_dir; 552 } 553 554 /** 555 * gdm_user_get_shell: 556 * @user: the user object to examine. 557 * 558 * Retrieves the login shell of @user. 559 * 560 * Returns: a pointer to an array of characters which must not be modified or 561 * freed, or %NULL. 562 * 563 * Since: 1.0 564 **/ 565 566 G_CONST_RETURN gchar * 567 gdm_user_get_shell (GdmUser *user) 568 { 569 g_return_val_if_fail (GDM_IS_USER (user), NULL); 570 571 return user->shell; 572 } 573 574 gulong 575 gdm_user_get_login_frequency (GdmUser *user) 576 { 577 g_return_val_if_fail (GDM_IS_USER (user), 0); 578 579 return user->login_frequency; 580 } 581 582 G_CONST_RETURN gchar * 583 gdm_user_get_icon_url (GdmUser *user) 584 { 585 g_return_val_if_fail (GDM_IS_USER (user), NULL); 586 587 /* FIXME: Icon can be one of: 588 * ~/.face 589 * ~/.face.icon 590 * ~/.gnome/gdm:[face]picture 591 * ${GlobalFaceDir}/${username} 592 * ${GlobalFaceDir}/${username}.png 593 * but we only monitor the first. 594 */ 595 return user->icon_url; 596 } -
daemon/gdm-user.h
diff -Nur -x '*.orig' -x '*~' gdm-2.28.0/daemon/gdm-user.h gdm-2.28.0.new/daemon/gdm-user.h
old new 1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- 2 * 3 * Copyright (C) 2004-2005 James M. Cape <jcape@ignore-your.tv>. 4 * Copyright (C) 2007-2008 William Jon McCann <mccann@jhu.edu> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 21 /* 22 * Facade object for user data, owned by GdmUserManager 23 */ 24 25 #ifndef __GDM_USER__ 26 #define __GDM_USER__ 1 27 28 #include <sys/types.h> 29 #include <glib-object.h> 30 31 G_BEGIN_DECLS 32 33 #define GDM_TYPE_USER (gdm_user_get_type ()) 34 #define GDM_USER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDM_TYPE_USER, GdmUser)) 35 #define GDM_IS_USER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDM_TYPE_USER)) 36 37 typedef struct _GdmUser GdmUser; 38 39 GType gdm_user_get_type (void) G_GNUC_CONST; 40 41 uid_t gdm_user_get_uid (GdmUser *user); 42 G_CONST_RETURN gchar *gdm_user_get_user_name (GdmUser *user); 43 G_CONST_RETURN gchar *gdm_user_get_real_name (GdmUser *user); 44 G_CONST_RETURN gchar *gdm_user_get_home_directory (GdmUser *user); 45 G_CONST_RETURN gchar *gdm_user_get_shell (GdmUser *user); 46 guint gdm_user_get_num_sessions (GdmUser *user); 47 GList *gdm_user_get_sessions (GdmUser *user); 48 gulong gdm_user_get_login_frequency (GdmUser *user); 49 G_CONST_RETURN gchar *gdm_user_get_icon_url (GdmUser *user); 50 51 G_END_DECLS 52 53 #endif -
daemon/gdm-user-manager.c
diff -Nur -x '*.orig' -x '*~' gdm-2.28.0/daemon/gdm-user-manager.c gdm-2.28.0.new/daemon/gdm-user-manager.c
old new 1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- 2 * 3 * Copyright (C) 2007-2008 William Jon McCann <mccann@jhu.edu> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 * 19 */ 20 21 #include "config.h" 22 23 #include <stdlib.h> 24 #include <stdio.h> 25 #include <fcntl.h> 26 #include <unistd.h> 27 #include <string.h> 28 #include <signal.h> 29 #include <errno.h> 30 #include <sys/stat.h> 31 #include <sys/types.h> 32 33 #ifdef HAVE_PATHS_H 34 #include <paths.h> 35 #endif /* HAVE_PATHS_H */ 36 37 #include <glib.h> 38 #include <glib/gi18n.h> 39 #include <glib/gstdio.h> 40 #include <glib-object.h> 41 #include <gio/gio.h> 42 43 #include <dbus/dbus.h> 44 #include <dbus/dbus-glib.h> 45 #include <dbus/dbus-glib-lowlevel.h> 46 47 #include "gdm-user-manager.h" 48 #include "gdm-user-manager-glue.h" 49 #include "gdm-user-private.h" 50 51 #define GDM_USER_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_USER_MANAGER, GdmUserManagerPrivate)) 52 53 #define GDM_DBUS_PATH "/org/gnome/DisplayManager" 54 #define GDM_USER_MANAGER_DBUS_PATH GDM_DBUS_PATH "/UserManager" 55 #define GDM_USER_MANAGER_DBUS_NAME "org.gnome.DisplayManager.UserManager" 56 57 #define CK_NAME "org.freedesktop.ConsoleKit" 58 #define CK_PATH "/org/freedesktop/ConsoleKit" 59 #define CK_INTERFACE "org.freedesktop.ConsoleKit" 60 61 #define CK_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager" 62 #define CK_MANAGER_INTERFACE "org.freedesktop.ConsoleKit.Manager" 63 #define CK_SEAT_INTERFACE "org.freedesktop.ConsoleKit.Seat" 64 #define CK_SESSION_INTERFACE "org.freedesktop.ConsoleKit.Session" 65 66 #ifdef __sun 67 #define DEFAULT_MINIMAL_UID 100 68 #else 69 #define DEFAULT_MINIMAL_UID 500 70 #endif 71 72 #ifndef _PATH_SHELLS 73 #define _PATH_SHELLS "/etc/shells" 74 #endif 75 #define PATH_PASSWD "/etc/passwd" 76 77 #define LOGIN_CACHE_FILE CACHEDIR "/login_frequency.cache" 78 79 #define DEFAULT_EXCLUDE { "bin", \ 80 "root", \ 81 "daemon", \ 82 "adm", \ 83 "lp", \ 84 "sync", \ 85 "shutdown", \ 86 "halt", \ 87 "mail", \ 88 "news", \ 89 "uucp", \ 90 "operator", \ 91 "nobody", \ 92 "nobody4", \ 93 "noaccess", \ 94 GDM_USERNAME, \ 95 "postgres", \ 96 "pvm", \ 97 "rpm", \ 98 "nfsnobody", \ 99 "pcap", \ 100 NULL } 101 102 struct GdmUserManagerPrivate 103 { 104 GHashTable *users; 105 GHashTable *sessions; 106 GHashTable *exclusions; 107 GHashTable *shells; 108 DBusGConnection *connection; 109 DBusGProxy *seat_proxy; 110 char *seat_id; 111 112 GFileMonitor *passwd_monitor; 113 GFileMonitor *shells_monitor; 114 115 guint reload_id; 116 guint ck_history_id; 117 118 guint8 loaded_passwd : 1; 119 guint8 loaded_cache : 1; 120 }; 121 122 enum { 123 USERS_LOADED, 124 USER_ADDED, 125 USER_REMOVED, 126 USER_UPDATED, 127 LAST_SIGNAL 128 }; 129 130 static guint signals [LAST_SIGNAL] = { 0, }; 131 132 static void gdm_user_manager_class_init (GdmUserManagerClass *klass); 133 static void gdm_user_manager_init (GdmUserManager *user_manager); 134 static void gdm_user_manager_finalize (GObject *object); 135 136 G_DEFINE_TYPE (GdmUserManager, gdm_user_manager, G_TYPE_OBJECT) 137 138 GQuark 139 gdm_user_manager_error_quark (void) 140 { 141 static GQuark ret = 0; 142 if (ret == 0) { 143 ret = g_quark_from_static_string ("gdm_user_manager_error"); 144 } 145 146 return ret; 147 } 148 149 static void 150 on_user_sessions_changed (GdmUser *user, 151 GdmUserManager *manager) 152 { 153 guint nsessions; 154 155 nsessions = gdm_user_get_num_sessions (user); 156 157 g_debug ("GdmUserManager: sessions changed user=%s num=%d", 158 gdm_user_get_user_name (user), 159 nsessions); 160 161 /* only signal on zero and one */ 162 if (nsessions > 1) { 163 return; 164 } 165 166 g_signal_emit (manager, signals [USER_UPDATED], 0, gdm_user_get_uid (user)); 167 } 168 169 static void 170 on_user_icon_changed (GdmUser *user, 171 GdmUserManager *manager) 172 { 173 g_debug ("GdmUserManager: user icon changed"); 174 } 175 176 static char * 177 get_seat_id_for_session (DBusGConnection *connection, 178 const char *session_id) 179 { 180 DBusGProxy *proxy; 181 GError *error; 182 char *seat_id; 183 gboolean res; 184 185 proxy = NULL; 186 seat_id = NULL; 187 188 proxy = dbus_g_proxy_new_for_name (connection, 189 CK_NAME, 190 session_id, 191 CK_SESSION_INTERFACE); 192 if (proxy == NULL) { 193 g_warning ("Failed to connect to the ConsoleKit session object"); 194 goto out; 195 } 196 197 error = NULL; 198 res = dbus_g_proxy_call (proxy, 199 "GetSeatId", 200 &error, 201 G_TYPE_INVALID, 202 DBUS_TYPE_G_OBJECT_PATH, &seat_id, 203 G_TYPE_INVALID); 204 if (! res) { 205 if (error != NULL) { 206 g_debug ("Failed to identify the current seat: %s", error->message); 207 g_error_free (error); 208 } else { 209 g_debug ("Failed to identify the current seat"); 210 } 211 } 212 out: 213 if (proxy != NULL) { 214 g_object_unref (proxy); 215 } 216 217 return seat_id; 218 } 219 220 static char * 221 get_x11_display_for_session (DBusGConnection *connection, 222 const char *session_id) 223 { 224 DBusGProxy *proxy; 225 GError *error; 226 char *x11_display; 227 gboolean res; 228 229 proxy = NULL; 230 x11_display = NULL; 231 232 proxy = dbus_g_proxy_new_for_name (connection, 233 CK_NAME, 234 session_id, 235 CK_SESSION_INTERFACE); 236 if (proxy == NULL) { 237 g_warning ("Failed to connect to the ConsoleKit session object"); 238 goto out; 239 } 240 241 error = NULL; 242 res = dbus_g_proxy_call (proxy, 243 "GetX11Display", 244 &error, 245 G_TYPE_INVALID, 246 G_TYPE_STRING, &x11_display, 247 G_TYPE_INVALID); 248 if (! res) { 249 if (error != NULL) { 250 g_debug ("Failed to identify the x11 display: %s", error->message); 251 g_error_free (error); 252 } else { 253 g_debug ("Failed to identify the x11 display"); 254 } 255 } 256 out: 257 if (proxy != NULL) { 258 g_object_unref (proxy); 259 } 260 261 return x11_display; 262 } 263 264 static gboolean 265 maybe_add_session_for_user (GdmUserManager *manager, 266 GdmUser *user, 267 const char *ssid) 268 { 269 char *sid; 270 char *x11_display; 271 gboolean ret; 272 273 ret = FALSE; 274 sid = NULL; 275 x11_display = NULL; 276 277 /* skip if on another seat */ 278 sid = get_seat_id_for_session (manager->priv->connection, ssid); 279 if (sid == NULL 280 || manager->priv->seat_id == NULL 281 || strcmp (sid, manager->priv->seat_id) != 0) { 282 g_debug ("GdmUserManager: not adding session on other seat: %s", ssid); 283 goto out; 284 } 285 286 /* skip if doesn't have an x11 display */ 287 x11_display = get_x11_display_for_session (manager->priv->connection, ssid); 288 if (x11_display == NULL || x11_display[0] == '\0') { 289 g_debug ("GdmUserManager: not adding session without a x11 display: %s", ssid); 290 goto out; 291 } 292 293 if (g_hash_table_lookup (manager->priv->exclusions, gdm_user_get_user_name (user))) { 294 g_debug ("GdmUserManager: excluding user '%s'", gdm_user_get_user_name (user)); 295 goto out; 296 } 297 298 g_hash_table_insert (manager->priv->sessions, 299 g_strdup (ssid), 300 g_strdup (gdm_user_get_user_name (user))); 301 302 _gdm_user_add_session (user, ssid); 303 g_debug ("GdmUserManager: added session for user: %s", gdm_user_get_user_name (user)); 304 305 ret = TRUE; 306 307 out: 308 g_free (sid); 309 g_free (x11_display); 310 311 return ret; 312 } 313 314 static void 315 add_sessions_for_user (GdmUserManager *manager, 316 GdmUser *user) 317 { 318 DBusGProxy *proxy; 319 GError *error; 320 gboolean res; 321 guint32 uid; 322 GPtrArray *sessions; 323 int i; 324 325 proxy = dbus_g_proxy_new_for_name (manager->priv->connection, 326 CK_NAME, 327 CK_MANAGER_PATH, 328 CK_MANAGER_INTERFACE); 329 if (proxy == NULL) { 330 g_warning ("Failed to connect to the ConsoleKit manager object"); 331 goto out; 332 } 333 334 uid = gdm_user_get_uid (user); 335 336 g_debug ("Getting list of sessions for user %u", uid); 337 338 error = NULL; 339 res = dbus_g_proxy_call (proxy, 340 "GetSessionsForUnixUser", 341 &error, 342 G_TYPE_UINT, uid, 343 G_TYPE_INVALID, 344 dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), 345 &sessions, 346 G_TYPE_INVALID); 347 if (! res) { 348 if (error != NULL) { 349 g_debug ("Failed to find sessions for user: %s", error->message); 350 g_error_free (error); 351 } else { 352 g_debug ("Failed to find sessions for user"); 353 } 354 goto out; 355 } 356 357 g_debug ("Found %d sessions for user %s", sessions->len, gdm_user_get_user_name (user)); 358 359 for (i = 0; i < sessions->len; i++) { 360 char *ssid; 361 362 ssid = g_ptr_array_index (sessions, i); 363 maybe_add_session_for_user (manager, user, ssid); 364 } 365 366 g_ptr_array_foreach (sessions, (GFunc)g_free, NULL); 367 g_ptr_array_free (sessions, TRUE); 368 369 out: 370 if (proxy != NULL) { 371 g_object_unref (proxy); 372 } 373 } 374 375 static GdmUser * 376 create_user (GdmUserManager *manager) 377 { 378 GdmUser *user; 379 380 user = g_object_new (GDM_TYPE_USER, NULL); 381 g_signal_connect (user, 382 "sessions-changed", 383 G_CALLBACK (on_user_sessions_changed), 384 manager); 385 g_signal_connect (user, 386 "icon-changed", 387 G_CALLBACK (on_user_icon_changed), 388 manager); 389 return user; 390 } 391 392 static void 393 add_user (GdmUserManager *manager, 394 GdmUser *user) 395 { 396 add_sessions_for_user (manager, user); 397 g_hash_table_insert (manager->priv->users, 398 g_strdup (gdm_user_get_user_name (user)), 399 g_object_ref (user)); 400 401 g_signal_emit (manager, signals[USER_ADDED], 0, gdm_user_get_uid (user)); 402 } 403 404 static GdmUser * 405 add_new_user_for_pwent (GdmUserManager *manager, 406 struct passwd *pwent) 407 { 408 GdmUser *user; 409 410 g_debug ("Creating new user"); 411 412 user = create_user (manager); 413 _gdm_user_update (user, pwent); 414 415 add_user (manager, user); 416 417 return user; 418 } 419 420 static char * 421 get_current_seat_id (DBusGConnection *connection) 422 { 423 DBusGProxy *proxy; 424 GError *error; 425 char *session_id; 426 char *seat_id; 427 gboolean res; 428 429 proxy = NULL; 430 session_id = NULL; 431 seat_id = NULL; 432 433 proxy = dbus_g_proxy_new_for_name (connection, 434 CK_NAME, 435 CK_MANAGER_PATH, 436 CK_MANAGER_INTERFACE); 437 if (proxy == NULL) { 438 g_warning ("Failed to connect to the ConsoleKit manager object"); 439 goto out; 440 } 441 442 error = NULL; 443 res = dbus_g_proxy_call (proxy, 444 "GetCurrentSession", 445 &error, 446 G_TYPE_INVALID, 447 DBUS_TYPE_G_OBJECT_PATH, 448 &session_id, 449 G_TYPE_INVALID); 450 if (! res) { 451 if (error != NULL) { 452 g_debug ("Failed to identify the current session: %s", error->message); 453 g_error_free (error); 454 } else { 455 g_debug ("Failed to identify the current session"); 456 } 457 goto out; 458 } 459 460 seat_id = get_seat_id_for_session (connection, session_id); 461 462 out: 463 if (proxy != NULL) { 464 g_object_unref (proxy); 465 } 466 g_free (session_id); 467 468 return seat_id; 469 } 470 471 static gboolean 472 get_uid_from_session_id (GdmUserManager *manager, 473 const char *session_id, 474 uid_t *uidp) 475 { 476 DBusGProxy *proxy; 477 GError *error; 478 guint uid; 479 gboolean res; 480 481 proxy = dbus_g_proxy_new_for_name (manager->priv->connection, 482 CK_NAME, 483 session_id, 484 CK_SESSION_INTERFACE); 485 if (proxy == NULL) { 486 g_warning ("Failed to connect to the ConsoleKit session object"); 487 return FALSE; 488 } 489 490 error = NULL; 491 res = dbus_g_proxy_call (proxy, 492 "GetUnixUser", 493 &error, 494 G_TYPE_INVALID, 495 G_TYPE_UINT, &uid, 496 G_TYPE_INVALID); 497 g_object_unref (proxy); 498 499 if (! res) { 500 if (error != NULL) { 501 g_warning ("Failed to query the session: %s", error->message); 502 g_error_free (error); 503 } else { 504 g_warning ("Failed to query the session"); 505 } 506 return FALSE; 507 } 508 509 if (uidp != NULL) { 510 *uidp = (uid_t) uid; 511 } 512 513 return TRUE; 514 } 515 516 static void 517 seat_session_added (DBusGProxy *seat_proxy, 518 const char *session_id, 519 GdmUserManager *manager) 520 { 521 uid_t uid; 522 gboolean res; 523 struct passwd *pwent; 524 GdmUser *user; 525 gboolean is_new; 526 527 g_debug ("Session added: %s", session_id); 528 529 res = get_uid_from_session_id (manager, session_id, &uid); 530 if (! res) { 531 g_warning ("Unable to lookup user for session"); 532 return; 533 } 534 535 errno = 0; 536 pwent = getpwuid (uid); 537 if (pwent == NULL) { 538 g_warning ("Unable to lookup user id %d: %s", (int)uid, g_strerror (errno)); 539 return; 540 } 541 542 /* check exclusions up front */ 543 if (g_hash_table_lookup (manager->priv->exclusions, pwent->pw_name)) { 544 g_debug ("GdmUserManager: excluding user '%s'", pwent->pw_name); 545 return; 546 } 547 548 user = g_hash_table_lookup (manager->priv->users, pwent->pw_name); 549 if (user == NULL) { 550 g_debug ("Creating new user"); 551 552 user = create_user (manager); 553 _gdm_user_update (user, pwent); 554 is_new = TRUE; 555 } else { 556 is_new = FALSE; 557 } 558 559 res = maybe_add_session_for_user (manager, user, session_id); 560 561 /* only add the user if we added a session */ 562 if (is_new) { 563 if (res) { 564 add_user (manager, user); 565 } else { 566 g_object_unref (user); 567 } 568 } 569 } 570 571 static void 572 seat_session_removed (DBusGProxy *seat_proxy, 573 const char *session_id, 574 GdmUserManager *manager) 575 { 576 GdmUser *user; 577 char *username; 578 579 g_debug ("Session removed: %s", session_id); 580 581 /* since the session object may already be gone 582 * we can't query CK directly */ 583 584 username = g_hash_table_lookup (manager->priv->sessions, session_id); 585 if (username == NULL) { 586 return; 587 } 588 589 user = g_hash_table_lookup (manager->priv->users, username); 590 if (user == NULL) { 591 /* nothing to do */ 592 return; 593 } 594 595 g_debug ("GdmUserManager: Session removed for %s", username); 596 _gdm_user_remove_session (user, session_id); 597 } 598 599 static void 600 on_proxy_destroy (DBusGProxy *proxy, 601 GdmUserManager *manager) 602 { 603 g_debug ("GdmUserManager: seat proxy destroyed"); 604 605 manager->priv->seat_proxy = NULL; 606 } 607 608 static void 609 get_seat_proxy (GdmUserManager *manager) 610 { 611 DBusGProxy *proxy; 612 GError *error; 613 614 g_assert (manager->priv->seat_proxy == NULL); 615 616 error = NULL; 617 manager->priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); 618 if (manager->priv->connection == NULL) { 619 if (error != NULL) { 620 g_warning ("Failed to connect to the D-Bus daemon: %s", error->message); 621 g_error_free (error); 622 } else { 623 g_warning ("Failed to connect to the D-Bus daemon"); 624 } 625 return; 626 } 627 628 manager->priv->seat_id = get_current_seat_id (manager->priv->connection); 629 if (manager->priv->seat_id == NULL) { 630 return; 631 } 632 633 g_debug ("GdmUserManager: Found current seat: %s", manager->priv->seat_id); 634 635 error = NULL; 636 proxy = dbus_g_proxy_new_for_name_owner (manager->priv->connection, 637 CK_NAME, 638 manager->priv->seat_id, 639 CK_SEAT_INTERFACE, 640 &error); 641 642 if (proxy == NULL) { 643 if (error != NULL) { 644 g_warning ("Failed to connect to the ConsoleKit seat object: %s", 645 error->message); 646 g_error_free (error); 647 } else { 648 g_warning ("Failed to connect to the ConsoleKit seat object"); 649 } 650 return; 651 } 652 653 g_signal_connect (proxy, "destroy", G_CALLBACK (on_proxy_destroy), manager); 654 655 dbus_g_proxy_add_signal (proxy, 656 "SessionAdded", 657 DBUS_TYPE_G_OBJECT_PATH, 658 G_TYPE_INVALID); 659 dbus_g_proxy_add_signal (proxy, 660 "SessionRemoved", 661 DBUS_TYPE_G_OBJECT_PATH, 662 G_TYPE_INVALID); 663 dbus_g_proxy_connect_signal (proxy, 664 "SessionAdded", 665 G_CALLBACK (seat_session_added), 666 manager, 667 NULL); 668 dbus_g_proxy_connect_signal (proxy, 669 "SessionRemoved", 670 G_CALLBACK (seat_session_removed), 671 manager, 672 NULL); 673 manager->priv->seat_proxy = proxy; 674 675 } 676 677 /** 678 * gdm_manager_get_user: 679 * @manager: the manager to query. 680 * @username: the login name of the user to get. 681 * 682 * Retrieves a pointer to the #GdmUser object for the login named @username 683 * from @manager. This pointer is not a reference, and should not be released. 684 * 685 * Returns: a pointer to a #GdmUser object. 686 **/ 687 static GdmUser * 688 gdm_user_manager_get_user (GdmUserManager *manager, 689 const char *username) 690 { 691 GdmUser *user; 692 693 g_return_val_if_fail (GDM_IS_USER_MANAGER (manager), NULL); 694 g_return_val_if_fail (username != NULL && username[0] != '\0', NULL); 695 696 user = g_hash_table_lookup (manager->priv->users, username); 697 698 if (user == NULL) { 699 struct passwd *pwent; 700 701 pwent = getpwnam (username); 702 703 if (pwent != NULL) { 704 user = add_new_user_for_pwent (manager, pwent); 705 } 706 } 707 708 return user; 709 } 710 711 static GdmUser * 712 gdm_user_manager_get_user_by_uid (GdmUserManager *manager, 713 uid_t uid) 714 { 715 GdmUser *user; 716 struct passwd *pwent; 717 718 g_return_val_if_fail (GDM_IS_USER_MANAGER (manager), NULL); 719 720 pwent = getpwuid (uid); 721 if (pwent == NULL) { 722 g_warning ("GdmUserManager: unable to lookup uid %d", (int)uid); 723 return NULL; 724 } 725 726 user = g_hash_table_lookup (manager->priv->users, pwent->pw_name); 727 728 if (user == NULL) { 729 user = add_new_user_for_pwent (manager, pwent); 730 } 731 732 return user; 733 } 734 735 static void 736 listify_hash_values_hfunc (gpointer key, 737 gpointer value, 738 gpointer user_data) 739 { 740 GSList **list = user_data; 741 742 *list = g_slist_prepend (*list, value); 743 } 744 745 static gboolean 746 parse_value_as_ulong (const char *value, 747 gulong *ulongval) 748 { 749 char *end_of_valid_long; 750 glong long_value; 751 gulong ulong_value; 752 753 errno = 0; 754 long_value = strtol (value, &end_of_valid_long, 10); 755 756 if (*value == '\0' || *end_of_valid_long != '\0') { 757 return FALSE; 758 } 759 760 ulong_value = long_value; 761 if (ulong_value != long_value || errno == ERANGE) { 762 return FALSE; 763 } 764 765 *ulongval = ulong_value; 766 767 return TRUE; 768 } 769 770 static gboolean 771 parse_ck_history_line (const char *line, 772 char **user_namep, 773 gulong *frequencyp) 774 { 775 GRegex *re; 776 GMatchInfo *match_info; 777 gboolean res; 778 gboolean ret; 779 GError *error; 780 781 ret = FALSE; 782 re = NULL; 783 match_info = NULL; 784 785 error = NULL; 786 re = g_regex_new ("(?P<username>[0-9a-zA-Z]+)[ ]+(?P<frequency>[0-9]+)", 0, 0, &error); 787 if (re == NULL) { 788 if (error != NULL) { 789 g_critical ("%s", error->message); 790 } else { 791 g_critical ("Error in regex call"); 792 } 793 goto out; 794 } 795 796 g_regex_match (re, line, 0, &match_info); 797 798 res = g_match_info_matches (match_info); 799 if (! res) { 800 g_warning ("Unable to parse history: %s", line); 801 goto out; 802 } 803 804 if (user_namep != NULL) { 805 *user_namep = g_match_info_fetch_named (match_info, "username"); 806 } 807 808 if (frequencyp != NULL) { 809 char *freq; 810 freq = g_match_info_fetch_named (match_info, "frequency"); 811 res = parse_value_as_ulong (freq, frequencyp); 812 g_free (freq); 813 if (! res) { 814 goto out; 815 } 816 } 817 818 ret = TRUE; 819 820 out: 821 if (match_info != NULL) { 822 g_match_info_free (match_info); 823 } 824 if (re != NULL) { 825 g_regex_unref (re); 826 } 827 return ret; 828 } 829 830 static void 831 process_ck_history_line (GdmUserManager *manager, 832 const char *line) 833 { 834 gboolean res; 835 char *username; 836 gulong frequency; 837 struct passwd *pwent; 838 GdmUser *user; 839 840 frequency = 0; 841 username = NULL; 842 res = parse_ck_history_line (line, &username, &frequency); 843 if (! res) { 844 return; 845 } 846 847 if (g_hash_table_lookup (manager->priv->exclusions, username)) { 848 g_debug ("GdmUserManager: excluding user '%s'", username); 849 g_free (username); 850 return; 851 } 852 853 /* do not show system users; we cannot use gdm_user_manager_get_user() 854 * here since this creates/signals users as a side effect */ 855 pwent = getpwnam (username); 856 if (pwent == NULL) { 857 g_warning ("Unable to lookup user name %s: %s", username, g_strerror (errno)); 858 return; 859 } 860 if (pwent->pw_uid < DEFAULT_MINIMAL_UID) { 861 g_debug ("GdmUserManager: excluding user '%s'", username); 862 return; 863 } 864 865 user = gdm_user_manager_get_user (manager, username); 866 if (user == NULL) { 867 g_debug ("GdmUserManager: unable to lookup user '%s'", username); 868 g_free (username); 869 return; 870 } 871 872 g_object_set (user, "login-frequency", frequency, NULL); 873 g_signal_emit (manager, signals [USER_UPDATED], 0, gdm_user_get_uid (user)); 874 g_free (username); 875 } 876 877 static gboolean 878 ck_history_watch (GIOChannel *source, 879 GIOCondition condition, 880 GdmUserManager *manager) 881 { 882 GIOStatus status; 883 gboolean done = FALSE; 884 885 g_return_val_if_fail (manager != NULL, FALSE); 886 887 if (condition & G_IO_IN) { 888 char *str; 889 GError *error; 890 891 error = NULL; 892 status = g_io_channel_read_line (source, &str, NULL, NULL, &error); 893 if (error != NULL) { 894 g_warning ("GdmUserManager: unable to read line: %s", error->message); 895 g_error_free (error); 896 } 897 898 if (status == G_IO_STATUS_NORMAL) { 899 g_debug ("GdmUserManager: history output: %s", str); 900 process_ck_history_line (manager, str); 901 } else if (status == G_IO_STATUS_EOF) { 902 done = TRUE; 903 } 904 905 g_free (str); 906 } else if (condition & G_IO_HUP) { 907 done = TRUE; 908 } 909 910 if (done) { 911 FILE *fp; 912 913 /* Cache login counts */ 914 fp = fopen (LOGIN_CACHE_FILE, "w"); 915 if (fp != NULL) { 916 GHashTableIter iter; 917 gpointer value; 918 919 g_hash_table_iter_init (&iter, manager->priv->users); 920 while (g_hash_table_iter_next (&iter, NULL, &value)) { 921 GdmUser *user = (GdmUser *) value; 922 fprintf (fp, "%s %lu\n", 923 gdm_user_get_user_name (user), 924 gdm_user_get_login_frequency (user)); 925 } 926 fclose (fp); 927 } 928 else 929 g_warning ("Unable to write to login cache file: %s", LOGIN_CACHE_FILE); 930 931 manager->priv->ck_history_id = 0; 932 return FALSE; 933 } 934 935 return TRUE; 936 } 937 938 static void 939 reload_ck_history (GdmUserManager *manager) 940 { 941 char *command; 942 const char *seat_id; 943 GError *error; 944 gboolean res; 945 char **argv; 946 int standard_out; 947 GIOChannel *channel; 948 949 seat_id = NULL; 950 if (manager->priv->seat_id != NULL 951 && g_str_has_prefix (manager->priv->seat_id, "/org/freedesktop/ConsoleKit/")) { 952 953 seat_id = manager->priv->seat_id + strlen ("/org/freedesktop/ConsoleKit/"); 954 } 955 956 if (seat_id == NULL) { 957 g_warning ("Unable to find users: no seat-id found"); 958 return; 959 } 960 961 command = g_strdup_printf ("ck-history --frequent --seat='%s' --session-type=''", 962 seat_id); 963 g_debug ("GdmUserManager: running '%s'", command); 964 error = NULL; 965 if (! g_shell_parse_argv (command, NULL, &argv, &error)) { 966 if (error != NULL) { 967 g_warning ("Could not parse command: %s", error->message); 968 g_error_free (error); 969 } else { 970 g_warning ("Could not parse command"); 971 } 972 goto out; 973 } 974 975 error = NULL; 976 res = g_spawn_async_with_pipes (NULL, 977 argv, 978 NULL, 979 G_SPAWN_SEARCH_PATH, 980 NULL, 981 NULL, 982 NULL, /* pid */ 983 NULL, 984 &standard_out, 985 NULL, 986 &error); 987 g_strfreev (argv); 988 if (! res) { 989 if (error != NULL) { 990 g_warning ("Unable to run ck-history: %s", error->message); 991 g_error_free (error); 992 } else { 993 g_warning ("Unable to run ck-history"); 994 } 995 goto out; 996 } 997 998 channel = g_io_channel_unix_new (standard_out); 999 g_io_channel_set_close_on_unref (channel, TRUE); 1000 g_io_channel_set_flags (channel, 1001 g_io_channel_get_flags (channel) | G_IO_FLAG_NONBLOCK, 1002 NULL); 1003 manager->priv->ck_history_id = g_io_add_watch (channel, 1004 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, 1005 (GIOFunc)ck_history_watch, 1006 manager); 1007 g_io_channel_unref (channel); 1008 1009 out: 1010 g_free (command); 1011 } 1012 1013 static void 1014 reload_passwd (GdmUserManager *manager) 1015 { 1016 struct passwd *pwent; 1017 GSList *old_users; 1018 GSList *new_users; 1019 GSList *list; 1020 FILE *fp; 1021 1022 old_users = NULL; 1023 new_users = NULL; 1024 1025 errno = 0; 1026 fp = fopen (PATH_PASSWD, "r"); 1027 if (fp == NULL) { 1028 g_warning ("Unable to open %s: %s", PATH_PASSWD, g_strerror (errno)); 1029 goto out; 1030 } 1031 1032 g_hash_table_foreach (manager->priv->users, listify_hash_values_hfunc, &old_users); 1033 g_slist_foreach (old_users, (GFunc) g_object_ref, NULL); 1034 1035 /* Make sure we keep users who are logged in no matter what. */ 1036 for (list = old_users; list; list = list->next) { 1037 if (gdm_user_get_num_sessions (list->data) > 0) { 1038 g_object_freeze_notify (G_OBJECT (list->data)); 1039 new_users = g_slist_prepend (new_users, g_object_ref (list->data)); 1040 } 1041 } 1042 1043 for (pwent = fgetpwent (fp); pwent != NULL; pwent = fgetpwent (fp)) { 1044 GdmUser *user; 1045 1046 user = NULL; 1047 1048 /* Skip users below MinimalUID... */ 1049 if (pwent->pw_uid < DEFAULT_MINIMAL_UID) { 1050 continue; 1051 } 1052 1053 /* ...And users w/ invalid shells... */ 1054 if (pwent->pw_shell == NULL || 1055 !g_hash_table_lookup (manager->priv->shells, pwent->pw_shell)) { 1056 g_debug ("GdmUserManager: skipping user with bad shell: %s", pwent->pw_name); 1057 continue; 1058 } 1059 1060 /* ...And explicitly excluded users */ 1061 if (g_hash_table_lookup (manager->priv->exclusions, pwent->pw_name)) { 1062 g_debug ("GdmUserManager: explicitly skipping user: %s", pwent->pw_name); 1063 continue; 1064 } 1065 1066 user = g_hash_table_lookup (manager->priv->users, pwent->pw_name); 1067 1068 /* Update users already in the *new* list */ 1069 if (g_slist_find (new_users, user)) { 1070 _gdm_user_update (user, pwent); 1071 continue; 1072 } 1073 1074 if (user == NULL) { 1075 user = create_user (manager); 1076 } else { 1077 g_object_ref (user); 1078 } 1079 1080 /* Freeze & update users not already in the new list */ 1081 g_object_freeze_notify (G_OBJECT (user)); 1082 _gdm_user_update (user, pwent); 1083 1084 new_users = g_slist_prepend (new_users, user); 1085 } 1086 1087 /* Go through and handle removed users */ 1088 for (list = old_users; list; list = list->next) { 1089 if (! g_slist_find (new_users, list->data)) { 1090 g_signal_emit (manager, signals[USER_REMOVED], 0, gdm_user_get_uid (GDM_USER (list->data))); 1091 g_hash_table_remove (manager->priv->users, 1092 gdm_user_get_user_name (list->data)); 1093 } 1094 } 1095 1096 /* Go through and handle added users */ 1097 for (list = new_users; list; list = list->next) { 1098 if (!g_slist_find (old_users, list->data)) { 1099 add_user (manager, list->data); 1100 } 1101 } 1102 1103 if (!manager->priv->loaded_passwd) { 1104 g_signal_emit (manager, signals[USERS_LOADED], 0); 1105 manager->priv->loaded_passwd = TRUE; 1106 } 1107 1108 out: 1109 /* Cleanup */ 1110 1111 fclose (fp); 1112 1113 g_slist_foreach (new_users, (GFunc) g_object_thaw_notify, NULL); 1114 g_slist_foreach (new_users, (GFunc) g_object_unref, NULL); 1115 g_slist_free (new_users); 1116 1117 g_slist_foreach (old_users, (GFunc) g_object_unref, NULL); 1118 g_slist_free (old_users); 1119 } 1120 1121 static void 1122 load_login_frequency_cache (GdmUserManager *manager) 1123 { 1124 GIOChannel *channel; 1125 gchar *line; 1126 1127 channel = g_io_channel_new_file (LOGIN_CACHE_FILE, "r", NULL); 1128 if (channel == NULL) 1129 return; 1130 1131 while (g_io_channel_read_line (channel, &line, NULL, NULL, NULL) == G_IO_STATUS_NORMAL) { 1132 process_ck_history_line (manager, line); 1133 g_free (line); 1134 } 1135 1136 g_io_channel_close (channel); 1137 } 1138 1139 static void 1140 reload_users (GdmUserManager *manager) 1141 { 1142 reload_passwd (manager); 1143 if (!manager->priv->loaded_cache) { 1144 load_login_frequency_cache (manager); 1145 manager->priv->loaded_cache = TRUE; 1146 } 1147 reload_ck_history (manager); 1148 } 1149 1150 static gboolean 1151 reload_users_timeout (GdmUserManager *manager) 1152 { 1153 reload_users (manager); 1154 manager->priv->reload_id = 0; 1155 1156 return FALSE; 1157 } 1158 1159 static void 1160 queue_reload_users (GdmUserManager *manager) 1161 { 1162 if (manager->priv->reload_id > 0) { 1163 return; 1164 } 1165 1166 manager->priv->reload_id = g_idle_add ((GSourceFunc)reload_users_timeout, manager); 1167 } 1168 1169 static void 1170 reload_shells (GdmUserManager *manager) 1171 { 1172 char *shell; 1173 1174 setusershell (); 1175 1176 g_hash_table_remove_all (manager->priv->shells); 1177 for (shell = getusershell (); shell != NULL; shell = getusershell ()) { 1178 /* skip well known not-real shells */ 1179 if (shell == NULL 1180 || strcmp (shell, "/sbin/nologin") == 0 1181 || strcmp (shell, "/bin/false") == 0) { 1182 g_debug ("GdmUserManager: skipping shell %s", shell); 1183 continue; 1184 } 1185 g_hash_table_insert (manager->priv->shells, 1186 g_strdup (shell), 1187 GUINT_TO_POINTER (TRUE)); 1188 } 1189 1190 endusershell (); 1191 } 1192 1193 static void 1194 on_shells_monitor_changed (GFileMonitor *monitor, 1195 GFile *file, 1196 GFile *other_file, 1197 GFileMonitorEvent event_type, 1198 GdmUserManager *manager) 1199 { 1200 if (event_type != G_FILE_MONITOR_EVENT_CHANGED && 1201 event_type != G_FILE_MONITOR_EVENT_CREATED) { 1202 return; 1203 } 1204 1205 reload_shells (manager); 1206 reload_passwd (manager); 1207 } 1208 1209 static void 1210 on_passwd_monitor_changed (GFileMonitor *monitor, 1211 GFile *file, 1212 GFile *other_file, 1213 GFileMonitorEvent event_type, 1214 GdmUserManager *manager) 1215 { 1216 if (event_type != G_FILE_MONITOR_EVENT_CHANGED && 1217 event_type != G_FILE_MONITOR_EVENT_CREATED) { 1218 return; 1219 } 1220 1221 reload_passwd (manager); 1222 } 1223 1224 static void 1225 gdm_user_manager_class_init (GdmUserManagerClass *klass) 1226 { 1227 GObjectClass *object_class = G_OBJECT_CLASS (klass); 1228 1229 object_class->finalize = gdm_user_manager_finalize; 1230 1231 signals [USERS_LOADED] = 1232 g_signal_new ("users-loaded", 1233 G_TYPE_FROM_CLASS (klass), 1234 G_SIGNAL_RUN_LAST, 1235 G_STRUCT_OFFSET (GdmUserManagerClass, users_loaded), 1236 NULL, NULL, 1237 g_cclosure_marshal_VOID__OBJECT, 1238 G_TYPE_NONE, 0); 1239 signals [USER_ADDED] = 1240 g_signal_new ("user-added", 1241 G_TYPE_FROM_CLASS (klass), 1242 G_SIGNAL_RUN_LAST, 1243 G_STRUCT_OFFSET (GdmUserManagerClass, user_added), 1244 NULL, NULL, 1245 g_cclosure_marshal_VOID__OBJECT, 1246 G_TYPE_NONE, 1, G_TYPE_INT64); 1247 signals [USER_REMOVED] = 1248 g_signal_new ("user-removed", 1249 G_TYPE_FROM_CLASS (klass), 1250 G_SIGNAL_RUN_LAST, 1251 G_STRUCT_OFFSET (GdmUserManagerClass, user_removed), 1252 NULL, NULL, 1253 g_cclosure_marshal_VOID__OBJECT, 1254 G_TYPE_NONE, 1, G_TYPE_INT64); 1255 signals [USER_UPDATED] = 1256 g_signal_new ("user-updated", 1257 G_TYPE_FROM_CLASS (klass), 1258 G_SIGNAL_RUN_LAST, 1259 G_STRUCT_OFFSET (GdmUserManagerClass, user_updated), 1260 NULL, NULL, 1261 g_cclosure_marshal_VOID__OBJECT, 1262 G_TYPE_NONE, 1, G_TYPE_INT64); 1263 1264 g_type_class_add_private (klass, sizeof (GdmUserManagerPrivate)); 1265 1266 dbus_g_object_type_install_info (GDM_TYPE_USER_MANAGER, &dbus_glib_gdm_user_manager_object_info); 1267 } 1268 1269 static void 1270 gdm_user_manager_init (GdmUserManager *manager) 1271 { 1272 int i; 1273 GFile *file; 1274 GError *error; 1275 const char *exclude_default[] = DEFAULT_EXCLUDE; 1276 1277 manager->priv = GDM_USER_MANAGER_GET_PRIVATE (manager); 1278 1279 /* sessions */ 1280 manager->priv->sessions = g_hash_table_new_full (g_str_hash, 1281 g_str_equal, 1282 g_free, 1283 g_free); 1284 1285 /* exclusions */ 1286 manager->priv->exclusions = g_hash_table_new_full (g_str_hash, 1287 g_str_equal, 1288 g_free, 1289 NULL); 1290 for (i = 0; exclude_default[i] != NULL; i++) { 1291 g_hash_table_insert (manager->priv->exclusions, 1292 g_strdup (exclude_default [i]), 1293 GUINT_TO_POINTER (TRUE)); 1294 } 1295 1296 /* /etc/shells */ 1297 manager->priv->shells = g_hash_table_new_full (g_str_hash, 1298 g_str_equal, 1299 g_free, 1300 NULL); 1301 reload_shells (manager); 1302 file = g_file_new_for_path (_PATH_SHELLS); 1303 error = NULL; 1304 manager->priv->shells_monitor = g_file_monitor_file (file, 1305 G_FILE_MONITOR_NONE, 1306 NULL, 1307 &error); 1308 if (manager->priv->shells_monitor != NULL) { 1309 g_signal_connect (manager->priv->shells_monitor, 1310 "changed", 1311 G_CALLBACK (on_shells_monitor_changed), 1312 manager); 1313 } else { 1314 g_warning ("Unable to monitor %s: %s", _PATH_SHELLS, error->message); 1315 g_error_free (error); 1316 } 1317 g_object_unref (file); 1318 1319 /* /etc/passwd */ 1320 manager->priv->users = g_hash_table_new_full (g_str_hash, 1321 g_str_equal, 1322 g_free, 1323 (GDestroyNotify) g_object_run_dispose); 1324 file = g_file_new_for_path (PATH_PASSWD); 1325 manager->priv->passwd_monitor = g_file_monitor_file (file, 1326 G_FILE_MONITOR_NONE, 1327 NULL, 1328 &error); 1329 if (manager->priv->passwd_monitor != NULL) { 1330 g_signal_connect (manager->priv->passwd_monitor, 1331 "changed", 1332 G_CALLBACK (on_passwd_monitor_changed), 1333 manager); 1334 } else { 1335 g_warning ("Unable to monitor %s: %s", PATH_PASSWD, error->message); 1336 g_error_free (error); 1337 } 1338 g_object_unref (file); 1339 1340 1341 get_seat_proxy (manager); 1342 1343 queue_reload_users (manager); 1344 1345 dbus_g_connection_register_g_object (manager->priv->connection, GDM_USER_MANAGER_DBUS_PATH, G_OBJECT (manager)); 1346 } 1347 1348 static void 1349 gdm_user_manager_finalize (GObject *object) 1350 { 1351 GdmUserManager *manager; 1352 1353 g_return_if_fail (object != NULL); 1354 g_return_if_fail (GDM_IS_USER_MANAGER (object)); 1355 1356 manager = GDM_USER_MANAGER (object); 1357 1358 g_return_if_fail (manager->priv != NULL); 1359 1360 if (manager->priv->seat_proxy != NULL) { 1361 g_object_unref (manager->priv->seat_proxy); 1362 } 1363 1364 if (manager->priv->ck_history_id != 0) { 1365 g_source_remove (manager->priv->ck_history_id); 1366 manager->priv->ck_history_id = 0; 1367 } 1368 1369 if (manager->priv->reload_id > 0) { 1370 g_source_remove (manager->priv->reload_id); 1371 manager->priv->reload_id = 0; 1372 } 1373 1374 g_hash_table_destroy (manager->priv->sessions); 1375 1376 g_file_monitor_cancel (manager->priv->passwd_monitor); 1377 g_hash_table_destroy (manager->priv->users); 1378 1379 g_file_monitor_cancel (manager->priv->shells_monitor); 1380 g_hash_table_destroy (manager->priv->shells); 1381 1382 g_free (manager->priv->seat_id); 1383 1384 G_OBJECT_CLASS (gdm_user_manager_parent_class)->finalize (object); 1385 } 1386 1387 GdmUserManager * 1388 gdm_user_manager_new (void) 1389 { 1390 return GDM_USER_MANAGER (g_object_new (GDM_TYPE_USER_MANAGER, NULL)); 1391 } 1392 1393 /* 1394 Example: 1395 dbus-send --system --print-reply --dest=org.gnome.DisplayManager \ 1396 /org/gnome/DisplayManager/UserManager org.gnome.DisplayManager.UserManager.CountUsers 1397 */ 1398 gboolean 1399 gdm_user_manager_count_users (GdmUserManager *user_manager, 1400 gint *user_count, 1401 GError **error) 1402 { 1403 *user_count = g_hash_table_size (user_manager->priv->users); 1404 1405 return TRUE; 1406 } 1407 1408 /* 1409 Example: 1410 dbus-send --system --print-reply --dest=org.gnome.DisplayManager \ 1411 /org/gnome/DisplayManager/UserManager org.gnome.DisplayManager.UserManager.GetUserList 1412 */ 1413 gboolean 1414 gdm_user_manager_get_user_list (GdmUserManager *user_manager, 1415 GArray **user_list, 1416 GError **error) 1417 { 1418 GHashTableIter iter; 1419 GdmUser *user; 1420 1421 *user_list = g_array_new (FALSE, FALSE, sizeof (gint64)); 1422 g_hash_table_iter_init (&iter, user_manager->priv->users); 1423 while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&user)) { 1424 gint64 uid = gdm_user_get_uid (user); 1425 g_array_append_val (*user_list, uid); 1426 } 1427 1428 return TRUE; 1429 } 1430 1431 1432 /* 1433 Example: 1434 dbus-send --system --print-reply --dest=org.gnome.DisplayManager \ 1435 /org/gnome/DisplayManager/UserManager org.gnome.DisplayManager.UserManager.GetUserInfo int64:1000 1436 */ 1437 gboolean 1438 gdm_user_manager_get_user_info (GdmUserManager *user_manager, 1439 gint64 uid, 1440 gchar **user_name, 1441 gchar **real_name, 1442 gchar **shell, 1443 gint *login_count, 1444 gchar **icon_url, 1445 GError **error) 1446 { 1447 GdmUser *user; 1448 1449 user = gdm_user_manager_get_user_by_uid (user_manager, uid); 1450 if (user == NULL) 1451 return FALSE; 1452 1453 *user_name = g_strdup (gdm_user_get_user_name (user)); 1454 *real_name = g_strdup (gdm_user_get_real_name (user)); 1455 *login_count = gdm_user_get_login_frequency (user); 1456 *shell = g_strdup (gdm_user_get_shell (user)); 1457 *icon_url = g_strdup (gdm_user_get_icon_url (user)); 1458 1459 return TRUE; 1460 } 1461 1462 /* 1463 Example: 1464 dbus-send --system --print-reply --dest=org.gnome.DisplayManager \ 1465 /org/gnome/DisplayManager/UserManager org.gnome.DisplayManager.UserManager.GetUsersInfo array:int64:1000,1001 1466 */ 1467 gboolean 1468 gdm_user_manager_get_users_info (GdmUserManager *user_manager, 1469 GArray *uids, 1470 GPtrArray **users_info, 1471 GError **error) 1472 { 1473 int i; 1474 1475 *users_info = g_ptr_array_new (); 1476 1477 for (i = 0; i < uids->len; i++) { 1478 gint64 uid; 1479 GdmUser *user; 1480 GValueArray *user_info; 1481 GValue arg = {0}; 1482 1483 uid = g_array_index (uids, gint64, i); 1484 user = gdm_user_manager_get_user_by_uid (user_manager, uid); 1485 if (user == NULL) 1486 continue; 1487 1488 user_info = g_value_array_new (5); 1489 1490 g_value_init (&arg, G_TYPE_INT64); 1491 g_value_set_int64 (&arg, uid); 1492 g_value_array_append (user_info, &arg); 1493 g_value_unset (&arg); 1494 1495 g_value_init (&arg, G_TYPE_STRING); 1496 g_value_set_string (&arg, gdm_user_get_user_name (user)); 1497 g_value_array_append (user_info, &arg); 1498 g_value_unset (&arg); 1499 1500 g_value_init (&arg, G_TYPE_STRING); 1501 g_value_set_string (&arg, gdm_user_get_real_name (user)); 1502 g_value_array_append (user_info, &arg); 1503 g_value_unset (&arg); 1504 1505 g_value_init (&arg, G_TYPE_STRING); 1506 g_value_set_string (&arg, gdm_user_get_shell (user)); 1507 g_value_array_append (user_info, &arg); 1508 g_value_unset (&arg); 1509 1510 g_value_init (&arg, G_TYPE_INT); 1511 g_value_set_int (&arg, gdm_user_get_login_frequency (user)); 1512 g_value_array_append (user_info, &arg); 1513 g_value_unset (&arg); 1514 1515 g_value_init (&arg, G_TYPE_STRING); 1516 g_value_set_string (&arg, gdm_user_get_icon_url (user)); 1517 g_value_array_append (user_info, &arg); 1518 g_value_unset (&arg); 1519 1520 g_ptr_array_add (*users_info, user_info); 1521 } 1522 1523 return TRUE; 1524 } 1525 1526 /* 1527 Example: 1528 dbus-send --system --print-reply --dest=org.gnome.DisplayManager \ 1529 /org/gnome/DisplayManager/UserManager org.gnome.DisplayManager.UserManager.GetUsersLoaded 1530 */ 1531 gboolean 1532 gdm_user_manager_get_users_loaded (GdmUserManager *user_manager, 1533 gboolean *is_loaded, 1534 GError **error) 1535 { 1536 *is_loaded = user_manager->priv->loaded_passwd; 1537 return TRUE; 1538 } -
daemon/gdm-user-manager.h
diff -Nur -x '*.orig' -x '*~' gdm-2.28.0/daemon/gdm-user-manager.h gdm-2.28.0.new/daemon/gdm-user-manager.h
old new 1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- 2 * 3 * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 * 19 */ 20 21 #ifndef __GDM_USER_MANAGER_H 22 #define __GDM_USER_MANAGER_H 23 24 #include <glib-object.h> 25 26 #include "gdm-user.h" 27 28 G_BEGIN_DECLS 29 30 #define GDM_TYPE_USER_MANAGER (gdm_user_manager_get_type ()) 31 #define GDM_USER_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_USER_MANAGER, GdmUserManager)) 32 #define GDM_USER_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_USER_MANAGER, GdmUserManagerClass)) 33 #define GDM_IS_USER_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_USER_MANAGER)) 34 #define GDM_IS_USER_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_USER_MANAGER)) 35 #define GDM_USER_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_USER_MANAGER, GdmUserManagerClass)) 36 37 typedef struct GdmUserManagerPrivate GdmUserManagerPrivate; 38 39 typedef struct 40 { 41 GObject parent; 42 GdmUserManagerPrivate *priv; 43 } GdmUserManager; 44 45 typedef struct 46 { 47 GObjectClass parent_class; 48 49 void (* users_loaded) (GdmUserManager *user_manager); 50 void (* user_added) (GdmUserManager *user_manager, 51 gint64 uid); 52 void (* user_removed) (GdmUserManager *user_manager, 53 gint64 uid); 54 void (* user_updated) (GdmUserManager *user_manager, 55 gint64 uid); 56 } GdmUserManagerClass; 57 58 #define GDM_USER_MANAGER_ERROR gdm_user_manager_error_quark () 59 60 GQuark gdm_user_manager_error_quark (void); 61 GType gdm_user_manager_get_type (void); 62 63 GdmUserManager * gdm_user_manager_new (void); 64 65 gboolean gdm_user_manager_count_users (GdmUserManager *user_manager, 66 gint *user_count, 67 GError **error); 68 69 gboolean gdm_user_manager_get_user_list (GdmUserManager *user_manager, 70 GArray **user_list, 71 GError **error); 72 73 gboolean gdm_user_manager_get_user_info (GdmUserManager *user_manager, 74 gint64 uid, 75 gchar **user_name, 76 gchar **real_name, 77 gchar **shell, 78 gint *login_count, 79 gchar **icon_url, 80 GError **error); 81 82 gboolean gdm_user_manager_get_users_info (GdmUserManager *user_manager, 83 GArray *uids, 84 GPtrArray **user_info, 85 GError **error); 86 87 gboolean gdm_user_manager_get_users_loaded (GdmUserManager *user_manager, 88 gboolean *is_loaded, 89 GError **error); 90 91 G_END_DECLS 92 93 #endif /* __GDM_USER_MANAGER_H */ -
daemon/gdm-user-manager.xml
diff -Nur -x '*.orig' -x '*~' gdm-2.28.0/daemon/gdm-user-manager.xml gdm-2.28.0.new/daemon/gdm-user-manager.xml
old new 1 <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> 2 <node name="/org/gnome/DisplayManager/UserManager"> 3 <interface name="org.gnome.DisplayManager.UserManager"> 4 5 <!-- Get the number of known users --> 6 <method name="CountUsers"> 7 <arg name="user_count" direction="out" type="i"/> 8 </method> 9 10 <!-- Get the list of known UIDs --> 11 <method name="GetUserList"> 12 <arg name="uids" direction="out" type="ax"/> 13 </method> 14 15 <!-- Get user info for a user --> 16 <method name="GetUserInfo"> 17 <arg name="uid" direction="in" type="x"/> 18 <arg name="user_name" direction="out" type="s"/> 19 <arg name="real_name" direction="out" type="s"/> 20 <arg name="shell" direction="out" type="s"/> 21 <arg name="login_count" direction="out" type="i"/> 22 <arg name="icon_url" direction="out" type="s"/> 23 </method> 24 25 <!-- Get user info for a list of users --> 26 <method name="GetUsersInfo"> 27 <arg name="uid" direction="in" type="ax"/> 28 <!-- (uid, user_name, real_name, shell, login_count, icon_url) --> 29 <arg name="user_info" direction="out" type="a(xsssis)"/> 30 </method> 31 32 <!-- Query if the initial user list is loaded --> 33 <method name="GetUsersLoaded"> 34 <arg name="is_loaded" direction="out" type="b"/> 35 </method> 36 37 <!-- Triggered when the initial user list is loaded --> 38 <signal name="UsersLoaded" /> 39 40 <!-- Triggered when a users are added to/removed from the system. 41 Clients should monitor these signals as soon as they connect to 42 this object --> 43 <signal name="UserAdded"> 44 <arg name="uid" type="x"/> 45 </signal> 46 <signal name="UserRemoved"> 47 <arg name="uid" type="x"/> 48 </signal> 49 50 <!-- Triggered when a user has updated information --> 51 <signal name="UserUpdated"> 52 <arg name="uid" type="x"/> 53 </signal> 54 55 </interface> 56 </node> -
daemon/gdm-user-private.h
diff -Nur -x '*.orig' -x '*~' gdm-2.28.0/daemon/gdm-user-private.h gdm-2.28.0.new/daemon/gdm-user-private.h
old new 1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- 2 * 3 * Copyright (C) 2004-2005 James M. Cape <jcape@ignore-your.tv>. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 */ 19 20 /* 21 * Private interfaces to the GdmUser object 22 */ 23 24 #ifndef __GDM_USER_PRIVATE__ 25 #define __GDM_USER_PRIVATE__ 1 26 27 #include <pwd.h> 28 29 #include "gdm-user.h" 30 31 G_BEGIN_DECLS 32 33 void _gdm_user_update (GdmUser *user, 34 const struct passwd *pwent); 35 void _gdm_user_add_session (GdmUser *user, 36 const char *session_id); 37 void _gdm_user_remove_session (GdmUser *user, 38 const char *session_id); 39 40 G_END_DECLS 41 42 #endif /* !__GDM_USER_PRIVATE__ */ -
daemon/main.c
diff -Nur -x '*.orig' -x '*~' gdm-2.28.0/daemon/main.c gdm-2.28.0.new/daemon/main.c
old new 43 43 #include <dbus/dbus-glib.h> 44 44 #include <dbus/dbus-glib-lowlevel.h> 45 45 46 #include "gdm-user-manager.h" 46 47 #include "gdm-manager.h" 47 48 #include "gdm-log.h" 48 49 #include "gdm-common.h" … … 59 60 60 61 extern char **environ; 61 62 63 static GdmUserManager *user_manager = NULL; 62 64 static GdmManager *manager = NULL; 63 65 static GdmSettings *settings = NULL; 64 66 static uid_t gdm_uid = -1; … … 576 578 goto out; 577 579 } 578 580 581 user_manager = gdm_user_manager_new (); 582 if (user_manager == NULL) { 583 g_warning ("Could not construct user manager object"); 584 exit (1); 585 } 586 579 587 if (! gdm_settings_direct_init (settings, GDMCONFDIR "/gdm.schemas", "/")) { 580 588 g_warning ("Unable to initialize settings"); 581 589 goto out; -
daemon/Makefile.am
diff -Nur -x '*.orig' -x '*~' gdm-2.28.0/daemon/Makefile.am gdm-2.28.0.new/daemon/Makefile.am
old new 9 9 -DDATADIR=\"$(datadir)\" \ 10 10 -DDMCONFDIR=\"$(dmconfdir)\" \ 11 11 -DGDMCONFDIR=\"$(gdmconfdir)\" \ 12 -DCACHEDIR=\"$(cachedir)\" \ 12 13 -DLIBDIR=\"$(libdir)\" \ 13 14 -DLIBEXECDIR=\"$(libexecdir)\" \ 14 15 -DLOGDIR=\"$(logdir)\" \ … … 34 35 gdm-session-direct-glue.h \ 35 36 gdm-manager-glue.h \ 36 37 gdm-display-glue.h \ 38 gdm-user-manager-glue.h \ 37 39 gdm-xdmcp-greeter-display-glue.h \ 38 40 gdm-xdmcp-chooser-display-glue.h \ 39 41 gdm-static-display-glue.h \ … … 45 47 46 48 gdm-manager-glue.h: gdm-manager.xml Makefile.am 47 49 dbus-binding-tool --prefix=gdm_manager --mode=glib-server --output=gdm-manager-glue.h $(srcdir)/gdm-manager.xml 50 gdm-user-manager-glue.h: gdm-user-manager.xml Makefile.am 51 dbus-binding-tool --prefix=gdm_user_manager --mode=glib-server --output=gdm-user-manager-glue.h $(srcdir)/gdm-user-manager.xml 48 52 gdm-slave-glue.h: gdm-slave.xml Makefile.am 49 53 dbus-binding-tool --prefix=gdm_slave --mode=glib-server --output=gdm-slave-glue.h $(srcdir)/gdm-slave.xml 50 54 gdm-simple-slave-glue.h: gdm-simple-slave.xml Makefile.am … … 303 307 gdm-product-display.h \ 304 308 gdm-manager.c \ 305 309 gdm-manager.h \ 310 gdm-user.c \ 311 gdm-user.h \ 312 gdm-user-private.h \ 313 gdm-user-manager.c \ 314 gdm-user-manager.h \ 306 315 gdm-slave-proxy.c \ 307 316 gdm-slave-proxy.h \ 308 317 $(NULL) … … 365 374 gdm-session-direct.xml \ 366 375 gdm-manager.xml \ 367 376 gdm-display.xml \ 377 gdm-user-manager.xml \ 368 378 gdm-xdmcp-greeter-display.xml \ 369 379 gdm-xdmcp-chooser-display.xml \ 370 380 gdm-static-display.xml \ -
data/gdm.conf.in
diff -Nur -x '*.orig' -x '*~' gdm-2.28.0/data/gdm.conf.in gdm-2.28.0.new/data/gdm.conf.in
old new 8 8 <allow own="org.gnome.DisplayManager"/> 9 9 10 10 <allow send_destination="org.gnome.DisplayManager" 11 send_interface="org.gnome.DisplayManager.UserManager"/> 12 <allow send_destination="org.gnome.DisplayManager" 11 13 send_interface="org.gnome.DisplayManager.Manager"/> 12 14 <allow send_destination="org.gnome.DisplayManager" 13 15 send_interface="org.gnome.DisplayManager.Display"/> … … 28 30 29 31 <policy context="default"> 30 32 <deny send_destination="org.gnome.DisplayManager" 33 send_interface="org.gnome.DisplayManager.UserManager"/> 34 <deny send_destination="org.gnome.DisplayManager" 31 35 send_interface="org.gnome.DisplayManager.Manager"/> 32 36 <deny send_destination="org.gnome.DisplayManager" 33 37 send_interface="org.gnome.DisplayManager.Display"/> … … 71 75 <allow send_destination="org.gnome.DisplayManager" 72 76 send_interface="org.gnome.DisplayManager.LocalDisplayFactory" 73 77 send_member="StartGuestSession"/> 78 79 <allow send_destination="org.gnome.DisplayManager" 80 send_interface="org.gnome.DisplayManager.UserManager" 81 send_member="CountUsers"/> 82 <allow send_destination="org.gnome.DisplayManager" 83 send_interface="org.gnome.DisplayManager.UserManager" 84 send_member="GetUsersLoaded"/> 85 <allow send_destination="org.gnome.DisplayManager" 86 send_interface="org.gnome.DisplayManager.UserManager" 87 send_member="GetUserList"/> 88 <allow send_destination="org.gnome.DisplayManager" 89 send_interface="org.gnome.DisplayManager.UserManager" 90 send_member="GetUserInfo"/> 91 <allow send_destination="org.gnome.DisplayManager" 92 send_interface="org.gnome.DisplayManager.UserManager" 93 send_member="GetUsersInfo"/> 74 94 75 95 <allow send_destination="org.gnome.DisplayManager" 76 96 send_interface="org.gnome.DisplayManager.Manager" … … 80 100 81 101 <policy user="@GDM_USERNAME@"> 82 102 <allow send_destination="org.gnome.DisplayManager" 103 send_interface="org.gnome.DisplayManager.UserManager"/> 104 <allow send_destination="org.gnome.DisplayManager" 83 105 send_interface="org.gnome.DisplayManager.Manager"/> 84 106 <allow send_destination="org.gnome.DisplayManager" 85 107 send_interface="org.gnome.DisplayManager.Display"/>
Note: See TracBrowser
for help on using the repository browser.