The branch, master has been updated
       via  fc4845f s3: rpc_server/srvsvc: count open files in NetConnEnum
       via  fe6ec8c s3: rpc_server/srvsvc: count share connections in 
NetConnEnum
       via  e685472 s3: rpc_server/srvsvc: added routines to compute opens on 
share connections.
       via  992c86d s3: rpc_server/srvsvc: Added routines to count share 
connections.
      from  375d467 autorid: use the db argument in the initialize traverse 
action.

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


- Log -----------------------------------------------------------------
commit fc4845f481a01e7e12dd9f4de3a8a434234c339c
Author: Shekhar Amlekar <samle...@in.ibm.com>
Date:   Tue Mar 25 17:06:18 2014 +0530

    s3: rpc_server/srvsvc: count open files in NetConnEnum
    
    Signed-off-by: Shekhar Amlekar <samle...@in.ibm.com>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Christof Schmitt <c...@samba.org>
    
    Autobuild-User(master): Jeremy Allison <j...@samba.org>
    Autobuild-Date(master): Thu Apr  3 21:19:43 CEST 2014 on sn-devel-104

commit fe6ec8c111879e4130a6ba4675dccca0ffa2e573
Author: Shekhar Amlekar <samle...@in.ibm.com>
Date:   Tue Mar 25 16:49:44 2014 +0530

    s3: rpc_server/srvsvc: count share connections in NetConnEnum
    
    Signed-off-by: Shekhar Amlekar <samle...@in.ibm.com>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Christof Schmitt <c...@samba.org>

commit e68547204f1be7f70ca5107481a12213d0857ab9
Author: Shekhar Amlekar <samle...@in.ibm.com>
Date:   Tue Mar 25 16:30:49 2014 +0530

    s3: rpc_server/srvsvc: added routines to compute opens on share connections.
    
    Added routines count_share_opens() and share_file_fn() to count
    opens on share connections.
    
    Signed-off-by: Shekhar Amlekar <samle...@in.ibm.com>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Christof Schmitt <c...@samba.org>

commit 992c86d7154b54ba07dd13c060a870735b09c7f9
Author: Shekhar Amlekar <samle...@in.ibm.com>
Date:   Thu Apr 3 14:22:58 2014 +0530

    s3: rpc_server/srvsvc: Added routines to count share connections.
    
    Added routines count_share_conns() and share_conn_fn() to count
    connections to a share.
    
    Signed-off-by: Shekhar Amlekar <samle...@in.ibm.com>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    Reviewed-by: Christof Schmitt <c...@samba.org>

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

Summary of changes:
 source3/rpc_server/srvsvc/srv_srvsvc_nt.c |  225 ++++++++++++++++++++++++++---
 1 files changed, 205 insertions(+), 20 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c 
b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
index 4631691..39d5e05 100644
--- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c
@@ -61,6 +61,21 @@ struct sess_file_info {
        uint32_t num_entries;
 };
 
+struct share_file_stat {
+       struct srvsvc_NetConnInfo1 *netconn_arr;
+       struct server_id *svrid_arr;
+       const char *in_sharepath;
+       uint32_t resp_entries;
+       uint32_t total_entries;
+};
+
+struct share_conn_stat {
+       TALLOC_CTX *ctx;
+       const char *sharename;
+       struct server_id *svrid_arr;
+       int count;
+};
+
 /*******************************************************************
 ********************************************************************/
 
@@ -931,6 +946,104 @@ static WERROR init_srv_sess_info_1(struct pipes_struct *p,
 }
 
 /*******************************************************************
+ find the share connection on which this open exists.
+ ********************************************************************/
+
+static void share_file_fn(const struct share_mode_entry *e,
+                         const char *sharepath, const char *fname,
+                         void *data)
+{
+       struct share_file_stat *sfs = data;
+       uint32_t i;
+       uint32_t offset = sfs->total_entries - sfs->resp_entries;
+
+       if (strequal(sharepath, sfs->in_sharepath)) {
+               for (i=0; i < sfs->resp_entries; i++) {
+                       if (serverid_equal(&e->pid, &sfs->svrid_arr[offset + 
i])) {
+                               sfs->netconn_arr[i].num_open ++;
+                               return;
+                       }
+               }
+       }
+}
+
+/*******************************************************************
+ count number of open files on given share connections.
+ ********************************************************************/
+
+static void count_share_opens(struct srvsvc_NetConnInfo1 *arr,
+                             struct server_id *svrid_arr, char *sharepath,
+                             uint32_t resp_entries, uint32_t total_entries)
+{
+       struct share_file_stat sfs;
+
+       sfs.netconn_arr = arr;
+       sfs.svrid_arr = svrid_arr;
+       sfs.in_sharepath = sharepath;
+       sfs.resp_entries = resp_entries;
+       sfs.total_entries = total_entries;
+
+       share_mode_forall(share_file_fn, &sfs);
+}
+
+/****************************************************************************
+ process an entry from the connection db.
+****************************************************************************/
+
+static int share_conn_fn(struct smbXsrv_tcon_global0 *tcon,
+                         void *data)
+{
+       struct share_conn_stat *scs = data;
+
+       if (!process_exists(tcon->server_id)) {
+               return 0;
+       }
+
+       if (strequal(tcon->share_name, scs->sharename)) {
+               scs->svrid_arr = talloc_realloc(scs->ctx, scs->svrid_arr,
+                                               struct server_id,
+                                               scs->count + 1);
+               if (!scs->svrid_arr) {
+                       return 0;
+               }
+
+               scs->svrid_arr[scs->count] = tcon->server_id;
+               scs->count++;
+       }
+
+       return 0;
+}
+
+/****************************************************************************
+ Count the connections to a share. Build an array of serverid's owning these
+ connections.
+****************************************************************************/
+
+static uint32_t count_share_conns(TALLOC_CTX *ctx, const char *sharename,
+                                 struct server_id **arr)
+{
+       struct share_conn_stat scs;
+       NTSTATUS status;
+
+       scs.ctx = ctx;
+       scs.sharename = sharename;
+       scs.svrid_arr = NULL;
+       scs.count = 0;
+
+       status = smbXsrv_tcon_global_traverse(share_conn_fn, &scs);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0,("count_share_conns: traverse of "
+                        "smbXsrv_tcon_global.tdb failed - %s\n",
+                        nt_errstr(status)));
+               return 0;
+       }
+
+       *arr = scs.svrid_arr;
+       return scs.count;
+}
+
+/*******************************************************************
  fill in a conn info level 0 structure.
  ********************************************************************/
 
