1 /* packet-smb-sidsnooping.c
2 * Routines for snooping SID to name mappings
3 * Copyright 2003, Ronnie Sahlberg
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.
30 #include <epan/packet_info.h>
31 #include <epan/epan_dissect.h>
32 #include <epan/proto.h>
34 #include <epan/emem.h>
35 #include <epan/strutil.h>
36 #include "packet-dcerpc.h"
37 #include "packet-dcerpc-nt.h"
39 #include <epan/dissectors/packet-smb.h>
40 #include "packet-smb-sidsnooping.h"
43 static int hf_lsa
= -1;
44 static int hf_lsa_opnum
= -1;
46 static int hf_lsa_info_level
= -1;
47 static int hf_lsa_domain
= -1;
48 static int hf_nt_domain_sid
= -1;
49 static int hf_samr_hnd
= -1;
50 static int hf_samr_rid
= -1;
51 static int hf_samr_acct_name
= -1;
52 static int hf_samr_level
= -1;
55 GHashTable
*sid_name_table
= NULL
;
58 static GHashTable
*ctx_handle_table
= NULL
;
61 static gboolean lsa_policy_information_tap_installed
= FALSE
;
62 static gboolean samr_query_dispinfo_tap_installed
= FALSE
;
66 find_sid_name(const char *sid
)
71 old_sn
.sid
=(char*)sid
;
72 sn
=(sid_name
*)g_hash_table_lookup(sid_name_table
, &old_sn
);
80 add_sid_name_mapping(char *sid
, char *name
)
86 sn
=(sid_name
*)g_hash_table_lookup(sid_name_table
, &old_sn
);
91 sn
=wmem_new(wmem_file_scope(), sid_name
);
92 sn
->sid
=g_strdup(sid
);
93 sn
->name
=g_strdup(name
);
94 g_hash_table_insert(sid_name_table
, sn
, sn
);
101 * level 1 : user displayinfo 1
104 samr_query_dispinfo(void *dummy _U_
, packet_info
*pinfo
, epan_dissect_t
*edt
, const void *pri
)
106 const dcerpc_info
*ri
=(const dcerpc_info
*)pri
;
119 char sid_name_str
[256];
122 gp
=proto_get_finfo_ptr_array(edt
->tree
, hf_samr_level
);
123 if(!gp
|| gp
->len
!=1){
126 fi
=(field_info
*)gp
->pdata
[0];
127 info_level
=fi
->value
.value
.sinteger
;
139 if(ri
->ptype
== PDU_REQ
){
140 gp
=proto_get_finfo_ptr_array(edt
->tree
, hf_samr_hnd
);
141 if(!gp
|| gp
->len
!=1){
144 fi
=(field_info
*)gp
->pdata
[0];
146 old_ctx
=g_hash_table_lookup(ctx_handle_table
, GINT_TO_POINTER(pinfo
->fd
->num
));
148 g_hash_table_remove(ctx_handle_table
, GINT_TO_POINTER(pinfo
->fd
->num
));
151 old_ctx
=wmem_memdup(wmem_file_scope(), fi
->value
.value
.bytes
->data
, 20);
153 g_hash_table_insert(ctx_handle_table
, GINT_TO_POINTER(pinfo
->fd
->num
), old_ctx
);
158 if(!ri
->call_data
->req_frame
){
162 old_ctx
=g_hash_table_lookup(ctx_handle_table
, GINT_TO_POINTER(ri
->call_data
->req_frame
));
167 if (!dcerpc_fetch_polhnd_data((e_ctx_hnd
*)old_ctx
, &pol_name
, NULL
, NULL
, NULL
, ri
->call_data
->req_frame
)) {
174 sid
=strstr(pol_name
,"S-1-5");
179 for(sid_len
=4;1;sid_len
++){
180 if((sid
[sid_len
]>='0') && (sid
[sid_len
]<='9')){
183 if(sid
[sid_len
]=='-'){
189 gp_rids
=proto_get_finfo_ptr_array(edt
->tree
, hf_samr_rid
);
190 if(!gp_rids
|| gp_rids
->len
<1){
193 num_rids
=gp_rids
->len
;
194 gp_names
=proto_get_finfo_ptr_array(edt
->tree
, hf_samr_acct_name
);
195 if(!gp_names
|| gp_names
->len
<1){
198 num_names
=gp_names
->len
;
200 if(num_rids
>num_names
){
204 for(;num_rids
;num_rids
--){
209 fi_rid
=(field_info
*)gp_rids
->pdata
[num_rids
-1];
210 fi_name
=(field_info
*)gp_names
->pdata
[num_rids
-1];
211 g_strlcpy(sid_name_str
, sid
, 256);
212 sid_name_str
[len
++]='-';
213 g_snprintf(sid_name_str
+len
, 256-len
, "%d",fi_rid
->value
.value
.sinteger
);
214 add_sid_name_mapping(sid_name_str
, fi_name
->value
.value
.string
);
220 * PolicyInformation :
221 * level 3 : PRIMARY_DOMAIN_INFO lsa.domain_sid -> lsa.domain
222 * level 5 : ACCOUNT_DOMAIN_INFO lsa.domain_sid -> lsa.domain
223 * level 12 : DNS_DOMAIN_INFO lsa.domain_sid -> lsa.domain
226 lsa_policy_information(void *dummy _U_
, packet_info
*pinfo _U_
, epan_dissect_t
*edt
, const void *pri _U_
)
234 gp
=proto_get_finfo_ptr_array(edt
->tree
, hf_lsa_info_level
);
235 if(!gp
|| gp
->len
!=1){
238 fi
=(field_info
*)gp
->pdata
[0];
239 info_level
=fi
->value
.value
.sinteger
;
245 gp
=proto_get_finfo_ptr_array(edt
->tree
, hf_lsa_domain
);
246 if(!gp
|| gp
->len
!=1){
249 fi
=(field_info
*)gp
->pdata
[0];
250 domain
=fi
->value
.value
.string
;
252 gp
=proto_get_finfo_ptr_array(edt
->tree
, hf_nt_domain_sid
);
253 if(!gp
|| gp
->len
!=1){
256 fi
=(field_info
*)gp
->pdata
[0];
257 sid
=fi
->value
.value
.string
;
259 add_sid_name_mapping(sid
, domain
);
266 free_all_sid_names(gpointer key_arg
, gpointer value _U_
, gpointer user_data _U_
)
268 sid_name
*sn
= (sid_name
*)key_arg
;
271 g_free((gpointer
)sn
->sid
);
275 g_free((gpointer
)sn
->name
);
282 sid_name_equal(gconstpointer k1
, gconstpointer k2
)
284 const sid_name
*sn1
= (const sid_name
*)k1
;
285 const sid_name
*sn2
= (const sid_name
*)k2
;
287 return !strcmp(sn1
->sid
, sn2
->sid
);
291 sid_name_hash(gconstpointer k
)
293 const sid_name
*sn
= (const sid_name
*)k
;
296 for(sum
=0,i
=(int)strlen(sn
->sid
)-1;i
>=0;i
--){
305 free_all_ctx_handle(gpointer key_arg _U_
, gpointer value _U_
, gpointer user_data _U_
)
310 ctx_handle_equal(gconstpointer k1
, gconstpointer k2
)
312 int sn1
= GPOINTER_TO_INT(k1
);
313 int sn2
= GPOINTER_TO_INT(k2
);
319 ctx_handle_hash(gconstpointer k
)
321 int sn
= GPOINTER_TO_INT(k
);
328 sid_snooping_init(void)
330 GString
*error_string
;
332 if(lsa_policy_information_tap_installed
){
333 remove_tap_listener(&lsa_policy_information_tap_installed
);
334 lsa_policy_information_tap_installed
=FALSE
;
336 if(samr_query_dispinfo_tap_installed
){
337 remove_tap_listener(&samr_query_dispinfo_tap_installed
);
338 samr_query_dispinfo_tap_installed
=FALSE
;
342 g_hash_table_foreach_remove(sid_name_table
, free_all_sid_names
, NULL
);
345 if(ctx_handle_table
){
346 g_hash_table_foreach_remove(ctx_handle_table
, free_all_ctx_handle
, NULL
);
347 ctx_handle_table
=NULL
;
351 /* this code needs to be rewritten from scratch
352 disabling it now so that it wont cause wireshark to abort due to
357 if(!sid_name_snooping
){
361 sid_name_table
=g_hash_table_new(sid_name_hash
, sid_name_equal
);
364 ctx_handle_table
=g_hash_table_new(ctx_handle_hash
, ctx_handle_equal
);
368 hf_lsa
= proto_get_id_by_filter_name("lsa");
369 hf_lsa_opnum
= proto_registrar_get_id_byname("lsa.opnum");
371 hf_nt_domain_sid
= proto_registrar_get_id_byname("nt.domain_sid");
372 hf_lsa_domain
= proto_registrar_get_id_byname("lsa.domain");
373 hf_lsa_info_level
= proto_registrar_get_id_byname("lsa.info.level");
374 hf_samr_hnd
= proto_registrar_get_id_byname("samr.handle");
375 hf_samr_rid
= proto_registrar_get_id_byname("samr.rid");
376 hf_samr_acct_name
= proto_registrar_get_id_byname("samr.acct_name");
377 hf_samr_level
= proto_registrar_get_id_byname("samr.level");
380 error_string
=register_tap_listener("dcerpc",
381 &lsa_policy_information_tap_installed
,
382 "lsa.policy_information and ( lsa.info.level or lsa.domain or nt.domain_sid )",
383 TL_REQUIRES_PROTO_TREE
, NULL
, lsa_policy_information
, NULL
);
385 /* error, we failed to attach to the tap. clean up */
387 fprintf(stderr
, "tshark: Couldn't register proto_reg_handoff_smb_sidsnooping()/lsa_policy_information tap: %s\n",
389 g_string_free(error_string
, TRUE
);
392 lsa_policy_information_tap_installed
=TRUE
;
394 error_string
=register_tap_listener("dcerpc",
395 &samr_query_dispinfo_tap_installed
,
396 "samr and samr.opnum==40 and ( samr.handle or samr.rid or samr.acct_name or samr.level )",
397 TL_REQUIRES_PROTO_TREE
, NULL
, samr_query_dispinfo
, NULL
);
399 /* error, we failed to attach to the tap. clean up */
401 fprintf(stderr
, "tshark: Couldn't register proto_reg_handoff_smb_sidsnooping()/samr_query_dispinfo tap: %s\n",
403 g_string_free(error_string
, TRUE
);
406 samr_query_dispinfo_tap_installed
=TRUE
;
410 proto_register_smb_sidsnooping(void)
412 register_init_routine(sid_snooping_init
);
416 proto_reg_handoff_smb_sidsnooping(void)