group_mod.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. /*
  2. * $Id$
  3. *
  4. * Copyright (C) 2001-2003 FhG Fokus
  5. *
  6. * This file is part of Kamailio, a free SIP server.
  7. *
  8. * Kamailio is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version
  12. *
  13. * Kamailio is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. *
  22. * History:
  23. * --------
  24. * 2003-02-25 - created by janakj
  25. * 2003-03-11 - New module interface (janakj)
  26. * 2003-03-16 - flags export parameter added (janakj)
  27. * 2003-03-19 all mallocs/frees replaced w/ pkg_malloc/pkg_free
  28. * 2003-04-05 default_uri #define used (jiri)
  29. * 2004-06-07 updated to the new DB api: calls to group_db_* (andrei)
  30. * 2005-10-06 - added support for regexp-based groups (bogdan)
  31. */
  32. /**
  33. * \file
  34. * \brief Group membership module
  35. * \ingroup group
  36. * - Module: \ref group
  37. */
  38. /*!
  39. * \defgroup group GROUP :: The Kamailio group Module
  40. * This module provides functions to check if a certain user belongs to a
  41. * group. This group definitions are read from a DB table.
  42. */
  43. #include <stdio.h>
  44. #include <stdlib.h>
  45. #include <string.h>
  46. #include "../../sr_module.h"
  47. #include "../../dprint.h"
  48. #include "../../ut.h"
  49. #include "../../error.h"
  50. #include "../../mem/mem.h"
  51. #include "../../usr_avp.h"
  52. #include "group_mod.h"
  53. #include "group.h"
  54. #include "re_group.h"
  55. MODULE_VERSION
  56. #define TABLE_VERSION 2
  57. #define RE_TABLE_VERSION 1
  58. /*!
  59. * \brief Module destroy function prototype
  60. */
  61. static void destroy(void);
  62. /*!
  63. * \brief Module child-init function prototype
  64. */
  65. static int child_init(int rank);
  66. /*!
  67. * \brief Module initialization function prototype
  68. */
  69. static int mod_init(void);
  70. /*! Header field fixup */
  71. static int hf_fixup(void** param, int param_no);
  72. /*! get user group ID fixup */
  73. static int get_gid_fixup(void** param, int param_no);
  74. #define TABLE "grp"
  75. #define USER_COL "username"
  76. #define DOMAIN_COL "domain"
  77. #define GROUP_COL "grp"
  78. #define RE_TABLE "re_grp"
  79. #define RE_EXP_COL "reg_exp"
  80. #define RE_GID_COL "group_id"
  81. /*
  82. * Module parameter variables
  83. */
  84. static str db_url = str_init(DEFAULT_RODB_URL);
  85. /*! Table name where group definitions are stored */
  86. str table = str_init(TABLE);
  87. str user_column = str_init(USER_COL);
  88. str domain_column = str_init(DOMAIN_COL);
  89. str group_column = str_init(GROUP_COL);
  90. int use_domain = 0;
  91. /* table and columns used for regular expression-based groups */
  92. str re_table = {0, 0};
  93. str re_exp_column = str_init(RE_EXP_COL);
  94. str re_gid_column = str_init(RE_GID_COL);
  95. int multiple_gid = 1;
  96. /* DB functions and handlers */
  97. db_func_t group_dbf;
  98. db1_con_t* group_dbh = 0;
  99. /*!
  100. * Exported functions
  101. */
  102. static cmd_export_t cmds[] = {
  103. {"is_user_in", (cmd_function)is_user_in, 2, hf_fixup, 0,
  104. REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
  105. {"get_user_group", (cmd_function)get_user_group, 2, get_gid_fixup, 0,
  106. REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
  107. {0, 0, 0, 0, 0, 0}
  108. };
  109. /*!
  110. * Exported parameters
  111. */
  112. static param_export_t params[] = {
  113. {"db_url", PARAM_STR, &db_url },
  114. {"table", PARAM_STR, &table },
  115. {"user_column", PARAM_STR, &user_column },
  116. {"domain_column", PARAM_STR, &domain_column},
  117. {"group_column", PARAM_STR, &group_column },
  118. {"use_domain", INT_PARAM, &use_domain },
  119. {"re_table", PARAM_STR, &re_table },
  120. {"re_exp_column", PARAM_STR, &re_exp_column},
  121. {"re_gid_column", PARAM_STR, &re_gid_column},
  122. {"multiple_gid", INT_PARAM, &multiple_gid },
  123. {0, 0, 0}
  124. };
  125. /*!
  126. * Module interface
  127. */
  128. struct module_exports exports = {
  129. "group",
  130. DEFAULT_DLFLAGS, /* dlopen flags */
  131. cmds, /* Exported functions */
  132. params, /* Exported parameters */
  133. 0, /* exported statistics */
  134. 0, /* exported MI functions */
  135. 0, /* exported pseudo-variables */
  136. 0, /* extra processes */
  137. mod_init, /* module initialization function */
  138. 0, /* response function */
  139. destroy, /* destroy function */
  140. child_init /* child initialization function */
  141. };
  142. static int child_init(int rank)
  143. {
  144. if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
  145. return 0; /* do nothing for the main process */
  146. return group_db_init(&db_url);
  147. }
  148. static int mod_init(void)
  149. {
  150. /* Find a database module */
  151. if (group_db_bind(&db_url)) {
  152. return -1;
  153. }
  154. if (group_db_init(&db_url) < 0 ){
  155. LM_ERR("unable to open database connection\n");
  156. return -1;
  157. }
  158. /* check version for group table */
  159. if (db_check_table_version(&group_dbf, group_dbh, &table, TABLE_VERSION) < 0) {
  160. LM_ERR("error during group table version check.\n");
  161. return -1;
  162. }
  163. if (re_table.len) {
  164. /* check version for group re_group table */
  165. if (db_check_table_version(&group_dbf, group_dbh, &re_table, RE_TABLE_VERSION) < 0) {
  166. LM_ERR("error during re_group table version check.\n");
  167. return -1;
  168. }
  169. if (load_re( &re_table )!=0 ) {
  170. LM_ERR("failed to load <%s> table\n", re_table.s);
  171. return -1;
  172. }
  173. }
  174. group_db_close();
  175. return 0;
  176. }
  177. static void destroy(void)
  178. {
  179. group_db_close();
  180. }
  181. /*!
  182. * \brief Convert HF description string to hdr_field pointer
  183. *
  184. * Convert a header field description string to hdr_field structure
  185. * Supported strings: "Request-URI", "To", "From", "Credentials"
  186. * \param str1 header field description string
  187. * \return hdr_field structure on success, NULL on failure
  188. */
  189. static group_check_p get_hf( char *str1)
  190. {
  191. group_check_p gcp=NULL;
  192. str s;
  193. gcp = (group_check_p)pkg_malloc(sizeof(group_check_t));
  194. if(gcp == NULL) {
  195. LM_ERR("no pkg more memory\n");
  196. return 0;
  197. }
  198. memset(gcp, 0, sizeof(group_check_t));
  199. if (!strcasecmp( str1, "Request-URI")) {
  200. gcp->id = 1;
  201. } else if (!strcasecmp( str1, "To")) {
  202. gcp->id = 2;
  203. } else if (!strcasecmp( str1, "From")) {
  204. gcp->id = 3;
  205. } else if (!strcasecmp( str1, "Credentials")) {
  206. gcp->id = 4;
  207. } else {
  208. s.s = str1; s.len = strlen(s.s);
  209. if(pv_parse_spec( &s, &gcp->sp)==NULL
  210. || gcp->sp.type!=PVT_AVP)
  211. {
  212. LM_ERR("unsupported User Field identifier\n");
  213. pkg_free( gcp );
  214. return 0;
  215. }
  216. gcp->id = 5;
  217. }
  218. /* do not free all the time, needed by pseudo-variable spec */
  219. if(gcp->id!=5)
  220. pkg_free(str1);
  221. return gcp;
  222. }
  223. /*!
  224. * \brief Header fixup function
  225. * \param param fixed parameter
  226. * \param param_no number of parameters
  227. * \return 0 on success, negative on failure
  228. */
  229. static int hf_fixup(void** param, int param_no)
  230. {
  231. void* ptr;
  232. str* s;
  233. if (param_no == 1) {
  234. ptr = *param;
  235. if ( (*param = (void*)get_hf( ptr ))==0 )
  236. return E_UNSPEC;
  237. } else if (param_no == 2) {
  238. s = (str*)pkg_malloc(sizeof(str));
  239. if (!s) {
  240. LM_ERR("no pkg memory left\n");
  241. return E_UNSPEC;
  242. }
  243. s->s = (char*)*param;
  244. s->len = strlen(s->s);
  245. *param = (void*)s;
  246. }
  247. return 0;
  248. }
  249. /*!
  250. * \brief Group ID fixup
  251. * \param param fixed parameter
  252. * \param param_no number of parameters
  253. * \return 0 on success, negative on failure
  254. */
  255. static int get_gid_fixup(void** param, int param_no)
  256. {
  257. pv_spec_t *sp;
  258. void *ptr;
  259. str name;
  260. if (param_no == 1) {
  261. ptr = *param;
  262. if ( (*param = (void*)get_hf( ptr ))==0 )
  263. return E_UNSPEC;
  264. } else if (param_no == 2) {
  265. name.s = (char*)*param;
  266. name.len = strlen(name.s);
  267. sp = (pv_spec_t*)pkg_malloc(sizeof(pv_spec_t));
  268. if (sp == NULL) {
  269. LM_ERR("no more pkg memory\n");
  270. return E_UNSPEC;
  271. }
  272. if(pv_parse_spec(&name, sp)==NULL || sp->type!=PVT_AVP)
  273. {
  274. LM_ERR("bad AVP spec <%s>\n", name.s);
  275. pv_spec_free(sp);
  276. return E_UNSPEC;
  277. }
  278. *param = sp;
  279. }
  280. return 0;
  281. }