1 /* packet-dcerpc-svcctl.c
2 * Routines for SMB \PIPE\svcctl packet disassembly
3 * Copyright 2003, Tim Potter <tpot@samba.org>
4 * Copyright 2003, Ronnie Sahlberg, added function dissectors
5 * Copyright 2010, Brett Kuskie <fullaxx@gmail.com>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include <epan/packet.h>
30 #include <epan/wmem/wmem.h>
31 #include "packet-dcerpc.h"
32 #include "packet-dcerpc-svcctl.h"
33 #include "packet-dcerpc-nt.h"
34 #include "packet-windows-common.h"
36 static int proto_dcerpc_svcctl = -1;
37 static int hf_svcctl_opnum = -1;
38 static int hf_svcctl_machinename = -1;
39 static int hf_svcctl_database = -1;
40 static int hf_svcctl_access_mask = -1;
41 static int hf_svcctl_scm_rights_connect = -1;
42 static int hf_svcctl_scm_rights_create_service = -1;
43 static int hf_svcctl_scm_rights_enumerate_service = -1;
44 static int hf_svcctl_scm_rights_lock = -1;
45 static int hf_svcctl_scm_rights_query_lock_status = -1;
46 static int hf_svcctl_scm_rights_modify_boot_config = -1;
47 static int hf_svcctl_hnd = -1;
48 static int hf_svcctl_lock = -1;
49 static int hf_svcctl_rc = -1;
50 static int hf_svcctl_size = -1;
51 static int hf_svcctl_required_size = -1;
52 static int hf_svcctl_is_locked = -1;
53 static int hf_svcctl_lock_duration = -1;
54 static int hf_svcctl_lock_owner = -1;
55 static int hf_svcctl_service_type = -1;
56 static int hf_svcctl_service_type_kernel_driver = -1;
57 static int hf_svcctl_service_type_fs_driver = -1;
58 static int hf_svcctl_service_type_win32_own_process = -1;
59 static int hf_svcctl_service_type_win32_share_process = -1;
60 static int hf_svcctl_service_type_interactive_process = -1;
61 static int hf_svcctl_service_state = -1;
62 static int hf_svcctl_buffer = -1;
63 /* static int hf_svcctl_bytes_needed = -1; */
64 /* static int hf_svcctl_services_returned = -1; */
65 static int hf_svcctl_resume = -1;
66 static int hf_svcctl_service_name = -1;
67 static int hf_svcctl_display_name = -1;
68 static int hf_svcctl_service_start_type = -1;
69 static int hf_svcctl_service_error_control = -1;
70 static int hf_svcctl_binarypathname = -1;
71 static int hf_svcctl_loadordergroup = -1;
72 static int hf_svcctl_tagid = -1;
73 static int hf_svcctl_dependencies = -1;
74 static int hf_svcctl_depend_size = -1;
75 static int hf_svcctl_service_start_name = -1;
76 static int hf_svcctl_password = -1;
77 static int hf_svcctl_password_size = -1;
79 static gint ett_dcerpc_svcctl = -1;
80 static gint ett_dcerpc_svcctl_service_type_bits = -1;
82 static e_uuid_t uuid_dcerpc_svcctl = {
83 0x367abb81, 0x9844, 0x35f1,
84 { 0xad, 0x32, 0x98, 0xf0, 0x38, 0x00, 0x10, 0x03 }
87 static guint16 ver_dcerpc_svcctl = 2;
89 #define SVCCTL_SERVICE_TYPE_KERNEL_DRIVER 0x01
90 #define SVCCTL_SERVICE_TYPE_FILE_SYSTEM_DRIVER 0x02
91 #define SVCCTL_SERVICE_TYPE_WIN32_OWN_PROCESS 0x10
92 #define SVCCTL_SERVICE_TYPE_WIN32_SHARE_PROCESS 0x20
93 #define SVCCTL_SERVICE_TYPE_INTERACTIVE_PROCESS 0x100
94 #define SVCCTL_SERVICE_TYPE_NO_CHANGE 0xffffffff
95 static const true_false_string tfs_svcctl_service_type_kernel_driver = {
96 "Is a kernel driver service",
97 "Is not a kernel driver service"
99 static const true_false_string tfs_svcctl_service_type_fs_driver = {
100 "Is a file system driver service",
101 "Is not a file system driver service"
103 static const true_false_string tfs_svcctl_service_type_win32_own_process = {
104 "Service runs its own processes",
105 "Service does not run its own process"
107 static const true_false_string tfs_svcctl_service_type_win32_share_process = {
108 "Service shares its process",
109 "Service does not share its process"
111 static const true_false_string tfs_svcctl_service_type_interactive_process = {
112 "Service can interact with the desktop",
113 "Service cannot interact with the desktop"
117 svcctl_dissect_dwServiceType_flags(tvbuff_t *tvb, int offset,
118 packet_info *pinfo, proto_tree *parent_tree,
119 guint8 *drep, int opnum)
121 guint32 value, len=4;
122 proto_item *item = NULL;
123 proto_tree *tree = NULL;
125 (void) dissect_dcerpc_uint32 (tvb, offset, pinfo, NULL, drep, 0, &value);
127 item = proto_tree_add_uint(parent_tree, hf_svcctl_service_type, tvb, offset, len, value);
128 tree = proto_item_add_subtree(item, ett_dcerpc_svcctl_service_type_bits);
132 case SVC_CREATE_SERVICE_W:
133 proto_tree_add_boolean(tree, hf_svcctl_service_type_interactive_process,
134 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_INTERACTIVE_PROCESS);
135 proto_tree_add_boolean(tree, hf_svcctl_service_type_win32_share_process,
136 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_WIN32_SHARE_PROCESS);
137 proto_tree_add_boolean(tree, hf_svcctl_service_type_win32_own_process,
138 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_WIN32_OWN_PROCESS);
139 proto_tree_add_boolean(tree, hf_svcctl_service_type_fs_driver,
140 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_FILE_SYSTEM_DRIVER);
141 proto_tree_add_boolean(tree, hf_svcctl_service_type_kernel_driver,
142 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_KERNEL_DRIVER);
144 case SVC_ENUM_SERVICES_STATUS_W:
145 proto_tree_add_boolean(tree, hf_svcctl_service_type_win32_share_process,
146 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_WIN32_SHARE_PROCESS);
147 proto_tree_add_boolean(tree, hf_svcctl_service_type_win32_own_process,
148 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_WIN32_OWN_PROCESS);
149 proto_tree_add_boolean(tree, hf_svcctl_service_type_fs_driver,
150 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_FILE_SYSTEM_DRIVER);
151 proto_tree_add_boolean(tree, hf_svcctl_service_type_kernel_driver,
152 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_KERNEL_DRIVER);
154 case SVC_QUERY_SERVICE_CONFIG_W:
155 proto_tree_add_boolean(tree, hf_svcctl_service_type_win32_share_process,
156 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_WIN32_SHARE_PROCESS);
157 proto_tree_add_boolean(tree, hf_svcctl_service_type_win32_own_process,
158 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_WIN32_OWN_PROCESS);
159 proto_tree_add_boolean(tree, hf_svcctl_service_type_fs_driver,
160 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_FILE_SYSTEM_DRIVER);
161 proto_tree_add_boolean(tree, hf_svcctl_service_type_kernel_driver,
162 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_KERNEL_DRIVER);
170 #define SVCCTL_SERVICE_ACTIVE 0x01
171 #define SVCCTL_SERVICE_INACTIVE 0x02
172 #define SVCCTL_SERVICE_STATE_ALL 0x03
173 static const value_string svcctl_service_status_vals[] = {
174 { SVCCTL_SERVICE_ACTIVE, "SERVICE_ACTIVE" },
175 { SVCCTL_SERVICE_INACTIVE, "SERVICE_INACTIVE" },
176 { SVCCTL_SERVICE_STATE_ALL, "SERVICE_STATE_ALL" },
180 #define SVCCTL_SERVICE_BOOT_START 0x00
181 #define SVCCTL_SERVICE_SYSTEM_START 0x01
182 #define SVCCTL_SERVICE_AUTO_START 0x02
183 #define SVCCTL_SERVICE_DEMAND_START 0x03
184 #define SVCCTL_SERVICE_DISABLED 0x04
185 static const value_string svcctl_service_start_type_vals[] = {
186 { SVCCTL_SERVICE_BOOT_START, "SERVICE_BOOT_START" },
187 { SVCCTL_SERVICE_SYSTEM_START, "SERVICE_SYSTEM_START" },
188 { SVCCTL_SERVICE_AUTO_START, "SERVICE_AUTO_START" },
189 { SVCCTL_SERVICE_DEMAND_START, "SERVICE_DEMAND_START" },
190 { SVCCTL_SERVICE_DISABLED, "SERVICE_DISABLED" },
194 #define SVCCTL_SERVICE_ERROR_IGNORE 0x00
195 #define SVCCTL_SERVICE_ERROR_NORMAL 0x01
196 #define SVCCTL_SERVICE_ERROR_SEVERE 0x02
197 #define SVCCTL_SERVICE_ERROR_CRITICAL 0x03
198 static const value_string svcctl_service_error_control_vals[] = {
199 { SVCCTL_SERVICE_ERROR_IGNORE, "SERVICE_ERROR_IGNORE" },
200 { SVCCTL_SERVICE_ERROR_NORMAL, "SERVICE_ERROR_NORMAL" },
201 { SVCCTL_SERVICE_ERROR_SEVERE, "SERVICE_ERROR_SEVERE" },
202 { SVCCTL_SERVICE_ERROR_CRITICAL, "SERVICE_ERROR_CRITICAL" },
207 svcctl_dissect_pointer_long(tvbuff_t *tvb, int offset,
208 packet_info *pinfo, proto_tree *tree,
209 dcerpc_info *di, guint8 *drep)
211 offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, di, drep,
217 svcctl_scm_specific_rights(tvbuff_t *tvb, gint offset, proto_tree *tree,
220 proto_tree_add_boolean(tree, hf_svcctl_scm_rights_modify_boot_config, tvb, offset, 4, access);
221 proto_tree_add_boolean(tree, hf_svcctl_scm_rights_query_lock_status, tvb, offset, 4, access);
222 proto_tree_add_boolean(tree, hf_svcctl_scm_rights_lock, tvb, offset, 4, access);
223 proto_tree_add_boolean(tree, hf_svcctl_scm_rights_enumerate_service, tvb, offset, 4, access);
224 proto_tree_add_boolean(tree, hf_svcctl_scm_rights_create_service, tvb, offset, 4, access);
225 proto_tree_add_boolean(tree, hf_svcctl_scm_rights_connect, tvb, offset, 4, access);
228 struct access_mask_info svcctl_scm_access_mask_info = {
230 svcctl_scm_specific_rights,
231 NULL, /* Generic mapping table */
232 NULL /* Standard mapping table */
236 * IDL long OpenSCManager(
237 * IDL [in] [string] [unique] char *MachineName,
238 * IDL [in] [string] [unique] char *DatabaseName,
239 * IDL [in] long access_mask,
240 * IDL [out] SC_HANDLE handle,
244 svcctl_dissect_OpenSCManager_rqst(tvbuff_t *tvb, int offset,
245 packet_info *pinfo, proto_tree *tree,
246 dcerpc_info *di, guint8 *drep)
248 dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
252 dcv->private_data=NULL;
253 offset = dissect_ndr_pointer_cb(
254 tvb, offset, pinfo, tree, di, drep,
255 dissect_ndr_char_cvstring, NDR_POINTER_UNIQUE,
256 "MachineName", hf_svcctl_machinename, cb_str_postprocess,
257 GINT_TO_POINTER(CB_STR_COL_INFO | CB_STR_SAVE | 1));
258 mn=(const char *)dcv->private_data;
263 dcv->private_data=NULL;
264 offset = dissect_ndr_pointer_cb(
265 tvb, offset, pinfo, tree, di, drep,
266 dissect_ndr_char_cvstring, NDR_POINTER_UNIQUE,
267 "Database", hf_svcctl_database, cb_str_postprocess,
268 GINT_TO_POINTER(CB_STR_COL_INFO | 1));
269 dn=(const char *)dcv->private_data;
273 /* OpenSCManager() stores the server\database in se_data */
274 if(!pinfo->fd->flags.visited){
276 dcv->se_data=wmem_strdup_printf(wmem_file_scope(), "%s\\%s",mn,dn);
281 offset = dissect_nt_access_mask(
282 tvb, offset, pinfo, tree, di, drep, hf_svcctl_access_mask,
283 &svcctl_scm_access_mask_info, NULL);
289 svcctl_dissect_OpenSCManager_reply(tvbuff_t *tvb, int offset,
290 packet_info *pinfo, proto_tree *tree,
291 dcerpc_info *di, guint8 *drep)
293 dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
294 e_ctx_hnd policy_hnd;
295 proto_item *hnd_item;
300 offset = dissect_nt_policy_hnd(
301 tvb, offset, pinfo, tree, di, drep, hf_svcctl_hnd, &policy_hnd,
302 &hnd_item, TRUE, FALSE);
304 offset = dissect_doserror(
305 tvb, offset, pinfo, tree, di, drep, hf_svcctl_rc, &status);
308 const char *pol_name;
311 pol_name = wmem_strdup_printf(wmem_packet_scope(),
312 "OpenSCManagerW(%s)", (char *)dcv->se_data);
314 pol_name = "Unknown OpenSCManagerW() handle";
316 if(!pinfo->fd->flags.visited){
317 dcerpc_store_polhnd_name(&policy_hnd, pinfo, pol_name);
321 proto_item_append_text(hnd_item, ": %s", pol_name);
328 svcctl_dissect_OpenSCManagerW_rqst(tvbuff_t *tvb, int offset,
329 packet_info *pinfo, proto_tree *tree,
330 dcerpc_info *di, guint8 *drep)
332 dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
336 dcv->private_data=NULL;
337 offset = dissect_ndr_pointer_cb(
338 tvb, offset, pinfo, tree, di, drep,
339 dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE,
340 "MachineName", hf_svcctl_machinename, cb_wstr_postprocess,
341 GINT_TO_POINTER(CB_STR_COL_INFO | CB_STR_SAVE | 1));
342 mn=(const char *)dcv->private_data;
347 dcv->private_data=NULL;
348 offset = dissect_ndr_pointer_cb(
349 tvb, offset, pinfo, tree, di, drep,
350 dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE,
351 "Database", hf_svcctl_database, cb_wstr_postprocess,
352 GINT_TO_POINTER(CB_STR_COL_INFO | 1));
353 dn=(const char *)dcv->private_data;
357 /* OpenSCManager() stores the server\database in se_data */
358 if(!pinfo->fd->flags.visited){
360 dcv->se_data=wmem_strdup_printf(wmem_file_scope(), "%s\\%s",mn,dn);
365 offset = dissect_nt_access_mask(
366 tvb, offset, pinfo, tree, di, drep, hf_svcctl_access_mask,
367 &svcctl_scm_access_mask_info, NULL);
373 svcctl_dissect_OpenSCManagerW_reply(tvbuff_t *tvb, int offset,
374 packet_info *pinfo, proto_tree *tree,
375 dcerpc_info *di, guint8 *drep)
377 dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
378 e_ctx_hnd policy_hnd;
379 proto_item *hnd_item;
384 offset = dissect_nt_policy_hnd(
385 tvb, offset, pinfo, tree, di, drep, hf_svcctl_hnd, &policy_hnd,
386 &hnd_item, TRUE, FALSE);
388 offset = dissect_doserror(
389 tvb, offset, pinfo, tree, di, drep, hf_svcctl_rc, &status);
392 const char *pol_name;
395 pol_name = wmem_strdup_printf(wmem_packet_scope(),
396 "OpenSCManagerW(%s)", (char *)dcv->se_data);
398 pol_name = "Unknown OpenSCManagerW() handle";
400 if(!pinfo->fd->flags.visited){
401 dcerpc_store_polhnd_name(&policy_hnd, pinfo, pol_name);
405 proto_item_append_text(hnd_item, ": %s", pol_name);
412 svcctl_dissect_CreateServiceW_rqst(tvbuff_t *tvb, int offset,
413 packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
416 offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, di, drep,
417 hf_svcctl_hnd, NULL, NULL, FALSE, FALSE);
420 offset = dissect_ndr_cvstring(tvb, offset, pinfo, tree, di, drep,
421 sizeof(guint16), hf_svcctl_service_name, TRUE, NULL);
424 offset = dissect_ndr_pointer_cb(
425 tvb, offset, pinfo, tree, di, drep,
426 dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE,
427 "Display Name", hf_svcctl_display_name, cb_wstr_postprocess,
431 offset = dissect_nt_access_mask(
432 tvb, offset, pinfo, tree, di, drep, hf_svcctl_access_mask,
433 &svcctl_scm_access_mask_info, NULL);
436 offset = svcctl_dissect_dwServiceType_flags(tvb, offset, pinfo, tree, drep, SVC_CREATE_SERVICE_W);
438 /* service start type */
439 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
440 hf_svcctl_service_start_type, NULL);
442 /* service error control */
443 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
444 hf_svcctl_service_error_control, NULL);
446 /* binary path name */
447 offset = dissect_ndr_cvstring(tvb, offset, pinfo, tree, di, drep,
448 sizeof(guint16), hf_svcctl_binarypathname, TRUE, NULL);
450 /* load order group */
451 offset = dissect_ndr_pointer_cb(
452 tvb, offset, pinfo, tree, di, drep,
453 dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE,
454 "Load Order Group", hf_svcctl_loadordergroup, cb_wstr_postprocess,
458 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
459 hf_svcctl_tagid, NULL);
462 offset = dissect_ndr_pointer_cb(
463 tvb, offset, pinfo, tree, di, drep,
464 dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE,
465 "Dependencies", hf_svcctl_dependencies, cb_wstr_postprocess,
469 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
470 hf_svcctl_depend_size, NULL);
472 /* service start name */
473 offset = dissect_ndr_pointer_cb(
474 tvb, offset, pinfo, tree, di, drep,
475 dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE,
476 "Service Start Name", hf_svcctl_service_start_name, cb_wstr_postprocess,
480 offset = dissect_ndr_pointer_cb(
481 tvb, offset, pinfo, tree, di, drep,
482 dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE,
483 "Password", hf_svcctl_password, cb_wstr_postprocess,
487 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
488 hf_svcctl_password_size, NULL);
494 svcctl_dissect_CreateServiceW_reply(tvbuff_t *tvb, int offset,
495 packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
498 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
499 hf_svcctl_tagid, NULL);
502 offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, di, drep,
503 hf_svcctl_hnd, NULL, NULL, FALSE, FALSE);
505 offset = dissect_doserror(
506 tvb, offset, pinfo, tree, di, drep, hf_svcctl_rc, NULL);
513 * IDL BOOL CloseServiceHandle(
514 * IDL [in][out] SC_HANDLE handle
518 svcctl_dissect_CloseServiceHandle_rqst(tvbuff_t *tvb, int offset,
519 packet_info *pinfo, proto_tree *tree,
520 dcerpc_info *di, guint8 *drep)
522 e_ctx_hnd policy_hnd;
527 offset = dissect_nt_policy_hnd(
528 tvb, offset, pinfo, tree, di, drep, hf_svcctl_hnd, &policy_hnd,
531 dcerpc_fetch_polhnd_data(&policy_hnd, &pol_name, NULL, NULL, NULL,
534 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
541 svcctl_dissect_CloseServiceHandle_reply(tvbuff_t *tvb, int offset,
542 packet_info *pinfo, proto_tree *tree,
543 dcerpc_info *di, guint8 *drep)
545 offset = dissect_nt_policy_hnd(
546 tvb, offset, pinfo, tree, di, drep, hf_svcctl_hnd, NULL,
549 offset = dissect_doserror(
550 tvb, offset, pinfo, tree, di, drep, hf_svcctl_rc, NULL);
558 * IDL long LockServiceDatabase(
559 * IDL [in] SC_HANDLE dbhandle,
560 * IDL [out] SC_HANDLE lock,
564 svcctl_dissect_LockServiceDatabase_rqst(tvbuff_t *tvb, int offset,
565 packet_info *pinfo, proto_tree *tree,
566 dcerpc_info *di, guint8 *drep)
568 /* XXX - why is the "is a close" argument TRUE? */
569 offset = dissect_nt_policy_hnd(
570 tvb, offset, pinfo, tree, di, drep, hf_svcctl_hnd, NULL,
576 svcctl_dissect_LockServiceDatabase_reply(tvbuff_t *tvb, int offset,
577 packet_info *pinfo, proto_tree *tree,
578 dcerpc_info *di, guint8 *drep)
580 /* XXX - why is the "is an open" argument TRUE? */
581 offset = dissect_nt_policy_hnd(
582 tvb, offset, pinfo, tree, di, drep, hf_svcctl_lock, NULL,
585 offset = dissect_doserror(
586 tvb, offset, pinfo, tree, di, drep, hf_svcctl_rc, NULL);
594 * IDL long UnlockServiceDatabase(
595 * IDL [in][out] SC_HANDLE lock,
599 svcctl_dissect_UnlockServiceDatabase_rqst(tvbuff_t *tvb, int offset,
600 packet_info *pinfo, proto_tree *tree,
601 dcerpc_info *di, guint8 *drep)
603 /* XXX - why is the "is a close" argument TRUE? */
604 offset = dissect_nt_policy_hnd(
605 tvb, offset, pinfo, tree, di, drep, hf_svcctl_lock, NULL,
611 svcctl_dissect_UnlockServiceDatabase_reply(tvbuff_t *tvb, int offset,
612 packet_info *pinfo, proto_tree *tree,
613 dcerpc_info *di, guint8 *drep)
615 /* XXX - why is the "is an open" argument TRUE? */
616 offset = dissect_nt_policy_hnd(
617 tvb, offset, pinfo, tree, di, drep, hf_svcctl_lock, NULL,
620 offset = dissect_doserror(
621 tvb, offset, pinfo, tree, di, drep, hf_svcctl_rc, NULL);
628 * IDL typedef struct {
629 * IDL long is_locked,
630 * IDL [unique][string] char *lock_owner,
631 * IDL long lock_duration,
635 svcctl_dissect_QUERY_SERVICE_LOCK_STATUS(tvbuff_t *tvb, int offset,
636 packet_info *pinfo, proto_tree *tree,
637 dcerpc_info *di, guint8 *drep)
639 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
640 hf_svcctl_is_locked, NULL);
642 offset = dissect_ndr_pointer(
643 tvb, offset, pinfo, tree, di, drep,
644 dissect_ndr_char_cvstring, NDR_POINTER_UNIQUE,
645 "Owner", hf_svcctl_lock_owner);
647 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
648 hf_svcctl_lock_duration, NULL);
654 * IDL long QueryServiceLockStatus(
655 * IDL [in] SC_HANDLE db_handle,
656 * IDL [in] long buf_size,
657 * IDL [out][ref] QUERY_SERVICE_LOCK_STATUS *status,
658 * IDL [out][ref] long *required_buf_size
662 svcctl_dissect_QueryServiceLockStatus_rqst(tvbuff_t *tvb, int offset,
663 packet_info *pinfo, proto_tree *tree,
664 dcerpc_info *di, guint8 *drep)
666 /* XXX - why is the "is a close" argument TRUE? */
667 offset = dissect_nt_policy_hnd(
668 tvb, offset, pinfo, tree, di, drep, hf_svcctl_hnd, NULL,
671 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
672 hf_svcctl_size, NULL);
677 svcctl_dissect_QueryServiceLockStatus_reply(tvbuff_t *tvb, int offset,
678 packet_info *pinfo, proto_tree *tree,
679 dcerpc_info *di, guint8 *drep)
681 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
682 svcctl_dissect_QUERY_SERVICE_LOCK_STATUS, NDR_POINTER_REF,
685 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
686 hf_svcctl_required_size, NULL);
688 offset = dissect_doserror(
689 tvb, offset, pinfo, tree, di, drep, hf_svcctl_rc, NULL);
695 * IDL long EnumServicesStatus(
696 * IDL [in] SC_HANDLE db_handle,
697 * IDL [in] long type,
698 * IDL [in] long status,
699 * IDL [in] long buf_size,
700 * IDL [in][unique] long *resume_handle,
705 svcctl_dissect_EnumServicesStatus_rqst(tvbuff_t *tvb, int offset,
706 packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
709 offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, di, drep,
710 hf_svcctl_hnd, NULL, NULL, FALSE, FALSE);
713 offset = svcctl_dissect_dwServiceType_flags(tvb, offset, pinfo, tree, drep, SVC_ENUM_SERVICES_STATUS_W);
716 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
717 hf_svcctl_service_state, NULL);
720 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
721 hf_svcctl_size, NULL);
724 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
725 svcctl_dissect_pointer_long, NDR_POINTER_UNIQUE,
726 "Resume Handle", hf_svcctl_resume);
732 svcctl_dissect_OpenServiceW_rqst(tvbuff_t *tvb, int offset,
733 packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
736 offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, di, drep,
737 hf_svcctl_hnd, NULL, NULL, FALSE, FALSE);
740 offset = dissect_ndr_cvstring(tvb, offset, pinfo, tree, di, drep,
741 sizeof(guint16), hf_svcctl_service_name, TRUE, NULL);
744 offset = dissect_nt_access_mask(
745 tvb, offset, pinfo, tree, di, drep, hf_svcctl_access_mask,
746 &svcctl_scm_access_mask_info, NULL);
752 svcctl_dissect_OpenServiceW_reply(tvbuff_t *tvb, int offset,
753 packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
756 offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, di, drep,
757 hf_svcctl_hnd, NULL, NULL, FALSE, FALSE);
759 offset = dissect_doserror(
760 tvb, offset, pinfo, tree, di, drep, hf_svcctl_rc, NULL);
766 svcctl_dissect_QueryServiceConfigW_rqst(tvbuff_t *tvb, int offset,
767 packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
770 offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, di, drep,
771 hf_svcctl_hnd, NULL, NULL, FALSE, FALSE);
774 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
775 hf_svcctl_buffer, NULL);
780 static dcerpc_sub_dissector dcerpc_svcctl_dissectors[] = {
781 { SVC_CLOSE_SERVICE_HANDLE, "CloseServiceHandle",
782 svcctl_dissect_CloseServiceHandle_rqst,
783 svcctl_dissect_CloseServiceHandle_reply },
784 { SVC_CONTROL_SERVICE, "ControlService", NULL, NULL },
785 { SVC_DELETE_SERVICE, "DeleteService", NULL, NULL },
786 { SVC_LOCK_SERVICE_DATABASE, "LockServiceDatabase",
787 svcctl_dissect_LockServiceDatabase_rqst,
788 svcctl_dissect_LockServiceDatabase_reply },
789 { SVC_QUERY_SERVICE_OBJECT_SECURITY, "QueryServiceObjectSecurity",
791 { SVC_SET_SERVICE_OBJECT_SECURITY, "SetServiceObjectSecurity",
793 { SVC_QUERY_SERVICE_STATUS, "QueryServiceStatus",
795 { SVC_SET_SERVICE_STATUS, "SetServiceStatus",
797 { SVC_UNLOCK_SERVICE_DATABASE, "UnlockServiceDatabase",
798 svcctl_dissect_UnlockServiceDatabase_rqst,
799 svcctl_dissect_UnlockServiceDatabase_reply },
800 { SVC_NOTIFY_BOOT_CONFIG_STATUS, "NotifyBootConfigStatus",
802 { SVC_SC_SET_SERVICE_BITS_W, "ScSetServiceBitsW",
804 { SVC_CHANGE_SERVICE_CONFIG_W, "ChangeServiceConfigW",
806 { SVC_CREATE_SERVICE_W, "CreateServiceW",
807 svcctl_dissect_CreateServiceW_rqst,
808 svcctl_dissect_CreateServiceW_reply },
809 { SVC_ENUM_DEPENDENT_SERVICES_W, "EnumDependentServicesW",
811 { SVC_ENUM_SERVICES_STATUS_W, "EnumServicesStatusW",
812 svcctl_dissect_EnumServicesStatus_rqst, NULL },
813 { SVC_OPEN_SC_MANAGER_W, "OpenSCManagerW",
814 svcctl_dissect_OpenSCManagerW_rqst,
815 svcctl_dissect_OpenSCManagerW_reply },
816 { SVC_OPEN_SERVICE_W, "OpenServiceW",
817 svcctl_dissect_OpenServiceW_rqst,
818 svcctl_dissect_OpenServiceW_reply },
819 { SVC_QUERY_SERVICE_CONFIG_W, "QueryServiceConfigW",
820 svcctl_dissect_QueryServiceConfigW_rqst, NULL },
821 { SVC_QUERY_SERVICE_LOCK_STATUS_W, "QueryServiceLockStatusW",
823 { SVC_START_SERVICE_W, "StartServiceW", NULL, NULL },
824 { SVC_GET_SERVICE_DISPLAY_NAME_W, "GetServiceDisplayNameW",
826 { SVC_GET_SERVICE_KEY_NAME_W, "GetServiceKeyNameW", NULL, NULL },
827 { SVC_SC_SET_SERVICE_BITS_A, "ScSetServiceBitsA", NULL, NULL },
828 { SVC_CHANGE_SERVICE_CONFIG_A, "ChangeServiceConfigA", NULL, NULL },
829 { SVC_CREATE_SERVICE_A, "CreateServiceA", NULL, NULL },
830 { SVC_ENUM_DEPENDENT_SERVICES_A, "EnumDependentServicesA",
832 { SVC_ENUM_SERVICES_STATUS_A, "EnumServicesStatusA",
833 svcctl_dissect_EnumServicesStatus_rqst,
835 { SVC_OPEN_SC_MANAGER_A, "OpenSCManagerA",
836 svcctl_dissect_OpenSCManager_rqst,
837 svcctl_dissect_OpenSCManager_reply },
838 { SVC_OPEN_SERVICE_A, "OpenServiceA", NULL, NULL },
839 { SVC_QUERY_SERVICE_CONFIG_A, "QueryServiceConfigA", NULL, NULL },
840 { SVC_QUERY_SERVICE_LOCK_STATUS_A, "QueryServiceLockStatusA",
841 svcctl_dissect_QueryServiceLockStatus_rqst,
842 svcctl_dissect_QueryServiceLockStatus_reply },
843 { SVC_START_SERVICE_A, "StartServiceA", NULL, NULL },
844 { SVC_GET_SERVICE_DISPLAY_NAME_A, "GetServiceDisplayNameA",
846 { SVC_GET_SERVICE_KEY_NAME_A, "GetServiceKeyNameA", NULL, NULL },
847 { SVC_SC_GET_CURRENT_GROUPE_STATE_W, "ScGetCurrentGroupStateW",
849 { SVC_ENUM_SERVICE_GROUP_W, "EnumServiceGroupW",
851 { SVC_CHANGE_SERVICE_CONFIG2_A, "ChangeServiceConfig2A",
853 { SVC_CHANGE_SERVICE_CONFIG2_W, "ChangeServiceConfig2W",
855 { SVC_QUERY_SERVICE_CONFIG2_A, "QueryServiceConfig2A",
857 { SVC_QUERY_SERVICE_CONFIG2_W, "QueryServiceConfig2W",
859 { SVC_QUERY_SERVICE_STATUS_EX, "QueryServiceStatusEx",
861 { SVC_ENUM_SERVICES_STATUS_EX_A, "EnumServicesStatusExA",
863 { SVC_ENUM_SERVICES_STATUS_EX_W, "EnumServicesStatusExW",
865 { SVC_SC_SEND_TS_MESSAGE, "ScSendTSMessage",
867 {0, NULL, NULL, NULL}
871 proto_register_dcerpc_svcctl(void)
873 static hf_register_info hf[] = {
875 { "Operation", "svcctl.opnum", FT_UINT16, BASE_DEC,
876 NULL, 0x0, NULL, HFILL }},
877 { &hf_svcctl_machinename,
878 { "MachineName", "svcctl.machinename", FT_STRING, BASE_NONE,
879 NULL, 0x0, "Name of the host we want to open the database on", HFILL }},
880 { &hf_svcctl_database,
881 { "Database", "svcctl.database", FT_STRING, BASE_NONE,
882 NULL, 0x0, "Name of the database to open", HFILL }},
883 { &hf_svcctl_access_mask,
884 { "Access Mask", "svcctl.access_mask", FT_UINT32, BASE_HEX,
885 NULL, 0x0, "SVCCTL Access Mask", HFILL }},
886 { &hf_svcctl_scm_rights_connect,
887 { "Connect", "svcctl.scm_rights_connect", FT_BOOLEAN, 32,
888 TFS(&tfs_set_notset), 0x00000001, "SVCCTL Rights to connect to SCM", HFILL }},
889 { &hf_svcctl_scm_rights_create_service,
890 { "Create Service", "svcctl.scm_rights_create_service", FT_BOOLEAN, 32,
891 TFS(&tfs_set_notset), 0x00000002, "SVCCTL Rights to create services", HFILL }},
892 { &hf_svcctl_scm_rights_enumerate_service,
893 { "Enumerate Service", "svcctl.scm_rights_enumerate_service", FT_BOOLEAN, 32,
894 TFS(&tfs_set_notset), 0x00000004, "SVCCTL Rights to enumerate services", HFILL }},
895 { &hf_svcctl_scm_rights_lock,
896 { "Lock", "svcctl.scm_rights_lock", FT_BOOLEAN, 32,
897 TFS(&tfs_set_notset), 0x00000008, "SVCCTL Rights to lock database", HFILL }},
898 { &hf_svcctl_scm_rights_query_lock_status,
899 { "Query Lock Status", "svcctl.scm_rights_query_lock_status", FT_BOOLEAN, 32,
900 TFS(&tfs_set_notset), 0x00000010, "SVCCTL Rights to query database lock status", HFILL }},
901 { &hf_svcctl_scm_rights_modify_boot_config,
902 { "Modify Boot Config", "svcctl.scm_rights_modify_boot_config", FT_BOOLEAN, 32,
903 TFS(&tfs_set_notset), 0x00000020, "SVCCTL Rights to modify boot config", HFILL }},
905 { "Context Handle", "svcctl.hnd", FT_BYTES, BASE_NONE,
906 NULL, 0x0, "SVCCTL Context handle", HFILL }},
908 { "Lock", "svcctl.lock", FT_BYTES, BASE_NONE,
909 NULL, 0x0, "SVCCTL Database Lock", HFILL }},
911 { "Return code", "svcctl.rc", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
912 &DOS_errors_ext, 0x0, "SVCCTL return code", HFILL }},
914 { "Size", "svcctl.size", FT_UINT32, BASE_DEC,
915 NULL, 0x0, "SVCCTL size of buffer", HFILL }},
916 { &hf_svcctl_required_size,
917 { "Required Size", "svcctl.required_size", FT_UINT32, BASE_DEC,
918 NULL, 0x0, "SVCCTL required size of buffer for data to fit", HFILL }},
919 { &hf_svcctl_is_locked,
920 { "IsLocked", "svcctl.is_locked", FT_UINT32, BASE_DEC,
921 NULL, 0x0, "SVCCTL whether the database is locked or not", HFILL }},
922 { &hf_svcctl_lock_duration,
923 { "Duration", "svcctl.lock_duration", FT_UINT32, BASE_DEC,
924 NULL, 0x0, "SVCCTL number of seconds the database has been locked", HFILL }},
925 { &hf_svcctl_lock_owner,
926 { "Owner", "svcctl.lock_owner", FT_STRING, BASE_NONE,
927 NULL, 0x0, "SVCCTL the user that holds the database lock", HFILL }},
928 { &hf_svcctl_service_type,
929 { "Service Type", "svcctl.service_type", FT_UINT32, BASE_HEX,
930 NULL, 0x0, "SVCCTL type of service", HFILL }},
931 { &hf_svcctl_service_type_kernel_driver,
932 { "Kernel Driver Service", "svcctl.service_type.kernel", FT_BOOLEAN, 32,
933 TFS(&tfs_svcctl_service_type_kernel_driver), SVCCTL_SERVICE_TYPE_KERNEL_DRIVER, "Request includes kernel driver services?", HFILL }},
934 { &hf_svcctl_service_type_fs_driver,
935 { "File System Driver Service", "svcctl.service_type.fs", FT_BOOLEAN, 32,
936 TFS(&tfs_svcctl_service_type_fs_driver), SVCCTL_SERVICE_TYPE_FILE_SYSTEM_DRIVER, "Request includes file system driver services?", HFILL }},
937 { &hf_svcctl_service_type_win32_own_process,
938 { "Self Process Service", "svcctl.service_type.win32_own", FT_BOOLEAN, 32,
939 TFS(&tfs_svcctl_service_type_win32_own_process), SVCCTL_SERVICE_TYPE_WIN32_OWN_PROCESS, "Request includes services that run their own process?", HFILL }},
940 { &hf_svcctl_service_type_win32_share_process,
941 { "Shared Process Service", "svcctl.service_type.win32_shared", FT_BOOLEAN, 32,
942 TFS(&tfs_svcctl_service_type_win32_share_process), SVCCTL_SERVICE_TYPE_WIN32_SHARE_PROCESS, "Request includes services that share their process?", HFILL }},
943 { &hf_svcctl_service_type_interactive_process,
944 { "Interactive Process Service", "svcctl.service_type.interactive", FT_BOOLEAN, 32,
945 TFS(&tfs_svcctl_service_type_interactive_process), SVCCTL_SERVICE_TYPE_INTERACTIVE_PROCESS, "Request includes services that can interact with the desktop?", HFILL }},
946 { &hf_svcctl_service_state,
947 { "Service State", "svcctl.service_state", FT_UINT32, BASE_DEC,
948 VALS(svcctl_service_status_vals), 0x0, "SVCCTL service state", HFILL }},
950 { "Buffer", "svcctl.buffer", FT_UINT32, BASE_DEC,
951 NULL, 0x0, "SVCCTL buffer", HFILL }},
953 { &hf_svcctl_bytes_needed,
954 { "Bytes Needed", "svcctl.bytes_needed", FT_UINT32, BASE_DEC,
955 NULL, 0x0, "SVCCTL bytes needed", HFILL }},
956 { &hf_svcctl_services_returned,
957 { "Services Returned", "svcctl.services_returned", FT_UINT32, BASE_DEC,
958 NULL, 0x0, "SVCCTL services returned", HFILL }},
960 { &hf_svcctl_service_name,
961 { "Service Name", "svcctl.servicename", FT_STRING, BASE_NONE,
962 NULL, 0x0, "SVCCTL name of service", HFILL }},
963 { &hf_svcctl_display_name,
964 { "Display Name", "svcctl.displayname", FT_STRING, BASE_NONE,
965 NULL, 0x0, "SVCCTL display name", HFILL }},
966 { &hf_svcctl_service_start_type,
967 { "Service Start Type", "svcctl.service_start_type", FT_UINT32, BASE_DEC,
968 VALS(svcctl_service_start_type_vals), 0x0, "SVCCTL service start type", HFILL }},
969 { &hf_svcctl_service_error_control,
970 { "Service Error Control", "svcctl.service_error_control", FT_UINT32, BASE_DEC,
971 VALS(svcctl_service_error_control_vals), 0x0, "SVCCTL service error control", HFILL }},
972 { &hf_svcctl_binarypathname,
973 { "Binary Path Name", "svcctl.binarypathname", FT_STRING, BASE_NONE,
974 NULL, 0x0, "SVCCTL binary path name", HFILL }},
975 { &hf_svcctl_loadordergroup,
976 { "Load Order Group", "svcctl.loadordergroup", FT_STRING, BASE_NONE,
977 NULL, 0x0, "SVCCTL load order group", HFILL }},
979 { "Tag Id", "svcctl.tagid", FT_UINT32, BASE_DEC,
980 NULL, 0x0, "SVCCTL tag id", HFILL }},
981 { &hf_svcctl_dependencies,
982 { "Dependencies", "svcctl.dependencies", FT_STRING, BASE_NONE,
983 NULL, 0x0, "SVCCTL dependencies", HFILL }},
984 { &hf_svcctl_depend_size,
985 { "Depend Size", "svcctl.depend_size", FT_UINT32, BASE_DEC,
986 NULL, 0x0, "SVCCTL depend size", HFILL }},
987 { &hf_svcctl_service_start_name,
988 { "Service Start Name", "svcctl.service_start_name", FT_STRING, BASE_NONE,
989 NULL, 0x0, "SVCCTL service start name", HFILL }},
990 { &hf_svcctl_password,
991 { "Password", "svcctl.password", FT_STRING, BASE_NONE,
992 NULL, 0x0, "SVCCTL password", HFILL }},
993 { &hf_svcctl_password_size,
994 { "Password Size", "svcctl.password_size", FT_UINT32, BASE_DEC,
995 NULL, 0x0, "SVCCTL password size", HFILL }},
997 { "Resume Handle", "svcctl.resume", FT_UINT32, BASE_DEC,
998 NULL, 0x0, "SVCCTL resume handle", HFILL }},
1001 static gint *ett[] = {
1003 &ett_dcerpc_svcctl_service_type_bits,
1006 proto_dcerpc_svcctl = proto_register_protocol(
1007 "Microsoft Service Control", "SVCCTL", "svcctl");
1009 proto_register_field_array(proto_dcerpc_svcctl, hf, array_length(hf));
1010 proto_register_subtree_array(ett, array_length(ett));
1014 proto_reg_handoff_dcerpc_svcctl(void)
1016 /* Register protocol as dcerpc */
1018 dcerpc_init_uuid(proto_dcerpc_svcctl, ett_dcerpc_svcctl,
1019 &uuid_dcerpc_svcctl, ver_dcerpc_svcctl,
1020 dcerpc_svcctl_dissectors, hf_svcctl_opnum);