OSDN Git Service

Fix building issues with pie-x86
[android-x86/external-koush-Superuser.git] / Superuser / jni / su / db.c
index cbccd6e..dd47197 100644 (file)
 #include <stdio.h>
 #include <limits.h>
 #include <sqlite3.h>
+#include <time.h>
 
 #include "su.h"
 
-static int database_callback(void *NotUsed, int argc, char **argv, char **azColName){
+struct callback_data_t {
+    struct su_context *ctx;
+    policy_t policy;
+};
+
+static int database_callback(void *v, int argc, char **argv, char **azColName){
+    struct callback_data_t *data = (struct callback_data_t *)v;
+    int command_match = 0;
+    policy_t policy = DENY;
     int i;
-    for(i=0; i<argc; i++){
-        printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
+    time_t until = 0;
+    for(i = 0; i < argc; i++) {
+        if (strcmp(azColName[i], "policy") == 0) {
+            if (argv[i] == NULL) {
+                policy = DENY;
+            }
+            if (strcmp(argv[i], "allow") == 0) {
+                policy = ALLOW;
+            }
+            else if (strcmp(argv[i], "interactive") == 0) {
+                policy = INTERACTIVE;
+            }
+            else {
+                policy = DENY;
+            }
+        }
+        else if (strcmp(azColName[i], "command") == 0) {
+            // null or empty command means to match all commands (whitelist all from uid)
+            command_match = argv[i] == NULL || strlen(argv[i]) == 0 || strcmp(argv[i], get_command(&(data->ctx->to))) == 0;
+        }
+        else if (strcmp(azColName[i], "until") == 0) {
+            if (argv[i] != NULL) {
+                until = atoi(argv[i]);
+            }
+        }
+    }
+
+    // check for command match
+    if (command_match) {
+        // also make sure this policy has not expired
+        if (until == 0 || until > time(NULL)) {
+            if (policy == DENY) {
+                data->policy = DENY;
+                return -1;
+            }
+
+            data->policy = ALLOW;
+            // even though we allow, continue, so we can see if there's another policy
+            // that denies...
+        }
     }
-    printf("\n");
+    
     return 0;
 }
 
-int database_check(struct su_context *ctx) {
+policy_t database_check(struct su_context *ctx) {
     sqlite3 *db = NULL;
     
     char query[512];
-    snprintf(query, sizeof(query), "select allow_type, until, command from access where uid=%d", ctx->from.uid);
-    int ret = sqlite3_open(query, &db);
+    snprintf(query, sizeof(query), "select policy, until, command from uid_policy where uid=%d", ctx->from.uid);
+    int ret = sqlite3_open_v2(ctx->user.database_path, &db, SQLITE_OPEN_READONLY, NULL);
     if (ret) {
-        LOGE("sqlite3 open failure");
-        return ret;
+        LOGE("sqlite3 open %s failure: %d", ctx->user.database_path, ret);
+        sqlite3_close(db);
+        return INTERACTIVE;
     }
-
+    
+    char *err = NULL;
+    struct callback_data_t data;
+    data.ctx = ctx;
+    data.policy = INTERACTIVE;
+    ret = sqlite3_exec(db, query, database_callback, &data, &err);
     sqlite3_close(db);
+    if (err != NULL) {
+        LOGE("sqlite3_exec: %s", err);
+        return DENY;
+    }
 
-    return -1;
+    return data.policy;
 }