switchuser.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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. : Pw(pw),
  14. cfg(c),
  15. displayName(display)
  16. {
  17. }
  18. SwitchUser::~SwitchUser() {
  19. // Never called
  20. }
  21. void SwitchUser::Login(const char* cmd) {
  22. SetEnvironment();
  23. SetUserId();
  24. Execute(cmd);
  25. }
  26. void SwitchUser::SetEnvironment() {
  27. char *term = getenv("TERM");
  28. char** environ;
  29. environ = (char **) new char*[2];
  30. environ[0] = 0;
  31. if(term)
  32. putenv(StrConcat("TERM=", term));
  33. putenv(StrConcat("HOME=", Pw->pw_dir));
  34. putenv(StrConcat("SHELL=", Pw->pw_shell));
  35. putenv(StrConcat("USER=", Pw->pw_name));
  36. putenv(StrConcat("LOGNAME=", Pw->pw_name));
  37. putenv(StrConcat("PATH=", cfg->getOption("default_path").c_str()));
  38. putenv(StrConcat("DISPLAY=", displayName.c_str()));
  39. putenv(StrConcat("MAIL="_PATH_MAILDIR"/", Pw->pw_name));
  40. chdir(Pw->pw_dir);
  41. }
  42. void SwitchUser::SetUserId() {
  43. if( (Pw == 0) ||
  44. (initgroups(Pw->pw_name, Pw->pw_gid) != 0) ||
  45. (setgid(Pw->pw_gid) != 0) ||
  46. (setuid(Pw->pw_uid) != 0) ) {
  47. cerr << APPNAME << ": could not switch user id" << endl;
  48. exit(ERR_EXIT);
  49. }
  50. }
  51. void SwitchUser::Execute(const char* cmd) {
  52. char *args[4];
  53. char* shell = strdup(Pw->pw_shell);
  54. char *shell_basename = BaseName(shell);
  55. args[0] = new char[strlen(shell_basename) + 2];
  56. strcpy(args[0], "-");
  57. strcat(args[0], shell_basename);
  58. args[1] = "-c";
  59. args[2] = (char*)cmd;
  60. args[3] = 0;
  61. execv(shell, args);
  62. cerr << APPNAME << ": could not execute login command" << endl;
  63. }
  64. char* SwitchUser::BaseName(const char* name) {
  65. const char *base = name;
  66. while(*name) {
  67. if(*name == '/')
  68. base = name + 1;
  69. ++name;
  70. }
  71. return (char*) base;
  72. }
  73. char* SwitchUser::StrConcat(const char* str1, const char* str2) {
  74. char* tmp = new char[strlen(str1) + strlen(str2) + 1];
  75. strcpy(tmp, str1);
  76. strcat(tmp, str2);
  77. return tmp;
  78. }