userdb.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311
  1. /*
  2. * Copyright (C) 2011, 2012, 2013 Citrix Systems
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. Neither the name of the project nor the names of its contributors
  15. * may be used to endorse or promote products derived from this software
  16. * without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  19. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21. * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  22. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  23. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  24. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  25. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  26. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  27. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. */
  30. #include <stdlib.h>
  31. #include <stdio.h>
  32. #include <string.h>
  33. #include <time.h>
  34. #include <unistd.h>
  35. #include <limits.h>
  36. #include <ifaddrs.h>
  37. #include <getopt.h>
  38. #include <locale.h>
  39. #include <libgen.h>
  40. #include <pthread.h>
  41. #include <signal.h>
  42. #include <sys/types.h>
  43. #include <sys/time.h>
  44. #include <sys/stat.h>
  45. #include <sys/resource.h>
  46. #include <event2/bufferevent.h>
  47. #include <event2/buffer.h>
  48. #include "userdb.h"
  49. #include "dbdrivers/dbdriver.h"
  50. #include "mainrelay.h"
  51. #include "ns_turn_utils.h"
  52. #include "ns_turn_server.h"
  53. #include "ns_turn_maps.h"
  54. #include "apputils.h"
  55. //////////// REALM //////////////
  56. static realm_params_t *default_realm_params_ptr = NULL;
  57. static ur_string_map *realms = NULL;
  58. static turn_mutex o_to_realm_mutex;
  59. static ur_string_map *o_to_realm = NULL;
  60. static secrets_list_t realms_list;
  61. void lock_realms(void) {
  62. ur_string_map_lock(realms);
  63. }
  64. void unlock_realms(void) {
  65. ur_string_map_unlock(realms);
  66. }
  67. void update_o_to_realm(ur_string_map * o_to_realm_new) {
  68. TURN_MUTEX_LOCK(&o_to_realm_mutex);
  69. ur_string_map_free(&o_to_realm);
  70. o_to_realm = o_to_realm_new;
  71. TURN_MUTEX_UNLOCK(&o_to_realm_mutex);
  72. }
  73. void create_default_realm()
  74. {
  75. if(default_realm_params_ptr) {
  76. return;
  77. }
  78. static realm_params_t _default_realm_params =
  79. {
  80. 1,
  81. {
  82. "\0", /* name */
  83. {0,0,0}
  84. },
  85. {0,NULL}
  86. };
  87. /* init everything: */
  88. TURN_MUTEX_INIT_RECURSIVE(&o_to_realm_mutex);
  89. init_secrets_list(&realms_list);
  90. o_to_realm = ur_string_map_create(free);
  91. default_realm_params_ptr = &_default_realm_params;
  92. realms = ur_string_map_create(NULL);
  93. lock_realms();
  94. default_realm_params_ptr->status.alloc_counters = ur_string_map_create(NULL);
  95. unlock_realms();
  96. }
  97. void get_default_realm_options(realm_options_t* ro)
  98. {
  99. if(ro) {
  100. lock_realms();
  101. bcopy(&(default_realm_params_ptr->options),ro,sizeof(realm_options_t));
  102. unlock_realms();
  103. }
  104. }
  105. void set_default_realm_name(char *realm) {
  106. lock_realms();
  107. ur_string_map_value_type value = (ur_string_map_value_type)default_realm_params_ptr;
  108. STRCPY(default_realm_params_ptr->options.name,realm);
  109. ur_string_map_put(realms, (ur_string_map_key_type)default_realm_params_ptr->options.name, value);
  110. add_to_secrets_list(&realms_list, realm);
  111. unlock_realms();
  112. }
  113. realm_params_t* get_realm(char* name)
  114. {
  115. if(name && name[0]) {
  116. lock_realms();
  117. ur_string_map_value_type value = 0;
  118. ur_string_map_key_type key = (ur_string_map_key_type)name;
  119. if (ur_string_map_get(realms, key, &value)) {
  120. unlock_realms();
  121. return (realm_params_t*)value;
  122. } else {
  123. realm_params_t *ret = (realm_params_t*)malloc(sizeof(realm_params_t));
  124. bcopy(default_realm_params_ptr,ret,sizeof(realm_params_t));
  125. STRCPY(ret->options.name,name);
  126. value = (ur_string_map_value_type)ret;
  127. ur_string_map_put(realms, key, value);
  128. ret->status.alloc_counters = ur_string_map_create(NULL);
  129. add_to_secrets_list(&realms_list, name);
  130. unlock_realms();
  131. return ret;
  132. }
  133. }
  134. return default_realm_params_ptr;
  135. }
  136. int get_realm_data(char* name, realm_params_t* rp)
  137. {
  138. lock_realms();
  139. bcopy(get_realm(name),rp,sizeof(realm_params_t));
  140. unlock_realms();
  141. return 0;
  142. }
  143. int get_realm_options_by_origin(char *origin, realm_options_t* ro)
  144. {
  145. ur_string_map_value_type value = 0;
  146. TURN_MUTEX_LOCK(&o_to_realm_mutex);
  147. if (ur_string_map_get(o_to_realm, (ur_string_map_key_type) origin, &value) && value) {
  148. char *realm = strdup((char*)value);
  149. TURN_MUTEX_UNLOCK(&o_to_realm_mutex);
  150. realm_params_t rp;
  151. get_realm_data(realm, &rp);
  152. bcopy(&(rp.options),ro,sizeof(realm_options_t));
  153. free(realm);
  154. return 1;
  155. } else {
  156. TURN_MUTEX_UNLOCK(&o_to_realm_mutex);
  157. get_default_realm_options(ro);
  158. return 0;
  159. }
  160. }
  161. void get_realm_options_by_name(char *realm, realm_options_t* ro)
  162. {
  163. realm_params_t rp;
  164. get_realm_data(realm, &rp);
  165. bcopy(&(rp.options),ro,sizeof(realm_options_t));
  166. }
  167. int change_total_quota(char *realm, int value)
  168. {
  169. int ret = value;
  170. lock_realms();
  171. realm_params_t* rp = get_realm(realm);
  172. rp->options.perf_options.total_quota = value;
  173. unlock_realms();
  174. return ret;
  175. }
  176. int change_user_quota(char *realm, int value)
  177. {
  178. int ret = value;
  179. lock_realms();
  180. realm_params_t* rp = get_realm(realm);
  181. rp->options.perf_options.user_quota = value;
  182. unlock_realms();
  183. return ret;
  184. }
  185. static void must_set_admin_realm(void *realm0)
  186. {
  187. char* realm = (char*)realm0;
  188. if(!realm || !realm[0]) {
  189. fprintf(stderr, "The operation cannot be completed: the realm must be set.\n");
  190. exit(-1);
  191. }
  192. }
  193. static void must_set_admin_user(void *user0)
  194. {
  195. char* user = (char*)user0;
  196. if(!user || !user[0]) {
  197. fprintf(stderr, "The operation cannot be completed: the user must be set.\n");
  198. exit(-1);
  199. }
  200. }
  201. static void must_set_admin_pwd(void *pwd0)
  202. {
  203. char* pwd = (char*)pwd0;
  204. if(!pwd || !pwd[0]) {
  205. fprintf(stderr, "The operation cannot be completed: the password must be set.\n");
  206. exit(-1);
  207. }
  208. }
  209. static void must_set_admin_origin(void *origin0)
  210. {
  211. char* origin = (char*)origin0;
  212. if(!origin || !origin[0]) {
  213. fprintf(stderr, "The operation cannot be completed: the origin must be set.\n");
  214. exit(-1);
  215. }
  216. }
  217. /////////// SHARED SECRETS /////////////////
  218. void init_secrets_list(secrets_list_t *sl)
  219. {
  220. if(sl) {
  221. bzero(sl,sizeof(secrets_list_t));
  222. }
  223. }
  224. void clean_secrets_list(secrets_list_t *sl)
  225. {
  226. if(sl) {
  227. if(sl->secrets) {
  228. size_t i = 0;
  229. for(i = 0;i<sl->sz;++i) {
  230. if(sl->secrets[i]) {
  231. free(sl->secrets[i]);
  232. }
  233. }
  234. free(sl->secrets);
  235. sl->secrets = NULL;
  236. sl->sz = 0;
  237. }
  238. }
  239. }
  240. size_t get_secrets_list_size(secrets_list_t *sl)
  241. {
  242. if(sl && sl->secrets) {
  243. return sl->sz;
  244. }
  245. return 0;
  246. }
  247. const char* get_secrets_list_elem(secrets_list_t *sl, size_t i)
  248. {
  249. if(get_secrets_list_size(sl)>i) {
  250. return sl->secrets[i];
  251. }
  252. return NULL;
  253. }
  254. void add_to_secrets_list(secrets_list_t *sl, const char* elem)
  255. {
  256. if(sl && elem) {
  257. sl->secrets = (char**)realloc(sl->secrets,(sizeof(char*)*(sl->sz+1)));
  258. sl->secrets[sl->sz] = strdup(elem);
  259. sl->sz += 1;
  260. }
  261. }
  262. ////////////////////////////////////////////
  263. static int get_auth_secrets(secrets_list_t *sl, u08bits *realm)
  264. {
  265. int ret = -1;
  266. const turn_dbdriver_t * dbd = get_dbdriver();
  267. clean_secrets_list(sl);
  268. if(get_secrets_list_size(&turn_params.default_users_db.ram_db.static_auth_secrets)) {
  269. size_t i = 0;
  270. for(i=0;i<get_secrets_list_size(&turn_params.default_users_db.ram_db.static_auth_secrets);++i) {
  271. add_to_secrets_list(sl,get_secrets_list_elem(&turn_params.default_users_db.ram_db.static_auth_secrets,i));
  272. }
  273. ret=0;
  274. }
  275. if (dbd && dbd->get_auth_secrets) {
  276. ret = (*dbd->get_auth_secrets)(sl, realm);
  277. }
  278. return ret;
  279. }
  280. /*
  281. * Timestamp retrieval
  282. */
  283. static turn_time_t get_rest_api_timestamp(char *usname)
  284. {
  285. turn_time_t ts = 0;
  286. int ts_set = 0;
  287. char *col = strchr(usname,turn_params.rest_api_separator);
  288. if(col) {
  289. if(col == usname) {
  290. usname +=1;
  291. } else {
  292. char *ptr = usname;
  293. int found_non_figure = 0;
  294. while(ptr < col) {
  295. if(!(ptr[0]>='0' && ptr[0]<='9')) {
  296. found_non_figure=1;
  297. break;
  298. }
  299. ++ptr;
  300. }
  301. if(found_non_figure) {
  302. ts = (turn_time_t)atol(col+1);
  303. ts_set = 1;
  304. } else {
  305. *col=0;
  306. ts = (turn_time_t)atol(usname);
  307. ts_set = 1;
  308. *col=turn_params.rest_api_separator;
  309. }
  310. }
  311. }
  312. if(!ts_set) {
  313. ts = (turn_time_t)atol(usname);
  314. }
  315. return ts;
  316. }
  317. static char *get_real_username(char *usname)
  318. {
  319. if(usname[0] && turn_params.use_auth_secret_with_timestamp) {
  320. char *col=strchr(usname,turn_params.rest_api_separator);
  321. if(col) {
  322. if(col == usname) {
  323. usname +=1;
  324. } else {
  325. char *ptr = usname;
  326. int found_non_figure = 0;
  327. while(ptr < col) {
  328. if(!(ptr[0]>='0' && ptr[0]<='9')) {
  329. found_non_figure=1;
  330. break;
  331. }
  332. ++ptr;
  333. }
  334. if(!found_non_figure) {
  335. usname = col+1;
  336. } else {
  337. *col=0;
  338. usname = strdup(usname);
  339. *col=turn_params.rest_api_separator;
  340. return usname;
  341. }
  342. }
  343. }
  344. }
  345. return strdup(usname);
  346. }
  347. /*
  348. * Password retrieval
  349. */
  350. int get_user_key(int in_oauth, int *out_oauth, int *max_session_time, u08bits *usname, u08bits *realm, hmackey_t key, ioa_network_buffer_handle nbh)
  351. {
  352. int ret = -1;
  353. if(max_session_time)
  354. *max_session_time = 0;
  355. if(in_oauth && out_oauth && usname && usname[0]) {
  356. stun_attr_ref sar = stun_attr_get_first_by_type_str(ioa_network_buffer_data(nbh),
  357. ioa_network_buffer_get_size(nbh),
  358. STUN_ATTRIBUTE_OAUTH_ACCESS_TOKEN);
  359. if(sar) {
  360. int len = stun_attr_get_len(sar);
  361. const u08bits *value = stun_attr_get_value(sar);
  362. *out_oauth = 1;
  363. if(len>0 && value) {
  364. const turn_dbdriver_t * dbd = get_dbdriver();
  365. if (dbd && dbd->get_oauth_key) {
  366. oauth_key_data_raw rawKey;
  367. bzero(&rawKey,sizeof(rawKey));
  368. int gres = (*(dbd->get_oauth_key))(usname,&rawKey);
  369. if(gres<0)
  370. return ret;
  371. if(!rawKey.kid[0])
  372. return ret;
  373. if(rawKey.lifetime) {
  374. if(!turn_time_before(turn_time(),(turn_time_t)(rawKey.timestamp + rawKey.lifetime+OAUTH_TIME_DELTA))) {
  375. return ret;
  376. }
  377. }
  378. oauth_key_data okd;
  379. bzero(&okd,sizeof(okd));
  380. convert_oauth_key_data_raw(&rawKey, &okd);
  381. char err_msg[1025] = "\0";
  382. size_t err_msg_size = sizeof(err_msg) - 1;
  383. oauth_key okey;
  384. bzero(&okey,sizeof(okey));
  385. if (convert_oauth_key_data(&okd, &okey, err_msg, err_msg_size) < 0) {
  386. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s\n", err_msg);
  387. return -1;
  388. }
  389. oauth_token dot;
  390. bzero((&dot),sizeof(dot));
  391. encoded_oauth_token etoken;
  392. bzero(&etoken,sizeof(etoken));
  393. if((size_t)len > sizeof(etoken.token)) {
  394. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Encoded oAuth token is too large\n");
  395. return -1;
  396. }
  397. bcopy(value,etoken.token,(size_t)len);
  398. etoken.size = (size_t)len;
  399. const char* server_name = (char*)turn_params.oauth_server_name;
  400. if(!(server_name && server_name[0])) {
  401. server_name = (char*)realm;
  402. if(!(server_name && server_name[0])) {
  403. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot determine oAuth server name");
  404. return -1;
  405. }
  406. }
  407. if (decode_oauth_token((const u08bits *) server_name, &etoken,&okey, &dot) < 0) {
  408. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot decode oauth token\n");
  409. return -1;
  410. }
  411. switch(dot.enc_block.key_length) {
  412. case SHA1SIZEBYTES:
  413. break;
  414. case SHA256SIZEBYTES:
  415. case SHA384SIZEBYTES:
  416. case SHA512SIZEBYTES:
  417. default:
  418. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong size of the MAC key in oAuth token(3): %d\n",(int)dot.enc_block.key_length);
  419. return -1;
  420. };
  421. password_t pwdtmp;
  422. if(stun_check_message_integrity_by_key_str(TURN_CREDENTIALS_LONG_TERM,
  423. ioa_network_buffer_data(nbh),
  424. ioa_network_buffer_get_size(nbh),
  425. dot.enc_block.mac_key,
  426. pwdtmp,
  427. SHATYPE_DEFAULT)>0) {
  428. turn_time_t lifetime = (turn_time_t)(dot.enc_block.lifetime);
  429. if(lifetime) {
  430. turn_time_t ts = (turn_time_t)(dot.enc_block.timestamp >> 16);
  431. turn_time_t to = ts + lifetime + OAUTH_TIME_DELTA;
  432. turn_time_t ct = turn_time();
  433. if(!turn_time_before(ct,to)) {
  434. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "oAuth token is too old\n");
  435. return -1;
  436. }
  437. if(max_session_time) {
  438. *max_session_time = to - ct;
  439. }
  440. }
  441. bcopy(dot.enc_block.mac_key,key,dot.enc_block.key_length);
  442. if(rawKey.realm[0]) {
  443. bcopy(rawKey.realm,realm,sizeof(rawKey.realm));
  444. }
  445. ret = 0;
  446. }
  447. }
  448. }
  449. }
  450. }
  451. if(out_oauth && *out_oauth) {
  452. return ret;
  453. }
  454. if(turn_params.use_auth_secret_with_timestamp) {
  455. turn_time_t ctime = (turn_time_t) time(NULL);
  456. turn_time_t ts = 0;
  457. secrets_list_t sl;
  458. size_t sll = 0;
  459. init_secrets_list(&sl);
  460. if(get_auth_secrets(&sl, realm)<0)
  461. return ret;
  462. ts = get_rest_api_timestamp((char*)usname);
  463. if(!turn_time_before(ts, ctime)) {
  464. u08bits hmac[MAXSHASIZE];
  465. unsigned int hmac_len;
  466. password_t pwdtmp;
  467. hmac[0] = 0;
  468. stun_attr_ref sar = stun_attr_get_first_by_type_str(ioa_network_buffer_data(nbh),
  469. ioa_network_buffer_get_size(nbh),
  470. STUN_ATTRIBUTE_MESSAGE_INTEGRITY);
  471. if (!sar)
  472. return -1;
  473. int sarlen = stun_attr_get_len(sar);
  474. switch(sarlen) {
  475. case SHA1SIZEBYTES:
  476. hmac_len = SHA1SIZEBYTES;
  477. break;
  478. case SHA256SIZEBYTES:
  479. case SHA384SIZEBYTES:
  480. case SHA512SIZEBYTES:
  481. default:
  482. return -1;
  483. };
  484. for(sll=0;sll<get_secrets_list_size(&sl);++sll) {
  485. const char* secret = get_secrets_list_elem(&sl,sll);
  486. if(secret) {
  487. if(stun_calculate_hmac(usname, strlen((char*)usname), (const u08bits*)secret, strlen(secret), hmac, &hmac_len, SHATYPE_DEFAULT)>=0) {
  488. size_t pwd_length = 0;
  489. char *pwd = base64_encode(hmac,hmac_len,&pwd_length);
  490. if(pwd) {
  491. if(pwd_length<1) {
  492. free(pwd);
  493. } else {
  494. if(stun_produce_integrity_key_str((u08bits*)usname, realm, (u08bits*)pwd, key, SHATYPE_DEFAULT)>=0) {
  495. if(stun_check_message_integrity_by_key_str(TURN_CREDENTIALS_LONG_TERM,
  496. ioa_network_buffer_data(nbh),
  497. ioa_network_buffer_get_size(nbh),
  498. key,
  499. pwdtmp,
  500. SHATYPE_DEFAULT)>0) {
  501. ret = 0;
  502. }
  503. }
  504. free(pwd);
  505. if(ret==0)
  506. break;
  507. }
  508. }
  509. }
  510. }
  511. }
  512. }
  513. clean_secrets_list(&sl);
  514. return ret;
  515. }
  516. ur_string_map_value_type ukey = NULL;
  517. ur_string_map_lock(turn_params.default_users_db.ram_db.static_accounts);
  518. if(ur_string_map_get(turn_params.default_users_db.ram_db.static_accounts, (ur_string_map_key_type)usname, &ukey)) {
  519. ret = 0;
  520. }
  521. ur_string_map_unlock(turn_params.default_users_db.ram_db.static_accounts);
  522. if(ret==0) {
  523. size_t sz = get_hmackey_size(SHATYPE_DEFAULT);
  524. bcopy(ukey,key,sz);
  525. return 0;
  526. }
  527. const turn_dbdriver_t * dbd = get_dbdriver();
  528. if (dbd && dbd->get_user_key) {
  529. ret = (*(dbd->get_user_key))(usname, realm, key);
  530. }
  531. return ret;
  532. }
  533. u08bits *start_user_check(turnserver_id id, turn_credential_type ct, int in_oauth, int *out_oauth, u08bits *usname, u08bits *realm, get_username_resume_cb resume, ioa_net_data *in_buffer, u64bits ctxkey, int *postpone_reply)
  534. {
  535. *postpone_reply = 1;
  536. struct auth_message am;
  537. bzero(&am,sizeof(struct auth_message));
  538. am.id = id;
  539. am.ct = ct;
  540. am.in_oauth = in_oauth;
  541. am.out_oauth = *out_oauth;
  542. STRCPY(am.username,usname);
  543. STRCPY(am.realm,realm);
  544. am.resume_func = resume;
  545. memcpy(&(am.in_buffer),in_buffer,sizeof(ioa_net_data));
  546. in_buffer->nbh = NULL;
  547. am.ctxkey = ctxkey;
  548. send_auth_message_to_auth_server(&am);
  549. return NULL;
  550. }
  551. int check_new_allocation_quota(u08bits *user, int oauth, u08bits *realm)
  552. {
  553. int ret = 0;
  554. if (user || oauth) {
  555. u08bits *username = oauth ? (u08bits*)strdup("") : (u08bits*)get_real_username((char*)user);
  556. realm_params_t *rp = get_realm((char*)realm);
  557. ur_string_map_lock(rp->status.alloc_counters);
  558. if (rp->options.perf_options.total_quota && (rp->status.total_current_allocs >= rp->options.perf_options.total_quota)) {
  559. ret = -1;
  560. } else if(username[0]){
  561. ur_string_map_value_type value = 0;
  562. if (!ur_string_map_get(rp->status.alloc_counters, (ur_string_map_key_type) username, &value)) {
  563. value = (ur_string_map_value_type) 1;
  564. ur_string_map_put(rp->status.alloc_counters, (ur_string_map_key_type) username, value);
  565. ++(rp->status.total_current_allocs);
  566. } else {
  567. if ((rp->options.perf_options.user_quota) && ((size_t) value >= (size_t)(rp->options.perf_options.user_quota))) {
  568. ret = -1;
  569. } else {
  570. value = (ur_string_map_value_type)(((size_t)value) + 1);
  571. ur_string_map_put(rp->status.alloc_counters, (ur_string_map_key_type) username, value);
  572. ++(rp->status.total_current_allocs);
  573. }
  574. }
  575. } else {
  576. ++(rp->status.total_current_allocs);
  577. }
  578. free(username);
  579. ur_string_map_unlock(rp->status.alloc_counters);
  580. }
  581. return ret;
  582. }
  583. void release_allocation_quota(u08bits *user, int oauth, u08bits *realm)
  584. {
  585. if (user) {
  586. u08bits *username = oauth ? (u08bits*)strdup("") : (u08bits*)get_real_username((char*)user);
  587. realm_params_t *rp = get_realm((char*)realm);
  588. ur_string_map_lock(rp->status.alloc_counters);
  589. if(username[0]) {
  590. ur_string_map_value_type value = 0;
  591. ur_string_map_get(rp->status.alloc_counters, (ur_string_map_key_type) username, &value);
  592. if (value) {
  593. value = (ur_string_map_value_type)(((size_t)value) - 1);
  594. ur_string_map_put(rp->status.alloc_counters, (ur_string_map_key_type) username, value);
  595. }
  596. }
  597. if (rp->status.total_current_allocs)
  598. --(rp->status.total_current_allocs);
  599. ur_string_map_unlock(rp->status.alloc_counters);
  600. free(username);
  601. }
  602. }
  603. //////////////////////////////////
  604. int add_static_user_account(char *user)
  605. {
  606. /* Realm is either default or empty for users taken from file or command-line */
  607. if(user && !turn_params.use_auth_secret_with_timestamp) {
  608. char *s = strstr(user, ":");
  609. if(!s || (s==user) || (strlen(s)<2)) {
  610. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user account: %s\n",user);
  611. } else {
  612. size_t ulen = s-user;
  613. char *usname = (char*)malloc(sizeof(char)*(ulen+1));
  614. strncpy(usname,user,ulen);
  615. usname[ulen]=0;
  616. if(SASLprep((u08bits*)usname)<0) {
  617. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user name: %s\n",user);
  618. free(usname);
  619. return -1;
  620. }
  621. s = skip_blanks(s+1);
  622. hmackey_t *key = (hmackey_t*)malloc(sizeof(hmackey_t));
  623. if(strstr(s,"0x")==s) {
  624. char *keysource = s + 2;
  625. size_t sz = get_hmackey_size(SHATYPE_DEFAULT);
  626. if(strlen(keysource)<sz*2) {
  627. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key format: %s\n",s);
  628. } if(convert_string_key_to_binary(keysource, *key, sz)<0) {
  629. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key: %s\n",s);
  630. free(usname);
  631. free(key);
  632. return -1;
  633. }
  634. } else {
  635. //this is only for default realm
  636. stun_produce_integrity_key_str((u08bits*)usname, (u08bits*)get_realm(NULL)->options.name, (u08bits*)s, *key, SHATYPE_DEFAULT);
  637. }
  638. {
  639. ur_string_map_lock(turn_params.default_users_db.ram_db.static_accounts);
  640. ur_string_map_put(turn_params.default_users_db.ram_db.static_accounts, (ur_string_map_key_type)usname, (ur_string_map_value_type)*key);
  641. ur_string_map_unlock(turn_params.default_users_db.ram_db.static_accounts);
  642. }
  643. turn_params.default_users_db.ram_db.users_number++;
  644. free(usname);
  645. return 0;
  646. }
  647. }
  648. return -1;
  649. }
  650. ////////////////// Admin /////////////////////////
  651. static int list_users(u08bits *realm, int is_admin)
  652. {
  653. const turn_dbdriver_t * dbd = get_dbdriver();
  654. if (dbd) {
  655. if(is_admin) {
  656. if(dbd->list_admin_users) {
  657. (*dbd->list_admin_users)(0);
  658. }
  659. } else {
  660. if(dbd->list_users) {
  661. (*dbd->list_users)(realm,NULL,NULL);
  662. }
  663. }
  664. }
  665. return 0;
  666. }
  667. static int show_secret(u08bits *realm)
  668. {
  669. const turn_dbdriver_t * dbd = get_dbdriver();
  670. if (dbd && dbd->list_secrets) {
  671. (*dbd->list_secrets)(realm,NULL,NULL);
  672. }
  673. return 0;
  674. }
  675. static int del_secret(u08bits *secret, u08bits *realm) {
  676. must_set_admin_realm(realm);
  677. const turn_dbdriver_t * dbd = get_dbdriver();
  678. if (dbd && dbd->del_secret) {
  679. (*dbd->del_secret)(secret, realm);
  680. }
  681. return 0;
  682. }
  683. static int set_secret(u08bits *secret, u08bits *realm) {
  684. if(!secret || (secret[0]==0))
  685. return 0;
  686. must_set_admin_realm(realm);
  687. del_secret(secret, realm);
  688. const turn_dbdriver_t * dbd = get_dbdriver();
  689. if (dbd && dbd->set_secret) {
  690. (*dbd->set_secret)(secret, realm);
  691. }
  692. return 0;
  693. }
  694. static int add_origin(u08bits *origin0, u08bits *realm)
  695. {
  696. u08bits origin[STUN_MAX_ORIGIN_SIZE+1];
  697. get_canonic_origin((const char *)origin0, (char *)origin, sizeof(origin)-1);
  698. const turn_dbdriver_t * dbd = get_dbdriver();
  699. if (dbd && dbd->add_origin) {
  700. (*dbd->add_origin)(origin, realm);
  701. }
  702. return 0;
  703. }
  704. static int del_origin(u08bits *origin0)
  705. {
  706. u08bits origin[STUN_MAX_ORIGIN_SIZE+1];
  707. get_canonic_origin((const char *)origin0, (char *)origin, sizeof(origin)-1);
  708. const turn_dbdriver_t * dbd = get_dbdriver();
  709. if (dbd && dbd->del_origin) {
  710. (*dbd->del_origin)(origin);
  711. }
  712. return 0;
  713. }
  714. static int list_origins(u08bits *realm)
  715. {
  716. const turn_dbdriver_t * dbd = get_dbdriver();
  717. if (dbd && dbd->list_origins) {
  718. (*dbd->list_origins)(realm,NULL,NULL);
  719. }
  720. return 0;
  721. }
  722. static int set_realm_option_one(u08bits *realm, unsigned long value, const char* opt)
  723. {
  724. if(value == (unsigned long)-1)
  725. return 0;
  726. const turn_dbdriver_t * dbd = get_dbdriver();
  727. if (dbd && dbd->set_realm_option_one) {
  728. (*dbd->set_realm_option_one)(realm, value, opt);
  729. }
  730. return 0;
  731. }
  732. static int set_realm_option(u08bits *realm, perf_options_t *po)
  733. {
  734. set_realm_option_one(realm,(unsigned long)po->max_bps,"max-bps");
  735. set_realm_option_one(realm,(unsigned long)po->user_quota,"user-quota");
  736. set_realm_option_one(realm,(unsigned long)po->total_quota,"total-quota");
  737. return 0;
  738. }
  739. static int list_realm_options(u08bits *realm)
  740. {
  741. const turn_dbdriver_t * dbd = get_dbdriver();
  742. if (dbd && dbd->list_realm_options) {
  743. (*dbd->list_realm_options)(realm);
  744. }
  745. return 0;
  746. }
  747. int adminuser(u08bits *user, u08bits *realm, u08bits *pwd, u08bits *secret, u08bits *origin, TURNADMIN_COMMAND_TYPE ct, perf_options_t *po, int is_admin)
  748. {
  749. hmackey_t key;
  750. char skey[sizeof(hmackey_t) * 2 + 1];
  751. if (ct == TA_LIST_USERS) {
  752. return list_users(realm, is_admin);
  753. }
  754. if (ct == TA_LIST_ORIGINS) {
  755. return list_origins(realm);
  756. }
  757. if (ct == TA_SHOW_SECRET) {
  758. return show_secret(realm);
  759. }
  760. if (ct == TA_SET_SECRET) {
  761. return set_secret(secret, realm);
  762. }
  763. if (ct == TA_DEL_SECRET) {
  764. return del_secret(secret, realm);
  765. }
  766. if (ct == TA_ADD_ORIGIN) {
  767. must_set_admin_origin(origin);
  768. must_set_admin_realm(realm);
  769. return add_origin(origin, realm);
  770. }
  771. if (ct == TA_DEL_ORIGIN) {
  772. must_set_admin_origin(origin);
  773. return del_origin(origin);
  774. }
  775. if (ct == TA_SET_REALM_OPTION) {
  776. must_set_admin_realm(realm);
  777. if (!(po && (po->max_bps != ((band_limit_t) -1) || po->total_quota >= 0 || po->user_quota >= 0))) {
  778. fprintf(stderr, "The operation cannot be completed: a realm option must be set.\n");
  779. exit(-1);
  780. }
  781. return set_realm_option(realm, po);
  782. }
  783. if (ct == TA_LIST_REALM_OPTIONS) {
  784. return list_realm_options(realm);
  785. }
  786. must_set_admin_user(user);
  787. if (ct != TA_DELETE_USER && !is_admin) {
  788. must_set_admin_pwd(pwd);
  789. {
  790. stun_produce_integrity_key_str(user, realm, pwd, key, SHATYPE_DEFAULT);
  791. size_t i = 0;
  792. size_t sz = get_hmackey_size(SHATYPE_DEFAULT);
  793. int maxsz = (int) (sz * 2) + 1;
  794. char *s = skey;
  795. for (i = 0; (i < sz) && (maxsz > 2); i++) {
  796. snprintf(s, (size_t) (sz * 2), "%02x", (unsigned int) key[i]);
  797. maxsz -= 2;
  798. s += 2;
  799. }
  800. skey[sz * 2] = 0;
  801. }
  802. }
  803. const turn_dbdriver_t * dbd = get_dbdriver();
  804. if (ct == TA_PRINT_KEY) {
  805. printf("0x%s\n", skey);
  806. } else if (dbd) {
  807. if(!is_admin)
  808. must_set_admin_realm(realm);
  809. if (ct == TA_DELETE_USER) {
  810. if(is_admin) {
  811. if (dbd->del_admin_user)
  812. (*dbd->del_admin_user)(user);
  813. } else {
  814. if (dbd->del_user)
  815. (*dbd->del_user)(user, realm);
  816. }
  817. } else if (ct == TA_UPDATE_USER) {
  818. if(is_admin) {
  819. must_set_admin_pwd(pwd);
  820. if (dbd->set_admin_user) {
  821. password_t password;
  822. generate_new_enc_password((char*)pwd,(char*)password);
  823. (*dbd->set_admin_user)(user, realm, password);
  824. }
  825. } else {
  826. if (dbd->set_user_key)
  827. (*dbd->set_user_key)(user, realm, skey);
  828. }
  829. }
  830. }
  831. return 0;
  832. }
  833. /////////// PING //////////////
  834. void auth_ping(redis_context_handle rch)
  835. {
  836. const turn_dbdriver_t * dbd = get_dbdriver();
  837. if (dbd && dbd->auth_ping) {
  838. (*dbd->auth_ping)(rch);
  839. }
  840. }
  841. ///////////////// TEST /////////////////
  842. #if defined(DB_TEST)
  843. void run_db_test(void)
  844. {
  845. turn_dbdriver_t * dbd = get_dbdriver();
  846. if (dbd) {
  847. printf("DB TEST 1:\n");
  848. dbd->list_oauth_keys();
  849. printf("DB TEST 2:\n");
  850. oauth_key_data_raw key_;
  851. oauth_key_data_raw *key=&key_;
  852. dbd->get_oauth_key((const u08bits*)"north",key);
  853. printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s\n",
  854. key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->as_rs_alg);
  855. printf("DB TEST 3:\n");
  856. STRCPY(key->as_rs_alg,"as_rs_alg");
  857. STRCPY(key->ikm_key,"ikm_key");
  858. STRCPY(key->kid,"kid");
  859. key->timestamp = 123;
  860. key->lifetime = 456;
  861. dbd->del_oauth_key((const u08bits*)"kid");
  862. dbd->set_oauth_key(key);
  863. dbd->list_oauth_keys();
  864. printf("DB TEST 4:\n");
  865. dbd->get_oauth_key((const u08bits*)"kid",key);
  866. printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s\n",
  867. key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->as_rs_alg);
  868. printf("DB TEST 5:\n");
  869. dbd->del_oauth_key((const u08bits*)"kid");
  870. dbd->list_oauth_keys();
  871. printf("DB TEST 6:\n");
  872. dbd->get_oauth_key((const u08bits*)"north",key);
  873. oauth_key_data oakd;
  874. convert_oauth_key_data_raw(key, &oakd);
  875. printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, as_rs_alg=%s\n",
  876. oakd.kid, oakd.ikm_key, (unsigned long long)oakd.timestamp, (unsigned long)oakd.lifetime, oakd.as_rs_alg);
  877. oauth_key oak;
  878. char err_msg[1025];
  879. err_msg[0]=0;
  880. if(convert_oauth_key_data(&oakd,&oak,err_msg,sizeof(err_msg)-1)<0) {
  881. printf(" ERROR: %s\n",err_msg);
  882. } else {
  883. printf(" OK!\n");
  884. }
  885. printf("DB TEST END\n");
  886. }
  887. }
  888. #endif
  889. ///////////////// WHITE/BLACK IP LISTS ///////////////////
  890. #if !defined(TURN_NO_RWLOCK)
  891. static pthread_rwlock_t* whitelist_rwlock = NULL;
  892. static pthread_rwlock_t* blacklist_rwlock = NULL;
  893. #else
  894. static turn_mutex whitelist_mutex;
  895. static turn_mutex blacklist_mutex;
  896. #endif
  897. static ip_range_list_t* ipwhitelist = NULL;
  898. static ip_range_list_t* ipblacklist = NULL;
  899. void init_dynamic_ip_lists(void)
  900. {
  901. #if !defined(TURN_NO_RWLOCK)
  902. whitelist_rwlock = (pthread_rwlock_t*) malloc(sizeof(pthread_rwlock_t));
  903. pthread_rwlock_init(whitelist_rwlock, NULL);
  904. blacklist_rwlock = (pthread_rwlock_t*) malloc(sizeof(pthread_rwlock_t));
  905. pthread_rwlock_init(blacklist_rwlock, NULL);
  906. #else
  907. turn_mutex_init(&whitelist_mutex);
  908. turn_mutex_init(&blacklist_mutex);
  909. #endif
  910. }
  911. void ioa_lock_whitelist(ioa_engine_handle e)
  912. {
  913. UNUSED_ARG(e);
  914. #if !defined(TURN_NO_RWLOCK)
  915. pthread_rwlock_rdlock(whitelist_rwlock);
  916. #else
  917. turn_mutex_lock(&whitelist_mutex);
  918. #endif
  919. }
  920. void ioa_unlock_whitelist(ioa_engine_handle e)
  921. {
  922. UNUSED_ARG(e);
  923. #if !defined(TURN_NO_RWLOCK)
  924. pthread_rwlock_unlock(whitelist_rwlock);
  925. #else
  926. turn_mutex_unlock(&whitelist_mutex);
  927. #endif
  928. }
  929. static void ioa_wrlock_whitelist(ioa_engine_handle e)
  930. {
  931. UNUSED_ARG(e);
  932. #if !defined(TURN_NO_RWLOCK)
  933. pthread_rwlock_wrlock(whitelist_rwlock);
  934. #else
  935. turn_mutex_lock(&whitelist_mutex);
  936. #endif
  937. }
  938. const ip_range_list_t* ioa_get_whitelist(ioa_engine_handle e)
  939. {
  940. UNUSED_ARG(e);
  941. return ipwhitelist;
  942. }
  943. void ioa_lock_blacklist(ioa_engine_handle e)
  944. {
  945. UNUSED_ARG(e);
  946. #if !defined(TURN_NO_RWLOCK)
  947. pthread_rwlock_rdlock(blacklist_rwlock);
  948. #else
  949. turn_mutex_lock(&blacklist_mutex);
  950. #endif
  951. }
  952. void ioa_unlock_blacklist(ioa_engine_handle e)
  953. {
  954. UNUSED_ARG(e);
  955. #if !defined(TURN_NO_RWLOCK)
  956. pthread_rwlock_unlock(blacklist_rwlock);
  957. #else
  958. turn_mutex_unlock(&blacklist_mutex);
  959. #endif
  960. }
  961. static void ioa_wrlock_blacklist(ioa_engine_handle e)
  962. {
  963. UNUSED_ARG(e);
  964. #if !defined(TURN_NO_RWLOCK)
  965. pthread_rwlock_wrlock(blacklist_rwlock);
  966. #else
  967. turn_mutex_lock(&blacklist_mutex);
  968. #endif
  969. }
  970. const ip_range_list_t* ioa_get_blacklist(ioa_engine_handle e)
  971. {
  972. UNUSED_ARG(e);
  973. return ipblacklist;
  974. }
  975. ip_range_list_t* get_ip_list(const char *kind)
  976. {
  977. ip_range_list_t *ret = (ip_range_list_t*) malloc(sizeof(ip_range_list_t));
  978. bzero(ret,sizeof(ip_range_list_t));
  979. const turn_dbdriver_t * dbd = get_dbdriver();
  980. if (dbd && dbd->get_ip_list) {
  981. (*dbd->get_ip_list)(kind, ret);
  982. }
  983. return ret;
  984. }
  985. void ip_list_free(ip_range_list_t *l)
  986. {
  987. if(l) {
  988. if(l->rs)
  989. free(l->rs);
  990. free(l);
  991. }
  992. }
  993. void update_white_and_black_lists(void)
  994. {
  995. {
  996. ip_range_list_t *wl = get_ip_list("allowed");
  997. ip_range_list_t *owl = NULL;
  998. ioa_wrlock_whitelist(NULL);
  999. owl = ipwhitelist;
  1000. ipwhitelist = wl;
  1001. ioa_unlock_whitelist(NULL);
  1002. ip_list_free(owl);
  1003. }
  1004. {
  1005. ip_range_list_t *bl = get_ip_list("denied");
  1006. ip_range_list_t *obl = NULL;
  1007. ioa_wrlock_blacklist(NULL);
  1008. obl = ipblacklist;
  1009. ipblacklist = bl;
  1010. ioa_unlock_blacklist(NULL);
  1011. ip_list_free(obl);
  1012. }
  1013. }
  1014. /////////////// add ACL record ///////////////////
  1015. int add_ip_list_range(const char * range0, const char * realm, ip_range_list_t * list)
  1016. {
  1017. char *range = strdup(range0);
  1018. char* separator = strchr(range, '-');
  1019. if (separator) {
  1020. *separator = '\0';
  1021. }
  1022. ioa_addr min, max;
  1023. if (make_ioa_addr((const u08bits*) range, 0, &min) < 0) {
  1024. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong address format: %s\n", range);
  1025. free(range);
  1026. return -1;
  1027. }
  1028. if (separator) {
  1029. if (make_ioa_addr((const u08bits*) separator + 1, 0, &max) < 0) {
  1030. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong address format: %s\n", separator + 1);
  1031. free(range);
  1032. return -1;
  1033. }
  1034. } else {
  1035. // Doesn't have a '-' character in it, so assume that this is a single address
  1036. addr_cpy(&max, &min);
  1037. }
  1038. if (separator)
  1039. *separator = '-';
  1040. ++(list->ranges_number);
  1041. list->rs = (ip_range_t*) realloc(list->rs, sizeof(ip_range_t) * list->ranges_number);
  1042. STRCPY(list->rs[list->ranges_number - 1].str,range);
  1043. if(realm)
  1044. STRCPY(list->rs[list->ranges_number - 1].realm,realm);
  1045. else
  1046. list->rs[list->ranges_number - 1].realm[0]=0;
  1047. free(range);
  1048. ioa_addr_range_set(&(list->rs[list->ranges_number - 1].enc), &min, &max);
  1049. return 0;
  1050. }
  1051. int check_ip_list_range(const char * range0)
  1052. {
  1053. char *range = strdup(range0);
  1054. char* separator = strchr(range, '-');
  1055. if (separator) {
  1056. *separator = '\0';
  1057. }
  1058. ioa_addr min, max;
  1059. if (make_ioa_addr((const u08bits*) range, 0, &min) < 0) {
  1060. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong address range format: %s\n", range);
  1061. free(range);
  1062. return -1;
  1063. }
  1064. if (separator) {
  1065. if (make_ioa_addr((const u08bits*) separator + 1, 0, &max) < 0) {
  1066. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong address range format: %s\n", separator + 1);
  1067. free(range);
  1068. return -1;
  1069. }
  1070. } else {
  1071. // Doesn't have a '-' character in it, so assume that this is a single address
  1072. addr_cpy(&max, &min);
  1073. }
  1074. if (separator)
  1075. *separator = '-';
  1076. free(range);
  1077. return 0;
  1078. }
  1079. /////////// REALM //////////////
  1080. void reread_realms(void)
  1081. {
  1082. {
  1083. realm_params_t* defrp = get_realm(NULL);
  1084. lock_realms();
  1085. defrp->options.perf_options.max_bps = turn_params.max_bps;
  1086. defrp->options.perf_options.total_quota = turn_params.total_quota;
  1087. defrp->options.perf_options.user_quota = turn_params.user_quota;
  1088. unlock_realms();
  1089. }
  1090. const turn_dbdriver_t * dbd = get_dbdriver();
  1091. if (dbd && dbd->reread_realms) {
  1092. (*dbd->reread_realms)(&realms_list);
  1093. }
  1094. }
  1095. ///////////////////////////////