aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-smb-sidsnooping.c
diff options
context:
space:
mode:
authorgram <gram@f5534014-38df-0310-8fa8-9805f1628bb7>2004-07-18 18:06:47 +0000
committergram <gram@f5534014-38df-0310-8fa8-9805f1628bb7>2004-07-18 18:06:47 +0000
commit35a6e092c3153cc7fbd1337c2230d596b0f7abcb (patch)
tree4eff24a2e16c8963e497e1fc575f35e6af59bd26 /epan/dissectors/packet-smb-sidsnooping.c
parent8dd1ee5ef22a787f4035d68e8e2ec8371fd23266 (diff)
Move dissectors to epan/dissectors directory.
Also move ncp222.py, x11-fields, process-x11-fields.pl, make-reg-dotc, and make-reg-dotc.py. Adjust #include lines in files that include packet-*.h files. git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@11410 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'epan/dissectors/packet-smb-sidsnooping.c')
-rw-r--r--epan/dissectors/packet-smb-sidsnooping.c457
1 files changed, 457 insertions, 0 deletions
diff --git a/epan/dissectors/packet-smb-sidsnooping.c b/epan/dissectors/packet-smb-sidsnooping.c
new file mode 100644
index 0000000000..84cdb8125e
--- /dev/null
+++ b/epan/dissectors/packet-smb-sidsnooping.c
@@ -0,0 +1,457 @@
+/* packet-smb-sidsnooping.c
+ * Routines for snooping SID to name mappings
+ * Copyright 2003, Ronnie Sahlberg
+ *
+ * $Id$
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include "epan/packet_info.h"
+#include "epan/epan_dissect.h"
+#include "epan/proto.h"
+#include "tap.h"
+#include "packet-dcerpc.h"
+#include "packet-dcerpc-nt.h"
+#include "register.h"
+#include "smb.h"
+#include "packet-smb-sidsnooping.h"
+
+static int hf_lsa = -1;
+static int hf_lsa_info_level = -1;
+static int hf_lsa_opnum = -1;
+static int hf_lsa_domain = -1;
+static int hf_nt_domain_sid = -1;
+static int hf_samr_hnd = -1;
+static int hf_samr_rid = -1;
+static int hf_samr_acct_name = -1;
+static int hf_samr_level = -1;
+
+
+
+GHashTable *sid_name_table = NULL;
+static GMemChunk *sid_name_chunk = NULL;
+static int sid_name_init_count = 200;
+
+
+
+static GMemChunk *ctx_handle_chunk = NULL;
+static int ctx_handle_init_count = 200;
+static GHashTable *ctx_handle_table = NULL;
+
+
+static void *lsa_policy_information_flag = NULL;
+static void *samr_query_dispinfo_flag = NULL;
+
+
+char *
+find_sid_name(char *sid)
+{
+ sid_name *sn;
+ sid_name old_sn;
+
+ old_sn.sid=sid;
+ sn=g_hash_table_lookup(sid_name_table, &old_sn);
+ if(!sn){
+ return NULL;
+ }
+ return sn->name;
+}
+
+static void
+add_sid_name_mapping(char *sid, char *name)
+{
+ sid_name *sn;
+ sid_name old_sn;
+
+ old_sn.sid=sid;
+ sn=g_hash_table_lookup(sid_name_table, &old_sn);
+ if(sn){
+ return;
+ }
+
+ sn=g_mem_chunk_alloc(sid_name_chunk);
+ sn->sid=g_strdup(sid);
+ sn->name=g_strdup(name);
+ g_hash_table_insert(sid_name_table, sn, sn);
+}
+
+
+
+/*
+ * QueryDispInfo :
+ * level 1 : user displayinfo 1
+ */
+static int
+samr_query_dispinfo(void *dummy _U_, packet_info *pinfo, epan_dissect_t *edt, void *pri)
+{
+ dcerpc_info *ri=pri;
+ void *old_ctx=NULL;
+ char *pol_name;
+ char *sid;
+ int sid_len;
+ int num_rids;
+ int num_names;
+ GPtrArray *gp;
+ GPtrArray *gp_rids;
+ GPtrArray *gp_names;
+ field_info *fi;
+ field_info *fi_rid;
+ field_info *fi_name;
+ char sid_name[256];
+ int info_level;
+
+ gp=proto_get_finfo_ptr_array(edt->tree, hf_samr_level);
+ if(!gp || gp->len!=1){
+ return 0;
+ }
+ fi=gp->pdata[0];
+ info_level=fi->value.value.integer;
+
+ if(info_level!=1){
+ return 0;
+ }
+
+ if(!ri){
+ return 0;
+ }
+ if(!ri->call_data){
+ return 0;
+ }
+ if(ri->ptype == PDU_REQ){
+ gp=proto_get_finfo_ptr_array(edt->tree, hf_samr_hnd);
+ if(!gp || gp->len!=1){
+ return 0;
+ }
+ fi=gp->pdata[0];
+
+ old_ctx=g_hash_table_lookup(ctx_handle_table, (gpointer)pinfo->fd->num);
+ if(old_ctx){
+ g_hash_table_remove(ctx_handle_table, (gpointer)pinfo->fd->num);
+ }
+ if(!old_ctx){
+ old_ctx=g_mem_chunk_alloc(ctx_handle_chunk);
+ memcpy(old_ctx, fi->value.value.bytes->data, 20);
+ }
+ g_hash_table_insert(ctx_handle_table, (gpointer)pinfo->fd->num, old_ctx);
+
+ return 0;
+ }
+
+ if(!ri->call_data->req_frame){
+ return 0;
+ }
+
+ old_ctx=g_hash_table_lookup(ctx_handle_table, (gpointer)ri->call_data->req_frame);
+ if(!old_ctx){
+ return 0;
+ }
+
+ if (!dcerpc_smb_fetch_pol(old_ctx, &pol_name, NULL, NULL, ri->call_data->req_frame)) {
+ return 0;
+ }
+
+ if (!pol_name)
+ return 0;
+
+ sid=strstr(pol_name,"S-1-5");
+ if(!sid){
+ return 0;
+ }
+
+ for(sid_len=4;1;sid_len++){
+ if((sid[sid_len]>='0') && (sid[sid_len]<='9')){
+ continue;
+ }
+ if(sid[sid_len]=='-'){
+ continue;
+ }
+ break;
+ }
+
+ gp_rids=proto_get_finfo_ptr_array(edt->tree, hf_samr_rid);
+ if(!gp_rids || gp_rids->len<1){
+ return 0;
+ }
+ num_rids=gp_rids->len;
+ gp_names=proto_get_finfo_ptr_array(edt->tree, hf_samr_acct_name);
+ if(!gp_names || gp_names->len<1){
+ return 0;
+ }
+ num_names=gp_names->len;
+
+ if(num_rids>num_names){
+ num_rids=num_names;
+ }
+
+ for(;num_rids;num_rids--){
+ int len=sid_len;
+
+ fi_rid=gp_rids->pdata[num_rids-1];
+ fi_name=gp_names->pdata[num_rids-1];
+ strncpy(sid_name, sid, len);
+ sid_name[len++]='-';
+ len+=sprintf(sid_name+len,"%d",fi_rid->value.value.integer);
+ sid_name[len]=0;
+ add_sid_name_mapping(sid_name, fi_name->value.value.string);
+ }
+ return 1;
+}
+
+/*
+ * PolicyInformation :
+ * level 3 : PRIMARY_DOMAIN_INFO lsa.domain_sid -> lsa.domain
+ * level 5 : ACCOUNT_DOMAIN_INFO lsa.domain_sid -> lsa.domain
+ * level 12 : DNS_DOMAIN_INFO lsa.domain_sid -> lsa.domain
+ */
+static int
+lsa_policy_information(void *dummy _U_, packet_info *pinfo _U_, epan_dissect_t *edt, void *pri _U_)
+{
+ GPtrArray *gp;
+ field_info *fi;
+ char *domain;
+ char *sid;
+ int info_level;
+
+ gp=proto_get_finfo_ptr_array(edt->tree, hf_lsa_info_level);
+ if(!gp || gp->len!=1){
+ return 0;
+ }
+ fi=gp->pdata[0];
+ info_level=fi->value.value.integer;
+
+ switch(info_level){
+ case 3:
+ case 5:
+ case 12:
+ gp=proto_get_finfo_ptr_array(edt->tree, hf_lsa_domain);
+ if(!gp || gp->len!=1){
+ return 0;
+ }
+ fi=gp->pdata[0];
+ domain=fi->value.value.string;
+
+ gp=proto_get_finfo_ptr_array(edt->tree, hf_nt_domain_sid);
+ if(!gp || gp->len!=1){
+ return 0;
+ }
+ fi=gp->pdata[0];
+ sid=fi->value.value.string;
+
+ add_sid_name_mapping(sid, domain);
+ break;
+ }
+ return 0;
+}
+
+static gboolean
+free_all_sid_names(gpointer key_arg, gpointer value _U_, gpointer user_data _U_)
+{
+ sid_name *sn = (sid_name *)key_arg;
+
+ if(sn->sid){
+ g_free((gpointer)sn->sid);
+ sn->sid=NULL;
+ }
+ if(sn->name){
+ g_free((gpointer)sn->name);
+ sn->name=NULL;
+ }
+ return TRUE;
+}
+
+static gint
+sid_name_equal(gconstpointer k1, gconstpointer k2)
+{
+ const sid_name *sn1 = (const sid_name *)k1;
+ const sid_name *sn2 = (const sid_name *)k2;
+
+ return !strcmp(sn1->sid, sn2->sid);
+}
+
+static guint
+sid_name_hash(gconstpointer k)
+{
+ const sid_name *sn = (const sid_name *)k;
+ int i, sum;
+
+ for(sum=0,i=strlen(sn->sid)-1;i>=0;i--){
+ sum+=sn->sid[i];
+ }
+
+ return sum;
+}
+
+
+static gboolean
+free_all_ctx_handle(gpointer key_arg _U_, gpointer value _U_, gpointer user_data _U_)
+{
+ return TRUE;
+}
+static gint
+ctx_handle_equal(gconstpointer k1, gconstpointer k2)
+{
+ int sn1 = (int)k1;
+ int sn2 = (int)k2;
+
+ return sn1==sn2;
+}
+
+static guint
+ctx_handle_hash(gconstpointer k)
+{
+ int sn = (int)k;
+
+ return sn;
+}
+
+
+static void
+sid_snooping_init(void)
+{
+ header_field_info *hfi;
+ GString *error_string;
+
+ if(lsa_policy_information_flag){
+ remove_tap_listener(lsa_policy_information_flag);
+ lsa_policy_information_flag=NULL;
+ }
+ if(samr_query_dispinfo_flag){
+ remove_tap_listener(samr_query_dispinfo_flag);
+ samr_query_dispinfo_flag=NULL;
+ }
+
+ if(sid_name_table){
+ g_hash_table_foreach_remove(sid_name_table, free_all_sid_names, NULL);
+ sid_name_table=NULL;
+ }
+ if(sid_name_chunk){
+ g_mem_chunk_destroy(sid_name_chunk);
+ sid_name_chunk=NULL;
+ }
+ if(ctx_handle_table){
+ g_hash_table_foreach_remove(ctx_handle_table, free_all_ctx_handle, NULL);
+ ctx_handle_table=NULL;
+ }
+ if(ctx_handle_chunk){
+ g_mem_chunk_destroy(ctx_handle_chunk);
+ ctx_handle_chunk=NULL;
+ }
+
+
+ if(!sid_name_snooping){
+ return;
+ }
+
+
+ sid_name_table=g_hash_table_new(sid_name_hash, sid_name_equal);
+ sid_name_chunk = g_mem_chunk_new("sid_name_chunk",
+ sizeof(sid_name),
+ sid_name_init_count * sizeof(sid_name),
+ G_ALLOC_ONLY);
+
+
+ ctx_handle_table=g_hash_table_new(ctx_handle_hash, ctx_handle_equal);
+ ctx_handle_chunk = g_mem_chunk_new("ctx_handle_chunk",
+ 20, /* our dcerpc context handles are 20 bytes */
+ ctx_handle_init_count * 20,
+ G_ALLOC_ONLY);
+
+
+ hf_lsa=proto_get_id_by_filter_name("lsa");
+
+ hfi=proto_registrar_get_byname("lsa.opnum");
+ if(hfi){
+ hf_lsa_opnum=hfi->id;
+ }
+
+ hfi=proto_registrar_get_byname("nt.domain_sid");
+ if(hfi){
+ hf_nt_domain_sid=hfi->id;
+ }
+
+ hfi=proto_registrar_get_byname("lsa.domain");
+ if(hfi){
+ hf_lsa_domain=hfi->id;
+ }
+
+ hfi=proto_registrar_get_byname("lsa.info.level");
+ if(hfi){
+ hf_lsa_info_level=hfi->id;
+ }
+
+ hfi=proto_registrar_get_byname("samr.hnd");
+ if(hfi){
+ hf_samr_hnd=hfi->id;
+ }
+ hfi=proto_registrar_get_byname("samr.rid");
+ if(hfi){
+ hf_samr_rid=hfi->id;
+ }
+ hfi=proto_registrar_get_byname("samr.acct_name");
+ if(hfi){
+ hf_samr_acct_name=hfi->id;
+ }
+ hfi=proto_registrar_get_byname("samr.level");
+ if(hfi){
+ hf_samr_level=hfi->id;
+ }
+
+
+
+ error_string=register_tap_listener("dcerpc", lsa_policy_information, "lsa.policy_information and ( lsa.info.level or lsa.domain or nt.domain_sid )", NULL, lsa_policy_information, NULL);
+ if(error_string){
+ /* error, we failed to attach to the tap. clean up */
+
+ fprintf(stderr, "tethereal: Couldn't register proto_reg_handoff_smb_sidsnooping()/lsa_policy_information tap: %s\n",
+ error_string->str);
+ g_string_free(error_string, TRUE);
+ exit(1);
+ }
+ lsa_policy_information_flag=lsa_policy_information;
+
+ 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);
+ if(error_string){
+ /* error, we failed to attach to the tap. clean up */
+
+ fprintf(stderr, "tethereal: Couldn't register proto_reg_handoff_smb_sidsnooping()/samr_query_dispinfo tap: %s\n",
+ error_string->str);
+ g_string_free(error_string, TRUE);
+ exit(1);
+ }
+ samr_query_dispinfo_flag=samr_query_dispinfo;
+}
+
+void
+proto_register_smb_sidsnooping(void)
+{
+ register_init_routine(sid_snooping_init);
+}
+
+void
+proto_reg_handoff_smb_sidsnooping(void)
+{
+}
+