OpenVAS Manager  7.0.3~git
manage_acl.c
Go to the documentation of this file.
1 /* OpenVAS Manager
2  * $Id$
3  * Description: Manager Manage library: Access Control "Layer".
4  *
5  * Authors:
6  * Matthew Mundell <matthew.mundell@greenbone.net>
7  *
8  * Copyright:
9  * Copyright (C) 2013 Greenbone Networks GmbH
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25 
34 #include "manage_acl.h"
35 #include "manage_sql.h"
36 #include "sql.h"
37 
38 #include <assert.h>
39 #include <stdlib.h>
40 #include <string.h>
41 
42 #undef G_LOG_DOMAIN
43 
46 #define G_LOG_DOMAIN "md manage"
47 
55 int
56 acl_user_may (const char *operation)
57 {
58  int ret;
59  gchar *quoted_operation;
60 
61  assert (operation);
62 
63  if (strlen (current_credentials.uuid) == 0)
64  /* Allow the dummy user in init_manage to do anything. */
65  return 1;
66 
67  if (sql_int ("SELECT user_can_everything ('%s');",
68  current_credentials.uuid))
69  return 1;
70 
71  quoted_operation = sql_quote (operation);
72 
73  ret = sql_int (ACL_USER_MAY ("0"),
77  quoted_operation,
78  quoted_operation,
79  quoted_operation,
80  quoted_operation);
81 
82  g_free (quoted_operation);
83 
84  return ret;
85 }
86 
94 int
95 acl_role_can_super_everyone (const char *role_id)
96 {
97  gchar *quoted_role_id;
98  quoted_role_id = sql_quote (role_id);
99  if (sql_int (" SELECT EXISTS (SELECT * FROM permissions"
100  " WHERE name = 'Super'"
101  /* Super on everyone. */
102  " AND (resource = 0)"
103  " AND subject_location"
104  " = " G_STRINGIFY (LOCATION_TABLE)
105  " AND (subject_type = 'role'"
106  " AND subject"
107  " = (SELECT id"
108  " FROM roles"
109  " WHERE uuid = '%s')));",
110  role_id))
111  {
112  g_free (quoted_role_id);
113  return 1;
114  }
115  g_free (quoted_role_id);
116  return 0;
117 }
118 
126 int
127 acl_user_can_super_everyone (const char *uuid)
128 {
129  gchar *quoted_uuid;
130 
131  quoted_uuid = sql_quote (uuid);
132  if (sql_int (" SELECT EXISTS (SELECT * FROM permissions"
133  " WHERE name = 'Super'"
134  /* Super on everyone. */
135  " AND (resource = 0)"
136  " AND subject_location"
137  " = " G_STRINGIFY (LOCATION_TABLE)
138  " AND ((subject_type = 'user'"
139  " AND subject"
140  " = (SELECT id FROM users"
141  " WHERE users.uuid = '%s'))"
142  " OR (subject_type = 'group'"
143  " AND subject"
144  " IN (SELECT DISTINCT \"group\""
145  " FROM group_users"
146  " WHERE \"user\""
147  " = (SELECT id"
148  " FROM users"
149  " WHERE users.uuid"
150  " = '%s')))"
151  " OR (subject_type = 'role'"
152  " AND subject"
153  " IN (SELECT DISTINCT role"
154  " FROM role_users"
155  " WHERE \"user\""
156  " = (SELECT id"
157  " FROM users"
158  " WHERE users.uuid"
159  " = '%s')))));",
160  quoted_uuid,
161  quoted_uuid,
162  quoted_uuid))
163  {
164  g_free (quoted_uuid);
165  return 1;
166  }
167  g_free (quoted_uuid);
168  return 0;
169 }
170 
178 int
179 acl_user_can_everything (const char *user_id)
180 {
181  gchar *quoted_user_id;
182  int ret;
183 
184  quoted_user_id = sql_quote (user_id);
185  ret = sql_int ("SELECT count(*) > 0 FROM permissions"
186  " WHERE resource = 0"
187  " AND subject_location"
188  " = " G_STRINGIFY (LOCATION_TABLE)
189  " AND ((subject_type = 'user'"
190  " AND subject"
191  " = (SELECT id FROM users"
192  " WHERE users.uuid = '%s'))"
193  " OR (subject_type = 'group'"
194  " AND subject"
195  " IN (SELECT DISTINCT \"group\""
196  " FROM group_users"
197  " WHERE \"user\" = (SELECT id"
198  " FROM users"
199  " WHERE users.uuid"
200  " = '%s')))"
201  " OR (subject_type = 'role'"
202  " AND subject"
203  " IN (SELECT DISTINCT role"
204  " FROM role_users"
205  " WHERE \"user\" = (SELECT id"
206  " FROM users"
207  " WHERE users.uuid"
208  " = '%s'))))"
209  " AND name = 'Everything';",
210  quoted_user_id,
211  quoted_user_id,
212  quoted_user_id);
213  g_free (quoted_user_id);
214  return ret;
215 }
216 
225 int
226 acl_user_has_super (const char *super_user_id, user_t other_user)
227 {
228  gchar *quoted_super_user_id;
229 
230  quoted_super_user_id = sql_quote (super_user_id);
231  if (sql_int (" SELECT EXISTS (SELECT * FROM permissions"
232  " WHERE name = 'Super'"
233  /* Super on everyone. */
234  " AND ((resource = 0)"
235  /* Super on other_user. */
236  " OR ((resource_type = 'user')"
237  " AND (resource = %llu))"
238  /* Super on other_user's role. */
239  " OR ((resource_type = 'role')"
240  " AND (resource"
241  " IN (SELECT DISTINCT role"
242  " FROM role_users"
243  " WHERE \"user\" = %llu)))"
244  /* Super on other_user's group. */
245  " OR ((resource_type = 'group')"
246  " AND (resource"
247  " IN (SELECT DISTINCT \"group\""
248  " FROM group_users"
249  " WHERE \"user\" = %llu))))"
250  " AND subject_location"
251  " = " G_STRINGIFY (LOCATION_TABLE)
252  " AND ((subject_type = 'user'"
253  " AND subject"
254  " = (SELECT id FROM users"
255  " WHERE users.uuid = '%s'))"
256  " OR (subject_type = 'group'"
257  " AND subject"
258  " IN (SELECT DISTINCT \"group\""
259  " FROM group_users"
260  " WHERE \"user\""
261  " = (SELECT id"
262  " FROM users"
263  " WHERE users.uuid"
264  " = '%s')))"
265  " OR (subject_type = 'role'"
266  " AND subject"
267  " IN (SELECT DISTINCT role"
268  " FROM role_users"
269  " WHERE \"user\""
270  " = (SELECT id"
271  " FROM users"
272  " WHERE users.uuid"
273  " = '%s')))));",
274  other_user,
275  other_user,
276  other_user,
277  super_user_id,
278  super_user_id,
279  super_user_id))
280  {
281  g_free (quoted_super_user_id);
282  return 1;
283  }
284  g_free (quoted_super_user_id);
285  return 0;
286 }
287 
295 int
296 acl_user_is_admin (const char *uuid)
297 {
298  int ret;
299  gchar *quoted_uuid;
300 
301  quoted_uuid = sql_quote (uuid);
302  ret = sql_int ("SELECT count (*) FROM role_users"
303  " WHERE role = (SELECT id FROM roles"
304  " WHERE uuid = '" ROLE_UUID_ADMIN "')"
305  " AND \"user\" = (SELECT id FROM users WHERE uuid = '%s');",
306  quoted_uuid);
307  g_free (quoted_uuid);
308  return ret;
309 }
310 
318 int
319 acl_user_is_observer (const char *uuid)
320 {
321  int ret;
322  gchar *quoted_uuid;
323 
324  quoted_uuid = sql_quote (uuid);
325  ret = sql_int ("SELECT count (*) FROM role_users"
326  " WHERE role = (SELECT id FROM roles"
327  " WHERE uuid = '" ROLE_UUID_OBSERVER "')"
328  " AND \"user\" = (SELECT id FROM users WHERE uuid = '%s');",
329  quoted_uuid);
330  g_free (quoted_uuid);
331  return ret;
332 }
333 
341 int
342 user_is_super_admin (const char *uuid)
343 {
344  int ret;
345  gchar *quoted_uuid;
346 
347  quoted_uuid = sql_quote (uuid);
348  ret = sql_int ("SELECT count (*) FROM role_users"
349  " WHERE role = (SELECT id FROM roles"
350  " WHERE uuid = '" ROLE_UUID_SUPER_ADMIN "')"
351  " AND \"user\" = (SELECT id FROM users WHERE uuid = '%s');",
352  quoted_uuid);
353  g_free (quoted_uuid);
354  return ret;
355 }
356 
364 int
365 acl_user_is_user (const char *uuid)
366 {
367  int ret;
368  gchar *quoted_uuid;
369 
370  quoted_uuid = sql_quote (uuid);
371  ret = sql_int ("SELECT count (*) FROM role_users"
372  " WHERE role = (SELECT id FROM roles"
373  " WHERE uuid = '" ROLE_UUID_USER "')"
374  " AND \"user\" = (SELECT id FROM users WHERE uuid = '%s');",
375  quoted_uuid);
376  g_free (quoted_uuid);
377  return ret;
378 }
379 
385 #define ACL_SUPER_CLAUSE(format) \
386  " name = 'Super'" \
387  /* Super on everyone. */ \
388  " AND ((resource = 0)" \
389  /* Super on other_user. */ \
390  " OR ((resource_type = 'user')" \
391  " AND (resource = (SELECT %ss%s.owner" \
392  " FROM %ss%s" \
393  " WHERE %s = " format ")))" \
394  /* Super on other_user's role. */ \
395  " OR ((resource_type = 'role')" \
396  " AND (resource" \
397  " IN (SELECT DISTINCT role" \
398  " FROM role_users" \
399  " WHERE \"user\"" \
400  " = (SELECT %ss%s.owner" \
401  " FROM %ss%s" \
402  " WHERE %s" \
403  " = " format "))))" \
404  /* Super on other_user's group. */ \
405  " OR ((resource_type = 'group')" \
406  " AND (resource" \
407  " IN (SELECT DISTINCT \"group\"" \
408  " FROM group_users" \
409  " WHERE \"user\"" \
410  " = (SELECT %ss%s.owner" \
411  " FROM %ss%s" \
412  " WHERE %s = " format ")))))" \
413  " AND subject_location = " G_STRINGIFY (LOCATION_TABLE) \
414  " AND ((subject_type = 'user'" \
415  " AND subject" \
416  " = (SELECT id FROM users" \
417  " WHERE users.uuid = '%s'))" \
418  " OR (subject_type = 'group'" \
419  " AND subject" \
420  " IN (SELECT DISTINCT \"group\"" \
421  " FROM group_users" \
422  " WHERE \"user\"" \
423  " = (SELECT id" \
424  " FROM users" \
425  " WHERE users.uuid" \
426  " = '%s')))" \
427  " OR (subject_type = 'role'" \
428  " AND subject" \
429  " IN (SELECT DISTINCT role" \
430  " FROM role_users" \
431  " WHERE \"user\"" \
432  " = (SELECT id" \
433  " FROM users" \
434  " WHERE users.uuid" \
435  " = '%s'))))"
436 
446 #define ACL_SUPER_CLAUSE_ARGS(type, field, value, user_id, trash) \
447  type, \
448  trash ? (strcasecmp (type, "task") ? "_trash" : "") : "", \
449  type, \
450  trash ? (strcasecmp (type, "task") ? "_trash" : "") : "", \
451  field, \
452  value, \
453  type, \
454  trash ? (strcasecmp (type, "task") ? "_trash" : "") : "", \
455  type, \
456  trash ? (strcasecmp (type, "task") ? "_trash" : "") : "", \
457  field, \
458  value, \
459  type, \
460  trash ? (strcasecmp (type, "task") ? "_trash" : "") : "", \
461  type, \
462  trash ? (strcasecmp (type, "task") ? "_trash" : "") : "", \
463  field, \
464  value, \
465  user_id, \
466  user_id, \
467  user_id
468 
479 int
480 acl_user_has_super_on (const char *type, const char *field, const char *value,
481  int trash)
482 {
483  gchar *quoted_value;
484  quoted_value = sql_quote (value);
485  if (sql_int ("SELECT EXISTS (SELECT * FROM permissions"
486  " WHERE " ACL_SUPER_CLAUSE ("'%s'") ");",
487  ACL_SUPER_CLAUSE_ARGS (type, field, quoted_value,
488  current_credentials.uuid, trash)))
489  {
490  g_free (quoted_value);
491  return 1;
492  }
493  g_free (quoted_value);
494  return 0;
495 }
496 
507 int
508 acl_user_has_super_on_resource (const char *type, const char *field,
509  resource_t resource, int trash)
510 {
511  if (sql_int ("SELECT EXISTS (SELECT * FROM permissions"
512  " WHERE " ACL_SUPER_CLAUSE ("%llu") ");",
513  ACL_SUPER_CLAUSE_ARGS (type, field, resource,
514  current_credentials.uuid, trash)))
515  return 1;
516  return 0;
517 }
518 
530 int
531 acl_user_owns_name (const char *type, const char *value)
532 {
533  gchar *quoted_value;
534  int ret;
535 
536  assert (current_credentials.uuid);
537  assert (type && strcmp (type, "result"));
538 
539  if ((strcmp (type, "nvt") == 0)
540  || (strcmp (type, "cve") == 0)
541  || (strcmp (type, "cpe") == 0)
542  || (strcmp (type, "ovaldef") == 0)
543  || (strcmp (type, "cert_bund_adv") == 0)
544  || (strcmp (type, "dfn_cert_adv") == 0))
545  return 1;
546 
547  if (acl_user_has_super_on (type, "name", value, 0))
548  return 1;
549 
550  quoted_value = sql_quote (value);
551  ret = sql_int ("SELECT count(*) FROM %ss"
552  " WHERE name = '%s'"
553  " AND ((owner IS NULL)"
554  " OR (owner = (SELECT users.id FROM users"
555  " WHERE users.uuid = '%s')));",
556  type,
557  quoted_value,
558  current_credentials.uuid);
559  g_free (quoted_value);
560 
561  return ret;
562 }
563 
572 int
573 acl_user_is_owner (const char *type, const char *uuid)
574 {
575  int ret;
576  gchar *quoted_uuid;
577 
578  assert (uuid && current_credentials.uuid);
579 
580  quoted_uuid = g_strdup (uuid);
581  ret = sql_int ("SELECT count(*) FROM %ss"
582  " WHERE uuid = '%s'"
583  " AND owner = (SELECT users.id FROM users"
584  " WHERE users.uuid = '%s');",
585  type,
586  quoted_uuid,
587  current_credentials.uuid);
588  g_free (quoted_uuid);
589 
590  return ret;
591 }
592 
605 int
606 acl_user_owns_uuid (const char *type, const char *uuid, int trash)
607 {
608  int ret;
609  gchar *quoted_uuid;
610 
611  assert (current_credentials.uuid);
612 
613  if ((strcmp (type, "nvt") == 0)
614  || (strcmp (type, "cve") == 0)
615  || (strcmp (type, "cpe") == 0)
616  || (strcmp (type, "ovaldef") == 0)
617  || (strcmp (type, "cert_bund_adv") == 0)
618  || (strcmp (type, "dfn_cert_adv") == 0))
619  return 1;
620 
621  if (acl_user_has_super_on (type, "uuid", uuid, 0))
622  return 1;
623 
624  quoted_uuid = sql_quote (uuid);
625  if (strcmp (type, "result") == 0)
626  ret = sql_int ("SELECT count(*) FROM results, reports"
627  " WHERE results.uuid = '%s'"
628  " AND results.report = reports.id"
629  " AND ((reports.owner IS NULL)"
630  " OR (reports.owner = (SELECT users.id FROM users"
631  " WHERE users.uuid = '%s')));",
632  quoted_uuid,
633  current_credentials.uuid);
634  else
635  ret = sql_int ("SELECT count(*) FROM %ss%s"
636  " WHERE uuid = '%s'"
637  "%s"
638  " AND ((owner IS NULL)"
639  " OR (owner = (SELECT users.id FROM users"
640  " WHERE users.uuid = '%s')));",
641  type,
642  (strcmp (type, "task") && trash) ? "_trash" : "",
643  quoted_uuid,
644  (strcmp (type, "task")
645  ? ""
646  : (trash ? " AND hidden = 2" : " AND hidden < 2")),
647  current_credentials.uuid);
648  g_free (quoted_uuid);
649 
650  return ret;
651 }
652 
665 int
666 acl_user_owns (const char *type, resource_t resource, int trash)
667 {
668  int ret;
669 
670  assert (current_credentials.uuid);
671 
672  if ((strcmp (type, "nvt") == 0)
673  || (strcmp (type, "cve") == 0)
674  || (strcmp (type, "cpe") == 0)
675  || (strcmp (type, "ovaldef") == 0)
676  || (strcmp (type, "cert_bund_adv") == 0)
677  || (strcmp (type, "dfn_cert_adv") == 0))
678  return 1;
679 
680  if (acl_user_has_super_on_resource (type, "id", resource, trash))
681  return 1;
682 
683  if (strcmp (type, "result") == 0)
684  ret = sql_int ("SELECT count(*) FROM results, reports"
685  " WHERE results.id = %llu"
686  " AND results.report = reports.id"
687  " AND ((reports.owner IS NULL)"
688  " OR (reports.owner = (SELECT users.id FROM users"
689  " WHERE users.uuid = '%s')));",
690  resource,
691  current_credentials.uuid);
692  else
693  ret = sql_int ("SELECT count(*) FROM %ss%s"
694  " WHERE id = %llu"
695  "%s"
696  " AND ((owner IS NULL)"
697  " OR (owner = (SELECT users.id FROM users"
698  " WHERE users.uuid = '%s')));",
699  type,
700  (strcmp (type, "task") && trash) ? "_trash" : "",
701  resource,
702  (strcmp (type, "task")
703  ? ""
704  : (trash ? " AND hidden = 2" : " AND hidden < 2")),
705  current_credentials.uuid);
706 
707  return ret;
708 }
709 
721 int
722 acl_user_owns_trash_uuid (const char *type, const char *uuid)
723 {
724  int ret;
725  gchar *quoted_uuid;
726 
727  assert (current_credentials.uuid);
728  assert (type && strcmp (type, "task"));
729 
730  if (acl_user_has_super_on (type, "uuid", uuid, 1))
731  return 1;
732 
733  quoted_uuid = sql_quote (uuid);
734  ret = sql_int ("SELECT count(*) FROM %ss_trash"
735  " WHERE uuid = '%s'"
736  " AND ((owner IS NULL)"
737  " OR (owner = (SELECT users.id FROM users"
738  " WHERE users.uuid = '%s')));",
739  type,
740  quoted_uuid,
741  current_credentials.uuid);
742  g_free (quoted_uuid);
743 
744  return ret;
745 }
746 
757 int
758 acl_user_has_access_uuid (const char *type, const char *uuid,
759  const char *permission, int trash)
760 {
761  int ret, get;
762  char *uuid_task;
763  gchar *quoted_permission, *quoted_uuid;
764 
765  assert (current_credentials.uuid);
766 
767  if (permission && (valid_omp_command (permission) == 0))
768  return 0;
769 
770  if (!strcmp (current_credentials.uuid, ""))
771  return 1;
772 
773  /* The Super case is checked here. */
774  ret = acl_user_owns_uuid (type, uuid, trash);
775  if (ret)
776  return ret;
777 
778  if (trash)
779  /* For simplicity, trashcan items are visible only to their owners. */
780  return 0;
781 
782  quoted_uuid = sql_quote (uuid);
783  if (strcasecmp (type, "report") == 0)
784  {
785  task_t task;
786  report_t report;
787 
788  switch (sql_int64 (&report,
789  "SELECT id FROM reports WHERE uuid = '%s';",
790  quoted_uuid))
791  {
792  case 0:
793  break;
794  case 1: /* Too few rows in result of query. */
795  g_free (quoted_uuid);
796  return 0;
797  break;
798  default: /* Programming error. */
799  assert (0);
800  case -1:
801  g_free (quoted_uuid);
802  return 0;
803  break;
804  }
805 
806  report_task (report, &task);
807  if (task == 0)
808  {
809  g_free (quoted_uuid);
810  return 0;
811  }
812  task_uuid (task, &uuid_task);
813  }
814  else if (strcasecmp (type, "result") == 0)
815  {
816  task_t task;
817 
818  switch (sql_int64 (&task,
819  "SELECT task FROM results WHERE uuid = '%s';",
820  uuid))
821  {
822  case 0:
823  break;
824  case 1: /* Too few rows in result of query. */
825  g_free (quoted_uuid);
826  return 0;
827  break;
828  default: /* Programming error. */
829  assert (0);
830  case -1:
831  g_free (quoted_uuid);
832  return 0;
833  break;
834  }
835 
836  task_uuid (task, &uuid_task);
837  }
838  else
839  uuid_task = NULL;
840 
841  if ((strcmp (type, "permission") == 0)
842  && ((permission == NULL)
843  || (strlen (permission) > 3 && strncmp (permission, "get", 3) == 0)))
844  {
845  ret = sql_int ("SELECT count(*) FROM permissions"
846  /* Any permission implies 'get'. */
847  " WHERE (resource_uuid = '%s'"
848  /* Users may view any permissions that affect them. */
849  " OR uuid = '%s')"
850  " AND subject_location = " G_STRINGIFY (LOCATION_TABLE)
851  " AND ((subject_type = 'user'"
852  " AND subject"
853  " = (SELECT id FROM users"
854  " WHERE users.uuid = '%s'))"
855  " OR (subject_type = 'group'"
856  " AND subject"
857  " IN (SELECT DISTINCT \"group\""
858  " FROM group_users"
859  " WHERE \"user\" = (SELECT id"
860  " FROM users"
861  " WHERE users.uuid"
862  " = '%s')))"
863  " OR (subject_type = 'role'"
864  " AND subject"
865  " IN (SELECT DISTINCT role"
866  " FROM role_users"
867  " WHERE \"user\" = (SELECT id"
868  " FROM users"
869  " WHERE users.uuid"
870  " = '%s'))));",
871  uuid_task ? uuid_task : quoted_uuid,
872  uuid_task ? uuid_task : quoted_uuid,
873  current_credentials.uuid,
874  current_credentials.uuid,
875  current_credentials.uuid);
876  free (uuid_task);
877  g_free (quoted_uuid);
878  return ret;
879  }
880  else if (strcmp (type, "permission") == 0)
881  {
882  /* There are no "permissions on permissions", so if a user does not
883  * effectively own a permission, there's no way for the user to access
884  * the permission. */
885  free (uuid_task);
886  g_free (quoted_uuid);
887  return 0;
888  }
889 
890  get = (permission == NULL
891  || (strlen (permission) > 3 && strncmp (permission, "get", 3) == 0));
892  quoted_permission = sql_quote (permission ? permission : "");
893 
894  ret = sql_int ("SELECT count(*) FROM permissions"
895  " WHERE resource_uuid = '%s'"
896  " AND subject_location = " G_STRINGIFY (LOCATION_TABLE)
897  " AND ((subject_type = 'user'"
898  " AND subject"
899  " = (SELECT id FROM users"
900  " WHERE users.uuid = '%s'))"
901  " OR (subject_type = 'group'"
902  " AND subject"
903  " IN (SELECT DISTINCT \"group\""
904  " FROM group_users"
905  " WHERE \"user\" = (SELECT id"
906  " FROM users"
907  " WHERE users.uuid"
908  " = '%s')))"
909  " OR (subject_type = 'role'"
910  " AND subject"
911  " IN (SELECT DISTINCT role"
912  " FROM role_users"
913  " WHERE \"user\" = (SELECT id"
914  " FROM users"
915  " WHERE users.uuid"
916  " = '%s'))))"
917  " %s%s%s;",
918  uuid_task ? uuid_task : quoted_uuid,
919  current_credentials.uuid,
920  current_credentials.uuid,
921  current_credentials.uuid,
922  (get ? "" : "AND name = '"),
923  (get ? "" : quoted_permission),
924  (get ? "" : "'"));
925 
926  free (uuid_task);
927  g_free (quoted_permission);
928  g_free (quoted_uuid);
929  return ret;
930 }
931 
947 gchar *
948 acl_where_owned_user (const char *user_id, const char *user_sql,
949  const char *type, const get_data_t *get, int owned,
950  const gchar *owner_filter, resource_t resource,
951  array_t *permissions)
952 {
953  gchar *owned_clause;
954 
955  if (owned)
956  {
957  gchar *permission_clause, *filter_owned_clause;
958  GString *permission_or;
959  int table_trash, permissions_include_get;
960  guint index;
961 
962  permissions_include_get = 0;
963  permission_or = g_string_new ("");
964  index = 0;
965  if (permissions == NULL || permissions->len == 0)
966  {
967  /* Treat filters with no permissions keyword as "any". */
968  permission_or = g_string_new ("t ()");
969  index = 1;
970  permissions_include_get = 1;
971  }
972  else if (permissions)
973  for (; index < permissions->len; index++)
974  {
975  gchar *permission, *quoted;
976  permission = (gchar*) g_ptr_array_index (permissions, index);
977  if (strcasecmp (permission, "any") == 0)
978  {
979  g_string_free (permission_or, TRUE);
980  permission_or = g_string_new ("t ()");
981  index = 1;
982  permissions_include_get = 1;
983  break;
984  }
985  if (g_str_has_prefix (permission, "get_"))
986  permissions_include_get = 1;
987  quoted = sql_quote (permission);
988  if (index == 0)
989  g_string_append_printf (permission_or, "name = '%s'", quoted);
990  else
991  g_string_append_printf (permission_or, " OR name = '%s'",
992  quoted);
993  g_free (quoted);
994  }
995  else
996  permissions_include_get = 1;
997 
998  /* Check on index is because default is owner and global, for backward
999  * compatibility. */
1000  permission_clause = NULL;
1001  if (user_id && index)
1002  {
1003  gchar *clause;
1004  clause
1005  = g_strdup_printf ("OR EXISTS"
1006  " (SELECT id FROM permissions"
1007  " WHERE resource = %ss%s.id"
1008  " AND resource_type = '%s'"
1009  " AND resource_location = %i"
1010  " AND subject_location"
1011  " = " G_STRINGIFY (LOCATION_TABLE)
1012  " AND ((subject_type = 'user'"
1013  " AND subject"
1014  " = (%s))"
1015  " OR (subject_type = 'group'"
1016  " AND subject"
1017  " IN (SELECT DISTINCT \"group\""
1018  " FROM group_users"
1019  " WHERE \"user\""
1020  " = (%s)))"
1021  " OR (subject_type = 'role'"
1022  " AND subject"
1023  " IN (SELECT DISTINCT role"
1024  " FROM role_users"
1025  " WHERE \"user\""
1026  " = (%s))))"
1027  " AND (%s))",
1028  type,
1029  get->trash && strcmp (type, "task") ? "_trash" : "",
1030  type,
1032  user_sql,
1033  user_sql,
1034  user_sql,
1035  permission_or->str);
1036 
1037  if (strcmp (type, "report") == 0)
1038  permission_clause
1039  = g_strdup_printf ("%s"
1040  " OR EXISTS"
1041  " (SELECT id FROM permissions"
1042  " WHERE resource = reports%s.task"
1043  " AND resource_type = 'task'"
1044  " AND subject_location"
1045  " = " G_STRINGIFY (LOCATION_TABLE)
1046  " AND ((subject_type = 'user'"
1047  " AND subject"
1048  " = (%s))"
1049  " OR (subject_type = 'group'"
1050  " AND subject"
1051  " IN (SELECT DISTINCT \"group\""
1052  " FROM group_users"
1053  " WHERE \"user\""
1054  " = (%s)))"
1055  " OR (subject_type = 'role'"
1056  " AND subject"
1057  " IN (SELECT DISTINCT role"
1058  " FROM role_users"
1059  " WHERE \"user\""
1060  " = (%s))))"
1061  " AND (%s))",
1062  clause,
1063  get->trash ? "_trash" : "",
1064  user_sql,
1065  user_sql,
1066  user_sql,
1067  permission_or->str);
1068  else if (strcmp (type, "result") == 0)
1069  permission_clause
1070  = g_strdup_printf ("%s"
1071  " OR EXISTS"
1072  " (SELECT id FROM permissions"
1073  " WHERE resource = results%s.task"
1074  " AND resource_type = 'task'"
1075  " AND subject_location"
1076  " = " G_STRINGIFY (LOCATION_TABLE)
1077  " AND ((subject_type = 'user'"
1078  " AND subject"
1079  " = (%s))"
1080  " OR (subject_type = 'group'"
1081  " AND subject"
1082  " IN (SELECT DISTINCT \"group\""
1083  " FROM group_users"
1084  " WHERE \"user\""
1085  " = (%s)))"
1086  " OR (subject_type = 'role'"
1087  " AND subject"
1088  " IN (SELECT DISTINCT role"
1089  " FROM role_users"
1090  " WHERE \"user\""
1091  " = (%s))))"
1092  " AND (%s))",
1093  clause,
1094  get->trash ? "_trash" : "",
1095  user_sql,
1096  user_sql,
1097  user_sql,
1098  permission_or->str);
1099 
1100  if ((strcmp (type, "report") == 0)
1101  || (strcmp (type, "result") == 0))
1102  g_free (clause);
1103  else
1104  permission_clause = clause;
1105  }
1106 
1107  g_string_free (permission_or, TRUE);
1108 
1109  table_trash = get->trash && strcasecmp (type, "task");
1110  if (resource || (user_id == NULL))
1111  owned_clause
1112  = g_strdup (" (t ())");
1113  else if (strcmp (type, "permission") == 0)
1114  {
1115  int admin;
1116  assert (strcmp (user_id, ""));
1117  admin = acl_user_can_everything (user_id);
1118  /* A user sees permissions that involve the user. Admin users also
1119  * see all higher level permissions. */
1120  owned_clause
1121  = g_strdup_printf (/* Either the user is the owner. */
1122  " ((permissions%s.owner = (%s))"
1123  /* Or, for admins, it's a global permission. */
1124  " %s"
1125  /* Or the permission applies to the user. */
1126  " OR (%i = 0" /* Skip for trash. */
1127  " AND (permissions%s.subject_type = 'user'"
1128  " AND permissions%s.subject_location"
1129  " = " G_STRINGIFY (LOCATION_TABLE)
1130  " AND permissions%s.subject"
1131  " = (%s)))"
1132  /* Or the permission applies to the user's group. */
1133  " OR (%i = 0" /* Skip for trash. */
1134  " AND (permissions%s.subject_type = 'group'"
1135  " AND permissions%s.subject_location"
1136  " = " G_STRINGIFY (LOCATION_TABLE)
1137  " AND permissions%s.subject"
1138  " IN (SELECT DISTINCT \"group\""
1139  " FROM group_users"
1140  " WHERE \"user\" = (%s))))"
1141  /* Or the permission applies to the user's role. */
1142  " OR (%i = 0" /* Skip for trash. */
1143  " AND (permissions%s.subject_type = 'role'"
1144  " AND permissions%s.subject_location"
1145  " = " G_STRINGIFY (LOCATION_TABLE)
1146  " AND permissions%s.subject"
1147  " IN (SELECT DISTINCT role"
1148  " FROM role_users"
1149  " WHERE \"user\" = (%s))))"
1150  /* Or the user has super permission. */
1151  " OR EXISTS (SELECT * FROM permissions AS inside"
1152  " WHERE name = 'Super'"
1153  /* Super on everyone. */
1154  " AND ((inside.resource = 0)"
1155  /* Super on outer permission user. */
1156  " OR ((inside.resource_type = 'user')"
1157  " AND (inside.resource = permissions%s.owner))"
1158  /* Super on outer permission user's role. */
1159  " OR ((inside.resource_type = 'role')"
1160  " AND (inside.resource"
1161  " IN (SELECT DISTINCT role"
1162  " FROM role_users"
1163  " WHERE \"user\""
1164  " = permissions%s.owner)))"
1165  /* Super on outer permission user's group. */
1166  " OR ((inside.resource_type = 'group')"
1167  " AND (inside.resource"
1168  " IN (SELECT DISTINCT \"group\""
1169  " FROM group_users"
1170  " WHERE \"user\""
1171  " = permissions%s.owner))))"
1172  " AND subject_location"
1173  " = " G_STRINGIFY (LOCATION_TABLE)
1174  " AND ((inside.subject_type = 'user'"
1175  " AND inside.subject"
1176  " = (%s))"
1177  " OR (inside.subject_type = 'group'"
1178  " AND inside.subject"
1179  " IN (SELECT DISTINCT \"group\""
1180  " FROM group_users"
1181  " WHERE \"user\""
1182  " = (%s)))"
1183  " OR (inside.subject_type = 'role'"
1184  " AND inside.subject"
1185  " IN (SELECT DISTINCT role"
1186  " FROM role_users"
1187  " WHERE \"user\""
1188  " = (%s)))))"
1189  " %s)",
1190  get->trash ? "_trash" : "",
1191  user_sql,
1192  admin
1193  ? (get->trash
1194  ? "OR (permissions_trash.owner IS NULL)"
1195  : "OR (permissions.owner IS NULL)")
1196  : "",
1197  get->trash,
1198  table_trash ? "_trash" : "",
1199  table_trash ? "_trash" : "",
1200  table_trash ? "_trash" : "",
1201  user_sql,
1202  get->trash,
1203  table_trash ? "_trash" : "",
1204  table_trash ? "_trash" : "",
1205  table_trash ? "_trash" : "",
1206  user_sql,
1207  get->trash,
1208  table_trash ? "_trash" : "",
1209  table_trash ? "_trash" : "",
1210  table_trash ? "_trash" : "",
1211  user_sql,
1212  table_trash ? "_trash" : "",
1213  table_trash ? "_trash" : "",
1214  table_trash ? "_trash" : "",
1215  user_sql,
1216  user_sql,
1217  user_sql,
1218  permission_clause ? permission_clause : "");
1219  }
1220  else
1221  owned_clause
1222  = g_strdup_printf (/* Either a global resource (like Full and Fast).
1223  *
1224  * The globals are only required when GET permission
1225  * is requested, because it is only possible to read
1226  * the globals (unless the user has super on
1227  * everything like Super Admin does, but that is
1228  * covered by the super case below). */
1229  " (%s%s%s%s%s"
1230  /* Or the user is the owner. */
1231  " %s (%ss%s.owner"
1232  " = (%s))"
1233  /* Or the user has super permission. */
1234  " OR EXISTS (SELECT * FROM permissions"
1235  " WHERE name = 'Super'"
1236  /* Super on everyone. */
1237  " AND ((resource = 0)"
1238  /* Super on other_user. */
1239  " OR ((resource_type = 'user')"
1240  " AND (resource = %ss%s.owner))"
1241  /* Super on other_user's role. */
1242  " OR ((resource_type = 'role')"
1243  " AND (resource"
1244  " IN (SELECT DISTINCT role"
1245  " FROM role_users"
1246  " WHERE \"user\""
1247  " = %ss%s.owner)))"
1248  /* Super on other_user's group. */
1249  " OR ((resource_type = 'group')"
1250  " AND (resource"
1251  " IN (SELECT DISTINCT \"group\""
1252  " FROM group_users"
1253  " WHERE \"user\""
1254  " = %ss%s.owner))))"
1255  " AND subject_location"
1256  " = " G_STRINGIFY (LOCATION_TABLE)
1257  " AND ((subject_type = 'user'"
1258  " AND subject"
1259  " = (%s))"
1260  " OR (subject_type = 'group'"
1261  " AND subject"
1262  " IN (SELECT DISTINCT \"group\""
1263  " FROM group_users"
1264  " WHERE \"user\""
1265  " = (%s)))"
1266  " OR (subject_type = 'role'"
1267  " AND subject"
1268  " IN (SELECT DISTINCT role"
1269  " FROM role_users"
1270  " WHERE \"user\""
1271  " = (%s)))))"
1272  " %s)",
1273  permissions_include_get ? "(" : "",
1274  permissions_include_get ? type : "",
1275  permissions_include_get ? "s" : "",
1276  permissions_include_get && table_trash
1277  ? "_trash"
1278  : "",
1279  permissions_include_get ? ".owner IS NULL)" : "",
1280  permissions_include_get ? "OR" : "",
1281  type,
1282  table_trash ? "_trash" : "",
1283  user_sql,
1284  type,
1285  table_trash ? "_trash" : "",
1286  type,
1287  table_trash ? "_trash" : "",
1288  type,
1289  table_trash ? "_trash" : "",
1290  user_sql,
1291  user_sql,
1292  user_sql,
1293  permission_clause ? permission_clause : "");
1294 
1295  g_free (permission_clause);
1296 
1297  if (get->trash && (strcasecmp (type, "task") == 0))
1298  {
1299  gchar *new;
1300  new = g_strdup_printf (" (%ss.hidden = 2"
1301  " AND %s)",
1302  type,
1303  owned_clause);
1304  g_free (owned_clause);
1305  owned_clause = new;
1306  }
1307 
1308  if (owner_filter == NULL
1309  || (owner_filter && (strcmp (owner_filter, "any") == 0)))
1310  filter_owned_clause = g_strdup (owned_clause);
1311  else if (owner_filter && strcmp (owner_filter, ""))
1312  {
1313  gchar *quoted;
1314  quoted = sql_quote (owner_filter);
1315  filter_owned_clause = g_strdup_printf ("(owner = (SELECT id"
1316  " FROM users"
1317  " WHERE name = '%s')"
1318  " AND %s)",
1319  quoted,
1320  owned_clause);
1321  g_free (quoted);
1322  }
1323  else
1324  filter_owned_clause = g_strdup_printf ("((owner = (%s)"
1325  " OR owner IS NULL)"
1326  " AND %s)",
1327  user_sql,
1328  owned_clause);
1329 
1330  g_free (owned_clause);
1331  owned_clause = filter_owned_clause;
1332  }
1333  else
1334  owned_clause = g_strdup (" t ()");
1335 
1336  return owned_clause;
1337 }
1338 
1351 gchar *
1352 acl_where_owned (const char *type, const get_data_t *get, int owned,
1353  const gchar *owner_filter, resource_t resource,
1354  array_t *permissions)
1355 {
1356  gchar *ret, *user_sql;
1357  if (current_credentials.uuid)
1358  user_sql = g_strdup_printf ("SELECT id FROM users WHERE users.uuid = '%s'",
1359  current_credentials.uuid);
1360  else
1361  user_sql = NULL;
1362  ret = acl_where_owned_user (current_credentials.uuid, user_sql, type, get,
1363  owned, owner_filter, resource, permissions);
1364  g_free (user_sql);
1365  return ret;
1366 }
1367 
1377 gchar *
1378 acl_where_owned_for_get (const char *type, const char *user_sql)
1379 {
1380  gchar *owned_clause;
1381  get_data_t get;
1382  array_t *permissions;
1383  gchar *user_sql_new;
1384 
1385  if (user_sql)
1386  user_sql_new = g_strdup (user_sql);
1387  else if (current_credentials.uuid)
1388  user_sql_new = g_strdup_printf ("SELECT id FROM users WHERE users.uuid = '%s'",
1389  current_credentials.uuid);
1390  else
1391  user_sql_new = NULL;
1392 
1393  get.trash = 0;
1394  permissions = make_array ();
1395  array_add (permissions, g_strdup_printf ("get_%ss", type));
1396  owned_clause = acl_where_owned_user (current_credentials.uuid
1397  ? current_credentials.uuid
1398  /* Use user_sql_new. */
1399  : "",
1400  user_sql_new,
1401  type,
1402  &get,
1403  1, /* Do owner checks. */
1404  "any",
1405  0, /* Resource. */
1406  permissions);
1407  array_free (permissions);
1408  g_free (user_sql_new);
1409 
1410  return owned_clause;
1411 }
1412 
1423 gchar *
1424 acl_users_with_access_sql (const char *type, const char *resource_id,
1425  const char *users_where)
1426 {
1427  GString *users_string;
1428  int users_count = 0;
1429  gchar *old_user_id, *command;
1430  iterator_t users;
1431 
1432  old_user_id = current_credentials.uuid;
1433  init_iterator (&users, "SELECT id, uuid FROM users WHERE %s;",
1434  users_where ? users_where : "t()");
1435 
1436  users_string = g_string_new ("(VALUES ");
1437 
1438  command = g_strdup_printf ("get_%ss", type);
1439 
1440  while (next (&users))
1441  {
1442  current_credentials.uuid = g_strdup (iterator_string (&users, 1));
1444  if (acl_user_has_access_uuid (type, resource_id, command, 0))
1445  {
1446  if (users_count)
1447  g_string_append (users_string,
1448  ", ");
1449 
1450  g_string_append_printf (users_string,
1451  "(%llu)",
1452  iterator_int64 (&users, 0));
1453  users_count ++;
1454  }
1455  g_free (current_credentials.uuid);
1456  }
1457  g_string_append(users_string, ")");
1458  cleanup_iterator (&users);
1459 
1460  current_credentials.uuid = old_user_id;
1461  manage_session_init (old_user_id);
1462 
1463  g_free (command);
1464 
1465  if (users_count == 0)
1466  {
1467  g_string_free (users_string, TRUE);
1468  return NULL;
1469  }
1470 
1471  return g_string_free (users_string, FALSE);
1472 
1473 }
1474 
1486 gchar *
1487 acl_users_with_access_where (const char *type, const char *resource_id,
1488  const char *users_where, const char* user_expr)
1489 {
1490  gchar *values, *ret;
1491  assert (user_expr);
1492  values = acl_users_with_access_sql (type, resource_id, users_where);
1493  if (values)
1494  ret = g_strdup_printf ("%s IN %s", user_expr, values);
1495  else
1496  ret = g_strdup ("NOT t()");
1497  g_free (values);
1498  return ret;
1499 }
int trash
Boolean. Whether to return from trashcan.
Definition: manage.h:318
int acl_user_is_user(const char *uuid)
Check whether a user has the User role.
Definition: manage_acl.c:365
#define LOCATION_TRASH
Location of a constituent of a trashcan resource.
Definition: manage_sql.h:86
int acl_user_is_owner(const char *type, const char *uuid)
Test whether a user is the actual owner of a resource.
Definition: manage_acl.c:573
int acl_user_owns_name(const char *type, const char *value)
Test whether a user effectively owns a resource.
Definition: manage_acl.c:531
int sql_int(char *sql,...)
Get a particular cell from a SQL query, as an int.
Definition: sql.c:438
int acl_user_owns_uuid(const char *type, const char *uuid, int trash)
Test whether a user effectively owns a resource.
Definition: manage_acl.c:606
int acl_user_has_super(const char *super_user_id, user_t other_user)
Test whether a user has super permission on another user.
Definition: manage_acl.c:226
A generic SQL iterator.
Definition: iterator.h:52
int acl_role_can_super_everyone(const char *role_id)
Check whether a role has Super Admin capability.
Definition: manage_acl.c:95
int acl_user_has_access_uuid(const char *type, const char *uuid, const char *permission, int trash)
Test whether the user may access a resource.
Definition: manage_acl.c:758
int sql_int64(long long int *ret, char *sql,...)
Get a particular cell from a SQL query, as an int64.
Definition: sql.c:501
gchar * acl_where_owned_for_get(const char *type, const char *user_sql)
Generate ownership part of WHERE, for getting a type of resource.
Definition: manage_acl.c:1378
int task_uuid(task_t, char **)
Return the UUID of a task.
Definition: manage_sql.c:17885
gboolean report_task(report_t, task_t *)
int acl_user_owns_trash_uuid(const char *type, const char *uuid)
Test whether a user effectively owns a resource.
Definition: manage_acl.c:722
#define ROLE_UUID_USER
Predefined role UUID.
Definition: manage_sql.h:188
#define ROLE_UUID_SUPER_ADMIN
Predefined role UUID.
Definition: manage_sql.h:193
#define ACL_SUPER_CLAUSE(format)
Super clause.
Definition: manage_acl.c:385
gchar * sql_quote(const char *string)
Quotes a string to be passed to sql statements.
Definition: sql.c:121
long long int user_t
Definition: manage.h:302
Command data for a get command.
Definition: manage.h:310
#define ROLE_UUID_OBSERVER
Predefined role UUID.
Definition: manage_sql.h:198
int acl_user_is_observer(const char *uuid)
Check whether a user is an Observer.
Definition: manage_acl.c:319
void manage_session_init(const char *uuid)
Setup session.
Definition: manage_pg.c:46
int acl_user_has_super_on(const char *type, const char *field, const char *value, int trash)
Test whether a user has Super permission on a resource.
Definition: manage_acl.c:480
int acl_user_can_everything(const char *user_id)
Test whether a user may perform any operation.
Definition: manage_acl.c:179
long long int report_t
Definition: manage.h:288
int acl_user_has_super_on_resource(const char *type, const char *field, resource_t resource, int trash)
Test whether a user has Super permission on a resource.
Definition: manage_acl.c:508
gchar * acl_where_owned_user(const char *user_id, const char *user_sql, const char *type, const get_data_t *get, int owned, const gchar *owner_filter, resource_t resource, array_t *permissions)
Generate the ownership part of an SQL WHERE clause for a given user.
Definition: manage_acl.c:948
int valid_omp_command(const char *name)
Check whether a command name is valid.
Definition: manage_sql.c:545
#define ACL_USER_MAY(resource)
Generate SQL for user permission check.
Definition: manage_acl.h:37
int acl_user_is_admin(const char *uuid)
Check whether a user is an Admin.
Definition: manage_acl.c:296
gchar * acl_where_owned(const char *type, const get_data_t *get, int owned, const gchar *owner_filter, resource_t resource, array_t *permissions)
Generate the ownership part of an SQL WHERE clause.
Definition: manage_acl.c:1352
void cleanup_iterator(iterator_t *)
Cleanup an iterator.
Definition: sql.c:664
int acl_user_may(const char *operation)
Test whether a user may perform an operation.
Definition: manage_acl.c:56
credentials_t current_credentials
Current credentials during any OMP command.
Definition: manage.c:717
int user_is_super_admin(const char *uuid)
Check whether a user is a Super Admin.
Definition: manage_acl.c:342
const char * iterator_string(iterator_t *iterator, int col)
Get a string column from an iterator.
Definition: sql.c:652
gchar * acl_users_with_access_where(const char *type, const char *resource_id, const char *users_where, const char *user_expr)
Get a static SQL condition selecting users that can get a resource.
Definition: manage_acl.c:1487
int acl_user_can_super_everyone(const char *uuid)
Check whether a user is a Super Admin.
Definition: manage_acl.c:127
#define ROLE_UUID_ADMIN
Predefined role UUID.
Definition: manage_sql.h:168
#define ACL_SUPER_CLAUSE_ARGS(type, field, value, user_id, trash)
Super clause arguments.
Definition: manage_acl.c:446
gboolean next(iterator_t *)
Increment an iterator.
Definition: sql.c:689
#define LOCATION_TABLE
Location of a constituent of a trashcan resource.
Definition: manage_sql.h:81
void init_iterator(iterator_t *iterator, const char *sql,...)
Initialise an iterator.
Definition: sql.c:577
long long int task_t
Definition: manage.h:286
long long int iterator_int64(iterator_t *iterator, int col)
Get an integer column from an iterator.
Definition: sql.c:637
int acl_user_owns(const char *type, resource_t resource, int trash)
Test whether a user effectively owns a resource.
Definition: manage_acl.c:666
long long int resource_t
A resource, like a task or target.
Definition: iterator.h:42
gchar * acl_users_with_access_sql(const char *type, const char *resource_id, const char *users_where)
Get an SQL values expression of users that can get a resource.
Definition: manage_acl.c:1424