dcerpc: add example of NetShareGetInfo
[libsmb2.git] / lib / smb2-share-enum.c
index c01da50a03158019f69d4b77b61e43a0eccb9b08..435ed76d5012e48bdec2ba64cc4166bee603eea8 100644 (file)
 #include "libsmb2-private.h"
 
 struct smb2nse {
-        struct srvsvc_netshareenumall_req ea_req;
-
         smb2_command_cb cb;
         void *cb_data;
+        union {
+                struct srvsvc_netshareenumall_req se_req;
+                struct srvsvc_netsharegetinfo_req si_req;
+        };
 };
 
 static void
@@ -75,11 +77,11 @@ nse_free(struct smb2nse *nse)
 }
 
 static void
-share_enum_ioctl_cb(struct dcerpc_context *dce, int status,
-                    void *command_data, void *cb_data)
+srvsvc_ioctl_cb(struct dcerpc_context *dce, int status,
+                void *command_data, void *cb_data)
 {
         struct smb2nse *nse = cb_data;
-        struct srvsvc_netshareenumall_rep *rep = command_data;
+        struct srvsvc_rep *rep = command_data;
         struct smb2_context *smb2 = dcerpc_get_smb2_context(dce);
 
         if (status != SMB2_STATUS_SUCCESS) {
@@ -88,7 +90,7 @@ share_enum_ioctl_cb(struct dcerpc_context *dce, int status,
                 dcerpc_destroy_context(dce);
                 return;
         }
-
+        
         nse->cb(smb2, rep->status, rep, nse->cb_data);
         nse_free(nse);
         dcerpc_destroy_context(dce);
@@ -110,10 +112,10 @@ share_enum_bind_cb(struct dcerpc_context *dce, int status,
 
         status = dcerpc_call_async(dce,
                                    SRVSVC_NETSHAREENUMALL,
-                                   srvsvc_netshareenumall_encoder, &nse->ea_req,
-                                   srvsvc_netshareenumall_decoder,
+                                   srvsvc_NetShareEnumAll_encoder, &nse->se_req,
+                                   srvsvc_NetShareEnumAll_decoder,
                                    sizeof(struct srvsvc_netshareenumall_rep),
-                                   share_enum_ioctl_cb, nse);
+                                   srvsvc_ioctl_cb, nse);
         if (status) {
                 nse->cb(smb2, status, NULL, nse->cb_data);
                 nse_free(nse);
@@ -122,9 +124,47 @@ share_enum_bind_cb(struct dcerpc_context *dce, int status,
         }
 }
 
+int
+smb2_share_enum_async(struct smb2_context *smb2,
+                      smb2_command_cb cb, void *cb_data)
+{
+        struct dcerpc_context *dce;
+        struct smb2nse *nse;
+        int rc;
+
+        dce = dcerpc_create_context(smb2, "srvsvc", &srvsvc_interface);
+        if (dce == NULL) {
+                return -ENOMEM;
+        }
+        
+        nse = calloc(1, sizeof(struct smb2nse));
+        if (nse == NULL) {
+                smb2_set_error(smb2, "Failed to allocate nse");
+                dcerpc_destroy_context(dce);
+                return -ENOMEM;
+        }
+        nse->cb = cb;
+        nse->cb_data = cb_data;
+
+        nse->se_req.server = smb2->server;
+        nse->se_req.level = 1;
+        nse->se_req.ctr = NULL;
+        nse->se_req.max_buffer = 0xffffffff;
+        nse->se_req.resume_handle = 0;
+
+        rc = dcerpc_open_async(dce, share_enum_bind_cb, nse);
+        if (rc) {
+                free(nse);
+                dcerpc_destroy_context(dce);
+                return rc;
+        }
+        
+        return 0;
+}
+
 static void
-share_enum_connect_cb(struct dcerpc_context *dce, int status,
-                      void *command_data, void *cb_data)
+share_info_bind_cb(struct dcerpc_context *dce, int status,
+                   void *command_data, void *cb_data)
 {
         struct smb2nse *nse = cb_data;
         struct smb2_context *smb2 = dcerpc_get_smb2_context(dce);
@@ -136,7 +176,12 @@ share_enum_connect_cb(struct dcerpc_context *dce, int status,
                 return;
         }
 
-        status = dcerpc_bind_async(dce, share_enum_bind_cb, nse);
+        status = dcerpc_call_async(dce,
+                                   SRVSVC_NETSHAREGETINFO,
+                                   srvsvc_NetShareGetInfo_encoder, &nse->si_req,
+                                   srvsvc_NetShareGetInfo_decoder,
+                                   sizeof(struct srvsvc_netsharegetinfo_rep),
+                                   srvsvc_ioctl_cb, nse);
         if (status) {
                 nse->cb(smb2, status, NULL, nse->cb_data);
                 nse_free(nse);
@@ -146,7 +191,7 @@ share_enum_connect_cb(struct dcerpc_context *dce, int status,
 }
 
 int
-smb2_share_enum_async(struct smb2_context *smb2,
+smb2_share_info_async(struct smb2_context *smb2, const char *share,
                       smb2_command_cb cb, void *cb_data)
 {
         struct dcerpc_context *dce;
@@ -157,7 +202,7 @@ smb2_share_enum_async(struct smb2_context *smb2,
         if (dce == NULL) {
                 return -ENOMEM;
         }
-        
+
         nse = calloc(1, sizeof(struct smb2nse));
         if (nse == NULL) {
                 smb2_set_error(smb2, "Failed to allocate nse");
@@ -167,18 +212,16 @@ smb2_share_enum_async(struct smb2_context *smb2,
         nse->cb = cb;
         nse->cb_data = cb_data;
 
-        nse->ea_req.server = smb2->server;
-        nse->ea_req.level = 1;
-        nse->ea_req.ctr = NULL;
-        nse->ea_req.max_buffer = 0xffffffff;
-        nse->ea_req.resume_handle = 0;
+        nse->si_req.server = smb2->server;
+        nse->si_req.share = share;
+        nse->si_req.level = 1;
 
-        rc = dcerpc_open_async(dce, share_enum_connect_cb, nse);
+        rc = dcerpc_open_async(dce, share_info_bind_cb, nse);
         if (rc) {
                 free(nse);
                 dcerpc_destroy_context(dce);
                 return rc;
         }
-        
+
         return 0;
 }