9 #include <security/pam_appl.h>
18 #include <gio/gunixsocketaddress.h>
20 #define LOGIN_PROMPT "login:"
22 static int console_fd = -1;
24 static GList *user_entries = NULL;
25 static GList *getpwent_link = NULL;
27 static GList *group_entries = NULL;
29 static int active_vt = 7;
39 struct pam_conv conversation;
55 initgroups (const char *user, gid_t group)
66 getgroups (int size, gid_t list[])
68 const gchar *group_list;
72 /* Get groups we are a member of */
73 group_list = g_getenv ("LIGHTDM_TEST_GROUPS");
76 groups = g_strsplit (group_list, ",", -1);
77 groups_length = g_strv_length (groups);
83 if (groups_length > size)
88 for (i = 0; groups[i]; i++)
89 list[i] = atoi (groups[i]);
97 setgroups (size_t size, const gid_t *list)
102 group_list = g_string_new ("");
103 for (i = 0; i < size; i++)
106 g_string_append (group_list, ",");
107 g_string_append_printf (group_list, "%d", list[i]);
109 g_setenv ("LIGHTDM_TEST_GROUPS", group_list->str, TRUE);
110 g_string_free (group_list, TRUE);
128 setresgid (gid_t rgid, gid_t ugid, gid_t sgid)
146 setresuid (uid_t ruid, uid_t uuid, uid_t suid)
152 redirect_path (const gchar *path)
157 // Don't redirect if inside the running directory
158 if (g_str_has_prefix (path, g_getenv ("LIGHTDM_TEST_ROOT")))
159 return g_strdup (path);
161 // Don't redirect if inside the build directory
162 if (g_str_has_prefix (path, BUILDDIR))
163 return g_strdup (path);
165 if (g_str_has_prefix (path, "/tmp"))
166 return g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "tmp", path + strlen ("tmp"), NULL);
168 if (g_str_has_prefix (path, SYSCONFDIR))
169 return g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "etc", path + strlen (SYSCONFDIR), NULL);
171 if (g_str_has_prefix (path, LOCALSTATEDIR))
172 return g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "var", path + strlen (LOCALSTATEDIR), NULL);
174 return g_strdup (path);
179 open_wrapper (const char *func, const char *pathname, int flags, mode_t mode)
181 int (*_open) (const char *pathname, int flags, mode_t mode);
182 gchar *new_path = NULL;
185 _open = (int (*)(const char *pathname, int flags, mode_t mode)) dlsym (RTLD_NEXT, func);
187 if (strcmp (pathname, "/dev/console") == 0)
191 console_fd = _open ("/dev/null", flags, mode);
192 fcntl (console_fd, F_SETFD, FD_CLOEXEC);
197 new_path = redirect_path (pathname);
198 fd = _open (new_path, flags, mode);
205 open (const char *pathname, int flags, ...)
211 va_start (ap, flags);
212 mode = va_arg (ap, mode_t);
215 return open_wrapper ("open", pathname, flags, mode);
219 open64 (const char *pathname, int flags, ...)
225 va_start (ap, flags);
226 mode = va_arg (ap, mode_t);
229 return open_wrapper ("open64", pathname, flags, mode);
233 fopen (const char *path, const char *mode)
235 FILE *(*_fopen) (const char *pathname, const char *mode);
236 gchar *new_path = NULL;
239 _fopen = (FILE *(*)(const char *pathname, const char *mode)) dlsym (RTLD_NEXT, "fopen");
241 new_path = redirect_path (path);
242 result = _fopen (new_path, mode);
249 creat (const char *pathname, mode_t mode)
251 int (*_creat) (const char *pathname, mode_t mode);
252 gchar *new_path = NULL;
255 _creat = (int (*)(const char *pathname, mode_t mode)) dlsym (RTLD_NEXT, "creat");
257 new_path = redirect_path (pathname);
258 result = _creat (new_path, mode);
265 creat64 (const char *pathname, mode_t mode)
267 int (*_creat64) (const char *pathname, mode_t mode);
268 gchar *new_path = NULL;
271 _creat64 = (int (*)(const char *pathname, mode_t mode)) dlsym (RTLD_NEXT, "creat64");
273 new_path = redirect_path (pathname);
274 result = _creat64 (new_path, mode);
281 access (const char *pathname, int mode)
283 int (*_access) (const char *pathname, int mode);
284 gchar *new_path = NULL;
287 _access = (int (*)(const char *pathname, int mode)) dlsym (RTLD_NEXT, "access");
289 new_path = redirect_path (pathname);
290 ret = _access (new_path, mode);
297 stat (const char *path, struct stat *buf)
299 int (*_stat) (const char *path, struct stat *buf);
300 gchar *new_path = NULL;
303 _stat = (int (*)(const char *path, struct stat *buf)) dlsym (RTLD_NEXT, "stat");
305 new_path = redirect_path (path);
306 ret = _stat (new_path, buf);
313 stat64 (const char *path, struct stat *buf)
315 int (*_stat64) (const char *path, struct stat *buf);
316 gchar *new_path = NULL;
319 _stat64 = (int (*)(const char *path, struct stat *buf)) dlsym (RTLD_NEXT, "stat64");
321 new_path = redirect_path (path);
322 ret = _stat (new_path, buf);
329 __xstat (int version, const char *path, struct stat *buf)
331 int (*___xstat) (int version, const char *path, struct stat *buf);
332 gchar *new_path = NULL;
335 ___xstat = (int (*)(int version, const char *path, struct stat *buf)) dlsym (RTLD_NEXT, "__xstat");
337 new_path = redirect_path (path);
338 ret = ___xstat (version, new_path, buf);
345 __xstat64 (int version, const char *path, struct stat *buf)
347 int (*___xstat64) (int version, const char *path, struct stat *buf);
348 gchar *new_path = NULL;
351 ___xstat64 = (int (*)(int version, const char *path, struct stat *buf)) dlsym (RTLD_NEXT, "__xstat64");
353 new_path = redirect_path (path);
354 ret = ___xstat64 (version, new_path, buf);
361 mkdir (const char *pathname, mode_t mode)
363 int (*_mkdir) (const char *pathname, mode_t mode);
364 gchar *new_path = NULL;
367 _mkdir = (int (*)(const char *pathname, mode_t mode)) dlsym (RTLD_NEXT, "mkdir");
369 new_path = redirect_path (pathname);
370 result = _mkdir (new_path, mode);
377 chown (const char *pathname, uid_t owner, gid_t group)
379 int (*_chown) (const char *pathname, uid_t owner, gid_t group);
380 gchar *new_path = NULL;
383 _chown = (int (*)(const char *pathname, uid_t owner, gid_t group)) dlsym (RTLD_NEXT, "chown");
385 new_path = redirect_path (pathname);
386 result = _chown (new_path, owner, group);
393 ioctl (int d, int request, void *data)
395 int (*_ioctl) (int d, int request, void *data);
397 _ioctl = (int (*)(int d, int request, void *data)) dlsym (RTLD_NEXT, "ioctl");
398 if (d > 0 && d == console_fd)
400 struct vt_stat *console_state;
406 console_state = data;
407 console_state->v_active = active_vt;
410 active_vt = GPOINTER_TO_INT (data);
418 return _ioctl (d, request, data);
424 int (*_close) (int fd);
426 if (fd > 0 && fd == console_fd)
429 _close = (int (*)(int fd)) dlsym (RTLD_NEXT, "close");
435 free_user (gpointer data)
437 struct passwd *entry = data;
439 g_free (entry->pw_name);
440 g_free (entry->pw_passwd);
441 g_free (entry->pw_gecos);
442 g_free (entry->pw_dir);
443 g_free (entry->pw_shell);
450 gchar *path, *data = NULL, **lines;
452 GError *error = NULL;
454 g_list_free_full (user_entries, free_user);
456 getpwent_link = NULL;
458 path = g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "etc", "passwd", NULL);
459 g_file_get_contents (path, &data, NULL, &error);
462 g_warning ("Error loading passwd file: %s", error->message);
463 g_clear_error (&error);
468 lines = g_strsplit (data, "\n", -1);
471 for (i = 0; lines[i]; i++)
473 gchar *line, **fields;
475 line = g_strstrip (lines[i]);
476 fields = g_strsplit (line, ":", -1);
477 if (g_strv_length (fields) == 7)
479 struct passwd *entry = malloc (sizeof (struct passwd));
481 entry->pw_name = g_strdup (fields[0]);
482 entry->pw_passwd = g_strdup (fields[1]);
483 entry->pw_uid = atoi (fields[2]);
484 entry->pw_gid = atoi (fields[3]);
485 entry->pw_gecos = g_strdup (fields[4]);
486 entry->pw_dir = g_strdup (fields[5]);
487 entry->pw_shell = g_strdup (fields[6]);
488 user_entries = g_list_append (user_entries, entry);
498 if (getpwent_link == NULL)
501 if (user_entries == NULL)
503 getpwent_link = user_entries;
507 if (getpwent_link->next == NULL)
509 getpwent_link = getpwent_link->next;
512 return getpwent_link->data;
518 getpwent_link = NULL;
524 getpwent_link = NULL;
528 getpwnam (const char *name)
537 for (link = user_entries; link; link = link->next)
539 struct passwd *entry = link->data;
540 if (strcmp (entry->pw_name, name) == 0)
556 for (link = user_entries; link; link = link->next)
558 struct passwd *entry = link->data;
559 if (entry->pw_uid == uid)
569 free_group (gpointer data)
571 struct group *entry = data;
573 g_free (entry->gr_name);
574 g_free (entry->gr_passwd);
575 g_strfreev (entry->gr_mem);
582 gchar *path, *data = NULL, **lines;
584 GError *error = NULL;
586 g_list_free_full (group_entries, free_group);
587 group_entries = NULL;
589 path = g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "etc", "group", NULL);
590 g_file_get_contents (path, &data, NULL, &error);
593 g_warning ("Error loading group file: %s", error->message);
594 g_clear_error (&error);
599 lines = g_strsplit (data, "\n", -1);
602 for (i = 0; lines[i]; i++)
604 gchar *line, **fields;
606 line = g_strstrip (lines[i]);
607 fields = g_strsplit (line, ":", -1);
608 if (g_strv_length (fields) == 4)
610 struct group *entry = malloc (sizeof (struct group));
612 entry->gr_name = g_strdup (fields[0]);
613 entry->gr_passwd = g_strdup (fields[1]);
614 entry->gr_gid = atoi (fields[2]);
615 entry->gr_mem = g_strsplit (fields[3], ",", -1);
616 group_entries = g_list_append (group_entries, entry);
624 getgrnam (const char *name)
630 for (link = group_entries; link; link = link->next)
632 struct group *entry = link->data;
633 if (strcmp (entry->gr_name, name) == 0)
649 for (link = group_entries; link; link = link->next)
651 struct group *entry = link->data;
652 if (entry->gr_gid == gid)
662 pam_start (const char *service_name, const char *user, const struct pam_conv *conversation, pam_handle_t **pamh)
664 pam_handle_t *handle;
666 if (service_name == NULL || conversation == NULL || pamh == NULL)
667 return PAM_SYSTEM_ERR;
669 handle = *pamh = malloc (sizeof (pam_handle_t));
673 handle->service_name = strdup (service_name);
674 handle->user = user ? strdup (user) : NULL;
675 handle->authtok = NULL;
676 handle->ruser = NULL;
678 handle->conversation.conv = conversation->conv;
679 handle->conversation.appdata_ptr = conversation->appdata_ptr;
680 handle->envlist = malloc (sizeof (char *) * 1);
681 handle->envlist[0] = NULL;
687 send_info (pam_handle_t *pamh, const char *message)
689 struct pam_message **msg;
690 struct pam_response *resp = NULL;
692 msg = calloc (1, sizeof (struct pam_message *));
693 msg[0] = malloc (sizeof (struct pam_message));
694 msg[0]->msg_style = PAM_TEXT_INFO;
695 msg[0]->msg = message;
696 pamh->conversation.conv (1, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr);
708 pam_authenticate (pam_handle_t *pamh, int flags)
710 struct passwd *entry;
711 gboolean password_matches = FALSE;
714 return PAM_SYSTEM_ERR;
716 if (strcmp (pamh->service_name, "test-remote") == 0)
719 struct pam_message **msg;
720 struct pam_response *resp = NULL;
722 msg = malloc (sizeof (struct pam_message *) * 1);
723 msg[0] = malloc (sizeof (struct pam_message));
724 msg[0]->msg_style = PAM_PROMPT_ECHO_ON;
725 msg[0]->msg = "remote-login:";
726 result = pamh->conversation.conv (1, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr);
729 if (result != PAM_SUCCESS)
734 if (resp[0].resp == NULL)
742 pamh->ruser = strdup (resp[0].resp);
746 msg = malloc (sizeof (struct pam_message *) * 1);
747 msg[0] = malloc (sizeof (struct pam_message));
748 msg[0]->msg_style = PAM_PROMPT_ECHO_OFF;
749 msg[0]->msg = "remote-password:";
750 result = pamh->conversation.conv (1, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr);
753 if (result != PAM_SUCCESS)
758 if (resp[0].resp == NULL)
765 free (pamh->authtok);
766 pamh->authtok = strdup (resp[0].resp);
770 password_matches = strcmp (pamh->ruser, "remote-user") == 0 && strcmp (pamh->authtok, "password") == 0;
772 if (password_matches)
778 /* Prompt for username */
779 if (pamh->user == NULL)
782 struct pam_message **msg;
783 struct pam_response *resp = NULL;
785 msg = malloc (sizeof (struct pam_message *) * 1);
786 msg[0] = malloc (sizeof (struct pam_message));
787 msg[0]->msg_style = PAM_PROMPT_ECHO_ON;
788 msg[0]->msg = LOGIN_PROMPT;
789 result = pamh->conversation.conv (1, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr);
792 if (result != PAM_SUCCESS)
797 if (resp[0].resp == NULL)
803 pamh->user = strdup (resp[0].resp);
808 if (strcmp (pamh->user, "log-pam") == 0)
809 send_info (pamh, "pam_authenticate");
811 /* Crash on authenticate */
812 if (strcmp (pamh->user, "crash-authenticate") == 0)
813 kill (getpid (), SIGSEGV);
815 /* Look up password database */
816 entry = getpwnam (pamh->user);
818 /* Prompt for password if required */
819 if (entry && strcmp (pamh->user, "always-password") != 0 && (strcmp (pamh->service_name, "lightdm-autologin") == 0 || strcmp (entry->pw_passwd, "") == 0))
820 password_matches = TRUE;
823 int i, n_messages = 0, password_index, result;
824 struct pam_message **msg;
825 struct pam_response *resp = NULL;
827 msg = malloc (sizeof (struct pam_message *) * 5);
828 if (strcmp (pamh->user, "info-prompt") == 0)
830 msg[n_messages] = malloc (sizeof (struct pam_message));
831 msg[n_messages]->msg_style = PAM_TEXT_INFO;
832 msg[n_messages]->msg = "Welcome to LightDM";
835 if (strcmp (pamh->user, "multi-info-prompt") == 0)
837 msg[n_messages] = malloc (sizeof (struct pam_message));
838 msg[n_messages]->msg_style = PAM_TEXT_INFO;
839 msg[n_messages]->msg = "Welcome to LightDM";
841 msg[n_messages] = malloc (sizeof (struct pam_message));
842 msg[n_messages]->msg_style = PAM_ERROR_MSG;
843 msg[n_messages]->msg = "This is an error";
845 msg[n_messages] = malloc (sizeof (struct pam_message));
846 msg[n_messages]->msg_style = PAM_TEXT_INFO;
847 msg[n_messages]->msg = "You should have seen three messages";
850 if (strcmp (pamh->user, "multi-prompt") == 0)
852 msg[n_messages] = malloc (sizeof (struct pam_message));
853 msg[n_messages]->msg_style = PAM_PROMPT_ECHO_ON;
854 msg[n_messages]->msg = "Favorite Color:";
857 msg[n_messages] = malloc (sizeof (struct pam_message));
858 msg[n_messages]->msg_style = PAM_PROMPT_ECHO_OFF;
859 msg[n_messages]->msg = "Password:";
860 password_index = n_messages;
862 result = pamh->conversation.conv (n_messages, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr);
863 for (i = 0; i < n_messages; i++)
866 if (result != PAM_SUCCESS)
871 if (resp[password_index].resp == NULL)
878 password_matches = strcmp (entry->pw_passwd, resp[password_index].resp) == 0;
880 if (password_matches && strcmp (pamh->user, "multi-prompt") == 0)
881 password_matches = strcmp ("blue", resp[0].resp) == 0;
883 for (i = 0; i < n_messages; i++)
890 /* Do two factor authentication */
891 if (password_matches && strcmp (pamh->user, "two-factor") == 0)
893 msg = malloc (sizeof (struct pam_message *) * 1);
894 msg[0] = malloc (sizeof (struct pam_message));
895 msg[0]->msg_style = PAM_PROMPT_ECHO_ON;
896 msg[0]->msg = "OTP:";
898 result = pamh->conversation.conv (1, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr);
904 if (resp[0].resp == NULL)
909 password_matches = strcmp (resp[0].resp, "otp") == 0;
915 /* Special user has home directory created on login */
916 if (password_matches && strcmp (pamh->user, "mount-home-dir") == 0)
917 g_mkdir_with_parents (entry->pw_dir, 0755);
919 /* Special user 'change-user1' changes user on authentication */
920 if (password_matches && strcmp (pamh->user, "change-user1") == 0)
923 pamh->user = g_strdup ("change-user2");
926 /* Special user 'change-user-invalid' changes to an invalid user on authentication */
927 if (password_matches && strcmp (pamh->user, "change-user-invalid") == 0)
930 pamh->user = g_strdup ("invalid-user");
933 if (password_matches)
940 get_env_value (const char *name_value, const char *name)
944 for (j = 0; name[j] && name[j] != '=' && name[j] == name_value[j]; j++);
945 if (name_value[j] == '=')
946 return &name_value[j + 1];
952 pam_putenv (pam_handle_t *pamh, const char *name_value)
956 if (pamh == NULL || name_value == NULL)
957 return PAM_SYSTEM_ERR;
959 for (i = 0; pamh->envlist[i]; i++)
961 if (get_env_value (pamh->envlist[i], name_value))
965 if (pamh->envlist[i])
967 free (pamh->envlist[i]);
968 pamh->envlist[i] = strdup (name_value);
972 pamh->envlist = realloc (pamh->envlist, sizeof (char *) * (i + 2));
973 pamh->envlist[i] = strdup (name_value);
974 pamh->envlist[i + 1] = NULL;
981 pam_getenv (pam_handle_t *pamh, const char *name)
985 if (pamh == NULL || name == NULL)
988 for (i = 0; pamh->envlist[i]; i++)
991 value = get_env_value (pamh->envlist[i], name);
1000 pam_getenvlist (pam_handle_t *pamh)
1005 return pamh->envlist;
1009 pam_set_item (pam_handle_t *pamh, int item_type, const void *item)
1011 if (pamh == NULL || item == NULL)
1012 return PAM_SYSTEM_ERR;
1019 pamh->tty = strdup ((const char *) item);
1023 return PAM_BAD_ITEM;
1028 pam_get_item (const pam_handle_t *pamh, int item_type, const void **item)
1030 if (pamh == NULL || item == NULL)
1031 return PAM_SYSTEM_ERR;
1036 *item = pamh->service_name;
1044 *item = pamh->authtok;
1048 *item = pamh->ruser;
1051 case PAM_USER_PROMPT:
1052 *item = LOGIN_PROMPT;
1060 *item = &pamh->conversation;
1064 return PAM_BAD_ITEM;
1069 pam_open_session (pam_handle_t *pamh, int flags)
1072 return PAM_SYSTEM_ERR;
1074 if (strcmp (pamh->user, "session-error") == 0)
1075 return PAM_SESSION_ERR;
1077 if (strcmp (pamh->user, "log-pam") == 0)
1078 send_info (pamh, "pam_open_session");
1080 if (strcmp (pamh->user, "make-home-dir") == 0)
1082 struct passwd *entry;
1083 entry = getpwnam (pamh->user);
1084 g_mkdir_with_parents (entry->pw_dir, 0755);
1091 pam_close_session (pam_handle_t *pamh, int flags)
1094 return PAM_SYSTEM_ERR;
1096 if (strcmp (pamh->user, "log-pam") == 0)
1097 send_info (pamh, "pam_close_session");
1103 pam_acct_mgmt (pam_handle_t *pamh, int flags)
1106 return PAM_SYSTEM_ERR;
1109 return PAM_USER_UNKNOWN;
1111 if (strcmp (pamh->user, "log-pam") == 0)
1112 send_info (pamh, "pam_acct_mgmt");
1114 if (strcmp (pamh->user, "denied") == 0)
1115 return PAM_PERM_DENIED;
1116 if (strcmp (pamh->user, "expired") == 0)
1117 return PAM_ACCT_EXPIRED;
1118 if (strcmp (pamh->user, "new-authtok") == 0)
1119 return PAM_NEW_AUTHTOK_REQD;
1125 pam_chauthtok (pam_handle_t *pamh, int flags)
1127 struct passwd *entry;
1129 struct pam_message **msg;
1130 struct pam_response *resp = NULL;
1133 return PAM_SYSTEM_ERR;
1135 if (strcmp (pamh->user, "log-pam") == 0)
1136 send_info (pamh, "pam_chauthtok");
1138 msg = malloc (sizeof (struct pam_message *) * 1);
1139 msg[0] = malloc (sizeof (struct pam_message));
1140 msg[0]->msg_style = PAM_PROMPT_ECHO_OFF;
1141 msg[0]->msg = "Enter new password:";
1142 result = pamh->conversation.conv (1, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr);
1145 if (result != PAM_SUCCESS)
1149 return PAM_CONV_ERR;
1150 if (resp[0].resp == NULL)
1153 return PAM_CONV_ERR;
1156 /* Update password database */
1157 entry = getpwnam (pamh->user);
1158 free (entry->pw_passwd);
1159 entry->pw_passwd = resp[0].resp;
1166 pam_setcred (pam_handle_t *pamh, int flags)
1171 return PAM_SYSTEM_ERR;
1173 if (strcmp (pamh->user, "log-pam") == 0)
1174 send_info (pamh, "pam_setcred");
1176 /* Put the test directories into the path */
1177 e = g_strdup_printf ("PATH=%s/tests/src/.libs:%s/tests/src:%s/tests/src:%s/src:%s", BUILDDIR, BUILDDIR, SRCDIR, BUILDDIR, pam_getenv (pamh, "PATH"));
1178 pam_putenv (pamh, e);
1181 if (strcmp (pamh->user, "cred-error") == 0)
1182 return PAM_CRED_ERR;
1183 if (strcmp (pamh->user, "cred-expired") == 0)
1184 return PAM_CRED_EXPIRED;
1185 if (strcmp (pamh->user, "cred-unavail") == 0)
1186 return PAM_CRED_UNAVAIL;
1188 /* Join special groups if requested */
1189 if (strcmp (pamh->user, "group-member") == 0 && flags & PAM_ESTABLISH_CRED)
1191 struct group *group;
1195 group = getgrnam ("test-group");
1198 groups_length = getgroups (0, NULL);
1199 groups = malloc (sizeof (gid_t) * (groups_length + 1));
1200 groups_length = getgroups (groups_length, groups);
1201 groups[groups_length] = group->gr_gid;
1203 setgroups (groups_length, groups);
1207 /* We need to pass our group overrides down the child process - the environment via PAM seems the only way to do it easily */
1208 pam_putenv (pamh, g_strdup_printf ("LIGHTDM_TEST_GROUPS=%s", g_getenv ("LIGHTDM_TEST_GROUPS")));
1215 pam_end (pam_handle_t *pamh, int pam_status)
1218 return PAM_SYSTEM_ERR;
1220 free (pamh->service_name);
1224 free (pamh->authtok);
1235 pam_strerror (pam_handle_t *pamh, int errnum)
1245 return "Critical error - immediate abort";
1247 return "Failed to load module";
1248 case PAM_SYMBOL_ERR:
1249 return "Symbol not found";
1250 case PAM_SERVICE_ERR:
1251 return "Error in service module";
1252 case PAM_SYSTEM_ERR:
1253 return "System error";
1255 return "Memory buffer error";
1256 case PAM_PERM_DENIED:
1257 return "Permission denied";
1259 return "Authentication failure";
1260 case PAM_CRED_INSUFFICIENT:
1261 return "Insufficient credentials to access authentication data";
1262 case PAM_AUTHINFO_UNAVAIL:
1263 return "Authentication service cannot retrieve authentication info";
1264 case PAM_USER_UNKNOWN:
1265 return "User not known to the underlying authentication module";
1267 return "Have exhausted maximum number of retries for service";
1268 case PAM_NEW_AUTHTOK_REQD:
1269 return "Authentication token is no longer valid; new one required";
1270 case PAM_ACCT_EXPIRED:
1271 return "User account has expired";
1272 case PAM_SESSION_ERR:
1273 return "Cannot make/remove an entry for the specified session";
1274 case PAM_CRED_UNAVAIL:
1275 return "Authentication service cannot retrieve user credentials";
1276 case PAM_CRED_EXPIRED:
1277 return "User credentials expired";
1279 return "Failure setting user credentials";
1280 case PAM_NO_MODULE_DATA:
1281 return "No module specific data is present";
1283 return "Bad item passed to pam_*_item()";
1285 return "Conversation error";
1286 case PAM_AUTHTOK_ERR:
1287 return "Authentication token manipulation error";
1288 case PAM_AUTHTOK_RECOVERY_ERR:
1289 return "Authentication information cannot be recovered";
1290 case PAM_AUTHTOK_LOCK_BUSY:
1291 return "Authentication token lock busy";
1292 case PAM_AUTHTOK_DISABLE_AGING:
1293 return "Authentication token aging disabled";
1295 return "Failed preliminary check by password service";
1297 return "The return value should be ignored by PAM dispatch";
1298 case PAM_MODULE_UNKNOWN:
1299 return "Module is unknown";
1300 case PAM_AUTHTOK_EXPIRED:
1301 return "Authentication token expired";
1302 case PAM_CONV_AGAIN:
1303 return "Conversation is waiting for event";
1304 case PAM_INCOMPLETE:
1305 return "Application needs to call libpam again";
1307 return "Unknown PAM error";
1317 pututxline (struct utmp *ut)
1327 struct xcb_connection_t
1335 xcb_connect_to_display_with_auth_info (const char *display, xcb_auth_info_t *auth, int *screen)
1337 xcb_connection_t *c;
1339 GSocketAddress *address;
1340 GError *error = NULL;
1342 c = malloc (sizeof (xcb_connection_t));
1343 c->display = g_strdup (display);
1346 if (display == NULL)
1347 display = getenv ("DISPLAY");
1348 if (display == NULL)
1349 c->error = XCB_CONN_CLOSED_PARSE_ERR;
1353 c->socket = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, &error);
1355 g_printerr ("%s\n", error->message);
1356 g_clear_error (&error);
1357 if (c->socket == NULL)
1358 c->error = XCB_CONN_ERROR;
1365 /* Skip the hostname, we'll assume it's localhost */
1366 d = g_strdup_printf (".x%s", strchr (display, ':'));
1368 socket_path = g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), d, NULL);
1370 address = g_unix_socket_address_new (socket_path);
1371 if (!g_socket_connect (c->socket, address, NULL, &error))
1372 c->error = XCB_CONN_ERROR;
1374 g_printerr ("Failed to connect to X socket %s: %s\n", socket_path, error->message);
1375 g_free (socket_path);
1376 g_clear_error (&error);
1379 // FIXME: Send auth info
1384 g_object_unref (address);
1390 xcb_connect (const char *displayname, int *screenp)
1392 return xcb_connect_to_display_with_auth_info(displayname, NULL, screenp);
1396 xcb_connection_has_error (xcb_connection_t *c)
1402 xcb_disconnect (xcb_connection_t *c)
1406 g_object_unref (c->socket);