1 /* packet-smb-sidsnooping.c
2 * Routines for snooping SID to name mappings
3 * Copyright 2003, Ronnie Sahlberg
5 * $Id: packet-smb-sidsnooping.c,v 1.10 2003/12/02 21:15:46 guy Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 #include "epan/packet_info.h"
33 #include "epan/epan_dissect.h"
34 #include "epan/proto.h"
36 #include "packet-dcerpc.h"
37 #include "packet-dcerpc-nt.h"
40 #include "packet-smb-sidsnooping.h"
42 static int hf_lsa = -1;
43 static int hf_lsa_info_level = -1;
44 static int hf_lsa_opnum = -1;
45 static int hf_lsa_domain = -1;
46 static int hf_lsa_domain_sid = -1;
47 static int hf_samr_hnd = -1;
48 static int hf_samr_rid = -1;
49 static int hf_samr_acct_name = -1;
50 static int hf_samr_level = -1;
54 GHashTable *sid_name_table = NULL;
55 static GMemChunk *sid_name_chunk = NULL;
56 static int sid_name_init_count = 200;
60 static GMemChunk *ctx_handle_chunk = NULL;
61 static int ctx_handle_init_count = 200;
62 static GHashTable *ctx_handle_table = NULL;
65 static void *lsa_policy_information_flag = NULL;
66 static void *samr_query_dispinfo_flag = NULL;
70 find_sid_name(char *sid)
76 sn=g_hash_table_lookup(sid_name_table, &old_sn);
84 add_sid_name_mapping(char *sid, char *name)
90 sn=g_hash_table_lookup(sid_name_table, &old_sn);
95 sn=g_mem_chunk_alloc(sid_name_chunk);
96 sn->sid=g_strdup(sid);
97 sn->name=g_strdup(name);
98 g_hash_table_insert(sid_name_table, sn, sn);
105 * level 1 : user displayinfo 1
108 samr_query_dispinfo(void *dummy _U_, packet_info *pinfo, epan_dissect_t *edt, void *pri)
126 gp=proto_get_finfo_ptr_array(edt->tree, hf_samr_level);
127 if(!gp || gp->len!=1){
131 info_level=fi->value.value.integer;
144 gp=proto_get_finfo_ptr_array(edt->tree, hf_samr_hnd);
145 if(!gp || gp->len!=1){
150 old_ctx=g_hash_table_lookup(ctx_handle_table, (gpointer)pinfo->fd->num);
152 g_hash_table_remove(ctx_handle_table, (gpointer)pinfo->fd->num);
155 old_ctx=g_mem_chunk_alloc(ctx_handle_chunk);
156 memcpy(old_ctx, fi->value.value.bytes->data, 20);
158 g_hash_table_insert(ctx_handle_table, (gpointer)pinfo->fd->num, old_ctx);
163 if(!ri->call_data->req_frame){
167 old_ctx=g_hash_table_lookup(ctx_handle_table, (gpointer)ri->call_data->req_frame);
172 if (!dcerpc_smb_fetch_pol(old_ctx, &pol_name, NULL, NULL, ri->call_data->req_frame)) {
176 sid=strstr(pol_name,"S-1-5");
181 for(sid_len=4;1;sid_len++){
182 if((sid[sid_len]>='0') && (sid[sid_len]<='9')){
185 if(sid[sid_len]=='-'){
191 gp_rids=proto_get_finfo_ptr_array(edt->tree, hf_samr_rid);
192 if(!gp_rids || gp_rids->len<1){
195 num_rids=gp_rids->len;
196 gp_names=proto_get_finfo_ptr_array(edt->tree, hf_samr_acct_name);
197 if(!gp_names || gp_names->len<1){
200 num_names=gp_names->len;
202 if(num_rids>num_names){
206 for(;num_rids;num_rids--){
209 fi_rid=gp_rids->pdata[num_rids-1];
210 fi_name=gp_names->pdata[num_rids-1];
211 strncpy(sid_name, sid, len);
213 len+=sprintf(sid_name+len,"%d",fi_rid->value.value.integer);
215 add_sid_name_mapping(sid_name, fi_name->value.value.string);
221 * PolicyInformation :
222 * level 3 : PRIMARY_DOMAIN_INFO lsa.domain_sid -> lsa.domain
223 * level 5 : ACCOUNT_DOMAIN_INFO lsa.domain_sid -> lsa.domain
224 * level 12 : DNS_DOMAIN_INFO lsa.domain_sid -> lsa.domain
227 lsa_policy_information(void *dummy _U_, packet_info *pinfo _U_, epan_dissect_t *edt, void *pri _U_)
235 gp=proto_get_finfo_ptr_array(edt->tree, hf_lsa_info_level);
236 if(!gp || gp->len!=1){
240 info_level=fi->value.value.integer;
246 gp=proto_get_finfo_ptr_array(edt->tree, hf_lsa_domain);
247 if(!gp || gp->len!=1){
251 domain=fi->value.value.string;
253 gp=proto_get_finfo_ptr_array(edt->tree, hf_lsa_domain_sid);
254 if(!gp || gp->len!=1){
258 sid=fi->value.value.string;
260 add_sid_name_mapping(sid, domain);
267 free_all_sid_names(gpointer key_arg, gpointer value _U_, gpointer user_data _U_)
269 sid_name *sn = (sid_name *)key_arg;
272 g_free((gpointer)sn->sid);
276 g_free((gpointer)sn->name);
283 sid_name_equal(gconstpointer k1, gconstpointer k2)
285 const sid_name *sn1 = (const sid_name *)k1;
286 const sid_name *sn2 = (const sid_name *)k2;
288 return !strcmp(sn1->sid, sn2->sid);
292 sid_name_hash(gconstpointer k)
294 const sid_name *sn = (const sid_name *)k;
297 for(sum=0,i=strlen(sn->sid)-1;i>=0;i--){
306 free_all_ctx_handle(gpointer key_arg _U_, gpointer value _U_, gpointer user_data _U_)
311 ctx_handle_equal(gconstpointer k1, gconstpointer k2)
320 ctx_handle_hash(gconstpointer k)
329 sid_snooping_init(void)
331 header_field_info *hfi;
332 GString *error_string;
334 if(lsa_policy_information_flag){
335 remove_tap_listener(lsa_policy_information_flag);
336 lsa_policy_information_flag=NULL;
338 if(samr_query_dispinfo_flag){
339 remove_tap_listener(samr_query_dispinfo_flag);
340 samr_query_dispinfo_flag=NULL;
344 g_hash_table_foreach_remove(sid_name_table, free_all_sid_names, NULL);
348 g_mem_chunk_destroy(sid_name_chunk);
351 if(ctx_handle_table){
352 g_hash_table_foreach_remove(ctx_handle_table, free_all_ctx_handle, NULL);
353 ctx_handle_table=NULL;
355 if(ctx_handle_chunk){
356 g_mem_chunk_destroy(ctx_handle_chunk);
357 ctx_handle_chunk=NULL;
361 if(!sid_name_snooping){
366 sid_name_table=g_hash_table_new(sid_name_hash, sid_name_equal);
367 sid_name_chunk = g_mem_chunk_new("sid_name_chunk",
369 sid_name_init_count * sizeof(sid_name),
373 ctx_handle_table=g_hash_table_new(ctx_handle_hash, ctx_handle_equal);
374 ctx_handle_chunk = g_mem_chunk_new("ctx_handle_chunk",
375 20, /* our dcerpc context handles are 20 bytes */
376 ctx_handle_init_count * 20,
380 hf_lsa=proto_get_id_by_filter_name("lsa");
382 hfi=proto_registrar_get_byname("lsa.opnum");
384 hf_lsa_opnum=hfi->id;
387 hfi=proto_registrar_get_byname("lsa.domain_sid");
389 hf_lsa_domain_sid=hfi->id;
392 hfi=proto_registrar_get_byname("lsa.domain");
394 hf_lsa_domain=hfi->id;
397 hfi=proto_registrar_get_byname("lsa.info.level");
399 hf_lsa_info_level=hfi->id;
402 hfi=proto_registrar_get_byname("samr.hnd");
406 hfi=proto_registrar_get_byname("samr.rid");
410 hfi=proto_registrar_get_byname("samr.acct_name");
412 hf_samr_acct_name=hfi->id;
414 hfi=proto_registrar_get_byname("samr.level");
416 hf_samr_level=hfi->id;
421 error_string=register_tap_listener("dcerpc", lsa_policy_information, "lsa.policy_information and ( lsa.info.level or lsa.domain or lsa.domain_sid )", NULL, lsa_policy_information, NULL);
423 /* error, we failed to attach to the tap. clean up */
425 fprintf(stderr, "tethereal: Couldn't register proto_reg_handoff_smb_sidsnooping()/lsa_policy_information tap: %s\n",
427 g_string_free(error_string, TRUE);
430 lsa_policy_information_flag=lsa_policy_information;
432 error_string=register_tap_listener("dcerpc", samr_query_dispinfo, "samr and samr.opnum==40 and ( samr.hnd or samr.rid or samr.acct_name or samr.level )", NULL, samr_query_dispinfo, NULL);
434 /* error, we failed to attach to the tap. clean up */
436 fprintf(stderr, "tethereal: Couldn't register proto_reg_handoff_smb_sidsnooping()/samr_query_dispinfo tap: %s\n",
438 g_string_free(error_string, TRUE);
441 samr_query_dispinfo_flag=samr_query_dispinfo;
445 proto_register_smb_sidsnooping(void)
447 register_init_routine(sid_snooping_init);
451 proto_reg_handoff_smb_sidsnooping(void)