adding some enumerate services code, client and server.
authorLuke Leighton <lkcl@samba.org>
Wed, 9 Dec 1998 16:28:04 +0000 (16:28 +0000)
committerLuke Leighton <lkcl@samba.org>
Wed, 9 Dec 1998 16:28:04 +0000 (16:28 +0000)
(This used to be commit dacf5b152bf74cc3ee9a816911384a5eb0e77afa)

source3/include/proto.h
source3/include/rpc_svcctl.h
source3/libsmb/smberr.c
source3/rpc_client/cli_svcctl.c
source3/rpc_parse/parse_misc.c
source3/rpc_parse/parse_prs.c
source3/rpc_parse/parse_svc.c
source3/rpc_server/srv_svcctl.c
source3/rpcclient/cmd_svcctl.c

index de2d6f476c4a200d36ea3d0a2544c1ec982427a1..e8d232645a14673f47247b64b7b1d3092173fd0a 100644 (file)
@@ -487,6 +487,7 @@ void pwdb_set_must_change_time(char *p, int max_len, time_t t);
 void pwdb_set_last_set_time(char *p, int max_len, time_t t);
 void pwdb_sethexpwd(char *p, const char *pwd, uint16 acct_ctrl);
 BOOL pwdb_gethexpwd(const char *p, char *pwd);
+BOOL pwdb_init_myworkgroup(void);
 BOOL pwdb_initialise(BOOL is_server);
 
 /*The following definitions come from  lib/util_sid.c  */
@@ -746,6 +747,7 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[
 
 /*The following definitions come from  libsmb/smberr.c  */
 
+char *smb_err_msg(uint8 class, uint32 num);
 char *smb_errstr(char *inbuf);
 
 /*The following definitions come from  locking/locking.c  */
@@ -1778,7 +1780,8 @@ BOOL do_svc_open_sc_man(struct cli_state *cli, uint16 fnum,
 BOOL do_svc_enum_svcs(struct cli_state *cli, uint16 fnum, 
                                POLICY_HND *hnd,
                                uint32 services_type, uint32 services_state,
-                               uint32 buf_size, uint32 *resume_hnd);
+                               uint32 buf_size, uint32 *resume_hnd,
+                               ENUM_SRVC_STATUS **svcs);
 BOOL do_svc_close(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd);
 
 /*The following definitions come from  rpc_client/cli_wkssvc.c  */
@@ -2503,8 +2506,14 @@ void make_svc_r_open_sc_man(SVC_R_OPEN_SC_MAN *r_u, POLICY_HND *hnd,
 void svc_io_r_open_sc_man(char *desc,  SVC_R_OPEN_SC_MAN *r_u, prs_struct *ps, int depth);
 void make_svc_q_enum_svcs_status(SVC_Q_ENUM_SVCS_STATUS *q_c, POLICY_HND *hnd,
                                uint32 service_type, uint32 service_state,
-                               uint32 buf_size, uint32 enum_hnd );
+                               uint32 buf_size, uint32 resume_hnd );
 void svc_io_q_enum_svcs_status(char *desc,  SVC_Q_ENUM_SVCS_STATUS *q_u, prs_struct *ps, int depth);
+void make_svc_r_enum_svcs_status(SVC_R_ENUM_SVCS_STATUS *r_c, 
+                               ENUM_SRVC_STATUS *svcs, uint32 more_buf_size,
+                               uint32 num_svcs, uint32 resume_hnd,
+                               uint32 dos_status);
+void svc_io_r_enum_svcs_status(char *desc, SVC_R_ENUM_SVCS_STATUS *svc, prs_struct *ps, int depth);
+void svc_io_svc_status(char *desc,  SVC_STATUS *svc, prs_struct *ps, int depth);
 void make_svc_q_close(SVC_Q_CLOSE *q_c, POLICY_HND *hnd);
 void svc_io_q_close(char *desc,  SVC_Q_CLOSE *q_u, prs_struct *ps, int depth);
 void svc_io_r_close(char *desc,  SVC_R_CLOSE *r_u, prs_struct *ps, int depth);
index 424192821898f9d958128e755ecdb0db7ffc2de9..451fdaa459a8dbb2192c06e2ef5333cde9e451f2 100644 (file)
@@ -65,14 +65,14 @@ typedef struct svc_status_info
 
 } SVC_STATUS;
 
