Potential fixes for rpc_server/srv_srvsvc_nt.c

Richard Sharpe realrichardsharpe at gmail.com
Thu May 17 11:20:47 MDT 2012


On Thu, May 17, 2012 at 9:53 AM, Richard Sharpe
<realrichardsharpe at gmail.com> wrote:
> Hi,
>
> While that code has moved around a bit in master, it is the same code.
> Here is a fix that is better than the current code, but it still needs
> work. I need to figure out how to obtain the total number of users
> connected.
>
> --- rpc_server/srv_srvsvc_nt.c.orig     2012-05-16 19:23:02.696062901 -0700
> +++ rpc_server/srv_srvsvc_nt.c  2012-05-17 09:49:31.886078938 -0700
> @@ -904,7 +904,8 @@
>  fill in a conn info level 0 structure.
>  ********************************************************************/
>
> -static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
> +static WERROR init_srv_conn_info_0(const char *path,
> +                                  struct srvsvc_NetConnCtr0 *ctr0,
>                                   uint32_t *resume_handle_p,
>                                   uint32_t *total_entries)
>  {
> @@ -958,12 +959,38 @@
>  fill in a conn info level 1 structure.
>  ********************************************************************/
>
> -static WERROR init_srv_conn_info_1(struct srvsvc_NetConnCtr1 *ctr1,
> +struct share_conn_count {
> +       char *sharename;
> +       unsigned int count;
> +};
> +
> +static int traverse_count_shares_fn(struct db_record *rec,
> +                                   const struct connections_key *key,
> +                                   const struct connections_data *crec,
> +                                   void *state)
> +{
> +       struct share_conn_count *share_wanted = state;
> +
> +       if (crec->cnum == -1)
> +               return 0;
> +
> +       DEBUG(10,("Service in record: %s, service asked for: %s\n",
> +               crec->servicename, share_wanted->sharename));
> +
> +       if (strcmp(crec->servicename, share_wanted->sharename) == 0)
> +               share_wanted->count++;
> +
> +       return 0;
> +}
> +
> +static WERROR init_srv_conn_info_1(const char *path,
> +                                  struct srvsvc_NetConnCtr1 *ctr1,
>                                   uint32_t *resume_handle_p,
>                                   uint32_t *total_entries)
>  {
>        uint32_t num_entries = 0;
>        uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
> +       struct share_conn_count share_count;
>
>        DEBUG(5,("init_srv_conn_info_1\n"));
>
> @@ -980,6 +1007,15 @@
>
>        for (; resume_handle < *total_entries; resume_handle++) {
>
> +               DEBUG(10, ("ctr1->array: %p, %p\n", ctr1,
> +                       ctr1 ? ctr1->array : NULL));
> +               share_count.count = 0;
> +               share_count.sharename = path;
> +
> +               DEBUG(10, ("Looking up count of connections for %s\n",
> +                       share_count.sharename));
> +               connections_forall(traverse_count_shares_fn, &share_count);
> +
>                ctr1->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
>                                                   ctr1->array,
>                                                   struct srvsvc_NetConnInfo1,
> @@ -990,11 +1026,15 @@
>
>                ctr1->array[num_entries].conn_id        = *total_entries;
>                ctr1->array[num_entries].conn_type      = 0x3;
> -               ctr1->array[num_entries].num_open       = 1;
> -               ctr1->array[num_entries].num_users      = 1;
> +               /* The following is still wrong, but more correct than before */
> +               ctr1->array[num_entries].num_open       = share_count.count;
> +               ctr1->array[num_entries].num_users      = share_count.count;
>                ctr1->array[num_entries].conn_time      = 3;
> -               ctr1->array[num_entries].user           = "dummy_user";
> -               ctr1->array[num_entries].share          = "IPC$";
> +               if (strcmp(path, "IPC$") == 0)
> +                       ctr1->array[num_entries].user = "dummy_user";
> +               else
> +                       ctr1->array[num_entries].user = NULL;
> +               ctr1->array[num_entries].share          = path;
>
>                /* move on to creating next connection */
>                num_entries++;
> @@ -1201,12 +1241,14 @@
>
>        switch (r->in.info_ctr->level) {
>                case 0:
> -                       werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
> +                       werr = init_srv_conn_info_0(r->in.path,
> +                                                   r->in.info_ctr->ctr.ctr0,
>                                                    r->in.resume_handle,
>                                                    r->out.totalentries);
>                        break;
>                case 1:
> -                       werr = init_srv_conn_info_1(r->in.info_ctr->ctr.ctr1,
> +                       werr = init_srv_conn_info_1(r->in.path,
> +                                                   r->in.info_ctr->ctr.ctr1,
>                                                    r->in.resume_handle,
>                                                    r->out.totalentries);
>                        break;

Sigh,

That code was wrong. I should only fill in the array if there are connections,
and I am doing it wrong. The following is better, but still not
correct. If there are connections, then the array should show them
all.

--- rpc_server/srv_srvsvc_nt.c.orig     2012-05-16 19:23:02.696062901 -0700
+++ rpc_server/srv_srvsvc_nt.c  2012-05-17 10:17:12.642582543 -0700
@@ -904,7 +904,8 @@
  fill in a conn info level 0 structure.
  ********************************************************************/

-static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
+static WERROR init_srv_conn_info_0(const char *path,
+                                  struct srvsvc_NetConnCtr0 *ctr0,
                                   uint32_t *resume_handle_p,
                                   uint32_t *total_entries)
 {
@@ -958,12 +959,38 @@
  fill in a conn info level 1 structure.
  ********************************************************************/

-static WERROR init_srv_conn_info_1(struct srvsvc_NetConnCtr1 *ctr1,
+struct share_conn_count {
+       char *sharename;
+       unsigned int count;
+};
+
+static int traverse_count_shares_fn(struct db_record *rec,
+                                   const struct connections_key *key,
+                                   const struct connections_data *crec,
+                                   void *state)
+{
+       struct share_conn_count *share_wanted = state;
+
+       if (crec->cnum == -1)
+               return 0;
+
+       DEBUG(10,("Service in record: %s, service asked for: %s\n",
+               crec->servicename, share_wanted->sharename));
+
+       if (strcmp(crec->servicename, share_wanted->sharename) == 0)
+               share_wanted->count++;
+
+       return 0;
+}
+
+static WERROR init_srv_conn_info_1(const char *path,
+                                  struct srvsvc_NetConnCtr1 *ctr1,
                                   uint32_t *resume_handle_p,
                                   uint32_t *total_entries)
 {
        uint32_t num_entries = 0;
        uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
+       struct share_conn_count share_count;

        DEBUG(5,("init_srv_conn_info_1\n"));

@@ -974,12 +1001,22 @@
                return WERR_OK;
        }

-       *total_entries = 1;

        ZERO_STRUCTP(ctr1);

+       share_count.count = 0;
+       share_count.sharename = path;
+
+       DEBUG(10, ("Looking up count of connections for %s\n",
+               share_count.sharename));
+       connections_forall(traverse_count_shares_fn, &share_count);
+
+       *total_entries = share_count.count;
+
        for (; resume_handle < *total_entries; resume_handle++) {

+               DEBUG(10, ("ctr1->array: %p, %p\n", ctr1,
+                       ctr1 ? ctr1->array : NULL));
                ctr1->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
                                                   ctr1->array,
                                                   struct srvsvc_NetConnInfo1,
@@ -990,11 +1027,11 @@

                ctr1->array[num_entries].conn_id        = *total_entries;
                ctr1->array[num_entries].conn_type      = 0x3;
-               ctr1->array[num_entries].num_open       = 1;
-               ctr1->array[num_entries].num_users      = 1;
+               ctr1->array[num_entries].num_open       = share_count.count;
+               ctr1->array[num_entries].num_users      = share_count.count;
                ctr1->array[num_entries].conn_time      = 3;
                ctr1->array[num_entries].user           = "dummy_user";
-               ctr1->array[num_entries].share          = "IPC$";
+               ctr1->array[num_entries].share          = path;

                /* move on to creating next connection */
                num_entries++;
@@ -1201,12 +1238,14 @@

        switch (r->in.info_ctr->level) {
                case 0:
-                       werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
+                       werr = init_srv_conn_info_0(r->in.path,
+                                                   r->in.info_ctr->ctr.ctr0,
                                                    r->in.resume_handle,
                                                    r->out.totalentries);
                        break;
                case 1:
-                       werr = init_srv_conn_info_1(r->in.info_ctr->ctr.ctr1,
+                       werr = init_srv_conn_info_1(r->in.path,
+                                                   r->in.info_ctr->ctr.ctr1,
                                                    r->in.resume_handle,
                                                    r->out.totalentries);
                        break;


-- 
Regards,
Richard Sharpe
(何以解憂?唯有杜康。--曹操)


More information about the samba-technical mailing list