Potential fixes for rpc_server/srv_srvsvc_nt.c

Richard Sharpe realrichardsharpe at gmail.com
Thu May 17 17:40:06 MDT 2012


I think this is a more correct set of fixes ... against 3.5.15

--- samba-3.5.15/source3/rpc_server/srv_srvsvc_nt.c     2012-04-27
12:10:36.000000000 -0700
+++ srv_srvsvc_nt.c     2012-05-17 16:11:50.576678329 -0700
@@ -500,7 +500,7 @@ static bool is_enumeration_allowed(pipes
         return true;

     return share_access_check(p->server_info->ptok, lp_servicename(snum),
-                              FILE_READ_DATA);
+                              FILE_READ_DATA, NULL);
 }

 /*******************************************************************
@@ -904,12 +904,89 @@ static WERROR init_srv_sess_info_1(pipes
  fill in a conn info level 0 structure.
  ********************************************************************/

-static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
+struct share_conn_count {
+       char *sharename;
+       unsigned int count;
+       unsigned int level;
+       struct srvsvc_NetConnCtr0 *ctr0;
+       struct srvsvc_NetConnCtr1 *ctr1;
+       WERROR err;
+};
+
+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;
+
+       if (!process_exists(crec->pid))
+               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) {
+               switch (share_wanted->level) {
+               case 0:
+                       share_wanted->ctr0->array =
TALLOC_REALLOC_ARRAY(talloc_tos(),
+                                                  share_wanted->ctr0->array,
+                                                  struct srvsvc_NetConnInfo0,
+                                                  share_wanted->count+1);
+                       if (!share_wanted->ctr0->array) {
+                               share_wanted->err = WERR_NOMEM;
+                               return 1;
+                       }
+
+
share_wanted->ctr0->array[share_wanted->count].conn_id =
share_wanted->count+1;
+                       break;
+               case 1:
+                       share_wanted->ctr1->array =
TALLOC_REALLOC_ARRAY(talloc_tos(),
+                                                  share_wanted->ctr1->array,
+                                                  struct srvsvc_NetConnInfo1,
+                                                  share_wanted->count+1);
+                       if (!share_wanted->ctr1->array) {
+                               share_wanted->err = WERR_NOMEM;
+                               return 1;
+                       }
+
+
share_wanted->ctr1->array[share_wanted->count].conn_id =
share_wanted->count+1;
+
share_wanted->ctr1->array[share_wanted->count].conn_type = 0x3;
+
share_wanted->ctr1->array[share_wanted->count].num_open = 1;
+
share_wanted->ctr1->array[share_wanted->count].num_users = 1;
+
share_wanted->ctr1->array[share_wanted->count].conn_time = 3;
+
share_wanted->ctr1->array[share_wanted->count].user = "dummy_user";
+
share_wanted->ctr1->array[share_wanted->count].share =
share_wanted->sharename;
+
+                       break;
+               default:
+
+                       break;
+               }
+
+               share_wanted->count++;
+       }
+
+       return 0;
+}
+
+static WERROR init_srv_conn_info_0(const char *path,
+                                  struct srvsvc_NetConnCtr0 *ctr0,
                                   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;
+
+       share_count.sharename = path;
+       share_count.err = WERR_OK;
+       share_count.level = 0;
+       share_count.count = 0;
+       share_count.ctr0 = ctr0;

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

@@ -920,28 +997,12 @@ static WERROR init_srv_conn_info_0(struc
                return WERR_OK;
        }

-       *total_entries = 1;
-
-       ZERO_STRUCTP(ctr0);
-
-       for (; resume_handle < *total_entries; resume_handle++) {
-
-               ctr0->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
-                                                  ctr0->array,
-                                                  struct srvsvc_NetConnInfo0,
-                                                  num_entries+1);
-               if (!ctr0->array) {
-                       return WERR_NOMEM;
-               }
+       connections_forall(traverse_count_shares_fn, &share_count);
+       if (!W_ERROR_EQUAL(share_count.err, WERR_OK))
+               return share_count.err;

-               ctr0->array[num_entries].conn_id = *total_entries;
-
-               /* move on to creating next connection */
-               num_entries++;
-       }
-
-       ctr0->count = num_entries;
-       *total_entries = num_entries;
+       ctr0->count = share_count.count;
+       *total_entries = share_count.count;

        if (resume_handle_p) {
                if (*resume_handle_p >= *total_entries) {
@@ -958,12 +1019,14 @@ static WERROR init_srv_conn_info_0(struc
  fill in a conn info level 1 structure.
  ********************************************************************/

-static WERROR init_srv_conn_info_1(struct srvsvc_NetConnCtr1 *ctr1,
+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,34 +1037,23 @@ static WERROR init_srv_conn_info_1(struc
                return WERR_OK;
        }

-       *total_entries = 1;

        ZERO_STRUCTP(ctr1);

-       for (; resume_handle < *total_entries; resume_handle++) {
-
-               ctr1->array = TALLOC_REALLOC_ARRAY(talloc_tos(),
-                                                  ctr1->array,
-                                                  struct srvsvc_NetConnInfo1,
-                                                  num_entries+1);
-               if (!ctr1->array) {
-                       return WERR_NOMEM;
-               }
+       share_count.err = WERR_OK;
+       share_count.count = 0;
+       share_count.level = 1;
+       share_count.sharename = path;
+       share_count.ctr1 = ctr1;
+
+       DEBUG(10, ("Looking up count of connections for %s\n",
+               share_count.sharename));
+       connections_forall(traverse_count_shares_fn, &share_count);
+       if (!W_ERROR_EQUAL(share_count.err, WERR_OK))
+               return share_count.err;

-               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].conn_time      = 3;
-               ctr1->array[num_entries].user           = "dummy_user";
-               ctr1->array[num_entries].share          = "IPC$";
-
-               /* move on to creating next connection */
-               num_entries++;
-       }
-
-       ctr1->count = num_entries;
-       *total_entries = num_entries;
+       ctr1->count = share_count.count;
+       *total_entries = share_count.count;

        if (resume_handle_p) {
                if (*resume_handle_p >= *total_entries) {
@@ -1201,12 +1253,14 @@ WERROR _srvsvc_NetConnEnum(pipes_struct

        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;


More information about the samba-technical mailing list