summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2006-01-06 21:04:32 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:49:48 -0500
commita8eec313549905724a8186a1a4c14480658e2967 (patch)
treed5508e749de4d304a86a3abfc733b0b529d1c5e6
parentb51fe793c7cefb693d6d3633272b82238e712abe (diff)
downloadsamba-a8eec313549905724a8186a1a4c14480658e2967.tar.gz
samba-a8eec313549905724a8186a1a4c14480658e2967.tar.bz2
samba-a8eec313549905724a8186a1a4c14480658e2967.zip
r12746: An initial version of the kludge_acls module.
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)
-rw-r--r--source4/dsdb/samdb/ldb_modules/config.mk13
-rw-r--r--source4/dsdb/samdb/ldb_modules/kludge_acl.c210
-rw-r--r--source4/lib/ldb/common/ldb_modules.c1
-rw-r--r--source4/lib/ldb/common/ldb_msg.c10
-rw-r--r--source4/scripting/ejs/smbcalls_auth.c17
-rw-r--r--source4/scripting/ejs/smbcalls_ldb.c11
-rwxr-xr-xsource4/setup/provision4
-rw-r--r--source4/setup/provision_init.ldif2
8 files changed, 257 insertions, 11 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk
index 7fc0522034..c53c7c1606 100644
--- a/source4/dsdb/samdb/ldb_modules/config.mk
+++ b/source4/dsdb/samdb/ldb_modules/config.mk
@@ -70,6 +70,19 @@ REQUIRED_SUBSYSTEMS = \
################################################
################################################
+# 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]
SUBSYSTEM = LIBLDB
diff --git a/source4/dsdb/samdb/ldb_modules/kludge_acl.c b/source4/dsdb/samdb/ldb_modules/kludge_acl.c
new file mode 100644
index 0000000000..d2fd96267d
--- /dev/null
+++ b/source4/dsdb/samdb/ldb_modules/kludge_acl.c
@@ -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;
+}
diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c
index 715112a628..f83f0b06ef 100644
--- a/source4/lib/ldb/common/ldb_modules.c
+++ b/source4/lib/ldb/common/ldb_modules.c
@@ -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 }
};
diff --git a/source4/lib/ldb/common/ldb_msg.c b/source4/lib/ldb/common/ldb_msg.c
index 269599818c..deb32133c1 100644
--- a/source4/lib/ldb/common/ldb_msg.c
+++ b/source4/lib/ldb/common/ldb_msg.c
@@ -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--;
}
/*
diff --git a/source4/scripting/ejs/smbcalls_auth.c b/source4/scripting/ejs/smbcalls_auth.c
index 8ef04bec97..3ec376f4fe 100644
--- a/source4/scripting/ejs/smbcalls_auth.c
+++ b/source4/scripting/ejs/smbcalls_auth.c
@@ -158,9 +158,26 @@ static int ejs_userAuth(MprVarHandle eid, int argc, struct MprVar **argv)
}
/*
+ 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);
}
diff --git a/source4/scripting/ejs/smbcalls_ldb.c b/source4/scripting/ejs/smbcalls_ldb.c
index 798747b36c..39698947d7 100644
--- a/source4/scripting/ejs/smbcalls_ldb.c
+++ b/source4/scripting/ejs/smbcalls_ldb.c
@@ -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,
diff --git a/source4/setup/provision b/source4/setup/provision
index 51e62016a8..6974afeec9 100755
--- a/source4/setup/provision
+++ b/source4/setup/provision
@@ -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;
diff --git a/source4/setup/provision_init.ldif b/source4/setup/provision_init.ldif
index 6d452a17e7..db532f3078 100644
--- a/source4/setup/provision_init.ldif
+++ b/source4/setup/provision_init.ldif
@@ -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