r12746: An initial version of the kludge_acls module.
authorAndrew Bartlett <abartlet@samba.org>
Fri, 6 Jan 2006 21:04:32 +0000 (21:04 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:49:48 +0000 (13:49 -0500)
This should be replaced with real ACLs, which tridge is working on.
In the meantime, the rules are very simple:

- SYSTEM and Administrators can read all.

- Users and anonymous cannot read passwords, can read everything else

- list of 'password' attributes is hard-coded

Most of the difficult work in this was fighting with the C/js
interface to add a system_session() all, as it still doesn't get on
with me :-)

Andrew Bartlett
(This used to be commit be9d0cae8989429ef47a713d8f0a82f12966fc78)

source4/dsdb/samdb/ldb_modules/config.mk
source4/dsdb/samdb/ldb_modules/kludge_acl.c [new file with mode: 0644]
source4/lib/ldb/common/ldb_modules.c
source4/lib/ldb/common/ldb_msg.c
source4/scripting/ejs/smbcalls_auth.c
source4/scripting/ejs/smbcalls_ldb.c
source4/setup/provision
source4/setup/provision_init.ldif

index 7fc0522034ec71dcf5f28b03f69c9914c8ef1554..c53c7c160699c8ffc5f8b0c767213c05831ba3fd 100644 (file)
@@ -69,6 +69,19 @@ REQUIRED_SUBSYSTEMS = \
 # End MODULE libldb_rootdse
 ################################################
 
+################################################
+# Start MODULE libldb_cludge_acl
+[MODULE::libldb_kludge_acl]
+SUBSYSTEM = LIBLDB
+OUTPUT_TYPE = MERGEDOBJ
+OBJ_FILES = \
+               kludge_acl.o
+REQUIRED_SUBSYSTEMS = \
+               LIB_SECURITY
+#
+# End MODULE libldb_rootdse
+################################################
+
 ################################################
 # Start MODULE libldb_extended_dn
 [MODULE::libldb_extended_dn]
