summaryrefslogtreecommitdiffstats
path: root/source3/lib
diff options
context:
space:
mode:
Diffstat (limited to 'source3/lib')
-rw-r--r--source3/lib/membuffer.c370
-rw-r--r--source3/lib/util.c25
-rw-r--r--source3/lib/util_hnd.c316
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;
+ }
+}
+