switchuser.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /* SLiM - Simple Login Manager
  2. Copyright (C) 1997, 1998 Per Liden
  3. Copyright (C) 2004-06 Simone Rota <sip@varlock.com>
  4. Copyright (C) 2004-06 Johannes Winkelmann <jw@tks6.net>
  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. #include "switchuser.h"
  11. using namespace std;
  12. SwitchUser::SwitchUser(struct passwd *pw, Cfg *c, const string& display)
  13. : cfg(c),
  14. Pw(pw),
  15. displayName(display)
  16. {
  17. }
  18. SwitchUser::~SwitchUser() {
  19. // Never called
  20. }
  21. void SwitchUser::Login(const char* cmd, const char* mcookie) {
  22. SetEnvironment();
  23. SetUserId();
  24. SetClientAuth(mcookie);
  25. Execute(cmd);
  26. }
  27. void SwitchUser::SetEnvironment() {
  28. char *term = getenv("TERM");
  29. char** environ;
  30. environ = (char **) new char*[2];
  31. environ[0] = 0;
  32. if(term)
  33. putenv(StrConcat("TERM=", term));
  34. putenv(StrConcat("HOME=", Pw->pw_dir));
  35. putenv(StrConcat("SHELL=", Pw->pw_shell));
  36. putenv(StrConcat("USER=", Pw->pw_name));
  37. putenv(StrConcat("LOGNAME=", Pw->pw_name));
  38. putenv(StrConcat("PATH=", cfg->getOption("default_path").c_str()));
  39. putenv(StrConcat("DISPLAY=", displayName.c_str()));
  40. putenv(StrConcat("MAIL="_PATH_MAILDIR"/", Pw->pw_name));
  41. putenv(StrConcat("XAUTHORITY=", StrConcat(Pw->pw_dir,"/.Xauthority")));
  42. /* putenv("XAUTHORITY=/tmp/serverauth"); */
  43. chdir(Pw->pw_dir);
  44. }
  45. void SwitchUser::SetUserId() {
  46. if( (Pw == 0) ||
  47. (initgroups(Pw->pw_name, Pw->pw_gid) != 0) ||
  48. (setgid(Pw->pw_gid) != 0) ||
  49. (setuid(Pw->pw_uid) != 0) ) {
  50. cerr << APPNAME << ": could not switch user id" << endl;
  51. exit(ERR_EXIT);
  52. }
  53. }
  54. void SwitchUser::Execute(const char* cmd) {
  55. char *args[4];
  56. char* shell = strdup(Pw->pw_shell);
  57. char *shell_basename = BaseName(shell);
  58. args[0] = new char[strlen(shell_basename) + 2];
  59. strcpy(args[0], "-");
  60. strcat(args[0], shell_basename);
  61. args[1] = "-c";
  62. args[2] = (char*)cmd;
  63. args[3] = 0;
  64. execv(shell, args);
  65. cerr << APPNAME << ": could not execute login command" << endl;
  66. }
  67. char* SwitchUser::BaseName(const char* name) {
  68. const char *base = name;
  69. while(*name) {
  70. if(*name == '/')
  71. base = name + 1;
  72. ++name;
  73. }
  74. return (char*) base;
  75. }
  76. char* SwitchUser::StrConcat(const char* str1, const char* str2) {
  77. char* tmp = new char[strlen(str1) + strlen(str2) + 1];
  78. strcpy(tmp, str1);
  79. strcat(tmp, str2);
  80. return tmp;
  81. }
  82. void SwitchUser::SetClientAuth(const char* mcookie) {
  83. int r;
  84. string home = string(Pw->pw_dir);
  85. string authfile = home + "/.Xauthority";
  86. remove(authfile.c_str());
  87. string cmd = cfg->getOption("xauth_path") + " -q -f " + authfile + " add :0 . " + mcookie;
  88. r = system(cmd.c_str());
  89. }