diff --git a/source4/dsdb/samdb/ldb_modules/kludge_acl.c b/source4/dsdb/samdb/ldb_modules/kludge_acl.c
new file mode 100644 (file)
index 0000000..d2fd962
--- /dev/null
@@ -0,0 +1,210 @@
+/* 
+   ldb database library
+
+   Copyright (C) Andrew Bartlett 2005
+
+    This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ *  Name: ldb
+ *
+ *  Component: ldb kludge ACL module
+ *
+ *  Description: Simple module to enforce a simple form of access
+ *               control, sufficient for securing a default Samba4 
+ *               installation.
+ *
+ *  Author: Andrew Bartlett
+ */
+
+#include "includes.h"
+#include "ldb/include/ldb.h"
+#include "ldb/include/ldb_errors.h"
+#include "ldb/include/ldb_private.h"
+#include "auth/auth.h"
+
+/* Kludge ACL rules:
+ *
+ * - System can read passwords
+ * - Administrators can write anything
+ * - Users can read anything that is not a password
+ *
+ */
+
+const char *password_attribs[] = {
+       "sambaPassword",
+       "ntPwdHash",
+       "sambaNTPwdHistory",
+       "lmPwdHash", 
+       "sambaLMPwdHistory",
+       "krb5key"
+};
+
+enum user_is {
+       ANONYMOUS,
+       USER,
+       ADMINISTRATOR,
+       SYSTEM
+};
+
+struct private_data {
+
+       char *some_private_data;
+};
+
+static enum user_is what_is_user(struct ldb_module *module) 
+{
+       struct auth_session_info *session_info
+               = ldb_get_opaque(module->ldb, "sessionInfo");
+       if (!session_info) {
+               return ANONYMOUS;
+       }
+       
+       if (is_system_token(session_info->security_token)) {
+               return SYSTEM;
+       }
+
+       if (is_administrator_token(session_info->security_token)) {
+               return SYSTEM;
+       }
+       if (is_authenticated_token(session_info->security_token)) {
+               return USER;
+       }
+       if (is_anonymous_token(session_info->security_token)) {
+               return ANONYMOUS;
+       }
+       return ANONYMOUS;
+}
+
+/* search */
+static int kludge_acl_search(struct ldb_module *module, struct ldb_request *req)
+{
+       enum user_is user_type;
+       int ret = ldb_next_request(module, req);
+       struct ldb_message *msg;
+       int i, j;
+
+       if (ret != LDB_SUCCESS) {
+               return ret;
+       }
+
+       user_type = what_is_user(module);
+       switch (user_type) {
+       case SYSTEM:
+       case ADMINISTRATOR:
+               return ret;
+       default:
+               /* For every message, remove password attributes */
+               for (i=0; i < req->op.search.res->count; i++) {
+                       msg = req->op.search.res->msgs[i];
+                       for (j=0; j < ARRAY_SIZE(password_attribs); j++) {
+                               ldb_msg_remove_attr(msg, password_attribs[j]);
+                       }
+               }
+       }
+       return ret;
+}
+
+/* ANY change type */
+static int kludge_acl_change(struct ldb_module *module, struct ldb_request *req){
+       enum user_is user_type = what_is_user(module);
+       switch (user_type) {
+       case SYSTEM:
+       case ADMINISTRATOR:
+               return ldb_next_request(module, req);
+       default:
+               ldb_set_errstring(module, 
+                                 talloc_asprintf(req, "kludge_acl_change: "
+                                                 "attempted database modify not permitted. User is not SYSTEM or an administrator"));
+               return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
+       }
+}
+
+/* start a transaction */
+static int kludge_acl_start_trans(struct ldb_module *module)
+{
+       return ldb_next_start_trans(module);
+}
+
+/* end a transaction */
+static int kludge_acl_end_trans(struct ldb_module *module)
+{
+       return ldb_next_end_trans(module);
+}
+
+/* delete a transaction */
+static int kludge_acl_del_trans(struct ldb_module *module)
+{
+       return ldb_next_del_trans(module);
+}
+
+static int kludge_acl_destructor(void *module_ctx)
+{
+       struct ldb_module *ctx = talloc_get_type(module_ctx, struct ldb_module);
+       struct private_data *data = talloc_get_type(ctx->private_data, struct private_data);
+       /* put your clean-up functions here */
+       if (data->some_private_data) talloc_free(data->some_private_data);
+       return 0;
+}
+
+static int kludge_acl_request(struct ldb_module *module, struct ldb_request *req)
+{
+       switch (req->operation) {
+
+       case LDB_REQ_SEARCH:
+               return kludge_acl_search(module, req);
+       case LDB_REQ_REGISTER:
+               return ldb_next_request(module, req);
+       default:
+               /* anything else must be a change of some kind */
+               return kludge_acl_change(module, req);
+       }
+}
+
+static const struct ldb_module_ops kludge_acl_ops = {
+       .name              = "kludge_acl",
+       .request           = kludge_acl_request,
+       .start_transaction = kludge_acl_start_trans,
+       .end_transaction   = kludge_acl_end_trans,
+       .del_transaction   = kludge_acl_del_trans,
+};
+
+struct ldb_module *kludge_acl_module_init(struct ldb_context *ldb, const char *options[])
+{
+       struct ldb_module *ctx;
+       struct private_data *data;
+
+       ctx = talloc(ldb, struct ldb_module);
+       if (!ctx)
+               return NULL;
+
+       data = talloc(ctx, struct private_data);
+       if (data == NULL) {
+               talloc_free(ctx);
+               return NULL;
+       }
+
+       data->some_private_data = NULL;
+       ctx->private_data = data;
+
+       ctx->ldb = ldb;
+       ctx->prev = ctx->next = NULL;
+       ctx->ops = &kludge_acl_ops;
+
+       talloc_set_destructor (ctx, kludge_acl_destructor);
+
+       return ctx;
+}
index 715112a628d02d130ec2e82c3041700c04296851..f83f0b06ef7ef7f5794d93e7516687f2ec30f133 100644 (file)
@@ -141,6 +141,7 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[])
                { "rootdse", rootdse_module_init },
                { "extended_dn", extended_dn_module_init },
                { "password_hash", password_hash_module_init },
+               { "kludge_acl", kludge_acl_module_init },
 #endif
                { NULL, NULL }
        };
