[SCM] Samba Shared Repository - branch v4-0-test updated - release-4-0-0alpha2-1349-g7c43560

Andrew Bartlett abartlet at samba.org
Thu Mar 20 02:27:17 GMT 2008


The branch, v4-0-test has been updated
       via  7c4356084a389c3a4edc16f06906ce6127a3a59b (commit)
       via  2f2b110fb870132099bad1d4c16ed8962affb3ce (commit)
      from  b6bb7621053bccc9d06b1b2ee9f71b1b1acf3b70 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v4-0-test


- Log -----------------------------------------------------------------
commit 7c4356084a389c3a4edc16f06906ce6127a3a59b
Merge: 2f2b110fb870132099bad1d4c16ed8962affb3ce b6bb7621053bccc9d06b1b2ee9f71b1b1acf3b70
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Mar 20 13:25:05 2008 +1100

    Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into 4-0-local

commit 2f2b110fb870132099bad1d4c16ed8962affb3ce
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Mar 20 12:12:10 2008 +1100

    More kludge ACLs!
    
    Rather than killing off the nasty 'kludge ACLs' stuff, this patch
    extends it, to ensure that LSA secrets and the registry are also
    protected.
    
    Andrew Bartlett

-----------------------------------------------------------------------

Summary of changes:
 source/dsdb/samdb/ldb_modules/kludge_acl.c |   45 +-----
 source/libcli/security/security.h          |    8 +
 source/libcli/security/security_token.c    |   27 ++++
 source/rpc_server/lsa/dcesrv_lsa.c         |   48 ++++++-
 source/rpc_server/winreg/rpc_winreg.c      |  233 +++++++++++++++++-----------
 5 files changed, 237 insertions(+), 124 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/dsdb/samdb/ldb_modules/kludge_acl.c b/source/dsdb/samdb/ldb_modules/kludge_acl.c
index e3e1f7a..e418031 100644
--- a/source/dsdb/samdb/ldb_modules/kludge_acl.c
+++ b/source/dsdb/samdb/ldb_modules/kludge_acl.c
@@ -46,42 +46,15 @@
  *
  */
 
-enum user_is {
-	ANONYMOUS,
-	USER,
-	ADMINISTRATOR,
-	SYSTEM
-};
-
 struct kludge_private_data {
 	const char **password_attrs;
 };
 
-static enum user_is what_is_user(struct ldb_module *module) 
+static enum security_user_level what_is_user(struct ldb_module *module) 
 {
 	struct auth_session_info *session_info
 		= (struct auth_session_info *)ldb_get_opaque(module->ldb, "sessionInfo");
-	if (!session_info) {
-		return ANONYMOUS;
-	}
-	
-	if (security_token_is_system(session_info->security_token)) {
-		return SYSTEM;
-	}
-
-	if (security_token_is_anonymous(session_info->security_token)) {
-		return ANONYMOUS;
-	}
-
-	if (security_token_has_builtin_administrators(session_info->security_token)) {
-		return ADMINISTRATOR;
-	}
-
-	if (security_token_has_nt_authenticated_users(session_info->security_token)) {
-		return USER;
-	}
-
-	return ANONYMOUS;
+	return security_session_user_level(session_info);
 }
 
 static const char *user_name(TALLOC_CTX *mem_ctx, struct ldb_module *module) 