@@ -988,12 +1101,15 @@ static WERROR init_srv_conn_info_0(struct 
srvsvc_NetConnCtr0 *ctr0,
  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 *name,
+                                  struct srvsvc_NetConnCtr1 *ctr1,
                                   uint32_t *resume_handle_p,
                                   uint32_t *total_entries)
 {
-       uint32_t num_entries = 0;
+       uint32_t num_entries = 0, snum = 0;
        uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
+       char *share_name = NULL;
+       struct server_id *svrid_arr = NULL;
 
        DEBUG(5,("init_srv_conn_info_1\n"));
 
@@ -1004,41 +1120,109 @@ static WERROR init_srv_conn_info_1(struct 
srvsvc_NetConnCtr1 *ctr1,
                return WERR_OK;
        }
 
-       *total_entries = 1;
+       /* check if this is a server name or a share name */
+       if (name && (strlen(name) > 2)  && (name[0] == '\\') &&
+                       (name[1] == '\\')) {
 
-       ZERO_STRUCTP(ctr1);
-
-       for (; resume_handle < *total_entries; resume_handle++) {
+               /* 'name' is a server name - this part is unimplemented */
+               *total_entries = 1;
+       } else {
+                /* 'name' is a share name */
+               snum = find_service(talloc_tos(), name, &share_name);
 
-               ctr1->array = talloc_realloc(talloc_tos(),
-                                                  ctr1->array,
-                                                  struct srvsvc_NetConnInfo1,
-                                                  num_entries+1);
-               if (!ctr1->array) {
+               if (!share_name) {
                        return WERR_NOMEM;
                }
 
+               if (snum < 0) {
+                       return WERR_INVALID_NAME;
+               }
+
+               /*
+                * count the num of connections to this share. Also,
+                * build a list of serverid's that own these
+                * connections. The serverid list is used later to
+                * identify the share connection on which an open exists.
+                */
+
+               *total_entries = count_share_conns(talloc_tos(),
+                                                  share_name,
+                                                  &svrid_arr);
+       }
+
+       if (resume_handle >= *total_entries) {
+               if (resume_handle_p) {
+                       *resume_handle_p = 0;
+               }
+               return WERR_OK;
+       }
+
+       /*
+        * We know num_entries must be positive, due to
+        * the check resume_handle >= *total_entries above.
+        */
+
+       num_entries = *total_entries - resume_handle;
+
+       ZERO_STRUCTP(ctr1);
+
+       ctr1->array = talloc_zero_array(talloc_tos(),
+                                       struct srvsvc_NetConnInfo1,
+                                       num_entries);
+
+       W_ERROR_HAVE_NO_MEMORY(ctr1->array);
+
+       for (num_entries = 0; resume_handle < *total_entries;
+               num_entries++, resume_handle++) {
+
                ctr1->array[num_entries].conn_id        = *total_entries;
                ctr1->array[num_entries].conn_type      = 0x3;
-               ctr1->array[num_entries].num_open       = 1;
+
+               /*
+                * if these are connections to a share, we are going to
+                * compute the opens on them later. If it's for the server,
+                * it's unimplemented.
+                */
+
+               if (!share_name) {
+                       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$";
+       }
+
+       /* now compute open files on the share connections */
+
+       if (share_name) {
+
+               /*
+                * the locking tdb, which has the open files information,
+                * does not store share name or share (service) number, but
+                * just the share path. So, we can compute open files only
+                * on the share path. If more than one shares are  defined
+                * on a share path, open files on all of them are included
+                * in the count.
+                *
+                * To have the correct behavior in case multiple shares
+                * are defined on the same path, changes to tdb records
+                * would be required. That would be lot more effort, so
+                * this seems a good stopgap fix.
+                */
+
+               count_share_opens(ctr1->array, svrid_arr,
+                                 lp_path(talloc_tos(), snum),
+                                 num_entries, *total_entries);
 
-               /* move on to creating next connection */
-               num_entries++;
        }
 
        ctr1->count = num_entries;
        *total_entries = num_entries;
 
        if (resume_handle_p) {
-               if (*resume_handle_p >= *total_entries) {
-                       *resume_handle_p = 0;
-               } else {
-                       *resume_handle_p = resume_handle;
-               }
+               *resume_handle_p = resume_handle;
        }
 
        return WERR_OK;
@@ -1231,7 +1415,8 @@ WERROR _srvsvc_NetConnEnum(struct pipes_struct *p,
                                                    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;


-- 
Samba Shared Repository

Reply via email to