[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha7-1093-g46317ce

Volker Lendecke vlendec at samba.org
Sun Apr 19 09:46:03 GMT 2009


The branch, master has been updated
       via  46317ce214dd0f23222db48984a6b3c585085d89 (commit)
       via  bf196df52ff62154ecbcdf7800c7c8b058e325bc (commit)
       via  386511b8e12672ec68f09838ddf6e36b7fddae04 (commit)
       via  35e6a0e618db99287d12092cd8048276ffdb2356 (commit)
       via  9b3f2e69f772a12c661879109e0edcda6c365be4 (commit)
      from  fa4ff87acdfc2fa064eb7fb9d45eef0969128994 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 46317ce214dd0f23222db48984a6b3c585085d89
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Apr 18 22:23:02 2009 +0200

    Remove flag "builtin_domain" from disp_info

commit bf196df52ff62154ecbcdf7800c7c8b058e325bc
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Apr 18 16:58:24 2009 +0200

    Remove flag "builtin_domain" from samr_info

commit 386511b8e12672ec68f09838ddf6e36b7fddae04
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Apr 18 16:54:13 2009 +0200

    Make get_samr_info_by_sid use recent coding conventions

commit 35e6a0e618db99287d12092cd8048276ffdb2356
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Apr 18 16:46:53 2009 +0200

    Add "uint32_t access_granted" to policy handles
    
    All policy handles have a mask of allowed operations attached that were
    calculated at creation time, so they should carry this mask. This is the basis
    for consolidating all our policy handle access checks.
    
    If you want to do your own more complicated access checks further down, just
    pass "0" to policy_handle_find.

commit 9b3f2e69f772a12c661879109e0edcda6c365be4
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Apr 18 16:10:57 2009 +0200

    Make "struct policy" private to srv_lsa_hnd.c

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

Summary of changes:
 source3/include/ntdomain.h          |   18 +------
 source3/include/proto.h             |   20 +++++---
 source3/rpc_server/srv_lsa_hnd.c    |   99 +++++++++++++++++++++++++++++-----
 source3/rpc_server/srv_samr_nt.c    |  100 ++++++++++++++---------------------
 source3/rpc_server/srv_spoolss_nt.c |    3 +-
 source3/smbd/conn.c                 |    2 +-
 6 files changed, 141 insertions(+), 101 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h
index c95931b..de53aeb 100644
--- a/source3/include/ntdomain.h
+++ b/source3/include/ntdomain.h
@@ -110,23 +110,7 @@ typedef struct _input_data {
 	prs_struct data;
 } input_data;
 
-/*
- * Handle database - stored per pipe.
- */
-
-struct policy {
-	struct policy *next, *prev;
-
-	struct policy_handle pol_hnd;
-
-	void *data_ptr;
-};
-
-struct handle_list {
-	struct policy *Policy; 	/* List of policies. */
-	size_t count;			/* Current number of handles. */
-	size_t pipe_ref_count;	/* Number of pipe handles referring to this list. */
-};
+struct handle_list;
 
 /* Domain controller authentication protocol info */
 struct dcinfo {
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 8eb5c46..fa60e6d 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -5875,6 +5875,7 @@ NTSTATUS evlog_convert_tdb_to_evt(TALLOC_CTX *mem_ctx,
 
 /* The following definitions come from rpc_server/srv_lsa_hnd.c  */
 
+size_t num_pipe_handles(struct handle_list *list);
 bool init_pipe_handle_list(pipes_struct *p,
 			   const struct ndr_syntax_id *syntax);
 bool create_policy_hnd(pipes_struct *p, struct policy_handle *hnd, void *data_ptr);
@@ -5884,16 +5885,21 @@ bool close_policy_hnd(pipes_struct *p, struct policy_handle *hnd);
 void close_policy_by_pipe(pipes_struct *p);
 bool pipe_access_check(pipes_struct *p);
 
-NTSTATUS _policy_handle_create(struct pipes_struct *p, struct policy_handle *hnd,
-			       void *pdata, size_t size, const char *name);
-#define policy_handle_create(_p, _hnd, _ptr, _type) \
-	_policy_handle_create((_p), (_hnd), (_ptr), sizeof(_type), #_type)
+void *_policy_handle_create(struct pipes_struct *p, struct policy_handle *hnd,
+			    uint32_t access_granted, size_t data_size,
+			    const char *type, NTSTATUS *pstatus);
+#define policy_handle_create(_p, _hnd, _access, _type, _pstatus) \
+	(_type *)_policy_handle_create((_p), (_hnd), (_access), sizeof(_type), #_type, \
+				       (_pstatus))
 
 void *_policy_handle_find(struct pipes_struct *p,
 			  const struct policy_handle *hnd,
-			  const char *type);
-#define policy_handle_find(_p, _hnd, _type) \
-	(_type *)_policy_handle_find((_p), (_hnd), #_type)
+			  uint32_t access_required, uint32_t *paccess_granted,
+			  const char *name, const char *location,
+			  NTSTATUS *pstatus);
+#define policy_handle_find(_p, _hnd, _access_required, _access_granted, _type, _pstatus) \
+	(_type *)_policy_handle_find((_p), (_hnd), (_access_required), \
+				     (_access_granted), #_type, __location__, (_pstatus))
 
 
 /* The following definitions come from rpc_server/srv_pipe.c  */
diff --git a/source3/rpc_server/srv_lsa_hnd.c b/source3/rpc_server/srv_lsa_hnd.c
index e158284..2490ca3 100644
--- a/source3/rpc_server/srv_lsa_hnd.c
+++ b/source3/rpc_server/srv_lsa_hnd.c
@@ -24,6 +24,26 @@
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_SRV
 
+/*
+ * Handle database - stored per pipe.
+ */
+
+struct policy {
+	struct policy *next, *prev;
+
+	struct policy_handle pol_hnd;
+
+	uint32_t access_granted;
+
+	void *data_ptr;
+};
+
+struct handle_list {
+	struct policy *Policy; 	/* List of policies. */
+	size_t count;			/* Current number of handles. */
+	size_t pipe_ref_count;	/* Number of pipe handles referring to this list. */
+};
+
 /* This is the max handles across all instances of a pipe name. */
 #ifndef MAX_OPEN_POLS
 #define MAX_OPEN_POLS 1024
@@ -40,6 +60,14 @@ static bool is_samr_lsa_pipe(const struct ndr_syntax_id *syntax)
 		|| ndr_syntax_id_equal(syntax, &ndr_table_lsarpc.syntax_id));
 }
 
+size_t num_pipe_handles(struct handle_list *list)
+{
+	if (list == NULL) {
+		return 0;
+	}
+	return list->count;
+}
+
 /****************************************************************************
  Initialise a policy handle list on a pipe. Handle list is shared between all
  pipes of the same name.
@@ -112,7 +140,9 @@ bool init_pipe_handle_list(pipes_struct *p, const struct ndr_syntax_id *syntax)
   data_ptr is TALLOC_FREE()'ed
 ****************************************************************************/
 
-bool create_policy_hnd(pipes_struct *p, struct policy_handle *hnd, void *data_ptr)
+static struct policy *create_policy_hnd_internal(pipes_struct *p,
+						 struct policy_handle *hnd,
+						 void *data_ptr)
 {
 	static uint32 pol_hnd_low  = 0;
 	static uint32 pol_hnd_high = 0;
@@ -123,13 +153,13 @@ bool create_policy_hnd(pipes_struct *p, struct policy_handle *hnd, void *data_pt
 	if (p->pipe_handles->count > MAX_OPEN_POLS) {
 		DEBUG(0,("create_policy_hnd: ERROR: too many handles (%d) on this pipe.\n",
 				(int)p->pipe_handles->count));
-		return False;
+		return NULL;
 	}
 
 	pol = TALLOC_ZERO_P(NULL, struct policy);
 	if (!pol) {
 		DEBUG(0,("create_policy_hnd: ERROR: out of memory!\n"));
-		return False;
+		return NULL;
 	}
 
 	if (data_ptr != NULL) {
@@ -160,7 +190,13 @@ bool create_policy_hnd(pipes_struct *p, struct policy_handle *hnd, void *data_pt
 	DEBUG(4,("Opened policy hnd[%d] ", (int)p->pipe_handles->count));
 	dump_data(4, (uint8 *)hnd, sizeof(*hnd));
 
-	return True;
+	return pol;
+}
+
+bool create_policy_hnd(pipes_struct *p, struct policy_handle *hnd,
+		       void *data_ptr)
+{
+	return create_policy_hnd_internal(p, hnd, data_ptr) != NULL;
 }
 
 /****************************************************************************
@@ -281,47 +317,80 @@ bool pipe_access_check(pipes_struct *p)
 	return True;
 }
 
-NTSTATUS _policy_handle_create(struct pipes_struct *p, struct policy_handle *hnd,
-			       void *pdata, size_t data_size, const char *type)
+void *_policy_handle_create(struct pipes_struct *p, struct policy_handle *hnd,
+			    uint32_t access_granted, size_t data_size,
+			    const char *type, NTSTATUS *pstatus)
 {
-	void **ppdata = (void **)pdata;
+	struct policy *pol;
 	void *data;
 
 	if (p->pipe_handles->count > MAX_OPEN_POLS) {
 		DEBUG(0, ("policy_handle_create: ERROR: too many handles (%d) "
 			  "on pipe %s.\n", (int)p->pipe_handles->count,
 			  get_pipe_name_from_iface(&p->syntax)));
-		return NT_STATUS_INSUFFICIENT_RESOURCES;
+		*pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
+		return NULL;
 	}
 
 	data = talloc_size(talloc_tos(), data_size);
 	if (data == NULL) {
-		return NT_STATUS_NO_MEMORY;
+		*pstatus = NT_STATUS_NO_MEMORY;
+		return NULL;
 	}
 	talloc_set_name(data, type);
 
-	if (!create_policy_hnd(p, hnd, data)) {
+	pol = create_policy_hnd_internal(p, hnd, data);
+	if (pol == NULL) {
 		TALLOC_FREE(data);
-		return NT_STATUS_NO_MEMORY;
+		*pstatus = NT_STATUS_NO_MEMORY;
+		return NULL;
 	}
-	*ppdata = data;
-	return NT_STATUS_OK;
+	pol->access_granted = access_granted;
+	*pstatus = NT_STATUS_OK;
+	return data;
 }
 
 void *_policy_handle_find(struct pipes_struct *p,
 			  const struct policy_handle *hnd,
-			  const char *name)
+			  uint32_t access_required,
+			  uint32_t *paccess_granted,
+			  const char *name, const char *location,
+			  NTSTATUS *pstatus)
 {
+	struct policy *pol;
 	void *data;
 
-	if (find_policy_by_hnd_internal(p, hnd, &data) == NULL) {
+	pol = find_policy_by_hnd_internal(p, hnd, &data);
+	if (pol == NULL) {
+		*pstatus = NT_STATUS_INVALID_HANDLE;
 		return NULL;
 	}
 	if (strcmp(name, talloc_get_name(data)) != 0) {
 		DEBUG(10, ("expected %s, got %s\n", name,
 			   talloc_get_name(data)));
+		*pstatus = NT_STATUS_INVALID_HANDLE;
 		return NULL;
 	}
+	if ((access_required & pol->access_granted) != access_required) {
+		if (geteuid() == sec_initial_uid()) {
+			DEBUG(4, ("%s: ACCESS should be DENIED (granted: "
+				  "%#010x; required: %#010x)\n", location,
+				  pol->access_granted, access_required));
+			DEBUGADD(4,("but overwritten by euid == 0\n"));
+			goto okay;
+		}
+		DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: "
+			 "%#010x)\n", location, pol->access_granted,
+			 access_required));
+		*pstatus = NT_STATUS_ACCESS_DENIED;
+		return NULL;
+	}
+
+ okay:
 	DEBUG(10, ("found handle of type %s\n", talloc_get_name(data)));
+	if (paccess_granted != NULL) {
+		*paccess_granted = pol->access_granted;
+	}
+	*pstatus = NT_STATUS_OK;
 	return data;
 }
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index 159760c..329c709 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -49,12 +49,11 @@
 #define MAX_SAM_ENTRIES_W95 50
 
 struct samr_connect_info {
-	uint32_t acc_granted;
+	uint8_t dummy;
 };
 
 typedef struct disp_info {
 	DOM_SID sid; /* identify which domain this is. */
-	bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
 	struct pdb_search *users; /* querydispinfo 1 and 4 */
 	struct pdb_search *machines; /* querydispinfo 2 */
 	struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
@@ -73,7 +72,6 @@ typedef struct disp_info {
 struct samr_info {
 	/* for use by the \PIPE\samr policy */
 	DOM_SID sid;
-	bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
 	uint32 status; /* some sort of flag.  best to record it.  comes from opnum 0x39 */
 	uint32 acc_granted;
 	DISP_INFO *disp_info;
@@ -347,7 +345,6 @@ static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
 			}
 		}
 		sid_copy(&builtin_dispinfo->sid, &global_sid_Builtin);
-		builtin_dispinfo->builtin_domain = true;
 
 		return builtin_dispinfo;
 	}
@@ -364,7 +361,6 @@ static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
 			}
 		}
 		sid_copy(&domain_dispinfo->sid, get_global_sam_sid());
-		domain_dispinfo->builtin_domain = false;
 
 		return domain_dispinfo;
 	}
@@ -382,26 +378,20 @@ static struct samr_info *get_samr_info_by_sid(TALLOC_CTX *mem_ctx,
 					      DOM_SID *psid)
 {
 	struct samr_info *info;
-	fstring sid_str;
-
-	if (psid) {
-		sid_to_fstring(sid_str, psid);
-	} else {
-		fstrcpy(sid_str,"(NULL)");
-	}
 
-	if ((info = TALLOC_ZERO_P(mem_ctx, struct samr_info)) == NULL) {
+	info = talloc_zero(mem_ctx, struct samr_info);
+	if (info == NULL) {
 		return NULL;
 	}
 	talloc_set_destructor(info, samr_info_destructor);
 
-	DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
+	DEBUG(10, ("get_samr_info_by_sid: created new info for sid %s\n",
+		   sid_string_dbg(psid)));
+
 	if (psid) {
 		sid_copy( &info->sid, psid);
-		info->builtin_domain = sid_check_is_builtin(psid);
 	} else {
 		DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
-		info->builtin_domain = False;
 	}
 
 	info->disp_info = get_samr_dispinfo_by_sid(psid);
@@ -517,7 +507,7 @@ static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
 {
 	struct samr_displayentry *entry;
 
-	if (info->builtin_domain) {
+	if (sid_check_is_builtin(&info->sid)) {
 		/* No users in builtin. */
 		return 0;
 	}
@@ -541,7 +531,7 @@ static uint32 count_sam_groups(struct disp_info *info)
 {
 	struct samr_displayentry *entry;
 
-	if (info->builtin_domain) {
+	if (sid_check_is_builtin(&info->sid)) {
 		/* No groups in builtin. */
 		return 0;
 	}
@@ -613,10 +603,10 @@ NTSTATUS _samr_OpenDomain(pipes_struct *p,
 
 	/* find the connection policy handle. */
 
-	cinfo = policy_handle_find(p, r->in.connect_handle,
-				   struct samr_connect_info);
-	if (cinfo == NULL) {
-		return NT_STATUS_INVALID_HANDLE;
+	cinfo = policy_handle_find(p, r->in.connect_handle, 0, NULL,
+				   struct samr_connect_info, &status);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
 	}
 
 	/*check if access can be granted as requested by client. */
@@ -989,7 +979,7 @@ NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
 
 	DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
 
-	if (info->builtin_domain) {
+	if (sid_check_is_builtin(&info->sid)) {
 		/* No users in builtin. */
 		*r->out.resume_handle = *r->in.resume_handle;
 		DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
@@ -1128,7 +1118,7 @@ NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
 
 	DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
 
-	if (info->builtin_domain) {
+	if (sid_check_is_builtin(&info->sid)) {
 		/* No groups in builtin. */
 		*r->out.resume_handle = *r->in.resume_handle;
 		DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
@@ -1471,7 +1461,7 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
 	if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
 		return NT_STATUS_INVALID_HANDLE;
 
-	if (info->builtin_domain) {
+	if (sid_check_is_builtin(&info->sid)) {
 		DEBUG(5,("_samr_QueryDisplayInfo: Nothing in BUILTIN\n"));
 		return NT_STATUS_OK;
 	}
@@ -3043,14 +3033,13 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p,
 	uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
 	bool can_add_account = False;
 	SE_PRIV se_rights;
-	DISP_INFO *disp_info = NULL;
 
 	/* Get the domain SID stored in the domain policy */
-	if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted,
-				     &disp_info))
+	if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid,
+				     &acc_granted, NULL))
 		return NT_STATUS_INVALID_HANDLE;
 
-	if (disp_info->builtin_domain) {
+	if (sid_check_is_builtin(&sid)) {
 		DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
 		return NT_STATUS_ACCESS_DENIED;
 	}
@@ -3198,6 +3187,7 @@ NTSTATUS _samr_Connect(pipes_struct *p,
 		       struct samr_Connect *r)
 {
 	struct samr_connect_info *info;
+	uint32_t acc_granted;
 	struct policy_handle hnd;
 	uint32    des_access = r->in.access_mask;
 	NTSTATUS status;
@@ -3209,14 +3199,6 @@ NTSTATUS _samr_Connect(pipes_struct *p,
 		return NT_STATUS_ACCESS_DENIED;
 	}
 
-	/* set up the SAMR connect_anon response */
-
-	status = policy_handle_create(p, &hnd, &info,
-				      struct samr_connect_info);
-	if (!NT_STATUS_IS_OK(status)) {
-		return status;
-	}
-
 	/* don't give away the farm but this is probably ok.  The SAMR_ACCESS_ENUM_DOMAINS
 	   was observed from a win98 client trying to enumerate users (when configured
 	   user level access control on shares)   --jerry */
@@ -3224,7 +3206,18 @@ NTSTATUS _samr_Connect(pipes_struct *p,
 	map_max_allowed_access(p->server_info->ptok, &des_access);
 
 	se_map_generic( &des_access, &sam_generic_mapping );
-	info->acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS|SAMR_ACCESS_LOOKUP_DOMAIN);
+
+	acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
+				    |SAMR_ACCESS_LOOKUP_DOMAIN);
+
+	/* set up the SAMR connect_anon response */
+
+	info = policy_handle_create(p, &hnd, acc_granted,
+				    struct samr_connect_info,
+				    &status);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
 
 	*r->out.connect_handle = hnd;
 	return NT_STATUS_OK;
@@ -3281,14 +3274,12 @@ NTSTATUS _samr_Connect2(pipes_struct *p,
 	if ( !NT_STATUS_IS_OK(nt_status) )
 		return nt_status;
 
-	nt_status = policy_handle_create(p, &hnd, &info,
-					 struct samr_connect_info);
+	info = policy_handle_create(p, &hnd, acc_granted,
+				    struct samr_connect_info, &nt_status);
         if (!NT_STATUS_IS_OK(nt_status)) {
                 return nt_status;
         }
 
-	info->acc_granted = acc_granted;
-
 	DEBUG(5,("%s: %d\n", fn, __LINE__));
 
 	*r->out.connect_handle = hnd;
@@ -3363,23 +3354,18 @@ NTSTATUS _samr_Connect5(pipes_struct *p,
 NTSTATUS _samr_LookupDomain(pipes_struct *p,
 			    struct samr_LookupDomain *r)
 {
-	NTSTATUS status = NT_STATUS_OK;
+	NTSTATUS status;
 	struct samr_connect_info *info;
 	const char *domain_name;
 	DOM_SID *sid = NULL;
 
-	info = policy_handle_find(p, r->in.connect_handle,
-				  struct samr_connect_info);
-	if (info == NULL) {
-		return NT_STATUS_INVALID_HANDLE;
-	}
-
 	/* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
 	   Reverted that change so we will work with RAS servers again */
 
-	status = access_check_samr_function(info->acc_granted,
-					    SAMR_ACCESS_LOOKUP_DOMAIN,
-					    "_samr_LookupDomain");
+	info = policy_handle_find(p, r->in.connect_handle,
+				  SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
+				  struct samr_connect_info,
+				  &status);
 	if (!NT_STATUS_IS_OK(status)) {
 		return status;
 	}
@@ -3424,14 +3410,8 @@ NTSTATUS _samr_EnumDomains(pipes_struct *p,
 	struct samr_SamArray *sam;
 
 	info = policy_handle_find(p, r->in.connect_handle,
-				  struct samr_connect_info);
-	if (info == NULL) {
-		return NT_STATUS_INVALID_HANDLE;
-	}
-


-- 
Samba Shared Repository


More information about the samba-cvs mailing list