s3: Fix some DEBUG messages
[ira/wip.git] / source3 / rpc_server / srv_lsa_hnd.c
index e1582840c38e4379f12f796ad806d600f35011ba..4348fb8d4a7b115b15af60ec40a919120c90b887 100644 (file)
 #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
+#define MAX_OPEN_POLS 2048
 #endif
 
 /****************************************************************************
@@ -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.
@@ -81,8 +109,9 @@ bool init_pipe_handle_list(pipes_struct *p, const struct ndr_syntax_id *syntax)
                }
                ZERO_STRUCTP(hl);
 
-               DEBUG(10,("init_pipe_handles: created handle list for "
-                         "pipe %s\n", get_pipe_name_from_iface(syntax)));
+               DEBUG(10,("init_pipe_handle_list: created handle list for "
+                         "pipe %s\n",
+                         get_pipe_name_from_syntax(talloc_tos(), syntax)));
        }
 
        /*
@@ -97,9 +126,9 @@ bool init_pipe_handle_list(pipes_struct *p, const struct ndr_syntax_id *syntax)
 
        p->pipe_handles = hl;
 
-       DEBUG(10,("init_pipe_handles: pipe_handles ref count = %lu for pipe %s\n",
-                 (unsigned long)p->pipe_handles->pipe_ref_count,
-                 get_pipe_name_from_iface(syntax)));
+       DEBUG(10,("init_pipe_handle_list: pipe_handles ref count = %lu for "
+                 "pipe %s\n", (unsigned long)p->pipe_handles->pipe_ref_count,
+                 get_pipe_name_from_syntax(talloc_tos(), syntax)));
 
        return True;
 }
@@ -112,7 +141,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 +154,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 +191,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;
 }
 
 /****************************************************************************
@@ -249,7 +286,8 @@ void close_policy_by_pipe(pipes_struct *p)
 
                SAFE_FREE(p->pipe_handles);
                DEBUG(10,("close_policy_by_pipe: deleted handle list for "
-                         "pipe %s\n", get_pipe_name_from_iface(&p->syntax)));
+                         "pipe %s\n",
+                         get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
        }
 }
 
@@ -281,47 +319,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;
+                         get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
+               *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);
+       talloc_set_name_const(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;
 }