epan/dissectors/pidl/samr/samr.cnf cnf_dissect_lsa_BinaryString => lsarpc_dissect_str...
[wireshark-sm.git] / epan / dissectors / packet-smb-sidsnooping.c
blob4fac527f323424476ef884342d4f11d4e77f2d70
1 /* packet-smb-sidsnooping.c
2 * Routines for snooping SID to name mappings
3 * Copyright 2003, Ronnie Sahlberg
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 #include "config.h"
14 #include <epan/packet.h>
15 #include <epan/epan_dissect.h>
16 #include <epan/tap.h>
17 #include <wsutil/report_message.h>
18 #include "packet-dcerpc.h"
19 #include "packet-dcerpc-nt.h"
20 #include "packet-smb.h"
21 #include "packet-smb-sidsnooping.h"
23 void proto_register_smb_sidsnooping(void);
25 #if 0
26 static int hf_lsa;
27 static int hf_lsa_opnum;
28 #endif
29 static int hf_lsa_info_level;
30 static int hf_lsa_domain;
31 static int hf_nt_domain_sid;
32 static int hf_samr_hnd;
33 static int hf_samr_rid;
34 static int hf_samr_acct_name;
35 static int hf_samr_level;
38 GHashTable *sid_name_table;
41 static GHashTable *ctx_handle_table;
44 static bool lsa_policy_information_tap_installed;
45 static bool samr_query_dispinfo_tap_installed;
48 const char *
49 find_sid_name(const char *sid)
51 return (const char *)g_hash_table_lookup(sid_name_table, sid);
54 static void
55 add_sid_name_mapping(const char *sid, const char *name)
57 if (find_sid_name(sid)) {
58 return;
61 g_hash_table_insert(sid_name_table, g_strdup(sid), g_strdup(name));
67 * QueryDispInfo :
68 * level 1 : user displayinfo 1
70 static tap_packet_status
71 samr_query_dispinfo(void *dummy _U_, packet_info *pinfo, epan_dissect_t *edt, const void *pri, tap_flags_t flags _U_)
73 const dcerpc_info *ri=(const dcerpc_info *)pri;
74 void *old_ctx=NULL;
75 char *pol_name;
76 char *sid;
77 int sid_len;
78 int num_rids;
79 int num_names;
80 GPtrArray *gp;
81 GPtrArray *gp_rids;
82 GPtrArray *gp_names;
83 field_info *fi;
84 field_info *fi_rid;
85 field_info *fi_name;
86 char sid_name_str[256];
87 int info_level;
89 gp=proto_get_finfo_ptr_array(edt->tree, hf_samr_level);
90 if(!gp || gp->len!=1){
91 return TAP_PACKET_DONT_REDRAW;
93 fi=(field_info *)gp->pdata[0];
94 info_level = fvalue_get_sinteger(fi->value);
96 if(info_level!=1){
97 return TAP_PACKET_DONT_REDRAW;
100 if(!ri){
101 return TAP_PACKET_DONT_REDRAW;
103 if(!ri->call_data){
104 return TAP_PACKET_DONT_REDRAW;
106 if(ri->ptype == PDU_REQ){
107 gp=proto_get_finfo_ptr_array(edt->tree, hf_samr_hnd);
108 if(!gp || gp->len!=1){
109 return TAP_PACKET_DONT_REDRAW;
111 fi=(field_info *)gp->pdata[0];
113 old_ctx=g_hash_table_lookup(ctx_handle_table, GINT_TO_POINTER(pinfo->num));
114 if(old_ctx){
115 g_hash_table_remove(ctx_handle_table, GINT_TO_POINTER(pinfo->num));
117 if(!old_ctx){
118 old_ctx=wmem_memdup(wmem_file_scope(), fvalue_get_bytes_data(fi->value), 20);
120 g_hash_table_insert(ctx_handle_table, GINT_TO_POINTER(pinfo->num), old_ctx);
122 return TAP_PACKET_DONT_REDRAW;
125 if(!ri->call_data->req_frame){
126 return TAP_PACKET_DONT_REDRAW;
129 old_ctx=g_hash_table_lookup(ctx_handle_table, GINT_TO_POINTER(ri->call_data->req_frame));
130 if(!old_ctx){
131 return TAP_PACKET_DONT_REDRAW;
134 if (!dcerpc_fetch_polhnd_data((e_ctx_hnd *)old_ctx, &pol_name, NULL, NULL, NULL, ri->call_data->req_frame)) {
135 return TAP_PACKET_DONT_REDRAW;
138 if (!pol_name)
139 return TAP_PACKET_DONT_REDRAW;
141 sid=strstr(pol_name,"S-1-5");
142 if(!sid){
143 return TAP_PACKET_DONT_REDRAW;
146 for(sid_len=4;1;sid_len++){
147 if((sid[sid_len]>='0') && (sid[sid_len]<='9')){
148 continue;
150 if(sid[sid_len]=='-'){
151 continue;
153 break;
156 gp_rids=proto_get_finfo_ptr_array(edt->tree, hf_samr_rid);
157 if(!gp_rids || gp_rids->len<1){
158 return TAP_PACKET_DONT_REDRAW;
160 num_rids=gp_rids->len;
161 gp_names=proto_get_finfo_ptr_array(edt->tree, hf_samr_acct_name);
162 if(!gp_names || gp_names->len<1){
163 return TAP_PACKET_DONT_REDRAW;
165 num_names=gp_names->len;
167 if(num_rids>num_names){
168 num_rids=num_names;
171 for(;num_rids;num_rids--){
172 int len=sid_len;
173 if (len > 247)
174 len = 247;
176 fi_rid=(field_info *)gp_rids->pdata[num_rids-1];
177 fi_name=(field_info *)gp_names->pdata[num_rids-1];
178 (void) g_strlcpy(sid_name_str, sid, 256);
179 sid_name_str[len++]='-';
180 snprintf(sid_name_str+len, 256-len, "%d", fvalue_get_sinteger(fi_rid->value));
181 add_sid_name_mapping(sid_name_str, fvalue_get_string(fi_name->value));
183 return TAP_PACKET_REDRAW;
187 * PolicyInformation :
188 * level 3 : PRIMARY_DOMAIN_INFO lsa.domain_sid -> lsa.domain
189 * level 5 : ACCOUNT_DOMAIN_INFO lsa.domain_sid -> lsa.domain
190 * level 12 : DNS_DOMAIN_INFO lsa.domain_sid -> lsa.domain
192 static tap_packet_status
193 lsa_policy_information(void *dummy _U_, packet_info *pinfo _U_, epan_dissect_t *edt, const void *pri _U_, tap_flags_t flags _U_)
195 GPtrArray *gp;
196 field_info *fi;
197 const char *domain;
198 const char *sid;
199 int info_level;
201 gp=proto_get_finfo_ptr_array(edt->tree, hf_lsa_info_level);
202 if(!gp || gp->len!=1){
203 return TAP_PACKET_DONT_REDRAW;
205 fi=(field_info *)gp->pdata[0];
206 info_level = fvalue_get_sinteger(fi->value);
208 switch(info_level){
209 case 3:
210 case 5:
211 case 12:
212 gp=proto_get_finfo_ptr_array(edt->tree, hf_lsa_domain);
213 if(!gp || gp->len!=1){
214 return TAP_PACKET_DONT_REDRAW;
216 fi=(field_info *)gp->pdata[0];
217 domain=fvalue_get_string(fi->value);
219 gp=proto_get_finfo_ptr_array(edt->tree, hf_nt_domain_sid);
220 if(!gp || gp->len!=1){
221 return TAP_PACKET_DONT_REDRAW;
223 fi=(field_info *)gp->pdata[0];
224 sid=fvalue_get_string(fi->value);
226 add_sid_name_mapping(sid, domain);
227 break;
229 return TAP_PACKET_DONT_REDRAW;
233 static int
234 ctx_handle_equal(const void *k1, const void *k2)
236 int sn1 = GPOINTER_TO_INT(k1);
237 int sn2 = GPOINTER_TO_INT(k2);
239 return sn1==sn2;
242 static unsigned
243 ctx_handle_hash(const void *k)
245 int sn = GPOINTER_TO_INT(k);
247 return sn;
251 static void
252 sid_snooping_init(void)
254 GString *error_string;
256 if(lsa_policy_information_tap_installed){
257 remove_tap_listener(&lsa_policy_information_tap_installed);
258 lsa_policy_information_tap_installed=false;
260 if(samr_query_dispinfo_tap_installed){
261 remove_tap_listener(&samr_query_dispinfo_tap_installed);
262 samr_query_dispinfo_tap_installed=false;
265 sid_name_table = g_hash_table_new_full(g_str_hash, g_str_equal,
266 g_free, g_free);
267 ctx_handle_table = g_hash_table_new(ctx_handle_hash, ctx_handle_equal);
268 /* TODO this code needs to be rewritten from scratch
269 disabling it now so that it won't cause wireshark to abort due to
270 unknown hf fields
272 sid_name_snooping=false;
274 if(!sid_name_snooping){
275 return;
280 #if 0
281 hf_lsa = proto_get_id_by_filter_name("lsa");
282 hf_lsa_opnum = proto_registrar_get_id_byname("lsa.opnum");
283 #endif
284 hf_nt_domain_sid = proto_registrar_get_id_byname("nt.domain_sid");
285 hf_lsa_domain = proto_registrar_get_id_byname("lsa.domain");
286 hf_lsa_info_level = proto_registrar_get_id_byname("lsa.info.level");
287 hf_samr_hnd = proto_registrar_get_id_byname("samr.handle");
288 hf_samr_rid = proto_registrar_get_id_byname("samr.rid");
289 hf_samr_acct_name = proto_registrar_get_id_byname("samr.acct_name");
290 hf_samr_level = proto_registrar_get_id_byname("samr.level");
293 error_string=register_tap_listener("dcerpc",
294 &lsa_policy_information_tap_installed,
295 "lsa.policy_information and ( lsa.info.level or lsa.domain or nt.domain_sid )",
296 TL_REQUIRES_PROTO_TREE, NULL, lsa_policy_information, NULL, NULL);
297 if(error_string){
298 /* error, we failed to attach to the tap. clean up */
300 report_failure( "Couldn't register proto_reg_handoff_smb_sidsnooping()/lsa_policy_information tap: %s\n",
301 error_string->str);
302 g_string_free(error_string, true);
303 return;
305 lsa_policy_information_tap_installed=true;
307 error_string=register_tap_listener("dcerpc",
308 &samr_query_dispinfo_tap_installed,
309 "samr and samr.opnum==40 and ( samr.handle or samr.rid or samr.acct_name or samr.level )",
310 TL_REQUIRES_PROTO_TREE, NULL, samr_query_dispinfo, NULL, NULL);
311 if(error_string){
312 /* error, we failed to attach to the tap. clean up */
314 report_failure( "Couldn't register proto_reg_handoff_smb_sidsnooping()/samr_query_dispinfo tap: %s\n",
315 error_string->str);
316 g_string_free(error_string, true);
317 return;
319 samr_query_dispinfo_tap_installed=true;
322 static void
323 sid_snooping_cleanup(void)
325 g_hash_table_destroy(sid_name_table);
326 g_hash_table_destroy(ctx_handle_table);
329 void
330 proto_register_smb_sidsnooping(void)
332 register_init_routine(sid_snooping_init);
333 register_cleanup_routine(sid_snooping_cleanup);
337 * Editor modelines - https://www.wireshark.org/tools/modelines.html
339 * Local variables:
340 * c-basic-offset: 8
341 * tab-width: 8
342 * indent-tabs-mode: t
343 * End:
345 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
346 * :indentSize=8:tabSize=8:noTabs=false: