3769b2f94df85e15acc237733f104791c871ab7c
[platform/core/security/libprivilege-control.git] / db / rules-db.sql
1 -- !!! CAUTION !!!
2 -- 1. Beware of updating schema!
3 --    We can drop views and triggers,
4 --    but we should copy data from tables
5 --    according to the schema version!
6 -- 2. If you change definition of tables
7 --    update the schema counter at the bottom!!
8
9 -- TODO: Use "USING" in joins whenever possible
10
11 .load librules-db-sql-udf.so
12 PRAGMA foreign_keys = ON;
13 PRAGMA auto_vacuum = NONE;
14
15 BEGIN EXCLUSIVE TRANSACTION;
16
17 -- PRAGMA cache_size = 2000;
18
19 CREATE TABLE IF NOT EXISTS  app (
20     app_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
21     label_id INTEGER NOT NULL,
22     UNIQUE(label_id),
23
24     FOREIGN KEY(label_id) REFERENCES label(label_id)
25 );
26 CREATE INDEX IF NOT EXISTS app_index ON app(app_id, label_id);
27
28
29 CREATE TABLE IF NOT EXISTS app_permission (
30     app_id INTEGER NOT NULL,
31     permission_id INTEGER NOT NULL,
32     is_volatile INTEGER NOT NULL  DEFAULT 0,
33     is_enabled INTEGER NOT NULL  DEFAULT 1,
34
35     PRIMARY KEY(app_id, permission_id),
36
37     FOREIGN KEY(app_id) REFERENCES app(app_id),
38     FOREIGN KEY(permission_id) REFERENCES permission(permission_id)
39 );
40
41 CREATE TABLE IF NOT EXISTS app_path (
42     app_id INTEGER NOT NULL,
43     path TEXT NOT NULL,
44     label_id INTEGER NOT NULL,
45     access INTEGER NOT NULL,
46     app_path_type_id INTEGER NOT NULL ,
47
48     -- TODO:
49     -- Desired behavior should be:
50     -- allow one app to register a path only once (already implemented by the primary key)
51     -- prohibit two apps registering the same path with different labels (probably cannot be done by SQL constraints)
52     -- allow two apps to register the same path if label is also same
53
54     PRIMARY KEY (app_id, path),
55
56     FOREIGN KEY(app_id) REFERENCES app(app_id),
57     FOREIGN KEY(label_id) REFERENCES label(label_id),
58     FOREIGN KEY(app_path_type_id) REFERENCES app_path_type(app_path_type_id)
59 );
60
61 CREATE TABLE IF NOT EXISTS app_path_type (
62     app_path_type_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
63     name TEXT NOT NULL ,
64
65     UNIQUE (name)
66 );
67 -- CREATE INDEX IF NOT EXISTS app_path_type_index ON app_path_type(app_path_type_id, name);
68
69
70 CREATE TABLE IF NOT EXISTS permission_permission_rule (
71     permission_id INTEGER NOT NULL,
72     target_permission_id INTEGER NOT NULL,
73     access INTEGER NOT NULL DEFAULT 0,
74     is_reverse INTEGER NOT NULL  DEFAULT 0,
75
76     PRIMARY KEY (permission_id, target_permission_id, is_reverse),
77
78     FOREIGN KEY(permission_id) REFERENCES permission(permission_id),
79     FOREIGN KEY(target_permission_id) REFERENCES permission(permission_id)
80 );
81
82 CREATE TABLE IF NOT EXISTS permission_label_rule (
83     permission_id INTEGER NOT NULL,
84     label_id INTEGER NOT NULL,
85     access INTEGER NOT NULL DEFAULT 0,
86     is_reverse INTEGER NOT NULL  DEFAULT 0,
87
88     PRIMARY KEY (permission_id,label_id, is_reverse),
89
90     FOREIGN KEY(permission_id) REFERENCES permission(permission_id),
91     FOREIGN KEY(label_id) REFERENCES label(label_id)
92 );
93
94 CREATE TABLE IF NOT EXISTS permission_app_path_type_rule (
95     permission_id INTEGER NOT NULL,
96     app_path_type_id INTEGER NOT NULL,
97     access INTEGER NOT NULL DEFAULT 0,
98     is_reverse INTEGER NOT NULL  DEFAULT 0,
99
100     PRIMARY KEY (permission_id, app_path_type_id, is_reverse),
101
102     FOREIGN KEY(permission_id) REFERENCES permission(permission_id),
103     FOREIGN KEY(app_path_type_id) REFERENCES app_path_type(app_path_type_id)
104 );
105
106
107 CREATE TABLE IF NOT EXISTS label (
108     label_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
109     name TEXT NOT NULL,
110
111     UNIQUE(name)
112 );
113
114 CREATE TABLE IF NOT EXISTS permission_type (
115     permission_type_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
116     type_name TEXT NOT NULL,
117
118     UNIQUE(type_name)
119 );
120
121 CREATE TABLE IF NOT EXISTS permission (
122     permission_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT ,
123     permission_type_id INTEGER NOT NULL,
124     name TEXT NOT NULL,
125
126     UNIQUE (name, permission_type_id),
127
128     FOREIGN KEY(permission_type_id) REFERENCES permission_type(permission_type_id)
129 );
130
131
132 CREATE TABLE IF NOT EXISTS all_smack_binary_rules(
133     subject TEXT NOT NULL,
134     object  TEXT NOT NULL,
135     access  INTEGER NOT NULL,
136     is_volatile INTEGER NOT NULL
137 );
138
139 -- TEMPORARY TABLES ------------------------------------------------------------
140 -- Definitions are repeated in code.
141
142 CREATE TEMPORARY TABLE history_smack_rule(
143     subject TEXT NOT NULL,
144     object  TEXT NOT NULL,
145     access  INTEGER NOT NULL
146 );
147
148
149 CREATE TEMPORARY TABLE modified_label(
150    name TEXT NOT NULL,
151    UNIQUE (name)
152 );
153
154
155 CREATE TEMPORARY TABLE all_smack_binary_rules_modified(
156     subject TEXT NOT NULL,
157     object  TEXT NOT NULL,
158     access  INTEGER NOT NULL
159 );
160
161
162 CREATE TEMPORARY TABLE history_smack_rule_modified(
163     subject TEXT NOT NULL,
164     object  TEXT NOT NULL,
165     access  INTEGER NOT NULL
166 );
167
168
169 -- PERMISSION VIEW -------------------------------------------------------------
170 DROP VIEW IF EXISTS permission_view;
171 CREATE VIEW permission_view AS
172 SELECT      permission.permission_id, permission.name, permission_type.type_name
173 FROM        permission
174 INNER JOIN  permission_type USING(permission_type_id);
175
176 DROP TRIGGER IF EXISTS permission_view_insert_trigger;
177 CREATE TRIGGER permission_view_insert_trigger
178 INSTEAD OF INSERT ON permission_view
179 BEGIN
180     -- Add the permission
181     INSERT OR IGNORE INTO permission(name,permission_type_id)
182     SELECT      NEW.name, permission_type.permission_type_id
183     FROM        permission_type
184     WHERE       permission_type.type_name = NEW.type_name;
185
186
187     -- Delete the previous definition of the permission
188     DELETE FROM permission_label_rule_view
189     WHERE       permission_label_rule_view.permission_name = NEW.name AND
190                 permission_label_rule_view.permission_type_name = NEW.type_name;
191 END;
192
193 -- PERMISSION TO LABEL RULE VIEW -----------------------------------------------
194 DROP VIEW IF EXISTS permission_label_rule_view;
195 CREATE VIEW permission_label_rule_view AS
196 SELECT
197         permission_view.permission_id       AS permission_id,
198         permission_view.name                AS permission_name,
199         permission_view.type_name           AS permission_type_name,
200         label.name                              AS label_name,
201         permission_label_rule.access            AS access,
202         permission_label_rule.is_reverse        AS is_reverse
203 FROM    permission_label_rule
204 LEFT JOIN permission_view USING(permission_id)
205 LEFT JOIN label USING(label_id);
206
207
208 -- Preferred way of adding permission rules would be to use these ONE, multi-row
209 -- insert statement, with one check of a condition
210 -- that there is such permission id. It's impossible to make those inserts in C,
211 -- so the programmer has to secure, that there is a permission with a given id.
212 -- (Check it and insert in the same transaction)
213 -- In runtime we accept ONLY inserts with label.
214 -- All other kinds of permissions are filled during the database creation.
215 DROP TRIGGER IF EXISTS permission_label_rule_view_insert_trigger;
216 CREATE TRIGGER permission_label_rule_view_insert_trigger
217 INSTEAD OF INSERT ON permission_label_rule_view
218 BEGIN
219     -- Adding api features adds a label it it's not present.
220     INSERT OR IGNORE INTO label(name) VALUES (NEW.label_name);
221
222     INSERT INTO permission_label_rule(permission_id, label_id, access, is_reverse)
223     SELECT      NEW.permission_id,
224                 label.label_id,
225                 str_to_access(NEW.access),
226                 NEW.is_reverse
227     FROM        label
228     WHERE       label.name = NEW.label_name;
229 END;
230
231
232 -- TODO: Potential problem - undeleted labels.
233 DROP TRIGGER IF EXISTS permission_label_rule_view_delete_trigger;
234 CREATE TRIGGER permission_label_rule_view_delete_trigger
235 INSTEAD OF DELETE ON permission_label_rule_view
236 BEGIN
237         DELETE FROM permission_label_rule
238         WHERE   permission_label_rule.permission_id
239                 IN (SELECT permission_view.permission_id
240                     FROM   permission_view
241                     WHERE  permission_view.name = OLD.permission_name AND
242                            permission_view.type_name = OLD.permission_type_name);
243 END;
244
245
246 -- PERMISSION TO APP PATH TYPE RULE VIEW ---------------------------------------
247 DROP VIEW IF EXISTS permission_app_path_type_rule_view;
248 CREATE VIEW permission_app_path_type_rule_view AS
249 SELECT
250         permission_view.permission_id       AS permission_id,
251         permission_view.name                AS permission_name,
252         permission_view.type_name           AS permission_type_name,
253         app_path_type.name                      AS app_path_type_name,
254         permission_app_path_type_rule.access       AS access,
255         permission_app_path_type_rule.is_reverse   AS is_reverse
256 FROM    permission_app_path_type_rule
257 LEFT JOIN permission_view USING(permission_id)
258 LEFT JOIN app_path_type USING(app_path_type_id);
259
260
261 DROP TRIGGER IF EXISTS permission_app_path_type_rule_view_insert_trigger;
262 CREATE TRIGGER permission_app_path_type_rule_view_insert_trigger
263 INSTEAD OF INSERT
264 ON permission_app_path_type_rule_view
265 BEGIN
266     INSERT INTO permission_app_path_type_rule(permission_id,
267                                               app_path_type_id,
268                                               access,
269                                               is_reverse)
270     SELECT      permission_view.permission_id,
271                 app_path_type.app_path_type_id,
272                 str_to_access(NEW.access),
273                 NEW.is_reverse
274     FROM        permission_view, app_path_type
275     WHERE       permission_view.name = NEW.permission_name AND
276                 permission_view.type_name = NEW.permission_type_name AND
277                 app_path_type.name = NEW.app_path_type_name;
278 END;
279
280 DROP TRIGGER IF EXISTS permission_app_path_type_rule_view_delete_trigger;
281 CREATE TRIGGER permission_app_path_type_rule_view_delete_trigger
282 INSTEAD OF DELETE
283 ON permission_app_path_type_rule_view
284 BEGIN
285     -- Delete the rule
286     DELETE FROM permission_app_path_type_rule
287     WHERE       permission_app_path_type_rule.permission_id
288                 IN (SELECT permission_view.permission_id
289                     FROM   permission_view
290                     WHERE  permission_view.name = OLD.permission_name AND
291                            permission_view.type_name = OLD.permission_type_name);
292 END;
293
294
295 -- PERMISSION TO PERMISSION RULE VIEW ------------------------------------------
296 DROP VIEW IF EXISTS permission_permission_rule_view;
297 CREATE VIEW permission_permission_rule_view AS
298 SELECT
299         tmp_permission_view.permission_id       AS permission_id,
300         tmp_permission_view.name                AS permission_name,
301         tmp_permission_view.type_name           AS permission_type_name,
302         tmp_target_permission_view.name         AS target_permission_name,
303         tmp_target_permission_view.type_name    AS target_permission_type_name,
304         permission_permission_rule.access       AS access,
305         permission_permission_rule.is_reverse   AS is_reverse
306 FROM    permission_permission_rule
307 LEFT JOIN permission_view AS tmp_permission_view USING(permission_id)
308 LEFT JOIN permission_view AS tmp_target_permission_view
309 ON permission_permission_rule.target_permission_id = tmp_target_permission_view.permission_id;
310
311
312 -- Trigger for manual addition of rules.
313 DROP TRIGGER IF EXISTS permission_permission_rule_view_insert_trigger;
314 CREATE TRIGGER  permission_permission_rule_view_insert_trigger
315 INSTEAD OF INSERT ON  permission_permission_rule_view
316 BEGIN
317
318     INSERT INTO permission_permission_rule(permission_id,
319                                            target_permission_id,
320                                            access,
321                                            is_reverse)
322     SELECT  tmp_permission_view.permission_id,
323             tmp_target_permission_view.permission_id,
324             str_to_access(NEW.access),
325             NEW.is_reverse
326     FROM    permission_view AS tmp_permission_view,
327             permission_view AS tmp_target_permission_view
328     WHERE   tmp_permission_view.name = NEW.permission_name AND
329             tmp_permission_view.type_name = NEW.permission_type_name AND
330             tmp_target_permission_view.name = NEW.target_permission_name AND
331             tmp_target_permission_view.type_name = NEW.target_permission_type_name;
332 END;
333
334
335 DROP TRIGGER IF EXISTS permission_permission_rule_view_delete_trigger;
336 CREATE TRIGGER  permission_permission_rule_view_delete_trigger
337 INSTEAD OF DELETE ON  permission_permission_rule_view
338 BEGIN
339     -- Delete the rule
340     DELETE FROM permission_permission_rule_view
341     WHERE       permission_permission_rule_view.permission_id
342                 IN (SELECT permission_view.permission_id
343                     FROM   permission_view
344                     WHERE  permission_view.name = OLD.permission_name AND
345                            permission_view.type_name = OLD.permission_type_name);
346 END;
347
348
349
350 -- LABEL VIEW ------------------------------------------------------------------
351 -- There are no INSTEAD OF triggers on regular tables.
352 -- We use a view to delete unreferenced labels:
353 DROP VIEW IF EXISTS label_view;
354 CREATE VIEW label_view AS SELECT * FROM label;
355
356 DROP TRIGGER IF EXISTS label_view_delete_trigger;
357 CREATE TRIGGER label_view_delete_trigger
358 INSTEAD OF DELETE ON label_view
359 WHEN    OLD.label_id NOT IN (SELECT app.label_id
360                              FROM app) AND
361         OLD.label_id NOT IN (SELECT permission_label_rule.label_id
362                              FROM permission_label_rule) AND
363         OLD.label_id NOT IN (SELECT app_path.label_id
364                              FROM app_path)
365 BEGIN
366         DELETE FROM label WHERE label.name = OLD.name;
367 END;
368
369
370 -- APPLICATION VIEW ------------------------------------------------------------
371 DROP VIEW IF EXISTS application_view;
372 CREATE VIEW application_view AS
373 SELECT      app.app_id, label.name
374 FROM        label
375 INNER JOIN  app USING(label_id);
376
377 DROP TRIGGER IF EXISTS application_view_insert_trigger;
378 CREATE TRIGGER application_view_insert_trigger
379 INSTEAD OF INSERT ON application_view
380 BEGIN
381     -- The app's label could have been added by the permission.
382     INSERT OR IGNORE INTO label(name) VALUES (NEW.name);
383
384     -- Add application:
385     INSERT INTO app(label_id)
386     SELECT label_id
387     FROM   label
388     WHERE  label.name = NEW.name;
389
390     -- Add the permission granted to all applications
391     INSERT INTO app_permission_view(app_id, name, type_name, is_volatile, is_enabled)
392     VALUES (last_insert_rowid(), "ALL_APPS", "ALL_APPS", 0, 1);
393
394 END;
395
396
397 DROP TRIGGER IF EXISTS application_view_delete_trigger;
398 CREATE TRIGGER application_view_delete_trigger
399 INSTEAD OF DELETE ON application_view
400 BEGIN
401         -- Delete rules that correspond to app's paths:
402         DELETE FROM permission_label_rule
403         WHERE       permission_label_rule.label_id IN
404                    (SELECT     app_path.label_id
405                     FROM       app_path
406                     INNER JOIN application_view USING(app_id)
407                     WHERE      application_view.name = OLD.name);
408
409         -- Delete path
410         DELETE FROM path_view
411         WHERE path_view.owner_app_label_name=OLD.name;
412
413         -- Delete apps permissions:
414         DELETE FROM app_permission
415         WHERE       app_permission.app_id
416                     IN (SELECT application_view.app_id
417                         FROM   application_view
418                         WHERE  application_view.name = OLD.name
419                         LIMIT  1);
420
421         -- Delete application
422         DELETE FROM app
423         WHERE app.app_id IN (SELECT application_view.app_id
424                              FROM   application_view
425                              WHERE  application_view.name = OLD.name
426                              LIMIT  1);
427
428         -- Delete label
429         DELETE FROM label_view
430         WHERE label_view.name = OLD.name;
431 END;
432
433
434 -- PATH VIEW -------------------------------------------------------------------
435 DROP VIEW IF EXISTS path_view;
436 CREATE VIEW path_view AS
437 SELECT  application_view.name   AS owner_app_label_name,
438         app_path.path           AS path,
439         label.name              AS path_label_name,
440         app_path.access         AS access,
441         app_path_type.name      AS path_type_name
442
443 FROM    app_path
444 LEFT JOIN app_path_type     USING (app_path_type_id)
445 LEFT JOIN application_view  USING (app_id)
446 LEFT JOIN label             USING (label_id);
447
448
449 -- For an existing application we add a path.
450 DROP TRIGGER IF EXISTS path_view_insert_trigger;
451 CREATE TRIGGER path_view_insert_trigger
452 INSTEAD OF INSERT ON path_view
453 WHEN NEW.owner_app_label_name IN (SELECT application_view.name
454                                   FROM application_view)
455 BEGIN
456     -- The path's label could have been added by the permission.
457     INSERT OR IGNORE INTO label(name) VALUES (NEW.path_label_name);
458
459     -- Add the path
460     INSERT INTO app_path(app_id, path, label_id, access, app_path_type_id)
461     SELECT  application_view.app_id,
462             NEW.path,
463             label.label_id,
464             str_to_access(NEW.access),
465             app_path_type.app_path_type_id
466     FROM    application_view, app_path_type, label
467     WHERE   application_view.name = NEW.owner_app_label_name AND
468             app_path_type.name = NEW.path_type_name AND
469             label.name = NEW.path_label_name;
470 END;
471
472 DROP TRIGGER IF EXISTS path_view_delete_trigger;
473 CREATE TRIGGER path_view_delete_trigger
474 INSTEAD OF DELETE ON path_view
475 BEGIN
476         -- Delete the path
477         DELETE FROM app_path
478         WHERE app_path.app_id IN (SELECT  app.app_id
479                                   FROM    app, label
480                                   WHERE   label.name = OLD.owner_app_label_name AND
481                                           app.label_id = label.label_id);
482
483         -- Delete the path's label if it's not used any more
484         DELETE FROM label_view WHERE label_view.name = OLD.path_label_name;
485 END;
486
487 -- APP PERMISSION LIST VIEW ----------------------------------------------------
488 -- Used in check_app_permission_internal to check if permissions are present
489 -- TODO: Check if SQLite optimizer doesn't change app_permission_view to the same code.
490 DROP VIEW IF EXISTS app_permission_list_view;
491 CREATE VIEW app_permission_list_view AS
492 SELECT      app_permission.app_id AS app_id,
493             app_permission.permission_id AS permission_id,
494             permission_view.name AS permission_name,
495             permission_view.type_name AS permission_type_name,
496             app_permission.is_volatile AS is_volatile,
497             app_permission.is_enabled AS is_enabled
498 FROM        app_permission
499 INNER JOIN  permission_view USING(permission_id);
500
501
502
503
504 -- APP PERMISSION VIEW ---------------------------------------------------------
505 DROP VIEW IF EXISTS app_permission_view;
506 CREATE VIEW app_permission_view AS
507 SELECT      application_view.app_id,
508             application_view.name  AS app_name,
509             permission_view.permission_id,
510             permission_view.name,
511             permission_view.type_name,
512             app_permission.is_volatile,
513             app_permission.is_enabled
514 FROM        app_permission
515 INNER JOIN  application_view USING(app_id)
516 INNER JOIN  permission_view USING(permission_id);
517
518
519 DROP TRIGGER IF EXISTS app_permission_view_insert_trigger;
520 CREATE TRIGGER app_permission_view_insert_trigger
521 INSTEAD OF INSERT ON app_permission_view
522 BEGIN
523     INSERT INTO app_permission(app_id, permission_id, is_volatile, is_enabled)
524     SELECT      NEW.app_id,
525                 permission_view.permission_id,
526                 NEW.is_volatile,
527                 NEW.is_enabled
528     FROM        permission_view
529     WHERE       permission_view.name = NEW.name AND
530                 permission_view.type_name = NEW.type_name;
531 END;
532
533
534
535
536 -- It's forbidden do change permission from not volatile to volatile.
537 -- We have to check it before inserting anything.
538 -- Used in updating permissions
539 DROP TRIGGER IF EXISTS app_permission_view_update_trigger;
540 CREATE TRIGGER app_permission_view_update_trigger
541 INSTEAD OF UPDATE ON app_permission_view
542 BEGIN
543     UPDATE OR IGNORE app_permission
544     SET              is_enabled = NEW.is_enabled
545     WHERE            app_permission.app_id = OLD.app_id AND
546                      app_permission.permission_id
547                      IN (SELECT  permission_view.permission_id
548                          FROM    permission_view
549                          WHERE   permission_view.name = OLD.name AND
550                                  permission_view.type_name = OLD.type_name
551                          LIMIT 1);
552 END;
553
554
555 DROP TRIGGER IF EXISTS app_permission_view_delete_trigger;
556 CREATE TRIGGER app_permission_view_delete_trigger
557 INSTEAD OF DELETE ON app_permission_view
558 BEGIN
559     DELETE FROM app_permission
560     WHERE       app_permission.app_id
561                 IN (SELECT application_view.app_id
562                     FROM   application_view
563                     WHERE  application_view.name = OLD.app_name
564                     LIMIT  1)
565                 AND
566                 app_permission.permission_id NOT IN (SELECT permission_view.permission_id
567                                                      FROM   permission_view
568                                                      WHERE  permission_view.name = "ALL_APPS" AND
569                                                             permission_view.type_name = "ALL_APPS");
570 END;
571
572 -- APP PERMISSION VOLATILE VIEW ------------------------------------------------
573 DROP VIEW IF EXISTS app_permission_volatile_view;
574 CREATE VIEW app_permission_volatile_view AS
575 SELECT      *
576 FROM        app_permission_view
577 WHERE       app_permission_view.is_volatile = 1;
578
579
580 DROP TRIGGER IF EXISTS app_permission_volatile_view_delete_trigger;
581 CREATE TRIGGER app_permission_volatile_view_delete_trigger
582 INSTEAD OF DELETE ON app_permission_volatile_view
583 BEGIN
584     DELETE FROM app_permission
585     WHERE       app_permission.is_volatile = 1 AND
586                 app_permission.app_id
587                 IN (SELECT application_view.app_id
588                     FROM   application_view
589                     WHERE  application_view.name = OLD.app_name
590                     LIMIT  1);
591 END;
592
593
594 -- APPLICATIONS PERMISSIONS ID -------------------------------------------------
595 -- All applications and their permissions
596 DROP VIEW IF EXISTS app_label_with_permission_view;
597 CREATE VIEW app_label_with_permission_view AS
598 SELECT      app_permission.permission_id,
599             application_view.name,
600             application_view.app_id,
601             app_permission.is_volatile
602 FROM        app_permission
603 INNER JOIN  application_view USING(app_id)
604 WHERE       app_permission.is_enabled = 1;
605
606
607
608 -- PERMISSION TO PERMISSION RULE VIEW ------------------------------------------
609 -- ltl = label to label
610 DROP VIEW IF EXISTS ltl_permission_permission_rule_view;
611 CREATE VIEW ltl_permission_permission_rule_view AS
612 SELECT      (CASE WHEN is_reverse = 0 THEN app1.name ELSE app2.name END) AS subject,
613             (CASE WHEN is_reverse = 1 THEN app1.name ELSE app2.name END) AS object,
614             p.access,
615             app1.is_volatile OR app2.is_volatile AS is_volatile
616 FROM        permission_permission_rule AS p
617 INNER JOIN  app_label_with_permission_view AS app1 USING(permission_id)
618 INNER JOIN  app_label_with_permission_view AS app2
619             ON app2.permission_id = p.target_permission_id
620 WHERE       app1.app_id != app2.app_id;
621
622 -- PERMISSION TO LABEL RULE VIEW -----------------------------------------------
623 -- ltl = label to label
624 DROP VIEW IF EXISTS ltl_permission_label_rule_view;
625 CREATE VIEW ltl_permission_label_rule_view AS
626 SELECT      (CASE WHEN is_reverse = 0 THEN app.name ELSE label.name END) AS subject,
627             (CASE WHEN is_reverse = 1 THEN app.name ELSE label.name END) AS object,
628             p.access,
629             app.is_volatile
630 FROM        permission_label_rule AS p
631 INNER JOIN  app_label_with_permission_view AS app USING(permission_id)
632 INNER JOIN  label USING(label_id)
633 WHERE       app.name != label.name;
634
635
636
637 -- PERMISSION TO PATH TYPE RULE VIEW -------------------------------------------
638 -- ltl = label to label
639 DROP VIEW IF EXISTS ltl_permission_app_path_type_rule_view;
640 CREATE VIEW ltl_permission_app_path_type_rule_view AS
641 SELECT      (CASE WHEN is_reverse = 0 THEN app.name ELSE label.name END) AS subject,
642             (CASE WHEN is_reverse = 1 THEN app.name ELSE label.name END) AS object,
643             p.access,
644             app.is_volatile
645 FROM        permission_app_path_type_rule AS p
646 INNER JOIN  app_label_with_permission_view AS app USING(permission_id)
647 INNER JOIN  app_path USING(app_path_type_id)
648 INNER JOIN  label USING(label_id)
649 WHERE       app.name != label.name;
650
651
652 -- PERMISSION TO APPLICATION'S OWN PATHS ---------------------------------------
653 -- ltl = label to label
654 DROP VIEW IF EXISTS ltl_app_path_view;
655 CREATE VIEW ltl_app_path_view AS
656 SELECT      application_view.name   AS subject,
657             label.name              AS object,
658             app_path.access         AS access
659 FROM        app_path
660 INNER JOIN  application_view USING(app_id)
661 INNER JOIN  label USING(label_id);
662
663
664 -- SMACK RULES VIEWS -----------------------------------------------------------
665 DROP VIEW IF EXISTS all_smack_binary_rules_view;
666 CREATE VIEW all_smack_binary_rules_view AS
667 SELECT  subject,
668         object,
669         bitwise_or(access) AS access,
670         MIN(is_volatile) AS is_volatile
671 FROM   (SELECT subject, object, access, is_volatile
672         FROM   ltl_permission_permission_rule_view
673         UNION ALL
674         SELECT subject, object, access, is_volatile
675         FROM   ltl_permission_label_rule_view
676         UNION ALL
677         SELECT subject, object, access, is_volatile
678         FROM   ltl_permission_app_path_type_rule_view
679         UNION ALL
680         SELECT subject, object, access, 0
681         FROM   ltl_app_path_view
682        )
683 GROUP BY subject, object
684 ORDER BY subject, object ASC;
685
686 -- ALL INSERTED DATA VIEW ------------------------------------------------------
687 -- This view is used to clear the database from inserted rules.
688 -- We loose all information about installed applications
689 -- and folders.
690 DROP VIEW IF EXISTS all_inserted_data;
691 CREATE VIEW all_inserted_data AS
692 SELECT      *
693 FROM        label;
694
695 DROP TRIGGER IF EXISTS all_inserted_data_delete_trigger;
696 CREATE TRIGGER all_inserted_data_delete_trigger INSTEAD OF
697 DELETE ON all_inserted_data
698 BEGIN
699     DELETE FROM permission_label_rule;
700     DELETE FROM permission_permission_rule;
701     DELETE FROM permission_app_path_type_rule;
702
703     DELETE FROM app_permission;
704
705     DELETE FROM permission;
706     DELETE FROM permission_type;
707
708     DELETE FROM app_path;
709     DELETE FROM app_path_type;
710     DELETE FROM app;
711
712     DELETE FROM label;
713 END;
714
715
716
717 -- SMACK RULES MODIFICATIONS VIEW ----------------------------------------------
718 -- This definition is repeated during opening a connection with the database.
719 -- Used to get all smack rules, even volatile.
720 -- Ensure it's the same!
721 CREATE TEMPORARY VIEW modified_smack_rules AS
722 SELECT  subject, object,
723         access_to_str(access_add) AS access_add,
724         access_to_str(access_del) AS access_del
725 FROM    (
726         SELECT     subject, object,
727                    s1.access & ~s2.access AS access_add,
728                    s2.access & ~s1.access AS access_del
729         FROM       all_smack_binary_rules AS s1
730         INNER JOIN history_smack_rule AS s2
731                    USING (subject, object)
732         WHERE      s1.access != s2.access
733
734         UNION
735
736         SELECT     subject, object,
737                    s1.access AS access_add,
738                    0 AS access_del
739         FROM       all_smack_binary_rules AS s1
740         LEFT JOIN  history_smack_rule s2
741                    USING (subject, object)
742         WHERE      s2.subject IS NULL AND
743                    s2.object  IS NULL
744
745         UNION
746
747         SELECT     subject, object,
748                    0 AS access_add,
749                    s1.access AS access_del
750         FROM       history_smack_rule s1
751         LEFT JOIN  all_smack_binary_rules AS s2
752                    USING (subject, object)
753         WHERE      s2.subject IS NULL AND
754                    s2.object  IS NULL
755         )
756 ORDER BY subject, object ASC;
757
758
759 -- Update here!
760 PRAGMA schema_version = 1;
761
762 COMMIT TRANSACTION;