www.pudn.com > tdi_fw.rar > sids.c, change:2009-04-28,size:4921b
/* Copyright (c) 2002-2005 Vladislav Goncharov. * * Redistribution and use in source forms, with and without modification, * are permitted provided that this entire comment appears intact. * * Redistribution in binary form may occur without any restrictions. * * This software is provided ``AS IS'' without any warranties of any kind. */ // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil -*- (for GNU Emacs) // // $Id: sids.c,v 1.1 2009/04/28 12:53:28 tanwen Exp $ /* * Working with SID bitmasks */ #include <ntddk.h> #include "sock.h" #include "ipc.h" #include "memtrack.h" #include "sids.h" #include "tdi_fw.h" struct sid_nfo { ULONG sid_len; char sid_data[]; }; static struct { char *buf; struct sid_nfo *list[MAX_SIDS_COUNT]; int count; KSPIN_LOCK guard; } g_sids; void sids_init(void) { KeInitializeSpinLock(&g_sids.guard); } NTSTATUS set_sid_list(char *buf, ULONG size) { KIRQL irql; NTSTATUS status; ULONG pos; int i; KeAcquireSpinLock(&g_sids.guard, &irql); // first, free information if (g_sids.buf != NULL) { free(g_sids.buf); g_sids.buf = NULL; } memset(g_sids.list, 0, sizeof(g_sids.list)); g_sids.count = 0; if (size != 0) { // copy buffer g_sids.buf = (char *)malloc_np(size); if (g_sids.buf == NULL) { KdPrint(("[tdi_fw] set_sid_list: malloc_np!\n")); status = STATUS_INSUFFICIENT_RESOURCES; goto done; } memcpy(g_sids.buf, buf, size); // parse buffer and find struct sid_nfo for (pos = 0, i = 0; pos + sizeof(struct sid_nfo) < size && i < MAX_SIDS_COUNT; i++) { struct sid_nfo *nfo = (struct sid_nfo *)&g_sids.buf[pos]; if (pos + sizeof(*nfo) + nfo->sid_len > size) break; g_sids.list[i] = nfo; pos += sizeof(*nfo) + nfo->sid_len; } g_sids.count = i; if (pos == size) status = STATUS_SUCCESS; else status = STATUS_INVALID_PARAMETER; } else status = STATUS_SUCCESS; done: KeReleaseSpinLock(&g_sids.guard, irql); return status; } #define SeLengthSid(sid) (8 + 4 * ((unsigned char *)(sid))[1]) int get_sid_id(struct _SID_AND_ATTRIBUTES *sid_a, ULONG sid_a_size) { // doing linear search (optimize?) KIRQL irql; int i, result = 0; KdPrint(("[tdi_fw] get_sid_id: (sid_size = %u/%u)\n", SeLengthSid(sid_a->Sid), sid_a_size)); KeAcquireSpinLock(&g_sids.guard, &irql); for (i = 1; i < g_sids.count; i++) { // comparing sids byte by byte (can't call RtlEqualSid() due to DISPATCH_LEVEL) KdPrint(("[tdi_fw] get_sid_id: sid #%d size %u\n", i, SeLengthSid((PSID)g_sids.list[i]->sid_data))); if (SeLengthSid(sid_a->Sid) == SeLengthSid((PSID)g_sids.list[i]->sid_data) && memcmp(sid_a->Sid, (PSID)g_sids.list[i]->sid_data, SeLengthSid(sid_a->Sid)) == 0) { result = i; break; } } KeReleaseSpinLock(&g_sids.guard, irql); KdPrint(("[tdi_fw] get_sid_id: %d\n", result)); return result; } #define CURRENT_THREAD (HANDLE)-2 #define CURRENT_PROCESS (HANDLE)-1 #define TOKEN_QUERY 0x0008 struct _SID_AND_ATTRIBUTES * get_current_sid_a(ULONG *sid_a_size) // must be called at PASSIVE_LEVEL! { NTSTATUS status; HANDLE token; ULONG size; SID_AND_ATTRIBUTES *sid_a; *sid_a_size = 0; // open thread token status = ZwOpenThreadToken(CURRENT_THREAD, TOKEN_QUERY, FALSE, &token); if (status == STATUS_NO_TOKEN) { // open process token status = ZwOpenProcessToken(CURRENT_PROCESS, TOKEN_QUERY, &token); } if (status != STATUS_SUCCESS) { KdPrint(("[tdi_fw] get_current_sid_a: ZwOpen{Thread|Process}Token: 0x%x!\n")); return NULL; } size = sizeof(*sid_a) + 100; // default size sid_a = (SID_AND_ATTRIBUTES *)malloc_np(size); if (sid_a == NULL) { KdPrint(("[tdi_fw] get_current_sid_a: malloc_np!\n")); goto done; } status = ZwQueryInformationToken(token, TokenUser, sid_a, size, &size); if (status == STATUS_BUFFER_TOO_SMALL) { free(sid_a); sid_a = (SID_AND_ATTRIBUTES *)malloc_np(size); if (sid_a == NULL) { KdPrint(("[tdi_fw] get_current_sid_a: malloc_np!\n")); goto done; } status = ZwQueryInformationToken(token, TokenUser, sid_a, size, &size); } if (status != STATUS_SUCCESS) { KdPrint(("[tdi_fw] get_current_sid_a: ZwQueryInformationToken: 0x%x!\n")); free(sid_a); sid_a = NULL; goto done; } // got sid & attributes! *sid_a_size = size; done: ZwClose(token); return sid_a; } struct _SID_AND_ATTRIBUTES * copy_sid_a(SID_AND_ATTRIBUTES *sid_a, ULONG sid_a_size) { SID_AND_ATTRIBUTES *result; if (sid_a == NULL) return NULL; result = (SID_AND_ATTRIBUTES *)malloc_np(sid_a_size); if (result == NULL) return NULL; memcpy(result, sid_a, sid_a_size); result->Sid = (char *)result + ((char *)(sid_a->Sid) - (char *)sid_a); return result; }