Deleting paths on revoking permissions.
[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     -- Delete paths
571     DELETE FROM path_view
572     WHERE path_view.owner_app_label_name=OLD.app_name;
573
574 END;
575
576 -- APP PERMISSION VOLATILE VIEW ------------------------------------------------
577 DROP VIEW IF EXISTS app_permission_volatile_view;
578 CREATE VIEW app_permission_volatile_view AS
579 SELECT      *
580 FROM        app_permission_view
581 WHERE       app_permission_view.is_volatile = 1;
582
583
584 DROP TRIGGER IF EXISTS app_permission_volatile_view_delete_trigger;
585 CREATE TRIGGER app_permission_volatile_view_delete_trigger
586 INSTEAD OF DELETE ON app_permission_volatile_view
587 BEGIN
588     DELETE FROM app_permission
589     WHERE       app_permission.is_volatile = 1 AND
590                 app_permission.app_id
591                 IN (SELECT application_view.app_id
592                     FROM   application_view
593                     WHERE  application_view.name = OLD.app_name
594                     LIMIT  1);
595 END;
596
597
598 -- APPLICATIONS PERMISSIONS ID -------------------------------------------------
599 -- All applications and their permissions
600 DROP VIEW IF EXISTS app_label_with_permission_view;
601 CREATE VIEW app_label_with_permission_view AS
602 SELECT      app_permission.permission_id,
603             application_view.name,
604             application_view.app_id,
605             app_permission.is_volatile
606 FROM        app_permission
607 INNER JOIN  application_view USING(app_id)
608 WHERE       app_permission.is_enabled = 1;
609
610
611
612 -- PERMISSION TO PERMISSION RULE VIEW ------------------------------------------
613 -- ltl = label to label
614 DROP VIEW IF EXISTS ltl_permission_permission_rule_view;
615 CREATE VIEW ltl_permission_permission_rule_view AS
616 SELECT      (CASE WHEN is_reverse = 0 THEN app1.name ELSE app2.name END) AS subject,
617             (CASE WHEN is_reverse = 1 THEN app1.name ELSE app2.name END) AS object,
618             p.access,
619             app1.is_volatile OR app2.is_volatile AS is_volatile
620 FROM        permission_permission_rule AS p
621 INNER JOIN  app_label_with_permission_view AS app1 USING(permission_id)
622 INNER JOIN  app_label_with_permission_view AS app2
623             ON app2.permission_id = p.target_permission_id
624 WHERE       app1.app_id != app2.app_id;
625
626 -- PERMISSION TO LABEL RULE VIEW -----------------------------------------------
627 -- ltl = label to label
628 DROP VIEW IF EXISTS ltl_permission_label_rule_view;
629 CREATE VIEW ltl_permission_label_rule_view AS
630 SELECT      (CASE WHEN is_reverse = 0 THEN app.name ELSE label.name END) AS subject,
631             (CASE WHEN is_reverse = 1 THEN app.name ELSE label.name END) AS object,
632             p.access,
633             app.is_volatile
634 FROM        permission_label_rule AS p
635 INNER JOIN  app_label_with_permission_view AS app USING(permission_id)
636 INNER JOIN  label USING(label_id)
637 WHERE       app.name != label.name;
638
639
640
641 -- PERMISSION TO PATH TYPE RULE VIEW -------------------------------------------
642 -- ltl = label to label
643 DROP VIEW IF EXISTS ltl_permission_app_path_type_rule_view;
644 CREATE VIEW ltl_permission_app_path_type_rule_view AS
645 SELECT      (CASE WHEN is_reverse = 0 THEN app.name ELSE label.name END) AS subject,
646             (CASE WHEN is_reverse = 1 THEN app.name ELSE label.name END) AS object,
647             p.access,
648             app.is_volatile
649 FROM        permission_app_path_type_rule AS p
650 INNER JOIN  app_label_with_permission_view AS app USING(permission_id)
651 INNER JOIN  app_path USING(app_path_type_id)
652 INNER JOIN  label USING(label_id)
653 WHERE       app.name != label.name;
654
655
656 -- PERMISSION TO APPLICATION'S OWN PATHS ---------------------------------------
657 -- ltl = label to label
658 DROP VIEW IF EXISTS ltl_app_path_view;
659 CREATE VIEW ltl_app_path_view AS
660 SELECT      application_view.name   AS subject,
661             label.name              AS object,
662             app_path.access         AS access
663 FROM        app_path
664 INNER JOIN  application_view USING(app_id)
665 INNER JOIN  label USING(label_id);
666
667
668 -- SMACK RULES VIEWS -----------------------------------------------------------
669 DROP VIEW IF EXISTS all_smack_binary_rules_view;
670 CREATE VIEW all_smack_binary_rules_view AS
671 SELECT  subject,
672         object,
673         bitwise_or(access) AS access,
674         MIN(is_volatile) AS is_volatile
675 FROM   (SELECT subject, object, access, is_volatile
676         FROM   ltl_permission_permission_rule_view
677         UNION ALL
678         SELECT subject, object, access, is_volatile
679         FROM   ltl_permission_label_rule_view
680         UNION ALL
681         SELECT subject, object, access, is_volatile
682         FROM   ltl_permission_app_path_type_rule_view
683         UNION ALL
684         SELECT subject, object, access, 0
685         FROM   ltl_app_path_view
686        )
687 GROUP BY subject, object
688 ORDER BY subject, object ASC;
689
690 -- ALL INSERTED DATA VIEW ------------------------------------------------------
691 -- This view is used to clear the database from inserted rules.
692 -- We loose all information about installed applications
693 -- and folders.
694 DROP VIEW IF EXISTS all_inserted_data;
695 CREATE VIEW all_inserted_data AS
696 SELECT      *
697 FROM        label;
698
699 DROP TRIGGER IF EXISTS all_inserted_data_delete_trigger;
700 CREATE TRIGGER all_inserted_data_delete_trigger INSTEAD OF
701 DELETE ON all_inserted_data
702 BEGIN
703     DELETE FROM permission_label_rule;
704     DELETE FROM permission_permission_rule;
705     DELETE FROM permission_app_path_type_rule;
706
707     DELETE FROM app_permission;
708
709     DELETE FROM permission;
710     DELETE FROM permission_type;
711
712     DELETE FROM app_path;
713     DELETE FROM app_path_type;
714     DELETE FROM app;
715
716     DELETE FROM label;
717 END;
718
719
720
721 -- SMACK RULES MODIFICATIONS VIEW ----------------------------------------------
722 -- This definition is repeated during opening a connection with the database.
723 -- Used to get all smack rules, even volatile.
724 -- Ensure it's the same!
725 CREATE TEMPORARY VIEW modified_smack_rules AS
726 SELECT  subject, object,
727         access_to_str(access_add) AS access_add,
728         access_to_str(access_del) AS access_del
729 FROM    (
730         SELECT     subject, object,
731                    s1.access & ~s2.access AS access_add,
732                    s2.access & ~s1.access AS access_del
733         FROM       all_smack_binary_rules AS s1
734         INNER JOIN history_smack_rule AS s2
735                    USING (subject, object)
736         WHERE      s1.access != s2.access
737
738         UNION
739
740         SELECT     subject, object,
741                    s1.access AS access_add,
742                    0 AS access_del
743         FROM       all_smack_binary_rules AS s1
744         LEFT JOIN  history_smack_rule s2
745                    USING (subject, object)
746         WHERE      s2.subject IS NULL AND
747                    s2.object  IS NULL
748
749         UNION
750
751         SELECT     subject, object,
752                    0 AS access_add,
753                    s1.access AS access_del
754         FROM       history_smack_rule s1
755         LEFT JOIN  all_smack_binary_rules AS s2
756                    USING (subject, object)
757         WHERE      s2.subject IS NULL AND
758                    s2.object  IS NULL
759         )
760 ORDER BY subject, object ASC;
761
762
763 -- Update here!
764 PRAGMA schema_version = 1;
765
766 COMMIT TRANSACTION;