10 #include <security/pam_appl.h>
19 #include <gio/gunixsocketaddress.h>
21 #define LOGIN_PROMPT "login:"
23 static int console_fd = -1;
25 static GList *user_entries = NULL;
26 static GList *getpwent_link = NULL;
28 static GList *group_entries = NULL;
30 static int active_vt = 7;
40 struct pam_conv conversation;
56 initgroups (const char *user, gid_t group)
67 getgroups (int size, gid_t list[])
69 const gchar *group_list;
73 /* Get groups we are a member of */
74 group_list = g_getenv ("LIGHTDM_TEST_GROUPS");
77 groups = g_strsplit (group_list, ",", -1);
78 groups_length = g_strv_length (groups);
84 if (groups_length > size)
89 for (i = 0; groups[i]; i++)
90 list[i] = atoi (groups[i]);
98 setgroups (size_t size, const gid_t *list)
103 group_list = g_string_new ("");
104 for (i = 0; i < size; i++)
107 g_string_append (group_list, ",");
108 g_string_append_printf (group_list, "%d", list[i]);
110 g_setenv ("LIGHTDM_TEST_GROUPS", group_list->str, TRUE);
111 g_string_free (group_list, TRUE);
129 setresgid (gid_t rgid, gid_t ugid, gid_t sgid)
147 setresuid (uid_t ruid, uid_t uuid, uid_t suid)
153 redirect_path (const gchar *path)
158 // Don't redirect if inside the running directory
159 if (g_str_has_prefix (path, g_getenv ("LIGHTDM_TEST_ROOT")))
160 return g_strdup (path);
162 if (g_str_has_prefix (path, SYSCONFDIR))
163 return g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "etc", path + strlen (SYSCONFDIR), NULL);
165 if (g_str_has_prefix (path, LOCALSTATEDIR))
166 return g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "var", path + strlen (LOCALSTATEDIR), NULL);
168 // Don't redirect if inside the build directory
169 if (g_str_has_prefix (path, BUILDDIR))
170 return g_strdup (path);
172 if (g_str_has_prefix (path, "/tmp"))
173 return g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "tmp", path + strlen ("tmp"), NULL);
175 return g_strdup (path);
180 open_wrapper (const char *func, const char *pathname, int flags, mode_t mode)
182 int (*_open) (const char *pathname, int flags, mode_t mode);
183 gchar *new_path = NULL;
186 _open = (int (*)(const char *pathname, int flags, mode_t mode)) dlsym (RTLD_NEXT, func);
188 if (strcmp (pathname, "/dev/console") == 0)
192 console_fd = _open ("/dev/null", flags, mode);
193 fcntl (console_fd, F_SETFD, FD_CLOEXEC);
198 new_path = redirect_path (pathname);
199 fd = _open (new_path, flags, mode);
206 open (const char *pathname, int flags, ...)
212 va_start (ap, flags);
213 mode = va_arg (ap, mode_t);
216 return open_wrapper ("open", pathname, flags, mode);
220 open64 (const char *pathname, int flags, ...)
226 va_start (ap, flags);
227 mode = va_arg (ap, mode_t);
230 return open_wrapper ("open64", pathname, flags, mode);
234 fopen (const char *path, const char *mode)
236 FILE *(*_fopen) (const char *pathname, const char *mode);
237 gchar *new_path = NULL;
240 _fopen = (FILE *(*)(const char *pathname, const char *mode)) dlsym (RTLD_NEXT, "fopen");
242 new_path = redirect_path (path);
243 result = _fopen (new_path, mode);
250 creat (const char *pathname, mode_t mode)
252 int (*_creat) (const char *pathname, mode_t mode);
253 gchar *new_path = NULL;
256 _creat = (int (*)(const char *pathname, mode_t mode)) dlsym (RTLD_NEXT, "creat");
258 new_path = redirect_path (pathname);
259 result = _creat (new_path, mode);
266 creat64 (const char *pathname, mode_t mode)
268 int (*_creat64) (const char *pathname, mode_t mode);
269 gchar *new_path = NULL;
272 _creat64 = (int (*)(const char *pathname, mode_t mode)) dlsym (RTLD_NEXT, "creat64");
274 new_path = redirect_path (pathname);
275 result = _creat64 (new_path, mode);
282 access (const char *pathname, int mode)
284 int (*_access) (const char *pathname, int mode);
285 gchar *new_path = NULL;
288 _access = (int (*)(const char *pathname, int mode)) dlsym (RTLD_NEXT, "access");
290 new_path = redirect_path (pathname);
291 ret = _access (new_path, mode);
298 stat (const char *path, struct stat *buf)
300 int (*_stat) (const char *path, struct stat *buf);
301 gchar *new_path = NULL;
304 _stat = (int (*)(const char *path, struct stat *buf)) dlsym (RTLD_NEXT, "stat");
306 new_path = redirect_path (path);
307 ret = _stat (new_path, buf);
314 stat64 (const char *path, struct stat *buf)
316 int (*_stat64) (const char *path, struct stat *buf);
317 gchar *new_path = NULL;
320 _stat64 = (int (*)(const char *path, struct stat *buf)) dlsym (RTLD_NEXT, "stat64");
322 new_path = redirect_path (path);
323 ret = _stat (new_path, buf);
330 __xstat (int version, const char *path, struct stat *buf)
332 int (*___xstat) (int version, const char *path, struct stat *buf);
333 gchar *new_path = NULL;
336 ___xstat = (int (*)(int version, const char *path, struct stat *buf)) dlsym (RTLD_NEXT, "__xstat");
338 new_path = redirect_path (path);
339 ret = ___xstat (version, new_path, buf);
346 __xstat64 (int version, const char *path, struct stat *buf)
348 int (*___xstat64) (int version, const char *path, struct stat *buf);
349 gchar *new_path = NULL;
352 ___xstat64 = (int (*)(int version, const char *path, struct stat *buf)) dlsym (RTLD_NEXT, "__xstat64");
354 new_path = redirect_path (path);
355 ret = ___xstat64 (version, new_path, buf);
362 opendir (const char *name)
364 DIR *(*_opendir) (const char *name);
365 gchar *new_path = NULL;
368 _opendir = (DIR *(*)(const char *name)) dlsym (RTLD_NEXT, "opendir");
370 new_path = redirect_path (name);
371 result = _opendir (new_path);
378 mkdir (const char *pathname, mode_t mode)
380 int (*_mkdir) (const char *pathname, mode_t mode);
381 gchar *new_path = NULL;
384 _mkdir = (int (*)(const char *pathname, mode_t mode)) dlsym (RTLD_NEXT, "mkdir");
386 new_path = redirect_path (pathname);
387 result = _mkdir (new_path, mode);
394 chown (const char *pathname, uid_t owner, gid_t group)
396 int (*_chown) (const char *pathname, uid_t owner, gid_t group);
397 gchar *new_path = NULL;
400 _chown = (int (*)(const char *pathname, uid_t owner, gid_t group)) dlsym (RTLD_NEXT, "chown");
402 new_path = redirect_path (pathname);
403 result = _chown (new_path, owner, group);
410 ioctl (int d, int request, void *data)
412 int (*_ioctl) (int d, int request, void *data);
414 _ioctl = (int (*)(int d, int request, void *data)) dlsym (RTLD_NEXT, "ioctl");
415 if (d > 0 && d == console_fd)
417 struct vt_stat *console_state;
423 console_state = data;
424 console_state->v_active = active_vt;
427 active_vt = GPOINTER_TO_INT (data);
435 return _ioctl (d, request, data);
441 int (*_close) (int fd);
443 if (fd > 0 && fd == console_fd)
446 _close = (int (*)(int fd)) dlsym (RTLD_NEXT, "close");
452 free_user (gpointer data)
454 struct passwd *entry = data;
456 g_free (entry->pw_name);
457 g_free (entry->pw_passwd);
458 g_free (entry->pw_gecos);
459 g_free (entry->pw_dir);
460 g_free (entry->pw_shell);
467 gchar *path, *data = NULL, **lines;
469 GError *error = NULL;
471 g_list_free_full (user_entries, free_user);
473 getpwent_link = NULL;
475 path = g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "etc", "passwd", NULL);
476 g_file_get_contents (path, &data, NULL, &error);
479 g_warning ("Error loading passwd file: %s", error->message);
480 g_clear_error (&error);
485 lines = g_strsplit (data, "\n", -1);
488 for (i = 0; lines[i]; i++)
490 gchar *line, **fields;
492 line = g_strstrip (lines[i]);
493 fields = g_strsplit (line, ":", -1);
494 if (g_strv_length (fields) == 7)
496 struct passwd *entry = malloc (sizeof (struct passwd));
498 entry->pw_name = g_strdup (fields[0]);
499 entry->pw_passwd = g_strdup (fields[1]);
500 entry->pw_uid = atoi (fields[2]);
501 entry->pw_gid = atoi (fields[3]);
502 entry->pw_gecos = g_strdup (fields[4]);
503 entry->pw_dir = g_strdup (fields[5]);
504 entry->pw_shell = g_strdup (fields[6]);
505 user_entries = g_list_append (user_entries, entry);
515 if (getpwent_link == NULL)
518 if (user_entries == NULL)
520 getpwent_link = user_entries;
524 if (getpwent_link->next == NULL)
526 getpwent_link = getpwent_link->next;
529 return getpwent_link->data;
535 getpwent_link = NULL;
541 getpwent_link = NULL;
545 getpwnam (const char *name)
554 for (link = user_entries; link; link = link->next)
556 struct passwd *entry = link->data;
557 if (strcmp (entry->pw_name, name) == 0)
573 for (link = user_entries; link; link = link->next)
575 struct passwd *entry = link->data;
576 if (entry->pw_uid == uid)
586 free_group (gpointer data)
588 struct group *entry = data;
590 g_free (entry->gr_name);
591 g_free (entry->gr_passwd);
592 g_strfreev (entry->gr_mem);
599 gchar *path, *data = NULL, **lines;
601 GError *error = NULL;
603 g_list_free_full (group_entries, free_group);
604 group_entries = NULL;
606 path = g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "etc", "group", NULL);
607 g_file_get_contents (path, &data, NULL, &error);
610 g_warning ("Error loading group file: %s", error->message);
611 g_clear_error (&error);
616 lines = g_strsplit (data, "\n", -1);
619 for (i = 0; lines[i]; i++)
621 gchar *line, **fields;
623 line = g_strstrip (lines[i]);
624 fields = g_strsplit (line, ":", -1);
625 if (g_strv_length (fields) == 4)
627 struct group *entry = malloc (sizeof (struct group));
629 entry->gr_name = g_strdup (fields[0]);
630 entry->gr_passwd = g_strdup (fields[1]);
631 entry->gr_gid = atoi (fields[2]);
632 entry->gr_mem = g_strsplit (fields[3], ",", -1);
633 group_entries = g_list_append (group_entries, entry);
641 getgrnam (const char *name)
647 for (link = group_entries; link; link = link->next)
649 struct group *entry = link->data;
650 if (strcmp (entry->gr_name, name) == 0)
666 for (link = group_entries; link; link = link->next)
668 struct group *entry = link->data;
669 if (entry->gr_gid == gid)
679 pam_start (const char *service_name, const char *user, const struct pam_conv *conversation, pam_handle_t **pamh)
681 pam_handle_t *handle;
683 if (service_name == NULL || conversation == NULL || pamh == NULL)
684 return PAM_SYSTEM_ERR;
686 handle = *pamh = malloc (sizeof (pam_handle_t));
690 handle->service_name = strdup (service_name);
691 handle->user = user ? strdup (user) : NULL;
692 handle->authtok = NULL;
693 handle->ruser = NULL;
695 handle->conversation.conv = conversation->conv;
696 handle->conversation.appdata_ptr = conversation->appdata_ptr;
697 handle->envlist = malloc (sizeof (char *) * 1);
698 handle->envlist[0] = NULL;
704 send_info (pam_handle_t *pamh, const char *message)
706 struct pam_message **msg;
707 struct pam_response *resp = NULL;
709 msg = calloc (1, sizeof (struct pam_message *));
710 msg[0] = malloc (sizeof (struct pam_message));
711 msg[0]->msg_style = PAM_TEXT_INFO;
712 msg[0]->msg = message;
713 pamh->conversation.conv (1, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr);
725 pam_authenticate (pam_handle_t *pamh, int flags)
727 struct passwd *entry;
728 gboolean password_matches = FALSE;
731 return PAM_SYSTEM_ERR;
733 if (strcmp (pamh->service_name, "test-remote") == 0)
736 struct pam_message **msg;
737 struct pam_response *resp = NULL;
739 msg = malloc (sizeof (struct pam_message *) * 1);
740 msg[0] = malloc (sizeof (struct pam_message));
741 msg[0]->msg_style = PAM_PROMPT_ECHO_ON;
742 msg[0]->msg = "remote-login:";
743 result = pamh->conversation.conv (1, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr);
746 if (result != PAM_SUCCESS)
751 if (resp[0].resp == NULL)
759 pamh->ruser = strdup (resp[0].resp);
763 msg = malloc (sizeof (struct pam_message *) * 1);
764 msg[0] = malloc (sizeof (struct pam_message));
765 msg[0]->msg_style = PAM_PROMPT_ECHO_OFF;
766 msg[0]->msg = "remote-password:";
767 result = pamh->conversation.conv (1, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr);
770 if (result != PAM_SUCCESS)
775 if (resp[0].resp == NULL)
782 free (pamh->authtok);
783 pamh->authtok = strdup (resp[0].resp);
787 password_matches = strcmp (pamh->ruser, "remote-user") == 0 && strcmp (pamh->authtok, "password") == 0;
789 if (password_matches)
795 /* Prompt for username */
796 if (pamh->user == NULL)
799 struct pam_message **msg;
800 struct pam_response *resp = NULL;
802 msg = malloc (sizeof (struct pam_message *) * 1);
803 msg[0] = malloc (sizeof (struct pam_message));
804 msg[0]->msg_style = PAM_PROMPT_ECHO_ON;
805 msg[0]->msg = LOGIN_PROMPT;
806 result = pamh->conversation.conv (1, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr);
809 if (result != PAM_SUCCESS)
814 if (resp[0].resp == NULL)
820 pamh->user = strdup (resp[0].resp);
825 if (strcmp (pamh->user, "log-pam") == 0)
826 send_info (pamh, "pam_authenticate");
828 /* Crash on authenticate */
829 if (strcmp (pamh->user, "crash-authenticate") == 0)
830 kill (getpid (), SIGSEGV);
832 /* Look up password database */
833 entry = getpwnam (pamh->user);
835 /* Prompt for password if required */
836 if (entry && strcmp (pamh->user, "always-password") != 0 && (strcmp (pamh->service_name, "lightdm-autologin") == 0 || strcmp (entry->pw_passwd, "") == 0))
837 password_matches = TRUE;
840 int i, n_messages = 0, password_index, result;
841 struct pam_message **msg;
842 struct pam_response *resp = NULL;
844 msg = malloc (sizeof (struct pam_message *) * 5);
845 if (strcmp (pamh->user, "info-prompt") == 0)
847 msg[n_messages] = malloc (sizeof (struct pam_message));
848 msg[n_messages]->msg_style = PAM_TEXT_INFO;
849 msg[n_messages]->msg = "Welcome to LightDM";
852 if (strcmp (pamh->user, "multi-info-prompt") == 0)
854 msg[n_messages] = malloc (sizeof (struct pam_message));
855 msg[n_messages]->msg_style = PAM_TEXT_INFO;
856 msg[n_messages]->msg = "Welcome to LightDM";
858 msg[n_messages] = malloc (sizeof (struct pam_message));
859 msg[n_messages]->msg_style = PAM_ERROR_MSG;
860 msg[n_messages]->msg = "This is an error";
862 msg[n_messages] = malloc (sizeof (struct pam_message));
863 msg[n_messages]->msg_style = PAM_TEXT_INFO;
864 msg[n_messages]->msg = "You should have seen three messages";
867 if (strcmp (pamh->user, "multi-prompt") == 0)
869 msg[n_messages] = malloc (sizeof (struct pam_message));
870 msg[n_messages]->msg_style = PAM_PROMPT_ECHO_ON;
871 msg[n_messages]->msg = "Favorite Color:";
874 msg[n_messages] = malloc (sizeof (struct pam_message));
875 msg[n_messages]->msg_style = PAM_PROMPT_ECHO_OFF;
876 msg[n_messages]->msg = "Password:";
877 password_index = n_messages;
879 result = pamh->conversation.conv (n_messages, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr);
880 for (i = 0; i < n_messages; i++)
883 if (result != PAM_SUCCESS)
888 if (resp[password_index].resp == NULL)
895 password_matches = strcmp (entry->pw_passwd, resp[password_index].resp) == 0;
897 if (password_matches && strcmp (pamh->user, "multi-prompt") == 0)
898 password_matches = strcmp ("blue", resp[0].resp) == 0;
900 for (i = 0; i < n_messages; i++)
907 /* Do two factor authentication */
908 if (password_matches && strcmp (pamh->user, "two-factor") == 0)
910 msg = malloc (sizeof (struct pam_message *) * 1);
911 msg[0] = malloc (sizeof (struct pam_message));
912 msg[0]->msg_style = PAM_PROMPT_ECHO_ON;
913 msg[0]->msg = "OTP:";
915 result = pamh->conversation.conv (1, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr);
921 if (resp[0].resp == NULL)
926 password_matches = strcmp (resp[0].resp, "otp") == 0;
932 /* Special user has home directory created on login */
933 if (password_matches && strcmp (pamh->user, "mount-home-dir") == 0)
934 g_mkdir_with_parents (entry->pw_dir, 0755);
936 /* Special user 'change-user1' changes user on authentication */
937 if (password_matches && strcmp (pamh->user, "change-user1") == 0)
940 pamh->user = g_strdup ("change-user2");
943 /* Special user 'change-user-invalid' changes to an invalid user on authentication */
944 if (password_matches && strcmp (pamh->user, "change-user-invalid") == 0)
947 pamh->user = g_strdup ("invalid-user");
950 if (password_matches)
957 get_env_value (const char *name_value, const char *name)
961 for (j = 0; name[j] && name_value[j] && name[j] == name_value[j]; j++);
962 if (name[j] == '\0' && name_value[j] == '=')
963 return &name_value[j + 1];
969 pam_putenv (pam_handle_t *pamh, const char *name_value)
974 if (pamh == NULL || name_value == NULL)
975 return PAM_SYSTEM_ERR;
977 name = strdup (name_value);
978 for (i = 0; name[i]; i++)
981 for (i = 0; pamh->envlist[i]; i++)
983 if (get_env_value (pamh->envlist[i], name))
988 if (pamh->envlist[i])
990 free (pamh->envlist[i]);
991 pamh->envlist[i] = strdup (name_value);
995 pamh->envlist = realloc (pamh->envlist, sizeof (char *) * (i + 2));
996 pamh->envlist[i] = strdup (name_value);
997 pamh->envlist[i + 1] = NULL;
1004 pam_getenv (pam_handle_t *pamh, const char *name)
1008 if (pamh == NULL || name == NULL)
1011 for (i = 0; pamh->envlist[i]; i++)
1014 value = get_env_value (pamh->envlist[i], name);
1023 pam_getenvlist (pam_handle_t *pamh)
1028 return pamh->envlist;
1032 pam_set_item (pam_handle_t *pamh, int item_type, const void *item)
1034 if (pamh == NULL || item == NULL)
1035 return PAM_SYSTEM_ERR;
1042 pamh->tty = strdup ((const char *) item);
1046 return PAM_BAD_ITEM;
1051 pam_get_item (const pam_handle_t *pamh, int item_type, const void **item)
1053 if (pamh == NULL || item == NULL)
1054 return PAM_SYSTEM_ERR;
1059 *item = pamh->service_name;
1067 *item = pamh->authtok;
1071 *item = pamh->ruser;
1074 case PAM_USER_PROMPT:
1075 *item = LOGIN_PROMPT;
1083 *item = &pamh->conversation;
1087 return PAM_BAD_ITEM;
1092 pam_open_session (pam_handle_t *pamh, int flags)
1095 return PAM_SYSTEM_ERR;
1097 if (strcmp (pamh->user, "session-error") == 0)
1098 return PAM_SESSION_ERR;
1100 if (strcmp (pamh->user, "log-pam") == 0)
1101 send_info (pamh, "pam_open_session");
1103 if (strcmp (pamh->user, "make-home-dir") == 0)
1105 struct passwd *entry;
1106 entry = getpwnam (pamh->user);
1107 g_mkdir_with_parents (entry->pw_dir, 0755);
1114 pam_close_session (pam_handle_t *pamh, int flags)
1117 return PAM_SYSTEM_ERR;
1119 if (strcmp (pamh->user, "log-pam") == 0)
1120 send_info (pamh, "pam_close_session");
1126 pam_acct_mgmt (pam_handle_t *pamh, int flags)
1129 return PAM_SYSTEM_ERR;
1132 return PAM_USER_UNKNOWN;
1134 if (strcmp (pamh->user, "log-pam") == 0)
1135 send_info (pamh, "pam_acct_mgmt");
1137 if (strcmp (pamh->user, "denied") == 0)
1138 return PAM_PERM_DENIED;
1139 if (strcmp (pamh->user, "expired") == 0)
1140 return PAM_ACCT_EXPIRED;
1141 if (strcmp (pamh->user, "new-authtok") == 0)
1142 return PAM_NEW_AUTHTOK_REQD;
1148 pam_chauthtok (pam_handle_t *pamh, int flags)
1150 struct passwd *entry;
1152 struct pam_message **msg;
1153 struct pam_response *resp = NULL;
1156 return PAM_SYSTEM_ERR;
1158 if (strcmp (pamh->user, "log-pam") == 0)
1159 send_info (pamh, "pam_chauthtok");
1161 msg = malloc (sizeof (struct pam_message *) * 1);
1162 msg[0] = malloc (sizeof (struct pam_message));
1163 msg[0]->msg_style = PAM_PROMPT_ECHO_OFF;
1164 msg[0]->msg = "Enter new password:";
1165 result = pamh->conversation.conv (1, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr);
1168 if (result != PAM_SUCCESS)
1172 return PAM_CONV_ERR;
1173 if (resp[0].resp == NULL)
1176 return PAM_CONV_ERR;
1179 /* Update password database */
1180 entry = getpwnam (pamh->user);
1181 free (entry->pw_passwd);
1182 entry->pw_passwd = resp[0].resp;
1189 pam_setcred (pam_handle_t *pamh, int flags)
1194 return PAM_SYSTEM_ERR;
1196 if (strcmp (pamh->user, "log-pam") == 0)
1197 send_info (pamh, "pam_setcred");
1199 /* Put the test directories into the path */
1200 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"));
1201 pam_putenv (pamh, e);
1204 if (strcmp (pamh->user, "cred-error") == 0)
1205 return PAM_CRED_ERR;
1206 if (strcmp (pamh->user, "cred-expired") == 0)
1207 return PAM_CRED_EXPIRED;
1208 if (strcmp (pamh->user, "cred-unavail") == 0)
1209 return PAM_CRED_UNAVAIL;
1211 /* Join special groups if requested */
1212 if (strcmp (pamh->user, "group-member") == 0 && flags & PAM_ESTABLISH_CRED)
1214 struct group *group;
1218 group = getgrnam ("test-group");
1221 groups_length = getgroups (0, NULL);
1222 groups = malloc (sizeof (gid_t) * (groups_length + 1));
1223 groups_length = getgroups (groups_length, groups);
1224 groups[groups_length] = group->gr_gid;
1226 setgroups (groups_length, groups);
1230 /* We need to pass our group overrides down the child process - the environment via PAM seems the only way to do it easily */
1231 pam_putenv (pamh, g_strdup_printf ("LIGHTDM_TEST_GROUPS=%s", g_getenv ("LIGHTDM_TEST_GROUPS")));
1238 pam_end (pam_handle_t *pamh, int pam_status)
1241 return PAM_SYSTEM_ERR;
1243 free (pamh->service_name);
1247 free (pamh->authtok);
1258 pam_strerror (pam_handle_t *pamh, int errnum)
1268 return "Critical error - immediate abort";
1270 return "Failed to load module";
1271 case PAM_SYMBOL_ERR:
1272 return "Symbol not found";
1273 case PAM_SERVICE_ERR:
1274 return "Error in service module";
1275 case PAM_SYSTEM_ERR:
1276 return "System error";
1278 return "Memory buffer error";
1279 case PAM_PERM_DENIED:
1280 return "Permission denied";
1282 return "Authentication failure";
1283 case PAM_CRED_INSUFFICIENT:
1284 return "Insufficient credentials to access authentication data";
1285 case PAM_AUTHINFO_UNAVAIL:
1286 return "Authentication service cannot retrieve authentication info";
1287 case PAM_USER_UNKNOWN:
1288 return "User not known to the underlying authentication module";
1290 return "Have exhausted maximum number of retries for service";
1291 case PAM_NEW_AUTHTOK_REQD:
1292 return "Authentication token is no longer valid; new one required";
1293 case PAM_ACCT_EXPIRED:
1294 return "User account has expired";
1295 case PAM_SESSION_ERR:
1296 return "Cannot make/remove an entry for the specified session";
1297 case PAM_CRED_UNAVAIL:
1298 return "Authentication service cannot retrieve user credentials";
1299 case PAM_CRED_EXPIRED:
1300 return "User credentials expired";
1302 return "Failure setting user credentials";
1303 case PAM_NO_MODULE_DATA:
1304 return "No module specific data is present";
1306 return "Bad item passed to pam_*_item()";
1308 return "Conversation error";
1309 case PAM_AUTHTOK_ERR:
1310 return "Authentication token manipulation error";
1311 case PAM_AUTHTOK_RECOVERY_ERR:
1312 return "Authentication information cannot be recovered";
1313 case PAM_AUTHTOK_LOCK_BUSY:
1314 return "Authentication token lock busy";
1315 case PAM_AUTHTOK_DISABLE_AGING:
1316 return "Authentication token aging disabled";
1318 return "Failed preliminary check by password service";
1320 return "The return value should be ignored by PAM dispatch";
1321 case PAM_MODULE_UNKNOWN:
1322 return "Module is unknown";
1323 case PAM_AUTHTOK_EXPIRED:
1324 return "Authentication token expired";
1325 case PAM_CONV_AGAIN:
1326 return "Conversation is waiting for event";
1327 case PAM_INCOMPLETE:
1328 return "Application needs to call libpam again";
1330 return "Unknown PAM error";
1340 pututxline (struct utmp *ut)
1350 struct xcb_connection_t
1358 xcb_connect_to_display_with_auth_info (const char *display, xcb_auth_info_t *auth, int *screen)
1360 xcb_connection_t *c;
1362 GSocketAddress *address;
1363 GError *error = NULL;
1365 c = malloc (sizeof (xcb_connection_t));
1366 c->display = g_strdup (display);
1369 if (display == NULL)
1370 display = getenv ("DISPLAY");
1371 if (display == NULL)
1372 c->error = XCB_CONN_CLOSED_PARSE_ERR;
1376 c->socket = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, &error);
1378 g_printerr ("%s\n", error->message);
1379 g_clear_error (&error);
1380 if (c->socket == NULL)
1381 c->error = XCB_CONN_ERROR;
1388 /* Skip the hostname, we'll assume it's localhost */
1389 d = g_strdup_printf (".x%s", strchr (display, ':'));
1391 socket_path = g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), d, NULL);
1393 address = g_unix_socket_address_new (socket_path);
1394 if (!g_socket_connect (c->socket, address, NULL, &error))
1395 c->error = XCB_CONN_ERROR;
1397 g_printerr ("Failed to connect to X socket %s: %s\n", socket_path, error->message);
1398 g_free (socket_path);
1399 g_clear_error (&error);
1402 // FIXME: Send auth info
1407 g_object_unref (address);
1413 xcb_connect (const char *displayname, int *screenp)
1415 return xcb_connect_to_display_with_auth_info(displayname, NULL, screenp);
1419 xcb_connection_has_error (xcb_connection_t *c)
1425 xcb_disconnect (xcb_connection_t *c)
1429 g_object_unref (c->socket);