rpcclient "Service Control Manager" svcenum [-i] command.
authorLuke Leighton <lkcl@samba.org>
Thu, 28 Jan 1999 21:11:15 +0000 (21:11 +0000)
committerLuke Leighton <lkcl@samba.org>
Thu, 28 Jan 1999 21:11:15 +0000 (21:11 +0000)
source/include/proto.h
source/include/rpc_svcctl.h
source/rpc_client/cli_svcctl.c
source/rpc_parse/parse_svc.c
source/rpcclient/cmd_svcctl.c
source/rpcclient/display.c
source/rpcclient/rpcclient.c

index 6f2c9934e84ce5eaad5f2aaaa736321319569cc0..15ed9a50af48d12a1a4116e6a6def6efb394e8bd 100644 (file)
@@ -1778,17 +1778,26 @@ BOOL do_srv_net_srv_get_info(struct cli_state *cli, uint16 fnum,
 
 /*The following definitions come from  rpc_client/cli_svcctl.c  */
 
-BOOL do_svc_open_sc_man(struct cli_state *cli, uint16 fnum, 
+BOOL svc_open_sc_man(struct cli_state *cli, uint16 fnum, 
                                char *srv_name, char *db_name,
                                uint32 des_access,
                                POLICY_HND *hnd);
-BOOL do_svc_enum_svcs(struct cli_state *cli, uint16 fnum, 
+BOOL svc_open_service(struct cli_state *cli, uint16 fnum, 
+                               POLICY_HND *scm_hnd,
+                               char *srv_name,
+                               uint32 des_access,
+                               POLICY_HND *hnd);
+BOOL 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 *dos_error,
                                ENUM_SRVC_STATUS **svcs, uint32 *num_svcs);
-BOOL do_svc_close(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd);
+BOOL svc_query_svc_cfg(struct cli_state *cli, uint16 fnum,
+                               POLICY_HND *hnd,
+                               QUERY_SERVICE_CONFIG *cfg,
+                               uint32 *buf_size);
+BOOL svc_close(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd);
 
 /*The following definitions come from  rpc_client/cli_wkssvc.c  */
 
@@ -2540,6 +2549,7 @@ void make_svc_q_query_svc_config(SVC_Q_QUERY_SVC_CONFIG *q_c, POLICY_HND *hnd,
                                uint32 buf_size);
 void svc_io_q_query_svc_config(char *desc,  SVC_Q_QUERY_SVC_CONFIG *q_u, prs_struct *ps, int depth);
 void make_svc_r_query_svc_config(SVC_R_QUERY_SVC_CONFIG *r_c, 
+                               QUERY_SERVICE_CONFIG *cfg,
                                uint32 buf_size);
 void svc_io_r_query_svc_config(char *desc,  SVC_R_QUERY_SVC_CONFIG *r_u, prs_struct *ps, int depth);
 void make_svc_q_close(SVC_Q_CLOSE *q_c, POLICY_HND *hnd);
@@ -2769,6 +2779,8 @@ void display_reg_value_info(FILE *out_hnd, enum action_type action,
                                char *val_name, uint32 val_type, BUFFER2 *value);
 void display_reg_key_info(FILE *out_hnd, enum action_type action,
                                char *key_name, time_t key_mod_time);
+void display_query_svc_cfg(FILE *out_hnd, enum action_type action,
+                               QUERY_SERVICE_CONFIG *cfg);
 void display_svc_info(FILE *out_hnd, enum action_type action, ENUM_SRVC_STATUS *svc);
 
 /*The following definitions come from  rpcclient/rpcclient.c  */
index dc7d48d6b342fc7fd52117e2ea69a9471bf04072..8710a862765085117dd8386d12c92bdd178ceb9f 100644 (file)
@@ -58,8 +58,8 @@ typedef struct r_svc_open_sc_man_info
 typedef struct q_svc_open_service_info
 {
        POLICY_HND scman_pol;
-       UNISTR2 uni_srv_name;        /* unicode server name starting with '\\' */
-       uint32 des_access;            /* 0x80000004 - SC_MANAGER_xxxx */
+       UNISTR2 uni_svc_name;        /* unicode service name */
+       uint32 des_access;            /* 0x8000 0001 */
 
 } SVC_Q_OPEN_SERVICE;
 
index f14a699802e095306410745d65e95fd4727db51a..ebf8c15dc47c7e84aba7d8f96bf0bb57c3a602f7 100644 (file)
@@ -34,7 +34,7 @@ extern int DEBUGLEVEL;
 /****************************************************************************
 do a SVC Open Policy
 ****************************************************************************/
-BOOL do_svc_open_sc_man(struct cli_state *cli, uint16 fnum, 
+BOOL svc_open_sc_man(struct cli_state *cli, uint16 fnum, 
                                char *srv_name, char *db_name,
                                uint32 des_access,
                                POLICY_HND *hnd)
@@ -91,10 +91,71 @@ BOOL do_svc_open_sc_man(struct cli_state *cli, uint16 fnum,
 }
 
 
+/****************************************************************************
+do a SVC Open Service
+****************************************************************************/
+BOOL svc_open_service(struct cli_state *cli, uint16 fnum, 
+                               POLICY_HND *scm_hnd,
+                               char *srv_name,
+                               uint32 des_access,
+                               POLICY_HND *hnd)
+{
+       prs_struct rbuf;
+       prs_struct buf; 
+       SVC_Q_OPEN_SERVICE q_o;
+       BOOL valid_pol = False;
+
+       if (hnd == NULL || scm_hnd == NULL) return False;
+
+       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
+       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
+
+       /* create and send a MSRPC command with api SVC_OPEN_SERVICE */
+
+       DEBUG(4,("SVC Open Service\n"));
+
+       make_svc_q_open_service(&q_o, scm_hnd, srv_name, des_access);
+
+       /* turn parameters into data stream */
+       svc_io_q_open_service("", &q_o, &buf, 0);
+
+       /* send the data on \PIPE\ */
+       if (rpc_api_pipe_req(cli, fnum, SVC_OPEN_SERVICE, &buf, &rbuf))
+       {
+               SVC_R_OPEN_SERVICE r_o;
+               BOOL p;
+
+               ZERO_STRUCT(r_o);
+
+               svc_io_r_open_service("", &r_o, &rbuf, 0);
+               p = rbuf.offset != 0;
+
+               if (p && r_o.status != 0)
+               {
+                       /* report error code */
+                       DEBUG(0,("SVC_OPEN_SC_MAN: %s\n", get_nt_error_msg(r_o.status)));
+                       p = False;
+               }
+
+               if (p)
+               {
+                       /* ok, at last: we're happy. return the policy handle */
+                       memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
+                       valid_pol = True;
+               }
+       }
+
+       prs_mem_free(&rbuf);
+       prs_mem_free(&buf );
+
+       return valid_pol;
+}
+
+
 /****************************************************************************
 do a SVC Enumerate Services
 ****************************************************************************/
-BOOL do_svc_enum_svcs(struct cli_state *cli, uint16 fnum, 
+BOOL svc_enum_svcs(struct cli_state *cli, uint16 fnum, 
                                POLICY_HND *hnd,
                                uint32 services_type, uint32 services_state,
                                uint32 *buf_size, uint32 *resume_hnd,
@@ -161,10 +222,72 @@ BOOL do_svc_enum_svcs(struct cli_state *cli, uint16 fnum,
 }
 
 
+/****************************************************************************
+do a SVC Query Service Config
+****************************************************************************/
+BOOL svc_query_svc_cfg(struct cli_state *cli, uint16 fnum,
+                               POLICY_HND *hnd,
+                               QUERY_SERVICE_CONFIG *cfg,
+                               uint32 *buf_size)
+{
+       prs_struct rbuf;
+       prs_struct buf; 
+       SVC_Q_QUERY_SVC_CONFIG q_c;
+       BOOL valid_cfg = False;
+
+       if (hnd == NULL || buf_size == NULL) return False;
+
+       /* create and send a MSRPC command with api SVC_QUERY_SVC_CONFIG */
+
+       prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
+       prs_init(&rbuf, 0   , 4, SAFETY_MARGIN, True );
+
+       DEBUG(4,("SVC Query Service Config\n"));
+
+       /* store the parameters */
+       make_svc_q_query_svc_config(&q_c, hnd, *buf_size);
+
+       /* turn parameters into data stream */
+       svc_io_q_query_svc_config("", &q_c, &buf, 0);
+
+       /* send the data on \PIPE\ */
+       if (rpc_api_pipe_req(cli, fnum, SVC_QUERY_SVC_CONFIG, &buf, &rbuf))
+       {
+               SVC_R_QUERY_SVC_CONFIG r_c;
+               BOOL p;
+
+               ZERO_STRUCT (r_c);
+               ZERO_STRUCTP(cfg);
+
+               r_c.cfg = cfg;
+
+               svc_io_r_query_svc_config("", &r_c, &rbuf, 0);
+               p = rbuf.offset != 0;
+
+               if (p && r_c.status != 0)
+               {
+                       /* report error code */
+                       DEBUG(0,("SVC_QUERY_SVC_CONFIG: %s\n", get_nt_error_msg(r_c.status)));
+                       p = False;
+               }
+
+               if (p)
+               {
+                       valid_cfg = r_c.buf_size != 0;
+               }
+       }
+
+       prs_mem_free(&rbuf);
+       prs_mem_free(&buf );
+
+       return valid_cfg;
+}
+
+
 /****************************************************************************
 do a SVC Close
 ****************************************************************************/
-BOOL do_svc_close(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd)
+BOOL svc_close(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd)
 {
        prs_struct rbuf;
        prs_struct buf; 
index 912582f35e92c8e79bba1b6dc7be75b689342a5b..9c1f0f333598ddabc253b44e65d91d8801628efe 100644 (file)
@@ -106,7 +106,7 @@ void make_svc_q_open_service(SVC_Q_OPEN_SERVICE *q_u,
        DEBUG(5,("make_svc_q_open_service\n"));
 
        memcpy(&(q_u->scman_pol), hnd, sizeof(q_u->scman_pol));
-       make_unistr2(&(q_u->uni_srv_name), server, strlen(server)+1);
+       make_unistr2(&(q_u->uni_svc_name), server, strlen(server)+1);
        q_u->des_access = des_access;
 
 }
@@ -126,7 +126,7 @@ void svc_io_q_open_service(char *desc, SVC_Q_OPEN_SERVICE *q_u, prs_struct *ps,
        smb_io_pol_hnd("", &(q_u->scman_pol), ps, depth);
        prs_align(ps);
 
-       smb_io_unistr2("", &(q_u->uni_srv_name), 1, ps, depth); 
+       smb_io_unistr2("", &(q_u->uni_svc_name), 1, ps, depth); 
        prs_align(ps);
 
        prs_uint32("des_access", ps, depth, &(q_u->des_access));
@@ -492,12 +492,14 @@ void svc_io_q_query_svc_config(char *desc,  SVC_Q_QUERY_SVC_CONFIG *q_u, prs_str
 makes an SVC_R_QUERY_SVC_CONFIG structure.
 ********************************************************************/
 void make_svc_r_query_svc_config(SVC_R_QUERY_SVC_CONFIG *r_c, 
+                               QUERY_SERVICE_CONFIG *cfg,
                                uint32 buf_size)
 {
        if (r_c == NULL) return;
 
        DEBUG(5,("make_svc_r_query_svc_config\n"));
 
+       r_c->cfg      = cfg;
        r_c->buf_size = buf_size;
 }
 
index 162b0204b71484dbde7dced2fc1e2e3490c91db0..e30c20af6415909151129e8f7c4d5a2a5b160847 100644 (file)
@@ -50,6 +50,8 @@ void cmd_svc_enum(struct client_info *info)
        uint32 dos_error = 0;
        ENUM_SRVC_STATUS *svcs = NULL;
        uint32 num_svcs = 0;
+       fstring tmp;
+       BOOL request_info = False;
 
        POLICY_HND sc_man_pol;
        
@@ -61,11 +63,16 @@ void cmd_svc_enum(struct client_info *info)
 
        DEBUG(4,("cmd_svc_enum: server:%s\n", srv_name));
 
+       if (next_token(NULL, tmp, NULL, sizeof(tmp)))
+       {
+               request_info = strequal(tmp, "-i");
+       }
+
        /* open SVCCTL session. */
        res = res ? cli_nt_session_open(smb_cli, PIPE_SVCCTL, &fnum) : False;
 
        /* open service control manager receive a policy handle */
-       res = res ? do_svc_open_sc_man(smb_cli, fnum,
+       res = res ? svc_open_sc_man(smb_cli, fnum,
                                srv_name, NULL, 0x80000004,
                                &sc_man_pol) : False;
 
@@ -74,7 +81,7 @@ void cmd_svc_enum(struct client_info *info)
                buf_size += 0x800;
 
                /* enumerate services */
-               res1 = res ? do_svc_enum_svcs(smb_cli, fnum,
+               res1 = res ? svc_enum_svcs(smb_cli, fnum,
                                        &sc_man_pol,
                                        0x00000030, 0x00000003,
                                        &buf_size, &resume_hnd, &dos_error,
@@ -88,14 +95,39 @@ void cmd_svc_enum(struct client_info *info)
                fprintf(out_hnd,"--------\n");
        }
 
-       for (i = 0; i < num_svcs && svcs != NULL; i++)
+       for (i = 0; i < num_svcs && svcs != NULL && res1; i++)
        {
-               if (res1)
+               BOOL res2 = request_info;
+               BOOL res3;
+               POLICY_HND svc_pol;
+               fstring svc_name;
+               QUERY_SERVICE_CONFIG cfg;
+               uint32 svc_buf_size = 0x800;
+
+               fstrcpy(svc_name, unistr2(svcs[i].uni_srvc_name.buffer));
+
+               res2 = res2 ? svc_open_service(smb_cli, fnum,
+                                              &sc_man_pol,
+                                              svc_name, 0x80000001,
+                                              &svc_pol) : False;
+               res3 = res2 ? svc_query_svc_cfg(smb_cli, fnum,
+                                              &svc_pol, &cfg,
+                                              &svc_buf_size) : False;
+
+               if (res3)
+               {
+                       display_query_svc_cfg(out_hnd, ACTION_HEADER   , &cfg);
+                       display_query_svc_cfg(out_hnd, ACTION_ENUMERATE, &cfg);
+                       display_query_svc_cfg(out_hnd, ACTION_FOOTER   , &cfg);
+               }
+               else
                {
                        display_svc_info(out_hnd, ACTION_HEADER   , &svcs[i]);
                        display_svc_info(out_hnd, ACTION_ENUMERATE, &svcs[i]);
                        display_svc_info(out_hnd, ACTION_FOOTER   , &svcs[i]);
                }
+
+               res2 = res2 ? svc_close(smb_cli, fnum, &svc_pol) : False;
        }
 
        if (svcs != NULL)
@@ -103,7 +135,7 @@ void cmd_svc_enum(struct client_info *info)
                free(svcs);
        }
 
-       res  = res  ? do_svc_close(smb_cli, fnum, &sc_man_pol) : False;
+       res = res ? svc_close(smb_cli, fnum, &sc_man_pol) : False;
 
        /* close the session */
        cli_nt_session_close(smb_cli, fnum);
index 800b89e563b14dbceedde91cb8ae5f97771e0344..d37b7283f8f20ae1891a2616f689463b01936c07 100644 (file)
@@ -1535,6 +1535,62 @@ void display_reg_key_info(FILE *out_hnd, enum action_type action,
        }
 }
 
+/****************************************************************************
+convert a security permissions into a string
+****************************************************************************/
+char *get_svc_start_type_str(uint32 type)
+{
+       static fstring typestr;
+
+       switch (type)
+       {
+               case 0x00: fstrcpy(typestr, "Boot"    ); return typestr;
+               case 0x01: fstrcpy(typestr, "System"  ); return typestr;
+               case 0x02: fstrcpy(typestr, "Auto"    ); return typestr;
+               case 0x03: fstrcpy(typestr, "Manual"  ); return typestr;
+               case 0x04: fstrcpy(typestr, "Disabled"); return typestr;
+               default  : break;
+       }
+       slprintf(typestr, sizeof(typestr)-1, "[%d]", type);
+       return typestr;
+}
+
+
+/****************************************************************************
+ display structure
+ ****************************************************************************/
+void display_query_svc_cfg(FILE *out_hnd, enum action_type action,
+                               QUERY_SERVICE_CONFIG *cfg)
+{
+       switch (action)
+       {
+               case ACTION_HEADER:
+               {
+                       fprintf(out_hnd, "\tService:\t%s\n", unistr2_to_str(&cfg->uni_display_name)); /* service name unicode string */
+                       fprintf(out_hnd, "\t-------\n");
+                       break;
+               }
+               case ACTION_ENUMERATE:
+               {
+                       fprintf(out_hnd, "\tPath:\t%s\n"         ,  unistr2_to_str(&cfg->uni_bin_path_name));
+                       fprintf(out_hnd, "\tLoad Order:\t%s\n"   ,  unistr2_to_str(&cfg->uni_load_order_grp));
+                       fprintf(out_hnd, "\tDependencies:\t%s\n" ,  unistr2_to_str(&cfg->uni_dependencies));
+                       fprintf(out_hnd, "\tService Start:\t%s\n",  unistr2_to_str(&cfg->uni_service_start_name));
+                       fprintf(out_hnd, "\tService Type:\t%d\n" , cfg->service_type);
+                       fprintf(out_hnd, "\tStart Type:\t%s\n" , get_svc_start_type_str(cfg->start_type));
+                       fprintf(out_hnd, "\tError Control:\t%d\n" , cfg->error_control);
+                       fprintf(out_hnd, "\tTag Id:\t%d\n" , cfg->tag_id);
+                       break;
+
+               }
+               case ACTION_FOOTER:
+               {
+                       fprintf(out_hnd, "\n");
+                       break;
+               }
+       }
+}
+
 /****************************************************************************
  display structure
  ****************************************************************************/
index f2926276bc72346eb03c55ac8728339369570e3b..79ab1b68a1f9f854dfad6ccc5d395bee5547dbd1 100644 (file)
@@ -105,7 +105,7 @@ struct
   char *description;
 } commands[] = 
 {
-  {"svcenum",    cmd_svc_enum,         "Services Manager Enumeration"},
+  {"svcenum",    cmd_svc_enum,         "[-i] Lists Services Manager"},
   {"regenum",    cmd_reg_enum,         "<keyname> Registry Enumeration (keys, values)"},
   {"regdeletekey",cmd_reg_delete_key,  "<keyname> Registry Key Delete"},
   {"regcreatekey",cmd_reg_create_key,  "<keyname> [keyclass] Registry Key Create"},