-/* ENUM_SVC_STATUS */
+/* ENUM_SRVC_STATUS */
 typedef struct enum_svc_status_info
 {
        UNISTR uni_srvc_name;
        UNISTR uni_disp_name;
        SVC_STATUS status;
 
-} ENUM_SVC_STATUS;
+} ENUM_SRVC_STATUS;
 
 /* SVC_Q_ENUM_SVCS_STATUS */
 typedef struct q_svc_enum_svcs_status_info
@@ -89,8 +89,11 @@ typedef struct q_svc_enum_svcs_status_info
 typedef struct r_svc_enum_svcs_status_info
 {
        uint32 buf_size; /* service buffer size */
-       ENUM_SVC_STATUS *svcs;
-       uint32 status;             /* return status */
+       ENUM_SRVC_STATUS *svcs;
+       uint32 more_buf_size;
+       uint32 num_svcs;
+       ENUM_HND resume_hnd; /* resume handle */
+       uint32 dos_status; /* return status, DOS error code (wow!) */
 
 } SVC_R_ENUM_SVCS_STATUS;
 
index c2d8884d7384395cbd05577bc39e5f3f8b2b02f8..4fd9165c69b4aaab7e9456a3e20b4a66123b2c91 100644 (file)
@@ -147,35 +147,48 @@ struct
 /****************************************************************************
 return a SMB error string from a SMB buffer
 ****************************************************************************/
-char *smb_errstr(char *inbuf)
+char *smb_err_msg(uint8 class, uint32 num)
 {
-  static pstring ret;
-  int class = CVAL(inbuf,smb_rcls);
-  int num = SVAL(inbuf,smb_err);
-  int i,j;
+       static pstring ret;
+       int i,j;
 
-  for (i=0;err_classes[i].class;i++)
-    if (err_classes[i].code == class)
-      {
-       if (err_classes[i].err_msgs)
-         {
-           err_code_struct *err = err_classes[i].err_msgs;
-           for (j=0;err[j].name;j++)
-             if (num == err[j].code)
+       for (i=0;err_classes[i].class;i++)
+       {
+               if (err_classes[i].code == class)
                {
-                 if (DEBUGLEVEL > 0)
-                   slprintf(ret, sizeof(ret) - 1, "%s - %s (%s)",err_classes[i].class,
-                           err[j].name,err[j].message);
-                 else
-                   slprintf(ret, sizeof(ret) - 1, "%s - %s",err_classes[i].class,err[j].name);
-                 return ret;
+                       err_code_struct *err = err_classes[i].err_msgs;
+                       if (err != NULL)
+                       {
+                               for (j=0;err[j].name;j++)
+                               {
+                                       if (num == err[j].code)
+                                       {
+                                               if (DEBUGLEVEL > 0)
+                                               {
+                                                       slprintf(ret, sizeof(ret) - 1, "%s - %s (%s)",err_classes[i].class,
+                                                       err[j].name,err[j].message);
+                                               }
+                                               else
+                                               {
+                                                       slprintf(ret, sizeof(ret) - 1, "%s - %s",err_classes[i].class,err[j].name);
+                                               }
+                                               return ret;
+                                       }
+                               }
+                       }
+
                }
-         }
 
-       slprintf(ret, sizeof(ret) - 1, "%s - %d",err_classes[i].class,num);
-       return ret;
-      }
-  
-  slprintf(ret, sizeof(ret) - 1, "Error: Unknown error (%d,%d)",class,num);
-  return(ret);
+               slprintf(ret, sizeof(ret) - 1, "%s - %d",err_classes[i].class, num);
+               return ret;
+       }
+       slprintf(ret, sizeof(ret) - 1, "Error: Unknown error (%d,%d)",class,num);
+       return(ret);
+}
+/****************************************************************************
+return a SMB error string from a SMB buffer
+****************************************************************************/
+char *smb_errstr(char *inbuf)
+{
+       return smb_err_msg(CVAL(inbuf,smb_rcls), SVAL(inbuf,smb_err));
 }
