CUBRID Engine  latest
broker_acl.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 
20 /*
21  * broker_acl.c -
22  */
23 
24 #ident "$Id$"
25 
26 #include <assert.h>
27 #include <errno.h>
28 
29 #include "porting.h"
30 #include "broker_acl.h"
31 #include "cas_error.h"
32 #include "broker_util.h"
33 #include "broker_filename.h"
34 
35 #define ADMIN_ERR_MSG_SIZE BROKER_PATH_MAX * 2
36 #define ACCESS_FILE_DELIMITER ":"
37 #define IP_FILE_DELIMITER ","
38 
42 
43 static ACCESS_INFO *access_control_find_access_info (ACCESS_INFO ai[], int size, char *dbname, char *dbuser);
44 static int access_control_read_ip_info (IP_INFO * ip_info, char *filename, char *admin_err_msg);
45 static void access_control_repath_file (char *path);
47  unsigned char *address);
48 static int access_control_check_ip (T_SHM_APPL_SERVER * shm_as_p, IP_INFO * ip_info, unsigned char *address,
49  int info_index);
50 static int record_ip_access_time (T_SHM_APPL_SERVER * shm_as_p, int info_index, int list_index);
51 
52 int
54  char *admin_err_msg)
55 {
56  shm_as_p->access_control = shm_br->access_control;
57  shm_as_p->acl_chn = 0;
58 
59  if (shm_br->access_control && shm_br->access_control_file[0] != '\0')
60  {
61  char *access_file_name;
62 #if defined (WINDOWS)
63  char sem_name[BROKER_NAME_LEN];
64 
65  MAKE_ACL_SEM_NAME (sem_name, br_info_p->name);
66 
67  if (uw_sem_init (sem_name) < 0)
68  {
69  sprintf (admin_err_msg, "%s: cannot initialize acl semaphore", br_info_p->name);
70  return -1;
71  }
72 #else
73  if (uw_sem_init (&shm_as_p->acl_sem) < 0)
74  {
75  sprintf (admin_err_msg, "%s: cannot initialize acl semaphore", br_info_p->name);
76  return -1;
77  }
78 #endif
79  if (shm_br->access_control_file[0] != '\0')
80  {
82  access_file_name = get_cubrid_file_ptr (FID_ACCESS_CONTROL_FILE);
83  if (access_control_read_config_file (shm_as_p, access_file_name, admin_err_msg) != 0)
84  {
85  return -1;
86  }
87  }
88  }
89 
90  memcpy (shm_as_p->local_ip_addr, shm_br->my_ip_addr, 4);
91 
92  return 0;
93 }
94 
95 static ACCESS_INFO *
97 {
98  int i;
99 
100  for (i = 0; i < size; i++)
101  {
102  if (strcmp (ai[i].dbname, dbname) == 0 && strcmp (ai[i].dbuser, dbuser) == 0)
103  {
104  return &ai[i];
105  }
106  }
107 
108  return NULL;
109 }
110 
111 int
113 {
114  char buf[1024], path_buf[BROKER_PATH_MAX], *files, *token, *save = NULL;
115  FILE *fd_access_list;
116  int num_access_list = 0, line = 0;
117  ACCESS_INFO new_access_info[ACL_MAX_ITEM_COUNT];
119  bool is_current_broker_section;
120 #if defined(WINDOWS)
121  char acl_sem_name[BROKER_NAME_LEN];
122 #endif
123 
124  fd_access_list = fopen (filename, "r");
125 
126  if (fd_access_list == NULL)
127  {
128  sprintf (admin_err_msg, "%s: error while loading access control file(%s)", shm_appl->broker_name, filename);
129  return -1;
130  }
131 
132  is_current_broker_section = false;
133 
134  memset (new_access_info, '\0', sizeof (new_access_info));
135 
136  while (fgets (buf, 1024, fd_access_list))
137  {
138  char *dbname, *dbuser, *ip_file, *p;
139 
140  line++;
141  p = strchr (buf, '#');
142  if (p != NULL)
143  {
144  *p = '\0';
145  }
146 
147  trim (buf);
148 
149  if (buf[0] == '\0')
150  {
151  continue;
152  }
153 
154  if (is_current_broker_section == false && strncmp (buf, "[%", 2) == 0 && buf[strlen (buf) - 1] == ']')
155  {
156  buf[strlen (buf) - 1] = '\0';
157  if (strcasecmp (shm_appl->broker_name, buf + 2) == 0)
158  {
159  is_current_broker_section = true;
160  continue;
161  }
162  }
163  if (is_current_broker_section == false)
164  {
165  continue;
166  }
167 
168  if (strncmp (buf, "[%", 2) == 0 && buf[strlen (buf) - 1] == ']')
169  {
170  buf[strlen (buf) - 1] = '\0';
171  if (strcasecmp (shm_appl->broker_name, buf + 2) != 0)
172  {
173  break;
174  }
175  }
176 
177  if (num_access_list >= ACL_MAX_ITEM_COUNT)
178  {
179  sprintf (admin_err_msg, "%s: error while loading access control file(%s)" " - max item count(%d) exceeded.",
180  shm_appl->broker_name, filename, ACL_MAX_ITEM_COUNT);
181  goto error;
182  }
183 
184  dbname = strtok_r (buf, ACCESS_FILE_DELIMITER, &p);
185  if (dbname == NULL || strlen (dbname) > (ACL_MAX_DBNAME_LENGTH - 1))
186  {
187  sprintf (admin_err_msg,
188  "%s: error while loading access control file(%s:%d)" " - Database name is empty or too long.",
189  shm_appl->broker_name, filename, line);
190  goto error;
191  }
192 
193  dbuser = strtok_r (NULL, ACCESS_FILE_DELIMITER, &p);
194  if (dbuser == NULL || strlen (dbuser) > (ACL_MAX_DBUSER_LENGTH - 1))
195  {
196  sprintf (admin_err_msg,
197  "%s: error while loading access control file(%s:%d)" " - Database user is empty or too long.",
198  shm_appl->broker_name, filename, line);
199  goto error;
200  }
201 
202  ip_file = p;
203  if (ip_file == NULL)
204  {
205  sprintf (admin_err_msg,
206  "%s: error while loading access control file(%s:%d)" " - IP list file paths are empty.",
207  shm_appl->broker_name, filename, line);
208  goto error;
209  }
210 
211  access_info = access_control_find_access_info (new_access_info, num_access_list, dbname, dbuser);
212  if (access_info == NULL)
213  {
214  access_info = &new_access_info[num_access_list];
215  strncpy (access_info->dbname, dbname, ACL_MAX_DBNAME_LENGTH);
216  strncpy (access_info->dbuser, dbuser, ACL_MAX_DBUSER_LENGTH);
217  num_access_list++;
218  }
219 
220  if (access_info->ip_files[0] != '\0')
221  {
222  strncat (access_info->ip_files, ",", LINE_MAX - 1);
223  }
224  strncat (access_info->ip_files, ip_file, LINE_MAX - 1);
225  for (files = ip_file;; files = NULL)
226  {
227  token = strtok_r (files, IP_FILE_DELIMITER, &save);
228  if (token == NULL)
229  {
230  break;
231  }
232 
233  if (strlen (token) > BROKER_PATH_MAX - 1)
234  {
235  snprintf (admin_err_msg, ADMIN_ERR_MSG_SIZE,
236  "%s: error while loading access control file(%s)" " - a IP file path(%s) is too long",
237  shm_appl->broker_name, filename, token);
238  goto error;
239  }
240 
241  strncpy (path_buf, token, BROKER_PATH_MAX);
242  access_control_repath_file (path_buf);
243  if (access_control_read_ip_info (&(access_info->ip_info), path_buf, admin_err_msg) < 0)
244  {
245  goto error;
246  }
247  }
248  }
249 
250  fclose (fd_access_list);
251 
252 #if defined (WINDOWS)
253  MAKE_ACL_SEM_NAME (acl_sem_name, shm_appl->broker_name);
254  uw_sem_wait (acl_sem_name);
255 #else
256  uw_sem_wait (&shm_appl->acl_sem);
257 #endif
258 
259  memcpy (shm_appl->access_info, new_access_info, sizeof (new_access_info));
260  shm_appl->num_access_info = num_access_list;
261  shm_appl->acl_chn++;
262 
263 #if defined(WINDOWS)
264  uw_sem_post (acl_sem_name);
265 #else
266  uw_sem_post (&shm_appl->acl_sem);
267 #endif
268 
269  return 0;
270 
271 error:
272  fclose (fd_access_list);
273 
274  return -1;
275 }
276 
277 static void
279 {
280  char tmp_str[BROKER_PATH_MAX];
281 
282  trim (path);
283  strncpy (tmp_str, path, BROKER_PATH_MAX);
284  tmp_str[BROKER_PATH_MAX - 1] = 0;
285 
286  MAKE_FILEPATH (path, tmp_str, BROKER_PATH_MAX);
287 
288  if (IS_ABS_PATH (path))
289  {
290  return;
291  }
292 
293 #if !defined(CAS_FOR_ORACLE) && !defined(CAS_FOR_MYSQL)
294  envvar_confdir_file (tmp_str, BROKER_PATH_MAX, path);
295  MAKE_FILEPATH (path, tmp_str, BROKER_PATH_MAX);
296 #endif
297 
298  return;
299 }
300 
301 static int
303 {
304  char buf[LINE_MAX];
305  char *save;
306  FILE *fd_ip_list;
307  unsigned char i;
308  unsigned int ln = 0;
309 
310  fd_ip_list = fopen (filename, "r");
311 
312  if (fd_ip_list == NULL)
313  {
314  sprintf (admin_err_msg, "Could not open ip info file(%s)", filename);
315  return -1;
316  }
317 
318  buf[LINE_MAX - 2] = 0;
319  while (fgets (buf, LINE_MAX, fd_ip_list))
320  {
321  char *token, *p;
322  int address_index;
323 
324  ln++;
325  if (buf[LINE_MAX - 2] != 0 && buf[LINE_MAX - 2] != '\n')
326  {
327  sprintf (admin_err_msg, "Error while loading ip info file(%s)" " - %d line is too long", filename, ln);
328  goto error;
329  }
330 
331  p = strchr (buf, '#');
332  if (p != NULL)
333  {
334  *p = '\0';
335  }
336 
337  trim (buf);
338  if (buf[0] == '\0')
339  {
340  continue;
341  }
342 
343  if (ip_info->num_list >= ACL_MAX_IP_COUNT)
344  {
345  sprintf (admin_err_msg, "Error while loading ip info file(%s) line(%d)" " - max ip count(%d) exceeded.",
346  filename, ln, ACL_MAX_IP_COUNT);
347  goto error;
348  }
349 
350  token = strtok_r (buf, ".", &save);
351 
352  address_index = ip_info->num_list * IP_BYTE_COUNT;
353  for (i = 0; i < 4; i++)
354  {
355  if (token == NULL)
356  {
357  sprintf (admin_err_msg, "Error while loading ip info file(%s) line(%d)", filename, ln);
358  goto error;
359  }
360 
361  if (strcmp (token, "*") == 0)
362  {
363  break;
364  }
365  else
366  {
367  int adr = 0, result;
368 
369  result = parse_int (&adr, token, 10);
370 
371  if (result != 0 || adr > 255 || adr < 0)
372  {
373  sprintf (admin_err_msg, "Error while loading ip info file(%s) line(%d)", filename, ln);
374  goto error;
375  }
376 
377  ip_info->address_list[address_index + 1 + i] = (unsigned char) adr;
378  }
379 
380  token = strtok_r (NULL, ".", &save);
381  if (i == 3 && token != NULL)
382  {
383  sprintf (admin_err_msg, "Error while loading ip info file(%s) line(%d)", filename, ln);
384  goto error;
385  }
386  }
387  ip_info->address_list[address_index] = i;
388  ip_info->last_access_time[ip_info->num_list] = 0;
389  ip_info->num_list++;
390  }
391 
392  fclose (fd_ip_list);
393  return 0;
394 
395 error:
396  fclose (fd_ip_list);
397  return -1;
398 }
399 
400 int
401 access_control_check_right (T_SHM_APPL_SERVER * shm_as_p, char *dbname, char *dbuser, unsigned char *address)
402 {
403  if (access_info_changed != shm_as_p->acl_chn)
404  {
405 #if defined (WINDOWS)
406  char acl_sem_name[BROKER_NAME_LEN];
407 
408  MAKE_ACL_SEM_NAME (acl_sem_name, shm_as_p->broker_name);
409  uw_sem_wait (acl_sem_name);
410 #else
411  uw_sem_wait (&shm_as_p->acl_sem);
412 #endif
413  memcpy (access_info, shm_as_p->access_info, sizeof (access_info));
414  num_access_info = shm_as_p->num_access_info;
415  access_info_changed = shm_as_p->acl_chn;
416 #if defined (WINDOWS)
417  uw_sem_post (acl_sem_name);
418 #else
419  uw_sem_post (&shm_as_p->acl_sem);
420 #endif
421  }
422 
423  return (access_control_check_right_internal (shm_as_p, dbname, dbuser, address));
424 }
425 
426 static int
428 {
429  int i;
430  char *address_ptr;
431  int ret_val = -1;
432  bool local_ip_flag = false;
433 
434  if (address[0] == 127 && address[1] == 0 && address[2] == 0 && address[3] == 1)
435  {
436  local_ip_flag = true;
437  }
438 
439  address_ptr = strchr (dbname, '@');
440  if (address_ptr != NULL)
441  {
442  *address_ptr = '\0';
443  }
444 
445  for (i = 0; i < num_access_info; i++)
446  {
447  if ((strcmp (access_info[i].dbname, "*") == 0
448  || strncasecmp (access_info[i].dbname, dbname, ACL_MAX_DBNAME_LENGTH) == 0)
449  && (strcmp (access_info[i].dbuser, "*") == 0
450  || strncasecmp (access_info[i].dbuser, dbuser, ACL_MAX_DBUSER_LENGTH) == 0))
451  {
452  if (access_control_check_ip (shm_as_p, &access_info[i].ip_info, address, i) == 0)
453  {
454  ret_val = 0;
455  break;
456  }
457 
458  if (local_ip_flag == true
459  && access_control_check_ip (shm_as_p, &access_info[i].ip_info, shm_as_p->local_ip_addr, i) == 0)
460  {
461  break;
462  }
463  }
464  }
465 
466  if (address_ptr != NULL)
467  {
468  *address_ptr = '@';
469  }
470 
471  if (local_ip_flag == true)
472  {
473  return 0;
474  }
475 
476  return ret_val;
477 }
478 
479 static int
480 access_control_check_ip (T_SHM_APPL_SERVER * shm_as_p, IP_INFO * ip_info, unsigned char *address, int info_index)
481 {
482  int i;
483 
484  assert (ip_info && address);
485 
486  for (i = 0; i < ip_info->num_list; i++)
487  {
488  int address_index = i * IP_BYTE_COUNT;
489 
490  if (ip_info->address_list[address_index] == 0)
491  {
492  record_ip_access_time (shm_as_p, info_index, i);
493  return 0;
494  }
495  else
496  if (memcmp
497  ((void *) &ip_info->address_list[address_index + 1], (void *) address,
498  ip_info->address_list[address_index]) == 0)
499  {
500  record_ip_access_time (shm_as_p, info_index, i);
501  return 0;
502  }
503  }
504 
505  return -1;
506 }
507 
508 static int
509 record_ip_access_time (T_SHM_APPL_SERVER * shm_as_p, int info_index, int list_index)
510 {
511 #if defined (WINDOWS)
512  char acl_sem_name[BROKER_NAME_LEN];
513 #endif
514  if (access_info_changed != shm_as_p->acl_chn)
515  {
516  return -1;
517  }
518 #if defined (WINDOWS)
519  MAKE_ACL_SEM_NAME (acl_sem_name, shm_as_p->broker_name);
520  uw_sem_wait (acl_sem_name);
521 #else
522  uw_sem_wait (&shm_as_p->acl_sem);
523 #endif
524  shm_as_p->access_info[info_index].ip_info.last_access_time[list_index] = time (NULL);
525 #if defined (WINDOWS)
526  uw_sem_post (acl_sem_name);
527 #else
528  uw_sem_post (&shm_as_p->acl_sem);
529 #endif
530 
531  return 0;
532 }
unsigned char address_list[ACL_MAX_IP_COUNT *IP_BYTE_COUNT]
Definition: broker_shm.h:202
char * trim(char *str)
Definition: porting.c:2260
static char * dbuser
int access_control_read_config_file(T_SHM_APPL_SERVER *shm_appl, char *filename, char *admin_err_msg)
Definition: broker_acl.c:112
#define ACL_MAX_IP_COUNT
Definition: broker_shm.h:131
unsigned char local_ip_addr[4]
Definition: broker_shm.h:594
int parse_int(int *ret_p, const char *str_p, int base)
Definition: porting.c:2290
#define MAKE_FILEPATH(dest, src, dest_len)
Definition: broker_util.h:49
#define BROKER_PATH_MAX
Definition: broker_config.h:91
int access_control_check_right(T_SHM_APPL_SERVER *shm_as_p, char *dbname, char *dbuser, unsigned char *address)
Definition: broker_acl.c:401
static T_BROKER_INFO * br_info_p
Definition: broker.c:312
int uw_sem_post(sem_t *sem)
Definition: broker_shm.c:893
int access_info_changed
Definition: broker_acl.c:41
IP_INFO ip_info
Definition: broker_shm.h:213
int uw_sem_init(sem_t *sem)
Definition: broker_shm.c:834
ACCESS_INFO access_info[ACL_MAX_ITEM_COUNT]
Definition: broker_shm.h:635
unsigned char my_ip_addr[4]
Definition: broker_shm.h:654
ACCESS_INFO access_info[ACL_MAX_ITEM_COUNT]
Definition: broker_acl.c:39
char broker_name[BROKER_NAME_LEN]
Definition: broker_shm.h:588
int access_control_set_shm(T_SHM_APPL_SERVER *shm_as_p, T_BROKER_INFO *br_info_p, T_SHM_BROKER *shm_br, char *admin_err_msg)
Definition: broker_acl.c:53
static void access_control_repath_file(char *path)
Definition: broker_acl.c:278
static int access_control_check_right_internal(T_SHM_APPL_SERVER *shm_as_p, char *dbname, char *dbuser, unsigned char *address)
Definition: broker_acl.c:427
#define ACL_MAX_DBNAME_LENGTH
Definition: broker_shm.h:132
static int access_control_read_ip_info(IP_INFO *ip_info, char *filename, char *admin_err_msg)
Definition: broker_acl.c:302
#define IP_FILE_DELIMITER
Definition: broker_acl.c:37
#define assert(x)
#define ACCESS_FILE_DELIMITER
Definition: broker_acl.c:36
#define NULL
Definition: freelistheap.h:34
#define BROKER_NAME_LEN
Definition: broker_config.h:87
static char * dbname
static int access_control_check_ip(T_SHM_APPL_SERVER *shm_as_p, IP_INFO *ip_info, unsigned char *address, int info_index)
Definition: broker_acl.c:480
int num_access_info
Definition: broker_acl.c:40
static T_SHM_APPL_SERVER * shm_appl
Definition: broker.c:311
#define ACL_MAX_ITEM_COUNT
Definition: broker_shm.h:130
static T_SHM_BROKER * shm_br
Definition: broker.c:310
char admin_err_msg[ADMIN_ERR_MSG_SIZE]
static void error(const char *msg)
Definition: gencat.c:331
#define ACL_MAX_DBUSER_LENGTH
Definition: broker_shm.h:133
char dbname[ACL_MAX_DBNAME_LENGTH]
Definition: broker_shm.h:210
int num_list
Definition: broker_shm.h:204
static ACCESS_INFO * access_control_find_access_info(ACCESS_INFO ai[], int size, char *dbname, char *dbuser)
Definition: broker_acl.c:96
#define strlen(s1)
Definition: intl_support.c:43
char name[BROKER_NAME_LEN]
#define ADMIN_ERR_MSG_SIZE
Definition: broker_acl.c:35
int i
Definition: dynamic_load.c:954
#define IS_ABS_PATH(p)
Definition: porting.h:357
int uw_sem_wait(sem_t *sem)
Definition: broker_shm.c:867
void set_cubrid_file(T_CUBRID_FILE_ID fid, char *value)
bool access_control
Definition: broker_shm.h:660
char * get_cubrid_file_ptr(T_CUBRID_FILE_ID fid)
T_SHM_APPL_SERVER * shm_as_p
Definition: shard_proxy.c:43
char dbuser[ACL_MAX_DBUSER_LENGTH]
Definition: broker_shm.h:211
char access_control_file[SHM_BROKER_PATH_MAX]
Definition: broker_shm.h:659
time_t last_access_time[ACL_MAX_IP_COUNT]
Definition: broker_shm.h:203
#define IP_BYTE_COUNT
Definition: broker_shm.h:129
const char ** p
Definition: dynamic_load.c:945
char ip_files[LINE_MAX+1]
Definition: broker_shm.h:212
static int record_ip_access_time(T_SHM_APPL_SERVER *shm_as_p, int info_index, int list_index)
Definition: broker_acl.c:509
char * envvar_confdir_file(char *path, size_t size, const char *filename)