PAM.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. /* SLiM - Simple Login Manager
  2. * Copyright (C) 2007 Martin Parm
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. */
  9. #include <string>
  10. #include <iostream>
  11. #include "PAM.h"
  12. namespace PAM {
  13. Exception::Exception(pam_handle_t* _pam_handle,
  14. const std::string& _func_name,
  15. int _errnum):
  16. errnum(_errnum),
  17. errstr(pam_strerror(_pam_handle, _errnum)),
  18. func_name(_func_name)
  19. {}
  20. Exception::~Exception(void) {}
  21. Auth_Exception::Auth_Exception(pam_handle_t* _pam_handle,
  22. const std::string& _func_name,
  23. int _errnum):
  24. Exception(_pam_handle, _func_name, _errnum) {}
  25. Cred_Exception::Cred_Exception(pam_handle_t* _pam_handle,
  26. const std::string& _func_name,
  27. int _errnum):
  28. Exception(_pam_handle, _func_name, _errnum) {}
  29. int Authenticator::_end (void)
  30. {
  31. int result=pam_end(pam_handle, last_result);
  32. pam_handle=0;
  33. return result;
  34. }
  35. Authenticator::Authenticator(conversation* conv, void* data):
  36. pam_handle(0),
  37. last_result(PAM_SUCCESS)
  38. {
  39. pam_conversation.conv=conv;
  40. pam_conversation.appdata_ptr=data;
  41. }
  42. Authenticator::~Authenticator(void)
  43. {
  44. if (pam_handle)
  45. _end();
  46. }
  47. void Authenticator::start(const std::string& service)
  48. {
  49. switch ((last_result=pam_start(service.c_str(), NULL, &pam_conversation, &pam_handle))) {
  50. default:
  51. throw Exception(pam_handle, "pam_start()", last_result);
  52. case PAM_SUCCESS:
  53. break;
  54. }
  55. return;
  56. }
  57. void Authenticator::end(void)
  58. {
  59. switch ((last_result=_end())) {
  60. default:
  61. throw Exception(pam_handle, "pam_end()", last_result);
  62. case PAM_SUCCESS:
  63. break;
  64. }
  65. return;
  66. }
  67. void Authenticator::set_item(const Authenticator::ItemType item, const void* value)
  68. {
  69. switch ((last_result=pam_set_item(pam_handle, item, value))) {
  70. default:
  71. _end();
  72. throw Exception(pam_handle, "pam_set_item()", last_result);
  73. case PAM_SUCCESS:
  74. break;
  75. }
  76. return;
  77. }
  78. const void* Authenticator::get_item(const Authenticator::ItemType item)
  79. {
  80. const void* data;
  81. switch ((last_result=pam_get_item(pam_handle, item, &data))) {
  82. default:
  83. case PAM_SYSTEM_ERR:
  84. #ifdef __LIBPAM_VERSION
  85. case PAM_BAD_ITEM:
  86. #endif
  87. _end();
  88. throw Exception(pam_handle, "pam_get_item()", last_result);
  89. case PAM_PERM_DENIED: /* The value of item was NULL */
  90. case PAM_SUCCESS:
  91. break;
  92. }
  93. return data;
  94. }
  95. #ifdef __LIBPAM_VERSION
  96. void Authenticator::fail_delay(const unsigned int micro_sec)
  97. {
  98. switch ((last_result=pam_fail_delay(pam_handle, micro_sec))) {
  99. default:
  100. _end();
  101. throw Exception(pam_handle, "fail_delay()", last_result);
  102. case PAM_SUCCESS:
  103. break;
  104. }
  105. return;
  106. }
  107. #endif
  108. void Authenticator::authenticate(void)
  109. {
  110. switch ((last_result=pam_authenticate(pam_handle, 0))) {
  111. default:
  112. case PAM_ABORT:
  113. case PAM_AUTHINFO_UNAVAIL:
  114. _end();
  115. throw Exception(pam_handle, "pam_authenticate()", last_result);
  116. case PAM_USER_UNKNOWN:
  117. case PAM_MAXTRIES:
  118. case PAM_CRED_INSUFFICIENT:
  119. case PAM_AUTH_ERR:
  120. throw Auth_Exception(pam_handle, "pam_authentication()", last_result);
  121. case PAM_SUCCESS:
  122. break;
  123. }
  124. switch ((last_result=pam_acct_mgmt(pam_handle, PAM_SILENT))) {
  125. /* The documentation and implementation of Linux PAM differs:
  126. PAM_NEW_AUTHTOKEN_REQD is described in the documentation but
  127. don't exists in the actual implementation. This issue needs
  128. to be fixes at some point. */
  129. default:
  130. /* case PAM_NEW_AUTHTOKEN_REQD: */
  131. case PAM_ACCT_EXPIRED:
  132. case PAM_USER_UNKNOWN:
  133. _end();
  134. throw Exception(pam_handle, "pam_acct_mgmt()", last_result);
  135. case PAM_AUTH_ERR:
  136. case PAM_PERM_DENIED:
  137. throw Auth_Exception(pam_handle, "pam_acct_mgmt()", last_result);
  138. case PAM_SUCCESS:
  139. break;
  140. }
  141. return;
  142. }
  143. void Authenticator::open_session(void)
  144. {
  145. switch ((last_result=pam_setcred(pam_handle, PAM_ESTABLISH_CRED))) {
  146. default:
  147. case PAM_CRED_ERR:
  148. case PAM_CRED_UNAVAIL:
  149. _end();
  150. throw Exception(pam_handle, "pam_setcred()", last_result);
  151. case PAM_CRED_EXPIRED:
  152. case PAM_USER_UNKNOWN:
  153. throw Cred_Exception(pam_handle, "pam_setcred()", last_result);
  154. case PAM_SUCCESS:
  155. break;
  156. }
  157. switch ((last_result=pam_open_session(pam_handle, 0))) {
  158. /* The documentation and implementation of Linux PAM differs:
  159. PAM_SESSION_ERROR is described in the documentation but
  160. don't exists in the actual implementation. This issue needs
  161. to be fixes at some point. */
  162. default:
  163. /* case PAM_SESSION_ERROR: */
  164. pam_setcred(pam_handle, PAM_DELETE_CRED);
  165. _end();
  166. throw Exception(pam_handle, "pam_open_session()", last_result);
  167. case PAM_SUCCESS:
  168. break;
  169. }
  170. return;
  171. }
  172. void Authenticator::close_session(void)
  173. {
  174. switch ((last_result=pam_close_session(pam_handle, 0))) {
  175. /* The documentation and implementation of Linux PAM differs:
  176. PAM_SESSION_ERROR is described in the documentation but
  177. don't exists in the actual implementation. This issue needs
  178. to be fixes at some point. */
  179. default:
  180. /* case PAM_SESSION_ERROR: */
  181. pam_setcred(pam_handle, PAM_DELETE_CRED);
  182. _end();
  183. throw Exception(pam_handle, "pam_close_session", last_result);
  184. case PAM_SUCCESS:
  185. break;
  186. }
  187. switch ((last_result=pam_setcred(pam_handle, PAM_DELETE_CRED))) {
  188. default:
  189. case PAM_CRED_ERR:
  190. case PAM_CRED_UNAVAIL:
  191. case PAM_CRED_EXPIRED:
  192. case PAM_USER_UNKNOWN:
  193. _end();
  194. throw Exception(pam_handle, "pam_setcred()", last_result);
  195. case PAM_SUCCESS:
  196. break;
  197. }
  198. return;
  199. }
  200. void Authenticator::setenv(const std::string& key, const std::string& value)
  201. {
  202. std::string name_value = key+"="+value;
  203. switch ((last_result = pam_putenv(pam_handle, name_value.c_str()))) {
  204. default:
  205. case PAM_PERM_DENIED:
  206. case PAM_ABORT:
  207. case PAM_BUF_ERR:
  208. #ifdef __LIBPAM_VERSION
  209. case PAM_BAD_ITEM:
  210. #endif
  211. _end();
  212. throw Exception(pam_handle, "pam_putenv()", last_result);
  213. case PAM_SUCCESS:
  214. break;
  215. }
  216. return;
  217. }
  218. void Authenticator::delenv(const std::string& key)
  219. {
  220. switch ((last_result = pam_putenv(pam_handle, key.c_str()))) {
  221. default:
  222. case PAM_PERM_DENIED:
  223. case PAM_ABORT:
  224. case PAM_BUF_ERR:
  225. #ifdef __LIBPAM_VERSION
  226. case PAM_BAD_ITEM:
  227. #endif
  228. _end();
  229. throw Exception(pam_handle, "pam_putenv()", last_result);
  230. case PAM_SUCCESS:
  231. break;
  232. }
  233. return;
  234. }
  235. const char* Authenticator::getenv(const std::string& key)
  236. {
  237. return pam_getenv(pam_handle, key.c_str());
  238. }
  239. char** Authenticator::getenvlist(void)
  240. {
  241. return pam_getenvlist(pam_handle);
  242. }
  243. }
  244. std::ostream& operator<<( std::ostream& os, const PAM::Exception& e)
  245. {
  246. os << e.func_name << ": " << e.errstr;
  247. return os;
  248. }