index 90d74188dac0e8cb2ea10193c4b1772e5eeb7ad2..3535c90391f9a073aeabd9120fe8362fd57bc13e 100644 (file)
@@ -97,7 +97,8 @@ do a SVC Enumerate Services
 BOOL do_svc_enum_svcs(struct cli_state *cli, uint16 fnum, 
                                POLICY_HND *hnd,
                                uint32 services_type, uint32 services_state,
-                               uint32 buf_size, uint32 *resume_hnd)
+                               uint32 buf_size, uint32 *resume_hnd,
+                               ENUM_SRVC_STATUS **svcs)
 {
        prs_struct rbuf;
        prs_struct buf; 
@@ -123,7 +124,6 @@ BOOL do_svc_enum_svcs(struct cli_state *cli, uint16 fnum,
        /* send the data on \PIPE\ */
        if (rpc_api_pipe_req(cli, fnum, SVC_ENUM_SVCS_STATUS, &buf, &rbuf))
        {
-#if 0
                SVC_R_ENUM_SVCS_STATUS r_o;
                BOOL p;
 
@@ -132,22 +132,19 @@ BOOL do_svc_enum_svcs(struct cli_state *cli, uint16 fnum,
                svc_io_r_enum_svcs_status("", &r_o, &rbuf, 0);
                p = rbuf.offset != 0;
 
-               if (p && r_o.status != 0)
+               if (p && r_o.dos_status != 0)
                {
                        /* report error code */
-                       DEBUG(0,("SVC_ENUM_SVCS_STATUS: %s\n", get_nt_error_msg(r_o.status)));
-                       p = False;
+                       DEBUG(0,("SVC_ENUM_SVCS_STATUS: %s\n", smb_err_msg(ERRDOS, r_o.dos_status)));
+                       p = r_o.dos_status != ERRmoredata;
                }
 
                if (p)
                {
-                       /* ok, at last: we're happy. return the policy handle */
-                       memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
+                       (*svcs) = r_o.svcs;
+                       (*resume_hnd) = get_enum_hnd(&r_o.resume_hnd);
                        valid_pol = True;
                }
-#else
-       valid_pol = True;
-#endif
        }
 
        prs_mem_free(&rbuf);
index fdc67d09059e327a747186cf8389e49bd5a90134..6b3fc9415eb625b074ddad6d8840dc44e5999cb6 100644 (file)
@@ -343,7 +343,6 @@ void smb_io_unistr(char *desc,  UNISTR *uni, prs_struct *ps, int depth)
        prs_debug(ps, depth, desc, "smb_io_unistr");
        depth++;
 
-       prs_align(ps);
        prs_unistr("unistr", ps, depth, uni);
 }
 
index 75432627ab8bbc0bb66274bbaddb455f2e6bf30c..ef327f01a188c6b9c84ee0a4e7682d541b7d011c 100644 (file)
@@ -237,21 +237,22 @@ BOOL prs_unistr3(BOOL charmode, char *name, UNISTR3 *str, prs_struct *ps, int de
 BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str)
 {
        char *q = mem_data(&(ps->data), ps->offset);
-       int i = 0;
+       int i = -1;
        uint8 *start = (uint8*)q;
 
        if (q == NULL) return False;
 
-       do 
+       do
        {
+               i++;
                RW_SVAL(ps->io, q, str->buffer[i],0);
                q += 2;
-               i++;
-
-       } while ((i < sizeof(str->buffer) / sizeof(str->buffer[0])) &&
+       }
+       while ((i < sizeof(str->buffer) / sizeof(str->buffer[0])) &&
                     (str->buffer[i] != 0));
 
-       ps->offset += i*2;
+
+       ps->offset += (i+1)*2;
 
        dump_data(5+depth, (char *)start, i * 2);
 
index 2134d86f47b491e382310fcdd6ce568c2a01b6c4..2ebab5aea5e0d19a3d35b996e889d493abcb422b 100644 (file)
@@ -134,6 +134,204 @@ void svc_io_q_enum_svcs_status(char *desc,  SVC_Q_ENUM_SVCS_STATUS *q_u, prs_str
        smb_io_enum_hnd("resume_hnd", &(q_u->resume_hnd), ps, depth); 
 }
 
+/*******************************************************************
+makes an SVC_R_ENUM_SVCS_STATUS structure.
+********************************************************************/
+void make_svc_r_enum_svcs_status(SVC_R_ENUM_SVCS_STATUS *r_c, 
+                               ENUM_SRVC_STATUS *svcs, uint32 more_buf_size,
+                               uint32 num_svcs, uint32 resume_hnd,
+                               uint32 dos_status)
+{
+       if (r_c == NULL) return;
+
+       DEBUG(5,("make_svc_r_enum_svcs_status\n"));
+
+       r_c->svcs          = svcs;
+       r_c->more_buf_size = more_buf_size;
+       r_c->num_svcs      = num_svcs;
+       make_enum_hnd(&r_c->resume_hnd, resume_hnd);
+       r_c->dos_status = dos_status;
+}
+
+/*******************************************************************
+reads or writes a SVC_R_ENUM_SVCS_STATUS structure.
+
+this is another wierd structure.  WHY oh WHY can the microsoft teams
+not COMMUNICATE and get some CONSISTENCY TO THEIR DATA STRUCTURES!
+ARGH!
+
+********************************************************************/
+void svc_io_r_enum_svcs_status(char *desc, SVC_R_ENUM_SVCS_STATUS *svc, prs_struct *ps, int depth)
+{
+       int i;
+       if (svc == NULL) return;
+
+       prs_debug(ps, depth, desc, "svc_io_r_enum_svcs_status");
+       depth++;
+
+       prs_align(ps);
+       
+       /*
+        * format is actually as laid out in SVC_R_ENUM_SVCS_STATUS.
+        * the reason for all the jumping about, which is horrible
+        * and can be avoided, is due to the use of offsets instead
+        * of pointers.
+        *
+        * if i ever find out that these offsets are in fact non-zero
+        * tokens just like pointer-tokens, i am going to go MAD.
+        */
+
+       if (ps->io)
+       {
+               /* reading */
+
+               uint32 buf_offset;
+               uint32 new_offset;
+
+               prs_uint32("buf_size", ps, depth, &(svc->buf_size));
+
+               buf_offset = ps->offset;
+               ps->offset = buf_offset + svc->buf_size;
+
+               prs_uint32("more_buf_size", ps, depth, &(svc->more_buf_size));
+               prs_uint32("num_svcs", ps, depth, &(svc->num_svcs));
+               smb_io_enum_hnd("resume_hnd", &(svc->resume_hnd), ps, depth); 
+               prs_uint32("dos_status", ps, depth, &(svc->dos_status));
+
+               new_offset = ps->offset;
+               ps->offset = buf_offset;
+
+               svc->svcs = Realloc(NULL, svc->num_svcs * sizeof(ENUM_SRVC_STATUS));
+
+               if (svc->svcs == NULL)
+               {
+                       DEBUG(0,("svc_io_r_enum_svcs_status: Realloc failed\n"));
+                       ps->offset = 0x7fffffff;
+                       return;
+               }
+
+               bzero(svc->svcs, svc->num_svcs * sizeof(ENUM_SRVC_STATUS));
+
+               for (i = 0; i < svc->num_svcs; i++)
+               {
+                       fstring name;
+                       uint32 old_offset;
+                       uint32 srvc_offset;
+                       uint32 disp_offset;
+
+                       prs_uint32("srvc_offset", ps, depth, &srvc_offset);
+                       prs_uint32("disp_offset", ps, depth, &disp_offset);
+                       svc_io_svc_status("status", &svc->svcs[i].status, ps, depth); 
+
+                       old_offset = ps->offset;
+
+                       ps->offset = buf_offset + srvc_offset;
+                       slprintf(name, sizeof(name)-1, "srvc[%02d]", i);
+                       smb_io_unistr(name, &svc->svcs[i].uni_srvc_name, ps, depth);
+
+                       ps->offset = buf_offset + disp_offset;
+                       slprintf(name, sizeof(name)-1, "disp[%02d]", i);
+                       smb_io_unistr(name, &svc->svcs[i].uni_disp_name, ps, depth);
+
+                       ps->offset = old_offset;
+               }
+
+               ps->offset = new_offset;
+       }
+       else
+       {
+               /* writing */
+
+               uint32 buf_offset;
+               uint32 old_buf_offset;
+               uint32 srvc_offset = 9 * sizeof(uint32) * svc->num_svcs;
+
+               prs_uint32_pre("buf_size", ps, depth, &svc->buf_size, &buf_offset);
+               old_buf_offset = ps->offset;
+
+               srvc_offset += old_buf_offset;
+
+               if (svc->svcs == NULL)
+               {
+                       return;
+               }
+
+               for (i = 0; i < svc->num_svcs; i++)
+               {
+                       fstring name;
+                       uint32 old_offset;
+
+                       /*
+                        * store unicode string offset and unicode string
+                        */
+
+                       srvc_offset -= old_buf_offset;
+                       prs_uint32("srvc_offset", ps, depth, &srvc_offset);
+                       srvc_offset += old_buf_offset;
+
+                       slprintf(name, sizeof(name)-1, "srvc[%02d]", i);
+
+                       old_offset = ps->offset;
+                       ps->offset = srvc_offset;
+                       smb_io_unistr(name, &svc->svcs[i].uni_srvc_name, ps, depth);
+                       srvc_offset = ps->offset;
+                       ps->offset = old_offset;
+
+                       /*
+                        * store unicode string offset and unicode string
+                        */
+
+                       srvc_offset -= old_buf_offset;
+                       prs_uint32("disp_offset", ps, depth, &srvc_offset);
+                       srvc_offset += old_buf_offset;
+
+                       slprintf(name, sizeof(name)-1, "disp[%02d]", i);
+
+                       old_offset = ps->offset;
+                       ps->offset = srvc_offset;
+                       smb_io_unistr(name, &svc->svcs[i].uni_disp_name, ps, depth);
+                       srvc_offset = ps->offset;
+                       ps->offset = old_offset;
+
+                       /*
+                        * store status info
+                        */
+
+                       svc_io_svc_status("status", &svc->svcs[i].status, ps, depth); 
+               }
+
+               prs_uint32_post("buf_size", ps, depth, &svc->buf_size, buf_offset, srvc_offset - buf_offset - sizeof(uint32));
+
+               ps->offset = srvc_offset;
+
+               prs_uint32("more_buf_size", ps, depth, &(svc->more_buf_size));
+               prs_uint32("num_svcs", ps, depth, &(svc->num_svcs));
+               smb_io_enum_hnd("resume_hnd", &(svc->resume_hnd), ps, depth); 
+               prs_uint32("dos_status", ps, depth, &(svc->dos_status));
+       }
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void svc_io_svc_status(char *desc,  SVC_STATUS *svc, prs_struct *ps, int depth)
+{
+       if (svc == NULL) return;
+
+       prs_debug(ps, depth, desc, "svc_io_svc_status");
+       depth++;
+
+       prs_align(ps);
+
+       prs_uint32("svc_type", ps, depth, &(svc->svc_type));
+       prs_uint32("current_state", ps, depth, &(svc->current_state));
+       prs_uint32("controls_accepted", ps, depth, &(svc->controls_accepted));
+       prs_uint32("win32_exit_code", ps, depth, &(svc->win32_exit_code));
+       prs_uint32("svc_specific_exit_code", ps, depth, &(svc->svc_specific_exit_code));
+       prs_uint32("check_point", ps, depth, &(svc->check_point));
+       prs_uint32("wait_hint", ps, depth, &(svc->wait_hint));
+}
+
 /*******************************************************************
 makes an SVC_Q_CLOSE structure.
 ********************************************************************/
@@ -180,48 +378,3 @@ void svc_io_r_close(char *desc,  SVC_R_CLOSE *r_u, prs_struct *ps, int depth)
        prs_uint32("status", ps, depth, &(r_u->status));
 }
 
-#if 0
-/*******************************************************************
-reads or writes a SEC_DESC_BUF structure.
-********************************************************************/
-void sec_io_desc_buf(char *desc, SEC_DESC_BUF *sec, prs_struct *ps, int depth)
-{
-       uint32 off_len;
-       uint32 old_offset;
-       uint32 size;
-
-       if (sec == NULL) return;
-
-       prs_debug(ps, depth, desc, "sec_io_desc_buf");
-       depth++;
-
-       prs_align(ps);
-       
-       prs_uint32_pre("max_len", ps, depth, &(sec->max_len), &off_max_len);
-
-       old_offset = ps->offset;
-
-       if (sec->len != 0 && ps->io)
-       {
-               /* reading */
-               sec->sec = malloc(sizeof(*sec->sec));
-               ZERO_STRUCTP(sec->sec);
-
-               if (sec->sec == NULL)
-               {
-                       DEBUG(0,("INVALID SEC_DESC\n"));
-                       ps->offset = 0xfffffffe;
-                       return;
-               }
-       }
-
-       /* reading, length is non-zero; writing, descriptor is non-NULL */
-       if ((sec->len != 0 || (!ps->io)) && sec->sec != NULL)
-       {
-               sec_io_desc("sec   ", sec->sec, ps, depth);
-       }
-
-       size = ps->offset - old_offset;
-       prs_uint32_post("max_len", ps, depth, &(sec->max_len), off_max_len, size == 0 ? sec->max_len : size);
-}
-#endif
index be990639465159b689aa5a1c548776f5125b6889..6cf9b8cd2280da53daac3b6bf46ca30ec4f71af7 100644 (file)
@@ -120,6 +120,119 @@ static void api_svc_open_sc_man( uint16 vuid, prs_struct *data,
        svc_reply_open_sc_man(&q_u, rdata);
 }
 
+static char *dummy_services[] =
+{
+       "imapd",
+       "popd",
+       "smbd",
+       "nmbd",
+       "httpd",
+       "inetd",
+       "syslogd",
+       NULL
+};
+
+/*******************************************************************
+ svc_reply_enum_svcs_status
+ ********************************************************************/
+static void svc_reply_enum_svcs_status(SVC_Q_ENUM_SVCS_STATUS *q_u,
+                               prs_struct *rdata)
+{
+       uint32 dos_status = 0;
+       SVC_R_ENUM_SVCS_STATUS r_u;
+       ENUM_SRVC_STATUS *svcs = NULL;
+       int num_svcs = 0;
+       int buf_size = 0;
+       int i = get_enum_hnd(&q_u->resume_hnd);
+       uint32 resume_hnd = 0;
+       int max_buf_size = 0x80;
+
+       ZERO_STRUCT(r_u);
+
+       DEBUG(5,("svc_enum_svcs_status: %d\n", __LINE__));
+
+       if (dos_status == 0x0 && find_lsa_policy_by_hnd(&q_u->pol) == -1)
+       {
+               dos_status = 0xC000000 | NT_STATUS_INVALID_HANDLE;
+       }
+
+       if (dos_status == 0x0)
+       {
+               DEBUG(5,("svc_enum_svcs_status:\n"));
+               while (dummy_services[i] != NULL)
+               {
+               
+                       ENUM_SRVC_STATUS *svc = NULL;
+
+                       buf_size += strlen(dummy_services[i] + 1) * 2;
+                       buf_size += 9 * sizeof(uint32);
+
+                       DEBUG(10,("buf_size: %d q_u->buf_size: %d\n",
+                                  buf_size, q_u->buf_size));
+
+                       if (buf_size > q_u->buf_size)
+                       {
+                               if (buf_size >= max_buf_size)
+                               {
+                                       resume_hnd = i;
+                               }
+                               break;
+                       }
+
+                       num_svcs++;
+                       svcs = Realloc(svcs, num_svcs * sizeof(ENUM_SRVC_STATUS));
+                       if (svcs == NULL)
+                       {
+                               dos_status = ERRnomem;
+                               num_svcs = 0;
+                               break;
+                       }
+
+                       svc = &svcs[num_svcs-1];
+                       ZERO_STRUCTP(svc);
+
+                       make_unistr(&svc->uni_srvc_name, dummy_services[i]);
+                       make_unistr(&svc->uni_disp_name, dummy_services[i]);
+
+                       DEBUG(10,("show service: %s\n", dummy_services[i]));
+                       i++;
+               }
+       }
+
+       /*
+        * check for finished condition: no resume handle and last buffer fits
+        */
+
+       if (resume_hnd == 0 && buf_size <= q_u->buf_size)
+       {
+               /* this indicates, along with resume_hnd of 0, an end. */
+               max_buf_size = 0;
+       }
+
+       make_svc_r_enum_svcs_status(&r_u, svcs, max_buf_size, num_svcs, resume_hnd, dos_status);
+
+       /* store the response in the SMB stream */
+       svc_io_r_enum_svcs_status("", &r_u, rdata, 0);
+
+       if (svcs != NULL)
+       {
+               free(svcs);
+       }
+
+       DEBUG(5,("svc_enum_svcs_status: %d\n", __LINE__));
+}
+
+/*******************************************************************
+ api_svc_enum_svcs_status
+ ********************************************************************/
+static void api_svc_enum_svcs_status( uint16 vuid, prs_struct *data,
+                                    prs_struct *rdata )
+{
+       SVC_Q_ENUM_SVCS_STATUS q_u;
+       svc_io_q_enum_svcs_status("", &q_u, data, 0);
+       svc_reply_enum_svcs_status(&q_u, rdata);
+}
+
 /*******************************************************************
  array of \PIPE\svcctl operations
  ********************************************************************/
@@ -127,6 +240,7 @@ static struct api_struct api_svc_cmds[] =
 {
        { "SVC_CLOSE"        , SVC_CLOSE        , api_svc_close        },
        { "SVC_OPEN_SC_MAN"  , SVC_OPEN_SC_MAN  , api_svc_open_sc_man  },
+       { "SVC_ENUM_SVCS_STATUS", SVC_ENUM_SVCS_STATUS, api_svc_enum_svcs_status },
        { NULL,                0                , NULL                 }
 };
 
index 63f0d9651ca736e14611f4fd060aecc00b28a2d6..4f0978e17ff227b162b94e0d1af43c018d8e5c66 100644 (file)
@@ -46,6 +46,7 @@ void cmd_svc_enum(struct client_info *info)
        BOOL res1 = True;
        int i;
        uint32 resume_hnd = 0;
+       ENUM_SRVC_STATUS *svcs = NULL;
 
        POLICY_HND sc_man_pol;
        fstring full_keyname;
@@ -65,11 +66,20 @@ void cmd_svc_enum(struct client_info *info)
                                srv_name, NULL, 0x80000004,
                                &sc_man_pol) : False;
 
+       do
+       {
        /* enumerate services */
        res1 = res ? do_svc_enum_svcs(smb_cli, fnum,
                                &sc_man_pol,
                                0x00000030, 0x00000003,
-                               0x00000200, &resume_hnd) : False;
+                                       0x00000080, &resume_hnd, &svcs) : False;
+
+       } while (resume_hnd != 0);
+
+       if (svcs != NULL)
+       {
+               free(svcs);
+       }
 
 #if 0
        if (res1 && num_subkeys > 0)