@@ -104,7 +77,7 @@ struct kludge_acl_context {
 	void *up_context;
 	int (*up_callback)(struct ldb_context *, void *, struct ldb_reply *);
 
-	enum user_is user_type;
+	enum security_user_level user_type;
 	bool allowedAttributes;
 	bool allowedAttributesEffective;
 	bool allowedChildClasses;
@@ -272,8 +245,8 @@ static int kludge_acl_callback(struct ldb_context *ldb, void *context, struct ld
 	if (data && data->password_attrs) /* if we are not initialized just get through */
 	{
 		switch (ac->user_type) {
-		case SYSTEM:
-		case ADMINISTRATOR:
+		case SECURITY_SYSTEM:
+		case SECURITY_ADMINISTRATOR:
 			if (ac->allowedAttributesEffective) {
 				ret = kludge_acl_allowedAttributes(ldb, ares->message, "allowedAttributesEffective");
 				if (ret != LDB_SUCCESS) {
@@ -359,7 +332,7 @@ static int kludge_acl_search(struct ldb_module *module, struct ldb_request *req)
 	   so we don't allow a search for 'sambaPassword=penguin',
 	   just as we would not allow that attribute to be returned */
 	switch (ac->user_type) {
-	case SYSTEM:
+	case SECURITY_SYSTEM:
 		break;
 	default:
 		/* remove password attributes */
@@ -391,10 +364,10 @@ static int kludge_acl_search(struct ldb_module *module, struct ldb_request *req)
 /* 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);
+	enum security_user_level user_type = what_is_user(module);
 	switch (user_type) {
-	case SYSTEM:
-	case ADMINISTRATOR:
+	case SECURITY_SYSTEM:
+	case SECURITY_ADMINISTRATOR:
 		return ldb_next_request(module, req);
 	default:
 		ldb_asprintf_errstring(module->ldb,
diff --git a/source/libcli/security/security.h b/source/libcli/security/security.h
index d9485c8..c7f2a09 100644
--- a/source/libcli/security/security.h
+++ b/source/libcli/security/security.h
@@ -18,4 +18,12 @@
 */
 
 #include "librpc/gen_ndr/security.h"
+
+enum security_user_level {
+	SECURITY_ANONYMOUS,
+	SECURITY_USER,
+	SECURITY_ADMINISTRATOR,
+	SECURITY_SYSTEM
+};
+
 #include "libcli/security/proto.h"
diff --git a/source/libcli/security/security_token.c b/source/libcli/security/security_token.c
index e126340..0680c54 100644
--- a/source/libcli/security/security_token.c
+++ b/source/libcli/security/security_token.c
@@ -23,6 +23,7 @@
 #include "includes.h"
 #include "dsdb/samdb/samdb.h"
 #include "libcli/security/security.h"
+#include "auth/session.h"
 
 /*
   return a blank security token
@@ -141,3 +142,29 @@ bool security_token_has_nt_authenticated_users(const struct security_token *toke
 {
 	return security_token_has_sid_string(token, SID_NT_AUTHENTICATED_USERS);
 }
+
+enum security_user_level security_session_user_level(struct auth_session_info *session_info) 
+{
+	if (!session_info) {
+		return SECURITY_ANONYMOUS;
+	}
+	
+	if (security_token_is_system(session_info->security_token)) {
+		return SECURITY_SYSTEM;
+	}
+
+	if (security_token_is_anonymous(session_info->security_token)) {
+		return SECURITY_ANONYMOUS;
+	}
+
+	if (security_token_has_builtin_administrators(session_info->security_token)) {
+		return SECURITY_ADMINISTRATOR;
+	}
+
+	if (security_token_has_nt_authenticated_users(session_info->security_token)) {
+		return SECURITY_USER;
+	}
+
+	return SECURITY_ANONYMOUS;
+}
+
diff --git a/source/rpc_server/lsa/dcesrv_lsa.c b/source/rpc_server/lsa/dcesrv_lsa.c
index 4d381ea..429c413 100644
--- a/source/rpc_server/lsa/dcesrv_lsa.c
+++ b/source/rpc_server/lsa/dcesrv_lsa.c
@@ -99,8 +99,21 @@ static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX
 	int ret;
 
 	DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
+
 	if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
 		struct lsa_secret_state *secret_state = h->data;
+
+		/* Ensure user is permitted to delete this... */
+		switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+		{
+		case SECURITY_SYSTEM:
+		case SECURITY_ADMINISTRATOR:
+			break;
+		default:
+			/* Users and annonymous are not allowed delete things */
+			return NT_STATUS_ACCESS_DENIED;
+		}
+
 		ret = ldb_delete(secret_state->sam_ldb, 
 				 secret_state->secret_dn);
 		talloc_free(h);
@@ -446,6 +459,8 @@ static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TAL
 
 /* 
   lsa_CreateAccount 
+
+  This call does not seem to have any long-term effects, hence no database operations
 */
 static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
 				  struct lsa_CreateAccount *r)
@@ -1673,6 +1688,16 @@ static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALL
 	DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
 	ZERO_STRUCTP(r->out.sec_handle);
 	
+	switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+	{
+	case SECURITY_SYSTEM:
+	case SECURITY_ADMINISTRATOR:
+		break;
+	default:
+		/* Users and annonymous are not allowed create secrets */
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
 	policy_state = policy_handle->data;
 
 	if (!r->in.name.string) {
@@ -1819,6 +1844,16 @@ static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC
 		return NT_STATUS_INVALID_PARAMETER;
 	}
 	
+	switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+	{
+	case SECURITY_SYSTEM:
+	case SECURITY_ADMINISTRATOR:
+		break;
+	default:
+		/* Users and annonymous are not allowed to access secrets */
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
 	secret_state = talloc(mem_ctx, struct lsa_secret_state);
 	if (!secret_state) {
 		return NT_STATUS_NO_MEMORY;
@@ -1850,10 +1885,10 @@ static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC
 		}
 	
 	} else {
+		secret_state->global = false;
 		secret_state->sam_ldb = talloc_reference(secret_state, 
 				 secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
 
-		secret_state->global = false;
 		name = r->in.name.string;
 		if (strlen(name) < 1) {
 			return NT_STATUS_INVALID_PARAMETER;
@@ -2085,6 +2120,17 @@ static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLO
 
 	DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
 
+	/* Ensure user is permitted to read this... */
+	switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+	{
+	case SECURITY_SYSTEM:
+	case SECURITY_ADMINISTRATOR:
+		break;
+	default:
+		/* Users and annonymous are not allowed to read secrets */
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
 	secret_state = h->data;
 
 	/* pull all the user attributes */
diff --git a/source/rpc_server/winreg/rpc_winreg.c b/source/rpc_server/winreg/rpc_winreg.c
index 681e3b9..9993dc1 100644
--- a/source/rpc_server/winreg/rpc_winreg.c
+++ b/source/rpc_server/winreg/rpc_winreg.c
@@ -26,6 +26,7 @@
 #include "rpc_server/common/common.h"
 #include "librpc/gen_ndr/ndr_security.h"
 #include "param/param.h"
+#include "libcli/security/security.h"
 
 enum handle_types { HTYPE_REGVAL, HTYPE_REGKEY };
 
@@ -120,32 +121,39 @@ static WERROR dcesrv_winreg_CreateKey(struct dcesrv_call_state *dce_call,
 
 	newh = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY);
 
-	/* the security descriptor is optional */
-	if (r->in.secdesc != NULL) {
-		DATA_BLOB sdblob;
-		enum ndr_err_code ndr_err;
-		sdblob.data = r->in.secdesc->sd.data;
-		sdblob.length = r->in.secdesc->sd.len;
-		if (sdblob.data == NULL) {
-			return WERR_INVALID_PARAM;
+	switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+	{
+	case SECURITY_SYSTEM:
+	case SECURITY_ADMINISTRATOR:
+		/* the security descriptor is optional */
+		if (r->in.secdesc != NULL) {
+			DATA_BLOB sdblob;
+			enum ndr_err_code ndr_err;
+			sdblob.data = r->in.secdesc->sd.data;
+			sdblob.length = r->in.secdesc->sd.len;
+			if (sdblob.data == NULL) {
+				return WERR_INVALID_PARAM;
+			}
+			ndr_err = ndr_pull_struct_blob_all(&sdblob, mem_ctx, NULL, &sd,
+							   (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
+			if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+				return WERR_INVALID_PARAM;
+			}
 		}
-		ndr_err = ndr_pull_struct_blob_all(&sdblob, mem_ctx, NULL, &sd,
-						   (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
-		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-			return WERR_INVALID_PARAM;
+		
+		error = reg_key_add_name(newh, (struct registry_key *)h->data,
+					 r->in.name.name, NULL, r->in.secdesc?&sd:NULL,
+					 (struct registry_key **)&newh->data);
+		if (W_ERROR_IS_OK(error)) {
+			r->out.new_handle = &newh->wire_handle;
+		} else {
+			talloc_free(newh);
 		}
+		
+		return error;
+	default:
+		return WERR_ACCESS_DENIED;
 	}
-
-	error = reg_key_add_name(newh, (struct registry_key *)h->data,
-				 r->in.name.name, NULL, r->in.secdesc?&sd:NULL,
-				 (struct registry_key **)&newh->data);
-	if (W_ERROR_IS_OK(error)) {
-		r->out.new_handle = &newh->wire_handle;
-	} else {
-		talloc_free(newh);
-	}
-
-	return error;
 }
 
 
@@ -160,7 +168,14 @@ static WERROR dcesrv_winreg_DeleteKey(struct dcesrv_call_state *dce_call,
 
 	DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
 
-	return reg_key_del((struct registry_key *)h->data, r->in.key.name);
+	switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+	{
+	case SECURITY_SYSTEM:
+	case SECURITY_ADMINISTRATOR:
+		return reg_key_del((struct registry_key *)h->data, r->in.key.name);
+	default:
+		return WERR_ACCESS_DENIED;
+	}
 }
 
 
@@ -176,9 +191,16 @@ static WERROR dcesrv_winreg_DeleteValue(struct dcesrv_call_state *dce_call,
 
 	DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
 
-	key = h->data;
-
-	return reg_del_value(key, r->in.value.name);
+	switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+	{
+	case SECURITY_SYSTEM:
+	case SECURITY_ADMINISTRATOR:
+		key = h->data;
+		
+		return reg_del_value(key, r->in.value.name);
+	default:
+		return WERR_ACCESS_DENIED;
+	}
 }
 
 
@@ -289,7 +311,14 @@ static WERROR dcesrv_winreg_FlushKey(struct dcesrv_call_state *dce_call,
 
 	DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
 
-	return reg_key_flush(h->data);
+	switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+	{
+	case SECURITY_SYSTEM:
+	case SECURITY_ADMINISTRATOR:
+		return reg_key_flush(h->data);
+	default:
+		return WERR_ACCESS_DENIED;
+	}
 }
 
 
@@ -342,23 +371,31 @@ static WERROR dcesrv_winreg_OpenKey(struct dcesrv_call_state *dce_call,
 
 	DCESRV_PULL_HANDLE_FAULT(h, r->in.parent_handle, HTYPE_REGKEY);
 
-	if (r->in.keyname.name && strcmp(r->in.keyname.name, "") == 0) {
-		newh = talloc_reference(dce_call->context, h);
-		result = WERR_OK;
-	} else {
-		newh = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY);
-		result = reg_open_key(newh, (struct registry_key *)h->data,
-				      r->in.keyname.name,
-				      (struct registry_key **)&newh->data);
-	}
-
-	if (W_ERROR_IS_OK(result)) {
-		r->out.handle = &newh->wire_handle;
-	} else {
-		talloc_free(newh);
+	switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+	{
+	case SECURITY_SYSTEM:
+	case SECURITY_ADMINISTRATOR:
+	case SECURITY_USER:
+		if (r->in.keyname.name && strcmp(r->in.keyname.name, "") == 0) {
+			newh = talloc_reference(dce_call->context, h);
+			result = WERR_OK;
+		} else {
+			newh = dcesrv_handle_new(dce_call->context, HTYPE_REGKEY);
+			result = reg_open_key(newh, (struct registry_key *)h->data,
+					      r->in.keyname.name,
+					      (struct registry_key **)&newh->data);
+		}
+		
+		if (W_ERROR_IS_OK(result)) {
+			r->out.handle = &newh->wire_handle;
+		} else {
+			talloc_free(newh);
+		}
+		return result;
+	default:
+		return WERR_ACCESS_DENIED;
 	}
 
-	return result;
 }
 
 
@@ -376,17 +413,25 @@ static WERROR dcesrv_winreg_QueryInfoKey(struct dcesrv_call_state *dce_call,
 
 	DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
 
-	k = h->data;
-
-	ret = reg_key_get_info(mem_ctx, k, &classname, r->out.num_subkeys,
-			       r->out.num_values, r->out.last_changed_time,
-			       r->out.max_subkeylen, r->out.max_valnamelen, 
-			       r->out.max_valbufsize);
-
-	if (r->out.classname != NULL)
-		r->out.classname->name = classname;
-
-	return ret;
+	switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+	{
+	case SECURITY_SYSTEM:
+	case SECURITY_ADMINISTRATOR:
+	case SECURITY_USER:
+		k = h->data;
+		
+		ret = reg_key_get_info(mem_ctx, k, &classname, r->out.num_subkeys,
+				       r->out.num_values, r->out.last_changed_time,
+				       r->out.max_subkeylen, r->out.max_valnamelen, 
+				       r->out.max_valbufsize);
+		
+		if (r->out.classname != NULL)
+			r->out.classname->name = classname;
+		
+		return ret;
+	default:
+		return WERR_ACCESS_DENIED;
+	}
 }
 
 
@@ -405,35 +450,43 @@ static WERROR dcesrv_winreg_QueryValue(struct dcesrv_call_state *dce_call,
 
 	DCESRV_PULL_HANDLE_FAULT(h, r->in.handle, HTYPE_REGKEY);
 
-	key = h->data;
-
-	result = reg_key_get_value_by_name(mem_ctx, key, r->in.value_name.name,
-					   &value_type, &value_data);
-
-	if (!W_ERROR_IS_OK(result)) {
-		return result;
-	}
-
-	/* Just asking for the size of the buffer */
-	r->out.type = talloc(mem_ctx, uint32_t);
-	if (!r->out.type) {
-		return WERR_NOMEM;
-	}
-	*r->out.type = value_type;
-	r->out.length = talloc(mem_ctx, uint32_t);
-	if (!r->out.length) {
-		return WERR_NOMEM;
-	}
-	*r->out.length = value_data.length;
-	if (r->in.data == NULL) {
-		r->out.size = talloc(mem_ctx, uint32_t);
-		*r->out.size = value_data.length;
-	} else {
-		r->out.size = r->in.size;
-		r->out.data = value_data.data;
+	switch (security_session_user_level(dce_call->conn->auth_state.session_info))
+	{
+	case SECURITY_SYSTEM:
+	case SECURITY_ADMINISTRATOR:
+	case SECURITY_USER:
+		key = h->data;
+		
+		result = reg_key_get_value_by_name(mem_ctx, key, r->in.value_name.name,
+						   &value_type, &value_data);


-- 
Samba Shared Repository


More information about the samba-cvs mailing list