diff options
Diffstat (limited to 'source3/lib')
-rw-r--r-- | source3/lib/membuffer.c | 370 | ||||
-rw-r--r-- | source3/lib/util.c | 25 | ||||
-rw-r--r-- | source3/lib/util_hnd.c | 316 |
3 files changed, 711 insertions, 0 deletions
diff --git a/source3/lib/membuffer.c b/source3/lib/membuffer.c new file mode 100644 index 00000000000..0665b19ead3 --- /dev/null +++ b/source3/lib/membuffer.c @@ -0,0 +1,370 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + Samba memory buffer functions + Copyright (C) Andrew Tridgell 1992-1997 + Copyright (C) Luke Kenneth Casson Leighton 1996-1997 + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/******************************************************************* + * + * Description: memory buffer / stream management. + * Author : Luke K C Leighton + * Created : Dec 1997 + * + + * this module is intended for use in streaming data in and out of + * buffers. it is intended that a single data stream be subdivided + * into manageable sections. + + * for example, an rpc header contains a length field, but until the + * data has been created, the length is unknown. using this module, + * the header section can be tacked onto the front of the data memory + * list once the size of the data section preceding it is known. + + * the "margin" can be used to over-run and retrospectively lengthen + * the buffer. this is to save time in some of the loops, where it is + * not particularly desirable to realloc data by 1, 2 or 4 bytes + * repetitively... + + * each memory buffer contains a start and end offset. the end of + * one buffer should equal to the start of the next in the chain. + * (end - start = len, instead of end - start + 1 = len) + + * the debug log levels are very high in some of the routines: you + * have no idea how boring it gets staring at debug output from these + + ********************************************************************/ + + +#include "includes.h" + +extern int DEBUGLEVEL; + +/******************************************************************* + initialise a memory buffer. + ********************************************************************/ +void mem_init(struct mem_buf *buf, int margin) +{ + buf->dynamic = True; + buf->data = NULL; + buf->data_size = 0; + buf->data_used = 0; + + buf->margin = margin; + + buf->next = NULL; + + buf->offset.start = 0; + buf->offset.end = 0; +} + +/******************************************************************* + initialise a memory buffer. + + dynamic indicates memory has been dynamically allocated. + if mem_free is called, the memory will be freed. + ********************************************************************/ +void mem_create(struct mem_buf *buf, char *data, int size, int margin, BOOL dynamic) +{ + buf->dynamic = dynamic; + buf->data = data; + buf->data_size = size; + buf->data_used = size; + + buf->margin = margin; + + buf->next = NULL; + + buf->offset.start = 0; + buf->offset.end = size; +} + +/******************************************************************* + takes a memory buffer out of one structure: puts it in the other. + NULLs the one that the buffer is being stolen from. + ********************************************************************/ +void mem_take(struct mem_buf *mem_to, struct mem_buf *mem_from) +{ + memcpy(mem_to, mem_from, sizeof(*mem_to)); + + mem_init(mem_from, mem_from->margin); +} + +/******************************************************************* + allocate a memory buffer. assume it's empty + ********************************************************************/ +BOOL mem_alloc_data(struct mem_buf *buf, int size) +{ + if (!buf->dynamic) + { + DEBUG(3,("mem_alloc_data: warning - memory buffer type is set to static\n")); + } + + buf->data_size = size + buf->margin; + buf->data_used = size; + + buf->data = malloc(buf->data_size); + + if (buf->data == NULL) + { + DEBUG(3,("mem_alloc: could not malloc size %d\n", + buf->data_size)); + mem_init(buf, buf->margin); + + return False; + } + + bzero(buf->data, buf->data_size); + + return True; +} + +/******************************************************************* + allocates a memory buffer structure + ********************************************************************/ +BOOL mem_buf_copy(char *copy_into, struct mem_buf *buf, + uint32 offset, uint32 len) +{ + uint32 end = offset + len; + char *q = NULL; + uint32 data_len = mem_buf_len(buf); + uint32 start_offset = offset; + struct mem_buf **bcp = &buf; + + if (buf == NULL || copy_into == NULL) return False; + + DEBUG(200,("mem_buf_copy: data[%d..%d] offset %d len %d\n", + buf->offset.start, data_len, offset, len)); + + /* there's probably an off-by-one bug, here, and i haven't even tested the code :-) */ + while (offset < end && ((q = mem_data(bcp, offset)) != NULL)) + { + uint32 copy_len = (*bcp)->offset.end - offset; + + DEBUG(200,("\tdata[%d..%d] - offset %d len %d\n", + (*bcp)->offset.start, (*bcp)->offset.end, + offset, copy_len)); + + memcpy(copy_into, q, copy_len); + + offset += copy_len; + copy_into += copy_len; + } + + if ((*bcp) != NULL) + { + DEBUG(200,("mem_buf_copy: copied %d bytes\n", offset - start_offset)); + } + else + { + DEBUG(200,("mem_buf_copy: failed\n")); + } + + return buf != NULL; +} + +/******************************************************************* + allocates a memory buffer structure + ********************************************************************/ +BOOL mem_buf_init(struct mem_buf **buf, uint32 margin) +{ + if (buf == NULL) return False; + + if ((*buf) == NULL) + { + (*buf) = malloc(sizeof(**buf)); + if ((*buf) != NULL) + { + mem_init((*buf), margin); + return True; + } + } + else + { + (*buf)->margin = margin; + return True; + } + return False; +} + +/******************************************************************* + frees up a memory buffer. + ********************************************************************/ +void mem_buf_free(struct mem_buf **buf) +{ + if (buf == NULL) return; + if ((*buf) == NULL) return; + + mem_free_data(*buf); /* delete memory data */ + free(*buf); /* delete item */ + (*buf) = NULL; +} + +/******************************************************************* + frees a memory buffer chain. assumes that all items are malloced. + ********************************************************************/ +void mem_free_chain(struct mem_buf **buf) +{ + if (buf == NULL) return; + if ((*buf) == NULL) return; + + if ((*buf)->next != NULL) + { + mem_free_chain(&((*buf)->next)); /* delete all other items in chain */ + } + mem_buf_free(buf); +} + +/******************************************************************* + frees a memory buffer. + ********************************************************************/ +void mem_free_data(struct mem_buf *buf) +{ + if (buf == NULL) return; + + if (buf->data != NULL && buf->dynamic) + { + free(buf->data); /* delete data in this structure */ + } + mem_init(buf, buf->margin); +} + +/******************************************************************* + reallocate a memory buffer, including a safety margin + ********************************************************************/ +BOOL mem_realloc_data(struct mem_buf *buf, int new_size) +{ + char *new_data; + + if (!buf->dynamic) + { + DEBUG(3,("mem_realloc_data: memory buffer has not been dynamically allocated!\n")); + return False; + } + + if (new_size == 0) + { + mem_free_data(buf); + return True; + } + + new_data = Realloc(buf->data, new_size + buf->margin); + + if (new_data != NULL) + { + buf->data = new_data; + buf->data_size = new_size + buf->margin; + buf->data_used = new_size; + } + else if (buf->data_size <= new_size) + { + DEBUG(3,("mem_realloc: warning - could not realloc to %d(+%d)\n", + new_size, buf->margin)); + + buf->data_used = new_size; + } + else + { + DEBUG(3,("mem_realloc: error - could not realloc to %d\n", + new_size)); + + mem_free_data(buf); + return False; + } + + return True; +} + +/******************************************************************* + reallocate a memory buffer, retrospectively :-) + ********************************************************************/ +BOOL mem_grow_data(struct mem_buf **buf, BOOL io, int new_size) +{ + if (new_size + (*buf)->margin >= (*buf)->data_size) + { + if (io) + { + DEBUG(3,("mem_grow_data: cannot resize when reading from a data stream\n")); + } + else + { + return mem_realloc_data((*buf), new_size); + return False; + } + } + return True; +} + +/******************************************************************* + search for a memory buffer that falls within the specified offset + ********************************************************************/ +BOOL mem_find(struct mem_buf **buf, uint32 offset) +{ + struct mem_buf *f; + if (buf == NULL) return False; + + f = *buf; + + DEBUG(200,("mem_find: data[%d..%d] offset: %d\n", + f->offset.start, f->offset.end, offset)); + + while (f != NULL && offset >= f->offset.end) + { + f = f->next; + + DEBUG(200,("mem_find: next[%d..%d]\n", + f->offset.start, f->offset.end)); + } + + (*buf) = f; + + DEBUG(200,("mem_find: found data[%d..%d]\n", + (*buf)->offset.start,(*buf)->offset.end)); + + return f != NULL; +} + + +/******************************************************************* + add up the lengths of all sections. + ********************************************************************/ +uint32 mem_buf_len(struct mem_buf *buf) +{ + int len = 0; + while (buf != NULL) + { + len += buf->offset.end - buf->offset.start; + buf = buf->next; + } + return len; +} + + +/******************************************************************* + return the memory location specified by offset. may return NULL. + ********************************************************************/ +char *mem_data(struct mem_buf **buf, uint32 offset) +{ + if (mem_find(buf, offset)) + { + return &((*buf)->data[offset - (*buf)->offset.start]); + } + return NULL; +} + + diff --git a/source3/lib/util.c b/source3/lib/util.c index 5af41cc06cd..19fa42592fd 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -4848,4 +4848,29 @@ char *tab_depth(int depth) return spaces; } +/***************************************************************** + Convert a domain SID to an ascii string. (non-reentrant). +*****************************************************************/ +/* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */ +char *dom_sid_to_string(DOM_SID *sid) +{ + static pstring sidstr; + char subauth[16]; + int i; + uint32 ia = (sid->id_auth[5]) + + (sid->id_auth[4] << 8 ) + + (sid->id_auth[3] << 16) + + (sid->id_auth[2] << 24); + + sprintf(sidstr, "S-%d-%d", sid->sid_rev_num, ia); + + for (i = 0; i < sid->num_auths; i++) + { + sprintf(subauth, "-%d", sid->sub_auths[i]); + strcat(sidstr, subauth); + } + + DEBUG(7,("dom_sid_to_string returning %s\n", sidstr)); + return sidstr; +} diff --git a/source3/lib/util_hnd.c b/source3/lib/util_hnd.c new file mode 100644 index 00000000000..c8eabf35b41 --- /dev/null +++ b/source3/lib/util_hnd.c @@ -0,0 +1,316 @@ + +/* + * Unix SMB/Netbios implementation. + * Version 1.9. + * RPC Pipe client / server routines + * Copyright (C) Andrew Tridgell 1992-1997, + * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include "includes.h" + + +extern int DEBUGLEVEL; + +#ifndef MAX_OPEN_POLS +#define MAX_OPEN_POLS 50 +#endif + +struct reg_info +{ + /* for use by \PIPE\winreg */ + fstring name; /* name of registry key */ +}; + +struct samr_info +{ + /* for use by the \PIPE\samr policy */ + DOM_SID sid; + uint32 rid; /* relative id associated with the pol_hnd */ + uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */ +}; + +static struct +{ + BOOL open; + POLICY_HND pol_hnd; + + union + { + struct samr_info samr; + struct reg_info reg; + + } dev; + +} Policy[MAX_OPEN_POLS]; + + +#define VALID_POL(pnum) (((pnum) >= 0) && ((pnum) < MAX_OPEN_POLS)) +#define OPEN_POL(pnum) (VALID_POL(pnum) && Policy[pnum].open) + +/**************************************************************************** + create a unique policy handle +****************************************************************************/ +void create_pol_hnd(POLICY_HND *hnd) +{ + static uint32 pol_hnd_low = 0; + static uint32 pol_hnd_high = 0; + + if (hnd == NULL) return; + + /* i severely doubt that pol_hnd_high will ever be non-zero... */ + pol_hnd_low++; + if (pol_hnd_low == 0) pol_hnd_high++; + + SIVAL(hnd->data, 0 , 0x0); /* first bit must be null */ + SIVAL(hnd->data, 4 , pol_hnd_low ); /* second bit is incrementing */ + SIVAL(hnd->data, 8 , pol_hnd_high); /* second bit is incrementing */ + SIVAL(hnd->data, 12, time(NULL)); /* something random */ + SIVAL(hnd->data, 16, getpid()); /* something more random */ +} + +/**************************************************************************** + initialise policy handle states... +****************************************************************************/ +void init_lsa_policy_hnd(void) +{ + int i; + for (i = 0; i < MAX_OPEN_POLS; i++) + { + Policy[i].open = False; + } + + return; +} + +/**************************************************************************** + find first available policy slot. creates a policy handle for you. +****************************************************************************/ +BOOL open_lsa_policy_hnd(POLICY_HND *hnd) +{ + int i; + + for (i = 0; i < MAX_OPEN_POLS; i++) + { + if (!Policy[i].open) + { + Policy[i].open = True; + + create_pol_hnd(hnd); + memcpy(&(Policy[i].pol_hnd), hnd, sizeof(*hnd)); + + DEBUG(4,("Opened policy hnd[%x] ", i)); + dump_data(4, hnd->data, sizeof(hnd->data)); + + return True; + } + } + + /* i love obscure error messages. */ +#if TERRY_PRATCHET_INTERESTING_TIMES + DEBUG(1,("+++ OUT OF CHEESE ERROR +++ REDO FROM START ... @?!*@@\n")); +#else + DEBUG(1,("ERROR - open_lsa_policy_hnd: out of Policy Handles!\n")); +#endif + + return False; +} + +/**************************************************************************** + find policy index by handle +****************************************************************************/ +int find_lsa_policy_by_hnd(POLICY_HND *hnd) +{ + int i; + + for (i = 0; i < MAX_OPEN_POLS; i++) + { + if (memcmp(&(Policy[i].pol_hnd), hnd, sizeof(*hnd)) == 0) + { + DEBUG(4,("Found policy hnd[%x] ", i)); + dump_data(4, hnd->data, sizeof(hnd->data)); + + return i; + } + } + + DEBUG(4,("Policy not found: ")); + dump_data(4, hnd->data, sizeof(hnd->data)); + + return -1; +} + +/**************************************************************************** + set samr rid +****************************************************************************/ +BOOL set_lsa_policy_samr_rid(POLICY_HND *hnd, uint32 rid) +{ + int pnum = find_lsa_policy_by_hnd(hnd); + + if (OPEN_POL(pnum)) + { + DEBUG(3,("%s Setting policy device rid=%x pnum=%x\n", + timestring(), rid, pnum)); + + Policy[pnum].dev.samr.rid = rid; + return True; + } + else + { + DEBUG(3,("%s Error setting policy rid=%x (pnum=%x)\n", + timestring(), rid, pnum)); + return False; + } +} + +/**************************************************************************** + set samr pol status. absolutely no idea what this is. +****************************************************************************/ +BOOL set_lsa_policy_samr_pol_status(POLICY_HND *hnd, uint32 pol_status) +{ + int pnum = find_lsa_policy_by_hnd(hnd); + + if (OPEN_POL(pnum)) + { + DEBUG(3,("%s Setting policy status=%x pnum=%x\n", + timestring(), pol_status, pnum)); + + Policy[pnum].dev.samr.status = pol_status; + return True; + } + else + { + DEBUG(3,("%s Error setting policy status=%x (pnum=%x)\n", + timestring(), pol_status, pnum)); + return False; + } +} + +/**************************************************************************** + set samr sid +****************************************************************************/ +BOOL set_lsa_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid) +{ + int pnum = find_lsa_policy_by_hnd(hnd); + + if (OPEN_POL(pnum)) + { + DEBUG(3,("%s Setting policy sid=%s pnum=%x\n", + timestring(), dom_sid_to_string(sid), pnum)); + + memcpy(&(Policy[pnum].dev.samr.sid), sid, sizeof(*sid)); + return True; + } + else + { + DEBUG(3,("%s Error setting policy sid=%s (pnum=%x)\n", + timestring(), dom_sid_to_string(sid), pnum)); + return False; + } +} + +/**************************************************************************** + set samr rid +****************************************************************************/ +uint32 get_lsa_policy_samr_rid(POLICY_HND *hnd) +{ + int pnum = find_lsa_policy_by_hnd(hnd); + + if (OPEN_POL(pnum)) + { + uint32 rid = Policy[pnum].dev.samr.rid; + DEBUG(3,("%s Getting policy device rid=%x pnum=%x\n", + timestring(), rid, pnum)); + + return rid; + } + else + { + DEBUG(3,("%s Error getting policy (pnum=%x)\n", + timestring(), pnum)); + return 0xffffffff; + } +} + +/**************************************************************************** + set reg name +****************************************************************************/ +BOOL set_lsa_policy_reg_name(POLICY_HND *hnd, fstring name) +{ + int pnum = find_lsa_policy_by_hnd(hnd); + + if (OPEN_POL(pnum)) + { + DEBUG(3,("%s Setting policy pnum=%x name=%s\n", + timestring(), pnum, name)); + + fstrcpy(Policy[pnum].dev.reg.name, name); + return True; + } + else + { + DEBUG(3,("%s Error setting policy (pnum=%x) name=%s\n", + timestring(), pnum, name)); + return False; + } +} + +/**************************************************************************** + get reg name +****************************************************************************/ +BOOL get_lsa_policy_reg_name(POLICY_HND *hnd, fstring name) +{ + int pnum = find_lsa_policy_by_hnd(hnd); + + if (OPEN_POL(pnum)) + { + fstrcpy(name, Policy[pnum].dev.reg.name); + + DEBUG(3,("%s Getting policy pnum=%x name=%s\n", + timestring(), pnum, name)); + + return True; + } + else + { + DEBUG(3,("%s Error getting policy (pnum=%x)\n", + timestring(), pnum)); + return False; + } +} + +/**************************************************************************** + close an lsa policy +****************************************************************************/ +BOOL close_lsa_policy_hnd(POLICY_HND *hnd) +{ + int pnum = find_lsa_policy_by_hnd(hnd); + + if (OPEN_POL(pnum)) + { + DEBUG(3,("%s Closed policy name pnum=%x\n", timestring(), pnum)); + Policy[pnum].open = False; + return True; + } + else + { + DEBUG(3,("%s Error closing policy pnum=%x\n", timestring(), pnum)); + return False; + } +} + |