index 269599818c754db1e3211abfd1112bb148270955..deb32133c10b522ca36697f623366e6749f6c94e 100644 (file)
@@ -623,11 +623,13 @@ int ldb_msg_copy_attr(struct ldb_message *msg, const char *attr, const char *rep
 void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr)
 {
        struct ldb_message_element *el = ldb_msg_find_element(msg, attr);
-       int n = (el - msg->elements);
-       if (n != msg->num_elements-1) {
-               memmove(el, el+1, ((msg->num_elements-1) - n)*sizeof(*el));
+       if (el) {
+               int n = (el - msg->elements);
+               if (n != msg->num_elements-1) {
+                       memmove(el, el+1, ((msg->num_elements-1) - n)*sizeof(*el));
+               }
+               msg->num_elements--;
        }
-       msg->num_elements--;
 }
 
 /*
index 8ef04bec9795a37b3fa06a72230132a699d02efa..3ec376f4feb26226eb1eb9ab178d6c9ae64587f5 100644 (file)
@@ -157,10 +157,27 @@ static int ejs_userAuth(MprVarHandle eid, int argc, struct MprVar **argv)
        return 0;
 }
 
+/*
+  initialise credentials ejs object
+*/
+static int ejs_system_session(MprVarHandle eid, int argc, struct MprVar **argv)
+{
+       struct MprVar *obj = mprInitObject(eid, "session_info", argc, argv);
+       struct auth_session_info *session_info = system_session(mprMemCtx());
+
+       if (session_info == NULL) {
+               return -1;
+       }
+
+       mprSetPtrChild(obj, "session_info", session_info);
+       return 0;
+}
+
 /*
   setup C functions that be called from ejs
 */
 void smb_setup_ejs_auth(void)
 {
        ejsDefineCFunction(-1, "userAuth", ejs_userAuth, NULL, MPR_VAR_SCRIPT_HANDLE);
+       ejsDefineCFunction(-1, "system_session", ejs_system_session, NULL, MPR_VAR_SCRIPT_HANDLE);
 }
index 798747b36c847834fbb4547f9a989ea1dbb55107..39698947d7be59905fac8c53e7e6da27aa47d8e8 100644 (file)
@@ -385,9 +385,9 @@ static int ejs_ldbModify(MprVarHandle eid, int argc, struct MprVar **argv)
 static int ejs_ldbConnect(MprVarHandle eid, int argc, char **argv)
 {
        struct ldb_context *ldb;
-       struct auth_session_info *session_info;
+       struct auth_session_info *session_info = NULL;
        struct cli_credentials *creds = NULL;
-       struct MprVar *credentials;
+       struct MprVar *credentials, *session;
        struct MprVar *this = mprGetProperty(ejsGetLocalObject(eid), "this", 0);
 
        const char *dbfile;
@@ -397,13 +397,16 @@ static int ejs_ldbConnect(MprVarHandle eid, int argc, char **argv)
                return -1;
        }
 
-       session_info = mprGetThisPtr(eid, "session_info");
-
        credentials = mprGetProperty(this, "credentials", NULL);
        if (credentials) {
                creds = mprGetPtr(credentials, "creds");
        }
 
+       session = mprGetProperty(this, "session_info", NULL);
+       if (session) {
+               session_info = mprGetPtr(session, "session_info");
+       }
+
        dbfile = argv[0];
 
        ldb = ldb_wrap_connect(mprMemCtx(), dbfile, 
index 51e62016a872be7cd3be284454281a3e25b96fd0..6974afeec9b6160568eb7f56ba57cc34b9ebf6ad 100755 (executable)
@@ -114,10 +114,10 @@ if (!provision_validate(subobj, message)) {
 }
 
 var creds = options.get_credentials();
+var system_session = system_session();
 
 message("Provisioning for %s in realm %s\n", subobj.DOMAIN, subobj.REALM);
 message("Using administrator password: %s\n", subobj.ADMINPASS);
-message("Credentials: %s\n", creds);
-provision(subobj, message, blank, provision_default_paths(subobj), NULL, creds);
+provision(subobj, message, blank, provision_default_paths(subobj), system_session, creds);
 message("All OK\n");
 return 0;
index 6d452a17e7bbb99afcf658eff04c0697b412bdd7..db532f3078dae1cb8dfa2485b7bc4b6a6397839c 100644 (file)
@@ -69,5 +69,5 @@ isSynchronized: TRUE
 #Add modules to the list to activate them by default
 #beware often order is important
 dn: @MODULES
-@LIST: rootdse,paged_results,server_sort,extended_dn,samldb,password_hash,operational,objectguid,rdn_name,objectclass
+@LIST: rootdse,kludge_acl,paged_results,server_sort,extended_dn,samldb,password_hash,operational,objectguid,rdn_name,objectclass