From 8f28bda7f8c18de597d345126c9ee03e99776e55 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 17 Dec 2007 10:44:09 -0800 Subject: Fix bug #5121 (unix passwd sync not working on a streams based system). Jeremy. (This used to be commit 545cd2139cfc9484b733693814d4724d37125942) --- source3/lib/replace/libreplace.m4 | 1 + source3/lib/replace/system/network.h | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/replace/libreplace.m4 b/source3/lib/replace/libreplace.m4 index c10a4b2381..7a5283a4d6 100644 --- a/source3/lib/replace/libreplace.m4 +++ b/source3/lib/replace/libreplace.m4 @@ -100,6 +100,7 @@ AC_CHECK_HEADERS(sys/socket.h netinet/in.h netdb.h arpa/inet.h) AC_CHECK_HEADERS(netinet/ip.h netinet/tcp.h netinet/in_systm.h netinet/in_ip.h) AC_CHECK_HEADERS(sys/sockio.h sys/un.h) AC_CHECK_HEADERS(sys/mount.h mntent.h) +AC_CHECK_HEADERS(stropts.h) dnl we need to check that net/if.h really can be used, to cope with hpux dnl where including it always fails diff --git a/source3/lib/replace/system/network.h b/source3/lib/replace/system/network.h index d3ae2bf398..9087c02da1 100644 --- a/source3/lib/replace/system/network.h +++ b/source3/lib/replace/system/network.h @@ -78,6 +78,10 @@ #include #endif +#ifdef HAVE_STROPTS_H +#include +#endif + #ifdef REPLACE_INET_NTOA /* define is in "replace.h" */ char *rep_inet_ntoa(struct in_addr ip); -- cgit From c8071c3522abefb651596e2335e724ae50cb8a90 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 17 Dec 2007 16:20:44 -0800 Subject: Use the %*s feature of snprintf to remove anothe static fstring. Jeremy. (This used to be commit 4ae4b2358688bf289305a2db0ed01b653ac073b2) --- source3/lib/util.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/util.c b/source3/lib/util.c index 73b035b22b..11c14ea538 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -2227,17 +2227,12 @@ void dump_data_pw(const char *msg, const uchar * data, size_t len) #endif } -char *tab_depth(int depth) +const char *tab_depth(int level, int depth) { - static fstring spaces; - size_t len = depth * 4; - if (len > sizeof(fstring)-1) { - len = sizeof(fstring)-1; + if( DEBUGLVL(level) ) { + dbgtext("%*s", depth*4, ""); } - - memset(spaces, ' ', len); - spaces[len] = 0; - return spaces; + return ""; } /***************************************************************************** -- cgit From 2d1b03d67a7218cf2cf0a0f4cf8b49819b39ce23 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 17 Dec 2007 18:32:27 -0800 Subject: More static pstring elimination. Jeremy. (This used to be commit 92acc0115d8d4111289c2ade1db7bb060ee908db) --- source3/lib/display_sec.c | 112 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 86 insertions(+), 26 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/display_sec.c b/source3/lib/display_sec.c index f6a6bb6465..67392e4568 100644 --- a/source3/lib/display_sec.c +++ b/source3/lib/display_sec.c @@ -23,34 +23,92 @@ /**************************************************************************** convert a security permissions into a string ****************************************************************************/ -char *get_sec_mask_str(uint32 type) + +char *get_sec_mask_str(TALLOC_CTX *ctx, uint32 type) { - static fstring typestr=""; + char *typestr = talloc_strdup(ctx, ""); - typestr[0] = 0; + if (!typestr) { + return NULL; + } - if (type & GENERIC_ALL_ACCESS) - fstrcat(typestr, "Generic all access "); - if (type & GENERIC_EXECUTE_ACCESS) - fstrcat(typestr, "Generic execute access "); - if (type & GENERIC_WRITE_ACCESS) - fstrcat(typestr, "Generic write access "); - if (type & GENERIC_READ_ACCESS) - fstrcat(typestr, "Generic read access "); - if (type & MAXIMUM_ALLOWED_ACCESS) - fstrcat(typestr, "MAXIMUM_ALLOWED_ACCESS "); - if (type & SYSTEM_SECURITY_ACCESS) - fstrcat(typestr, "SYSTEM_SECURITY_ACCESS "); - if (type & SYNCHRONIZE_ACCESS) - fstrcat(typestr, "SYNCHRONIZE_ACCESS "); - if (type & WRITE_OWNER_ACCESS) - fstrcat(typestr, "WRITE_OWNER_ACCESS "); - if (type & WRITE_DAC_ACCESS) - fstrcat(typestr, "WRITE_DAC_ACCESS "); - if (type & READ_CONTROL_ACCESS) - fstrcat(typestr, "READ_CONTROL_ACCESS "); - if (type & DELETE_ACCESS) - fstrcat(typestr, "DELETE_ACCESS "); + if (type & GENERIC_ALL_ACCESS) { + typestr = talloc_asprintf_append(typestr, + "Generic all access "); + if (!typestr) { + return NULL; + } + } + if (type & GENERIC_EXECUTE_ACCESS) { + typestr = talloc_asprintf_append(typestr, + "Generic execute access"); + if (!typestr) { + return NULL; + } + } + if (type & GENERIC_WRITE_ACCESS) { + typestr = talloc_asprintf_append(typestr, + "Generic write access "); + if (!typestr) { + return NULL; + } + } + if (type & GENERIC_READ_ACCESS) { + typestr = talloc_asprintf_append(typestr, + "Generic read access "); + if (!typestr) { + return NULL; + } + } + if (type & MAXIMUM_ALLOWED_ACCESS) { + typestr = talloc_asprintf_append(typestr, + "MAXIMUM_ALLOWED_ACCESS "); + if (!typestr) { + return NULL; + } + } + if (type & SYSTEM_SECURITY_ACCESS) { + typestr = talloc_asprintf_append(typestr, + "SYSTEM_SECURITY_ACCESS "); + if (!typestr) { + return NULL; + } + } + if (type & SYNCHRONIZE_ACCESS) { + typestr = talloc_asprintf_append(typestr, + "SYNCHRONIZE_ACCESS "); + if (!typestr) { + return NULL; + } + } + if (type & WRITE_OWNER_ACCESS) { + typestr = talloc_asprintf_append(typestr, + "WRITE_OWNER_ACCESS "); + if (!typestr) { + return NULL; + } + } + if (type & WRITE_DAC_ACCESS) { + typestr = talloc_asprintf_append(typestr, + "WRITE_DAC_ACCESS "); + if (!typestr) { + return NULL; + } + } + if (type & READ_CONTROL_ACCESS) { + typestr = talloc_asprintf_append(typestr, + "READ_CONTROL_ACCESS "); + if (!typestr) { + return NULL; + } + } + if (type & DELETE_ACCESS) { + typestr = talloc_asprintf_append(typestr, + "DELETE_ACCESS "); + if (!typestr) { + return NULL; + } + } printf("\t\tSpecific bits: 0x%lx\n", (unsigned long)type&SPECIFIC_RIGHTS_MASK); @@ -62,7 +120,9 @@ char *get_sec_mask_str(uint32 type) ****************************************************************************/ void display_sec_access(SEC_ACCESS *info) { - printf("\t\tPermissions: 0x%x: %s\n", *info, get_sec_mask_str(*info)); + char *mask_str = get_sec_mask_str(NULL, *info); + printf("\t\tPermissions: 0x%x: %s\n", *info, mask_str ? mask_str : ""); + TALLOC_FREE(mask_str); } /**************************************************************************** -- cgit From f427d4ce65659419c8989d87acd97d00b4db41e6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 18 Dec 2007 09:41:03 +0100 Subject: Add a in-memory cache This is a more general API that caches data with a LRU scheme. See include/cache.h. No comments yet, I'm still working on it. But Jeremy has given me a hint in one of his checkins that he would like to make use of this now. The idea is that we get rid of all our silly little caches and merge them all into one cache that we can then very easily trim, for example even with a smbcontrol message if someone decides memory is tight. The main user is the stat cache, this patch also converts the getwd cache. More caches to come. (This used to be commit 7a911b35713538d82001a3c9f34152e293fe1943) --- source3/lib/cache.c | 298 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 298 insertions(+) create mode 100644 source3/lib/cache.c (limited to 'source3/lib') diff --git a/source3/lib/cache.c b/source3/lib/cache.c new file mode 100644 index 0000000000..baf2fe3984 --- /dev/null +++ b/source3/lib/cache.c @@ -0,0 +1,298 @@ +/* + Unix SMB/CIFS implementation. + In-memory cache + Copyright (C) Volker Lendecke 2007 + + 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 3 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, see . +*/ + +#include "cache.h" +#include "rbtree.h" + +struct memcache_element { + struct rb_node rb_node; + struct memcache_element *prev, *next; + size_t keylength, valuelength; + uint8 n; /* This is really an enum, but save memory */ + char data[1]; /* placeholder for offsetof */ +}; + +struct memcache { + struct memcache_element *mru, *lru; + struct rb_root tree; + size_t size; + size_t max_size; +}; + +static int memcache_destructor(struct memcache *cache) { + struct memcache_element *e, *next; + + for (e = cache->mru; e != NULL; e = next) { + next = e->next; + SAFE_FREE(e); + } + return 0; +} + +struct memcache *memcache_init(TALLOC_CTX *mem_ctx, size_t max_size) +{ + struct memcache *result; + + result = TALLOC_ZERO_P(mem_ctx, struct memcache); + if (result == NULL) { + return NULL; + } + result->max_size = max_size; + talloc_set_destructor(result, memcache_destructor); + return result; +} + +static struct memcache_element *memcache_node2elem(struct rb_node *node) +{ + return (struct memcache_element *) + ((char *)node - offsetof(struct memcache_element, rb_node)); +} + +static void memcache_element_parse(struct memcache_element *e, + DATA_BLOB *key, DATA_BLOB *value) +{ + key->data = ((uint8 *)e) + offsetof(struct memcache_element, data); + key->length = e->keylength; + value->data = key->data + e->keylength; + value->length = e->valuelength; +} + +static size_t memcache_element_size(size_t key_length, size_t value_length) +{ + return sizeof(struct memcache_element) - 1 + key_length + value_length; +} + +static int memcache_compare(struct memcache_element *e, enum memcache_number n, + DATA_BLOB key) +{ + DATA_BLOB this_key, this_value; + + if ((int)e->n < (int)n) return -1; + if ((int)e->n > (int)n) return 1; + + if (e->keylength < key.length) return -1; + if (e->keylength > key.length) return 1; + + memcache_element_parse(e, &this_key, &this_value); + return memcmp(this_key.data, key.data, key.length); +} + +static struct memcache_element *memcache_find( + struct memcache *cache, enum memcache_number n, DATA_BLOB key) +{ + struct rb_node *node; + + node = cache->tree.rb_node; + + while (node != NULL) { + struct memcache_element *elem = memcache_node2elem(node); + int cmp; + + cmp = memcache_compare(elem, n, key); + if (cmp == 0) { + return elem; + } + node = (cmp < 0) ? node->rb_left : node->rb_right; + } + + return NULL; +} + +bool memcache_lookup(struct memcache *cache, enum memcache_number n, + DATA_BLOB key, DATA_BLOB *value) +{ + struct memcache_element *e; + + e = memcache_find(cache, n, key); + if (e == NULL) { + return false; + } + + if (cache->size != 0) { + /* + * Do LRU promotion only when we will ever shrink + */ + if (e == cache->lru) { + cache->lru = e->prev; + } + DLIST_PROMOTE(cache->mru, e); + if (cache->mru == NULL) { + cache->mru = e; + } + } + + memcache_element_parse(e, &key, value); + return true; +} + +static void memcache_delete_element(struct memcache *cache, + struct memcache_element *e) +{ + rb_erase(&e->rb_node, &cache->tree); + + if (e == cache->lru) { + cache->lru = e->prev; + } + DLIST_REMOVE(cache->mru, e); + + cache->size -= memcache_element_size(e->keylength, e->valuelength); + + SAFE_FREE(e); +} + +static void memcache_trim(struct memcache *cache) +{ + if (cache->max_size == 0) { + return; + } + + while ((cache->size > cache->max_size) && (cache->lru != NULL)) { + memcache_delete_element(cache, cache->lru); + } +} + +void memcache_delete(struct memcache *cache, enum memcache_number n, + DATA_BLOB key) +{ + struct memcache_element *e; + + e = memcache_find(cache, n, key); + if (e == NULL) { + return; + } + + memcache_delete_element(cache, e); +} + +void memcache_add(struct memcache *cache, enum memcache_number n, + DATA_BLOB key, DATA_BLOB value) +{ + struct memcache_element *e; + struct rb_node **p; + struct rb_node *parent; + DATA_BLOB cache_key, cache_value; + size_t element_size; + + if (key.length == 0) { + return; + } + + e = memcache_find(cache, n, key); + + if (e != NULL) { + memcache_element_parse(e, &cache_key, &cache_value); + + if (value.length <= cache_value.length) { + /* + * We can reuse the existing record + */ + memcpy(cache_value.data, value.data, value.length); + e->valuelength = value.length; + return; + } + + memcache_delete_element(cache, e); + } + + element_size = memcache_element_size(key.length, value.length); + + + e = (struct memcache_element *)SMB_MALLOC(element_size); + + if (e == NULL) { + DEBUG(0, ("malloc failed\n")); + return; + } + + e->n = n; + e->keylength = key.length; + e->valuelength = value.length; + + memcache_element_parse(e, &cache_key, &cache_value); + memcpy(cache_key.data, key.data, key.length); + memcpy(cache_value.data, value.data, value.length); + + parent = NULL; + p = &cache->tree.rb_node; + + while (*p) { + struct memcache_element *elem = memcache_node2elem(*p); + int cmp; + + parent = (*p); + + cmp = memcache_compare(elem, n, key); + + p = (cmp < 0) ? &(*p)->rb_left : &(*p)->rb_right; + } + + rb_link_node(&e->rb_node, parent, p); + rb_insert_color(&e->rb_node, &cache->tree); + + DLIST_ADD(cache->mru, e); + if (cache->lru == NULL) { + cache->lru = e; + } + + cache->size += element_size; + memcache_trim(cache); +} + +void memcache_flush(struct memcache *cache, enum memcache_number n) +{ + struct rb_node *node; + + /* + * Find the smallest element of number n + */ + + node = cache->tree.rb_node; + if (node == NULL) { + return; + } + + while (true) { + struct memcache_element *elem = memcache_node2elem(node); + struct rb_node *next; + + if ((int)elem->n < (int)n) { + next = node->rb_right; + } + else { + next = node->rb_left; + } + if (next == NULL) { + break; + } + node = next; + } + + node = rb_next(node); + if (node == NULL) { + return; + } + + while (node != NULL) { + struct memcache_element *e = memcache_node2elem(node); + struct rb_node *next = rb_next(node); + + memcache_delete_element(cache, e); + node = next; + } +} -- cgit From 537c4cf9cdb1f76c317c8fbd12068ce1f3fbbf0b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Dec 2007 16:03:57 -0800 Subject: Fix valgrind error in dbwrap_rbt where rec_priv->node was being accessed after free. VALOKER PLEASE CHECK THIS VERY CAREFULLY !!!! This is a correct fix in that it fixes the valgrind error, but it looks inelegant to me. I think if I understood this code better I could craft a more subtle fix. Still looking at it.... Jeremy. (This used to be commit 12cce3be2a24fd72106d747890caf6c7f29db43d) --- source3/lib/dbwrap_rbt.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/dbwrap_rbt.c b/source3/lib/dbwrap_rbt.c index df568a0410..15d9b67414 100644 --- a/source3/lib/dbwrap_rbt.c +++ b/source3/lib/dbwrap_rbt.c @@ -68,6 +68,8 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) TDB_DATA this_key, this_val; + bool del_old_keyval = false; + if (rec_priv->node != NULL) { /* @@ -95,7 +97,7 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) */ rb_erase(&rec_priv->node->rb_node, &rec_priv->db_ctx->tree); - SAFE_FREE(rec_priv->node); + del_old_keyval = true; } node = (struct db_rbt_node *)SMB_MALLOC( @@ -103,6 +105,9 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) + data.dsize); if (node == NULL) { + if (del_old_keyval) { + SAFE_FREE(rec_priv->node); + } return NT_STATUS_NO_MEMORY; } @@ -152,6 +157,10 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) rb_link_node(&node->rb_node, parent, p); rb_insert_color(&node->rb_node, &rec_priv->db_ctx->tree); + if (del_old_keyval) { + SAFE_FREE(rec_priv->node); + } + return NT_STATUS_OK; } -- cgit From c99dc69a453a67a38b1a1d5c5088a55d22a68651 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Dec 2007 17:30:02 -0800 Subject: We've finished with the old node once we've copied the keyval. Jeremy. (This used to be commit 39f3efbcc5fbdff1db1b12e5fc7368968f240993) --- source3/lib/dbwrap_rbt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/dbwrap_rbt.c b/source3/lib/dbwrap_rbt.c index 15d9b67414..468b9405ee 100644 --- a/source3/lib/dbwrap_rbt.c +++ b/source3/lib/dbwrap_rbt.c @@ -121,6 +121,10 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) memcpy(this_key.dptr, rec->key.dptr, node->keysize); memcpy(this_val.dptr, data.dptr, node->valuesize); + if (del_old_keyval) { + SAFE_FREE(rec_priv->node); + } + parent = NULL; p = &rec_priv->db_ctx->tree.rb_node; @@ -157,10 +161,6 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) rb_link_node(&node->rb_node, parent, p); rb_insert_color(&node->rb_node, &rec_priv->db_ctx->tree); - if (del_old_keyval) { - SAFE_FREE(rec_priv->node); - } - return NT_STATUS_OK; } -- cgit From 712a28aaae6671be673f9b125cae59aec628d267 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 19 Dec 2007 15:45:22 +0100 Subject: Rename cache.[ch] to memcache.[ch] cache.h conflicts with an XFS DMAPI include on "opi" :-( (This used to be commit b8db804e07cc19d406ba3892d6eecbe16132a89a) --- source3/lib/cache.c | 298 ------------------------------------------------- source3/lib/memcache.c | 298 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 298 insertions(+), 298 deletions(-) delete mode 100644 source3/lib/cache.c create mode 100644 source3/lib/memcache.c (limited to 'source3/lib') diff --git a/source3/lib/cache.c b/source3/lib/cache.c deleted file mode 100644 index baf2fe3984..0000000000 --- a/source3/lib/cache.c +++ /dev/null @@ -1,298 +0,0 @@ -/* - Unix SMB/CIFS implementation. - In-memory cache - Copyright (C) Volker Lendecke 2007 - - 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 3 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, see . -*/ - -#include "cache.h" -#include "rbtree.h" - -struct memcache_element { - struct rb_node rb_node; - struct memcache_element *prev, *next; - size_t keylength, valuelength; - uint8 n; /* This is really an enum, but save memory */ - char data[1]; /* placeholder for offsetof */ -}; - -struct memcache { - struct memcache_element *mru, *lru; - struct rb_root tree; - size_t size; - size_t max_size; -}; - -static int memcache_destructor(struct memcache *cache) { - struct memcache_element *e, *next; - - for (e = cache->mru; e != NULL; e = next) { - next = e->next; - SAFE_FREE(e); - } - return 0; -} - -struct memcache *memcache_init(TALLOC_CTX *mem_ctx, size_t max_size) -{ - struct memcache *result; - - result = TALLOC_ZERO_P(mem_ctx, struct memcache); - if (result == NULL) { - return NULL; - } - result->max_size = max_size; - talloc_set_destructor(result, memcache_destructor); - return result; -} - -static struct memcache_element *memcache_node2elem(struct rb_node *node) -{ - return (struct memcache_element *) - ((char *)node - offsetof(struct memcache_element, rb_node)); -} - -static void memcache_element_parse(struct memcache_element *e, - DATA_BLOB *key, DATA_BLOB *value) -{ - key->data = ((uint8 *)e) + offsetof(struct memcache_element, data); - key->length = e->keylength; - value->data = key->data + e->keylength; - value->length = e->valuelength; -} - -static size_t memcache_element_size(size_t key_length, size_t value_length) -{ - return sizeof(struct memcache_element) - 1 + key_length + value_length; -} - -static int memcache_compare(struct memcache_element *e, enum memcache_number n, - DATA_BLOB key) -{ - DATA_BLOB this_key, this_value; - - if ((int)e->n < (int)n) return -1; - if ((int)e->n > (int)n) return 1; - - if (e->keylength < key.length) return -1; - if (e->keylength > key.length) return 1; - - memcache_element_parse(e, &this_key, &this_value); - return memcmp(this_key.data, key.data, key.length); -} - -static struct memcache_element *memcache_find( - struct memcache *cache, enum memcache_number n, DATA_BLOB key) -{ - struct rb_node *node; - - node = cache->tree.rb_node; - - while (node != NULL) { - struct memcache_element *elem = memcache_node2elem(node); - int cmp; - - cmp = memcache_compare(elem, n, key); - if (cmp == 0) { - return elem; - } - node = (cmp < 0) ? node->rb_left : node->rb_right; - } - - return NULL; -} - -bool memcache_lookup(struct memcache *cache, enum memcache_number n, - DATA_BLOB key, DATA_BLOB *value) -{ - struct memcache_element *e; - - e = memcache_find(cache, n, key); - if (e == NULL) { - return false; - } - - if (cache->size != 0) { - /* - * Do LRU promotion only when we will ever shrink - */ - if (e == cache->lru) { - cache->lru = e->prev; - } - DLIST_PROMOTE(cache->mru, e); - if (cache->mru == NULL) { - cache->mru = e; - } - } - - memcache_element_parse(e, &key, value); - return true; -} - -static void memcache_delete_element(struct memcache *cache, - struct memcache_element *e) -{ - rb_erase(&e->rb_node, &cache->tree); - - if (e == cache->lru) { - cache->lru = e->prev; - } - DLIST_REMOVE(cache->mru, e); - - cache->size -= memcache_element_size(e->keylength, e->valuelength); - - SAFE_FREE(e); -} - -static void memcache_trim(struct memcache *cache) -{ - if (cache->max_size == 0) { - return; - } - - while ((cache->size > cache->max_size) && (cache->lru != NULL)) { - memcache_delete_element(cache, cache->lru); - } -} - -void memcache_delete(struct memcache *cache, enum memcache_number n, - DATA_BLOB key) -{ - struct memcache_element *e; - - e = memcache_find(cache, n, key); - if (e == NULL) { - return; - } - - memcache_delete_element(cache, e); -} - -void memcache_add(struct memcache *cache, enum memcache_number n, - DATA_BLOB key, DATA_BLOB value) -{ - struct memcache_element *e; - struct rb_node **p; - struct rb_node *parent; - DATA_BLOB cache_key, cache_value; - size_t element_size; - - if (key.length == 0) { - return; - } - - e = memcache_find(cache, n, key); - - if (e != NULL) { - memcache_element_parse(e, &cache_key, &cache_value); - - if (value.length <= cache_value.length) { - /* - * We can reuse the existing record - */ - memcpy(cache_value.data, value.data, value.length); - e->valuelength = value.length; - return; - } - - memcache_delete_element(cache, e); - } - - element_size = memcache_element_size(key.length, value.length); - - - e = (struct memcache_element *)SMB_MALLOC(element_size); - - if (e == NULL) { - DEBUG(0, ("malloc failed\n")); - return; - } - - e->n = n; - e->keylength = key.length; - e->valuelength = value.length; - - memcache_element_parse(e, &cache_key, &cache_value); - memcpy(cache_key.data, key.data, key.length); - memcpy(cache_value.data, value.data, value.length); - - parent = NULL; - p = &cache->tree.rb_node; - - while (*p) { - struct memcache_element *elem = memcache_node2elem(*p); - int cmp; - - parent = (*p); - - cmp = memcache_compare(elem, n, key); - - p = (cmp < 0) ? &(*p)->rb_left : &(*p)->rb_right; - } - - rb_link_node(&e->rb_node, parent, p); - rb_insert_color(&e->rb_node, &cache->tree); - - DLIST_ADD(cache->mru, e); - if (cache->lru == NULL) { - cache->lru = e; - } - - cache->size += element_size; - memcache_trim(cache); -} - -void memcache_flush(struct memcache *cache, enum memcache_number n) -{ - struct rb_node *node; - - /* - * Find the smallest element of number n - */ - - node = cache->tree.rb_node; - if (node == NULL) { - return; - } - - while (true) { - struct memcache_element *elem = memcache_node2elem(node); - struct rb_node *next; - - if ((int)elem->n < (int)n) { - next = node->rb_right; - } - else { - next = node->rb_left; - } - if (next == NULL) { - break; - } - node = next; - } - - node = rb_next(node); - if (node == NULL) { - return; - } - - while (node != NULL) { - struct memcache_element *e = memcache_node2elem(node); - struct rb_node *next = rb_next(node); - - memcache_delete_element(cache, e); - node = next; - } -} diff --git a/source3/lib/memcache.c b/source3/lib/memcache.c new file mode 100644 index 0000000000..17630066ae --- /dev/null +++ b/source3/lib/memcache.c @@ -0,0 +1,298 @@ +/* + Unix SMB/CIFS implementation. + In-memory cache + Copyright (C) Volker Lendecke 2007 + + 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 3 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, see . +*/ + +#include "memcache.h" +#include "rbtree.h" + +struct memcache_element { + struct rb_node rb_node; + struct memcache_element *prev, *next; + size_t keylength, valuelength; + uint8 n; /* This is really an enum, but save memory */ + char data[1]; /* placeholder for offsetof */ +}; + +struct memcache { + struct memcache_element *mru, *lru; + struct rb_root tree; + size_t size; + size_t max_size; +}; + +static int memcache_destructor(struct memcache *cache) { + struct memcache_element *e, *next; + + for (e = cache->mru; e != NULL; e = next) { + next = e->next; + SAFE_FREE(e); + } + return 0; +} + +struct memcache *memcache_init(TALLOC_CTX *mem_ctx, size_t max_size) +{ + struct memcache *result; + + result = TALLOC_ZERO_P(mem_ctx, struct memcache); + if (result == NULL) { + return NULL; + } + result->max_size = max_size; + talloc_set_destructor(result, memcache_destructor); + return result; +} + +static struct memcache_element *memcache_node2elem(struct rb_node *node) +{ + return (struct memcache_element *) + ((char *)node - offsetof(struct memcache_element, rb_node)); +} + +static void memcache_element_parse(struct memcache_element *e, + DATA_BLOB *key, DATA_BLOB *value) +{ + key->data = ((uint8 *)e) + offsetof(struct memcache_element, data); + key->length = e->keylength; + value->data = key->data + e->keylength; + value->length = e->valuelength; +} + +static size_t memcache_element_size(size_t key_length, size_t value_length) +{ + return sizeof(struct memcache_element) - 1 + key_length + value_length; +} + +static int memcache_compare(struct memcache_element *e, enum memcache_number n, + DATA_BLOB key) +{ + DATA_BLOB this_key, this_value; + + if ((int)e->n < (int)n) return -1; + if ((int)e->n > (int)n) return 1; + + if (e->keylength < key.length) return -1; + if (e->keylength > key.length) return 1; + + memcache_element_parse(e, &this_key, &this_value); + return memcmp(this_key.data, key.data, key.length); +} + +static struct memcache_element *memcache_find( + struct memcache *cache, enum memcache_number n, DATA_BLOB key) +{ + struct rb_node *node; + + node = cache->tree.rb_node; + + while (node != NULL) { + struct memcache_element *elem = memcache_node2elem(node); + int cmp; + + cmp = memcache_compare(elem, n, key); + if (cmp == 0) { + return elem; + } + node = (cmp < 0) ? node->rb_left : node->rb_right; + } + + return NULL; +} + +bool memcache_lookup(struct memcache *cache, enum memcache_number n, + DATA_BLOB key, DATA_BLOB *value) +{ + struct memcache_element *e; + + e = memcache_find(cache, n, key); + if (e == NULL) { + return false; + } + + if (cache->size != 0) { + /* + * Do LRU promotion only when we will ever shrink + */ + if (e == cache->lru) { + cache->lru = e->prev; + } + DLIST_PROMOTE(cache->mru, e); + if (cache->mru == NULL) { + cache->mru = e; + } + } + + memcache_element_parse(e, &key, value); + return true; +} + +static void memcache_delete_element(struct memcache *cache, + struct memcache_element *e) +{ + rb_erase(&e->rb_node, &cache->tree); + + if (e == cache->lru) { + cache->lru = e->prev; + } + DLIST_REMOVE(cache->mru, e); + + cache->size -= memcache_element_size(e->keylength, e->valuelength); + + SAFE_FREE(e); +} + +static void memcache_trim(struct memcache *cache) +{ + if (cache->max_size == 0) { + return; + } + + while ((cache->size > cache->max_size) && (cache->lru != NULL)) { + memcache_delete_element(cache, cache->lru); + } +} + +void memcache_delete(struct memcache *cache, enum memcache_number n, + DATA_BLOB key) +{ + struct memcache_element *e; + + e = memcache_find(cache, n, key); + if (e == NULL) { + return; + } + + memcache_delete_element(cache, e); +} + +void memcache_add(struct memcache *cache, enum memcache_number n, + DATA_BLOB key, DATA_BLOB value) +{ + struct memcache_element *e; + struct rb_node **p; + struct rb_node *parent; + DATA_BLOB cache_key, cache_value; + size_t element_size; + + if (key.length == 0) { + return; + } + + e = memcache_find(cache, n, key); + + if (e != NULL) { + memcache_element_parse(e, &cache_key, &cache_value); + + if (value.length <= cache_value.length) { + /* + * We can reuse the existing record + */ + memcpy(cache_value.data, value.data, value.length); + e->valuelength = value.length; + return; + } + + memcache_delete_element(cache, e); + } + + element_size = memcache_element_size(key.length, value.length); + + + e = (struct memcache_element *)SMB_MALLOC(element_size); + + if (e == NULL) { + DEBUG(0, ("malloc failed\n")); + return; + } + + e->n = n; + e->keylength = key.length; + e->valuelength = value.length; + + memcache_element_parse(e, &cache_key, &cache_value); + memcpy(cache_key.data, key.data, key.length); + memcpy(cache_value.data, value.data, value.length); + + parent = NULL; + p = &cache->tree.rb_node; + + while (*p) { + struct memcache_element *elem = memcache_node2elem(*p); + int cmp; + + parent = (*p); + + cmp = memcache_compare(elem, n, key); + + p = (cmp < 0) ? &(*p)->rb_left : &(*p)->rb_right; + } + + rb_link_node(&e->rb_node, parent, p); + rb_insert_color(&e->rb_node, &cache->tree); + + DLIST_ADD(cache->mru, e); + if (cache->lru == NULL) { + cache->lru = e; + } + + cache->size += element_size; + memcache_trim(cache); +} + +void memcache_flush(struct memcache *cache, enum memcache_number n) +{ + struct rb_node *node; + + /* + * Find the smallest element of number n + */ + + node = cache->tree.rb_node; + if (node == NULL) { + return; + } + + while (true) { + struct memcache_element *elem = memcache_node2elem(node); + struct rb_node *next; + + if ((int)elem->n < (int)n) { + next = node->rb_right; + } + else { + next = node->rb_left; + } + if (next == NULL) { + break; + } + node = next; + } + + node = rb_next(node); + if (node == NULL) { + return; + } + + while (node != NULL) { + struct memcache_element *e = memcache_node2elem(node); + struct rb_node *next = rb_next(node); + + memcache_delete_element(cache, e); + node = next; + } +} -- cgit From 873b6f0f21e61be6e4f7084fc0ded768dfa077ab Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 19 Dec 2007 13:48:49 +0100 Subject: Samba Shared Repository - branch v3-2-test updated - initial-v3-2-unstable-716-g12cce3b On Tue, Dec 18, 2007 at 06:04:32PM -0600, Jeremy Allison wrote: > Fix valgrind error in dbwrap_rbt where rec_priv->node was > being accessed after free. VALOKER PLEASE CHECK THIS VERY > CAREFULLY !!!! This is a correct fix in that it fixes the > valgrind error, but it looks inelegant to me. I think if > I understood this code better I could craft a more subtle > fix. Still looking at it.... Thanks a lot. Fully correct. What about the attached little simplification? Volker (This used to be commit 5b72828600fb057a7aeb5f1a6fb6c23c23f28cd8) --- source3/lib/dbwrap_rbt.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/dbwrap_rbt.c b/source3/lib/dbwrap_rbt.c index 468b9405ee..93d73f29d1 100644 --- a/source3/lib/dbwrap_rbt.c +++ b/source3/lib/dbwrap_rbt.c @@ -68,8 +68,6 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) TDB_DATA this_key, this_val; - bool del_old_keyval = false; - if (rec_priv->node != NULL) { /* @@ -97,7 +95,11 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) */ rb_erase(&rec_priv->node->rb_node, &rec_priv->db_ctx->tree); - del_old_keyval = true; + + /* + * Keep the existing node around for a while: If the record + * existed before, we reference the key data in there. + */ } node = (struct db_rbt_node *)SMB_MALLOC( @@ -105,9 +107,7 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) + data.dsize); if (node == NULL) { - if (del_old_keyval) { - SAFE_FREE(rec_priv->node); - } + SAFE_FREE(rec_priv->node); return NT_STATUS_NO_MEMORY; } @@ -119,11 +119,9 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) db_rbt_parse_node(node, &this_key, &this_val); memcpy(this_key.dptr, rec->key.dptr, node->keysize); - memcpy(this_val.dptr, data.dptr, node->valuesize); + SAFE_FREE(rec_priv->node); - if (del_old_keyval) { - SAFE_FREE(rec_priv->node); - } + memcpy(this_val.dptr, data.dptr, node->valuesize); parent = NULL; p = &rec_priv->db_ctx->tree.rb_node; -- cgit From e518e19bc0000019f131354f55e9f5b55f6a2c5e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 19 Dec 2007 15:02:59 +0100 Subject: Remove Get_Pwnam and its associated static variable All callers are replaced by Get_Pwnam_alloc (This used to be commit 735f59315497113aebadcf9ad387e3dbfffa284a) --- source3/lib/substitute.c | 26 ++++++++++++++++--------- source3/lib/username.c | 49 +++++++++--------------------------------------- 2 files changed, 26 insertions(+), 49 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/substitute.c b/source3/lib/substitute.c index e06917c8fb..80feee9579 100644 --- a/source3/lib/substitute.c +++ b/source3/lib/substitute.c @@ -408,7 +408,7 @@ static const char *automount_path(const char *user_name) /* use the passwd entry as the default */ /* this will be the default if WITH_AUTOMOUNT is not used or fails */ - server_path = talloc_strdup(ctx, get_user_home_dir(user_name)); + server_path = talloc_strdup(ctx, get_user_home_dir(ctx, user_name)); if (!server_path) { return ""; } @@ -541,7 +541,6 @@ char *alloc_sub_basic(const char *smb_name, const char *domain_name, { char *b, *p, *s, *r, *a_string; fstring pidstr, vnnstr; - struct passwd *pass; char addr[INET6_ADDRSTRLEN]; const char *local_machine_name = get_local_machine_name(); @@ -571,15 +570,21 @@ char *alloc_sub_basic(const char *smb_name, const char *domain_name, } a_string = realloc_string_sub(a_string, "%U", r); break; - case 'G' : + case 'G' : { + struct passwd *pass; r = SMB_STRDUP(smb_name); if (r == NULL) { goto error; } - if ((pass = Get_Pwnam(r))!=NULL) { - a_string = realloc_string_sub(a_string, "%G", gidtoname(pass->pw_gid)); - } + pass = Get_Pwnam_alloc(talloc_tos(), r); + if (pass != NULL) { + a_string = realloc_string_sub( + a_string, "%G", + gidtoname(pass->pw_gid)); + } + TALLOC_FREE(pass); break; + } case 'D' : r = strdup_upper(domain_name); if (r == NULL) { @@ -766,7 +771,7 @@ static char *alloc_sub_advanced(const char *servicename, const char *user, const char *str) { char *a_string, *ret_string; - char *b, *p, *s, *h; + char *b, *p, *s; a_string = SMB_STRDUP(str); if (a_string == NULL) { @@ -782,10 +787,13 @@ static char *alloc_sub_advanced(const char *servicename, const char *user, case 'N' : a_string = realloc_string_sub(a_string, "%N", automount_server(user)); break; - case 'H': - if ((h = get_user_home_dir(user))) + case 'H': { + char *h; + if ((h = get_user_home_dir(talloc_tos(), user))) a_string = realloc_string_sub(a_string, "%H", h); + TALLOC_FREE(h); break; + } case 'P': a_string = realloc_string_sub(a_string, "%P", connectpath); break; diff --git a/source3/lib/username.c b/source3/lib/username.c index 21eed9f5fc..3087bac0f4 100644 --- a/source3/lib/username.c +++ b/source3/lib/username.c @@ -32,19 +32,24 @@ static struct passwd *uname_string_combinations2(char *s, TALLOC_CTX *mem_ctx, i Get a users home directory. ****************************************************************************/ -char *get_user_home_dir(const char *user) +char *get_user_home_dir(TALLOC_CTX *mem_ctx, const char *user) { - static struct passwd *pass; + struct passwd *pass; + char *result; /* Ensure the user exists. */ - pass = Get_Pwnam(user); + pass = Get_Pwnam_alloc(mem_ctx, user); if (!pass) return(NULL); + /* Return home directory from struct passwd. */ - return(pass->pw_dir); + result = talloc_move(mem_ctx, &pass->pw_dir); + + TALLOC_FREE(pass); + return result; } /**************************************************************************** @@ -55,8 +60,6 @@ char *get_user_home_dir(const char *user) * - using lp_usernamelevel() for permutations. ****************************************************************************/ -static struct passwd *Get_Pwnam_ret = NULL; - static struct passwd *Get_Pwnam_internals(TALLOC_CTX *mem_ctx, const char *user, char *user2) { @@ -134,40 +137,6 @@ struct passwd *Get_Pwnam_alloc(TALLOC_CTX *mem_ctx, const char *user) return ret; } -/**************************************************************************** - Get_Pwnam wrapper without modification. - NOTE: This with NOT modify 'user'! -****************************************************************************/ - -struct passwd *Get_Pwnam(const char *user) -{ - struct passwd *ret; - - ret = Get_Pwnam_alloc(NULL, user); - - /* This call used to just return the 'passwd' static buffer. - This could then have accidental reuse implications, so - we now malloc a copy, and free it in the next use. - - This should cause the (ab)user to segfault if it - uses an old struct. - - This is better than useing the wrong data in security - critical operations. - - The real fix is to make the callers free the returned - malloc'ed data. - */ - - if (Get_Pwnam_ret) { - TALLOC_FREE(Get_Pwnam_ret); - } - - Get_Pwnam_ret = ret; - - return ret; -} - /* The functions below have been taken from password.c and slightly modified */ /**************************************************************************** Apply a function to upper/lower case combinations -- cgit From df133758c2496a5c99441635eca6b77c9019cb8c Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Thu, 20 Dec 2007 14:57:29 -0800 Subject: fix dump printout when byte >= 0x80 (This used to be commit e18fab269c7370a6670c56eeab60fd90feecf0b2) --- source3/lib/tdb/tools/tdbtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/tdb/tools/tdbtool.c b/source3/lib/tdb/tools/tdbtool.c index 79435a3571..d104ccd7c4 100644 --- a/source3/lib/tdb/tools/tdbtool.c +++ b/source3/lib/tdb/tools/tdbtool.c @@ -135,7 +135,7 @@ static void print_data(const char *buf,int len) if (len<=0) return; printf("[%03X] ",i); for (i=0;i Date: Thu, 20 Dec 2007 10:55:45 +0100 Subject: Add a global cache It hurts, but I think this global variable is necessary for transition, and it has the potential to remove quite a few other global variables without messing with APIs too much. (This used to be commit c131d0dc52ec09c9227eff3d68877369c37aaed5) --- source3/lib/memcache.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/memcache.c b/source3/lib/memcache.c index 17630066ae..38bbd66085 100644 --- a/source3/lib/memcache.c +++ b/source3/lib/memcache.c @@ -20,6 +20,8 @@ #include "memcache.h" #include "rbtree.h" +static struct memcache *global_cache; + struct memcache_element { struct rb_node rb_node; struct memcache_element *prev, *next; @@ -58,6 +60,12 @@ struct memcache *memcache_init(TALLOC_CTX *mem_ctx, size_t max_size) return result; } +void memcache_set_global(struct memcache *cache) +{ + TALLOC_FREE(global_cache); + global_cache = cache; +} + static struct memcache_element *memcache_node2elem(struct rb_node *node) { return (struct memcache_element *) @@ -119,6 +127,13 @@ bool memcache_lookup(struct memcache *cache, enum memcache_number n, { struct memcache_element *e; + if (cache == NULL) { + cache = global_cache; + } + if (cache == NULL) { + return false; + } + e = memcache_find(cache, n, key); if (e == NULL) { return false; @@ -172,6 +187,13 @@ void memcache_delete(struct memcache *cache, enum memcache_number n, { struct memcache_element *e; + if (cache == NULL) { + cache = global_cache; + } + if (cache == NULL) { + return; + } + e = memcache_find(cache, n, key); if (e == NULL) { return; @@ -189,6 +211,13 @@ void memcache_add(struct memcache *cache, enum memcache_number n, DATA_BLOB cache_key, cache_value; size_t element_size; + if (cache == NULL) { + cache = global_cache; + } + if (cache == NULL) { + return; + } + if (key.length == 0) { return; } @@ -258,6 +287,13 @@ void memcache_flush(struct memcache *cache, enum memcache_number n) { struct rb_node *node; + if (cache == NULL) { + cache = global_cache; + } + if (cache == NULL) { + return; + } + /* * Find the smallest element of number n */ -- cgit From d3d870cc07447cf08a776c714a39f40f9c72da2c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 20 Dec 2007 14:41:58 +0100 Subject: Add memcache_add_talloc The first memcache API only had blobs, but we have quite a few objects that are more complex talloc'ed structues. The current one I'm looking at is the getpwnam cache, but there are others around. (This used to be commit ea0e5ad9a15c848904dee8cb2d3e392b6a894705) --- source3/lib/memcache.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/memcache.c b/source3/lib/memcache.c index 38bbd66085..192a822cde 100644 --- a/source3/lib/memcache.c +++ b/source3/lib/memcache.c @@ -37,11 +37,38 @@ struct memcache { size_t max_size; }; +static void memcache_element_parse(struct memcache_element *e, + DATA_BLOB *key, DATA_BLOB *value); + +static bool memcache_is_talloc(enum memcache_number n) +{ + bool result; + + switch (n) { + case GETPWNAM_CACHE: + result = true; + break; + default: + result = false; + break; + } + + return result; +} + static int memcache_destructor(struct memcache *cache) { struct memcache_element *e, *next; for (e = cache->mru; e != NULL; e = next) { next = e->next; + if (memcache_is_talloc(e->n) + && (e->valuelength == sizeof(void *))) { + DATA_BLOB key, value; + void *ptr; + memcache_element_parse(e, &key, &value); + memcpy(&ptr, value.data, sizeof(ptr)); + TALLOC_FREE(ptr); + } SAFE_FREE(e); } return 0; @@ -156,6 +183,25 @@ bool memcache_lookup(struct memcache *cache, enum memcache_number n, return true; } +void *memcache_lookup_talloc(struct memcache *cache, enum memcache_number n, + DATA_BLOB key) +{ + DATA_BLOB value; + void *result; + + if (!memcache_lookup(cache, n, key, &value)) { + return NULL; + } + + if (value.length != sizeof(result)) { + return NULL; + } + + memcpy(&result, value.data, sizeof(result)); + + return result; +} + static void memcache_delete_element(struct memcache *cache, struct memcache_element *e) { @@ -283,6 +329,12 @@ void memcache_add(struct memcache *cache, enum memcache_number n, memcache_trim(cache); } +void memcache_add_talloc(struct memcache *cache, enum memcache_number n, + DATA_BLOB key, void *ptr) +{ + return memcache_add(cache, n, key, data_blob_const(&ptr, sizeof(ptr))); +} + void memcache_flush(struct memcache *cache, enum memcache_number n) { struct rb_node *node; -- cgit From 44d086a15f4908a01d0c719498fde953bd4809e7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 20 Dec 2007 14:54:33 +0100 Subject: Convert the pwnam cache to memcache (This used to be commit 032c5589fe7f9f2fcb0f336e72517a81a720b6ce) --- source3/lib/util_pw.c | 68 ++++++++++++--------------------------------------- 1 file changed, 15 insertions(+), 53 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/util_pw.c b/source3/lib/util_pw.c index 1973626d84..428378505f 100644 --- a/source3/lib/util_pw.c +++ b/source3/lib/util_pw.c @@ -37,74 +37,36 @@ struct passwd *tcopy_passwd(TALLOC_CTX *mem_ctx, const struct passwd *from) return ret; } -#define PWNAMCACHE_SIZE 4 -static struct passwd **pwnam_cache = NULL; - -static void init_pwnam_cache(void) -{ - if (pwnam_cache != NULL) - return; - - pwnam_cache = TALLOC_ZERO_ARRAY(NULL, struct passwd *, - PWNAMCACHE_SIZE); - if (pwnam_cache == NULL) { - smb_panic("Could not init pwnam_cache"); - } - - return; -} - void flush_pwnam_cache(void) { - TALLOC_FREE(pwnam_cache); - pwnam_cache = NULL; - init_pwnam_cache(); + memcache_flush(NULL, GETPWNAM_CACHE); } struct passwd *getpwnam_alloc(TALLOC_CTX *mem_ctx, const char *name) { - int i; - - struct passwd *temp; + struct passwd *temp, *cached; - init_pwnam_cache(); - - for (i=0; ipw_name) == 0)) { - DEBUG(10, ("Got %s from pwnam_cache\n", name)); - return tcopy_passwd(mem_ctx, pwnam_cache[i]); - } + temp = (struct passwd *)memcache_lookup_talloc( + NULL, GETPWNAM_CACHE, data_blob_string_const(name)); + if (temp != NULL) { + return tcopy_passwd(mem_ctx, temp); } temp = sys_getpwnam(name); - - if (!temp) { -#if 0 - if (errno == ENOMEM) { - /* what now? */ - } -#endif + if (temp == NULL) { return NULL; } - for (i=0; i Date: Wed, 19 Dec 2007 21:59:28 +0100 Subject: Remove next_token_nr_talloc and its associated global Only client.c and clitar.c used this, I think they should carry the static themselves. Also move the a bit funny routine toktocliplist to clitar.c, the only place where it is used. (This used to be commit 86d9412611fd99c21e15c71d30a3f95e35d8535b) --- source3/lib/util_str.c | 77 -------------------------------------------------- 1 file changed, 77 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index ee76e33de8..7e21fe1195 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -136,83 +136,6 @@ bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx, return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false); } -/** -This is like next_token but is not re-entrant and "remembers" the first -parameter so you can pass NULL. This is useful for user interface code -but beware the fact that it is not re-entrant! -**/ - -static const char *last_ptr=NULL; - -bool next_token_nr_talloc(TALLOC_CTX *ctx, - const char **ptr, - char **pp_buff, - const char *sep) -{ - bool ret; - if (!ptr) { - ptr = &last_ptr; - } - - ret = next_token_talloc(ctx, ptr, pp_buff, sep); - last_ptr = *ptr; - return ret; -} - -void set_first_token(char *ptr) -{ - last_ptr = ptr; -} - -/** - Convert list of tokens to array; dependent on above routine. - Uses last_ptr from above - bit of a hack. -**/ - -char **toktocliplist(int *ctok, const char *sep) -{ - char *s=(char *)last_ptr; - int ictok=0; - char **ret, **iret; - - if (!sep) - sep = " \t\n\r"; - - while(*s && strchr_m(sep,*s)) - s++; - - /* nothing left? */ - if (!*s) - return(NULL); - - do { - ictok++; - while(*s && (!strchr_m(sep,*s))) - s++; - while(*s && strchr_m(sep,*s)) - *s++=0; - } while(*s); - - *ctok=ictok; - s=(char *)last_ptr; - - if (!(ret=iret=SMB_MALLOC_ARRAY(char *,ictok+1))) - return NULL; - - while(ictok--) { - *iret++=s; - if (ictok > 0) { - while(*s++) - ; - while(!*s) - s++; - } - } - - ret[*ctok] = NULL; - return ret; -} - /** * Case insensitive string compararison. * -- cgit From 0565bc733566462bace3bf9dd17a6fe6cbe87db5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 20 Dec 2007 15:16:25 +0100 Subject: Make data_blob_string_const return null terminated strings ... nobody was using it, so we're free to change it now :-) (This used to be commit 4b06c68482247d859ec30b8b1920706e43358989) --- source3/lib/data_blob.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/data_blob.c b/source3/lib/data_blob.c index e64e6a19a1..8bbbc32d7b 100644 --- a/source3/lib/data_blob.c +++ b/source3/lib/data_blob.c @@ -128,7 +128,7 @@ DATA_BLOB data_blob_string_const(const char *str) { DATA_BLOB blob; blob.data = CONST_DISCARD(uint8 *, str); - blob.length = strlen(str); + blob.length = strlen(str) + 1; blob.free = NULL; return blob; } -- cgit From 89f7883fe9b62248e8cc9e508ddef3a26330f71c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 20 Dec 2007 16:05:57 +0100 Subject: Add a singleton cache First user is yp_default_domain (This used to be commit c19363eb77fcc3e1bf3341e6373d38f1e91fc08f) --- source3/lib/access.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/access.c b/source3/lib/access.c index 1e4df83607..6a463446d1 100644 --- a/source3/lib/access.c +++ b/source3/lib/access.c @@ -97,13 +97,29 @@ static bool string_match(const char *tok,const char *s) } } else if (tok[0] == '@') { /* netgroup: look it up */ #ifdef HAVE_NETGROUP - static char *mydomain = NULL; + DATA_BLOB tmp; + char *mydomain = NULL; char *hostname = NULL; bool netgroup_ok = false; - if (!mydomain) + if (memcache_lookup( + NULL, SINGLETON_CACHE, + data_blob_string_const("yp_default_domain"), + &tmp)) { + + SMB_ASSERT(tmp.length > 0); + mydomain = (tmp.data[0] == '\0') + ? NULL : (char *)tmp.data; + } + else { yp_get_default_domain(&mydomain); + memcache_add( + NULL, SINGLETON_CACHE, + data_blob_string_const("yp_default_domain"), + data_blob_string_const(mydomain?mydomain:"")); + } + if (!mydomain) { DEBUG(0,("Unable to get default yp domain. " "Try without it.\n")); -- cgit From 184c927bf5a5107db38cdb3ae7b518826ecb7133 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 9 Dec 2007 18:25:34 +0100 Subject: Remove some statics from md4.c (This used to be commit 7e193c68b2a7eb16afc12379a4ceed41053d1eeb) --- source3/lib/md4.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/md4.c b/source3/lib/md4.c index 61d5848aae..bae0091e36 100644 --- a/source3/lib/md4.c +++ b/source3/lib/md4.c @@ -24,7 +24,14 @@ It assumes that a int is at least 32 bits long */ +#if 0 static uint32 A, B, C, D; +#else +#define A (state[0]) +#define B (state[1]) +#define C (state[2]) +#define D (state[3]) +#endif static uint32 F(uint32 X, uint32 Y, uint32 Z) { @@ -52,7 +59,7 @@ static uint32 lshift(uint32 x, int s) #define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + (uint32)0x6ED9EBA1,s) /* this applies md4 to 64 byte chunks */ -static void mdfour64(uint32 *M) +static void mdfour64(uint32_t *state, uint32 *M) { int j; uint32 AA, BB, CC, DD; @@ -121,6 +128,7 @@ void mdfour(unsigned char *out, const unsigned char *in, int n) { unsigned char buf[128]; uint32 M[16]; + uint32 state[4]; uint32 b = n * 8; int i; @@ -131,7 +139,7 @@ void mdfour(unsigned char *out, const unsigned char *in, int n) while (n > 64) { copy64(M, in); - mdfour64(M); + mdfour64(state, M); in += 64; n -= 64; } @@ -144,13 +152,13 @@ void mdfour(unsigned char *out, const unsigned char *in, int n) if (n <= 55) { copy4(buf+56, b); copy64(M, buf); - mdfour64(M); + mdfour64(state, M); } else { copy4(buf+120, b); copy64(M, buf); - mdfour64(M); + mdfour64(state, M); copy64(M, buf+64); - mdfour64(M); + mdfour64(state, M); } for (i=0;i<128;i++) @@ -161,8 +169,6 @@ void mdfour(unsigned char *out, const unsigned char *in, int n) copy4(out+4, B); copy4(out+8, C); copy4(out+12, D); - - A = B = C = D = 0; } -- cgit From 0cdf5cfdfbb6b412e1d365af4f2daf20087b37f5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 20 Dec 2007 20:59:27 +0100 Subject: Fix a missing prototype warning (This used to be commit 93e5de23e7109432f554745b18c6d630a39f9c2b) --- source3/lib/netapi/joindomain.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index 210763174e..10f7e94835 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -18,6 +18,7 @@ */ #include "includes.h" +#include "lib/netapi/joindomain.h" extern const char *opt_user_name; extern const char *opt_workgroup; -- cgit From addf598cde41d17ad4cf497a64b9a2b27e4028c5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 20 Dec 2007 22:17:16 +0100 Subject: Some C++ warnings (This used to be commit 5ab82d4f574f2a2e2761e9e414c66a70aeffb05d) --- source3/lib/memcache.c | 2 +- source3/lib/socket_wrapper/socket_wrapper.c | 4 ++-- source3/lib/time.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/memcache.c b/source3/lib/memcache.c index 192a822cde..448b8b2f84 100644 --- a/source3/lib/memcache.c +++ b/source3/lib/memcache.c @@ -61,7 +61,7 @@ static int memcache_destructor(struct memcache *cache) { for (e = cache->mru; e != NULL; e = next) { next = e->next; - if (memcache_is_talloc(e->n) + if (memcache_is_talloc((enum memcache_number)e->n) && (e->valuelength == sizeof(void *))) { DATA_BLOB key, value; void *ptr; diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index 3a72c5a74a..a84c460114 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/lib/socket_wrapper/socket_wrapper.c @@ -571,8 +571,8 @@ static const char *socket_wrapper_pcap_file(void) { static int initialized = 0; static const char *s = NULL; - static const struct swrap_file_hdr h; - static const struct swrap_packet p; + static const struct swrap_file_hdr h = { 0, }; + static const struct swrap_packet p = { 0, }; if (initialized == 1) { return s; diff --git a/source3/lib/time.c b/source3/lib/time.c index 5301e3a55a..f98e03197f 100644 --- a/source3/lib/time.c +++ b/source3/lib/time.c @@ -1382,7 +1382,7 @@ void unix_to_nt_time_abs(NTTIME *nt, time_t t) d = (double)(t); d *= 1.0e7; - *nt = d; + *nt = (NTTIME)d; /* convert to a negative value */ *nt=~*nt; @@ -1443,7 +1443,7 @@ const char *display_time(NTTIME nttime) low = ~(nttime & 0xFFFFFFFF); low = low/(1000*1000*10); - sec=high+low; + sec=(int)(high+low); days=sec/(60*60*24); hours=(sec - (days*60*60*24)) / (60*60); -- cgit From 99b86e4a266b99634f6a65015f6df115c421d3e5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 20 Dec 2007 22:27:01 +0100 Subject: Some C++ fixes (This used to be commit 5c392c4c6e277a24d0d477902dc7856b2b46ee53) --- source3/lib/secace.c | 5 +++-- source3/lib/secacl.c | 3 ++- source3/lib/secdesc.c | 12 ++++++++---- source3/lib/sharesec.c | 10 +++++++--- source3/lib/util_seaccess.c | 4 +++- 5 files changed, 23 insertions(+), 11 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/secace.c b/source3/lib/secace.c index 9e533a5a28..90ecc342cd 100644 --- a/source3/lib/secace.c +++ b/source3/lib/secace.c @@ -54,7 +54,8 @@ void sec_ace_copy(SEC_ACE *ace_dest, SEC_ACE *ace_src) Sets up a SEC_ACE structure. ********************************************************************/ -void init_sec_ace(SEC_ACE *t, const DOM_SID *sid, uint8 type, uint32 mask, uint8 flag) +void init_sec_ace(SEC_ACE *t, const DOM_SID *sid, enum security_ace_type type, + uint32 mask, uint8 flag) { t->type = type; t->flags = flag; @@ -83,7 +84,7 @@ NTSTATUS sec_ace_add_sid(TALLOC_CTX *ctx, SEC_ACE **pp_new, SEC_ACE *old, unsign for (i = 0; i < *num - 1; i ++) sec_ace_copy(&(*pp_new)[i], &old[i]); - (*pp_new)[i].type = 0; + (*pp_new)[i].type = SEC_ACE_TYPE_ACCESS_ALLOWED; (*pp_new)[i].flags = 0; (*pp_new)[i].size = SEC_ACE_HEADER_SIZE + sid_size(sid); (*pp_new)[i].access_mask = mask; diff --git a/source3/lib/secacl.c b/source3/lib/secacl.c index 328bc1b4b4..5e82242e1b 100644 --- a/source3/lib/secacl.c +++ b/source3/lib/secacl.c @@ -26,7 +26,8 @@ Create a SEC_ACL structure. ********************************************************************/ -SEC_ACL *make_sec_acl(TALLOC_CTX *ctx, uint16 revision, int num_aces, SEC_ACE *ace_list) +SEC_ACL *make_sec_acl(TALLOC_CTX *ctx, enum security_acl_revision revision, + int num_aces, SEC_ACE *ace_list) { SEC_ACL *dst; int i; diff --git a/source3/lib/secdesc.c b/source3/lib/secdesc.c index 4a9785009b..123c3bcc9b 100644 --- a/source3/lib/secdesc.c +++ b/source3/lib/secdesc.c @@ -182,7 +182,9 @@ SEC_DESC_BUF *sec_desc_merge(TALLOC_CTX *ctx, SEC_DESC_BUF *new_sdb, SEC_DESC_BU Creates a SEC_DESC structure ********************************************************************/ -SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision, uint16 type, +SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, + enum security_descriptor_revision revision, + uint16 type, const DOM_SID *owner_sid, const DOM_SID *grp_sid, SEC_ACL *sacl, SEC_ACL *dacl, size_t *sd_size) { @@ -329,8 +331,9 @@ NTSTATUS unmarshall_sec_desc(TALLOC_CTX *mem_ctx, uint8 *data, size_t len, SEC_DESC *make_standard_sec_desc(TALLOC_CTX *ctx, const DOM_SID *owner_sid, const DOM_SID *grp_sid, SEC_ACL *dacl, size_t *sd_size) { - return make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, - owner_sid, grp_sid, NULL, dacl, sd_size); + return make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1, + SEC_DESC_SELF_RELATIVE, owner_sid, grp_sid, NULL, + dacl, sd_size); } /******************************************************************* @@ -557,7 +560,8 @@ SEC_DESC_BUF *se_create_child_secdesc(TALLOC_CTX *ctx, SEC_DESC *parent_ctr, correct. Perhaps the user and group should be passed in as parameters by the caller? */ - sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, + sd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1, + SEC_DESC_SELF_RELATIVE, parent_ctr->owner_sid, parent_ctr->group_sid, parent_ctr->sacl, diff --git a/source3/lib/sharesec.c b/source3/lib/sharesec.c index b3b000579f..0027a8813a 100644 --- a/source3/lib/sharesec.c +++ b/source3/lib/sharesec.c @@ -92,7 +92,9 @@ SEC_DESC *get_share_security_default( TALLOC_CTX *ctx, size_t *psize, uint32 def init_sec_ace(&ace, &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 0); if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 1, &ace)) != NULL) { - psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, psize); + psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1, + SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, + psa, psize); } if (!psd) { @@ -291,7 +293,7 @@ bool parse_usershare_acl(TALLOC_CTX *ctx, const char *acl_str, SEC_DESC **ppsd) uint32 s_access; DOM_SID sid; char *sidstr; - uint8 type = SEC_ACE_TYPE_ACCESS_ALLOWED; + enum security_ace_type type = SEC_ACE_TYPE_ACCESS_ALLOWED; if (!next_token_talloc(ctx, &pacl, &sidstr, ":")) { DEBUG(0,("parse_usershare_acl: malformed usershare acl looking " @@ -339,7 +341,9 @@ bool parse_usershare_acl(TALLOC_CTX *ctx, const char *acl_str, SEC_DESC **ppsd) } if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, num_aces, ace_list)) != NULL) { - psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, &sd_size); + psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1, + SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, + psa, &sd_size); } if (!psd) { diff --git a/source3/lib/util_seaccess.c b/source3/lib/util_seaccess.c index 0481eea5f0..87e70bb95b 100644 --- a/source3/lib/util_seaccess.c +++ b/source3/lib/util_seaccess.c @@ -350,7 +350,9 @@ NTSTATUS samr_make_sam_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size) if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL) return NT_STATUS_NO_MEMORY; - if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL) + if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1, + SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, + psa, sd_size)) == NULL) return NT_STATUS_NO_MEMORY; return NT_STATUS_OK; -- cgit From 4418b989e7009c63d2206cecdfaa50cc66e1d8da Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 21 Dec 2007 12:53:12 +0100 Subject: Fix the build on Solaris (This used to be commit 5f5e52ba7b3862dc72a16d84e07503e98ccbbf8a) --- source3/lib/memcache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/memcache.c b/source3/lib/memcache.c index 448b8b2f84..457586bd68 100644 --- a/source3/lib/memcache.c +++ b/source3/lib/memcache.c @@ -332,7 +332,7 @@ void memcache_add(struct memcache *cache, enum memcache_number n, void memcache_add_talloc(struct memcache *cache, enum memcache_number n, DATA_BLOB key, void *ptr) { - return memcache_add(cache, n, key, data_blob_const(&ptr, sizeof(ptr))); + memcache_add(cache, n, key, data_blob_const(&ptr, sizeof(ptr))); } void memcache_flush(struct memcache *cache, enum memcache_number n) -- cgit From 72ffac399077ad7777f1282c94d9b661e7fa53fb Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 6 Dec 2007 19:04:49 +0100 Subject: Add NetGetJoinInformation(). Guenther (This used to be commit d341d251d6e22e9cc1c4596038fd5fe5c7c6c174) --- source3/lib/netapi/joindomain.c | 53 +++++++++++++++++++++++++++++++++++++++++ source3/lib/netapi/joindomain.h | 3 +++ 2 files changed, 56 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index 10f7e94835..6da4548f05 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -181,3 +181,56 @@ WERROR NetUnjoinDomain(const char *server_name, return werr; } + +WERROR NetGetJoinInformation(const char *server_name, + const char **name_buffer, + uint16_t *name_type) +{ + TALLOC_CTX *mem_ctx = NULL; + struct cli_state *cli = NULL; + struct rpc_pipe_client *pipe_cli = NULL; + NTSTATUS status; + WERROR werr; + + mem_ctx = talloc_init("NetGetJoinInformation"); + if (!mem_ctx) { + werr = WERR_NOMEM; + goto done; + } + + status = cli_full_connection(&cli, NULL, server_name, + NULL, 0, + "IPC$", "IPC", + opt_user_name, opt_workgroup, + opt_password, 0, Undefined, NULL); + + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); + goto done; + } + + pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_WKSSVC, + &status); + if (!pipe_cli) { + werr = ntstatus_to_werror(status); + goto done; + }; + + status = rpccli_wkssvc_NetrGetJoinInformation(pipe_cli, mem_ctx, + server_name, + name_buffer, + (enum wkssvc_NetJoinStatus *)name_type, + &werr); + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); + goto done; + } + + done: + if (cli) { + cli_shutdown(cli); + } + TALLOC_FREE(mem_ctx); + + return werr; +} diff --git a/source3/lib/netapi/joindomain.h b/source3/lib/netapi/joindomain.h index 2c71702db7..d0badd979d 100644 --- a/source3/lib/netapi/joindomain.h +++ b/source3/lib/netapi/joindomain.h @@ -27,3 +27,6 @@ WERROR NetUnjoinDomain(const char *server_name, const char *account, const char *password, uint32_t unjoin_flags); +WERROR NetGetJoinInformation(const char *server_name, + const char **name_buffer, + uint16_t *name_type); -- cgit From 67aa44e7a230cb3cf35c184692bf5249d6d424cf Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 11 Dec 2007 21:23:40 +0100 Subject: Split NetJoinDomain() into NetJoinDomainRemote() and the unsupported NetJoinDomainLocal(). Guenther (This used to be commit d2f21ce6727ec9e4df67989db07b48470d0790a4) --- source3/lib/netapi/joindomain.c | 96 +++++++++++++++++++++++++++++++---------- 1 file changed, 73 insertions(+), 23 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index 6da4548f05..1b951d7a5c 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -24,14 +24,25 @@ extern const char *opt_user_name; extern const char *opt_workgroup; extern const char *opt_password; -WERROR NetJoinDomain(const char *server_name, - const char *domain_name, - const char *account_ou, - const char *Account, - const char *password, - uint32_t join_flags) +static WERROR NetJoinDomainLocal(TALLOC_CTX *mem_ctx, + const char *server_name, + const char *domain_name, + const char *account_ou, + const char *Account, + const char *password, + uint32_t join_flags) +{ + return WERR_NOT_SUPPORTED; +} + +static WERROR NetJoinDomainRemote(TALLOC_CTX *mem_ctx, + const char *server_name, + const char *domain_name, + const char *account_ou, + const char *Account, + const char *password, + uint32_t join_flags) { - TALLOC_CTX *mem_ctx = NULL; struct cli_state *cli = NULL; struct rpc_pipe_client *pipe_cli = NULL; struct wkssvc_PasswordBuffer encrypted_password; @@ -41,22 +52,6 @@ WERROR NetJoinDomain(const char *server_name, ZERO_STRUCT(encrypted_password); - mem_ctx = talloc_init("NetJoinDomain"); - if (!mem_ctx) { - werr = WERR_NOMEM; - goto done; - } - - if (!server_name || is_myname_or_ipaddr(server_name)) { - werr = WERR_NOT_SUPPORTED; - goto done; - } - - if (!domain_name) { - werr = WERR_INVALID_PARAM; - goto done; - } - status = cli_full_connection(&cli, NULL, server_name, NULL, 0, "IPC$", "IPC", @@ -101,6 +96,61 @@ WERROR NetJoinDomain(const char *server_name, cli_set_timeout(cli, old_timeout); cli_shutdown(cli); } + + return werr; +} + +WERROR NetJoinDomain(const char *server_name, + const char *domain_name, + const char *account_ou, + const char *Account, + const char *password, + uint32_t join_flags) +{ + TALLOC_CTX *mem_ctx = NULL; + WERROR werr; + + mem_ctx = talloc_init("NetJoinDomain"); + if (!mem_ctx) { + werr = WERR_NOMEM; + goto done; + } + + if (!domain_name) { + werr = WERR_INVALID_PARAM; + goto done; + } + + if (!server_name || is_myname_or_ipaddr(server_name)) { + + const char *dc = NULL; + + /* FIXME: DsGetDcName */ + if (server_name == NULL) { + dc = domain_name; + } else { + dc = domain_name; + } + + werr = NetJoinDomainLocal(mem_ctx, + dc, + domain_name, + account_ou, + Account, + password, + join_flags); + + goto done; + } + + werr = NetJoinDomainRemote(mem_ctx, + server_name, + domain_name, + account_ou, + Account, + password, + join_flags); +done: TALLOC_FREE(mem_ctx); return werr; -- cgit From 4f6e8dfa51dfef72d13efc4acd3ede37d1f69eac Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 11 Dec 2007 21:32:16 +0100 Subject: Fill in NetJoinDomainLocal(). Guenther (This used to be commit 4896f22bb50ea9ae0c4807ed9b2dd4283c254364) --- source3/lib/netapi/joindomain.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index 1b951d7a5c..96983d43e3 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -32,7 +32,41 @@ static WERROR NetJoinDomainLocal(TALLOC_CTX *mem_ctx, const char *password, uint32_t join_flags) { - return WERR_NOT_SUPPORTED; + struct libnet_JoinCtx *r = NULL; + WERROR werr; + + werr = libnet_init_JoinCtx(mem_ctx, &r); + W_ERROR_NOT_OK_RETURN(werr); + + if (!server_name || !domain_name) { + return WERR_INVALID_PARAM; + } + + r->in.server_name = talloc_strdup(mem_ctx, server_name); + W_ERROR_HAVE_NO_MEMORY(r->in.server_name); + + r->in.domain_name = talloc_strdup(mem_ctx, domain_name); + W_ERROR_HAVE_NO_MEMORY(r->in.domain_name); + + if (account_ou) { + r->in.account_ou = talloc_strdup(mem_ctx, account_ou); + W_ERROR_HAVE_NO_MEMORY(r->in.account_ou); + } + + if (Account) { + r->in.admin_account = talloc_strdup(mem_ctx, Account); + W_ERROR_HAVE_NO_MEMORY(r->in.admin_account); + } + + if (password) { + r->in.password = talloc_strdup(mem_ctx, password); + W_ERROR_HAVE_NO_MEMORY(r->in.password); + } + + r->in.join_flags = join_flags; + r->in.modify_config = true; + + return libnet_Join(mem_ctx, r); } static WERROR NetJoinDomainRemote(TALLOC_CTX *mem_ctx, -- cgit From 749f699f871831e9ad5b2a57e498a32f959d23c6 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 12 Dec 2007 18:14:54 +0100 Subject: Build fixes for libnetapi. Guenther (This used to be commit 07d33557b95106ac57fdef8c767ab86192930a6d) --- source3/lib/netapi/netapi.c | 76 +++++++++++++++++++++++++++++++++++++++++++++ source3/lib/netapi/netapi.h | 26 ++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 source3/lib/netapi/netapi.c create mode 100644 source3/lib/netapi/netapi.h (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c new file mode 100644 index 0000000000..3da492bbe7 --- /dev/null +++ b/source3/lib/netapi/netapi.c @@ -0,0 +1,76 @@ +/* + * Unix SMB/CIFS implementation. + * NetApi Support + * Copyright (C) Guenther Deschner 2007 + * + * 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 3 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, see . + */ + +#include "includes.h" +#include "lib/netapi/netapi.h" + +extern bool AllowDebugChange; + +static bool libnetapi_initialized = false; + +WERROR libnetapi_init(struct libnetapi_ctx **context) +{ + struct libnetapi_ctx *ctx = NULL; + TALLOC_CTX *frame = NULL; + + if (libnetapi_initialized) { + return WERR_OK; + } + + frame = talloc_stackframe(); + + ctx = talloc_zero(frame, struct libnetapi_ctx); + if (!ctx) { + TALLOC_FREE(frame); + return WERR_NOMEM; + } + + DEBUGLEVEL = 0; + DEBUGLEVEL_CLASS[DBGC_ALL] = 0; + dbf = x_stderr; + x_setbuf(x_stderr, NULL); + AllowDebugChange = false; + + load_case_tables(); + + setup_logging("libnetapi", true); + + if (!lp_load(get_dyn_CONFIGFILE(), true, false, false, false)) { + TALLOC_FREE(frame); + return WERR_GENERAL_FAILURE; + } + + init_names(); + load_interfaces(); + reopen_logs(); + + BlockSignals(True, SIGPIPE); + + libnetapi_initialized = true; + + *context = ctx; + + return WERR_OK; +} + +WERROR libnetapi_free(struct libnetapi_ctx *ctx) +{ + TALLOC_FREE(ctx); + return WERR_OK; +} diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h new file mode 100644 index 0000000000..ad9fbe4209 --- /dev/null +++ b/source3/lib/netapi/netapi.h @@ -0,0 +1,26 @@ +/* + * Unix SMB/CIFS implementation. + * NetApi Support + * Copyright (C) Guenther Deschner 2007 + * + * 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 3 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, see . + */ + +struct libnetapi_ctx { + int debuglevel; +}; + +WERROR libnetapi_init(struct libnetapi_ctx **ctx); + +#include "joindomain.h" -- cgit From 7482a18c83d25b2d00e1086aafb33d9a0ff98309 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 12 Dec 2007 19:00:41 +0100 Subject: More minor libnetapi fixes. Guenther (This used to be commit 9f129c069f9feb357cbe1185058cfe3390609c09) --- source3/lib/netapi/netapi.h | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h index ad9fbe4209..ec629d56d9 100644 --- a/source3/lib/netapi/netapi.h +++ b/source3/lib/netapi/netapi.h @@ -22,5 +22,6 @@ struct libnetapi_ctx { }; WERROR libnetapi_init(struct libnetapi_ctx **ctx); +WERROR libnetapi_free(struct libnetapi_ctx *ctx); #include "joindomain.h" -- cgit From 5b5f75d229978d5b9fe14dca768fd8b68d2ab319 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 13 Dec 2007 16:21:27 +0100 Subject: Fill in local branch of NetGetJoinInformation(). Guenther (This used to be commit 46db8754511f915c296771e08e822ba810f804d5) --- source3/lib/netapi/joindomain.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index 96983d43e3..bc26c22370 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -282,6 +282,32 @@ WERROR NetGetJoinInformation(const char *server_name, goto done; } + if (!server_name || is_myname_or_ipaddr(server_name)) { + if ((lp_security() == SEC_ADS) && lp_realm()) { + *name_buffer = SMB_STRDUP(lp_realm()); + } else { + *name_buffer = SMB_STRDUP(lp_workgroup()); + } + if (!*name_buffer) { + werr = WERR_NOMEM; + goto done; + } + switch (lp_server_role()) { + case ROLE_DOMAIN_MEMBER: + case ROLE_DOMAIN_PDC: + case ROLE_DOMAIN_BDC: + *name_type = NetSetupDomainName; + break; + case ROLE_STANDALONE: + default: + *name_type = NetSetupWorkgroupName; + break; + } + + werr = WERR_OK; + goto done; + } + status = cli_full_connection(&cli, NULL, server_name, NULL, 0, "IPC$", "IPC", -- cgit From 41410c86cc698f997dd82a143fd92277060384b0 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 14 Dec 2007 12:22:20 +0100 Subject: Some libnet and netapi build fixes. Guenther (This used to be commit 1d47247283f7bc75291007be3fde72b1d3d95b99) --- source3/lib/netapi/joindomain.h | 5 +++++ source3/lib/netapi/netapi.h | 5 +++++ 2 files changed, 10 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.h b/source3/lib/netapi/joindomain.h index d0badd979d..73d2ec3d32 100644 --- a/source3/lib/netapi/joindomain.h +++ b/source3/lib/netapi/joindomain.h @@ -17,6 +17,9 @@ * along with this program; if not, see . */ +#ifndef __LIB_NETAPI_JOINDOMAIN_H__ +#define __LIB_NETAPI_JOINDOMAIN_H__ + WERROR NetJoinDomain(const char *server, const char *domain, const char *account_ou, @@ -30,3 +33,5 @@ WERROR NetUnjoinDomain(const char *server_name, WERROR NetGetJoinInformation(const char *server_name, const char **name_buffer, uint16_t *name_type); + +#endif diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h index ec629d56d9..0810ecb7bc 100644 --- a/source3/lib/netapi/netapi.h +++ b/source3/lib/netapi/netapi.h @@ -17,6 +17,9 @@ * along with this program; if not, see . */ +#ifndef __LIB_NETAPI_H__ +#define __LIB_NETAPI_H__ + struct libnetapi_ctx { int debuglevel; }; @@ -25,3 +28,5 @@ WERROR libnetapi_init(struct libnetapi_ctx **ctx); WERROR libnetapi_free(struct libnetapi_ctx *ctx); #include "joindomain.h" + +#endif -- cgit From 9dc0ac4637fdd05a95099c0a6a857c51ca811453 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 18 Dec 2007 02:15:49 +0100 Subject: Getting rid of external credentials in libnetapi. Guenther (This used to be commit c10481dba01a084b0f9c4265f3408a0ec9a8b646) --- source3/lib/netapi/joindomain.c | 16 ++++++++-------- source3/lib/netapi/netapi.h | 3 +++ 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index bc26c22370..8287cd046f 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -20,10 +20,6 @@ #include "includes.h" #include "lib/netapi/joindomain.h" -extern const char *opt_user_name; -extern const char *opt_workgroup; -extern const char *opt_password; - static WERROR NetJoinDomainLocal(TALLOC_CTX *mem_ctx, const char *server_name, const char *domain_name, @@ -219,8 +215,10 @@ WERROR NetUnjoinDomain(const char *server_name, status = cli_full_connection(&cli, NULL, server_name, NULL, 0, "IPC$", "IPC", - opt_user_name, opt_workgroup, - opt_password, 0, Undefined, NULL); + ctx->username, + ctx->workgroup, + ctx->password, + 0, Undefined, NULL); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); @@ -311,8 +309,10 @@ WERROR NetGetJoinInformation(const char *server_name, status = cli_full_connection(&cli, NULL, server_name, NULL, 0, "IPC$", "IPC", - opt_user_name, opt_workgroup, - opt_password, 0, Undefined, NULL); + ctx->username, + ctx->workgroup, + ctx->password, + 0, Undefined, NULL); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h index 0810ecb7bc..0637570c3e 100644 --- a/source3/lib/netapi/netapi.h +++ b/source3/lib/netapi/netapi.h @@ -22,6 +22,9 @@ struct libnetapi_ctx { int debuglevel; + char *username; + char *workgroup; + char *password; }; WERROR libnetapi_init(struct libnetapi_ctx **ctx); -- cgit From 4dd84b351125cdd95c945d8820ffe078f7325988 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 18 Dec 2007 02:21:38 +0100 Subject: Define NET_API_STATUS to be just a uin32_t. Guenther (This used to be commit a42850926a26a4065a6126affc3754d291a2e178) --- source3/lib/netapi/netapi.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h index 0637570c3e..7946cfb446 100644 --- a/source3/lib/netapi/netapi.h +++ b/source3/lib/netapi/netapi.h @@ -20,6 +20,8 @@ #ifndef __LIB_NETAPI_H__ #define __LIB_NETAPI_H__ +#define NET_API_STATUS uint32_t + struct libnetapi_ctx { int debuglevel; char *username; -- cgit From 3d853b8e7e975a3e1c07a125e775e3a597112912 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 18 Dec 2007 02:29:50 +0100 Subject: Move basic libnetapi functions to NET_API_STATUS. Guenther (This used to be commit 086c55005976b3173e915e465108214876aa5bd6) --- source3/lib/netapi/netapi.c | 14 +++++++------- source3/lib/netapi/netapi.h | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c index 3da492bbe7..898e62d6a5 100644 --- a/source3/lib/netapi/netapi.c +++ b/source3/lib/netapi/netapi.c @@ -24,13 +24,13 @@ extern bool AllowDebugChange; static bool libnetapi_initialized = false; -WERROR libnetapi_init(struct libnetapi_ctx **context) +NET_API_STATUS libnetapi_init(struct libnetapi_ctx **context) { struct libnetapi_ctx *ctx = NULL; TALLOC_CTX *frame = NULL; if (libnetapi_initialized) { - return WERR_OK; + return W_ERROR_V(WERR_OK); } frame = talloc_stackframe(); @@ -38,7 +38,7 @@ WERROR libnetapi_init(struct libnetapi_ctx **context) ctx = talloc_zero(frame, struct libnetapi_ctx); if (!ctx) { TALLOC_FREE(frame); - return WERR_NOMEM; + return W_ERROR_V(WERR_NOMEM); } DEBUGLEVEL = 0; @@ -53,7 +53,7 @@ WERROR libnetapi_init(struct libnetapi_ctx **context) if (!lp_load(get_dyn_CONFIGFILE(), true, false, false, false)) { TALLOC_FREE(frame); - return WERR_GENERAL_FAILURE; + return W_ERROR_V(WERR_GENERAL_FAILURE); } init_names(); @@ -66,11 +66,11 @@ WERROR libnetapi_init(struct libnetapi_ctx **context) *context = ctx; - return WERR_OK; + return W_ERROR_V(WERR_OK); } -WERROR libnetapi_free(struct libnetapi_ctx *ctx) +NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx) { TALLOC_FREE(ctx); - return WERR_OK; + return W_ERROR_V(WERR_OK); } diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h index 7946cfb446..3dfbc0cffb 100644 --- a/source3/lib/netapi/netapi.h +++ b/source3/lib/netapi/netapi.h @@ -29,8 +29,8 @@ struct libnetapi_ctx { char *password; }; -WERROR libnetapi_init(struct libnetapi_ctx **ctx); -WERROR libnetapi_free(struct libnetapi_ctx *ctx); +NET_API_STATUS libnetapi_init(struct libnetapi_ctx **ctx); +NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx); #include "joindomain.h" -- cgit From c9b44e0fc3750afb6e001baceffad8fa2f33ac4e Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 18 Dec 2007 02:34:07 +0100 Subject: Add basic credential functions for libnetapi. Guenther (This used to be commit 7c38f706b5dc17f15708ac932c84d863a0cc713e) --- source3/lib/netapi/netapi.c | 33 +++++++++++++++++++++++++++++++++ source3/lib/netapi/netapi.h | 3 +++ 2 files changed, 36 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c index 898e62d6a5..38b44c769d 100644 --- a/source3/lib/netapi/netapi.c +++ b/source3/lib/netapi/netapi.c @@ -74,3 +74,36 @@ NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx) TALLOC_FREE(ctx); return W_ERROR_V(WERR_OK); } + +NET_API_STATUS libnetapi_set_username(struct libnetapi_ctx *ctx, + const char *username) +{ + TALLOC_FREE(ctx->username); + ctx->username = talloc_strdup(ctx, username); + if (!ctx->username) { + return W_ERROR_V(WERR_NOMEM); + } + return W_ERROR_V(WERR_OK); +} + +NET_API_STATUS libnetapi_set_password(struct libnetapi_ctx *ctx, + const char *password) +{ + TALLOC_FREE(ctx->password); + ctx->password = talloc_strdup(ctx, password); + if (!ctx->password) { + return W_ERROR_V(WERR_NOMEM); + } + return W_ERROR_V(WERR_OK); +} + +NET_API_STATUS libnetapi_set_workgroup(struct libnetapi_ctx *ctx, + const char *workgroup) +{ + TALLOC_FREE(ctx->workgroup); + ctx->workgroup = talloc_strdup(ctx, workgroup); + if (!ctx->workgroup) { + return W_ERROR_V(WERR_NOMEM); + } + return W_ERROR_V(WERR_OK); +} diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h index 3dfbc0cffb..d75299601f 100644 --- a/source3/lib/netapi/netapi.h +++ b/source3/lib/netapi/netapi.h @@ -31,6 +31,9 @@ struct libnetapi_ctx { NET_API_STATUS libnetapi_init(struct libnetapi_ctx **ctx); NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx); +NET_API_STATUS libnetapi_set_username(struct libnetapi_ctx *ctx, const char *username); +NET_API_STATUS libnetapi_set_password(struct libnetapi_ctx *ctx, const char *password); +NET_API_STATUS libnetapi_set_workgroup(struct libnetapi_ctx *ctx, const char *workgroup); #include "joindomain.h" -- cgit From d14ee1dc08c5c765b07bd472e47e34152db2f9d3 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 18 Dec 2007 02:43:22 +0100 Subject: Use full string based debug_parse_levels in libnetapi. Guenther (This used to be commit 78d8f0e41aa3db0060596a7b345c2f04261986e0) --- source3/lib/netapi/netapi.c | 25 ++++++++++++++++++++++--- source3/lib/netapi/netapi.h | 4 +++- 2 files changed, 25 insertions(+), 4 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c index 38b44c769d..454d766ae9 100644 --- a/source3/lib/netapi/netapi.c +++ b/source3/lib/netapi/netapi.c @@ -42,20 +42,21 @@ NET_API_STATUS libnetapi_init(struct libnetapi_ctx **context) } DEBUGLEVEL = 0; - DEBUGLEVEL_CLASS[DBGC_ALL] = 0; + setup_logging("libnetapi", true); + dbf = x_stderr; x_setbuf(x_stderr, NULL); AllowDebugChange = false; load_case_tables(); - setup_logging("libnetapi", true); - if (!lp_load(get_dyn_CONFIGFILE(), true, false, false, false)) { TALLOC_FREE(frame); return W_ERROR_V(WERR_GENERAL_FAILURE); } + AllowDebugChange = true; + init_names(); load_interfaces(); reopen_logs(); @@ -75,6 +76,24 @@ NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx) return W_ERROR_V(WERR_OK); } +NET_API_STATUS libnetapi_set_debuglevel(struct libnetapi_ctx *ctx, + const char *debuglevel) +{ + AllowDebugChange = true; + ctx->debuglevel = debuglevel; + if (!debug_parse_levels(debuglevel)) { + return W_ERROR_V(WERR_GENERAL_FAILURE); + } + return W_ERROR_V(WERR_OK); +} + +NET_API_STATUS libnetapi_get_debuglevel(struct libnetapi_ctx *ctx, + const char **debuglevel) +{ + *debuglevel = ctx->debuglevel; + return W_ERROR_V(WERR_OK); +} + NET_API_STATUS libnetapi_set_username(struct libnetapi_ctx *ctx, const char *username) { diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h index d75299601f..278922224d 100644 --- a/source3/lib/netapi/netapi.h +++ b/source3/lib/netapi/netapi.h @@ -23,7 +23,7 @@ #define NET_API_STATUS uint32_t struct libnetapi_ctx { - int debuglevel; + const char *debuglevel; char *username; char *workgroup; char *password; @@ -31,6 +31,8 @@ struct libnetapi_ctx { NET_API_STATUS libnetapi_init(struct libnetapi_ctx **ctx); NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx); +NET_API_STATUS libnetapi_set_debuglevel(struct libnetapi_ctx *ctx, const char *debuglevel); +NET_API_STATUS libnetapi_get_debuglevel(struct libnetapi_ctx *ctx, const char **debuglevel); NET_API_STATUS libnetapi_set_username(struct libnetapi_ctx *ctx, const char *username); NET_API_STATUS libnetapi_set_password(struct libnetapi_ctx *ctx, const char *password); NET_API_STATUS libnetapi_set_workgroup(struct libnetapi_ctx *ctx, const char *workgroup); -- cgit From fb2c13fe191212f5e782b398fa4dffa42bfba129 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 18 Dec 2007 02:47:01 +0100 Subject: Add static libnetapi_ctx. Guenther (This used to be commit 97449ea341539a709953a57869570cf13be0f44e) --- source3/lib/netapi/netapi.c | 28 +++++++++++++++++++++++++--- source3/lib/netapi/netapi.h | 1 + 2 files changed, 26 insertions(+), 3 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c index 454d766ae9..853ac55f8a 100644 --- a/source3/lib/netapi/netapi.c +++ b/source3/lib/netapi/netapi.c @@ -22,14 +22,16 @@ extern bool AllowDebugChange; +struct libnetapi_ctx *stat_ctx = NULL; +TALLOC_CTX *frame = NULL; static bool libnetapi_initialized = false; NET_API_STATUS libnetapi_init(struct libnetapi_ctx **context) { struct libnetapi_ctx *ctx = NULL; - TALLOC_CTX *frame = NULL; - if (libnetapi_initialized) { + if (stat_ctx && libnetapi_initialized) { + *context = stat_ctx; return W_ERROR_V(WERR_OK); } @@ -65,14 +67,34 @@ NET_API_STATUS libnetapi_init(struct libnetapi_ctx **context) libnetapi_initialized = true; - *context = ctx; + *context = stat_ctx = ctx; return W_ERROR_V(WERR_OK); } +NET_API_STATUS libnetapi_getctx(struct libnetapi_ctx **ctx) +{ + if (stat_ctx) { + *ctx = stat_ctx; + return W_ERROR_V(WERR_OK); + } + + return libnetapi_init(ctx); +} + NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx) { + gfree_names(); + gfree_loadparm(); + gfree_case_tables(); + gfree_charcnv(); + gfree_interfaces(); + TALLOC_FREE(ctx); + TALLOC_FREE(frame); + + gfree_debugsyms(); + return W_ERROR_V(WERR_OK); } diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h index 278922224d..0b25c93d5b 100644 --- a/source3/lib/netapi/netapi.h +++ b/source3/lib/netapi/netapi.h @@ -30,6 +30,7 @@ struct libnetapi_ctx { }; NET_API_STATUS libnetapi_init(struct libnetapi_ctx **ctx); +NET_API_STATUS libnetapi_getctx(struct libnetapi_ctx **ctx); NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx); NET_API_STATUS libnetapi_set_debuglevel(struct libnetapi_ctx *ctx, const char *debuglevel); NET_API_STATUS libnetapi_get_debuglevel(struct libnetapi_ctx *ctx, const char **debuglevel); -- cgit From 62b3fd209d65caba36595dfbcde83fd74f4047b7 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 18 Dec 2007 02:52:34 +0100 Subject: Missed on instance of external creds. Guenther (This used to be commit 65d50f518766ab0a8115c2599d190e642eb00754) --- source3/lib/netapi/joindomain.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index 8287cd046f..67e53d4391 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -85,8 +85,10 @@ static WERROR NetJoinDomainRemote(TALLOC_CTX *mem_ctx, status = cli_full_connection(&cli, NULL, server_name, NULL, 0, "IPC$", "IPC", - opt_user_name, opt_workgroup, - opt_password, 0, Undefined, NULL); + ctx->username, + ctx->workgroup, + ctx->password, + 0, Undefined, NULL); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); -- cgit From dab660b9dc42b9e5817e59de4c97009796548b92 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 18 Dec 2007 02:54:18 +0100 Subject: Move NetJoinDomain and friends to NET_API_STATUS and the static libnetapi_ctx. Guenther (This used to be commit e640c3a4a7695613e9e619516befbaf3d44ecb10) --- source3/lib/netapi/joindomain.c | 126 +++++++++++++++++++++++++++++++++------- source3/lib/netapi/joindomain.h | 26 ++++----- 2 files changed, 119 insertions(+), 33 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index 67e53d4391..a0d3319998 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -18,9 +18,11 @@ */ #include "includes.h" -#include "lib/netapi/joindomain.h" -static WERROR NetJoinDomainLocal(TALLOC_CTX *mem_ctx, +#include "lib/netapi/netapi.h" +#include "libnet/libnet.h" + +static WERROR NetJoinDomainLocal(struct libnetapi_ctx *mem_ctx, const char *server_name, const char *domain_name, const char *account_ou, @@ -65,7 +67,7 @@ static WERROR NetJoinDomainLocal(TALLOC_CTX *mem_ctx, return libnet_Join(mem_ctx, r); } -static WERROR NetJoinDomainRemote(TALLOC_CTX *mem_ctx, +static WERROR NetJoinDomainRemote(struct libnetapi_ctx *ctx, const char *server_name, const char *domain_name, const char *account_ou, @@ -105,7 +107,7 @@ static WERROR NetJoinDomainRemote(TALLOC_CTX *mem_ctx, }; if (password) { - encode_wkssvc_join_password_buffer(mem_ctx, + encode_wkssvc_join_password_buffer(ctx, password, &cli->user_session_key, &encrypted_password); @@ -113,7 +115,7 @@ static WERROR NetJoinDomainRemote(TALLOC_CTX *mem_ctx, old_timeout = cli_set_timeout(cli, 60000); - status = rpccli_wkssvc_NetrJoinDomain2(pipe_cli, mem_ctx, + status = rpccli_wkssvc_NetrJoinDomain2(pipe_cli, ctx, server_name, domain_name, account_ou, Account, &encrypted_password, @@ -132,12 +134,13 @@ static WERROR NetJoinDomainRemote(TALLOC_CTX *mem_ctx, return werr; } -WERROR NetJoinDomain(const char *server_name, - const char *domain_name, - const char *account_ou, - const char *Account, - const char *password, - uint32_t join_flags) +static WERROR libnetapi_NetJoinDomain(struct libnetapi_ctx *ctx, + const char *server_name, + const char *domain_name, + const char *account_ou, + const char *Account, + const char *password, + uint32_t join_flags) { TALLOC_CTX *mem_ctx = NULL; WERROR werr; @@ -164,7 +167,7 @@ WERROR NetJoinDomain(const char *server_name, dc = domain_name; } - werr = NetJoinDomainLocal(mem_ctx, + werr = NetJoinDomainLocal(ctx, dc, domain_name, account_ou, @@ -175,7 +178,7 @@ WERROR NetJoinDomain(const char *server_name, goto done; } - werr = NetJoinDomainRemote(mem_ctx, + werr = NetJoinDomainRemote(ctx, server_name, domain_name, account_ou, @@ -188,10 +191,41 @@ done: return werr; } -WERROR NetUnjoinDomain(const char *server_name, - const char *account, - const char *password, - uint32_t unjoin_flags) +NET_API_STATUS NetJoinDomain(const char *server_name, + const char *domain_name, + const char *account_ou, + const char *Account, + const char *password, + uint32_t join_flags) +{ + struct libnetapi_ctx *ctx = NULL; + NET_API_STATUS status; + WERROR werr; + + status = libnetapi_getctx(&ctx); + if (status != 0) { + return status; + } + + werr = libnetapi_NetJoinDomain(ctx, + server_name, + domain_name, + account_ou, + Account, + password, + join_flags); + if (!W_ERROR_IS_OK(werr)) { + return W_ERROR_V(werr); + } + + return 0; +} + +static WERROR libnetapi_NetUnjoinDomain(struct libnetapi_ctx *ctx, + const char *server_name, + const char *account, + const char *password, + uint32_t unjoin_flags) { TALLOC_CTX *mem_ctx = NULL; struct cli_state *cli = NULL; @@ -266,9 +300,37 @@ WERROR NetUnjoinDomain(const char *server_name, return werr; } -WERROR NetGetJoinInformation(const char *server_name, - const char **name_buffer, - uint16_t *name_type) +NET_API_STATUS NetUnjoinDomain(const char *server_name, + const char *account, + const char *password, + uint32_t unjoin_flags) +{ + struct libnetapi_ctx *ctx = NULL; + NET_API_STATUS status; + WERROR werr; + + status = libnetapi_getctx(&ctx); + if (status != 0) { + return status; + } + + werr = libnetapi_NetUnjoinDomain(ctx, + server_name, + account, + password, + unjoin_flags); + if (!W_ERROR_IS_OK(werr)) { + return W_ERROR_V(werr); + } + + return 0; +} + + +WERROR libnetapi_NetGetJoinInformation(struct libnetapi_ctx *ctx, + const char *server_name, + const char **name_buffer, + uint16_t *name_type) { TALLOC_CTX *mem_ctx = NULL; struct cli_state *cli = NULL; @@ -346,3 +408,27 @@ WERROR NetGetJoinInformation(const char *server_name, return werr; } + +NET_API_STATUS NetGetJoinInformation(const char *server_name, + const char **name_buffer, + uint16_t *name_type) +{ + struct libnetapi_ctx *ctx = NULL; + NET_API_STATUS status; + WERROR werr; + + status = libnetapi_getctx(&ctx); + if (status != 0) { + return status; + } + + werr = libnetapi_NetGetJoinInformation(ctx, + server_name, + name_buffer, + name_type); + if (!W_ERROR_IS_OK(werr)) { + return W_ERROR_V(werr); + } + + return 0; +} diff --git a/source3/lib/netapi/joindomain.h b/source3/lib/netapi/joindomain.h index 73d2ec3d32..b72bc9aecb 100644 --- a/source3/lib/netapi/joindomain.h +++ b/source3/lib/netapi/joindomain.h @@ -20,18 +20,18 @@ #ifndef __LIB_NETAPI_JOINDOMAIN_H__ #define __LIB_NETAPI_JOINDOMAIN_H__ -WERROR NetJoinDomain(const char *server, - const char *domain, - const char *account_ou, - const char *account, - const char *password, - uint32_t join_options); -WERROR NetUnjoinDomain(const char *server_name, - const char *account, - const char *password, - uint32_t unjoin_flags); -WERROR NetGetJoinInformation(const char *server_name, - const char **name_buffer, - uint16_t *name_type); +NET_API_STATUS NetJoinDomain(const char *server, + const char *domain, + const char *account_ou, + const char *account, + const char *password, + uint32_t join_options); +NET_API_STATUS NetUnjoinDomain(const char *server_name, + const char *account, + const char *password, + uint32_t unjoin_flags); +NET_API_STATUS NetGetJoinInformation(const char *server_name, + const char **name_buffer, + uint16_t *name_type); #endif -- cgit From d1548d035f3c296d5044b9aa47fc350cb62e4e2d Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 19 Dec 2007 02:25:15 +0100 Subject: Use DsGetDcName in local libnetapi join to find a dc. Guenther (This used to be commit fbc60c1648ff8b1fa0ae33c09237e41232f9769c) --- source3/lib/netapi/joindomain.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index a0d3319998..c6bf3d687a 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -36,16 +36,31 @@ static WERROR NetJoinDomainLocal(struct libnetapi_ctx *mem_ctx, werr = libnet_init_JoinCtx(mem_ctx, &r); W_ERROR_NOT_OK_RETURN(werr); - if (!server_name || !domain_name) { + if (!domain_name) { return WERR_INVALID_PARAM; } - r->in.server_name = talloc_strdup(mem_ctx, server_name); - W_ERROR_HAVE_NO_MEMORY(r->in.server_name); - r->in.domain_name = talloc_strdup(mem_ctx, domain_name); W_ERROR_HAVE_NO_MEMORY(r->in.domain_name); + if (server_name) { + r->in.server_name = talloc_strdup(mem_ctx, server_name); + W_ERROR_HAVE_NO_MEMORY(r->in.server_name); + } else if (join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) { + NTSTATUS status; + struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; + uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED | + DS_WRITABLE_REQUIRED | + DS_RETURN_DNS_NAME; + status = DsGetDcName(mem_ctx, NULL, domain_name, + NULL, NULL, flags, &info); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + r->in.server_name = talloc_strdup(mem_ctx, info->domain_controller_name); + W_ERROR_HAVE_NO_MEMORY(r->in.server_name); + } + if (account_ou) { r->in.account_ou = talloc_strdup(mem_ctx, account_ou); W_ERROR_HAVE_NO_MEMORY(r->in.account_ou); @@ -158,17 +173,8 @@ static WERROR libnetapi_NetJoinDomain(struct libnetapi_ctx *ctx, if (!server_name || is_myname_or_ipaddr(server_name)) { - const char *dc = NULL; - - /* FIXME: DsGetDcName */ - if (server_name == NULL) { - dc = domain_name; - } else { - dc = domain_name; - } - werr = NetJoinDomainLocal(ctx, - dc, + server_name, domain_name, account_ou, Account, -- cgit From 14652eab180fa9555607a413e5d1b429d1e1673c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 19 Dec 2007 10:52:45 +0100 Subject: Fix NetJoinDomainLocal. Guenther (This used to be commit 24605c9175fb313c9c888783817da755cd8ce594) --- source3/lib/netapi/joindomain.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index c6bf3d687a..180210f707 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -43,10 +43,7 @@ static WERROR NetJoinDomainLocal(struct libnetapi_ctx *mem_ctx, r->in.domain_name = talloc_strdup(mem_ctx, domain_name); W_ERROR_HAVE_NO_MEMORY(r->in.domain_name); - if (server_name) { - r->in.server_name = talloc_strdup(mem_ctx, server_name); - W_ERROR_HAVE_NO_MEMORY(r->in.server_name); - } else if (join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) { + if (join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) { NTSTATUS status; struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED | -- cgit From 8f7723fc28cf9e71b0d5ef2890dbe95ae3fc5e07 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 19 Dec 2007 10:55:52 +0100 Subject: Remove unrequired TALLOC_CTX from libnetapi_NetJoinDomain & friends. Guenther (This used to be commit 96ebdca45b998da7e6137973dea717bf3ac76328) --- source3/lib/netapi/joindomain.c | 39 +++++---------------------------------- 1 file changed, 5 insertions(+), 34 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index 180210f707..08a39549f9 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -154,44 +154,28 @@ static WERROR libnetapi_NetJoinDomain(struct libnetapi_ctx *ctx, const char *password, uint32_t join_flags) { - TALLOC_CTX *mem_ctx = NULL; - WERROR werr; - - mem_ctx = talloc_init("NetJoinDomain"); - if (!mem_ctx) { - werr = WERR_NOMEM; - goto done; - } - if (!domain_name) { - werr = WERR_INVALID_PARAM; - goto done; + return WERR_INVALID_PARAM; } if (!server_name || is_myname_or_ipaddr(server_name)) { - werr = NetJoinDomainLocal(ctx, + return NetJoinDomainLocal(ctx, server_name, domain_name, account_ou, Account, password, join_flags); - - goto done; } - werr = NetJoinDomainRemote(ctx, + return NetJoinDomainRemote(ctx, server_name, domain_name, account_ou, Account, password, join_flags); -done: - TALLOC_FREE(mem_ctx); - - return werr; } NET_API_STATUS NetJoinDomain(const char *server_name, @@ -230,7 +214,6 @@ static WERROR libnetapi_NetUnjoinDomain(struct libnetapi_ctx *ctx, const char *password, uint32_t unjoin_flags) { - TALLOC_CTX *mem_ctx = NULL; struct cli_state *cli = NULL; struct rpc_pipe_client *pipe_cli = NULL; struct wkssvc_PasswordBuffer encrypted_password; @@ -240,17 +223,6 @@ static WERROR libnetapi_NetUnjoinDomain(struct libnetapi_ctx *ctx, ZERO_STRUCT(encrypted_password); - mem_ctx = talloc_init("NetUnjoinDomain"); - if (!mem_ctx) { - werr = WERR_NOMEM; - goto done; - } - - if (!server_name || is_myname_or_ipaddr(server_name)) { - werr = WERR_NOT_SUPPORTED; - goto done; - } - status = cli_full_connection(&cli, NULL, server_name, NULL, 0, "IPC$", "IPC", @@ -274,7 +246,7 @@ static WERROR libnetapi_NetUnjoinDomain(struct libnetapi_ctx *ctx, }; if (password) { - encode_wkssvc_join_password_buffer(mem_ctx, + encode_wkssvc_join_password_buffer(ctx, password, &cli->user_session_key, &encrypted_password); @@ -282,7 +254,7 @@ static WERROR libnetapi_NetUnjoinDomain(struct libnetapi_ctx *ctx, old_timeout = cli_set_timeout(cli, 60000); - status = rpccli_wkssvc_NetrUnjoinDomain2(pipe_cli, mem_ctx, + status = rpccli_wkssvc_NetrUnjoinDomain2(pipe_cli, ctx, server_name, account, &encrypted_password, @@ -298,7 +270,6 @@ static WERROR libnetapi_NetUnjoinDomain(struct libnetapi_ctx *ctx, cli_set_timeout(cli, old_timeout); cli_shutdown(cli); } - TALLOC_FREE(mem_ctx); return werr; } -- cgit From 75276ac2e3cb2d92e17231c906128bf98eea5d50 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 19 Dec 2007 11:03:45 +0100 Subject: Add support for remote and local unjoining in libnetapi. Guenther (This used to be commit 74048fe7cfbd05994d533bea4a477d6ca93449d9) --- source3/lib/netapi/joindomain.c | 94 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 89 insertions(+), 5 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index 08a39549f9..2cc93e2545 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -208,11 +208,73 @@ NET_API_STATUS NetJoinDomain(const char *server_name, return 0; } -static WERROR libnetapi_NetUnjoinDomain(struct libnetapi_ctx *ctx, - const char *server_name, - const char *account, - const char *password, - uint32_t unjoin_flags) +static WERROR NetUnjoinDomainLocal(struct libnetapi_ctx *mem_ctx, + const char *server_name, + const char *account, + const char *password, + uint32_t unjoin_flags) +{ + struct libnet_UnjoinCtx *r = NULL; + struct dom_sid domain_sid; + WERROR werr; + + if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) { + return WERR_SETUP_NOT_JOINED; + } + + werr = libnet_init_UnjoinCtx(mem_ctx, &r); + W_ERROR_NOT_OK_RETURN(werr); + + if (server_name) { + r->in.server_name = talloc_strdup(mem_ctx, server_name); + W_ERROR_HAVE_NO_MEMORY(r->in.server_name); + } else { + + NTSTATUS status; + const char *domain = NULL; + struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; + uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED | + DS_WRITABLE_REQUIRED | + DS_IS_FLAT_NAME | + DS_RETURN_DNS_NAME; + if (lp_realm()) { + domain = lp_realm(); + } else { + domain = lp_workgroup(); + } + status = DsGetDcName(mem_ctx, NULL, domain, + NULL, NULL, flags, &info); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + r->in.server_name = talloc_strdup(mem_ctx, info->domain_controller_name); + W_ERROR_HAVE_NO_MEMORY(r->in.server_name); + } + + if (account) { + r->in.admin_account = talloc_strdup(mem_ctx, account); + W_ERROR_HAVE_NO_MEMORY(r->in.admin_account); + } + + if (password) { + r->in.password = talloc_strdup(mem_ctx, password); + W_ERROR_HAVE_NO_MEMORY(r->in.password); + } + + r->in.unjoin_flags = unjoin_flags; + r->in.modify_config = true; + + r->in.domain_sid = &domain_sid; + + return libnet_Unjoin(mem_ctx, r); + +} + +static WERROR NetUnjoinDomainRemote(struct libnetapi_ctx *ctx, + const char *server_name, + const char *account, + const char *password, + uint32_t unjoin_flags) { struct cli_state *cli = NULL; struct rpc_pipe_client *pipe_cli = NULL; @@ -274,6 +336,28 @@ static WERROR libnetapi_NetUnjoinDomain(struct libnetapi_ctx *ctx, return werr; } +static WERROR libnetapi_NetUnjoinDomain(struct libnetapi_ctx *ctx, + const char *server_name, + const char *account, + const char *password, + uint32_t unjoin_flags) +{ + if (!server_name || is_myname_or_ipaddr(server_name)) { + + return NetUnjoinDomainLocal(ctx, + server_name, + account, + password, + unjoin_flags); + } + + return NetUnjoinDomainRemote(ctx, + server_name, + account, + password, + unjoin_flags); +} + NET_API_STATUS NetUnjoinDomain(const char *server_name, const char *account, const char *password, -- cgit From af08d8be3063ada42637a4ae7437499b03457de2 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 19 Dec 2007 12:09:08 +0100 Subject: Add libnetapi_errstr(). Guenther (This used to be commit 465e61a3599a277366ada6ecda3a1e6ddb1f2490) --- source3/lib/netapi/netapi.c | 50 +++++++++++++++++++++++++++++++++++++++++++++ source3/lib/netapi/netapi.h | 1 + 2 files changed, 51 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c index 853ac55f8a..70d7e654a7 100644 --- a/source3/lib/netapi/netapi.c +++ b/source3/lib/netapi/netapi.c @@ -148,3 +148,53 @@ NET_API_STATUS libnetapi_set_workgroup(struct libnetapi_ctx *ctx, } return W_ERROR_V(WERR_OK); } + +const char *libnetapi_errstr(struct libnetapi_ctx *ctx, + NET_API_STATUS status) +{ + const char *err_str = NULL; + + switch (status) { + case 0: + err_str = "Success"; + break; + case 0x00000057: /* WERR_INVALID_PARAM */ + err_str = "Invalid parameter"; + break; + case 0x0000052E: /* WERR_LOGON_FAILURE */ + err_str = "Invalid logon credentials"; + break; + case 0x00000995: /* WERR_DOMAIN_CONTROLLER_NOT_FOUND */ + err_str = "A domain controller could not be found"; + break; + case 0x00000a84: /* WERR_SETUP_NOT_JOINED */ + err_str = "Join failed"; + break; + case 0x00000a83: /* WERR_SETUP_ALREADY_JOINED */ + err_str = "Machine is already joined"; + break; + case 0x00000a85: /* WERR_SETUP_DOMAIN_CONTROLLER */ + err_str = "Machine is a Domain Controller"; + break; + case 0x00000032: /* WERR_NOT_SUPPORTED */ + err_str = "Not supported"; + break; + case 0x0000051f: /* WERR_NO_LOGON_SERVERS */ + err_str = "No logon servers found"; + break; + case 0x00000056: /* WERR_BAD_PASSWORD */ + err_str = "A bad password was supplied"; + break; + case 0x00000520: /* WERR_NO_SUCH_LOGON_SESSION */ + err_str = "No such logon session"; + break; + default: + err_str = talloc_asprintf(ctx, "0x%08x", status); + if (!err_str) { + return NULL; + } + break; + } + + return err_str; +} diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h index 0b25c93d5b..232d9c154f 100644 --- a/source3/lib/netapi/netapi.h +++ b/source3/lib/netapi/netapi.h @@ -37,6 +37,7 @@ NET_API_STATUS libnetapi_get_debuglevel(struct libnetapi_ctx *ctx, const char ** NET_API_STATUS libnetapi_set_username(struct libnetapi_ctx *ctx, const char *username); NET_API_STATUS libnetapi_set_password(struct libnetapi_ctx *ctx, const char *password); NET_API_STATUS libnetapi_set_workgroup(struct libnetapi_ctx *ctx, const char *workgroup); +const char *libnetapi_errstr(struct libnetapi_ctx *ctx, NET_API_STATUS status); #include "joindomain.h" -- cgit From 2bed9564dbe4fc3bc86d6ba231c5f2ecce468b5a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 19 Dec 2007 13:52:51 +0100 Subject: Split out local and remote paths for NetGetJoinInformation. Guenther (This used to be commit d1e4f9dd5cde79f915e3e0f652621d966aa850e8) --- source3/lib/netapi/joindomain.c | 92 +++++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 40 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index 2cc93e2545..0c8d645db9 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -384,50 +384,16 @@ NET_API_STATUS NetUnjoinDomain(const char *server_name, return 0; } - -WERROR libnetapi_NetGetJoinInformation(struct libnetapi_ctx *ctx, - const char *server_name, - const char **name_buffer, - uint16_t *name_type) +static WERROR NetGetJoinInformationRemote(struct libnetapi_ctx *ctx, + const char *server_name, + const char **name_buffer, + uint16_t *name_type) { - TALLOC_CTX *mem_ctx = NULL; struct cli_state *cli = NULL; struct rpc_pipe_client *pipe_cli = NULL; NTSTATUS status; WERROR werr; - mem_ctx = talloc_init("NetGetJoinInformation"); - if (!mem_ctx) { - werr = WERR_NOMEM; - goto done; - } - - if (!server_name || is_myname_or_ipaddr(server_name)) { - if ((lp_security() == SEC_ADS) && lp_realm()) { - *name_buffer = SMB_STRDUP(lp_realm()); - } else { - *name_buffer = SMB_STRDUP(lp_workgroup()); - } - if (!*name_buffer) { - werr = WERR_NOMEM; - goto done; - } - switch (lp_server_role()) { - case ROLE_DOMAIN_MEMBER: - case ROLE_DOMAIN_PDC: - case ROLE_DOMAIN_BDC: - *name_type = NetSetupDomainName; - break; - case ROLE_STANDALONE: - default: - *name_type = NetSetupWorkgroupName; - break; - } - - werr = WERR_OK; - goto done; - } - status = cli_full_connection(&cli, NULL, server_name, NULL, 0, "IPC$", "IPC", @@ -448,7 +414,7 @@ WERROR libnetapi_NetGetJoinInformation(struct libnetapi_ctx *ctx, goto done; }; - status = rpccli_wkssvc_NetrGetJoinInformation(pipe_cli, mem_ctx, + status = rpccli_wkssvc_NetrGetJoinInformation(pipe_cli, ctx, server_name, name_buffer, (enum wkssvc_NetJoinStatus *)name_type, @@ -462,11 +428,57 @@ WERROR libnetapi_NetGetJoinInformation(struct libnetapi_ctx *ctx, if (cli) { cli_shutdown(cli); } - TALLOC_FREE(mem_ctx); return werr; } +static WERROR NetGetJoinInformationLocal(struct libnetapi_ctx *ctx, + const char *server_name, + const char **name_buffer, + uint16_t *name_type) +{ + if ((lp_security() == SEC_ADS) && lp_realm()) { + *name_buffer = SMB_STRDUP(lp_realm()); + } else { + *name_buffer = SMB_STRDUP(lp_workgroup()); + } + if (!*name_buffer) { + return WERR_NOMEM; + } + + switch (lp_server_role()) { + case ROLE_DOMAIN_MEMBER: + case ROLE_DOMAIN_PDC: + case ROLE_DOMAIN_BDC: + *name_type = NetSetupDomainName; + break; + case ROLE_STANDALONE: + default: + *name_type = NetSetupWorkgroupName; + break; + } + + return WERR_OK; +} + +WERROR libnetapi_NetGetJoinInformation(struct libnetapi_ctx *ctx, + const char *server_name, + const char **name_buffer, + uint16_t *name_type) +{ + if (!server_name || is_myname_or_ipaddr(server_name)) { + return NetGetJoinInformationLocal(ctx, + server_name, + name_buffer, + name_type); + } + + return NetGetJoinInformationRemote(ctx, + server_name, + name_buffer, + name_type); +} + NET_API_STATUS NetGetJoinInformation(const char *server_name, const char **name_buffer, uint16_t *name_type) -- cgit From 721d36df8372dd45430a93c99180bb94ec7d9773 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 19 Dec 2007 15:10:24 +0100 Subject: Add NetServerGetInfo and NetServerSetInfo (for level 1005). Guenther (This used to be commit 1cad549f54563c3a9787624ba7a56b54107ebd57) --- source3/lib/netapi/netapi.h | 1 + source3/lib/netapi/serverinfo.c | 297 ++++++++++++++++++++++++++++++++++++++++ source3/lib/netapi/serverinfo.h | 30 ++++ 3 files changed, 328 insertions(+) create mode 100644 source3/lib/netapi/serverinfo.c create mode 100644 source3/lib/netapi/serverinfo.h (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h index 232d9c154f..a1137b45ee 100644 --- a/source3/lib/netapi/netapi.h +++ b/source3/lib/netapi/netapi.h @@ -40,5 +40,6 @@ NET_API_STATUS libnetapi_set_workgroup(struct libnetapi_ctx *ctx, const char *wo const char *libnetapi_errstr(struct libnetapi_ctx *ctx, NET_API_STATUS status); #include "joindomain.h" +#include "serverinfo.h" #endif diff --git a/source3/lib/netapi/serverinfo.c b/source3/lib/netapi/serverinfo.c new file mode 100644 index 0000000000..d6031b69d2 --- /dev/null +++ b/source3/lib/netapi/serverinfo.c @@ -0,0 +1,297 @@ +/* + * Unix SMB/CIFS implementation. + * NetApi Server Support + * Copyright (C) Guenther Deschner 2007 + * + * 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 3 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, see . + */ + +#include "includes.h" + +#include "lib/netapi/netapi.h" +#include "libnet/libnet.h" + +static WERROR NetServerGetInfoLocal_1005(struct libnetapi_ctx *ctx, + uint8_t **buffer) +{ + struct srvsvc_NetSrvInfo1005 info1005; + + info1005.comment = lp_serverstring(); + *buffer = (uint8_t *)talloc_memdup(ctx, &info1005, sizeof(info1005)); + if (!*buffer) { + return WERR_NOMEM; + } + + return WERR_OK; +} + +static WERROR NetServerGetInfoLocal(struct libnetapi_ctx *ctx, + const char *server_name, + uint32_t level, + uint8_t **buffer) +{ + switch (level) { + case 1005: + return NetServerGetInfoLocal_1005(ctx, buffer); + default: + return WERR_UNKNOWN_LEVEL; + } + + return WERR_UNKNOWN_LEVEL; +} + +static WERROR NetServerGetInfoRemote(struct libnetapi_ctx *ctx, + const char *server_name, + uint32_t level, + uint8_t **buffer) +{ + struct cli_state *cli = NULL; + struct rpc_pipe_client *pipe_cli = NULL; + NTSTATUS status; + WERROR werr; + union srvsvc_NetSrvInfo info; + + status = cli_full_connection(&cli, NULL, server_name, + NULL, 0, + "IPC$", "IPC", + ctx->username, + ctx->workgroup, + ctx->password, + 0, Undefined, NULL); + + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); + goto done; + } + + pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, + &status); + if (!pipe_cli) { + werr = ntstatus_to_werror(status); + goto done; + }; + + status = rpccli_srvsvc_NetSrvGetInfo(pipe_cli, ctx, + server_name, + level, + &info, + &werr); + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); + goto done; + } + + *buffer = (uint8_t *)&info; + + done: + if (cli) { + cli_shutdown(cli); + } + + return werr; +} + +WERROR libnetapi_NetServerGetInfo(struct libnetapi_ctx *ctx, + const char *server_name, + uint32_t level, + uint8_t **buffer) +{ + if (!server_name || is_myname_or_ipaddr(server_name)) { + return NetServerGetInfoLocal(ctx, + server_name, + level, + buffer); + } + + return NetServerGetInfoRemote(ctx, + server_name, + level, + buffer); + +} + +NET_API_STATUS NetServerGetInfo(const char *server_name, + uint32_t level, + uint8_t **buffer) +{ + struct libnetapi_ctx *ctx = NULL; + NET_API_STATUS status; + WERROR werr; + + status = libnetapi_getctx(&ctx); + if (status != 0) { + return status; + } + + werr = libnetapi_NetServerGetInfo(ctx, + server_name, + level, + buffer); + if (!W_ERROR_IS_OK(werr)) { + return W_ERROR_V(werr); + } + + return 0; +} + +static WERROR NetServerSetInfoLocal_1005(struct libnetapi_ctx *ctx, + uint8_t *buffer, + uint32_t *parm_error) +{ + struct srvsvc_NetSrvInfo1005 *info1005; + + if (!buffer) { + *parm_error = 1005; /* sure here ? */ + return WERR_INVALID_PARAM; + } + + info1005 = (struct srvsvc_NetSrvInfo1005 *)buffer; + + if (!info1005->comment) { + *parm_error = 1005; + return WERR_INVALID_PARAM; + } + + /* + return libnet_conf_set_parm(GLOBAL_NAME, + "server string", + info1005->comment); + */ + return WERR_NOT_SUPPORTED; +} + +static WERROR NetServerSetInfoLocal(struct libnetapi_ctx *ctx, + const char *server_name, + uint32_t level, + uint8_t *buffer, + uint32_t *parm_error) +{ + switch (level) { + case 1005: + return NetServerSetInfoLocal_1005(ctx, buffer, parm_error); + break; + default: + return WERR_UNKNOWN_LEVEL; + } + + return WERR_UNKNOWN_LEVEL; +} + +static WERROR NetServerSetInfoRemote(struct libnetapi_ctx *ctx, + const char *server_name, + uint32_t level, + uint8_t *buffer, + uint32_t *parm_error) +{ + struct cli_state *cli = NULL; + struct rpc_pipe_client *pipe_cli = NULL; + NTSTATUS status; + WERROR werr; + union srvsvc_NetSrvInfo info; + + status = cli_full_connection(&cli, NULL, server_name, + NULL, 0, + "IPC$", "IPC", + ctx->username, + ctx->workgroup, + ctx->password, + 0, Undefined, NULL); + + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); + goto done; + } + + pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, + &status); + if (!pipe_cli) { + werr = ntstatus_to_werror(status); + goto done; + }; + + switch (level) { + case 1005: + info.info1005 = (struct srvsvc_NetSrvInfo1005 *)buffer; + break; + default: + werr = WERR_NOT_SUPPORTED; + goto done; + } + + status = rpccli_srvsvc_NetSrvSetInfo(pipe_cli, ctx, + server_name, + level, + info, + parm_error, + &werr); + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); + goto done; + } + + done: + if (cli) { + cli_shutdown(cli); + } + + return werr; +} + +WERROR libnetapi_NetServerSetInfo(struct libnetapi_ctx *ctx, + const char *server_name, + uint32_t level, + uint8_t *buffer, + uint32_t *parm_error) +{ + if (!server_name || is_myname_or_ipaddr(server_name)) { + return NetServerSetInfoLocal(ctx, + server_name, + level, + buffer, + parm_error); + } + + return NetServerSetInfoRemote(ctx, + server_name, + level, + buffer, + parm_error); +} + + +NET_API_STATUS NetServerSetInfo(const char *server_name, + uint32_t level, + uint8_t *buffer, + uint32_t *parm_error) +{ + struct libnetapi_ctx *ctx = NULL; + NET_API_STATUS status; + WERROR werr; + + status = libnetapi_getctx(&ctx); + if (status != 0) { + return status; + } + + werr = libnetapi_NetServerSetInfo(ctx, + server_name, + level, + buffer, + parm_error); + if (!W_ERROR_IS_OK(werr)) { + return W_ERROR_V(werr); + } + + return 0; +} diff --git a/source3/lib/netapi/serverinfo.h b/source3/lib/netapi/serverinfo.h new file mode 100644 index 0000000000..66c406657a --- /dev/null +++ b/source3/lib/netapi/serverinfo.h @@ -0,0 +1,30 @@ +/* + * Unix SMB/CIFS implementation. + * NetApi Support + * Copyright (C) Guenther Deschner 2007 + * + * 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 3 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, see . + */ + +#ifndef __LIB_NETAPI_SERVERINFO_H__ +#define __LIB_NETAPI_SERVERINFO_H__ + +NET_API_STATUS NetServerGetInfo(const char *server_name, + uint32_t level, + uint8_t **buffer); +NET_API_STATUS NetServerSetInfo(const char *server_name, + uint32_t level, + uint8_t *buffer, + uint32_t *parm_error); +#endif -- cgit From 991112eda710c97dff607dd615c777023395da65 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 19 Dec 2007 16:07:40 +0100 Subject: Implement NetServerSetInfo level 1005 in local mode with smbconf registry. Guenther (This used to be commit 15c2bc15f20a677c3c94895150e396275de6ac9b) --- source3/lib/netapi/serverinfo.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/serverinfo.c b/source3/lib/netapi/serverinfo.c index d6031b69d2..d1bfa47649 100644 --- a/source3/lib/netapi/serverinfo.c +++ b/source3/lib/netapi/serverinfo.c @@ -163,12 +163,13 @@ static WERROR NetServerSetInfoLocal_1005(struct libnetapi_ctx *ctx, return WERR_INVALID_PARAM; } - /* - return libnet_conf_set_parm(GLOBAL_NAME, - "server string", - info1005->comment); - */ - return WERR_NOT_SUPPORTED; + if (!lp_include_registry_globals()) { + return WERR_NOT_SUPPORTED; + } + + return libnet_smbconf_set_global_param(ctx, + "server string", + info1005->comment); } static WERROR NetServerSetInfoLocal(struct libnetapi_ctx *ctx, @@ -180,7 +181,6 @@ static WERROR NetServerSetInfoLocal(struct libnetapi_ctx *ctx, switch (level) { case 1005: return NetServerSetInfoLocal_1005(ctx, buffer, parm_error); - break; default: return WERR_UNKNOWN_LEVEL; } -- cgit From 5479c50c37ee78037a96df8844fd06b1b0c9ccbb Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 20 Dec 2007 01:19:26 +0100 Subject: Merge all headers into libnetapi.h. Guenther (This used to be commit a2c5beda2ec98dea8951fb3a37774f5f325410ef) --- source3/lib/netapi/joindomain.h | 37 ------------------------------------- source3/lib/netapi/netapi.h | 24 ++++++++++++++++++++++-- source3/lib/netapi/serverinfo.h | 30 ------------------------------ 3 files changed, 22 insertions(+), 69 deletions(-) delete mode 100644 source3/lib/netapi/joindomain.h delete mode 100644 source3/lib/netapi/serverinfo.h (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.h b/source3/lib/netapi/joindomain.h deleted file mode 100644 index b72bc9aecb..0000000000 --- a/source3/lib/netapi/joindomain.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * NetApi Support - * Copyright (C) Guenther Deschner 2007 - * - * 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 3 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, see . - */ - -#ifndef __LIB_NETAPI_JOINDOMAIN_H__ -#define __LIB_NETAPI_JOINDOMAIN_H__ - -NET_API_STATUS NetJoinDomain(const char *server, - const char *domain, - const char *account_ou, - const char *account, - const char *password, - uint32_t join_options); -NET_API_STATUS NetUnjoinDomain(const char *server_name, - const char *account, - const char *password, - uint32_t unjoin_flags); -NET_API_STATUS NetGetJoinInformation(const char *server_name, - const char **name_buffer, - uint16_t *name_type); - -#endif diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h index a1137b45ee..bbd2282a77 100644 --- a/source3/lib/netapi/netapi.h +++ b/source3/lib/netapi/netapi.h @@ -39,7 +39,27 @@ NET_API_STATUS libnetapi_set_password(struct libnetapi_ctx *ctx, const char *pas NET_API_STATUS libnetapi_set_workgroup(struct libnetapi_ctx *ctx, const char *workgroup); const char *libnetapi_errstr(struct libnetapi_ctx *ctx, NET_API_STATUS status); -#include "joindomain.h" -#include "serverinfo.h" +/* wkssvc */ +NET_API_STATUS NetJoinDomain(const char *server, + const char *domain, + const char *account_ou, + const char *account, + const char *password, + uint32_t join_options); +NET_API_STATUS NetUnjoinDomain(const char *server_name, + const char *account, + const char *password, + uint32_t unjoin_flags); +NET_API_STATUS NetGetJoinInformation(const char *server_name, + const char **name_buffer, + uint16_t *name_type); +/* srvsvc */ +NET_API_STATUS NetServerGetInfo(const char *server_name, + uint32_t level, + uint8_t **buffer); +NET_API_STATUS NetServerSetInfo(const char *server_name, + uint32_t level, + uint8_t *buffer, + uint32_t *parm_error); #endif diff --git a/source3/lib/netapi/serverinfo.h b/source3/lib/netapi/serverinfo.h deleted file mode 100644 index 66c406657a..0000000000 --- a/source3/lib/netapi/serverinfo.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * NetApi Support - * Copyright (C) Guenther Deschner 2007 - * - * 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 3 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, see . - */ - -#ifndef __LIB_NETAPI_SERVERINFO_H__ -#define __LIB_NETAPI_SERVERINFO_H__ - -NET_API_STATUS NetServerGetInfo(const char *server_name, - uint32_t level, - uint8_t **buffer); -NET_API_STATUS NetServerSetInfo(const char *server_name, - uint32_t level, - uint8_t *buffer, - uint32_t *parm_error); -#endif -- cgit From f2fe17245436f8e68be2d5ad96b77721828f040a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 20 Dec 2007 12:12:06 +0100 Subject: Keep libnetapi_NetX calls static for now. Guenther (This used to be commit c255654c68923aca3e258906e49be82d719d5ccd) --- source3/lib/netapi/joindomain.c | 8 ++++---- source3/lib/netapi/serverinfo.c | 18 +++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index 0c8d645db9..0c3e021520 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -461,10 +461,10 @@ static WERROR NetGetJoinInformationLocal(struct libnetapi_ctx *ctx, return WERR_OK; } -WERROR libnetapi_NetGetJoinInformation(struct libnetapi_ctx *ctx, - const char *server_name, - const char **name_buffer, - uint16_t *name_type) +static WERROR libnetapi_NetGetJoinInformation(struct libnetapi_ctx *ctx, + const char *server_name, + const char **name_buffer, + uint16_t *name_type) { if (!server_name || is_myname_or_ipaddr(server_name)) { return NetGetJoinInformationLocal(ctx, diff --git a/source3/lib/netapi/serverinfo.c b/source3/lib/netapi/serverinfo.c index d1bfa47649..276a98c15e 100644 --- a/source3/lib/netapi/serverinfo.c +++ b/source3/lib/netapi/serverinfo.c @@ -102,10 +102,10 @@ static WERROR NetServerGetInfoRemote(struct libnetapi_ctx *ctx, return werr; } -WERROR libnetapi_NetServerGetInfo(struct libnetapi_ctx *ctx, - const char *server_name, - uint32_t level, - uint8_t **buffer) +static WERROR libnetapi_NetServerGetInfo(struct libnetapi_ctx *ctx, + const char *server_name, + uint32_t level, + uint8_t **buffer) { if (!server_name || is_myname_or_ipaddr(server_name)) { return NetServerGetInfoLocal(ctx, @@ -248,11 +248,11 @@ static WERROR NetServerSetInfoRemote(struct libnetapi_ctx *ctx, return werr; } -WERROR libnetapi_NetServerSetInfo(struct libnetapi_ctx *ctx, - const char *server_name, - uint32_t level, - uint8_t *buffer, - uint32_t *parm_error) +static WERROR libnetapi_NetServerSetInfo(struct libnetapi_ctx *ctx, + const char *server_name, + uint32_t level, + uint8_t *buffer, + uint32_t *parm_error) { if (!server_name || is_myname_or_ipaddr(server_name)) { return NetServerSetInfoLocal(ctx, -- cgit From 1a30bdb506f3f288e781cf1f445696c7eceb823e Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 20 Dec 2007 15:03:12 +0100 Subject: Remove doubled cli_set_timeout calls from libnetapi. Guenther (This used to be commit acc5d8e784b706001457ceeeb9bd4961a13d57d2) --- source3/lib/netapi/joindomain.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index 0c3e021520..e3d5eada02 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -109,8 +109,6 @@ static WERROR NetJoinDomainRemote(struct libnetapi_ctx *ctx, goto done; } - old_timeout = cli_set_timeout(cli, 60000); - pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_WKSSVC, &status); if (!pipe_cli) { @@ -298,8 +296,6 @@ static WERROR NetUnjoinDomainRemote(struct libnetapi_ctx *ctx, goto done; } - old_timeout = cli_set_timeout(cli, 60000); - pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_WKSSVC, &status); if (!pipe_cli) { -- cgit From 9518d738b17eb987dffb20f68df6b6768113b441 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 20 Dec 2007 15:06:20 +0100 Subject: Add error string for access denied in libnetapi. Guenther (This used to be commit 4df868e3c366958c64ed8445489c8d1e8a28e50b) --- source3/lib/netapi/netapi.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c index 70d7e654a7..1db745b5c7 100644 --- a/source3/lib/netapi/netapi.c +++ b/source3/lib/netapi/netapi.c @@ -158,6 +158,9 @@ const char *libnetapi_errstr(struct libnetapi_ctx *ctx, case 0: err_str = "Success"; break; + case 0x00000005: /* WERR_ACCESS_DENIED */ + err_str = "Access is denied"; + break; case 0x00000057: /* WERR_INVALID_PARAM */ err_str = "Invalid parameter"; break; -- cgit From d230cd8dd554439c7d5e8fa9d7fd56520d9288d0 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 21 Dec 2007 15:30:29 +0100 Subject: Make libnetapi_errstr use our NTSTATUS and WERROR error string macros. Guenther (This used to be commit e46aa35d432e930835206b9ce7583f46933015d8) --- source3/lib/netapi/netapi.c | 49 +++------------------------------------------ 1 file changed, 3 insertions(+), 46 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c index 1db745b5c7..032798d0f9 100644 --- a/source3/lib/netapi/netapi.c +++ b/source3/lib/netapi/netapi.c @@ -152,52 +152,9 @@ NET_API_STATUS libnetapi_set_workgroup(struct libnetapi_ctx *ctx, const char *libnetapi_errstr(struct libnetapi_ctx *ctx, NET_API_STATUS status) { - const char *err_str = NULL; - - switch (status) { - case 0: - err_str = "Success"; - break; - case 0x00000005: /* WERR_ACCESS_DENIED */ - err_str = "Access is denied"; - break; - case 0x00000057: /* WERR_INVALID_PARAM */ - err_str = "Invalid parameter"; - break; - case 0x0000052E: /* WERR_LOGON_FAILURE */ - err_str = "Invalid logon credentials"; - break; - case 0x00000995: /* WERR_DOMAIN_CONTROLLER_NOT_FOUND */ - err_str = "A domain controller could not be found"; - break; - case 0x00000a84: /* WERR_SETUP_NOT_JOINED */ - err_str = "Join failed"; - break; - case 0x00000a83: /* WERR_SETUP_ALREADY_JOINED */ - err_str = "Machine is already joined"; - break; - case 0x00000a85: /* WERR_SETUP_DOMAIN_CONTROLLER */ - err_str = "Machine is a Domain Controller"; - break; - case 0x00000032: /* WERR_NOT_SUPPORTED */ - err_str = "Not supported"; - break; - case 0x0000051f: /* WERR_NO_LOGON_SERVERS */ - err_str = "No logon servers found"; - break; - case 0x00000056: /* WERR_BAD_PASSWORD */ - err_str = "A bad password was supplied"; - break; - case 0x00000520: /* WERR_NO_SUCH_LOGON_SESSION */ - err_str = "No such logon session"; - break; - default: - err_str = talloc_asprintf(ctx, "0x%08x", status); - if (!err_str) { - return NULL; - } - break; + if (status & 0xc0000000) { + return get_friendly_nt_error_msg(NT_STATUS(status)); } - return err_str; + return get_friendly_werror_msg(W_ERROR(status)); } -- cgit From eddd190921f2b322a227044a5c8067397f80c0f5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 21 Dec 2007 15:51:00 +0100 Subject: Add basic remote NetGetDCName and NetGetAnyDCName versions to libnetapi. Guenther (This used to be commit 5bc49546a32abb4524133b9f2916cdd51d4eb462) --- source3/lib/netapi/getdc.c | 243 ++++++++++++++++++++++++++++++++++++++++++++ source3/lib/netapi/netapi.h | 9 ++ 2 files changed, 252 insertions(+) create mode 100644 source3/lib/netapi/getdc.c (limited to 'source3/lib') diff --git a/source3/lib/netapi/getdc.c b/source3/lib/netapi/getdc.c new file mode 100644 index 0000000000..85a0ae52ef --- /dev/null +++ b/source3/lib/netapi/getdc.c @@ -0,0 +1,243 @@ +/* + * Unix SMB/CIFS implementation. + * NetApi GetDC Support + * Copyright (C) Guenther Deschner 2007 + * + * 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 3 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, see . + */ + +#include "includes.h" + +#include "lib/netapi/netapi.h" +#include "libnet/libnet.h" + +#if 0 +#include "librpc/gen_ndr/cli_netlogon.h" +#endif + +NTSTATUS rpccli_netr_GetDcName(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const char *logon_server, + const char *domainname, + const char **dcname); +NTSTATUS rpccli_netr_GetAnyDCName(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const char *logon_server, + const char *domainname, + const char **dcname, + WERROR *werror); + +static WERROR NetGetDCNameLocal(struct libnetapi_ctx *ctx, + const char *server_name, + const char *domain_name, + uint8_t **buffer) +{ + return WERR_NOT_SUPPORTED; +} + +static WERROR NetGetDCNameRemote(struct libnetapi_ctx *ctx, + const char *server_name, + const char *domain_name, + uint8_t **buffer) +{ + struct cli_state *cli = NULL; + struct rpc_pipe_client *pipe_cli = NULL; + NTSTATUS status; + WERROR werr; + + status = cli_full_connection(&cli, NULL, server_name, + NULL, 0, + "IPC$", "IPC", + ctx->username, + ctx->workgroup, + ctx->password, + 0, Undefined, NULL); + + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); + goto done; + } + + pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, + &status); + if (!pipe_cli) { + werr = ntstatus_to_werror(status); + goto done; + }; + +#if 0 + werr = rpccli_netr_GetDcName(pipe_cli, ctx, + server_name, + domain_name, + (const char **)&buffer); +#else + werr = rpccli_netlogon_getdcname(pipe_cli, ctx, + server_name, + domain_name, + (char **)buffer); +#endif + done: + if (cli) { + cli_shutdown(cli); + } + + return werr; +} + +static WERROR libnetapi_NetGetDCName(struct libnetapi_ctx *ctx, + const char *server_name, + const char *domain_name, + uint8_t **buffer) +{ + if (!server_name || is_myname_or_ipaddr(server_name)) { + return NetGetDCNameLocal(ctx, + server_name, + domain_name, + buffer); + } + + return NetGetDCNameRemote(ctx, + server_name, + domain_name, + buffer); +} + +NET_API_STATUS NetGetDCName(const char *server_name, + const char *domain_name, + uint8_t **buffer) +{ + struct libnetapi_ctx *ctx = NULL; + NET_API_STATUS status; + WERROR werr; + + status = libnetapi_getctx(&ctx); + if (status != 0) { + return status; + } + + werr = libnetapi_NetGetDCName(ctx, + server_name, + domain_name, + buffer); + if (!W_ERROR_IS_OK(werr)) { + return W_ERROR_V(werr); + } + + return 0; +} + +static WERROR NetGetAnyDCNameLocal(struct libnetapi_ctx *ctx, + const char *server_name, + const char *domain_name, + uint8_t **buffer) +{ + return WERR_NOT_SUPPORTED; +} + +static WERROR NetGetAnyDCNameRemote(struct libnetapi_ctx *ctx, + const char *server_name, + const char *domain_name, + uint8_t **buffer) +{ + struct cli_state *cli = NULL; + struct rpc_pipe_client *pipe_cli = NULL; + NTSTATUS status; + WERROR werr; + + status = cli_full_connection(&cli, NULL, server_name, + NULL, 0, + "IPC$", "IPC", + ctx->username, + ctx->workgroup, + ctx->password, + 0, Undefined, NULL); + + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); + goto done; + } + + pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, + &status); + if (!pipe_cli) { + werr = ntstatus_to_werror(status); + goto done; + }; + +#if 0 + status = rpccli_netr_GetAnyDCName(pipe_cli, ctx, + server_name, + domain_name, + (const char **)&buffer, + &werr); + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); + goto done; + } +#else + werr = rpccli_netlogon_getanydcname(pipe_cli, ctx, + server_name, + domain_name, + (char **)buffer); +#endif + done: + if (cli) { + cli_shutdown(cli); + } + + return werr; + +} + +static WERROR libnetapi_NetGetAnyDCName(struct libnetapi_ctx *ctx, + const char *server_name, + const char *domain_name, + uint8_t **buffer) +{ + if (!server_name || is_myname_or_ipaddr(server_name)) { + return NetGetAnyDCNameLocal(ctx, + server_name, + domain_name, + buffer); + } + + return NetGetAnyDCNameRemote(ctx, + server_name, + domain_name, + buffer); +} + +NET_API_STATUS NetGetAnyDCName(const char *server_name, + const char *domain_name, + uint8_t **buffer) +{ + struct libnetapi_ctx *ctx = NULL; + NET_API_STATUS status; + WERROR werr; + + status = libnetapi_getctx(&ctx); + if (status != 0) { + return status; + } + + werr = libnetapi_NetGetAnyDCName(ctx, + server_name, + domain_name, + buffer); + if (!W_ERROR_IS_OK(werr)) { + return W_ERROR_V(werr); + } + + return 0; +} diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h index bbd2282a77..0dd6d95ceb 100644 --- a/source3/lib/netapi/netapi.h +++ b/source3/lib/netapi/netapi.h @@ -62,4 +62,13 @@ NET_API_STATUS NetServerSetInfo(const char *server_name, uint32_t level, uint8_t *buffer, uint32_t *parm_error); + +/* netlogon */ +NET_API_STATUS NetGetDCName(const char *server_name, + const char *domain_name, + uint8_t **buffer); +NET_API_STATUS NetGetAnyDCName(const char *server_name, + const char *domain_name, + uint8_t **buffer); + #endif -- cgit From 27a58bd50cfd749cdcfa90fe7abeaf15dc09bbf3 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 21 Dec 2007 16:02:35 +0100 Subject: Add getdc.c, a libnetapi example (incl. Makefile). Guenther (This used to be commit faedc78fc78527ee3bf05e1177ea43653aea67b2) --- source3/lib/netapi/examples/Makefile.in | 34 ++++++++++++++++++++ source3/lib/netapi/examples/getdc.c | 57 +++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 source3/lib/netapi/examples/Makefile.in create mode 100644 source3/lib/netapi/examples/getdc.c (limited to 'source3/lib') diff --git a/source3/lib/netapi/examples/Makefile.in b/source3/lib/netapi/examples/Makefile.in new file mode 100644 index 0000000000..79f9187d84 --- /dev/null +++ b/source3/lib/netapi/examples/Makefile.in @@ -0,0 +1,34 @@ +KRB5LIBS=@KRB5_LIBS@ +LDAP_LIBS=@LDAP_LIBS@ +LIBS=@LIBS@ -lnetapi +DEVELOPER_CFLAGS=@DEVELOPER_CFLAGS@ +FLAGS=@CFLAGS@ +CC=@CC@ +LDFLAGS=@PIE_LDFLAGS@ @LDFLAGS@ +DYNEXP=@DYNEXP@ + +# Compile a source file. +COMPILE_CC = $(CC) -I. $(FLAGS) $(PICFLAG) -c $< -o $@ +COMPILE = $(COMPILE_CC) + +.c.o: + @if (: >> $@ || : > $@) >/dev/null 2>&1; then rm -f $@; else \ + dir=`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` $(MAKEDIR); fi + @echo Compiling $*.c + @$(COMPILE) && exit 0;\ + echo "The following command failed:" 1>&2;\ + echo "$(COMPILE_CC)" 1>&2;\ + $(COMPILE_CC) >/dev/null 2>&1 + +GETDC_OBJ = getdc.o + +PROGS = getdc + +all: $(PROGS) + +getdc: $(GETDC_OBJ) + @echo Linking $@ + @$(CC) $(FLAGS) -o $@ $(GETDC_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) + +clean: + @rm -f $(PROGS) diff --git a/source3/lib/netapi/examples/getdc.c b/source3/lib/netapi/examples/getdc.c new file mode 100644 index 0000000000..ed6a8bd05d --- /dev/null +++ b/source3/lib/netapi/examples/getdc.c @@ -0,0 +1,57 @@ +/* + * Unix SMB/CIFS implementation. + * GetDCName query + * Copyright (C) Guenther Deschner 2007 + * + * 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 3 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, see . + */ + +#include +#include +#include +#include +#include + +#include + +int main(int argc, char **argv) +{ + NET_API_STATUS status; + struct libnetapi_ctx *ctx = NULL; + uint8_t *buffer; + + if (argc < 3) { + printf("usage: getdc \n"); + return -1; + } + + status = libnetapi_init(&ctx); + if (status != 0) { + return status; + } + + libnetapi_set_username(ctx, ""); + libnetapi_set_password(ctx, ""); + + status = NetGetDCName(argv[1], argv[2], &buffer); + if (status != 0) { + printf("GetDcName failed with: %s\n", libnetapi_errstr(ctx, status)); + } else { + printf("%s\n", (char *)buffer); + } + + libnetapi_free(ctx); + + return status; +} -- cgit From f3607f85b673ade41773fcfd2cb6935b512fbf60 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 21 Dec 2007 16:08:13 +0100 Subject: Add netdomjoin cmd line tool (another libnetapi example). Guenther (This used to be commit c502686f09713a7cf3786c254be6515a7aa23555) --- source3/lib/netapi/examples/Makefile.in | 7 +- source3/lib/netapi/examples/netdomjoin.c | 107 +++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 source3/lib/netapi/examples/netdomjoin.c (limited to 'source3/lib') diff --git a/source3/lib/netapi/examples/Makefile.in b/source3/lib/netapi/examples/Makefile.in index 79f9187d84..d618599433 100644 --- a/source3/lib/netapi/examples/Makefile.in +++ b/source3/lib/netapi/examples/Makefile.in @@ -21,8 +21,9 @@ COMPILE = $(COMPILE_CC) $(COMPILE_CC) >/dev/null 2>&1 GETDC_OBJ = getdc.o +NETDOMJOIN_OBJ = netdomjoin.o -PROGS = getdc +PROGS = getdc netdomjoin all: $(PROGS) @@ -30,5 +31,9 @@ getdc: $(GETDC_OBJ) @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(GETDC_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) +netdomjoin: $(NETDOMJOIN_OBJ) + @echo Linking $@ + @$(CC) $(FLAGS) -o $@ $(NETDOMJOIN_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) + clean: @rm -f $(PROGS) diff --git a/source3/lib/netapi/examples/netdomjoin.c b/source3/lib/netapi/examples/netdomjoin.c new file mode 100644 index 0000000000..a2bb700250 --- /dev/null +++ b/source3/lib/netapi/examples/netdomjoin.c @@ -0,0 +1,107 @@ +/* + * Unix SMB/CIFS implementation. + * Join Support (cmdline + netapi) + * Copyright (C) Guenther Deschner 2007 + * + * 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 3 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, see . + */ + +#include +#include +#include +#include +#include + +#include + +char *get_string_param(const char *param) +{ + char *p; + + p = strchr(param, '='); + if (!p) { + return NULL; + } + + return (p+1); +} + +int main(int argc, char **argv) +{ + NET_API_STATUS status; + const char *server_name = NULL; + const char *domain_name = NULL; + const char *account_ou = NULL; + const char *Account = NULL; + const char *password = NULL; + uint32_t join_flags = 3; + struct libnetapi_ctx *ctx = NULL; + int i; + + status = libnetapi_init(&ctx); + if (status != 0) { + return status; + } + + if (argc < 2) { + printf("usage: netdomjoin\n"); + printf("\t[hostname=HOSTNAME] [domain=DOMAIN] \n"); + return 0; + } + + if (argc > 2) { + server_name = argv[1]; + } + + for (i=0; i Date: Fri, 21 Dec 2007 16:36:06 +0100 Subject: Add netdomjoin-gui (my first gui application), another libnetapi user. Guenther (This used to be commit cf57ade5ec4a808eccb19a7723d753742fb71ca9) --- source3/lib/netapi/examples/Makefile.in | 12 +- source3/lib/netapi/examples/logo.png | Bin 0 -> 9329 bytes source3/lib/netapi/examples/netdomjoin-gui.c | 1347 ++++++++++++++++++++++++++ source3/lib/netapi/examples/samba.ico | Bin 0 -> 1406 bytes 4 files changed, 1357 insertions(+), 2 deletions(-) create mode 100644 source3/lib/netapi/examples/logo.png create mode 100644 source3/lib/netapi/examples/netdomjoin-gui.c create mode 100755 source3/lib/netapi/examples/samba.ico (limited to 'source3/lib') diff --git a/source3/lib/netapi/examples/Makefile.in b/source3/lib/netapi/examples/Makefile.in index d618599433..119e722aec 100644 --- a/source3/lib/netapi/examples/Makefile.in +++ b/source3/lib/netapi/examples/Makefile.in @@ -1,8 +1,11 @@ +GTK_FLAGS=`pkg-config gtk+-2.0 --cflags` +GTK_LIBS=`pkg-config gtk+-2.0 --libs` + KRB5LIBS=@KRB5_LIBS@ LDAP_LIBS=@LDAP_LIBS@ LIBS=@LIBS@ -lnetapi DEVELOPER_CFLAGS=@DEVELOPER_CFLAGS@ -FLAGS=@CFLAGS@ +FLAGS=@CFLAGS@ $(GTK_FLAGS) CC=@CC@ LDFLAGS=@PIE_LDFLAGS@ @LDFLAGS@ DYNEXP=@DYNEXP@ @@ -22,8 +25,9 @@ COMPILE = $(COMPILE_CC) GETDC_OBJ = getdc.o NETDOMJOIN_OBJ = netdomjoin.o +NETDOMJOIN_GUI_OBJ = netdomjoin-gui.o -PROGS = getdc netdomjoin +PROGS = getdc netdomjoin netdomjoin-gui all: $(PROGS) @@ -35,5 +39,9 @@ netdomjoin: $(NETDOMJOIN_OBJ) @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(NETDOMJOIN_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) +netdomjoin-gui: $(NETDOMJOIN_GUI_OBJ) + @echo Linking $@ + @$(CC) $(FLAGS) $(GTK_FLAGS) -o $@ $(NETDOMJOIN_GUI_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(GTK_LIBS) + clean: @rm -f $(PROGS) diff --git a/source3/lib/netapi/examples/logo.png b/source3/lib/netapi/examples/logo.png new file mode 100644 index 0000000000..6df4ace659 Binary files /dev/null and b/source3/lib/netapi/examples/logo.png differ diff --git a/source3/lib/netapi/examples/netdomjoin-gui.c b/source3/lib/netapi/examples/netdomjoin-gui.c new file mode 100644 index 0000000000..8ca6897cab --- /dev/null +++ b/source3/lib/netapi/examples/netdomjoin-gui.c @@ -0,0 +1,1347 @@ +/* + * Unix SMB/CIFS implementation. + * Join Support (gtk + netapi) + * Copyright (C) Guenther Deschner 2007 + * + * 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 3 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, see . + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#define MAX_CRED_LEN 256 +#define MAX_NETBIOS_NAME_LEN 15 + +#define SAMBA_ICON_PATH "/usr/share/pixmaps/samba/samba.ico" +#define SAMBA_IMAGE_PATH "/usr/share/pixmaps/samba/logo.png" + +#define WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED ( 0x00000020 ) +#define WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE ( 0x00000004 ) +#define WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE ( 0x00000002 ) +#define WKSSVC_JOIN_FLAGS_JOIN_TYPE ( 0x00000001 ) + +#define NetSetupWorkgroupName ( 2 ) +#define NetSetupDomainName ( 3 ) + +#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0) + +struct srvsvc_NetSrvInfo1005 { + const char *comment;/* [unique,charset(UTF16)] */ +}; + +static gboolean verbose = FALSE; + +typedef struct join_state { + struct libnetapi_ctx *ctx; + GtkWidget *window_main; + GtkWidget *window_parent; + GtkWidget *window_do_change; + GtkWidget *window_creds_prompt; + GtkWidget *entry_account; + GtkWidget *entry_password; + GtkWidget *entry_domain; + GtkWidget *entry_workgroup; + GtkWidget *button_ok; + GtkWidget *button_apply; + GtkWidget *button_ok_creds; + GtkWidget *label_reboot; + GtkWidget *label_current_name_buffer; + GtkWidget *label_current_name_type; + GtkWidget *label_full_computer_name; + uint16_t name_type_initial; + uint16_t name_type_new; + char *name_buffer_initial; + char *name_buffer_new; + char *password; + char *account; + char *comment; + char *comment_new; + char *my_fqdn; + char *my_dnsdomain; + char *my_hostname; + uint16_t server_role; + gboolean settings_changed; + gboolean hostname_changed; +} join_state; + +static void debug(const char *format, ...) +{ + va_list args; + + if (!verbose) { + return; + } + + va_start(args, format); + g_vprintf(format, args); + va_end(args); +} + +static gboolean callback_delete_event(GtkWidget *widget, + GdkEvent *event, + gpointer data) +{ + gtk_main_quit(); + return FALSE; +} + +static void callback_do_close(GtkWidget *widget, + gpointer data) +{ + debug("Closing now...\n"); + gtk_widget_destroy(data); +} + +static void free_join_state(struct join_state *s) +{ + SAFE_FREE(s->name_buffer_initial); + SAFE_FREE(s->name_buffer_new); + SAFE_FREE(s->password); + SAFE_FREE(s->account); + SAFE_FREE(s->comment); + SAFE_FREE(s->comment_new); + SAFE_FREE(s->my_fqdn); + SAFE_FREE(s->my_dnsdomain); + SAFE_FREE(s->my_hostname); + +} + +static void do_cleanup(struct join_state *state) +{ + libnetapi_free(state->ctx); + free_join_state(state); +} + +static void callback_apply_description_change(GtkWidget *widget, + gpointer data) +{ + struct join_state *state = (struct join_state *)data; + NET_API_STATUS status = 0; + uint32_t parm_err = 0; + struct srvsvc_NetSrvInfo1005 info1005; + GtkWidget *dialog; + + info1005.comment = state->comment_new; + + status = NetServerSetInfo(NULL, 1005, (uint8_t *)&info1005, &parm_err); + if (status) { + debug("NetServerSetInfo failed with: %s\n", + libnetapi_errstr(state->ctx, status)); + dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + "Failed to change computer description: %s.", + libnetapi_errstr(state->ctx, status)); + g_signal_connect_swapped(dialog, "response", + G_CALLBACK(gtk_widget_destroy), + dialog); + + gtk_widget_show(dialog); + return; + } + + gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), FALSE); +} + +static void callback_do_exit(GtkWidget *widget, + gpointer data) +{ + GtkWidget *dialog; + gint result; + struct join_state *state = (struct join_state *)data; + + if (!state->settings_changed) { + callback_delete_event(NULL, NULL, NULL); + return; + } + + dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_YES_NO, + "You must restart your computer before the new settings will take effect."); + result = gtk_dialog_run(GTK_DIALOG(dialog)); + switch (result) { + case GTK_RESPONSE_YES: + g_print("would reboot here\n"); + break; + case GTK_RESPONSE_NO: + default: + break; + } + gtk_widget_destroy(dialog); + gtk_widget_destroy(state->window_main); + do_cleanup(state); + exit(0); +} + + +static void callback_do_reboot(GtkWidget *widget, + gpointer data, + gpointer data2) +{ + GtkWidget *dialog; + struct join_state *state = (struct join_state *)data2; + + debug("callback_do_reboot\n"); + + state->settings_changed = TRUE; + dialog = gtk_message_dialog_new(GTK_WINDOW(data), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_OK, + "You must restart this computer for the changes to take effect."); +#if 0 + g_signal_connect_swapped(dialog, "response", + G_CALLBACK(gtk_widget_destroy), + dialog); + + debug("showing dialog\n"); + gtk_widget_show(dialog); +#else + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); +#endif + + gtk_label_set_text(GTK_LABEL(state->label_reboot), "Changes will take effect after you restart this computer"); + + debug("destroying do_change window\n"); + gtk_widget_destroy(GTK_WIDGET(state->window_do_change)); + + { + uint32_t status; + const char *buffer; + uint16_t type; + + status = NetGetJoinInformation(NULL, &buffer, &type); + if (status != 0) { + g_print("failed to query status\n"); + return; + } + + debug("got new status: %s\n", buffer); +#if 0 + SAFE_FREE(state->name_buffer_new); + state->name_buffer_new = strdup(buffer); + SAFE_FREE(buffer); + state->name_type_new = type; +#endif + gtk_label_set_text(GTK_LABEL(state->label_current_name_buffer), state->name_buffer_new); + if (state->name_type_new == 3) { + gtk_label_set_text(GTK_LABEL(state->label_current_name_type), "Domain:"); + } else { + gtk_label_set_text(GTK_LABEL(state->label_current_name_type), "Workgroup:"); + } + } +} + +static void callback_return_username(GtkWidget *widget, + gpointer data) +{ + const gchar *entry_text; + struct join_state *state = (struct join_state *)data; + if (!widget) { + return; + } + entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); + debug("callback_return_username: %s\n", entry_text); + SAFE_FREE(state->account); + state->account = strdup(entry_text); +} + +static void callback_return_username_and_enter(GtkWidget *widget, + gpointer data) +{ + const gchar *entry_text; + struct join_state *state = (struct join_state *)data; + if (!widget) { + return; + } + entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); + debug("callback_return_username: %s\n", entry_text); + SAFE_FREE(state->account); + state->account = strdup(entry_text); + g_signal_emit_by_name(state->button_ok_creds, "clicked"); +} + +static void callback_return_password(GtkWidget *widget, + gpointer data) +{ + const gchar *entry_text; + struct join_state *state = (struct join_state *)data; + if (!widget) { + return; + } + entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); +#ifdef DEBUG_PASSWORD + debug("callback_return_password: %s\n", entry_text); +#else + debug("callback_return_password: (not printed)\n"); +#endif + SAFE_FREE(state->password); + state->password = strdup(entry_text); +} + +static void callback_return_password_and_enter(GtkWidget *widget, + gpointer data) +{ + const gchar *entry_text; + struct join_state *state = (struct join_state *)data; + if (!widget) { + return; + } + entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); +#ifdef DEBUG_PASSWORD + debug("callback_return_password: %s\n", entry_text); +#else + debug("callback_return_password: (not printed)\n"); +#endif + SAFE_FREE(state->password); + state->password = strdup(entry_text); + g_signal_emit_by_name(state->button_ok_creds, "clicked"); +} + +static void callback_do_hostname_change(GtkWidget *widget, + gpointer data) +{ + GtkWidget *dialog; + const char *str = NULL; + + struct join_state *state = (struct join_state *)data; + + switch (state->name_type_initial) { + case NetSetupDomainName: + str = "To be implemented: call NetRenameMachineInDomain\n"; + break; + case NetSetupWorkgroupName: + str = "To be implemented: call SetComputerNameEx\n"; + break; + default: + break; + } + + dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + str); + + g_signal_connect_swapped(dialog, "response", + G_CALLBACK(gtk_widget_destroy), + dialog); + gtk_widget_show(dialog); +} + +static void callback_do_join(GtkWidget *widget, + gpointer data) +{ + GtkWidget *dialog; + + NET_API_STATUS status; + const char *err_str = NULL; + uint32_t join_flags = 0; + uint32_t unjoin_flags = 0; + gboolean domain_join = FALSE; + gboolean try_unjoin = FALSE; + const char *domain_or_workgroup = NULL; + + struct join_state *state = (struct join_state *)data; + + callback_return_username(state->entry_account, state); + callback_return_password(state->entry_password, state); + + if (state->window_creds_prompt) { + gtk_widget_destroy(GTK_WIDGET(state->window_creds_prompt)); + } + + if (state->name_type_new == NetSetupDomainName) { + domain_join = TRUE; + join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE | + WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE | + WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED; /* for testing */ + domain_or_workgroup = "domain"; + } else { + domain_or_workgroup = "workgroup"; + } + + if ((state->name_type_initial == NetSetupDomainName) && + (state->name_type_new == NetSetupWorkgroupName)) { + try_unjoin = TRUE; + unjoin_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE | + WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE; + } + + debug("callback_do_join: Joining a %s named %s using join_flags 0x%08x ", + domain_or_workgroup, + state->name_buffer_new, + join_flags); + if (domain_join) { + debug("as %s ", state->account); +#ifdef DEBUG_PASSWORD + debug("with %s ", state->password); +#endif + } + debug("\n"); + if (try_unjoin) { + + debug("callback_do_join: Unjoining\n"); + + status = NetUnjoinDomain(NULL, + state->account, + state->password, + unjoin_flags); + if (status != 0) { + err_str = libnetapi_errstr(state->ctx, status); + g_print("callback_do_join: failed to unjoin (%s)\n", + err_str); + + dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "The following error occured attempting to unjoin the %s: \"%s\": %s", + domain_or_workgroup, + state->name_buffer_new, + err_str); + + g_signal_connect_swapped(dialog, "response", + G_CALLBACK(gtk_widget_destroy), + dialog); + + gtk_widget_show(dialog); + + return; + } + + } + status = NetJoinDomain(NULL, + state->name_buffer_new, + NULL, + state->account, + state->password, + join_flags); + if (status != 0) { + err_str = libnetapi_errstr(state->ctx, status); + g_print("callback_do_join: failed to join (%s)\n", err_str); + + dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "The following error occured attempting to join the %s: \"%s\": %s", + domain_or_workgroup, + state->name_buffer_new, + err_str); + + g_signal_connect_swapped(dialog, "response", + G_CALLBACK(gtk_widget_destroy), + dialog); + + gtk_widget_show(dialog); + + return; + } + + debug("callback_do_join: Successfully joined %s\n", + domain_or_workgroup); + + dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_OK, + "Welcome to the %s %s.", + state->name_buffer_new, + domain_or_workgroup); + + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + + callback_do_reboot(NULL, state->window_parent, state); +} + +static void callback_creds_prompt(GtkWidget *widget, + gpointer data) +{ + GtkWidget *window; + GtkWidget *box1; + GtkWidget *bbox; + GtkWidget *button; + GtkWidget *label; + + struct join_state *state = (struct join_state *)data; + + debug("callback_creds_prompt:\n"); + + state->window_parent = state->window_do_change; + + if (state->hostname_changed) { + return callback_do_hostname_change(NULL, state); + } + + if ((state->name_type_initial != NetSetupDomainName) && + (state->name_type_new != NetSetupDomainName)) { + return callback_do_join(NULL, state); + } + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + + gtk_window_set_title(GTK_WINDOW(window), "Computer Name Changes"); + gtk_window_set_resizable(GTK_WINDOW(window), FALSE); + gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); + gtk_widget_set_size_request(GTK_WIDGET(window), 380, 280); + gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL); +/* gtk_window_set_icon_name(GTK_WIDGET(window), GTK_STOCK_DIALOG_AUTHENTICATION); */ + state->window_creds_prompt = window; + + g_signal_connect(G_OBJECT(window), "delete_event", + G_CALLBACK(callback_do_close), window); + + gtk_container_set_border_width(GTK_CONTAINER(window), 10); + + box1 = gtk_vbox_new(FALSE, 0); + + gtk_container_add(GTK_CONTAINER(window), box1); + + if ((state->name_type_initial == NetSetupDomainName) && + (state->name_type_new == NetSetupWorkgroupName)) { + label = gtk_label_new("Enter the name and password of an account with permission to leave the domain.\n"); + } else { + label = gtk_label_new("Enter the name and password of an account with permission to join the domain.\n"); + } + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + + gtk_box_pack_start(GTK_BOX(box1), label, FALSE, FALSE, 0); + + gtk_widget_show(label); + + /* USER NAME */ + label = gtk_label_new("User name:"); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_box_pack_start(GTK_BOX(box1), label, FALSE, FALSE, 0); + gtk_widget_show(label); + + state->entry_account = gtk_entry_new(); + gtk_entry_set_max_length(GTK_ENTRY(state->entry_account), MAX_CRED_LEN); + g_signal_connect(G_OBJECT(state->entry_account), "activate", + G_CALLBACK(callback_return_username_and_enter), + (gpointer)state); + gtk_editable_select_region(GTK_EDITABLE(state->entry_account), + 0, GTK_ENTRY(state->entry_account)->text_length); + gtk_box_pack_start(GTK_BOX(box1), state->entry_account, TRUE, TRUE, 0); + gtk_widget_show(state->entry_account); + + /* PASSWORD */ + label = gtk_label_new("Password:"); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_box_pack_start(GTK_BOX(box1), label, FALSE, FALSE, 0); + gtk_widget_show(label); + + state->entry_password = gtk_entry_new(); + gtk_entry_set_max_length(GTK_ENTRY(state->entry_password), MAX_CRED_LEN); + gtk_entry_set_visibility(GTK_ENTRY(state->entry_password), FALSE); + g_signal_connect(G_OBJECT(state->entry_password), "activate", + G_CALLBACK(callback_return_password_and_enter), + (gpointer)state); + gtk_editable_set_editable(GTK_EDITABLE(state->entry_password), TRUE); + gtk_editable_select_region(GTK_EDITABLE(state->entry_password), + 0, GTK_ENTRY(state->entry_password)->text_length); + gtk_box_pack_start(GTK_BOX(box1), state->entry_password, TRUE, TRUE, 0); + gtk_widget_show(state->entry_password); + + bbox = gtk_hbutton_box_new(); + gtk_container_set_border_width(GTK_CONTAINER(bbox), 5); + gtk_container_add(GTK_CONTAINER(box1), bbox); + gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); + gtk_box_set_spacing(GTK_BOX(bbox), 10); + + state->button_ok_creds = gtk_button_new_from_stock(GTK_STOCK_OK); + gtk_widget_grab_focus(GTK_WIDGET(state->button_ok_creds)); + gtk_container_add(GTK_CONTAINER(bbox), state->button_ok_creds); + g_signal_connect(G_OBJECT(state->button_ok_creds), "clicked", + G_CALLBACK(callback_do_join), + (gpointer)state); + gtk_widget_show(state->button_ok_creds); + + button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); + gtk_container_add(GTK_CONTAINER(bbox), button); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(callback_do_close), (gpointer) window); + gtk_widget_show_all(window); +} + +static void callback_enter_hostname_and_unlock(GtkWidget *widget, + gpointer data) +{ + const gchar *entry_text = NULL; + char *str = NULL; + struct join_state *state = (struct join_state *)data; + + entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); + debug("callback_enter_hostname_and_unlock: %s\n", entry_text); + if (!entry_text || entry_text[0] == 0) { + state->hostname_changed = FALSE; + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); + return; + } + if (strcasecmp(state->my_hostname, entry_text) == 0) { + state->hostname_changed = FALSE; + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); + return; + } + state->hostname_changed = TRUE; + if (state->name_type_initial == NetSetupDomainName) { + asprintf(&str, "%s.%s", entry_text, state->my_dnsdomain); + } else { + asprintf(&str, "%s.", entry_text); + } + gtk_label_set_text(GTK_LABEL(state->label_full_computer_name), str); + free(str); + + if (state->hostname_changed && str && str[0] != 0 && str[0] != '.') { + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), TRUE); + } +} + +static void callback_enter_computer_description_and_unlock(GtkWidget *widget, + gpointer data) +{ + const gchar *entry_text = NULL; + struct join_state *state = (struct join_state *)data; + int string_unchanged = 0; + + entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); + debug("callback_enter_computer_description_and_unlock: %s\n", + entry_text); +#if 0 + if (!entry_text || entry_text[0] == 0) { + string_unchanged = 1; + gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), + FALSE); + return; + } +#endif + if (entry_text && strcasecmp(state->comment, entry_text) == 0) { + string_unchanged = 1; + gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), + FALSE); + return; + } + + gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), TRUE); + SAFE_FREE(state->comment_new); + state->comment_new = strdup(entry_text); + +} + + +static void callback_enter_workgroup_and_unlock(GtkWidget *widget, + gpointer data) +{ + const gchar *entry_text = NULL; + struct join_state *state = (struct join_state *)data; + + entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); + debug("callback_enter_workgroup_and_unlock: %s\n", entry_text); + if (!entry_text || entry_text[0] == 0) { + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); + return; + } + if (strcasecmp(state->name_buffer_initial, entry_text) == 0) { + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); + return; + } + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), TRUE); + SAFE_FREE(state->name_buffer_new); + state->name_buffer_new = strdup(entry_text); + state->name_type_new = NetSetupWorkgroupName; +} + +static void callback_enter_domain_and_unlock(GtkWidget *widget, + gpointer data) +{ + const gchar *entry_text = NULL; + struct join_state *state = (struct join_state *)data; + + entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); + debug("callback_enter_domain_and_unlock: %s\n", entry_text); + if (!entry_text || entry_text[0] == 0) { + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); + return; + } + if (strcasecmp(state->name_buffer_initial, entry_text) == 0) { + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); + return; + } + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), TRUE); + SAFE_FREE(state->name_buffer_new); + state->name_buffer_new = strdup(entry_text); + state->name_type_new = NetSetupDomainName; +} + +static void callback_continue(GtkWidget *widget, + gpointer data) +{ + struct join_state *state = (struct join_state *)data; + + gtk_widget_grab_focus(GTK_WIDGET(state->button_ok)); + g_signal_emit_by_name(state->button_ok, "clicked"); +} + +static void callback_apply_continue(GtkWidget *widget, + gpointer data) +{ + struct join_state *state = (struct join_state *)data; + + gtk_widget_grab_focus(GTK_WIDGET(state->button_apply)); + g_signal_emit_by_name(state->button_apply, "clicked"); +} + +static void callback_do_join_workgroup(GtkWidget *widget, + gpointer data) +{ + struct join_state *state = (struct join_state *)data; + debug("callback_do_join_workgroup choosen\n"); + gtk_widget_set_sensitive(GTK_WIDGET(state->entry_workgroup), TRUE); + gtk_widget_grab_focus(GTK_WIDGET(state->entry_workgroup)); + gtk_widget_set_sensitive(GTK_WIDGET(state->entry_domain), FALSE); + callback_enter_workgroup_and_unlock(state->entry_workgroup, state); /* TEST */ +} + +static void callback_do_join_domain(GtkWidget *widget, + gpointer data) +{ + struct join_state *state = (struct join_state *)data; + debug("callback_do_join_domain choosen\n"); + gtk_widget_set_sensitive(GTK_WIDGET(state->entry_domain), TRUE); + gtk_widget_grab_focus(GTK_WIDGET(state->entry_domain)); + gtk_widget_set_sensitive(GTK_WIDGET(state->entry_workgroup), FALSE); + callback_enter_domain_and_unlock(state->entry_domain, state); /* TEST */ +} + +static void callback_do_change(GtkWidget *widget, + gpointer data) +{ + GtkWidget *window; + GtkWidget *box1; + GtkWidget *bbox; + GtkWidget *button_workgroup; + GtkWidget *button_domain; + GtkWidget *button; + GtkWidget *label; + GtkWidget *frame_horz; + GtkWidget *vbox; + GtkWidget *entry; + GSList *group; + + struct join_state *state = (struct join_state *)data; + + debug("callback_do_change called\n"); + + if (state->server_role == 3) { + GtkWidget *dialog; + dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + "Domain controller cannot be moved from one domain to another, they must first be demoted. Renaming this domain controller may cause it to become temporarily unavailable to users and computers. For information on renaming domain controllers, including alternate renaming methods, see Help and Support. To continue renaming this domain controller, click OK."); + g_signal_connect_swapped(dialog, "response", + G_CALLBACK(gtk_widget_destroy), + dialog); + + gtk_widget_show(dialog); + return; + } + + state->button_ok = gtk_button_new_from_stock(GTK_STOCK_OK); + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + + gtk_window_set_title(GTK_WINDOW(window), "Computer Name Changes"); + gtk_window_set_resizable(GTK_WINDOW(window), FALSE); + gtk_widget_set_size_request(GTK_WIDGET(window), 480, 500); /* breite * höhe */ + gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL); + + g_signal_connect(G_OBJECT(window), "delete_event", + G_CALLBACK(callback_do_close), window); + + gtk_container_set_border_width(GTK_CONTAINER(window), 10); + + box1 = gtk_vbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(window), box1); + + label = gtk_label_new("You can change the name and membership of this computer. Changes may affect access to network ressources."); + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_box_pack_start(GTK_BOX(box1), label, TRUE, TRUE, 0); + gtk_widget_show(label); + + /* COMPUTER NAME */ + label = gtk_label_new("Computer name:"); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_box_pack_start(GTK_BOX(box1), label, TRUE, TRUE, 0); + gtk_widget_show(label); + + state->label_full_computer_name = gtk_label_new(NULL); + { + entry = gtk_entry_new(); + gtk_entry_set_max_length(GTK_ENTRY(entry), MAX_NETBIOS_NAME_LEN); + g_signal_connect(G_OBJECT(entry), "changed", + G_CALLBACK(callback_enter_hostname_and_unlock), + (gpointer)state); + gtk_entry_set_text(GTK_ENTRY(entry), state->my_hostname); + gtk_editable_select_region(GTK_EDITABLE(entry), + 0, GTK_ENTRY(entry)->text_length); + + gtk_editable_set_editable(GTK_EDITABLE(entry), TRUE); /* ! */ + gtk_box_pack_start(GTK_BOX(box1), entry, TRUE, TRUE, 0); + gtk_widget_show(entry); + } + + /* FULL COMPUTER NAME */ + label = gtk_label_new("Full computer name:"); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_box_pack_start(GTK_BOX(box1), label, TRUE, TRUE, 0); + gtk_widget_show(label); + + { + const gchar *entry_text; + char *str = NULL; + entry_text = gtk_entry_get_text(GTK_ENTRY(entry)); + if (state->name_type_initial == NetSetupDomainName) { + asprintf(&str, "%s.%s", entry_text, state->my_dnsdomain); + } else { + asprintf(&str, "%s.", entry_text); + } + gtk_label_set_text(GTK_LABEL(state->label_full_computer_name), str); + free(str); + gtk_misc_set_alignment(GTK_MISC(state->label_full_computer_name), 0, 0); + gtk_box_pack_start(GTK_BOX(box1), state->label_full_computer_name, TRUE, TRUE, 0); + gtk_widget_show(state->label_full_computer_name); + } + + /* BOX */ + frame_horz = gtk_frame_new ("Member Of"); + gtk_box_pack_start(GTK_BOX(box1), frame_horz, TRUE, TRUE, 10); + + vbox = gtk_vbox_new(FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(vbox), 10); + gtk_container_add(GTK_CONTAINER(frame_horz), vbox); + + /* TWO ENTRIES */ + state->entry_workgroup = gtk_entry_new(); + state->entry_domain = gtk_entry_new(); + + /* DOMAIN */ + button_domain = gtk_radio_button_new_with_label(NULL, "Domain"); + if (state->name_type_initial == NetSetupDomainName) { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_domain), TRUE); + } + gtk_box_pack_start(GTK_BOX(vbox), button_domain, TRUE, TRUE, 0); + g_signal_connect(G_OBJECT(button_domain), "clicked", + G_CALLBACK(callback_do_join_domain), + (gpointer)state); + + { + gtk_entry_set_max_length(GTK_ENTRY(state->entry_domain), 50); + g_signal_connect(G_OBJECT(state->entry_domain), "changed", + G_CALLBACK(callback_enter_domain_and_unlock), + (gpointer)state); + g_signal_connect(G_OBJECT(state->entry_domain), "activate", + G_CALLBACK(callback_continue), + (gpointer)state); + if (state->name_type_initial == NetSetupDomainName) { + gtk_entry_set_text(GTK_ENTRY(state->entry_domain), state->name_buffer_initial); + gtk_widget_set_sensitive(state->entry_workgroup, FALSE); + gtk_widget_set_sensitive(state->entry_domain, TRUE); + } + gtk_editable_set_editable(GTK_EDITABLE(state->entry_domain), TRUE); + gtk_box_pack_start(GTK_BOX(vbox), state->entry_domain, TRUE, TRUE, 0); + gtk_widget_show(state->entry_domain); + } + gtk_widget_show(button_domain); + + /* WORKGROUP */ + group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button_domain)); + button_workgroup = gtk_radio_button_new_with_label(group, "Workgroup"); + if (state->name_type_initial == NetSetupWorkgroupName) { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_workgroup), TRUE); + } + gtk_box_pack_start(GTK_BOX(vbox), button_workgroup, TRUE, TRUE, 0); + g_signal_connect(G_OBJECT(button_workgroup), "clicked", + G_CALLBACK(callback_do_join_workgroup), + (gpointer)state); + { + gtk_entry_set_max_length(GTK_ENTRY(state->entry_workgroup), MAX_NETBIOS_NAME_LEN); + g_signal_connect(G_OBJECT(state->entry_workgroup), "changed", + G_CALLBACK(callback_enter_workgroup_and_unlock), + (gpointer)state); + g_signal_connect(G_OBJECT(state->entry_workgroup), "activate", + G_CALLBACK(callback_continue), + (gpointer)state); + + if (state->name_type_initial == NetSetupWorkgroupName) { + gtk_entry_set_text(GTK_ENTRY(state->entry_workgroup), state->name_buffer_initial); + gtk_widget_set_sensitive(GTK_WIDGET(state->entry_domain), FALSE); + gtk_widget_set_sensitive(GTK_WIDGET(state->entry_workgroup), TRUE); + } + gtk_box_pack_start(GTK_BOX(vbox), state->entry_workgroup, TRUE, TRUE, 0); + gtk_widget_show(state->entry_workgroup); + } + gtk_widget_show(button_workgroup); + + /* BUTTONS */ + bbox = gtk_hbutton_box_new(); + gtk_container_set_border_width(GTK_CONTAINER(bbox), 5); + gtk_container_add(GTK_CONTAINER(box1), bbox); + gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); + gtk_box_set_spacing(GTK_BOX(bbox), 10); + + state->window_do_change = window; + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); /* !!! */ + gtk_container_add(GTK_CONTAINER(bbox), state->button_ok); + g_signal_connect(G_OBJECT(state->button_ok), "clicked", + G_CALLBACK(callback_creds_prompt), + (gpointer)state); + + button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); + gtk_container_add(GTK_CONTAINER(bbox), button); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(callback_do_close), + (gpointer)window); + + gtk_widget_show_all(window); + +} + +static void callback_do_about(GtkWidget *widget, + gpointer data) +{ + GdkPixbuf *logo; + GError *error = NULL; + + debug("callback_do_about called\n"); + + logo = gdk_pixbuf_new_from_file(SAMBA_IMAGE_PATH, + &error); + if (logo == NULL) { + g_print("failed to load logo from %s: %s\n", + SAMBA_IMAGE_PATH, error->message); + } + + gtk_show_about_dialog(data, + "name", "Samba", + "version", "3.2.0pre2-GIT-904a90-test", + "copyright", "Copyright Andrew Tridgell and the Samba Team 1992-2007", + "website", "http://www.samba.org", + "license", "GPLv3", + "logo", logo, + "comments", "Samba gtk domain join utility", + NULL); +} + +static int draw_main_window(struct join_state *state) +{ + GtkWidget *window; + GtkWidget *button; + GtkWidget *label; + GtkWidget *main_vbox; + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *bbox; + GtkWidget *image; + GtkWidget *table; + GtkWidget *entry; + GdkPixbuf *icon; + GError *error = NULL; + + icon = gdk_pixbuf_new_from_file(SAMBA_ICON_PATH, + &error); + if (icon == NULL) { + g_print("failed to load logo from %s : %s\n", + SAMBA_ICON_PATH, error->message); + } + +#if 1 + image = gtk_image_new_from_file(SAMBA_IMAGE_PATH); +#else + image = gtk_image_new_from_file("/usr/share/pixmaps/redhat-system_settings.png"); +#endif + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + state->window_main = window; + + gtk_window_set_title(GTK_WINDOW(window), "Samba - Join Domain dialogue"); + gtk_widget_set_size_request(GTK_WIDGET(window), 600, 600); /* breite * höhe */ + gtk_window_set_resizable(GTK_WINDOW(window), FALSE); + gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL); + + g_signal_connect(G_OBJECT(window), "delete_event", + G_CALLBACK(callback_delete_event), NULL); + + gtk_container_set_border_width(GTK_CONTAINER(window), 10); + + main_vbox = gtk_vbox_new(FALSE, 10); + gtk_container_add(GTK_CONTAINER(window), main_vbox); + +#if 0 + gtk_box_pack_start(GTK_BOX(main_vbox), image, TRUE, TRUE, 10); + gtk_widget_show(image); +#endif + /* Hbox */ + hbox = gtk_hbox_new(FALSE, 10); + gtk_container_add(GTK_CONTAINER(main_vbox), hbox); + + { +/* gtk_box_pack_start(GTK_BOX(main_vbox), image, TRUE, TRUE, 10); */ + gtk_misc_set_alignment(GTK_MISC(image), 0, 0); + gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 10); + gtk_widget_show(image); + + /* Label */ + label = gtk_label_new("Samba uses the following information to identify your computer on the network."); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_widget_set_size_request(GTK_WIDGET(label), 500, 40); + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + gtk_widget_show(label); + } + + gtk_widget_show(hbox); + + vbox = gtk_vbox_new(FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(vbox), 10); + gtk_container_add(GTK_CONTAINER(main_vbox), vbox); + + /* Table */ + table = gtk_table_new(6, 3, TRUE); + gtk_table_set_row_spacings(GTK_TABLE(table), 5); + gtk_table_set_col_spacings(GTK_TABLE(table), 5); + gtk_container_add(GTK_CONTAINER(vbox), table); + + { + /* Label */ + label = gtk_label_new("Computer description:"); +/* gtk_misc_set_alignment(GTK_MISC(label), 0, 0); */ + gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1); + gtk_widget_show(label); + + state->button_apply = gtk_button_new_from_stock(GTK_STOCK_APPLY); + + /* Entry */ + entry = gtk_entry_new(); + gtk_entry_set_max_length(GTK_ENTRY(entry), 256); + g_signal_connect(G_OBJECT(entry), "changed", + G_CALLBACK(callback_enter_computer_description_and_unlock), + state); + g_signal_connect(G_OBJECT(entry), "activate", + G_CALLBACK(callback_apply_continue), + (gpointer)state); + + gtk_entry_set_text(GTK_ENTRY(entry), (char *)state->comment); + gtk_editable_set_editable(GTK_EDITABLE(entry), TRUE); /* ! */ + gtk_table_attach_defaults(GTK_TABLE(table), entry, 1, 3, 0, 1); + gtk_widget_show(entry); + } + + /* Label */ + label = gtk_label_new("For example: \"Samba \%v\"."); + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 3, 1, 2); + gtk_widget_show(label); + + /* Label */ + label = gtk_label_new("Full computer name:"); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3); + gtk_widget_show(label); + + { + /* Label */ + char *str = NULL; + if (state->name_type_initial == NetSetupDomainName) { + asprintf(&str, "%s.%s", state->my_hostname, + state->my_dnsdomain); + } else { + asprintf(&str, "%s.", state->my_hostname); + } + + label = gtk_label_new(str); + SAFE_FREE(str); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 3, 2, 3); + gtk_widget_show(label); + } + + /* Label */ + if (state->name_type_initial == NetSetupDomainName) { + label = gtk_label_new("Domain:"); + } else { + label = gtk_label_new("Workgroup:"); + } + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 3, 4); + gtk_widget_show(label); + state->label_current_name_type = label; + + /* Label */ + label = gtk_label_new(state->name_buffer_initial); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 3, 3, 4); + gtk_widget_show(label); + state->label_current_name_buffer = label; + + { + hbox = gtk_hbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(vbox), hbox); + label = gtk_label_new("To rename this computer or join a domain, click Change."); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + + } + + /* bbox */ + bbox = gtk_hbutton_box_new(); + gtk_container_set_border_width(GTK_CONTAINER(bbox), 5); + gtk_container_add(GTK_CONTAINER(hbox), bbox); + gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); + gtk_box_set_spacing(GTK_BOX(bbox), 10); + + button = gtk_button_new_with_mnemonic("Ch_ange"); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(callback_do_change), + (gpointer)state); + gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0); + gtk_widget_show(button); + + /* Label (hidden) */ + state->label_reboot = gtk_label_new(NULL); + gtk_label_set_line_wrap(GTK_LABEL(state->label_reboot), TRUE); + gtk_misc_set_alignment(GTK_MISC(state->label_reboot), 0, 0); + gtk_box_pack_start(GTK_BOX(vbox), state->label_reboot, TRUE, TRUE, 0); + gtk_widget_show(state->label_reboot); + +#if 0 + gtk_box_pack_start(GTK_BOX(vbox), + create_bbox(window, TRUE, NULL, 10, 85, 20, GTK_BUTTONBOX_END), + TRUE, TRUE, 5); +#endif + { + + GtkWidget *frame; + GtkWidget *bbox2; + GtkWidget *button2; + + frame = gtk_frame_new(NULL); + bbox2 = gtk_hbutton_box_new(); + + gtk_container_set_border_width(GTK_CONTAINER(bbox2), 5); + gtk_container_add(GTK_CONTAINER(frame), bbox2); + + /* Set the appearance of the Button Box */ + gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox2), GTK_BUTTONBOX_END); + gtk_box_set_spacing(GTK_BOX(bbox2), 10); + /*gtk_button_box_set_child_size(GTK_BUTTON_BOX(bbox2), child_w, child_h);*/ + + button2 = gtk_button_new_from_stock(GTK_STOCK_OK); + gtk_container_add(GTK_CONTAINER(bbox2), button2); + g_signal_connect(G_OBJECT(button2), "clicked", G_CALLBACK(callback_do_exit), state); + + button2 = gtk_button_new_from_stock(GTK_STOCK_CANCEL); + gtk_container_add(GTK_CONTAINER(bbox2), button2); + g_signal_connect(G_OBJECT(button2), "clicked", + G_CALLBACK(callback_delete_event), + window); + + gtk_container_add(GTK_CONTAINER(bbox2), state->button_apply); + g_signal_connect(G_OBJECT(state->button_apply), "clicked", + G_CALLBACK(callback_apply_description_change), + state); + gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), FALSE); + + button2 = gtk_button_new_from_stock(GTK_STOCK_ABOUT); + gtk_container_add(GTK_CONTAINER(bbox2), button2); + g_signal_connect(G_OBJECT(button2), "clicked", + G_CALLBACK(callback_do_about), + window); + + gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 5); + } + + gtk_widget_show_all(window); + + return 0; +} + +static int init_join_state(struct join_state **state) +{ + struct join_state *s; + + s = malloc(sizeof(struct join_state)); + if (!s) { + return -1; + } + + memset(s, '\0', sizeof(struct join_state)); + + *state = s; + + return 0; +} + +static int initialize_join_state(struct join_state *state, + const char *debug_level) +{ + struct libnetapi_ctx *ctx = NULL; + NET_API_STATUS status = 0; + + status = libnetapi_init(&ctx); + if (status) { + return status; + } + + if (debug_level) { + libnetapi_set_debuglevel(ctx, debug_level); + } + + { + char my_hostname[HOST_NAME_MAX]; + const char *p = NULL; + if (gethostname(my_hostname, sizeof(my_hostname)) == -1) { + return -1; + } + + state->my_fqdn = strdup(my_hostname); + if (!state->my_fqdn) { + return -1; + } + + p = strchr(my_hostname, '.'); + if (p) { + my_hostname[strlen(my_hostname) - strlen(p)] = '\0'; + state->my_hostname = strdup(my_hostname); + if (!state->my_hostname) { + return -1; + } + p++; + state->my_dnsdomain = strdup(p); + if (!state->my_dnsdomain) { + return -1; + } + } + } + + { + const char *buffer = NULL; + uint16_t type = 0; + status = NetGetJoinInformation(NULL, &buffer, &type); + if (status) { + return status; + } + state->name_buffer_initial = (char *)buffer; + state->name_type_initial = type; + } + + { + struct srvsvc_NetSrvInfo1005 *info1005 = NULL; + uint8_t *buffer = NULL; + + status = NetServerGetInfo(NULL, 1005, &buffer); + if (status) { + return status; + } + + info1005 = (struct srvsvc_NetSrvInfo1005 *)buffer; + + state->comment = strdup(info1005->comment); + if (!state->comment) { + return -1; + } + } +#if 0 + { + struct srvsvc_NetSrvInfo100 *info100 = NULL; + uint8_t *buffer = NULL; + + status = NetServerGetInfo(NULL, 100, &buffer); + if (status) { + return status; + } + + info100 = (struct srvsvc_NetSrvInfo100 *)buffer; + + state->comment = strdup(info100->comment); + if (!state->comment) { + return -1; + } + } +#endif + + state->ctx = ctx; + + return 0; +} + +int main(int argc, char **argv) +{ + GOptionContext *context = NULL; + static const char *debug_level = NULL; + struct join_state *state = NULL; + GError *error = NULL; + int ret = 0; + + static GOptionEntry entries[] = { + { "debug", 'd', 0, G_OPTION_ARG_STRING, &debug_level, "Debug level (for samba)", "N" }, + { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Verbose output", 0 }, + { NULL } + }; + + context = g_option_context_new("- Samba domain join utility"); + g_option_context_add_main_entries(context, entries, NULL); +/* g_option_context_add_main_entries(context, entries, GETTEXT_PACKAGE); */ + g_option_context_add_group(context, gtk_get_option_group(TRUE)); + g_option_context_parse(context, &argc, &argv, &error); + + gtk_init(&argc, &argv); + g_set_application_name("Samba"); + + ret = init_join_state(&state); + if (ret) { + return ret; + } + + ret = initialize_join_state(state, debug_level); + if (ret) { + return ret; + } + + draw_main_window(state); + + gtk_main(); + + do_cleanup(state); + + return 0; +} diff --git a/source3/lib/netapi/examples/samba.ico b/source3/lib/netapi/examples/samba.ico new file mode 100755 index 0000000000..b70c9590de Binary files /dev/null and b/source3/lib/netapi/examples/samba.ico differ -- cgit From 77a2e13cb1950cfd591f31b6a12eae66c342e632 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 21 Dec 2007 17:05:55 +0100 Subject: Move libnetapi examples into subdirs. Guenther (This used to be commit 0c3de6f3458419e57daaa71f1dad679897388f5a) --- source3/lib/netapi/examples/Makefile.in | 24 +- source3/lib/netapi/examples/getdc.c | 57 - source3/lib/netapi/examples/getdc/getdc.c | 57 + source3/lib/netapi/examples/logo.png | Bin 9329 -> 0 bytes source3/lib/netapi/examples/netdomjoin-gui.c | 1347 -------------------- .../lib/netapi/examples/netdomjoin-gui/logo.png | Bin 0 -> 9329 bytes .../lib/netapi/examples/netdomjoin-gui/samba.ico | Bin 0 -> 1406 bytes source3/lib/netapi/examples/netdomjoin.c | 107 -- .../netapi/examples/netdomjoin/netdomjoin-gui.c | 1347 ++++++++++++++++++++ .../lib/netapi/examples/netdomjoin/netdomjoin.c | 107 ++ source3/lib/netapi/examples/samba.ico | Bin 1406 -> 0 bytes 11 files changed, 1528 insertions(+), 1518 deletions(-) delete mode 100644 source3/lib/netapi/examples/getdc.c create mode 100644 source3/lib/netapi/examples/getdc/getdc.c delete mode 100644 source3/lib/netapi/examples/logo.png delete mode 100644 source3/lib/netapi/examples/netdomjoin-gui.c create mode 100644 source3/lib/netapi/examples/netdomjoin-gui/logo.png create mode 100755 source3/lib/netapi/examples/netdomjoin-gui/samba.ico delete mode 100644 source3/lib/netapi/examples/netdomjoin.c create mode 100644 source3/lib/netapi/examples/netdomjoin/netdomjoin-gui.c create mode 100644 source3/lib/netapi/examples/netdomjoin/netdomjoin.c delete mode 100755 source3/lib/netapi/examples/samba.ico (limited to 'source3/lib') diff --git a/source3/lib/netapi/examples/Makefile.in b/source3/lib/netapi/examples/Makefile.in index 119e722aec..c2f453dedc 100644 --- a/source3/lib/netapi/examples/Makefile.in +++ b/source3/lib/netapi/examples/Makefile.in @@ -14,6 +14,16 @@ DYNEXP=@DYNEXP@ COMPILE_CC = $(CC) -I. $(FLAGS) $(PICFLAG) -c $< -o $@ COMPILE = $(COMPILE_CC) +BINARY_PREREQS = proto_exists bin/.dummy + +MAKEDIR = || exec false; \ + if test -d "$$dir"; then :; else \ + echo mkdir "$$dir"; \ + mkdir -p "$$dir" >/dev/null 2>&1 || \ + test -d "$$dir" || \ + mkdir "$$dir" || \ + exec false; fi || exec false + .c.o: @if (: >> $@ || : > $@) >/dev/null 2>&1; then rm -f $@; else \ dir=`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` $(MAKEDIR); fi @@ -23,23 +33,23 @@ COMPILE = $(COMPILE_CC) echo "$(COMPILE_CC)" 1>&2;\ $(COMPILE_CC) >/dev/null 2>&1 -GETDC_OBJ = getdc.o -NETDOMJOIN_OBJ = netdomjoin.o -NETDOMJOIN_GUI_OBJ = netdomjoin-gui.o +GETDC_OBJ = getdc/getdc.o +NETDOMJOIN_OBJ = netdomjoin/netdomjoin.o +NETDOMJOIN_GUI_OBJ = netdomjoin-gui/netdomjoin-gui.o -PROGS = getdc netdomjoin netdomjoin-gui +PROGS = bin/getdc@EXEEXT@ bin/netdomjoin@EXEEXT@ bin/netdomjoin-gui@EXEEXT@ all: $(PROGS) -getdc: $(GETDC_OBJ) +bin/getdc@EXEEXT@: $(GETDC_OBJ) @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(GETDC_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) -netdomjoin: $(NETDOMJOIN_OBJ) +bin/netdomjoin@EXEEXT@: $(NETDOMJOIN_OBJ) @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(NETDOMJOIN_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) -netdomjoin-gui: $(NETDOMJOIN_GUI_OBJ) +bin/netdomjoin-gui@EXEEXT@: $(NETDOMJOIN_GUI_OBJ) @echo Linking $@ @$(CC) $(FLAGS) $(GTK_FLAGS) -o $@ $(NETDOMJOIN_GUI_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(GTK_LIBS) diff --git a/source3/lib/netapi/examples/getdc.c b/source3/lib/netapi/examples/getdc.c deleted file mode 100644 index ed6a8bd05d..0000000000 --- a/source3/lib/netapi/examples/getdc.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * GetDCName query - * Copyright (C) Guenther Deschner 2007 - * - * 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 3 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, see . - */ - -#include -#include -#include -#include -#include - -#include - -int main(int argc, char **argv) -{ - NET_API_STATUS status; - struct libnetapi_ctx *ctx = NULL; - uint8_t *buffer; - - if (argc < 3) { - printf("usage: getdc \n"); - return -1; - } - - status = libnetapi_init(&ctx); - if (status != 0) { - return status; - } - - libnetapi_set_username(ctx, ""); - libnetapi_set_password(ctx, ""); - - status = NetGetDCName(argv[1], argv[2], &buffer); - if (status != 0) { - printf("GetDcName failed with: %s\n", libnetapi_errstr(ctx, status)); - } else { - printf("%s\n", (char *)buffer); - } - - libnetapi_free(ctx); - - return status; -} diff --git a/source3/lib/netapi/examples/getdc/getdc.c b/source3/lib/netapi/examples/getdc/getdc.c new file mode 100644 index 0000000000..ed6a8bd05d --- /dev/null +++ b/source3/lib/netapi/examples/getdc/getdc.c @@ -0,0 +1,57 @@ +/* + * Unix SMB/CIFS implementation. + * GetDCName query + * Copyright (C) Guenther Deschner 2007 + * + * 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 3 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, see . + */ + +#include +#include +#include +#include +#include + +#include + +int main(int argc, char **argv) +{ + NET_API_STATUS status; + struct libnetapi_ctx *ctx = NULL; + uint8_t *buffer; + + if (argc < 3) { + printf("usage: getdc \n"); + return -1; + } + + status = libnetapi_init(&ctx); + if (status != 0) { + return status; + } + + libnetapi_set_username(ctx, ""); + libnetapi_set_password(ctx, ""); + + status = NetGetDCName(argv[1], argv[2], &buffer); + if (status != 0) { + printf("GetDcName failed with: %s\n", libnetapi_errstr(ctx, status)); + } else { + printf("%s\n", (char *)buffer); + } + + libnetapi_free(ctx); + + return status; +} diff --git a/source3/lib/netapi/examples/logo.png b/source3/lib/netapi/examples/logo.png deleted file mode 100644 index 6df4ace659..0000000000 Binary files a/source3/lib/netapi/examples/logo.png and /dev/null differ diff --git a/source3/lib/netapi/examples/netdomjoin-gui.c b/source3/lib/netapi/examples/netdomjoin-gui.c deleted file mode 100644 index 8ca6897cab..0000000000 --- a/source3/lib/netapi/examples/netdomjoin-gui.c +++ /dev/null @@ -1,1347 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * Join Support (gtk + netapi) - * Copyright (C) Guenther Deschner 2007 - * - * 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 3 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, see . - */ - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#define MAX_CRED_LEN 256 -#define MAX_NETBIOS_NAME_LEN 15 - -#define SAMBA_ICON_PATH "/usr/share/pixmaps/samba/samba.ico" -#define SAMBA_IMAGE_PATH "/usr/share/pixmaps/samba/logo.png" - -#define WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED ( 0x00000020 ) -#define WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE ( 0x00000004 ) -#define WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE ( 0x00000002 ) -#define WKSSVC_JOIN_FLAGS_JOIN_TYPE ( 0x00000001 ) - -#define NetSetupWorkgroupName ( 2 ) -#define NetSetupDomainName ( 3 ) - -#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0) - -struct srvsvc_NetSrvInfo1005 { - const char *comment;/* [unique,charset(UTF16)] */ -}; - -static gboolean verbose = FALSE; - -typedef struct join_state { - struct libnetapi_ctx *ctx; - GtkWidget *window_main; - GtkWidget *window_parent; - GtkWidget *window_do_change; - GtkWidget *window_creds_prompt; - GtkWidget *entry_account; - GtkWidget *entry_password; - GtkWidget *entry_domain; - GtkWidget *entry_workgroup; - GtkWidget *button_ok; - GtkWidget *button_apply; - GtkWidget *button_ok_creds; - GtkWidget *label_reboot; - GtkWidget *label_current_name_buffer; - GtkWidget *label_current_name_type; - GtkWidget *label_full_computer_name; - uint16_t name_type_initial; - uint16_t name_type_new; - char *name_buffer_initial; - char *name_buffer_new; - char *password; - char *account; - char *comment; - char *comment_new; - char *my_fqdn; - char *my_dnsdomain; - char *my_hostname; - uint16_t server_role; - gboolean settings_changed; - gboolean hostname_changed; -} join_state; - -static void debug(const char *format, ...) -{ - va_list args; - - if (!verbose) { - return; - } - - va_start(args, format); - g_vprintf(format, args); - va_end(args); -} - -static gboolean callback_delete_event(GtkWidget *widget, - GdkEvent *event, - gpointer data) -{ - gtk_main_quit(); - return FALSE; -} - -static void callback_do_close(GtkWidget *widget, - gpointer data) -{ - debug("Closing now...\n"); - gtk_widget_destroy(data); -} - -static void free_join_state(struct join_state *s) -{ - SAFE_FREE(s->name_buffer_initial); - SAFE_FREE(s->name_buffer_new); - SAFE_FREE(s->password); - SAFE_FREE(s->account); - SAFE_FREE(s->comment); - SAFE_FREE(s->comment_new); - SAFE_FREE(s->my_fqdn); - SAFE_FREE(s->my_dnsdomain); - SAFE_FREE(s->my_hostname); - -} - -static void do_cleanup(struct join_state *state) -{ - libnetapi_free(state->ctx); - free_join_state(state); -} - -static void callback_apply_description_change(GtkWidget *widget, - gpointer data) -{ - struct join_state *state = (struct join_state *)data; - NET_API_STATUS status = 0; - uint32_t parm_err = 0; - struct srvsvc_NetSrvInfo1005 info1005; - GtkWidget *dialog; - - info1005.comment = state->comment_new; - - status = NetServerSetInfo(NULL, 1005, (uint8_t *)&info1005, &parm_err); - if (status) { - debug("NetServerSetInfo failed with: %s\n", - libnetapi_errstr(state->ctx, status)); - dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - "Failed to change computer description: %s.", - libnetapi_errstr(state->ctx, status)); - g_signal_connect_swapped(dialog, "response", - G_CALLBACK(gtk_widget_destroy), - dialog); - - gtk_widget_show(dialog); - return; - } - - gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), FALSE); -} - -static void callback_do_exit(GtkWidget *widget, - gpointer data) -{ - GtkWidget *dialog; - gint result; - struct join_state *state = (struct join_state *)data; - - if (!state->settings_changed) { - callback_delete_event(NULL, NULL, NULL); - return; - } - - dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_YES_NO, - "You must restart your computer before the new settings will take effect."); - result = gtk_dialog_run(GTK_DIALOG(dialog)); - switch (result) { - case GTK_RESPONSE_YES: - g_print("would reboot here\n"); - break; - case GTK_RESPONSE_NO: - default: - break; - } - gtk_widget_destroy(dialog); - gtk_widget_destroy(state->window_main); - do_cleanup(state); - exit(0); -} - - -static void callback_do_reboot(GtkWidget *widget, - gpointer data, - gpointer data2) -{ - GtkWidget *dialog; - struct join_state *state = (struct join_state *)data2; - - debug("callback_do_reboot\n"); - - state->settings_changed = TRUE; - dialog = gtk_message_dialog_new(GTK_WINDOW(data), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_INFO, - GTK_BUTTONS_OK, - "You must restart this computer for the changes to take effect."); -#if 0 - g_signal_connect_swapped(dialog, "response", - G_CALLBACK(gtk_widget_destroy), - dialog); - - debug("showing dialog\n"); - gtk_widget_show(dialog); -#else - gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); -#endif - - gtk_label_set_text(GTK_LABEL(state->label_reboot), "Changes will take effect after you restart this computer"); - - debug("destroying do_change window\n"); - gtk_widget_destroy(GTK_WIDGET(state->window_do_change)); - - { - uint32_t status; - const char *buffer; - uint16_t type; - - status = NetGetJoinInformation(NULL, &buffer, &type); - if (status != 0) { - g_print("failed to query status\n"); - return; - } - - debug("got new status: %s\n", buffer); -#if 0 - SAFE_FREE(state->name_buffer_new); - state->name_buffer_new = strdup(buffer); - SAFE_FREE(buffer); - state->name_type_new = type; -#endif - gtk_label_set_text(GTK_LABEL(state->label_current_name_buffer), state->name_buffer_new); - if (state->name_type_new == 3) { - gtk_label_set_text(GTK_LABEL(state->label_current_name_type), "Domain:"); - } else { - gtk_label_set_text(GTK_LABEL(state->label_current_name_type), "Workgroup:"); - } - } -} - -static void callback_return_username(GtkWidget *widget, - gpointer data) -{ - const gchar *entry_text; - struct join_state *state = (struct join_state *)data; - if (!widget) { - return; - } - entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); - debug("callback_return_username: %s\n", entry_text); - SAFE_FREE(state->account); - state->account = strdup(entry_text); -} - -static void callback_return_username_and_enter(GtkWidget *widget, - gpointer data) -{ - const gchar *entry_text; - struct join_state *state = (struct join_state *)data; - if (!widget) { - return; - } - entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); - debug("callback_return_username: %s\n", entry_text); - SAFE_FREE(state->account); - state->account = strdup(entry_text); - g_signal_emit_by_name(state->button_ok_creds, "clicked"); -} - -static void callback_return_password(GtkWidget *widget, - gpointer data) -{ - const gchar *entry_text; - struct join_state *state = (struct join_state *)data; - if (!widget) { - return; - } - entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); -#ifdef DEBUG_PASSWORD - debug("callback_return_password: %s\n", entry_text); -#else - debug("callback_return_password: (not printed)\n"); -#endif - SAFE_FREE(state->password); - state->password = strdup(entry_text); -} - -static void callback_return_password_and_enter(GtkWidget *widget, - gpointer data) -{ - const gchar *entry_text; - struct join_state *state = (struct join_state *)data; - if (!widget) { - return; - } - entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); -#ifdef DEBUG_PASSWORD - debug("callback_return_password: %s\n", entry_text); -#else - debug("callback_return_password: (not printed)\n"); -#endif - SAFE_FREE(state->password); - state->password = strdup(entry_text); - g_signal_emit_by_name(state->button_ok_creds, "clicked"); -} - -static void callback_do_hostname_change(GtkWidget *widget, - gpointer data) -{ - GtkWidget *dialog; - const char *str = NULL; - - struct join_state *state = (struct join_state *)data; - - switch (state->name_type_initial) { - case NetSetupDomainName: - str = "To be implemented: call NetRenameMachineInDomain\n"; - break; - case NetSetupWorkgroupName: - str = "To be implemented: call SetComputerNameEx\n"; - break; - default: - break; - } - - dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - str); - - g_signal_connect_swapped(dialog, "response", - G_CALLBACK(gtk_widget_destroy), - dialog); - gtk_widget_show(dialog); -} - -static void callback_do_join(GtkWidget *widget, - gpointer data) -{ - GtkWidget *dialog; - - NET_API_STATUS status; - const char *err_str = NULL; - uint32_t join_flags = 0; - uint32_t unjoin_flags = 0; - gboolean domain_join = FALSE; - gboolean try_unjoin = FALSE; - const char *domain_or_workgroup = NULL; - - struct join_state *state = (struct join_state *)data; - - callback_return_username(state->entry_account, state); - callback_return_password(state->entry_password, state); - - if (state->window_creds_prompt) { - gtk_widget_destroy(GTK_WIDGET(state->window_creds_prompt)); - } - - if (state->name_type_new == NetSetupDomainName) { - domain_join = TRUE; - join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE | - WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE | - WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED; /* for testing */ - domain_or_workgroup = "domain"; - } else { - domain_or_workgroup = "workgroup"; - } - - if ((state->name_type_initial == NetSetupDomainName) && - (state->name_type_new == NetSetupWorkgroupName)) { - try_unjoin = TRUE; - unjoin_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE | - WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE; - } - - debug("callback_do_join: Joining a %s named %s using join_flags 0x%08x ", - domain_or_workgroup, - state->name_buffer_new, - join_flags); - if (domain_join) { - debug("as %s ", state->account); -#ifdef DEBUG_PASSWORD - debug("with %s ", state->password); -#endif - } - debug("\n"); - if (try_unjoin) { - - debug("callback_do_join: Unjoining\n"); - - status = NetUnjoinDomain(NULL, - state->account, - state->password, - unjoin_flags); - if (status != 0) { - err_str = libnetapi_errstr(state->ctx, status); - g_print("callback_do_join: failed to unjoin (%s)\n", - err_str); - - dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - "The following error occured attempting to unjoin the %s: \"%s\": %s", - domain_or_workgroup, - state->name_buffer_new, - err_str); - - g_signal_connect_swapped(dialog, "response", - G_CALLBACK(gtk_widget_destroy), - dialog); - - gtk_widget_show(dialog); - - return; - } - - } - status = NetJoinDomain(NULL, - state->name_buffer_new, - NULL, - state->account, - state->password, - join_flags); - if (status != 0) { - err_str = libnetapi_errstr(state->ctx, status); - g_print("callback_do_join: failed to join (%s)\n", err_str); - - dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - "The following error occured attempting to join the %s: \"%s\": %s", - domain_or_workgroup, - state->name_buffer_new, - err_str); - - g_signal_connect_swapped(dialog, "response", - G_CALLBACK(gtk_widget_destroy), - dialog); - - gtk_widget_show(dialog); - - return; - } - - debug("callback_do_join: Successfully joined %s\n", - domain_or_workgroup); - - dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_INFO, - GTK_BUTTONS_OK, - "Welcome to the %s %s.", - state->name_buffer_new, - domain_or_workgroup); - - gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); - - callback_do_reboot(NULL, state->window_parent, state); -} - -static void callback_creds_prompt(GtkWidget *widget, - gpointer data) -{ - GtkWidget *window; - GtkWidget *box1; - GtkWidget *bbox; - GtkWidget *button; - GtkWidget *label; - - struct join_state *state = (struct join_state *)data; - - debug("callback_creds_prompt:\n"); - - state->window_parent = state->window_do_change; - - if (state->hostname_changed) { - return callback_do_hostname_change(NULL, state); - } - - if ((state->name_type_initial != NetSetupDomainName) && - (state->name_type_new != NetSetupDomainName)) { - return callback_do_join(NULL, state); - } - - window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - - gtk_window_set_title(GTK_WINDOW(window), "Computer Name Changes"); - gtk_window_set_resizable(GTK_WINDOW(window), FALSE); - gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); - gtk_widget_set_size_request(GTK_WIDGET(window), 380, 280); - gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL); -/* gtk_window_set_icon_name(GTK_WIDGET(window), GTK_STOCK_DIALOG_AUTHENTICATION); */ - state->window_creds_prompt = window; - - g_signal_connect(G_OBJECT(window), "delete_event", - G_CALLBACK(callback_do_close), window); - - gtk_container_set_border_width(GTK_CONTAINER(window), 10); - - box1 = gtk_vbox_new(FALSE, 0); - - gtk_container_add(GTK_CONTAINER(window), box1); - - if ((state->name_type_initial == NetSetupDomainName) && - (state->name_type_new == NetSetupWorkgroupName)) { - label = gtk_label_new("Enter the name and password of an account with permission to leave the domain.\n"); - } else { - label = gtk_label_new("Enter the name and password of an account with permission to join the domain.\n"); - } - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); - - gtk_box_pack_start(GTK_BOX(box1), label, FALSE, FALSE, 0); - - gtk_widget_show(label); - - /* USER NAME */ - label = gtk_label_new("User name:"); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_box_pack_start(GTK_BOX(box1), label, FALSE, FALSE, 0); - gtk_widget_show(label); - - state->entry_account = gtk_entry_new(); - gtk_entry_set_max_length(GTK_ENTRY(state->entry_account), MAX_CRED_LEN); - g_signal_connect(G_OBJECT(state->entry_account), "activate", - G_CALLBACK(callback_return_username_and_enter), - (gpointer)state); - gtk_editable_select_region(GTK_EDITABLE(state->entry_account), - 0, GTK_ENTRY(state->entry_account)->text_length); - gtk_box_pack_start(GTK_BOX(box1), state->entry_account, TRUE, TRUE, 0); - gtk_widget_show(state->entry_account); - - /* PASSWORD */ - label = gtk_label_new("Password:"); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_box_pack_start(GTK_BOX(box1), label, FALSE, FALSE, 0); - gtk_widget_show(label); - - state->entry_password = gtk_entry_new(); - gtk_entry_set_max_length(GTK_ENTRY(state->entry_password), MAX_CRED_LEN); - gtk_entry_set_visibility(GTK_ENTRY(state->entry_password), FALSE); - g_signal_connect(G_OBJECT(state->entry_password), "activate", - G_CALLBACK(callback_return_password_and_enter), - (gpointer)state); - gtk_editable_set_editable(GTK_EDITABLE(state->entry_password), TRUE); - gtk_editable_select_region(GTK_EDITABLE(state->entry_password), - 0, GTK_ENTRY(state->entry_password)->text_length); - gtk_box_pack_start(GTK_BOX(box1), state->entry_password, TRUE, TRUE, 0); - gtk_widget_show(state->entry_password); - - bbox = gtk_hbutton_box_new(); - gtk_container_set_border_width(GTK_CONTAINER(bbox), 5); - gtk_container_add(GTK_CONTAINER(box1), bbox); - gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); - gtk_box_set_spacing(GTK_BOX(bbox), 10); - - state->button_ok_creds = gtk_button_new_from_stock(GTK_STOCK_OK); - gtk_widget_grab_focus(GTK_WIDGET(state->button_ok_creds)); - gtk_container_add(GTK_CONTAINER(bbox), state->button_ok_creds); - g_signal_connect(G_OBJECT(state->button_ok_creds), "clicked", - G_CALLBACK(callback_do_join), - (gpointer)state); - gtk_widget_show(state->button_ok_creds); - - button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); - gtk_container_add(GTK_CONTAINER(bbox), button); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(callback_do_close), (gpointer) window); - gtk_widget_show_all(window); -} - -static void callback_enter_hostname_and_unlock(GtkWidget *widget, - gpointer data) -{ - const gchar *entry_text = NULL; - char *str = NULL; - struct join_state *state = (struct join_state *)data; - - entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); - debug("callback_enter_hostname_and_unlock: %s\n", entry_text); - if (!entry_text || entry_text[0] == 0) { - state->hostname_changed = FALSE; - gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); - return; - } - if (strcasecmp(state->my_hostname, entry_text) == 0) { - state->hostname_changed = FALSE; - gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); - return; - } - state->hostname_changed = TRUE; - if (state->name_type_initial == NetSetupDomainName) { - asprintf(&str, "%s.%s", entry_text, state->my_dnsdomain); - } else { - asprintf(&str, "%s.", entry_text); - } - gtk_label_set_text(GTK_LABEL(state->label_full_computer_name), str); - free(str); - - if (state->hostname_changed && str && str[0] != 0 && str[0] != '.') { - gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), TRUE); - } -} - -static void callback_enter_computer_description_and_unlock(GtkWidget *widget, - gpointer data) -{ - const gchar *entry_text = NULL; - struct join_state *state = (struct join_state *)data; - int string_unchanged = 0; - - entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); - debug("callback_enter_computer_description_and_unlock: %s\n", - entry_text); -#if 0 - if (!entry_text || entry_text[0] == 0) { - string_unchanged = 1; - gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), - FALSE); - return; - } -#endif - if (entry_text && strcasecmp(state->comment, entry_text) == 0) { - string_unchanged = 1; - gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), - FALSE); - return; - } - - gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), TRUE); - SAFE_FREE(state->comment_new); - state->comment_new = strdup(entry_text); - -} - - -static void callback_enter_workgroup_and_unlock(GtkWidget *widget, - gpointer data) -{ - const gchar *entry_text = NULL; - struct join_state *state = (struct join_state *)data; - - entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); - debug("callback_enter_workgroup_and_unlock: %s\n", entry_text); - if (!entry_text || entry_text[0] == 0) { - gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); - return; - } - if (strcasecmp(state->name_buffer_initial, entry_text) == 0) { - gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); - return; - } - gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), TRUE); - SAFE_FREE(state->name_buffer_new); - state->name_buffer_new = strdup(entry_text); - state->name_type_new = NetSetupWorkgroupName; -} - -static void callback_enter_domain_and_unlock(GtkWidget *widget, - gpointer data) -{ - const gchar *entry_text = NULL; - struct join_state *state = (struct join_state *)data; - - entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); - debug("callback_enter_domain_and_unlock: %s\n", entry_text); - if (!entry_text || entry_text[0] == 0) { - gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); - return; - } - if (strcasecmp(state->name_buffer_initial, entry_text) == 0) { - gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); - return; - } - gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), TRUE); - SAFE_FREE(state->name_buffer_new); - state->name_buffer_new = strdup(entry_text); - state->name_type_new = NetSetupDomainName; -} - -static void callback_continue(GtkWidget *widget, - gpointer data) -{ - struct join_state *state = (struct join_state *)data; - - gtk_widget_grab_focus(GTK_WIDGET(state->button_ok)); - g_signal_emit_by_name(state->button_ok, "clicked"); -} - -static void callback_apply_continue(GtkWidget *widget, - gpointer data) -{ - struct join_state *state = (struct join_state *)data; - - gtk_widget_grab_focus(GTK_WIDGET(state->button_apply)); - g_signal_emit_by_name(state->button_apply, "clicked"); -} - -static void callback_do_join_workgroup(GtkWidget *widget, - gpointer data) -{ - struct join_state *state = (struct join_state *)data; - debug("callback_do_join_workgroup choosen\n"); - gtk_widget_set_sensitive(GTK_WIDGET(state->entry_workgroup), TRUE); - gtk_widget_grab_focus(GTK_WIDGET(state->entry_workgroup)); - gtk_widget_set_sensitive(GTK_WIDGET(state->entry_domain), FALSE); - callback_enter_workgroup_and_unlock(state->entry_workgroup, state); /* TEST */ -} - -static void callback_do_join_domain(GtkWidget *widget, - gpointer data) -{ - struct join_state *state = (struct join_state *)data; - debug("callback_do_join_domain choosen\n"); - gtk_widget_set_sensitive(GTK_WIDGET(state->entry_domain), TRUE); - gtk_widget_grab_focus(GTK_WIDGET(state->entry_domain)); - gtk_widget_set_sensitive(GTK_WIDGET(state->entry_workgroup), FALSE); - callback_enter_domain_and_unlock(state->entry_domain, state); /* TEST */ -} - -static void callback_do_change(GtkWidget *widget, - gpointer data) -{ - GtkWidget *window; - GtkWidget *box1; - GtkWidget *bbox; - GtkWidget *button_workgroup; - GtkWidget *button_domain; - GtkWidget *button; - GtkWidget *label; - GtkWidget *frame_horz; - GtkWidget *vbox; - GtkWidget *entry; - GSList *group; - - struct join_state *state = (struct join_state *)data; - - debug("callback_do_change called\n"); - - if (state->server_role == 3) { - GtkWidget *dialog; - dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - "Domain controller cannot be moved from one domain to another, they must first be demoted. Renaming this domain controller may cause it to become temporarily unavailable to users and computers. For information on renaming domain controllers, including alternate renaming methods, see Help and Support. To continue renaming this domain controller, click OK."); - g_signal_connect_swapped(dialog, "response", - G_CALLBACK(gtk_widget_destroy), - dialog); - - gtk_widget_show(dialog); - return; - } - - state->button_ok = gtk_button_new_from_stock(GTK_STOCK_OK); - window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - - gtk_window_set_title(GTK_WINDOW(window), "Computer Name Changes"); - gtk_window_set_resizable(GTK_WINDOW(window), FALSE); - gtk_widget_set_size_request(GTK_WIDGET(window), 480, 500); /* breite * höhe */ - gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL); - - g_signal_connect(G_OBJECT(window), "delete_event", - G_CALLBACK(callback_do_close), window); - - gtk_container_set_border_width(GTK_CONTAINER(window), 10); - - box1 = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(window), box1); - - label = gtk_label_new("You can change the name and membership of this computer. Changes may affect access to network ressources."); - gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_box_pack_start(GTK_BOX(box1), label, TRUE, TRUE, 0); - gtk_widget_show(label); - - /* COMPUTER NAME */ - label = gtk_label_new("Computer name:"); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_box_pack_start(GTK_BOX(box1), label, TRUE, TRUE, 0); - gtk_widget_show(label); - - state->label_full_computer_name = gtk_label_new(NULL); - { - entry = gtk_entry_new(); - gtk_entry_set_max_length(GTK_ENTRY(entry), MAX_NETBIOS_NAME_LEN); - g_signal_connect(G_OBJECT(entry), "changed", - G_CALLBACK(callback_enter_hostname_and_unlock), - (gpointer)state); - gtk_entry_set_text(GTK_ENTRY(entry), state->my_hostname); - gtk_editable_select_region(GTK_EDITABLE(entry), - 0, GTK_ENTRY(entry)->text_length); - - gtk_editable_set_editable(GTK_EDITABLE(entry), TRUE); /* ! */ - gtk_box_pack_start(GTK_BOX(box1), entry, TRUE, TRUE, 0); - gtk_widget_show(entry); - } - - /* FULL COMPUTER NAME */ - label = gtk_label_new("Full computer name:"); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_box_pack_start(GTK_BOX(box1), label, TRUE, TRUE, 0); - gtk_widget_show(label); - - { - const gchar *entry_text; - char *str = NULL; - entry_text = gtk_entry_get_text(GTK_ENTRY(entry)); - if (state->name_type_initial == NetSetupDomainName) { - asprintf(&str, "%s.%s", entry_text, state->my_dnsdomain); - } else { - asprintf(&str, "%s.", entry_text); - } - gtk_label_set_text(GTK_LABEL(state->label_full_computer_name), str); - free(str); - gtk_misc_set_alignment(GTK_MISC(state->label_full_computer_name), 0, 0); - gtk_box_pack_start(GTK_BOX(box1), state->label_full_computer_name, TRUE, TRUE, 0); - gtk_widget_show(state->label_full_computer_name); - } - - /* BOX */ - frame_horz = gtk_frame_new ("Member Of"); - gtk_box_pack_start(GTK_BOX(box1), frame_horz, TRUE, TRUE, 10); - - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 10); - gtk_container_add(GTK_CONTAINER(frame_horz), vbox); - - /* TWO ENTRIES */ - state->entry_workgroup = gtk_entry_new(); - state->entry_domain = gtk_entry_new(); - - /* DOMAIN */ - button_domain = gtk_radio_button_new_with_label(NULL, "Domain"); - if (state->name_type_initial == NetSetupDomainName) { - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_domain), TRUE); - } - gtk_box_pack_start(GTK_BOX(vbox), button_domain, TRUE, TRUE, 0); - g_signal_connect(G_OBJECT(button_domain), "clicked", - G_CALLBACK(callback_do_join_domain), - (gpointer)state); - - { - gtk_entry_set_max_length(GTK_ENTRY(state->entry_domain), 50); - g_signal_connect(G_OBJECT(state->entry_domain), "changed", - G_CALLBACK(callback_enter_domain_and_unlock), - (gpointer)state); - g_signal_connect(G_OBJECT(state->entry_domain), "activate", - G_CALLBACK(callback_continue), - (gpointer)state); - if (state->name_type_initial == NetSetupDomainName) { - gtk_entry_set_text(GTK_ENTRY(state->entry_domain), state->name_buffer_initial); - gtk_widget_set_sensitive(state->entry_workgroup, FALSE); - gtk_widget_set_sensitive(state->entry_domain, TRUE); - } - gtk_editable_set_editable(GTK_EDITABLE(state->entry_domain), TRUE); - gtk_box_pack_start(GTK_BOX(vbox), state->entry_domain, TRUE, TRUE, 0); - gtk_widget_show(state->entry_domain); - } - gtk_widget_show(button_domain); - - /* WORKGROUP */ - group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button_domain)); - button_workgroup = gtk_radio_button_new_with_label(group, "Workgroup"); - if (state->name_type_initial == NetSetupWorkgroupName) { - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_workgroup), TRUE); - } - gtk_box_pack_start(GTK_BOX(vbox), button_workgroup, TRUE, TRUE, 0); - g_signal_connect(G_OBJECT(button_workgroup), "clicked", - G_CALLBACK(callback_do_join_workgroup), - (gpointer)state); - { - gtk_entry_set_max_length(GTK_ENTRY(state->entry_workgroup), MAX_NETBIOS_NAME_LEN); - g_signal_connect(G_OBJECT(state->entry_workgroup), "changed", - G_CALLBACK(callback_enter_workgroup_and_unlock), - (gpointer)state); - g_signal_connect(G_OBJECT(state->entry_workgroup), "activate", - G_CALLBACK(callback_continue), - (gpointer)state); - - if (state->name_type_initial == NetSetupWorkgroupName) { - gtk_entry_set_text(GTK_ENTRY(state->entry_workgroup), state->name_buffer_initial); - gtk_widget_set_sensitive(GTK_WIDGET(state->entry_domain), FALSE); - gtk_widget_set_sensitive(GTK_WIDGET(state->entry_workgroup), TRUE); - } - gtk_box_pack_start(GTK_BOX(vbox), state->entry_workgroup, TRUE, TRUE, 0); - gtk_widget_show(state->entry_workgroup); - } - gtk_widget_show(button_workgroup); - - /* BUTTONS */ - bbox = gtk_hbutton_box_new(); - gtk_container_set_border_width(GTK_CONTAINER(bbox), 5); - gtk_container_add(GTK_CONTAINER(box1), bbox); - gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); - gtk_box_set_spacing(GTK_BOX(bbox), 10); - - state->window_do_change = window; - gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); /* !!! */ - gtk_container_add(GTK_CONTAINER(bbox), state->button_ok); - g_signal_connect(G_OBJECT(state->button_ok), "clicked", - G_CALLBACK(callback_creds_prompt), - (gpointer)state); - - button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); - gtk_container_add(GTK_CONTAINER(bbox), button); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(callback_do_close), - (gpointer)window); - - gtk_widget_show_all(window); - -} - -static void callback_do_about(GtkWidget *widget, - gpointer data) -{ - GdkPixbuf *logo; - GError *error = NULL; - - debug("callback_do_about called\n"); - - logo = gdk_pixbuf_new_from_file(SAMBA_IMAGE_PATH, - &error); - if (logo == NULL) { - g_print("failed to load logo from %s: %s\n", - SAMBA_IMAGE_PATH, error->message); - } - - gtk_show_about_dialog(data, - "name", "Samba", - "version", "3.2.0pre2-GIT-904a90-test", - "copyright", "Copyright Andrew Tridgell and the Samba Team 1992-2007", - "website", "http://www.samba.org", - "license", "GPLv3", - "logo", logo, - "comments", "Samba gtk domain join utility", - NULL); -} - -static int draw_main_window(struct join_state *state) -{ - GtkWidget *window; - GtkWidget *button; - GtkWidget *label; - GtkWidget *main_vbox; - GtkWidget *vbox; - GtkWidget *hbox; - GtkWidget *bbox; - GtkWidget *image; - GtkWidget *table; - GtkWidget *entry; - GdkPixbuf *icon; - GError *error = NULL; - - icon = gdk_pixbuf_new_from_file(SAMBA_ICON_PATH, - &error); - if (icon == NULL) { - g_print("failed to load logo from %s : %s\n", - SAMBA_ICON_PATH, error->message); - } - -#if 1 - image = gtk_image_new_from_file(SAMBA_IMAGE_PATH); -#else - image = gtk_image_new_from_file("/usr/share/pixmaps/redhat-system_settings.png"); -#endif - - window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - state->window_main = window; - - gtk_window_set_title(GTK_WINDOW(window), "Samba - Join Domain dialogue"); - gtk_widget_set_size_request(GTK_WIDGET(window), 600, 600); /* breite * höhe */ - gtk_window_set_resizable(GTK_WINDOW(window), FALSE); - gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL); - - g_signal_connect(G_OBJECT(window), "delete_event", - G_CALLBACK(callback_delete_event), NULL); - - gtk_container_set_border_width(GTK_CONTAINER(window), 10); - - main_vbox = gtk_vbox_new(FALSE, 10); - gtk_container_add(GTK_CONTAINER(window), main_vbox); - -#if 0 - gtk_box_pack_start(GTK_BOX(main_vbox), image, TRUE, TRUE, 10); - gtk_widget_show(image); -#endif - /* Hbox */ - hbox = gtk_hbox_new(FALSE, 10); - gtk_container_add(GTK_CONTAINER(main_vbox), hbox); - - { -/* gtk_box_pack_start(GTK_BOX(main_vbox), image, TRUE, TRUE, 10); */ - gtk_misc_set_alignment(GTK_MISC(image), 0, 0); - gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 10); - gtk_widget_show(image); - - /* Label */ - label = gtk_label_new("Samba uses the following information to identify your computer on the network."); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_widget_set_size_request(GTK_WIDGET(label), 500, 40); - gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); - gtk_widget_show(label); - } - - gtk_widget_show(hbox); - - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 10); - gtk_container_add(GTK_CONTAINER(main_vbox), vbox); - - /* Table */ - table = gtk_table_new(6, 3, TRUE); - gtk_table_set_row_spacings(GTK_TABLE(table), 5); - gtk_table_set_col_spacings(GTK_TABLE(table), 5); - gtk_container_add(GTK_CONTAINER(vbox), table); - - { - /* Label */ - label = gtk_label_new("Computer description:"); -/* gtk_misc_set_alignment(GTK_MISC(label), 0, 0); */ - gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1); - gtk_widget_show(label); - - state->button_apply = gtk_button_new_from_stock(GTK_STOCK_APPLY); - - /* Entry */ - entry = gtk_entry_new(); - gtk_entry_set_max_length(GTK_ENTRY(entry), 256); - g_signal_connect(G_OBJECT(entry), "changed", - G_CALLBACK(callback_enter_computer_description_and_unlock), - state); - g_signal_connect(G_OBJECT(entry), "activate", - G_CALLBACK(callback_apply_continue), - (gpointer)state); - - gtk_entry_set_text(GTK_ENTRY(entry), (char *)state->comment); - gtk_editable_set_editable(GTK_EDITABLE(entry), TRUE); /* ! */ - gtk_table_attach_defaults(GTK_TABLE(table), entry, 1, 3, 0, 1); - gtk_widget_show(entry); - } - - /* Label */ - label = gtk_label_new("For example: \"Samba \%v\"."); - gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 3, 1, 2); - gtk_widget_show(label); - - /* Label */ - label = gtk_label_new("Full computer name:"); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3); - gtk_widget_show(label); - - { - /* Label */ - char *str = NULL; - if (state->name_type_initial == NetSetupDomainName) { - asprintf(&str, "%s.%s", state->my_hostname, - state->my_dnsdomain); - } else { - asprintf(&str, "%s.", state->my_hostname); - } - - label = gtk_label_new(str); - SAFE_FREE(str); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 3, 2, 3); - gtk_widget_show(label); - } - - /* Label */ - if (state->name_type_initial == NetSetupDomainName) { - label = gtk_label_new("Domain:"); - } else { - label = gtk_label_new("Workgroup:"); - } - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 3, 4); - gtk_widget_show(label); - state->label_current_name_type = label; - - /* Label */ - label = gtk_label_new(state->name_buffer_initial); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 3, 3, 4); - gtk_widget_show(label); - state->label_current_name_buffer = label; - - { - hbox = gtk_hbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(vbox), hbox); - label = gtk_label_new("To rename this computer or join a domain, click Change."); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); - - - } - - /* bbox */ - bbox = gtk_hbutton_box_new(); - gtk_container_set_border_width(GTK_CONTAINER(bbox), 5); - gtk_container_add(GTK_CONTAINER(hbox), bbox); - gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); - gtk_box_set_spacing(GTK_BOX(bbox), 10); - - button = gtk_button_new_with_mnemonic("Ch_ange"); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(callback_do_change), - (gpointer)state); - gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0); - gtk_widget_show(button); - - /* Label (hidden) */ - state->label_reboot = gtk_label_new(NULL); - gtk_label_set_line_wrap(GTK_LABEL(state->label_reboot), TRUE); - gtk_misc_set_alignment(GTK_MISC(state->label_reboot), 0, 0); - gtk_box_pack_start(GTK_BOX(vbox), state->label_reboot, TRUE, TRUE, 0); - gtk_widget_show(state->label_reboot); - -#if 0 - gtk_box_pack_start(GTK_BOX(vbox), - create_bbox(window, TRUE, NULL, 10, 85, 20, GTK_BUTTONBOX_END), - TRUE, TRUE, 5); -#endif - { - - GtkWidget *frame; - GtkWidget *bbox2; - GtkWidget *button2; - - frame = gtk_frame_new(NULL); - bbox2 = gtk_hbutton_box_new(); - - gtk_container_set_border_width(GTK_CONTAINER(bbox2), 5); - gtk_container_add(GTK_CONTAINER(frame), bbox2); - - /* Set the appearance of the Button Box */ - gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox2), GTK_BUTTONBOX_END); - gtk_box_set_spacing(GTK_BOX(bbox2), 10); - /*gtk_button_box_set_child_size(GTK_BUTTON_BOX(bbox2), child_w, child_h);*/ - - button2 = gtk_button_new_from_stock(GTK_STOCK_OK); - gtk_container_add(GTK_CONTAINER(bbox2), button2); - g_signal_connect(G_OBJECT(button2), "clicked", G_CALLBACK(callback_do_exit), state); - - button2 = gtk_button_new_from_stock(GTK_STOCK_CANCEL); - gtk_container_add(GTK_CONTAINER(bbox2), button2); - g_signal_connect(G_OBJECT(button2), "clicked", - G_CALLBACK(callback_delete_event), - window); - - gtk_container_add(GTK_CONTAINER(bbox2), state->button_apply); - g_signal_connect(G_OBJECT(state->button_apply), "clicked", - G_CALLBACK(callback_apply_description_change), - state); - gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), FALSE); - - button2 = gtk_button_new_from_stock(GTK_STOCK_ABOUT); - gtk_container_add(GTK_CONTAINER(bbox2), button2); - g_signal_connect(G_OBJECT(button2), "clicked", - G_CALLBACK(callback_do_about), - window); - - gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 5); - } - - gtk_widget_show_all(window); - - return 0; -} - -static int init_join_state(struct join_state **state) -{ - struct join_state *s; - - s = malloc(sizeof(struct join_state)); - if (!s) { - return -1; - } - - memset(s, '\0', sizeof(struct join_state)); - - *state = s; - - return 0; -} - -static int initialize_join_state(struct join_state *state, - const char *debug_level) -{ - struct libnetapi_ctx *ctx = NULL; - NET_API_STATUS status = 0; - - status = libnetapi_init(&ctx); - if (status) { - return status; - } - - if (debug_level) { - libnetapi_set_debuglevel(ctx, debug_level); - } - - { - char my_hostname[HOST_NAME_MAX]; - const char *p = NULL; - if (gethostname(my_hostname, sizeof(my_hostname)) == -1) { - return -1; - } - - state->my_fqdn = strdup(my_hostname); - if (!state->my_fqdn) { - return -1; - } - - p = strchr(my_hostname, '.'); - if (p) { - my_hostname[strlen(my_hostname) - strlen(p)] = '\0'; - state->my_hostname = strdup(my_hostname); - if (!state->my_hostname) { - return -1; - } - p++; - state->my_dnsdomain = strdup(p); - if (!state->my_dnsdomain) { - return -1; - } - } - } - - { - const char *buffer = NULL; - uint16_t type = 0; - status = NetGetJoinInformation(NULL, &buffer, &type); - if (status) { - return status; - } - state->name_buffer_initial = (char *)buffer; - state->name_type_initial = type; - } - - { - struct srvsvc_NetSrvInfo1005 *info1005 = NULL; - uint8_t *buffer = NULL; - - status = NetServerGetInfo(NULL, 1005, &buffer); - if (status) { - return status; - } - - info1005 = (struct srvsvc_NetSrvInfo1005 *)buffer; - - state->comment = strdup(info1005->comment); - if (!state->comment) { - return -1; - } - } -#if 0 - { - struct srvsvc_NetSrvInfo100 *info100 = NULL; - uint8_t *buffer = NULL; - - status = NetServerGetInfo(NULL, 100, &buffer); - if (status) { - return status; - } - - info100 = (struct srvsvc_NetSrvInfo100 *)buffer; - - state->comment = strdup(info100->comment); - if (!state->comment) { - return -1; - } - } -#endif - - state->ctx = ctx; - - return 0; -} - -int main(int argc, char **argv) -{ - GOptionContext *context = NULL; - static const char *debug_level = NULL; - struct join_state *state = NULL; - GError *error = NULL; - int ret = 0; - - static GOptionEntry entries[] = { - { "debug", 'd', 0, G_OPTION_ARG_STRING, &debug_level, "Debug level (for samba)", "N" }, - { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Verbose output", 0 }, - { NULL } - }; - - context = g_option_context_new("- Samba domain join utility"); - g_option_context_add_main_entries(context, entries, NULL); -/* g_option_context_add_main_entries(context, entries, GETTEXT_PACKAGE); */ - g_option_context_add_group(context, gtk_get_option_group(TRUE)); - g_option_context_parse(context, &argc, &argv, &error); - - gtk_init(&argc, &argv); - g_set_application_name("Samba"); - - ret = init_join_state(&state); - if (ret) { - return ret; - } - - ret = initialize_join_state(state, debug_level); - if (ret) { - return ret; - } - - draw_main_window(state); - - gtk_main(); - - do_cleanup(state); - - return 0; -} diff --git a/source3/lib/netapi/examples/netdomjoin-gui/logo.png b/source3/lib/netapi/examples/netdomjoin-gui/logo.png new file mode 100644 index 0000000000..6df4ace659 Binary files /dev/null and b/source3/lib/netapi/examples/netdomjoin-gui/logo.png differ diff --git a/source3/lib/netapi/examples/netdomjoin-gui/samba.ico b/source3/lib/netapi/examples/netdomjoin-gui/samba.ico new file mode 100755 index 0000000000..b70c9590de Binary files /dev/null and b/source3/lib/netapi/examples/netdomjoin-gui/samba.ico differ diff --git a/source3/lib/netapi/examples/netdomjoin.c b/source3/lib/netapi/examples/netdomjoin.c deleted file mode 100644 index a2bb700250..0000000000 --- a/source3/lib/netapi/examples/netdomjoin.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * Join Support (cmdline + netapi) - * Copyright (C) Guenther Deschner 2007 - * - * 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 3 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, see . - */ - -#include -#include -#include -#include -#include - -#include - -char *get_string_param(const char *param) -{ - char *p; - - p = strchr(param, '='); - if (!p) { - return NULL; - } - - return (p+1); -} - -int main(int argc, char **argv) -{ - NET_API_STATUS status; - const char *server_name = NULL; - const char *domain_name = NULL; - const char *account_ou = NULL; - const char *Account = NULL; - const char *password = NULL; - uint32_t join_flags = 3; - struct libnetapi_ctx *ctx = NULL; - int i; - - status = libnetapi_init(&ctx); - if (status != 0) { - return status; - } - - if (argc < 2) { - printf("usage: netdomjoin\n"); - printf("\t[hostname=HOSTNAME] [domain=DOMAIN] \n"); - return 0; - } - - if (argc > 2) { - server_name = argv[1]; - } - - for (i=0; i. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#define MAX_CRED_LEN 256 +#define MAX_NETBIOS_NAME_LEN 15 + +#define SAMBA_ICON_PATH "/usr/share/pixmaps/samba/samba.ico" +#define SAMBA_IMAGE_PATH "/usr/share/pixmaps/samba/logo.png" + +#define WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED ( 0x00000020 ) +#define WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE ( 0x00000004 ) +#define WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE ( 0x00000002 ) +#define WKSSVC_JOIN_FLAGS_JOIN_TYPE ( 0x00000001 ) + +#define NetSetupWorkgroupName ( 2 ) +#define NetSetupDomainName ( 3 ) + +#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0) + +struct srvsvc_NetSrvInfo1005 { + const char *comment;/* [unique,charset(UTF16)] */ +}; + +static gboolean verbose = FALSE; + +typedef struct join_state { + struct libnetapi_ctx *ctx; + GtkWidget *window_main; + GtkWidget *window_parent; + GtkWidget *window_do_change; + GtkWidget *window_creds_prompt; + GtkWidget *entry_account; + GtkWidget *entry_password; + GtkWidget *entry_domain; + GtkWidget *entry_workgroup; + GtkWidget *button_ok; + GtkWidget *button_apply; + GtkWidget *button_ok_creds; + GtkWidget *label_reboot; + GtkWidget *label_current_name_buffer; + GtkWidget *label_current_name_type; + GtkWidget *label_full_computer_name; + uint16_t name_type_initial; + uint16_t name_type_new; + char *name_buffer_initial; + char *name_buffer_new; + char *password; + char *account; + char *comment; + char *comment_new; + char *my_fqdn; + char *my_dnsdomain; + char *my_hostname; + uint16_t server_role; + gboolean settings_changed; + gboolean hostname_changed; +} join_state; + +static void debug(const char *format, ...) +{ + va_list args; + + if (!verbose) { + return; + } + + va_start(args, format); + g_vprintf(format, args); + va_end(args); +} + +static gboolean callback_delete_event(GtkWidget *widget, + GdkEvent *event, + gpointer data) +{ + gtk_main_quit(); + return FALSE; +} + +static void callback_do_close(GtkWidget *widget, + gpointer data) +{ + debug("Closing now...\n"); + gtk_widget_destroy(data); +} + +static void free_join_state(struct join_state *s) +{ + SAFE_FREE(s->name_buffer_initial); + SAFE_FREE(s->name_buffer_new); + SAFE_FREE(s->password); + SAFE_FREE(s->account); + SAFE_FREE(s->comment); + SAFE_FREE(s->comment_new); + SAFE_FREE(s->my_fqdn); + SAFE_FREE(s->my_dnsdomain); + SAFE_FREE(s->my_hostname); + +} + +static void do_cleanup(struct join_state *state) +{ + libnetapi_free(state->ctx); + free_join_state(state); +} + +static void callback_apply_description_change(GtkWidget *widget, + gpointer data) +{ + struct join_state *state = (struct join_state *)data; + NET_API_STATUS status = 0; + uint32_t parm_err = 0; + struct srvsvc_NetSrvInfo1005 info1005; + GtkWidget *dialog; + + info1005.comment = state->comment_new; + + status = NetServerSetInfo(NULL, 1005, (uint8_t *)&info1005, &parm_err); + if (status) { + debug("NetServerSetInfo failed with: %s\n", + libnetapi_errstr(state->ctx, status)); + dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + "Failed to change computer description: %s.", + libnetapi_errstr(state->ctx, status)); + g_signal_connect_swapped(dialog, "response", + G_CALLBACK(gtk_widget_destroy), + dialog); + + gtk_widget_show(dialog); + return; + } + + gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), FALSE); +} + +static void callback_do_exit(GtkWidget *widget, + gpointer data) +{ + GtkWidget *dialog; + gint result; + struct join_state *state = (struct join_state *)data; + + if (!state->settings_changed) { + callback_delete_event(NULL, NULL, NULL); + return; + } + + dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_YES_NO, + "You must restart your computer before the new settings will take effect."); + result = gtk_dialog_run(GTK_DIALOG(dialog)); + switch (result) { + case GTK_RESPONSE_YES: + g_print("would reboot here\n"); + break; + case GTK_RESPONSE_NO: + default: + break; + } + gtk_widget_destroy(dialog); + gtk_widget_destroy(state->window_main); + do_cleanup(state); + exit(0); +} + + +static void callback_do_reboot(GtkWidget *widget, + gpointer data, + gpointer data2) +{ + GtkWidget *dialog; + struct join_state *state = (struct join_state *)data2; + + debug("callback_do_reboot\n"); + + state->settings_changed = TRUE; + dialog = gtk_message_dialog_new(GTK_WINDOW(data), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_OK, + "You must restart this computer for the changes to take effect."); +#if 0 + g_signal_connect_swapped(dialog, "response", + G_CALLBACK(gtk_widget_destroy), + dialog); + + debug("showing dialog\n"); + gtk_widget_show(dialog); +#else + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); +#endif + + gtk_label_set_text(GTK_LABEL(state->label_reboot), "Changes will take effect after you restart this computer"); + + debug("destroying do_change window\n"); + gtk_widget_destroy(GTK_WIDGET(state->window_do_change)); + + { + uint32_t status; + const char *buffer; + uint16_t type; + + status = NetGetJoinInformation(NULL, &buffer, &type); + if (status != 0) { + g_print("failed to query status\n"); + return; + } + + debug("got new status: %s\n", buffer); +#if 0 + SAFE_FREE(state->name_buffer_new); + state->name_buffer_new = strdup(buffer); + SAFE_FREE(buffer); + state->name_type_new = type; +#endif + gtk_label_set_text(GTK_LABEL(state->label_current_name_buffer), state->name_buffer_new); + if (state->name_type_new == 3) { + gtk_label_set_text(GTK_LABEL(state->label_current_name_type), "Domain:"); + } else { + gtk_label_set_text(GTK_LABEL(state->label_current_name_type), "Workgroup:"); + } + } +} + +static void callback_return_username(GtkWidget *widget, + gpointer data) +{ + const gchar *entry_text; + struct join_state *state = (struct join_state *)data; + if (!widget) { + return; + } + entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); + debug("callback_return_username: %s\n", entry_text); + SAFE_FREE(state->account); + state->account = strdup(entry_text); +} + +static void callback_return_username_and_enter(GtkWidget *widget, + gpointer data) +{ + const gchar *entry_text; + struct join_state *state = (struct join_state *)data; + if (!widget) { + return; + } + entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); + debug("callback_return_username: %s\n", entry_text); + SAFE_FREE(state->account); + state->account = strdup(entry_text); + g_signal_emit_by_name(state->button_ok_creds, "clicked"); +} + +static void callback_return_password(GtkWidget *widget, + gpointer data) +{ + const gchar *entry_text; + struct join_state *state = (struct join_state *)data; + if (!widget) { + return; + } + entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); +#ifdef DEBUG_PASSWORD + debug("callback_return_password: %s\n", entry_text); +#else + debug("callback_return_password: (not printed)\n"); +#endif + SAFE_FREE(state->password); + state->password = strdup(entry_text); +} + +static void callback_return_password_and_enter(GtkWidget *widget, + gpointer data) +{ + const gchar *entry_text; + struct join_state *state = (struct join_state *)data; + if (!widget) { + return; + } + entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); +#ifdef DEBUG_PASSWORD + debug("callback_return_password: %s\n", entry_text); +#else + debug("callback_return_password: (not printed)\n"); +#endif + SAFE_FREE(state->password); + state->password = strdup(entry_text); + g_signal_emit_by_name(state->button_ok_creds, "clicked"); +} + +static void callback_do_hostname_change(GtkWidget *widget, + gpointer data) +{ + GtkWidget *dialog; + const char *str = NULL; + + struct join_state *state = (struct join_state *)data; + + switch (state->name_type_initial) { + case NetSetupDomainName: + str = "To be implemented: call NetRenameMachineInDomain\n"; + break; + case NetSetupWorkgroupName: + str = "To be implemented: call SetComputerNameEx\n"; + break; + default: + break; + } + + dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + str); + + g_signal_connect_swapped(dialog, "response", + G_CALLBACK(gtk_widget_destroy), + dialog); + gtk_widget_show(dialog); +} + +static void callback_do_join(GtkWidget *widget, + gpointer data) +{ + GtkWidget *dialog; + + NET_API_STATUS status; + const char *err_str = NULL; + uint32_t join_flags = 0; + uint32_t unjoin_flags = 0; + gboolean domain_join = FALSE; + gboolean try_unjoin = FALSE; + const char *domain_or_workgroup = NULL; + + struct join_state *state = (struct join_state *)data; + + callback_return_username(state->entry_account, state); + callback_return_password(state->entry_password, state); + + if (state->window_creds_prompt) { + gtk_widget_destroy(GTK_WIDGET(state->window_creds_prompt)); + } + + if (state->name_type_new == NetSetupDomainName) { + domain_join = TRUE; + join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE | + WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE | + WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED; /* for testing */ + domain_or_workgroup = "domain"; + } else { + domain_or_workgroup = "workgroup"; + } + + if ((state->name_type_initial == NetSetupDomainName) && + (state->name_type_new == NetSetupWorkgroupName)) { + try_unjoin = TRUE; + unjoin_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE | + WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE; + } + + debug("callback_do_join: Joining a %s named %s using join_flags 0x%08x ", + domain_or_workgroup, + state->name_buffer_new, + join_flags); + if (domain_join) { + debug("as %s ", state->account); +#ifdef DEBUG_PASSWORD + debug("with %s ", state->password); +#endif + } + debug("\n"); + if (try_unjoin) { + + debug("callback_do_join: Unjoining\n"); + + status = NetUnjoinDomain(NULL, + state->account, + state->password, + unjoin_flags); + if (status != 0) { + err_str = libnetapi_errstr(state->ctx, status); + g_print("callback_do_join: failed to unjoin (%s)\n", + err_str); + + dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "The following error occured attempting to unjoin the %s: \"%s\": %s", + domain_or_workgroup, + state->name_buffer_new, + err_str); + + g_signal_connect_swapped(dialog, "response", + G_CALLBACK(gtk_widget_destroy), + dialog); + + gtk_widget_show(dialog); + + return; + } + + } + status = NetJoinDomain(NULL, + state->name_buffer_new, + NULL, + state->account, + state->password, + join_flags); + if (status != 0) { + err_str = libnetapi_errstr(state->ctx, status); + g_print("callback_do_join: failed to join (%s)\n", err_str); + + dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "The following error occured attempting to join the %s: \"%s\": %s", + domain_or_workgroup, + state->name_buffer_new, + err_str); + + g_signal_connect_swapped(dialog, "response", + G_CALLBACK(gtk_widget_destroy), + dialog); + + gtk_widget_show(dialog); + + return; + } + + debug("callback_do_join: Successfully joined %s\n", + domain_or_workgroup); + + dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_OK, + "Welcome to the %s %s.", + state->name_buffer_new, + domain_or_workgroup); + + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + + callback_do_reboot(NULL, state->window_parent, state); +} + +static void callback_creds_prompt(GtkWidget *widget, + gpointer data) +{ + GtkWidget *window; + GtkWidget *box1; + GtkWidget *bbox; + GtkWidget *button; + GtkWidget *label; + + struct join_state *state = (struct join_state *)data; + + debug("callback_creds_prompt:\n"); + + state->window_parent = state->window_do_change; + + if (state->hostname_changed) { + return callback_do_hostname_change(NULL, state); + } + + if ((state->name_type_initial != NetSetupDomainName) && + (state->name_type_new != NetSetupDomainName)) { + return callback_do_join(NULL, state); + } + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + + gtk_window_set_title(GTK_WINDOW(window), "Computer Name Changes"); + gtk_window_set_resizable(GTK_WINDOW(window), FALSE); + gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); + gtk_widget_set_size_request(GTK_WIDGET(window), 380, 280); + gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL); +/* gtk_window_set_icon_name(GTK_WIDGET(window), GTK_STOCK_DIALOG_AUTHENTICATION); */ + state->window_creds_prompt = window; + + g_signal_connect(G_OBJECT(window), "delete_event", + G_CALLBACK(callback_do_close), window); + + gtk_container_set_border_width(GTK_CONTAINER(window), 10); + + box1 = gtk_vbox_new(FALSE, 0); + + gtk_container_add(GTK_CONTAINER(window), box1); + + if ((state->name_type_initial == NetSetupDomainName) && + (state->name_type_new == NetSetupWorkgroupName)) { + label = gtk_label_new("Enter the name and password of an account with permission to leave the domain.\n"); + } else { + label = gtk_label_new("Enter the name and password of an account with permission to join the domain.\n"); + } + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + + gtk_box_pack_start(GTK_BOX(box1), label, FALSE, FALSE, 0); + + gtk_widget_show(label); + + /* USER NAME */ + label = gtk_label_new("User name:"); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_box_pack_start(GTK_BOX(box1), label, FALSE, FALSE, 0); + gtk_widget_show(label); + + state->entry_account = gtk_entry_new(); + gtk_entry_set_max_length(GTK_ENTRY(state->entry_account), MAX_CRED_LEN); + g_signal_connect(G_OBJECT(state->entry_account), "activate", + G_CALLBACK(callback_return_username_and_enter), + (gpointer)state); + gtk_editable_select_region(GTK_EDITABLE(state->entry_account), + 0, GTK_ENTRY(state->entry_account)->text_length); + gtk_box_pack_start(GTK_BOX(box1), state->entry_account, TRUE, TRUE, 0); + gtk_widget_show(state->entry_account); + + /* PASSWORD */ + label = gtk_label_new("Password:"); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_box_pack_start(GTK_BOX(box1), label, FALSE, FALSE, 0); + gtk_widget_show(label); + + state->entry_password = gtk_entry_new(); + gtk_entry_set_max_length(GTK_ENTRY(state->entry_password), MAX_CRED_LEN); + gtk_entry_set_visibility(GTK_ENTRY(state->entry_password), FALSE); + g_signal_connect(G_OBJECT(state->entry_password), "activate", + G_CALLBACK(callback_return_password_and_enter), + (gpointer)state); + gtk_editable_set_editable(GTK_EDITABLE(state->entry_password), TRUE); + gtk_editable_select_region(GTK_EDITABLE(state->entry_password), + 0, GTK_ENTRY(state->entry_password)->text_length); + gtk_box_pack_start(GTK_BOX(box1), state->entry_password, TRUE, TRUE, 0); + gtk_widget_show(state->entry_password); + + bbox = gtk_hbutton_box_new(); + gtk_container_set_border_width(GTK_CONTAINER(bbox), 5); + gtk_container_add(GTK_CONTAINER(box1), bbox); + gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); + gtk_box_set_spacing(GTK_BOX(bbox), 10); + + state->button_ok_creds = gtk_button_new_from_stock(GTK_STOCK_OK); + gtk_widget_grab_focus(GTK_WIDGET(state->button_ok_creds)); + gtk_container_add(GTK_CONTAINER(bbox), state->button_ok_creds); + g_signal_connect(G_OBJECT(state->button_ok_creds), "clicked", + G_CALLBACK(callback_do_join), + (gpointer)state); + gtk_widget_show(state->button_ok_creds); + + button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); + gtk_container_add(GTK_CONTAINER(bbox), button); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(callback_do_close), (gpointer) window); + gtk_widget_show_all(window); +} + +static void callback_enter_hostname_and_unlock(GtkWidget *widget, + gpointer data) +{ + const gchar *entry_text = NULL; + char *str = NULL; + struct join_state *state = (struct join_state *)data; + + entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); + debug("callback_enter_hostname_and_unlock: %s\n", entry_text); + if (!entry_text || entry_text[0] == 0) { + state->hostname_changed = FALSE; + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); + return; + } + if (strcasecmp(state->my_hostname, entry_text) == 0) { + state->hostname_changed = FALSE; + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); + return; + } + state->hostname_changed = TRUE; + if (state->name_type_initial == NetSetupDomainName) { + asprintf(&str, "%s.%s", entry_text, state->my_dnsdomain); + } else { + asprintf(&str, "%s.", entry_text); + } + gtk_label_set_text(GTK_LABEL(state->label_full_computer_name), str); + free(str); + + if (state->hostname_changed && str && str[0] != 0 && str[0] != '.') { + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), TRUE); + } +} + +static void callback_enter_computer_description_and_unlock(GtkWidget *widget, + gpointer data) +{ + const gchar *entry_text = NULL; + struct join_state *state = (struct join_state *)data; + int string_unchanged = 0; + + entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); + debug("callback_enter_computer_description_and_unlock: %s\n", + entry_text); +#if 0 + if (!entry_text || entry_text[0] == 0) { + string_unchanged = 1; + gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), + FALSE); + return; + } +#endif + if (entry_text && strcasecmp(state->comment, entry_text) == 0) { + string_unchanged = 1; + gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), + FALSE); + return; + } + + gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), TRUE); + SAFE_FREE(state->comment_new); + state->comment_new = strdup(entry_text); + +} + + +static void callback_enter_workgroup_and_unlock(GtkWidget *widget, + gpointer data) +{ + const gchar *entry_text = NULL; + struct join_state *state = (struct join_state *)data; + + entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); + debug("callback_enter_workgroup_and_unlock: %s\n", entry_text); + if (!entry_text || entry_text[0] == 0) { + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); + return; + } + if (strcasecmp(state->name_buffer_initial, entry_text) == 0) { + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); + return; + } + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), TRUE); + SAFE_FREE(state->name_buffer_new); + state->name_buffer_new = strdup(entry_text); + state->name_type_new = NetSetupWorkgroupName; +} + +static void callback_enter_domain_and_unlock(GtkWidget *widget, + gpointer data) +{ + const gchar *entry_text = NULL; + struct join_state *state = (struct join_state *)data; + + entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); + debug("callback_enter_domain_and_unlock: %s\n", entry_text); + if (!entry_text || entry_text[0] == 0) { + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); + return; + } + if (strcasecmp(state->name_buffer_initial, entry_text) == 0) { + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); + return; + } + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), TRUE); + SAFE_FREE(state->name_buffer_new); + state->name_buffer_new = strdup(entry_text); + state->name_type_new = NetSetupDomainName; +} + +static void callback_continue(GtkWidget *widget, + gpointer data) +{ + struct join_state *state = (struct join_state *)data; + + gtk_widget_grab_focus(GTK_WIDGET(state->button_ok)); + g_signal_emit_by_name(state->button_ok, "clicked"); +} + +static void callback_apply_continue(GtkWidget *widget, + gpointer data) +{ + struct join_state *state = (struct join_state *)data; + + gtk_widget_grab_focus(GTK_WIDGET(state->button_apply)); + g_signal_emit_by_name(state->button_apply, "clicked"); +} + +static void callback_do_join_workgroup(GtkWidget *widget, + gpointer data) +{ + struct join_state *state = (struct join_state *)data; + debug("callback_do_join_workgroup choosen\n"); + gtk_widget_set_sensitive(GTK_WIDGET(state->entry_workgroup), TRUE); + gtk_widget_grab_focus(GTK_WIDGET(state->entry_workgroup)); + gtk_widget_set_sensitive(GTK_WIDGET(state->entry_domain), FALSE); + callback_enter_workgroup_and_unlock(state->entry_workgroup, state); /* TEST */ +} + +static void callback_do_join_domain(GtkWidget *widget, + gpointer data) +{ + struct join_state *state = (struct join_state *)data; + debug("callback_do_join_domain choosen\n"); + gtk_widget_set_sensitive(GTK_WIDGET(state->entry_domain), TRUE); + gtk_widget_grab_focus(GTK_WIDGET(state->entry_domain)); + gtk_widget_set_sensitive(GTK_WIDGET(state->entry_workgroup), FALSE); + callback_enter_domain_and_unlock(state->entry_domain, state); /* TEST */ +} + +static void callback_do_change(GtkWidget *widget, + gpointer data) +{ + GtkWidget *window; + GtkWidget *box1; + GtkWidget *bbox; + GtkWidget *button_workgroup; + GtkWidget *button_domain; + GtkWidget *button; + GtkWidget *label; + GtkWidget *frame_horz; + GtkWidget *vbox; + GtkWidget *entry; + GSList *group; + + struct join_state *state = (struct join_state *)data; + + debug("callback_do_change called\n"); + + if (state->server_role == 3) { + GtkWidget *dialog; + dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + "Domain controller cannot be moved from one domain to another, they must first be demoted. Renaming this domain controller may cause it to become temporarily unavailable to users and computers. For information on renaming domain controllers, including alternate renaming methods, see Help and Support. To continue renaming this domain controller, click OK."); + g_signal_connect_swapped(dialog, "response", + G_CALLBACK(gtk_widget_destroy), + dialog); + + gtk_widget_show(dialog); + return; + } + + state->button_ok = gtk_button_new_from_stock(GTK_STOCK_OK); + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + + gtk_window_set_title(GTK_WINDOW(window), "Computer Name Changes"); + gtk_window_set_resizable(GTK_WINDOW(window), FALSE); + gtk_widget_set_size_request(GTK_WIDGET(window), 480, 500); /* breite * höhe */ + gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL); + + g_signal_connect(G_OBJECT(window), "delete_event", + G_CALLBACK(callback_do_close), window); + + gtk_container_set_border_width(GTK_CONTAINER(window), 10); + + box1 = gtk_vbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(window), box1); + + label = gtk_label_new("You can change the name and membership of this computer. Changes may affect access to network ressources."); + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_box_pack_start(GTK_BOX(box1), label, TRUE, TRUE, 0); + gtk_widget_show(label); + + /* COMPUTER NAME */ + label = gtk_label_new("Computer name:"); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_box_pack_start(GTK_BOX(box1), label, TRUE, TRUE, 0); + gtk_widget_show(label); + + state->label_full_computer_name = gtk_label_new(NULL); + { + entry = gtk_entry_new(); + gtk_entry_set_max_length(GTK_ENTRY(entry), MAX_NETBIOS_NAME_LEN); + g_signal_connect(G_OBJECT(entry), "changed", + G_CALLBACK(callback_enter_hostname_and_unlock), + (gpointer)state); + gtk_entry_set_text(GTK_ENTRY(entry), state->my_hostname); + gtk_editable_select_region(GTK_EDITABLE(entry), + 0, GTK_ENTRY(entry)->text_length); + + gtk_editable_set_editable(GTK_EDITABLE(entry), TRUE); /* ! */ + gtk_box_pack_start(GTK_BOX(box1), entry, TRUE, TRUE, 0); + gtk_widget_show(entry); + } + + /* FULL COMPUTER NAME */ + label = gtk_label_new("Full computer name:"); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_box_pack_start(GTK_BOX(box1), label, TRUE, TRUE, 0); + gtk_widget_show(label); + + { + const gchar *entry_text; + char *str = NULL; + entry_text = gtk_entry_get_text(GTK_ENTRY(entry)); + if (state->name_type_initial == NetSetupDomainName) { + asprintf(&str, "%s.%s", entry_text, state->my_dnsdomain); + } else { + asprintf(&str, "%s.", entry_text); + } + gtk_label_set_text(GTK_LABEL(state->label_full_computer_name), str); + free(str); + gtk_misc_set_alignment(GTK_MISC(state->label_full_computer_name), 0, 0); + gtk_box_pack_start(GTK_BOX(box1), state->label_full_computer_name, TRUE, TRUE, 0); + gtk_widget_show(state->label_full_computer_name); + } + + /* BOX */ + frame_horz = gtk_frame_new ("Member Of"); + gtk_box_pack_start(GTK_BOX(box1), frame_horz, TRUE, TRUE, 10); + + vbox = gtk_vbox_new(FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(vbox), 10); + gtk_container_add(GTK_CONTAINER(frame_horz), vbox); + + /* TWO ENTRIES */ + state->entry_workgroup = gtk_entry_new(); + state->entry_domain = gtk_entry_new(); + + /* DOMAIN */ + button_domain = gtk_radio_button_new_with_label(NULL, "Domain"); + if (state->name_type_initial == NetSetupDomainName) { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_domain), TRUE); + } + gtk_box_pack_start(GTK_BOX(vbox), button_domain, TRUE, TRUE, 0); + g_signal_connect(G_OBJECT(button_domain), "clicked", + G_CALLBACK(callback_do_join_domain), + (gpointer)state); + + { + gtk_entry_set_max_length(GTK_ENTRY(state->entry_domain), 50); + g_signal_connect(G_OBJECT(state->entry_domain), "changed", + G_CALLBACK(callback_enter_domain_and_unlock), + (gpointer)state); + g_signal_connect(G_OBJECT(state->entry_domain), "activate", + G_CALLBACK(callback_continue), + (gpointer)state); + if (state->name_type_initial == NetSetupDomainName) { + gtk_entry_set_text(GTK_ENTRY(state->entry_domain), state->name_buffer_initial); + gtk_widget_set_sensitive(state->entry_workgroup, FALSE); + gtk_widget_set_sensitive(state->entry_domain, TRUE); + } + gtk_editable_set_editable(GTK_EDITABLE(state->entry_domain), TRUE); + gtk_box_pack_start(GTK_BOX(vbox), state->entry_domain, TRUE, TRUE, 0); + gtk_widget_show(state->entry_domain); + } + gtk_widget_show(button_domain); + + /* WORKGROUP */ + group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button_domain)); + button_workgroup = gtk_radio_button_new_with_label(group, "Workgroup"); + if (state->name_type_initial == NetSetupWorkgroupName) { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_workgroup), TRUE); + } + gtk_box_pack_start(GTK_BOX(vbox), button_workgroup, TRUE, TRUE, 0); + g_signal_connect(G_OBJECT(button_workgroup), "clicked", + G_CALLBACK(callback_do_join_workgroup), + (gpointer)state); + { + gtk_entry_set_max_length(GTK_ENTRY(state->entry_workgroup), MAX_NETBIOS_NAME_LEN); + g_signal_connect(G_OBJECT(state->entry_workgroup), "changed", + G_CALLBACK(callback_enter_workgroup_and_unlock), + (gpointer)state); + g_signal_connect(G_OBJECT(state->entry_workgroup), "activate", + G_CALLBACK(callback_continue), + (gpointer)state); + + if (state->name_type_initial == NetSetupWorkgroupName) { + gtk_entry_set_text(GTK_ENTRY(state->entry_workgroup), state->name_buffer_initial); + gtk_widget_set_sensitive(GTK_WIDGET(state->entry_domain), FALSE); + gtk_widget_set_sensitive(GTK_WIDGET(state->entry_workgroup), TRUE); + } + gtk_box_pack_start(GTK_BOX(vbox), state->entry_workgroup, TRUE, TRUE, 0); + gtk_widget_show(state->entry_workgroup); + } + gtk_widget_show(button_workgroup); + + /* BUTTONS */ + bbox = gtk_hbutton_box_new(); + gtk_container_set_border_width(GTK_CONTAINER(bbox), 5); + gtk_container_add(GTK_CONTAINER(box1), bbox); + gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); + gtk_box_set_spacing(GTK_BOX(bbox), 10); + + state->window_do_change = window; + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); /* !!! */ + gtk_container_add(GTK_CONTAINER(bbox), state->button_ok); + g_signal_connect(G_OBJECT(state->button_ok), "clicked", + G_CALLBACK(callback_creds_prompt), + (gpointer)state); + + button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); + gtk_container_add(GTK_CONTAINER(bbox), button); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(callback_do_close), + (gpointer)window); + + gtk_widget_show_all(window); + +} + +static void callback_do_about(GtkWidget *widget, + gpointer data) +{ + GdkPixbuf *logo; + GError *error = NULL; + + debug("callback_do_about called\n"); + + logo = gdk_pixbuf_new_from_file(SAMBA_IMAGE_PATH, + &error); + if (logo == NULL) { + g_print("failed to load logo from %s: %s\n", + SAMBA_IMAGE_PATH, error->message); + } + + gtk_show_about_dialog(data, + "name", "Samba", + "version", "3.2.0pre2-GIT-904a90-test", + "copyright", "Copyright Andrew Tridgell and the Samba Team 1992-2007", + "website", "http://www.samba.org", + "license", "GPLv3", + "logo", logo, + "comments", "Samba gtk domain join utility", + NULL); +} + +static int draw_main_window(struct join_state *state) +{ + GtkWidget *window; + GtkWidget *button; + GtkWidget *label; + GtkWidget *main_vbox; + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *bbox; + GtkWidget *image; + GtkWidget *table; + GtkWidget *entry; + GdkPixbuf *icon; + GError *error = NULL; + + icon = gdk_pixbuf_new_from_file(SAMBA_ICON_PATH, + &error); + if (icon == NULL) { + g_print("failed to load logo from %s : %s\n", + SAMBA_ICON_PATH, error->message); + } + +#if 1 + image = gtk_image_new_from_file(SAMBA_IMAGE_PATH); +#else + image = gtk_image_new_from_file("/usr/share/pixmaps/redhat-system_settings.png"); +#endif + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + state->window_main = window; + + gtk_window_set_title(GTK_WINDOW(window), "Samba - Join Domain dialogue"); + gtk_widget_set_size_request(GTK_WIDGET(window), 600, 600); /* breite * höhe */ + gtk_window_set_resizable(GTK_WINDOW(window), FALSE); + gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL); + + g_signal_connect(G_OBJECT(window), "delete_event", + G_CALLBACK(callback_delete_event), NULL); + + gtk_container_set_border_width(GTK_CONTAINER(window), 10); + + main_vbox = gtk_vbox_new(FALSE, 10); + gtk_container_add(GTK_CONTAINER(window), main_vbox); + +#if 0 + gtk_box_pack_start(GTK_BOX(main_vbox), image, TRUE, TRUE, 10); + gtk_widget_show(image); +#endif + /* Hbox */ + hbox = gtk_hbox_new(FALSE, 10); + gtk_container_add(GTK_CONTAINER(main_vbox), hbox); + + { +/* gtk_box_pack_start(GTK_BOX(main_vbox), image, TRUE, TRUE, 10); */ + gtk_misc_set_alignment(GTK_MISC(image), 0, 0); + gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 10); + gtk_widget_show(image); + + /* Label */ + label = gtk_label_new("Samba uses the following information to identify your computer on the network."); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_widget_set_size_request(GTK_WIDGET(label), 500, 40); + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + gtk_widget_show(label); + } + + gtk_widget_show(hbox); + + vbox = gtk_vbox_new(FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(vbox), 10); + gtk_container_add(GTK_CONTAINER(main_vbox), vbox); + + /* Table */ + table = gtk_table_new(6, 3, TRUE); + gtk_table_set_row_spacings(GTK_TABLE(table), 5); + gtk_table_set_col_spacings(GTK_TABLE(table), 5); + gtk_container_add(GTK_CONTAINER(vbox), table); + + { + /* Label */ + label = gtk_label_new("Computer description:"); +/* gtk_misc_set_alignment(GTK_MISC(label), 0, 0); */ + gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1); + gtk_widget_show(label); + + state->button_apply = gtk_button_new_from_stock(GTK_STOCK_APPLY); + + /* Entry */ + entry = gtk_entry_new(); + gtk_entry_set_max_length(GTK_ENTRY(entry), 256); + g_signal_connect(G_OBJECT(entry), "changed", + G_CALLBACK(callback_enter_computer_description_and_unlock), + state); + g_signal_connect(G_OBJECT(entry), "activate", + G_CALLBACK(callback_apply_continue), + (gpointer)state); + + gtk_entry_set_text(GTK_ENTRY(entry), (char *)state->comment); + gtk_editable_set_editable(GTK_EDITABLE(entry), TRUE); /* ! */ + gtk_table_attach_defaults(GTK_TABLE(table), entry, 1, 3, 0, 1); + gtk_widget_show(entry); + } + + /* Label */ + label = gtk_label_new("For example: \"Samba \%v\"."); + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 3, 1, 2); + gtk_widget_show(label); + + /* Label */ + label = gtk_label_new("Full computer name:"); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3); + gtk_widget_show(label); + + { + /* Label */ + char *str = NULL; + if (state->name_type_initial == NetSetupDomainName) { + asprintf(&str, "%s.%s", state->my_hostname, + state->my_dnsdomain); + } else { + asprintf(&str, "%s.", state->my_hostname); + } + + label = gtk_label_new(str); + SAFE_FREE(str); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 3, 2, 3); + gtk_widget_show(label); + } + + /* Label */ + if (state->name_type_initial == NetSetupDomainName) { + label = gtk_label_new("Domain:"); + } else { + label = gtk_label_new("Workgroup:"); + } + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 3, 4); + gtk_widget_show(label); + state->label_current_name_type = label; + + /* Label */ + label = gtk_label_new(state->name_buffer_initial); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 3, 3, 4); + gtk_widget_show(label); + state->label_current_name_buffer = label; + + { + hbox = gtk_hbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(vbox), hbox); + label = gtk_label_new("To rename this computer or join a domain, click Change."); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + + } + + /* bbox */ + bbox = gtk_hbutton_box_new(); + gtk_container_set_border_width(GTK_CONTAINER(bbox), 5); + gtk_container_add(GTK_CONTAINER(hbox), bbox); + gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); + gtk_box_set_spacing(GTK_BOX(bbox), 10); + + button = gtk_button_new_with_mnemonic("Ch_ange"); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(callback_do_change), + (gpointer)state); + gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0); + gtk_widget_show(button); + + /* Label (hidden) */ + state->label_reboot = gtk_label_new(NULL); + gtk_label_set_line_wrap(GTK_LABEL(state->label_reboot), TRUE); + gtk_misc_set_alignment(GTK_MISC(state->label_reboot), 0, 0); + gtk_box_pack_start(GTK_BOX(vbox), state->label_reboot, TRUE, TRUE, 0); + gtk_widget_show(state->label_reboot); + +#if 0 + gtk_box_pack_start(GTK_BOX(vbox), + create_bbox(window, TRUE, NULL, 10, 85, 20, GTK_BUTTONBOX_END), + TRUE, TRUE, 5); +#endif + { + + GtkWidget *frame; + GtkWidget *bbox2; + GtkWidget *button2; + + frame = gtk_frame_new(NULL); + bbox2 = gtk_hbutton_box_new(); + + gtk_container_set_border_width(GTK_CONTAINER(bbox2), 5); + gtk_container_add(GTK_CONTAINER(frame), bbox2); + + /* Set the appearance of the Button Box */ + gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox2), GTK_BUTTONBOX_END); + gtk_box_set_spacing(GTK_BOX(bbox2), 10); + /*gtk_button_box_set_child_size(GTK_BUTTON_BOX(bbox2), child_w, child_h);*/ + + button2 = gtk_button_new_from_stock(GTK_STOCK_OK); + gtk_container_add(GTK_CONTAINER(bbox2), button2); + g_signal_connect(G_OBJECT(button2), "clicked", G_CALLBACK(callback_do_exit), state); + + button2 = gtk_button_new_from_stock(GTK_STOCK_CANCEL); + gtk_container_add(GTK_CONTAINER(bbox2), button2); + g_signal_connect(G_OBJECT(button2), "clicked", + G_CALLBACK(callback_delete_event), + window); + + gtk_container_add(GTK_CONTAINER(bbox2), state->button_apply); + g_signal_connect(G_OBJECT(state->button_apply), "clicked", + G_CALLBACK(callback_apply_description_change), + state); + gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), FALSE); + + button2 = gtk_button_new_from_stock(GTK_STOCK_ABOUT); + gtk_container_add(GTK_CONTAINER(bbox2), button2); + g_signal_connect(G_OBJECT(button2), "clicked", + G_CALLBACK(callback_do_about), + window); + + gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 5); + } + + gtk_widget_show_all(window); + + return 0; +} + +static int init_join_state(struct join_state **state) +{ + struct join_state *s; + + s = malloc(sizeof(struct join_state)); + if (!s) { + return -1; + } + + memset(s, '\0', sizeof(struct join_state)); + + *state = s; + + return 0; +} + +static int initialize_join_state(struct join_state *state, + const char *debug_level) +{ + struct libnetapi_ctx *ctx = NULL; + NET_API_STATUS status = 0; + + status = libnetapi_init(&ctx); + if (status) { + return status; + } + + if (debug_level) { + libnetapi_set_debuglevel(ctx, debug_level); + } + + { + char my_hostname[HOST_NAME_MAX]; + const char *p = NULL; + if (gethostname(my_hostname, sizeof(my_hostname)) == -1) { + return -1; + } + + state->my_fqdn = strdup(my_hostname); + if (!state->my_fqdn) { + return -1; + } + + p = strchr(my_hostname, '.'); + if (p) { + my_hostname[strlen(my_hostname) - strlen(p)] = '\0'; + state->my_hostname = strdup(my_hostname); + if (!state->my_hostname) { + return -1; + } + p++; + state->my_dnsdomain = strdup(p); + if (!state->my_dnsdomain) { + return -1; + } + } + } + + { + const char *buffer = NULL; + uint16_t type = 0; + status = NetGetJoinInformation(NULL, &buffer, &type); + if (status) { + return status; + } + state->name_buffer_initial = (char *)buffer; + state->name_type_initial = type; + } + + { + struct srvsvc_NetSrvInfo1005 *info1005 = NULL; + uint8_t *buffer = NULL; + + status = NetServerGetInfo(NULL, 1005, &buffer); + if (status) { + return status; + } + + info1005 = (struct srvsvc_NetSrvInfo1005 *)buffer; + + state->comment = strdup(info1005->comment); + if (!state->comment) { + return -1; + } + } +#if 0 + { + struct srvsvc_NetSrvInfo100 *info100 = NULL; + uint8_t *buffer = NULL; + + status = NetServerGetInfo(NULL, 100, &buffer); + if (status) { + return status; + } + + info100 = (struct srvsvc_NetSrvInfo100 *)buffer; + + state->comment = strdup(info100->comment); + if (!state->comment) { + return -1; + } + } +#endif + + state->ctx = ctx; + + return 0; +} + +int main(int argc, char **argv) +{ + GOptionContext *context = NULL; + static const char *debug_level = NULL; + struct join_state *state = NULL; + GError *error = NULL; + int ret = 0; + + static GOptionEntry entries[] = { + { "debug", 'd', 0, G_OPTION_ARG_STRING, &debug_level, "Debug level (for samba)", "N" }, + { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Verbose output", 0 }, + { NULL } + }; + + context = g_option_context_new("- Samba domain join utility"); + g_option_context_add_main_entries(context, entries, NULL); +/* g_option_context_add_main_entries(context, entries, GETTEXT_PACKAGE); */ + g_option_context_add_group(context, gtk_get_option_group(TRUE)); + g_option_context_parse(context, &argc, &argv, &error); + + gtk_init(&argc, &argv); + g_set_application_name("Samba"); + + ret = init_join_state(&state); + if (ret) { + return ret; + } + + ret = initialize_join_state(state, debug_level); + if (ret) { + return ret; + } + + draw_main_window(state); + + gtk_main(); + + do_cleanup(state); + + return 0; +} diff --git a/source3/lib/netapi/examples/netdomjoin/netdomjoin.c b/source3/lib/netapi/examples/netdomjoin/netdomjoin.c new file mode 100644 index 0000000000..a2bb700250 --- /dev/null +++ b/source3/lib/netapi/examples/netdomjoin/netdomjoin.c @@ -0,0 +1,107 @@ +/* + * Unix SMB/CIFS implementation. + * Join Support (cmdline + netapi) + * Copyright (C) Guenther Deschner 2007 + * + * 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 3 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, see . + */ + +#include +#include +#include +#include +#include + +#include + +char *get_string_param(const char *param) +{ + char *p; + + p = strchr(param, '='); + if (!p) { + return NULL; + } + + return (p+1); +} + +int main(int argc, char **argv) +{ + NET_API_STATUS status; + const char *server_name = NULL; + const char *domain_name = NULL; + const char *account_ou = NULL; + const char *Account = NULL; + const char *password = NULL; + uint32_t join_flags = 3; + struct libnetapi_ctx *ctx = NULL; + int i; + + status = libnetapi_init(&ctx); + if (status != 0) { + return status; + } + + if (argc < 2) { + printf("usage: netdomjoin\n"); + printf("\t[hostname=HOSTNAME] [domain=DOMAIN] \n"); + return 0; + } + + if (argc > 2) { + server_name = argv[1]; + } + + for (i=0; i Date: Fri, 21 Dec 2007 17:29:15 +0100 Subject: Move gtk app to the correct location. Thanks obnox! Guenther (This used to be commit 740a2b080db56d504c4edd58bf41d72edb3d32ee) --- .../examples/netdomjoin-gui/netdomjoin-gui.c | 1347 ++++++++++++++++++++ .../netapi/examples/netdomjoin/netdomjoin-gui.c | 1347 -------------------- 2 files changed, 1347 insertions(+), 1347 deletions(-) create mode 100644 source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c delete mode 100644 source3/lib/netapi/examples/netdomjoin/netdomjoin-gui.c (limited to 'source3/lib') diff --git a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c new file mode 100644 index 0000000000..8ca6897cab --- /dev/null +++ b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c @@ -0,0 +1,1347 @@ +/* + * Unix SMB/CIFS implementation. + * Join Support (gtk + netapi) + * Copyright (C) Guenther Deschner 2007 + * + * 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 3 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, see . + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#define MAX_CRED_LEN 256 +#define MAX_NETBIOS_NAME_LEN 15 + +#define SAMBA_ICON_PATH "/usr/share/pixmaps/samba/samba.ico" +#define SAMBA_IMAGE_PATH "/usr/share/pixmaps/samba/logo.png" + +#define WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED ( 0x00000020 ) +#define WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE ( 0x00000004 ) +#define WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE ( 0x00000002 ) +#define WKSSVC_JOIN_FLAGS_JOIN_TYPE ( 0x00000001 ) + +#define NetSetupWorkgroupName ( 2 ) +#define NetSetupDomainName ( 3 ) + +#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0) + +struct srvsvc_NetSrvInfo1005 { + const char *comment;/* [unique,charset(UTF16)] */ +}; + +static gboolean verbose = FALSE; + +typedef struct join_state { + struct libnetapi_ctx *ctx; + GtkWidget *window_main; + GtkWidget *window_parent; + GtkWidget *window_do_change; + GtkWidget *window_creds_prompt; + GtkWidget *entry_account; + GtkWidget *entry_password; + GtkWidget *entry_domain; + GtkWidget *entry_workgroup; + GtkWidget *button_ok; + GtkWidget *button_apply; + GtkWidget *button_ok_creds; + GtkWidget *label_reboot; + GtkWidget *label_current_name_buffer; + GtkWidget *label_current_name_type; + GtkWidget *label_full_computer_name; + uint16_t name_type_initial; + uint16_t name_type_new; + char *name_buffer_initial; + char *name_buffer_new; + char *password; + char *account; + char *comment; + char *comment_new; + char *my_fqdn; + char *my_dnsdomain; + char *my_hostname; + uint16_t server_role; + gboolean settings_changed; + gboolean hostname_changed; +} join_state; + +static void debug(const char *format, ...) +{ + va_list args; + + if (!verbose) { + return; + } + + va_start(args, format); + g_vprintf(format, args); + va_end(args); +} + +static gboolean callback_delete_event(GtkWidget *widget, + GdkEvent *event, + gpointer data) +{ + gtk_main_quit(); + return FALSE; +} + +static void callback_do_close(GtkWidget *widget, + gpointer data) +{ + debug("Closing now...\n"); + gtk_widget_destroy(data); +} + +static void free_join_state(struct join_state *s) +{ + SAFE_FREE(s->name_buffer_initial); + SAFE_FREE(s->name_buffer_new); + SAFE_FREE(s->password); + SAFE_FREE(s->account); + SAFE_FREE(s->comment); + SAFE_FREE(s->comment_new); + SAFE_FREE(s->my_fqdn); + SAFE_FREE(s->my_dnsdomain); + SAFE_FREE(s->my_hostname); + +} + +static void do_cleanup(struct join_state *state) +{ + libnetapi_free(state->ctx); + free_join_state(state); +} + +static void callback_apply_description_change(GtkWidget *widget, + gpointer data) +{ + struct join_state *state = (struct join_state *)data; + NET_API_STATUS status = 0; + uint32_t parm_err = 0; + struct srvsvc_NetSrvInfo1005 info1005; + GtkWidget *dialog; + + info1005.comment = state->comment_new; + + status = NetServerSetInfo(NULL, 1005, (uint8_t *)&info1005, &parm_err); + if (status) { + debug("NetServerSetInfo failed with: %s\n", + libnetapi_errstr(state->ctx, status)); + dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + "Failed to change computer description: %s.", + libnetapi_errstr(state->ctx, status)); + g_signal_connect_swapped(dialog, "response", + G_CALLBACK(gtk_widget_destroy), + dialog); + + gtk_widget_show(dialog); + return; + } + + gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), FALSE); +} + +static void callback_do_exit(GtkWidget *widget, + gpointer data) +{ + GtkWidget *dialog; + gint result; + struct join_state *state = (struct join_state *)data; + + if (!state->settings_changed) { + callback_delete_event(NULL, NULL, NULL); + return; + } + + dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_YES_NO, + "You must restart your computer before the new settings will take effect."); + result = gtk_dialog_run(GTK_DIALOG(dialog)); + switch (result) { + case GTK_RESPONSE_YES: + g_print("would reboot here\n"); + break; + case GTK_RESPONSE_NO: + default: + break; + } + gtk_widget_destroy(dialog); + gtk_widget_destroy(state->window_main); + do_cleanup(state); + exit(0); +} + + +static void callback_do_reboot(GtkWidget *widget, + gpointer data, + gpointer data2) +{ + GtkWidget *dialog; + struct join_state *state = (struct join_state *)data2; + + debug("callback_do_reboot\n"); + + state->settings_changed = TRUE; + dialog = gtk_message_dialog_new(GTK_WINDOW(data), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_OK, + "You must restart this computer for the changes to take effect."); +#if 0 + g_signal_connect_swapped(dialog, "response", + G_CALLBACK(gtk_widget_destroy), + dialog); + + debug("showing dialog\n"); + gtk_widget_show(dialog); +#else + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); +#endif + + gtk_label_set_text(GTK_LABEL(state->label_reboot), "Changes will take effect after you restart this computer"); + + debug("destroying do_change window\n"); + gtk_widget_destroy(GTK_WIDGET(state->window_do_change)); + + { + uint32_t status; + const char *buffer; + uint16_t type; + + status = NetGetJoinInformation(NULL, &buffer, &type); + if (status != 0) { + g_print("failed to query status\n"); + return; + } + + debug("got new status: %s\n", buffer); +#if 0 + SAFE_FREE(state->name_buffer_new); + state->name_buffer_new = strdup(buffer); + SAFE_FREE(buffer); + state->name_type_new = type; +#endif + gtk_label_set_text(GTK_LABEL(state->label_current_name_buffer), state->name_buffer_new); + if (state->name_type_new == 3) { + gtk_label_set_text(GTK_LABEL(state->label_current_name_type), "Domain:"); + } else { + gtk_label_set_text(GTK_LABEL(state->label_current_name_type), "Workgroup:"); + } + } +} + +static void callback_return_username(GtkWidget *widget, + gpointer data) +{ + const gchar *entry_text; + struct join_state *state = (struct join_state *)data; + if (!widget) { + return; + } + entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); + debug("callback_return_username: %s\n", entry_text); + SAFE_FREE(state->account); + state->account = strdup(entry_text); +} + +static void callback_return_username_and_enter(GtkWidget *widget, + gpointer data) +{ + const gchar *entry_text; + struct join_state *state = (struct join_state *)data; + if (!widget) { + return; + } + entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); + debug("callback_return_username: %s\n", entry_text); + SAFE_FREE(state->account); + state->account = strdup(entry_text); + g_signal_emit_by_name(state->button_ok_creds, "clicked"); +} + +static void callback_return_password(GtkWidget *widget, + gpointer data) +{ + const gchar *entry_text; + struct join_state *state = (struct join_state *)data; + if (!widget) { + return; + } + entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); +#ifdef DEBUG_PASSWORD + debug("callback_return_password: %s\n", entry_text); +#else + debug("callback_return_password: (not printed)\n"); +#endif + SAFE_FREE(state->password); + state->password = strdup(entry_text); +} + +static void callback_return_password_and_enter(GtkWidget *widget, + gpointer data) +{ + const gchar *entry_text; + struct join_state *state = (struct join_state *)data; + if (!widget) { + return; + } + entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); +#ifdef DEBUG_PASSWORD + debug("callback_return_password: %s\n", entry_text); +#else + debug("callback_return_password: (not printed)\n"); +#endif + SAFE_FREE(state->password); + state->password = strdup(entry_text); + g_signal_emit_by_name(state->button_ok_creds, "clicked"); +} + +static void callback_do_hostname_change(GtkWidget *widget, + gpointer data) +{ + GtkWidget *dialog; + const char *str = NULL; + + struct join_state *state = (struct join_state *)data; + + switch (state->name_type_initial) { + case NetSetupDomainName: + str = "To be implemented: call NetRenameMachineInDomain\n"; + break; + case NetSetupWorkgroupName: + str = "To be implemented: call SetComputerNameEx\n"; + break; + default: + break; + } + + dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + str); + + g_signal_connect_swapped(dialog, "response", + G_CALLBACK(gtk_widget_destroy), + dialog); + gtk_widget_show(dialog); +} + +static void callback_do_join(GtkWidget *widget, + gpointer data) +{ + GtkWidget *dialog; + + NET_API_STATUS status; + const char *err_str = NULL; + uint32_t join_flags = 0; + uint32_t unjoin_flags = 0; + gboolean domain_join = FALSE; + gboolean try_unjoin = FALSE; + const char *domain_or_workgroup = NULL; + + struct join_state *state = (struct join_state *)data; + + callback_return_username(state->entry_account, state); + callback_return_password(state->entry_password, state); + + if (state->window_creds_prompt) { + gtk_widget_destroy(GTK_WIDGET(state->window_creds_prompt)); + } + + if (state->name_type_new == NetSetupDomainName) { + domain_join = TRUE; + join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE | + WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE | + WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED; /* for testing */ + domain_or_workgroup = "domain"; + } else { + domain_or_workgroup = "workgroup"; + } + + if ((state->name_type_initial == NetSetupDomainName) && + (state->name_type_new == NetSetupWorkgroupName)) { + try_unjoin = TRUE; + unjoin_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE | + WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE; + } + + debug("callback_do_join: Joining a %s named %s using join_flags 0x%08x ", + domain_or_workgroup, + state->name_buffer_new, + join_flags); + if (domain_join) { + debug("as %s ", state->account); +#ifdef DEBUG_PASSWORD + debug("with %s ", state->password); +#endif + } + debug("\n"); + if (try_unjoin) { + + debug("callback_do_join: Unjoining\n"); + + status = NetUnjoinDomain(NULL, + state->account, + state->password, + unjoin_flags); + if (status != 0) { + err_str = libnetapi_errstr(state->ctx, status); + g_print("callback_do_join: failed to unjoin (%s)\n", + err_str); + + dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "The following error occured attempting to unjoin the %s: \"%s\": %s", + domain_or_workgroup, + state->name_buffer_new, + err_str); + + g_signal_connect_swapped(dialog, "response", + G_CALLBACK(gtk_widget_destroy), + dialog); + + gtk_widget_show(dialog); + + return; + } + + } + status = NetJoinDomain(NULL, + state->name_buffer_new, + NULL, + state->account, + state->password, + join_flags); + if (status != 0) { + err_str = libnetapi_errstr(state->ctx, status); + g_print("callback_do_join: failed to join (%s)\n", err_str); + + dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "The following error occured attempting to join the %s: \"%s\": %s", + domain_or_workgroup, + state->name_buffer_new, + err_str); + + g_signal_connect_swapped(dialog, "response", + G_CALLBACK(gtk_widget_destroy), + dialog); + + gtk_widget_show(dialog); + + return; + } + + debug("callback_do_join: Successfully joined %s\n", + domain_or_workgroup); + + dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_OK, + "Welcome to the %s %s.", + state->name_buffer_new, + domain_or_workgroup); + + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + + callback_do_reboot(NULL, state->window_parent, state); +} + +static void callback_creds_prompt(GtkWidget *widget, + gpointer data) +{ + GtkWidget *window; + GtkWidget *box1; + GtkWidget *bbox; + GtkWidget *button; + GtkWidget *label; + + struct join_state *state = (struct join_state *)data; + + debug("callback_creds_prompt:\n"); + + state->window_parent = state->window_do_change; + + if (state->hostname_changed) { + return callback_do_hostname_change(NULL, state); + } + + if ((state->name_type_initial != NetSetupDomainName) && + (state->name_type_new != NetSetupDomainName)) { + return callback_do_join(NULL, state); + } + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + + gtk_window_set_title(GTK_WINDOW(window), "Computer Name Changes"); + gtk_window_set_resizable(GTK_WINDOW(window), FALSE); + gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); + gtk_widget_set_size_request(GTK_WIDGET(window), 380, 280); + gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL); +/* gtk_window_set_icon_name(GTK_WIDGET(window), GTK_STOCK_DIALOG_AUTHENTICATION); */ + state->window_creds_prompt = window; + + g_signal_connect(G_OBJECT(window), "delete_event", + G_CALLBACK(callback_do_close), window); + + gtk_container_set_border_width(GTK_CONTAINER(window), 10); + + box1 = gtk_vbox_new(FALSE, 0); + + gtk_container_add(GTK_CONTAINER(window), box1); + + if ((state->name_type_initial == NetSetupDomainName) && + (state->name_type_new == NetSetupWorkgroupName)) { + label = gtk_label_new("Enter the name and password of an account with permission to leave the domain.\n"); + } else { + label = gtk_label_new("Enter the name and password of an account with permission to join the domain.\n"); + } + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + + gtk_box_pack_start(GTK_BOX(box1), label, FALSE, FALSE, 0); + + gtk_widget_show(label); + + /* USER NAME */ + label = gtk_label_new("User name:"); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_box_pack_start(GTK_BOX(box1), label, FALSE, FALSE, 0); + gtk_widget_show(label); + + state->entry_account = gtk_entry_new(); + gtk_entry_set_max_length(GTK_ENTRY(state->entry_account), MAX_CRED_LEN); + g_signal_connect(G_OBJECT(state->entry_account), "activate", + G_CALLBACK(callback_return_username_and_enter), + (gpointer)state); + gtk_editable_select_region(GTK_EDITABLE(state->entry_account), + 0, GTK_ENTRY(state->entry_account)->text_length); + gtk_box_pack_start(GTK_BOX(box1), state->entry_account, TRUE, TRUE, 0); + gtk_widget_show(state->entry_account); + + /* PASSWORD */ + label = gtk_label_new("Password:"); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_box_pack_start(GTK_BOX(box1), label, FALSE, FALSE, 0); + gtk_widget_show(label); + + state->entry_password = gtk_entry_new(); + gtk_entry_set_max_length(GTK_ENTRY(state->entry_password), MAX_CRED_LEN); + gtk_entry_set_visibility(GTK_ENTRY(state->entry_password), FALSE); + g_signal_connect(G_OBJECT(state->entry_password), "activate", + G_CALLBACK(callback_return_password_and_enter), + (gpointer)state); + gtk_editable_set_editable(GTK_EDITABLE(state->entry_password), TRUE); + gtk_editable_select_region(GTK_EDITABLE(state->entry_password), + 0, GTK_ENTRY(state->entry_password)->text_length); + gtk_box_pack_start(GTK_BOX(box1), state->entry_password, TRUE, TRUE, 0); + gtk_widget_show(state->entry_password); + + bbox = gtk_hbutton_box_new(); + gtk_container_set_border_width(GTK_CONTAINER(bbox), 5); + gtk_container_add(GTK_CONTAINER(box1), bbox); + gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); + gtk_box_set_spacing(GTK_BOX(bbox), 10); + + state->button_ok_creds = gtk_button_new_from_stock(GTK_STOCK_OK); + gtk_widget_grab_focus(GTK_WIDGET(state->button_ok_creds)); + gtk_container_add(GTK_CONTAINER(bbox), state->button_ok_creds); + g_signal_connect(G_OBJECT(state->button_ok_creds), "clicked", + G_CALLBACK(callback_do_join), + (gpointer)state); + gtk_widget_show(state->button_ok_creds); + + button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); + gtk_container_add(GTK_CONTAINER(bbox), button); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(callback_do_close), (gpointer) window); + gtk_widget_show_all(window); +} + +static void callback_enter_hostname_and_unlock(GtkWidget *widget, + gpointer data) +{ + const gchar *entry_text = NULL; + char *str = NULL; + struct join_state *state = (struct join_state *)data; + + entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); + debug("callback_enter_hostname_and_unlock: %s\n", entry_text); + if (!entry_text || entry_text[0] == 0) { + state->hostname_changed = FALSE; + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); + return; + } + if (strcasecmp(state->my_hostname, entry_text) == 0) { + state->hostname_changed = FALSE; + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); + return; + } + state->hostname_changed = TRUE; + if (state->name_type_initial == NetSetupDomainName) { + asprintf(&str, "%s.%s", entry_text, state->my_dnsdomain); + } else { + asprintf(&str, "%s.", entry_text); + } + gtk_label_set_text(GTK_LABEL(state->label_full_computer_name), str); + free(str); + + if (state->hostname_changed && str && str[0] != 0 && str[0] != '.') { + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), TRUE); + } +} + +static void callback_enter_computer_description_and_unlock(GtkWidget *widget, + gpointer data) +{ + const gchar *entry_text = NULL; + struct join_state *state = (struct join_state *)data; + int string_unchanged = 0; + + entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); + debug("callback_enter_computer_description_and_unlock: %s\n", + entry_text); +#if 0 + if (!entry_text || entry_text[0] == 0) { + string_unchanged = 1; + gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), + FALSE); + return; + } +#endif + if (entry_text && strcasecmp(state->comment, entry_text) == 0) { + string_unchanged = 1; + gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), + FALSE); + return; + } + + gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), TRUE); + SAFE_FREE(state->comment_new); + state->comment_new = strdup(entry_text); + +} + + +static void callback_enter_workgroup_and_unlock(GtkWidget *widget, + gpointer data) +{ + const gchar *entry_text = NULL; + struct join_state *state = (struct join_state *)data; + + entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); + debug("callback_enter_workgroup_and_unlock: %s\n", entry_text); + if (!entry_text || entry_text[0] == 0) { + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); + return; + } + if (strcasecmp(state->name_buffer_initial, entry_text) == 0) { + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); + return; + } + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), TRUE); + SAFE_FREE(state->name_buffer_new); + state->name_buffer_new = strdup(entry_text); + state->name_type_new = NetSetupWorkgroupName; +} + +static void callback_enter_domain_and_unlock(GtkWidget *widget, + gpointer data) +{ + const gchar *entry_text = NULL; + struct join_state *state = (struct join_state *)data; + + entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); + debug("callback_enter_domain_and_unlock: %s\n", entry_text); + if (!entry_text || entry_text[0] == 0) { + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); + return; + } + if (strcasecmp(state->name_buffer_initial, entry_text) == 0) { + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); + return; + } + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), TRUE); + SAFE_FREE(state->name_buffer_new); + state->name_buffer_new = strdup(entry_text); + state->name_type_new = NetSetupDomainName; +} + +static void callback_continue(GtkWidget *widget, + gpointer data) +{ + struct join_state *state = (struct join_state *)data; + + gtk_widget_grab_focus(GTK_WIDGET(state->button_ok)); + g_signal_emit_by_name(state->button_ok, "clicked"); +} + +static void callback_apply_continue(GtkWidget *widget, + gpointer data) +{ + struct join_state *state = (struct join_state *)data; + + gtk_widget_grab_focus(GTK_WIDGET(state->button_apply)); + g_signal_emit_by_name(state->button_apply, "clicked"); +} + +static void callback_do_join_workgroup(GtkWidget *widget, + gpointer data) +{ + struct join_state *state = (struct join_state *)data; + debug("callback_do_join_workgroup choosen\n"); + gtk_widget_set_sensitive(GTK_WIDGET(state->entry_workgroup), TRUE); + gtk_widget_grab_focus(GTK_WIDGET(state->entry_workgroup)); + gtk_widget_set_sensitive(GTK_WIDGET(state->entry_domain), FALSE); + callback_enter_workgroup_and_unlock(state->entry_workgroup, state); /* TEST */ +} + +static void callback_do_join_domain(GtkWidget *widget, + gpointer data) +{ + struct join_state *state = (struct join_state *)data; + debug("callback_do_join_domain choosen\n"); + gtk_widget_set_sensitive(GTK_WIDGET(state->entry_domain), TRUE); + gtk_widget_grab_focus(GTK_WIDGET(state->entry_domain)); + gtk_widget_set_sensitive(GTK_WIDGET(state->entry_workgroup), FALSE); + callback_enter_domain_and_unlock(state->entry_domain, state); /* TEST */ +} + +static void callback_do_change(GtkWidget *widget, + gpointer data) +{ + GtkWidget *window; + GtkWidget *box1; + GtkWidget *bbox; + GtkWidget *button_workgroup; + GtkWidget *button_domain; + GtkWidget *button; + GtkWidget *label; + GtkWidget *frame_horz; + GtkWidget *vbox; + GtkWidget *entry; + GSList *group; + + struct join_state *state = (struct join_state *)data; + + debug("callback_do_change called\n"); + + if (state->server_role == 3) { + GtkWidget *dialog; + dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + "Domain controller cannot be moved from one domain to another, they must first be demoted. Renaming this domain controller may cause it to become temporarily unavailable to users and computers. For information on renaming domain controllers, including alternate renaming methods, see Help and Support. To continue renaming this domain controller, click OK."); + g_signal_connect_swapped(dialog, "response", + G_CALLBACK(gtk_widget_destroy), + dialog); + + gtk_widget_show(dialog); + return; + } + + state->button_ok = gtk_button_new_from_stock(GTK_STOCK_OK); + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + + gtk_window_set_title(GTK_WINDOW(window), "Computer Name Changes"); + gtk_window_set_resizable(GTK_WINDOW(window), FALSE); + gtk_widget_set_size_request(GTK_WIDGET(window), 480, 500); /* breite * höhe */ + gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL); + + g_signal_connect(G_OBJECT(window), "delete_event", + G_CALLBACK(callback_do_close), window); + + gtk_container_set_border_width(GTK_CONTAINER(window), 10); + + box1 = gtk_vbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(window), box1); + + label = gtk_label_new("You can change the name and membership of this computer. Changes may affect access to network ressources."); + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_box_pack_start(GTK_BOX(box1), label, TRUE, TRUE, 0); + gtk_widget_show(label); + + /* COMPUTER NAME */ + label = gtk_label_new("Computer name:"); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_box_pack_start(GTK_BOX(box1), label, TRUE, TRUE, 0); + gtk_widget_show(label); + + state->label_full_computer_name = gtk_label_new(NULL); + { + entry = gtk_entry_new(); + gtk_entry_set_max_length(GTK_ENTRY(entry), MAX_NETBIOS_NAME_LEN); + g_signal_connect(G_OBJECT(entry), "changed", + G_CALLBACK(callback_enter_hostname_and_unlock), + (gpointer)state); + gtk_entry_set_text(GTK_ENTRY(entry), state->my_hostname); + gtk_editable_select_region(GTK_EDITABLE(entry), + 0, GTK_ENTRY(entry)->text_length); + + gtk_editable_set_editable(GTK_EDITABLE(entry), TRUE); /* ! */ + gtk_box_pack_start(GTK_BOX(box1), entry, TRUE, TRUE, 0); + gtk_widget_show(entry); + } + + /* FULL COMPUTER NAME */ + label = gtk_label_new("Full computer name:"); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_box_pack_start(GTK_BOX(box1), label, TRUE, TRUE, 0); + gtk_widget_show(label); + + { + const gchar *entry_text; + char *str = NULL; + entry_text = gtk_entry_get_text(GTK_ENTRY(entry)); + if (state->name_type_initial == NetSetupDomainName) { + asprintf(&str, "%s.%s", entry_text, state->my_dnsdomain); + } else { + asprintf(&str, "%s.", entry_text); + } + gtk_label_set_text(GTK_LABEL(state->label_full_computer_name), str); + free(str); + gtk_misc_set_alignment(GTK_MISC(state->label_full_computer_name), 0, 0); + gtk_box_pack_start(GTK_BOX(box1), state->label_full_computer_name, TRUE, TRUE, 0); + gtk_widget_show(state->label_full_computer_name); + } + + /* BOX */ + frame_horz = gtk_frame_new ("Member Of"); + gtk_box_pack_start(GTK_BOX(box1), frame_horz, TRUE, TRUE, 10); + + vbox = gtk_vbox_new(FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(vbox), 10); + gtk_container_add(GTK_CONTAINER(frame_horz), vbox); + + /* TWO ENTRIES */ + state->entry_workgroup = gtk_entry_new(); + state->entry_domain = gtk_entry_new(); + + /* DOMAIN */ + button_domain = gtk_radio_button_new_with_label(NULL, "Domain"); + if (state->name_type_initial == NetSetupDomainName) { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_domain), TRUE); + } + gtk_box_pack_start(GTK_BOX(vbox), button_domain, TRUE, TRUE, 0); + g_signal_connect(G_OBJECT(button_domain), "clicked", + G_CALLBACK(callback_do_join_domain), + (gpointer)state); + + { + gtk_entry_set_max_length(GTK_ENTRY(state->entry_domain), 50); + g_signal_connect(G_OBJECT(state->entry_domain), "changed", + G_CALLBACK(callback_enter_domain_and_unlock), + (gpointer)state); + g_signal_connect(G_OBJECT(state->entry_domain), "activate", + G_CALLBACK(callback_continue), + (gpointer)state); + if (state->name_type_initial == NetSetupDomainName) { + gtk_entry_set_text(GTK_ENTRY(state->entry_domain), state->name_buffer_initial); + gtk_widget_set_sensitive(state->entry_workgroup, FALSE); + gtk_widget_set_sensitive(state->entry_domain, TRUE); + } + gtk_editable_set_editable(GTK_EDITABLE(state->entry_domain), TRUE); + gtk_box_pack_start(GTK_BOX(vbox), state->entry_domain, TRUE, TRUE, 0); + gtk_widget_show(state->entry_domain); + } + gtk_widget_show(button_domain); + + /* WORKGROUP */ + group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button_domain)); + button_workgroup = gtk_radio_button_new_with_label(group, "Workgroup"); + if (state->name_type_initial == NetSetupWorkgroupName) { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_workgroup), TRUE); + } + gtk_box_pack_start(GTK_BOX(vbox), button_workgroup, TRUE, TRUE, 0); + g_signal_connect(G_OBJECT(button_workgroup), "clicked", + G_CALLBACK(callback_do_join_workgroup), + (gpointer)state); + { + gtk_entry_set_max_length(GTK_ENTRY(state->entry_workgroup), MAX_NETBIOS_NAME_LEN); + g_signal_connect(G_OBJECT(state->entry_workgroup), "changed", + G_CALLBACK(callback_enter_workgroup_and_unlock), + (gpointer)state); + g_signal_connect(G_OBJECT(state->entry_workgroup), "activate", + G_CALLBACK(callback_continue), + (gpointer)state); + + if (state->name_type_initial == NetSetupWorkgroupName) { + gtk_entry_set_text(GTK_ENTRY(state->entry_workgroup), state->name_buffer_initial); + gtk_widget_set_sensitive(GTK_WIDGET(state->entry_domain), FALSE); + gtk_widget_set_sensitive(GTK_WIDGET(state->entry_workgroup), TRUE); + } + gtk_box_pack_start(GTK_BOX(vbox), state->entry_workgroup, TRUE, TRUE, 0); + gtk_widget_show(state->entry_workgroup); + } + gtk_widget_show(button_workgroup); + + /* BUTTONS */ + bbox = gtk_hbutton_box_new(); + gtk_container_set_border_width(GTK_CONTAINER(bbox), 5); + gtk_container_add(GTK_CONTAINER(box1), bbox); + gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); + gtk_box_set_spacing(GTK_BOX(bbox), 10); + + state->window_do_change = window; + gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); /* !!! */ + gtk_container_add(GTK_CONTAINER(bbox), state->button_ok); + g_signal_connect(G_OBJECT(state->button_ok), "clicked", + G_CALLBACK(callback_creds_prompt), + (gpointer)state); + + button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); + gtk_container_add(GTK_CONTAINER(bbox), button); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(callback_do_close), + (gpointer)window); + + gtk_widget_show_all(window); + +} + +static void callback_do_about(GtkWidget *widget, + gpointer data) +{ + GdkPixbuf *logo; + GError *error = NULL; + + debug("callback_do_about called\n"); + + logo = gdk_pixbuf_new_from_file(SAMBA_IMAGE_PATH, + &error); + if (logo == NULL) { + g_print("failed to load logo from %s: %s\n", + SAMBA_IMAGE_PATH, error->message); + } + + gtk_show_about_dialog(data, + "name", "Samba", + "version", "3.2.0pre2-GIT-904a90-test", + "copyright", "Copyright Andrew Tridgell and the Samba Team 1992-2007", + "website", "http://www.samba.org", + "license", "GPLv3", + "logo", logo, + "comments", "Samba gtk domain join utility", + NULL); +} + +static int draw_main_window(struct join_state *state) +{ + GtkWidget *window; + GtkWidget *button; + GtkWidget *label; + GtkWidget *main_vbox; + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *bbox; + GtkWidget *image; + GtkWidget *table; + GtkWidget *entry; + GdkPixbuf *icon; + GError *error = NULL; + + icon = gdk_pixbuf_new_from_file(SAMBA_ICON_PATH, + &error); + if (icon == NULL) { + g_print("failed to load logo from %s : %s\n", + SAMBA_ICON_PATH, error->message); + } + +#if 1 + image = gtk_image_new_from_file(SAMBA_IMAGE_PATH); +#else + image = gtk_image_new_from_file("/usr/share/pixmaps/redhat-system_settings.png"); +#endif + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + state->window_main = window; + + gtk_window_set_title(GTK_WINDOW(window), "Samba - Join Domain dialogue"); + gtk_widget_set_size_request(GTK_WIDGET(window), 600, 600); /* breite * höhe */ + gtk_window_set_resizable(GTK_WINDOW(window), FALSE); + gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL); + + g_signal_connect(G_OBJECT(window), "delete_event", + G_CALLBACK(callback_delete_event), NULL); + + gtk_container_set_border_width(GTK_CONTAINER(window), 10); + + main_vbox = gtk_vbox_new(FALSE, 10); + gtk_container_add(GTK_CONTAINER(window), main_vbox); + +#if 0 + gtk_box_pack_start(GTK_BOX(main_vbox), image, TRUE, TRUE, 10); + gtk_widget_show(image); +#endif + /* Hbox */ + hbox = gtk_hbox_new(FALSE, 10); + gtk_container_add(GTK_CONTAINER(main_vbox), hbox); + + { +/* gtk_box_pack_start(GTK_BOX(main_vbox), image, TRUE, TRUE, 10); */ + gtk_misc_set_alignment(GTK_MISC(image), 0, 0); + gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 10); + gtk_widget_show(image); + + /* Label */ + label = gtk_label_new("Samba uses the following information to identify your computer on the network."); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_widget_set_size_request(GTK_WIDGET(label), 500, 40); + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + gtk_widget_show(label); + } + + gtk_widget_show(hbox); + + vbox = gtk_vbox_new(FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(vbox), 10); + gtk_container_add(GTK_CONTAINER(main_vbox), vbox); + + /* Table */ + table = gtk_table_new(6, 3, TRUE); + gtk_table_set_row_spacings(GTK_TABLE(table), 5); + gtk_table_set_col_spacings(GTK_TABLE(table), 5); + gtk_container_add(GTK_CONTAINER(vbox), table); + + { + /* Label */ + label = gtk_label_new("Computer description:"); +/* gtk_misc_set_alignment(GTK_MISC(label), 0, 0); */ + gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1); + gtk_widget_show(label); + + state->button_apply = gtk_button_new_from_stock(GTK_STOCK_APPLY); + + /* Entry */ + entry = gtk_entry_new(); + gtk_entry_set_max_length(GTK_ENTRY(entry), 256); + g_signal_connect(G_OBJECT(entry), "changed", + G_CALLBACK(callback_enter_computer_description_and_unlock), + state); + g_signal_connect(G_OBJECT(entry), "activate", + G_CALLBACK(callback_apply_continue), + (gpointer)state); + + gtk_entry_set_text(GTK_ENTRY(entry), (char *)state->comment); + gtk_editable_set_editable(GTK_EDITABLE(entry), TRUE); /* ! */ + gtk_table_attach_defaults(GTK_TABLE(table), entry, 1, 3, 0, 1); + gtk_widget_show(entry); + } + + /* Label */ + label = gtk_label_new("For example: \"Samba \%v\"."); + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 3, 1, 2); + gtk_widget_show(label); + + /* Label */ + label = gtk_label_new("Full computer name:"); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3); + gtk_widget_show(label); + + { + /* Label */ + char *str = NULL; + if (state->name_type_initial == NetSetupDomainName) { + asprintf(&str, "%s.%s", state->my_hostname, + state->my_dnsdomain); + } else { + asprintf(&str, "%s.", state->my_hostname); + } + + label = gtk_label_new(str); + SAFE_FREE(str); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 3, 2, 3); + gtk_widget_show(label); + } + + /* Label */ + if (state->name_type_initial == NetSetupDomainName) { + label = gtk_label_new("Domain:"); + } else { + label = gtk_label_new("Workgroup:"); + } + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 3, 4); + gtk_widget_show(label); + state->label_current_name_type = label; + + /* Label */ + label = gtk_label_new(state->name_buffer_initial); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 3, 3, 4); + gtk_widget_show(label); + state->label_current_name_buffer = label; + + { + hbox = gtk_hbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(vbox), hbox); + label = gtk_label_new("To rename this computer or join a domain, click Change."); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + + + } + + /* bbox */ + bbox = gtk_hbutton_box_new(); + gtk_container_set_border_width(GTK_CONTAINER(bbox), 5); + gtk_container_add(GTK_CONTAINER(hbox), bbox); + gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); + gtk_box_set_spacing(GTK_BOX(bbox), 10); + + button = gtk_button_new_with_mnemonic("Ch_ange"); + g_signal_connect(G_OBJECT(button), "clicked", + G_CALLBACK(callback_do_change), + (gpointer)state); + gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0); + gtk_widget_show(button); + + /* Label (hidden) */ + state->label_reboot = gtk_label_new(NULL); + gtk_label_set_line_wrap(GTK_LABEL(state->label_reboot), TRUE); + gtk_misc_set_alignment(GTK_MISC(state->label_reboot), 0, 0); + gtk_box_pack_start(GTK_BOX(vbox), state->label_reboot, TRUE, TRUE, 0); + gtk_widget_show(state->label_reboot); + +#if 0 + gtk_box_pack_start(GTK_BOX(vbox), + create_bbox(window, TRUE, NULL, 10, 85, 20, GTK_BUTTONBOX_END), + TRUE, TRUE, 5); +#endif + { + + GtkWidget *frame; + GtkWidget *bbox2; + GtkWidget *button2; + + frame = gtk_frame_new(NULL); + bbox2 = gtk_hbutton_box_new(); + + gtk_container_set_border_width(GTK_CONTAINER(bbox2), 5); + gtk_container_add(GTK_CONTAINER(frame), bbox2); + + /* Set the appearance of the Button Box */ + gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox2), GTK_BUTTONBOX_END); + gtk_box_set_spacing(GTK_BOX(bbox2), 10); + /*gtk_button_box_set_child_size(GTK_BUTTON_BOX(bbox2), child_w, child_h);*/ + + button2 = gtk_button_new_from_stock(GTK_STOCK_OK); + gtk_container_add(GTK_CONTAINER(bbox2), button2); + g_signal_connect(G_OBJECT(button2), "clicked", G_CALLBACK(callback_do_exit), state); + + button2 = gtk_button_new_from_stock(GTK_STOCK_CANCEL); + gtk_container_add(GTK_CONTAINER(bbox2), button2); + g_signal_connect(G_OBJECT(button2), "clicked", + G_CALLBACK(callback_delete_event), + window); + + gtk_container_add(GTK_CONTAINER(bbox2), state->button_apply); + g_signal_connect(G_OBJECT(state->button_apply), "clicked", + G_CALLBACK(callback_apply_description_change), + state); + gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), FALSE); + + button2 = gtk_button_new_from_stock(GTK_STOCK_ABOUT); + gtk_container_add(GTK_CONTAINER(bbox2), button2); + g_signal_connect(G_OBJECT(button2), "clicked", + G_CALLBACK(callback_do_about), + window); + + gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 5); + } + + gtk_widget_show_all(window); + + return 0; +} + +static int init_join_state(struct join_state **state) +{ + struct join_state *s; + + s = malloc(sizeof(struct join_state)); + if (!s) { + return -1; + } + + memset(s, '\0', sizeof(struct join_state)); + + *state = s; + + return 0; +} + +static int initialize_join_state(struct join_state *state, + const char *debug_level) +{ + struct libnetapi_ctx *ctx = NULL; + NET_API_STATUS status = 0; + + status = libnetapi_init(&ctx); + if (status) { + return status; + } + + if (debug_level) { + libnetapi_set_debuglevel(ctx, debug_level); + } + + { + char my_hostname[HOST_NAME_MAX]; + const char *p = NULL; + if (gethostname(my_hostname, sizeof(my_hostname)) == -1) { + return -1; + } + + state->my_fqdn = strdup(my_hostname); + if (!state->my_fqdn) { + return -1; + } + + p = strchr(my_hostname, '.'); + if (p) { + my_hostname[strlen(my_hostname) - strlen(p)] = '\0'; + state->my_hostname = strdup(my_hostname); + if (!state->my_hostname) { + return -1; + } + p++; + state->my_dnsdomain = strdup(p); + if (!state->my_dnsdomain) { + return -1; + } + } + } + + { + const char *buffer = NULL; + uint16_t type = 0; + status = NetGetJoinInformation(NULL, &buffer, &type); + if (status) { + return status; + } + state->name_buffer_initial = (char *)buffer; + state->name_type_initial = type; + } + + { + struct srvsvc_NetSrvInfo1005 *info1005 = NULL; + uint8_t *buffer = NULL; + + status = NetServerGetInfo(NULL, 1005, &buffer); + if (status) { + return status; + } + + info1005 = (struct srvsvc_NetSrvInfo1005 *)buffer; + + state->comment = strdup(info1005->comment); + if (!state->comment) { + return -1; + } + } +#if 0 + { + struct srvsvc_NetSrvInfo100 *info100 = NULL; + uint8_t *buffer = NULL; + + status = NetServerGetInfo(NULL, 100, &buffer); + if (status) { + return status; + } + + info100 = (struct srvsvc_NetSrvInfo100 *)buffer; + + state->comment = strdup(info100->comment); + if (!state->comment) { + return -1; + } + } +#endif + + state->ctx = ctx; + + return 0; +} + +int main(int argc, char **argv) +{ + GOptionContext *context = NULL; + static const char *debug_level = NULL; + struct join_state *state = NULL; + GError *error = NULL; + int ret = 0; + + static GOptionEntry entries[] = { + { "debug", 'd', 0, G_OPTION_ARG_STRING, &debug_level, "Debug level (for samba)", "N" }, + { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Verbose output", 0 }, + { NULL } + }; + + context = g_option_context_new("- Samba domain join utility"); + g_option_context_add_main_entries(context, entries, NULL); +/* g_option_context_add_main_entries(context, entries, GETTEXT_PACKAGE); */ + g_option_context_add_group(context, gtk_get_option_group(TRUE)); + g_option_context_parse(context, &argc, &argv, &error); + + gtk_init(&argc, &argv); + g_set_application_name("Samba"); + + ret = init_join_state(&state); + if (ret) { + return ret; + } + + ret = initialize_join_state(state, debug_level); + if (ret) { + return ret; + } + + draw_main_window(state); + + gtk_main(); + + do_cleanup(state); + + return 0; +} diff --git a/source3/lib/netapi/examples/netdomjoin/netdomjoin-gui.c b/source3/lib/netapi/examples/netdomjoin/netdomjoin-gui.c deleted file mode 100644 index 8ca6897cab..0000000000 --- a/source3/lib/netapi/examples/netdomjoin/netdomjoin-gui.c +++ /dev/null @@ -1,1347 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * Join Support (gtk + netapi) - * Copyright (C) Guenther Deschner 2007 - * - * 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 3 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, see . - */ - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#define MAX_CRED_LEN 256 -#define MAX_NETBIOS_NAME_LEN 15 - -#define SAMBA_ICON_PATH "/usr/share/pixmaps/samba/samba.ico" -#define SAMBA_IMAGE_PATH "/usr/share/pixmaps/samba/logo.png" - -#define WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED ( 0x00000020 ) -#define WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE ( 0x00000004 ) -#define WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE ( 0x00000002 ) -#define WKSSVC_JOIN_FLAGS_JOIN_TYPE ( 0x00000001 ) - -#define NetSetupWorkgroupName ( 2 ) -#define NetSetupDomainName ( 3 ) - -#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0) - -struct srvsvc_NetSrvInfo1005 { - const char *comment;/* [unique,charset(UTF16)] */ -}; - -static gboolean verbose = FALSE; - -typedef struct join_state { - struct libnetapi_ctx *ctx; - GtkWidget *window_main; - GtkWidget *window_parent; - GtkWidget *window_do_change; - GtkWidget *window_creds_prompt; - GtkWidget *entry_account; - GtkWidget *entry_password; - GtkWidget *entry_domain; - GtkWidget *entry_workgroup; - GtkWidget *button_ok; - GtkWidget *button_apply; - GtkWidget *button_ok_creds; - GtkWidget *label_reboot; - GtkWidget *label_current_name_buffer; - GtkWidget *label_current_name_type; - GtkWidget *label_full_computer_name; - uint16_t name_type_initial; - uint16_t name_type_new; - char *name_buffer_initial; - char *name_buffer_new; - char *password; - char *account; - char *comment; - char *comment_new; - char *my_fqdn; - char *my_dnsdomain; - char *my_hostname; - uint16_t server_role; - gboolean settings_changed; - gboolean hostname_changed; -} join_state; - -static void debug(const char *format, ...) -{ - va_list args; - - if (!verbose) { - return; - } - - va_start(args, format); - g_vprintf(format, args); - va_end(args); -} - -static gboolean callback_delete_event(GtkWidget *widget, - GdkEvent *event, - gpointer data) -{ - gtk_main_quit(); - return FALSE; -} - -static void callback_do_close(GtkWidget *widget, - gpointer data) -{ - debug("Closing now...\n"); - gtk_widget_destroy(data); -} - -static void free_join_state(struct join_state *s) -{ - SAFE_FREE(s->name_buffer_initial); - SAFE_FREE(s->name_buffer_new); - SAFE_FREE(s->password); - SAFE_FREE(s->account); - SAFE_FREE(s->comment); - SAFE_FREE(s->comment_new); - SAFE_FREE(s->my_fqdn); - SAFE_FREE(s->my_dnsdomain); - SAFE_FREE(s->my_hostname); - -} - -static void do_cleanup(struct join_state *state) -{ - libnetapi_free(state->ctx); - free_join_state(state); -} - -static void callback_apply_description_change(GtkWidget *widget, - gpointer data) -{ - struct join_state *state = (struct join_state *)data; - NET_API_STATUS status = 0; - uint32_t parm_err = 0; - struct srvsvc_NetSrvInfo1005 info1005; - GtkWidget *dialog; - - info1005.comment = state->comment_new; - - status = NetServerSetInfo(NULL, 1005, (uint8_t *)&info1005, &parm_err); - if (status) { - debug("NetServerSetInfo failed with: %s\n", - libnetapi_errstr(state->ctx, status)); - dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - "Failed to change computer description: %s.", - libnetapi_errstr(state->ctx, status)); - g_signal_connect_swapped(dialog, "response", - G_CALLBACK(gtk_widget_destroy), - dialog); - - gtk_widget_show(dialog); - return; - } - - gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), FALSE); -} - -static void callback_do_exit(GtkWidget *widget, - gpointer data) -{ - GtkWidget *dialog; - gint result; - struct join_state *state = (struct join_state *)data; - - if (!state->settings_changed) { - callback_delete_event(NULL, NULL, NULL); - return; - } - - dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_YES_NO, - "You must restart your computer before the new settings will take effect."); - result = gtk_dialog_run(GTK_DIALOG(dialog)); - switch (result) { - case GTK_RESPONSE_YES: - g_print("would reboot here\n"); - break; - case GTK_RESPONSE_NO: - default: - break; - } - gtk_widget_destroy(dialog); - gtk_widget_destroy(state->window_main); - do_cleanup(state); - exit(0); -} - - -static void callback_do_reboot(GtkWidget *widget, - gpointer data, - gpointer data2) -{ - GtkWidget *dialog; - struct join_state *state = (struct join_state *)data2; - - debug("callback_do_reboot\n"); - - state->settings_changed = TRUE; - dialog = gtk_message_dialog_new(GTK_WINDOW(data), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_INFO, - GTK_BUTTONS_OK, - "You must restart this computer for the changes to take effect."); -#if 0 - g_signal_connect_swapped(dialog, "response", - G_CALLBACK(gtk_widget_destroy), - dialog); - - debug("showing dialog\n"); - gtk_widget_show(dialog); -#else - gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); -#endif - - gtk_label_set_text(GTK_LABEL(state->label_reboot), "Changes will take effect after you restart this computer"); - - debug("destroying do_change window\n"); - gtk_widget_destroy(GTK_WIDGET(state->window_do_change)); - - { - uint32_t status; - const char *buffer; - uint16_t type; - - status = NetGetJoinInformation(NULL, &buffer, &type); - if (status != 0) { - g_print("failed to query status\n"); - return; - } - - debug("got new status: %s\n", buffer); -#if 0 - SAFE_FREE(state->name_buffer_new); - state->name_buffer_new = strdup(buffer); - SAFE_FREE(buffer); - state->name_type_new = type; -#endif - gtk_label_set_text(GTK_LABEL(state->label_current_name_buffer), state->name_buffer_new); - if (state->name_type_new == 3) { - gtk_label_set_text(GTK_LABEL(state->label_current_name_type), "Domain:"); - } else { - gtk_label_set_text(GTK_LABEL(state->label_current_name_type), "Workgroup:"); - } - } -} - -static void callback_return_username(GtkWidget *widget, - gpointer data) -{ - const gchar *entry_text; - struct join_state *state = (struct join_state *)data; - if (!widget) { - return; - } - entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); - debug("callback_return_username: %s\n", entry_text); - SAFE_FREE(state->account); - state->account = strdup(entry_text); -} - -static void callback_return_username_and_enter(GtkWidget *widget, - gpointer data) -{ - const gchar *entry_text; - struct join_state *state = (struct join_state *)data; - if (!widget) { - return; - } - entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); - debug("callback_return_username: %s\n", entry_text); - SAFE_FREE(state->account); - state->account = strdup(entry_text); - g_signal_emit_by_name(state->button_ok_creds, "clicked"); -} - -static void callback_return_password(GtkWidget *widget, - gpointer data) -{ - const gchar *entry_text; - struct join_state *state = (struct join_state *)data; - if (!widget) { - return; - } - entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); -#ifdef DEBUG_PASSWORD - debug("callback_return_password: %s\n", entry_text); -#else - debug("callback_return_password: (not printed)\n"); -#endif - SAFE_FREE(state->password); - state->password = strdup(entry_text); -} - -static void callback_return_password_and_enter(GtkWidget *widget, - gpointer data) -{ - const gchar *entry_text; - struct join_state *state = (struct join_state *)data; - if (!widget) { - return; - } - entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); -#ifdef DEBUG_PASSWORD - debug("callback_return_password: %s\n", entry_text); -#else - debug("callback_return_password: (not printed)\n"); -#endif - SAFE_FREE(state->password); - state->password = strdup(entry_text); - g_signal_emit_by_name(state->button_ok_creds, "clicked"); -} - -static void callback_do_hostname_change(GtkWidget *widget, - gpointer data) -{ - GtkWidget *dialog; - const char *str = NULL; - - struct join_state *state = (struct join_state *)data; - - switch (state->name_type_initial) { - case NetSetupDomainName: - str = "To be implemented: call NetRenameMachineInDomain\n"; - break; - case NetSetupWorkgroupName: - str = "To be implemented: call SetComputerNameEx\n"; - break; - default: - break; - } - - dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - str); - - g_signal_connect_swapped(dialog, "response", - G_CALLBACK(gtk_widget_destroy), - dialog); - gtk_widget_show(dialog); -} - -static void callback_do_join(GtkWidget *widget, - gpointer data) -{ - GtkWidget *dialog; - - NET_API_STATUS status; - const char *err_str = NULL; - uint32_t join_flags = 0; - uint32_t unjoin_flags = 0; - gboolean domain_join = FALSE; - gboolean try_unjoin = FALSE; - const char *domain_or_workgroup = NULL; - - struct join_state *state = (struct join_state *)data; - - callback_return_username(state->entry_account, state); - callback_return_password(state->entry_password, state); - - if (state->window_creds_prompt) { - gtk_widget_destroy(GTK_WIDGET(state->window_creds_prompt)); - } - - if (state->name_type_new == NetSetupDomainName) { - domain_join = TRUE; - join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE | - WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE | - WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED; /* for testing */ - domain_or_workgroup = "domain"; - } else { - domain_or_workgroup = "workgroup"; - } - - if ((state->name_type_initial == NetSetupDomainName) && - (state->name_type_new == NetSetupWorkgroupName)) { - try_unjoin = TRUE; - unjoin_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE | - WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE; - } - - debug("callback_do_join: Joining a %s named %s using join_flags 0x%08x ", - domain_or_workgroup, - state->name_buffer_new, - join_flags); - if (domain_join) { - debug("as %s ", state->account); -#ifdef DEBUG_PASSWORD - debug("with %s ", state->password); -#endif - } - debug("\n"); - if (try_unjoin) { - - debug("callback_do_join: Unjoining\n"); - - status = NetUnjoinDomain(NULL, - state->account, - state->password, - unjoin_flags); - if (status != 0) { - err_str = libnetapi_errstr(state->ctx, status); - g_print("callback_do_join: failed to unjoin (%s)\n", - err_str); - - dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - "The following error occured attempting to unjoin the %s: \"%s\": %s", - domain_or_workgroup, - state->name_buffer_new, - err_str); - - g_signal_connect_swapped(dialog, "response", - G_CALLBACK(gtk_widget_destroy), - dialog); - - gtk_widget_show(dialog); - - return; - } - - } - status = NetJoinDomain(NULL, - state->name_buffer_new, - NULL, - state->account, - state->password, - join_flags); - if (status != 0) { - err_str = libnetapi_errstr(state->ctx, status); - g_print("callback_do_join: failed to join (%s)\n", err_str); - - dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - "The following error occured attempting to join the %s: \"%s\": %s", - domain_or_workgroup, - state->name_buffer_new, - err_str); - - g_signal_connect_swapped(dialog, "response", - G_CALLBACK(gtk_widget_destroy), - dialog); - - gtk_widget_show(dialog); - - return; - } - - debug("callback_do_join: Successfully joined %s\n", - domain_or_workgroup); - - dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_INFO, - GTK_BUTTONS_OK, - "Welcome to the %s %s.", - state->name_buffer_new, - domain_or_workgroup); - - gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); - - callback_do_reboot(NULL, state->window_parent, state); -} - -static void callback_creds_prompt(GtkWidget *widget, - gpointer data) -{ - GtkWidget *window; - GtkWidget *box1; - GtkWidget *bbox; - GtkWidget *button; - GtkWidget *label; - - struct join_state *state = (struct join_state *)data; - - debug("callback_creds_prompt:\n"); - - state->window_parent = state->window_do_change; - - if (state->hostname_changed) { - return callback_do_hostname_change(NULL, state); - } - - if ((state->name_type_initial != NetSetupDomainName) && - (state->name_type_new != NetSetupDomainName)) { - return callback_do_join(NULL, state); - } - - window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - - gtk_window_set_title(GTK_WINDOW(window), "Computer Name Changes"); - gtk_window_set_resizable(GTK_WINDOW(window), FALSE); - gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); - gtk_widget_set_size_request(GTK_WIDGET(window), 380, 280); - gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL); -/* gtk_window_set_icon_name(GTK_WIDGET(window), GTK_STOCK_DIALOG_AUTHENTICATION); */ - state->window_creds_prompt = window; - - g_signal_connect(G_OBJECT(window), "delete_event", - G_CALLBACK(callback_do_close), window); - - gtk_container_set_border_width(GTK_CONTAINER(window), 10); - - box1 = gtk_vbox_new(FALSE, 0); - - gtk_container_add(GTK_CONTAINER(window), box1); - - if ((state->name_type_initial == NetSetupDomainName) && - (state->name_type_new == NetSetupWorkgroupName)) { - label = gtk_label_new("Enter the name and password of an account with permission to leave the domain.\n"); - } else { - label = gtk_label_new("Enter the name and password of an account with permission to join the domain.\n"); - } - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); - - gtk_box_pack_start(GTK_BOX(box1), label, FALSE, FALSE, 0); - - gtk_widget_show(label); - - /* USER NAME */ - label = gtk_label_new("User name:"); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_box_pack_start(GTK_BOX(box1), label, FALSE, FALSE, 0); - gtk_widget_show(label); - - state->entry_account = gtk_entry_new(); - gtk_entry_set_max_length(GTK_ENTRY(state->entry_account), MAX_CRED_LEN); - g_signal_connect(G_OBJECT(state->entry_account), "activate", - G_CALLBACK(callback_return_username_and_enter), - (gpointer)state); - gtk_editable_select_region(GTK_EDITABLE(state->entry_account), - 0, GTK_ENTRY(state->entry_account)->text_length); - gtk_box_pack_start(GTK_BOX(box1), state->entry_account, TRUE, TRUE, 0); - gtk_widget_show(state->entry_account); - - /* PASSWORD */ - label = gtk_label_new("Password:"); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_box_pack_start(GTK_BOX(box1), label, FALSE, FALSE, 0); - gtk_widget_show(label); - - state->entry_password = gtk_entry_new(); - gtk_entry_set_max_length(GTK_ENTRY(state->entry_password), MAX_CRED_LEN); - gtk_entry_set_visibility(GTK_ENTRY(state->entry_password), FALSE); - g_signal_connect(G_OBJECT(state->entry_password), "activate", - G_CALLBACK(callback_return_password_and_enter), - (gpointer)state); - gtk_editable_set_editable(GTK_EDITABLE(state->entry_password), TRUE); - gtk_editable_select_region(GTK_EDITABLE(state->entry_password), - 0, GTK_ENTRY(state->entry_password)->text_length); - gtk_box_pack_start(GTK_BOX(box1), state->entry_password, TRUE, TRUE, 0); - gtk_widget_show(state->entry_password); - - bbox = gtk_hbutton_box_new(); - gtk_container_set_border_width(GTK_CONTAINER(bbox), 5); - gtk_container_add(GTK_CONTAINER(box1), bbox); - gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); - gtk_box_set_spacing(GTK_BOX(bbox), 10); - - state->button_ok_creds = gtk_button_new_from_stock(GTK_STOCK_OK); - gtk_widget_grab_focus(GTK_WIDGET(state->button_ok_creds)); - gtk_container_add(GTK_CONTAINER(bbox), state->button_ok_creds); - g_signal_connect(G_OBJECT(state->button_ok_creds), "clicked", - G_CALLBACK(callback_do_join), - (gpointer)state); - gtk_widget_show(state->button_ok_creds); - - button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); - gtk_container_add(GTK_CONTAINER(bbox), button); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(callback_do_close), (gpointer) window); - gtk_widget_show_all(window); -} - -static void callback_enter_hostname_and_unlock(GtkWidget *widget, - gpointer data) -{ - const gchar *entry_text = NULL; - char *str = NULL; - struct join_state *state = (struct join_state *)data; - - entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); - debug("callback_enter_hostname_and_unlock: %s\n", entry_text); - if (!entry_text || entry_text[0] == 0) { - state->hostname_changed = FALSE; - gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); - return; - } - if (strcasecmp(state->my_hostname, entry_text) == 0) { - state->hostname_changed = FALSE; - gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); - return; - } - state->hostname_changed = TRUE; - if (state->name_type_initial == NetSetupDomainName) { - asprintf(&str, "%s.%s", entry_text, state->my_dnsdomain); - } else { - asprintf(&str, "%s.", entry_text); - } - gtk_label_set_text(GTK_LABEL(state->label_full_computer_name), str); - free(str); - - if (state->hostname_changed && str && str[0] != 0 && str[0] != '.') { - gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), TRUE); - } -} - -static void callback_enter_computer_description_and_unlock(GtkWidget *widget, - gpointer data) -{ - const gchar *entry_text = NULL; - struct join_state *state = (struct join_state *)data; - int string_unchanged = 0; - - entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); - debug("callback_enter_computer_description_and_unlock: %s\n", - entry_text); -#if 0 - if (!entry_text || entry_text[0] == 0) { - string_unchanged = 1; - gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), - FALSE); - return; - } -#endif - if (entry_text && strcasecmp(state->comment, entry_text) == 0) { - string_unchanged = 1; - gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), - FALSE); - return; - } - - gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), TRUE); - SAFE_FREE(state->comment_new); - state->comment_new = strdup(entry_text); - -} - - -static void callback_enter_workgroup_and_unlock(GtkWidget *widget, - gpointer data) -{ - const gchar *entry_text = NULL; - struct join_state *state = (struct join_state *)data; - - entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); - debug("callback_enter_workgroup_and_unlock: %s\n", entry_text); - if (!entry_text || entry_text[0] == 0) { - gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); - return; - } - if (strcasecmp(state->name_buffer_initial, entry_text) == 0) { - gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); - return; - } - gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), TRUE); - SAFE_FREE(state->name_buffer_new); - state->name_buffer_new = strdup(entry_text); - state->name_type_new = NetSetupWorkgroupName; -} - -static void callback_enter_domain_and_unlock(GtkWidget *widget, - gpointer data) -{ - const gchar *entry_text = NULL; - struct join_state *state = (struct join_state *)data; - - entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); - debug("callback_enter_domain_and_unlock: %s\n", entry_text); - if (!entry_text || entry_text[0] == 0) { - gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); - return; - } - if (strcasecmp(state->name_buffer_initial, entry_text) == 0) { - gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); - return; - } - gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), TRUE); - SAFE_FREE(state->name_buffer_new); - state->name_buffer_new = strdup(entry_text); - state->name_type_new = NetSetupDomainName; -} - -static void callback_continue(GtkWidget *widget, - gpointer data) -{ - struct join_state *state = (struct join_state *)data; - - gtk_widget_grab_focus(GTK_WIDGET(state->button_ok)); - g_signal_emit_by_name(state->button_ok, "clicked"); -} - -static void callback_apply_continue(GtkWidget *widget, - gpointer data) -{ - struct join_state *state = (struct join_state *)data; - - gtk_widget_grab_focus(GTK_WIDGET(state->button_apply)); - g_signal_emit_by_name(state->button_apply, "clicked"); -} - -static void callback_do_join_workgroup(GtkWidget *widget, - gpointer data) -{ - struct join_state *state = (struct join_state *)data; - debug("callback_do_join_workgroup choosen\n"); - gtk_widget_set_sensitive(GTK_WIDGET(state->entry_workgroup), TRUE); - gtk_widget_grab_focus(GTK_WIDGET(state->entry_workgroup)); - gtk_widget_set_sensitive(GTK_WIDGET(state->entry_domain), FALSE); - callback_enter_workgroup_and_unlock(state->entry_workgroup, state); /* TEST */ -} - -static void callback_do_join_domain(GtkWidget *widget, - gpointer data) -{ - struct join_state *state = (struct join_state *)data; - debug("callback_do_join_domain choosen\n"); - gtk_widget_set_sensitive(GTK_WIDGET(state->entry_domain), TRUE); - gtk_widget_grab_focus(GTK_WIDGET(state->entry_domain)); - gtk_widget_set_sensitive(GTK_WIDGET(state->entry_workgroup), FALSE); - callback_enter_domain_and_unlock(state->entry_domain, state); /* TEST */ -} - -static void callback_do_change(GtkWidget *widget, - gpointer data) -{ - GtkWidget *window; - GtkWidget *box1; - GtkWidget *bbox; - GtkWidget *button_workgroup; - GtkWidget *button_domain; - GtkWidget *button; - GtkWidget *label; - GtkWidget *frame_horz; - GtkWidget *vbox; - GtkWidget *entry; - GSList *group; - - struct join_state *state = (struct join_state *)data; - - debug("callback_do_change called\n"); - - if (state->server_role == 3) { - GtkWidget *dialog; - dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - "Domain controller cannot be moved from one domain to another, they must first be demoted. Renaming this domain controller may cause it to become temporarily unavailable to users and computers. For information on renaming domain controllers, including alternate renaming methods, see Help and Support. To continue renaming this domain controller, click OK."); - g_signal_connect_swapped(dialog, "response", - G_CALLBACK(gtk_widget_destroy), - dialog); - - gtk_widget_show(dialog); - return; - } - - state->button_ok = gtk_button_new_from_stock(GTK_STOCK_OK); - window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - - gtk_window_set_title(GTK_WINDOW(window), "Computer Name Changes"); - gtk_window_set_resizable(GTK_WINDOW(window), FALSE); - gtk_widget_set_size_request(GTK_WIDGET(window), 480, 500); /* breite * höhe */ - gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL); - - g_signal_connect(G_OBJECT(window), "delete_event", - G_CALLBACK(callback_do_close), window); - - gtk_container_set_border_width(GTK_CONTAINER(window), 10); - - box1 = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(window), box1); - - label = gtk_label_new("You can change the name and membership of this computer. Changes may affect access to network ressources."); - gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_box_pack_start(GTK_BOX(box1), label, TRUE, TRUE, 0); - gtk_widget_show(label); - - /* COMPUTER NAME */ - label = gtk_label_new("Computer name:"); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_box_pack_start(GTK_BOX(box1), label, TRUE, TRUE, 0); - gtk_widget_show(label); - - state->label_full_computer_name = gtk_label_new(NULL); - { - entry = gtk_entry_new(); - gtk_entry_set_max_length(GTK_ENTRY(entry), MAX_NETBIOS_NAME_LEN); - g_signal_connect(G_OBJECT(entry), "changed", - G_CALLBACK(callback_enter_hostname_and_unlock), - (gpointer)state); - gtk_entry_set_text(GTK_ENTRY(entry), state->my_hostname); - gtk_editable_select_region(GTK_EDITABLE(entry), - 0, GTK_ENTRY(entry)->text_length); - - gtk_editable_set_editable(GTK_EDITABLE(entry), TRUE); /* ! */ - gtk_box_pack_start(GTK_BOX(box1), entry, TRUE, TRUE, 0); - gtk_widget_show(entry); - } - - /* FULL COMPUTER NAME */ - label = gtk_label_new("Full computer name:"); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_box_pack_start(GTK_BOX(box1), label, TRUE, TRUE, 0); - gtk_widget_show(label); - - { - const gchar *entry_text; - char *str = NULL; - entry_text = gtk_entry_get_text(GTK_ENTRY(entry)); - if (state->name_type_initial == NetSetupDomainName) { - asprintf(&str, "%s.%s", entry_text, state->my_dnsdomain); - } else { - asprintf(&str, "%s.", entry_text); - } - gtk_label_set_text(GTK_LABEL(state->label_full_computer_name), str); - free(str); - gtk_misc_set_alignment(GTK_MISC(state->label_full_computer_name), 0, 0); - gtk_box_pack_start(GTK_BOX(box1), state->label_full_computer_name, TRUE, TRUE, 0); - gtk_widget_show(state->label_full_computer_name); - } - - /* BOX */ - frame_horz = gtk_frame_new ("Member Of"); - gtk_box_pack_start(GTK_BOX(box1), frame_horz, TRUE, TRUE, 10); - - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 10); - gtk_container_add(GTK_CONTAINER(frame_horz), vbox); - - /* TWO ENTRIES */ - state->entry_workgroup = gtk_entry_new(); - state->entry_domain = gtk_entry_new(); - - /* DOMAIN */ - button_domain = gtk_radio_button_new_with_label(NULL, "Domain"); - if (state->name_type_initial == NetSetupDomainName) { - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_domain), TRUE); - } - gtk_box_pack_start(GTK_BOX(vbox), button_domain, TRUE, TRUE, 0); - g_signal_connect(G_OBJECT(button_domain), "clicked", - G_CALLBACK(callback_do_join_domain), - (gpointer)state); - - { - gtk_entry_set_max_length(GTK_ENTRY(state->entry_domain), 50); - g_signal_connect(G_OBJECT(state->entry_domain), "changed", - G_CALLBACK(callback_enter_domain_and_unlock), - (gpointer)state); - g_signal_connect(G_OBJECT(state->entry_domain), "activate", - G_CALLBACK(callback_continue), - (gpointer)state); - if (state->name_type_initial == NetSetupDomainName) { - gtk_entry_set_text(GTK_ENTRY(state->entry_domain), state->name_buffer_initial); - gtk_widget_set_sensitive(state->entry_workgroup, FALSE); - gtk_widget_set_sensitive(state->entry_domain, TRUE); - } - gtk_editable_set_editable(GTK_EDITABLE(state->entry_domain), TRUE); - gtk_box_pack_start(GTK_BOX(vbox), state->entry_domain, TRUE, TRUE, 0); - gtk_widget_show(state->entry_domain); - } - gtk_widget_show(button_domain); - - /* WORKGROUP */ - group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button_domain)); - button_workgroup = gtk_radio_button_new_with_label(group, "Workgroup"); - if (state->name_type_initial == NetSetupWorkgroupName) { - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_workgroup), TRUE); - } - gtk_box_pack_start(GTK_BOX(vbox), button_workgroup, TRUE, TRUE, 0); - g_signal_connect(G_OBJECT(button_workgroup), "clicked", - G_CALLBACK(callback_do_join_workgroup), - (gpointer)state); - { - gtk_entry_set_max_length(GTK_ENTRY(state->entry_workgroup), MAX_NETBIOS_NAME_LEN); - g_signal_connect(G_OBJECT(state->entry_workgroup), "changed", - G_CALLBACK(callback_enter_workgroup_and_unlock), - (gpointer)state); - g_signal_connect(G_OBJECT(state->entry_workgroup), "activate", - G_CALLBACK(callback_continue), - (gpointer)state); - - if (state->name_type_initial == NetSetupWorkgroupName) { - gtk_entry_set_text(GTK_ENTRY(state->entry_workgroup), state->name_buffer_initial); - gtk_widget_set_sensitive(GTK_WIDGET(state->entry_domain), FALSE); - gtk_widget_set_sensitive(GTK_WIDGET(state->entry_workgroup), TRUE); - } - gtk_box_pack_start(GTK_BOX(vbox), state->entry_workgroup, TRUE, TRUE, 0); - gtk_widget_show(state->entry_workgroup); - } - gtk_widget_show(button_workgroup); - - /* BUTTONS */ - bbox = gtk_hbutton_box_new(); - gtk_container_set_border_width(GTK_CONTAINER(bbox), 5); - gtk_container_add(GTK_CONTAINER(box1), bbox); - gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); - gtk_box_set_spacing(GTK_BOX(bbox), 10); - - state->window_do_change = window; - gtk_widget_set_sensitive(GTK_WIDGET(state->button_ok), FALSE); /* !!! */ - gtk_container_add(GTK_CONTAINER(bbox), state->button_ok); - g_signal_connect(G_OBJECT(state->button_ok), "clicked", - G_CALLBACK(callback_creds_prompt), - (gpointer)state); - - button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); - gtk_container_add(GTK_CONTAINER(bbox), button); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(callback_do_close), - (gpointer)window); - - gtk_widget_show_all(window); - -} - -static void callback_do_about(GtkWidget *widget, - gpointer data) -{ - GdkPixbuf *logo; - GError *error = NULL; - - debug("callback_do_about called\n"); - - logo = gdk_pixbuf_new_from_file(SAMBA_IMAGE_PATH, - &error); - if (logo == NULL) { - g_print("failed to load logo from %s: %s\n", - SAMBA_IMAGE_PATH, error->message); - } - - gtk_show_about_dialog(data, - "name", "Samba", - "version", "3.2.0pre2-GIT-904a90-test", - "copyright", "Copyright Andrew Tridgell and the Samba Team 1992-2007", - "website", "http://www.samba.org", - "license", "GPLv3", - "logo", logo, - "comments", "Samba gtk domain join utility", - NULL); -} - -static int draw_main_window(struct join_state *state) -{ - GtkWidget *window; - GtkWidget *button; - GtkWidget *label; - GtkWidget *main_vbox; - GtkWidget *vbox; - GtkWidget *hbox; - GtkWidget *bbox; - GtkWidget *image; - GtkWidget *table; - GtkWidget *entry; - GdkPixbuf *icon; - GError *error = NULL; - - icon = gdk_pixbuf_new_from_file(SAMBA_ICON_PATH, - &error); - if (icon == NULL) { - g_print("failed to load logo from %s : %s\n", - SAMBA_ICON_PATH, error->message); - } - -#if 1 - image = gtk_image_new_from_file(SAMBA_IMAGE_PATH); -#else - image = gtk_image_new_from_file("/usr/share/pixmaps/redhat-system_settings.png"); -#endif - - window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - state->window_main = window; - - gtk_window_set_title(GTK_WINDOW(window), "Samba - Join Domain dialogue"); - gtk_widget_set_size_request(GTK_WIDGET(window), 600, 600); /* breite * höhe */ - gtk_window_set_resizable(GTK_WINDOW(window), FALSE); - gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL); - - g_signal_connect(G_OBJECT(window), "delete_event", - G_CALLBACK(callback_delete_event), NULL); - - gtk_container_set_border_width(GTK_CONTAINER(window), 10); - - main_vbox = gtk_vbox_new(FALSE, 10); - gtk_container_add(GTK_CONTAINER(window), main_vbox); - -#if 0 - gtk_box_pack_start(GTK_BOX(main_vbox), image, TRUE, TRUE, 10); - gtk_widget_show(image); -#endif - /* Hbox */ - hbox = gtk_hbox_new(FALSE, 10); - gtk_container_add(GTK_CONTAINER(main_vbox), hbox); - - { -/* gtk_box_pack_start(GTK_BOX(main_vbox), image, TRUE, TRUE, 10); */ - gtk_misc_set_alignment(GTK_MISC(image), 0, 0); - gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 10); - gtk_widget_show(image); - - /* Label */ - label = gtk_label_new("Samba uses the following information to identify your computer on the network."); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_widget_set_size_request(GTK_WIDGET(label), 500, 40); - gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); - gtk_widget_show(label); - } - - gtk_widget_show(hbox); - - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 10); - gtk_container_add(GTK_CONTAINER(main_vbox), vbox); - - /* Table */ - table = gtk_table_new(6, 3, TRUE); - gtk_table_set_row_spacings(GTK_TABLE(table), 5); - gtk_table_set_col_spacings(GTK_TABLE(table), 5); - gtk_container_add(GTK_CONTAINER(vbox), table); - - { - /* Label */ - label = gtk_label_new("Computer description:"); -/* gtk_misc_set_alignment(GTK_MISC(label), 0, 0); */ - gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1); - gtk_widget_show(label); - - state->button_apply = gtk_button_new_from_stock(GTK_STOCK_APPLY); - - /* Entry */ - entry = gtk_entry_new(); - gtk_entry_set_max_length(GTK_ENTRY(entry), 256); - g_signal_connect(G_OBJECT(entry), "changed", - G_CALLBACK(callback_enter_computer_description_and_unlock), - state); - g_signal_connect(G_OBJECT(entry), "activate", - G_CALLBACK(callback_apply_continue), - (gpointer)state); - - gtk_entry_set_text(GTK_ENTRY(entry), (char *)state->comment); - gtk_editable_set_editable(GTK_EDITABLE(entry), TRUE); /* ! */ - gtk_table_attach_defaults(GTK_TABLE(table), entry, 1, 3, 0, 1); - gtk_widget_show(entry); - } - - /* Label */ - label = gtk_label_new("For example: \"Samba \%v\"."); - gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 3, 1, 2); - gtk_widget_show(label); - - /* Label */ - label = gtk_label_new("Full computer name:"); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3); - gtk_widget_show(label); - - { - /* Label */ - char *str = NULL; - if (state->name_type_initial == NetSetupDomainName) { - asprintf(&str, "%s.%s", state->my_hostname, - state->my_dnsdomain); - } else { - asprintf(&str, "%s.", state->my_hostname); - } - - label = gtk_label_new(str); - SAFE_FREE(str); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 3, 2, 3); - gtk_widget_show(label); - } - - /* Label */ - if (state->name_type_initial == NetSetupDomainName) { - label = gtk_label_new("Domain:"); - } else { - label = gtk_label_new("Workgroup:"); - } - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 3, 4); - gtk_widget_show(label); - state->label_current_name_type = label; - - /* Label */ - label = gtk_label_new(state->name_buffer_initial); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 3, 3, 4); - gtk_widget_show(label); - state->label_current_name_buffer = label; - - { - hbox = gtk_hbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(vbox), hbox); - label = gtk_label_new("To rename this computer or join a domain, click Change."); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); - - - } - - /* bbox */ - bbox = gtk_hbutton_box_new(); - gtk_container_set_border_width(GTK_CONTAINER(bbox), 5); - gtk_container_add(GTK_CONTAINER(hbox), bbox); - gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); - gtk_box_set_spacing(GTK_BOX(bbox), 10); - - button = gtk_button_new_with_mnemonic("Ch_ange"); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(callback_do_change), - (gpointer)state); - gtk_box_pack_start(GTK_BOX(bbox), button, TRUE, TRUE, 0); - gtk_widget_show(button); - - /* Label (hidden) */ - state->label_reboot = gtk_label_new(NULL); - gtk_label_set_line_wrap(GTK_LABEL(state->label_reboot), TRUE); - gtk_misc_set_alignment(GTK_MISC(state->label_reboot), 0, 0); - gtk_box_pack_start(GTK_BOX(vbox), state->label_reboot, TRUE, TRUE, 0); - gtk_widget_show(state->label_reboot); - -#if 0 - gtk_box_pack_start(GTK_BOX(vbox), - create_bbox(window, TRUE, NULL, 10, 85, 20, GTK_BUTTONBOX_END), - TRUE, TRUE, 5); -#endif - { - - GtkWidget *frame; - GtkWidget *bbox2; - GtkWidget *button2; - - frame = gtk_frame_new(NULL); - bbox2 = gtk_hbutton_box_new(); - - gtk_container_set_border_width(GTK_CONTAINER(bbox2), 5); - gtk_container_add(GTK_CONTAINER(frame), bbox2); - - /* Set the appearance of the Button Box */ - gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox2), GTK_BUTTONBOX_END); - gtk_box_set_spacing(GTK_BOX(bbox2), 10); - /*gtk_button_box_set_child_size(GTK_BUTTON_BOX(bbox2), child_w, child_h);*/ - - button2 = gtk_button_new_from_stock(GTK_STOCK_OK); - gtk_container_add(GTK_CONTAINER(bbox2), button2); - g_signal_connect(G_OBJECT(button2), "clicked", G_CALLBACK(callback_do_exit), state); - - button2 = gtk_button_new_from_stock(GTK_STOCK_CANCEL); - gtk_container_add(GTK_CONTAINER(bbox2), button2); - g_signal_connect(G_OBJECT(button2), "clicked", - G_CALLBACK(callback_delete_event), - window); - - gtk_container_add(GTK_CONTAINER(bbox2), state->button_apply); - g_signal_connect(G_OBJECT(state->button_apply), "clicked", - G_CALLBACK(callback_apply_description_change), - state); - gtk_widget_set_sensitive(GTK_WIDGET(state->button_apply), FALSE); - - button2 = gtk_button_new_from_stock(GTK_STOCK_ABOUT); - gtk_container_add(GTK_CONTAINER(bbox2), button2); - g_signal_connect(G_OBJECT(button2), "clicked", - G_CALLBACK(callback_do_about), - window); - - gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 5); - } - - gtk_widget_show_all(window); - - return 0; -} - -static int init_join_state(struct join_state **state) -{ - struct join_state *s; - - s = malloc(sizeof(struct join_state)); - if (!s) { - return -1; - } - - memset(s, '\0', sizeof(struct join_state)); - - *state = s; - - return 0; -} - -static int initialize_join_state(struct join_state *state, - const char *debug_level) -{ - struct libnetapi_ctx *ctx = NULL; - NET_API_STATUS status = 0; - - status = libnetapi_init(&ctx); - if (status) { - return status; - } - - if (debug_level) { - libnetapi_set_debuglevel(ctx, debug_level); - } - - { - char my_hostname[HOST_NAME_MAX]; - const char *p = NULL; - if (gethostname(my_hostname, sizeof(my_hostname)) == -1) { - return -1; - } - - state->my_fqdn = strdup(my_hostname); - if (!state->my_fqdn) { - return -1; - } - - p = strchr(my_hostname, '.'); - if (p) { - my_hostname[strlen(my_hostname) - strlen(p)] = '\0'; - state->my_hostname = strdup(my_hostname); - if (!state->my_hostname) { - return -1; - } - p++; - state->my_dnsdomain = strdup(p); - if (!state->my_dnsdomain) { - return -1; - } - } - } - - { - const char *buffer = NULL; - uint16_t type = 0; - status = NetGetJoinInformation(NULL, &buffer, &type); - if (status) { - return status; - } - state->name_buffer_initial = (char *)buffer; - state->name_type_initial = type; - } - - { - struct srvsvc_NetSrvInfo1005 *info1005 = NULL; - uint8_t *buffer = NULL; - - status = NetServerGetInfo(NULL, 1005, &buffer); - if (status) { - return status; - } - - info1005 = (struct srvsvc_NetSrvInfo1005 *)buffer; - - state->comment = strdup(info1005->comment); - if (!state->comment) { - return -1; - } - } -#if 0 - { - struct srvsvc_NetSrvInfo100 *info100 = NULL; - uint8_t *buffer = NULL; - - status = NetServerGetInfo(NULL, 100, &buffer); - if (status) { - return status; - } - - info100 = (struct srvsvc_NetSrvInfo100 *)buffer; - - state->comment = strdup(info100->comment); - if (!state->comment) { - return -1; - } - } -#endif - - state->ctx = ctx; - - return 0; -} - -int main(int argc, char **argv) -{ - GOptionContext *context = NULL; - static const char *debug_level = NULL; - struct join_state *state = NULL; - GError *error = NULL; - int ret = 0; - - static GOptionEntry entries[] = { - { "debug", 'd', 0, G_OPTION_ARG_STRING, &debug_level, "Debug level (for samba)", "N" }, - { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Verbose output", 0 }, - { NULL } - }; - - context = g_option_context_new("- Samba domain join utility"); - g_option_context_add_main_entries(context, entries, NULL); -/* g_option_context_add_main_entries(context, entries, GETTEXT_PACKAGE); */ - g_option_context_add_group(context, gtk_get_option_group(TRUE)); - g_option_context_parse(context, &argc, &argv, &error); - - gtk_init(&argc, &argv); - g_set_application_name("Samba"); - - ret = init_join_state(&state); - if (ret) { - return ret; - } - - ret = initialize_join_state(state, debug_level); - if (ret) { - return ret; - } - - draw_main_window(state); - - gtk_main(); - - do_cleanup(state); - - return 0; -} -- cgit From 59ce7650f24eb7c35b8d3ee9f830711a4af8f8e9 Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Fri, 21 Dec 2007 11:59:56 -0600 Subject: De-couple smbd from staticly linking against winbindd client files. Implements a wrapper layer in winbind_util.c which are just stubs if compiled --without-winbind. When building with winbindd, it is now required to build the libwbclient DSO first (in the Makefile) and then either set LD_LIBRARY_PATH or /etc/ld.so.conf to pick up the library PATH. (This used to be commit 42787bccff4fcffafc7aae6a678e792604ecaaa5) --- source3/lib/winbind_util.c | 325 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 325 insertions(+) create mode 100644 source3/lib/winbind_util.c (limited to 'source3/lib') diff --git a/source3/lib/winbind_util.c b/source3/lib/winbind_util.c new file mode 100644 index 0000000000..4983b9ced0 --- /dev/null +++ b/source3/lib/winbind_util.c @@ -0,0 +1,325 @@ +/* + Unix SMB/CIFS implementation. + Winbind Utility functions + + Copyright (C) Gerald (Jerry) Carter 2007 + + 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 3 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, see . +*/ + +#include "includes.h" + +#if defined(WITH_WINBIND) + +#include "nsswitch/libwbclient/wbclient.h" + +/* Call winbindd to convert a name to a sid */ + +bool winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid, + enum lsa_SidType *name_type) +{ + struct wbcDomainSid dom_sid; + wbcErr result; + enum wbcSidType type; + + result = wbcLookupName(dom_name, name, &dom_sid, &type); + if (result != WBC_ERR_SUCCESS) + return False; + + memcpy(sid, &dom_sid, sizeof(DOM_SID)); + *name_type = (enum lsa_SidType)type; + + return True; +} + +/* Call winbindd to convert sid to name */ + +bool winbind_lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid, + const char **domain, const char **name, + enum lsa_SidType *name_type) +{ + struct wbcDomainSid dom_sid; + wbcErr result; + enum wbcSidType type; + char *domain_name = NULL; + char *account_name = NULL; + + memcpy(&dom_sid, sid, sizeof(dom_sid)); + + result = wbcLookupSid(&dom_sid, &domain_name, &account_name, &type); + if (result != WBC_ERR_SUCCESS) + return False; + + /* Copy out result */ + + if (domain) { + *domain = talloc_strdup(mem_ctx, domain_name); + } + if (name) { + *name = talloc_strdup(mem_ctx, account_name); + } + *name_type = (enum lsa_SidType)type; + + DEBUG(10, ("winbind_lookup_sid: SUCCESS: SID %s -> %s %s\n", + sid_string_dbg(sid), domain_name, account_name)); + + SAFE_FREE(domain_name); + SAFE_FREE(account_name); + + if ((domain && !*domain) || (name && !*name)) { + DEBUG(0,("winbind_lookup_sid: talloc() failed!\n")); + return False; + } + + + return True; +} + +/* Ping winbindd to see it is alive */ + +bool winbind_ping(void) +{ + wbcErr result = wbcPing(); + + return (result == WBC_ERR_SUCCESS); +} + +/* Call winbindd to convert SID to uid */ + +bool winbind_sid_to_uid(uid_t *puid, const DOM_SID *sid) +{ + struct wbcDomainSid dom_sid; + wbcErr result; + + memcpy(&dom_sid, sid, sizeof(dom_sid)); + + result = wbcSidToUid(&dom_sid, puid); + if (result != WBC_ERR_SUCCESS) + return False; + + return (result == WBC_ERR_SUCCESS); +} + +/* Call winbindd to convert uid to sid */ + +bool winbind_uid_to_sid(DOM_SID *sid, uid_t uid) +{ + struct wbcDomainSid dom_sid; + wbcErr result; + + result = wbcUidToSid(uid, &dom_sid); + if (result == WBC_ERR_SUCCESS) { + memcpy(sid, &dom_sid, sizeof(DOM_SID)); + } else { + sid_copy(sid, &global_sid_NULL); + } + + return (result == WBC_ERR_SUCCESS); +} + +/* Call winbindd to convert SID to gid */ + +bool winbind_sid_to_gid(gid_t *pgid, const DOM_SID *sid) +{ + struct wbcDomainSid dom_sid; + wbcErr result; + + memcpy(&dom_sid, sid, sizeof(dom_sid)); + + result = wbcSidToGid(&dom_sid, pgid); + if (result != WBC_ERR_SUCCESS) + return False; + + return (result == WBC_ERR_SUCCESS); +} + +/* Call winbindd to convert gid to sid */ + +bool winbind_gid_to_sid(DOM_SID *sid, gid_t gid) +{ + struct wbcDomainSid dom_sid; + wbcErr result; + + result = wbcGidToSid(gid, &dom_sid); + if (result == WBC_ERR_SUCCESS) { + memcpy(sid, &dom_sid, sizeof(DOM_SID)); + } else { + sid_copy(sid, &global_sid_NULL); + } + + return (result == WBC_ERR_SUCCESS); +} + +/* Check for a trusted domain */ + +wbcErr wb_is_trusted_domain(const char *domain) +{ + wbcErr result; + struct wbcDomainInfo info; + + result = wbcDomainInfo(domain, &info); + + if (result == WBC_ERR_SUCCESS) { + SAFE_FREE(info.short_name); + SAFE_FREE(info.dns_name); + } + + return result; +} + +/* Lookup a set of rids in a given domain */ + +bool winbind_lookup_rids(TALLOC_CTX *mem_ctx, + const DOM_SID *domain_sid, + int num_rids, uint32 *rids, + const char **domain_name, + const char ***names, enum lsa_SidType **types) +{ + const char *dom_name = NULL; + const char **namelist = NULL; + enum wbcSidType *name_types = NULL; + struct wbcDomainSid dom_sid; + wbcErr ret; + int i; + + memcpy(&dom_sid, domain_sid, sizeof(struct wbcDomainSid)); + + ret = wbcLookupRids(&dom_sid, num_rids, rids, + &dom_name, &namelist, &name_types); + if (ret != WBC_ERR_SUCCESS) + return False; + + *domain_name = talloc_strdup(mem_ctx, dom_name); + *names = TALLOC_ARRAY(mem_ctx, const char*, num_rids); + *types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_rids); + + for(i=0; i Date: Fri, 21 Dec 2007 13:47:45 -0600 Subject: Compile fix: Correct use of wbcDomainInfo() after function signature change. Also fixes a doxygen warngin about an undocumented parameter in the same function. (This used to be commit 290ab64e9e5fb2a28e14a5f344f22119d5304563) --- source3/lib/winbind_util.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/winbind_util.c b/source3/lib/winbind_util.c index 4983b9ced0..f4e7ab19e8 100644 --- a/source3/lib/winbind_util.c +++ b/source3/lib/winbind_util.c @@ -166,13 +166,12 @@ bool winbind_gid_to_sid(DOM_SID *sid, gid_t gid) wbcErr wb_is_trusted_domain(const char *domain) { wbcErr result; - struct wbcDomainInfo info; + struct wbcDomainInfo *info = NULL; result = wbcDomainInfo(domain, &info); - if (result == WBC_ERR_SUCCESS) { - SAFE_FREE(info.short_name); - SAFE_FREE(info.dns_name); + if (WBC_ERROR_IS_OK(result)) { + wbcFreeMemory(info); } return result; -- cgit From 0c3f431abaf2f33e11f74cbc868b5e1da255bfff Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 21 Dec 2007 12:11:23 -0800 Subject: Fix initialization warnings. Jeremy. (This used to be commit 832c093830cb3978641be3d87670fa900105da25) --- source3/lib/socket_wrapper/socket_wrapper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/socket_wrapper/socket_wrapper.c b/source3/lib/socket_wrapper/socket_wrapper.c index a84c460114..5b8052e5ed 100644 --- a/source3/lib/socket_wrapper/socket_wrapper.c +++ b/source3/lib/socket_wrapper/socket_wrapper.c @@ -572,7 +572,7 @@ static const char *socket_wrapper_pcap_file(void) static int initialized = 0; static const char *s = NULL; static const struct swrap_file_hdr h = { 0, }; - static const struct swrap_packet p = { 0, }; + static const struct swrap_packet p = { { 0, }, { { 0, }, { { 0, } } } }; if (initialized == 1) { return s; -- cgit From 86dfb55ffb99abf6fc61a91e58477790395abe38 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 22 Dec 2007 00:02:45 +0100 Subject: Correct netapi header filename. Thanks Jeremy. Guenther (This used to be commit f192737ec8140aa6570bfb49a165b31890d63b16) --- source3/lib/netapi/examples/getdc/getdc.c | 2 +- source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c | 2 +- source3/lib/netapi/examples/netdomjoin/netdomjoin.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/examples/getdc/getdc.c b/source3/lib/netapi/examples/getdc/getdc.c index ed6a8bd05d..4f5c5332d5 100644 --- a/source3/lib/netapi/examples/getdc/getdc.c +++ b/source3/lib/netapi/examples/getdc/getdc.c @@ -23,7 +23,7 @@ #include #include -#include +#include int main(int argc, char **argv) { diff --git a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c index 8ca6897cab..beb12be8b1 100644 --- a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c +++ b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c @@ -28,7 +28,7 @@ #include #include -#include +#include #define MAX_CRED_LEN 256 #define MAX_NETBIOS_NAME_LEN 15 diff --git a/source3/lib/netapi/examples/netdomjoin/netdomjoin.c b/source3/lib/netapi/examples/netdomjoin/netdomjoin.c index a2bb700250..e8b529927f 100644 --- a/source3/lib/netapi/examples/netdomjoin/netdomjoin.c +++ b/source3/lib/netapi/examples/netdomjoin/netdomjoin.c @@ -23,7 +23,7 @@ #include #include -#include +#include char *get_string_param(const char *param) { -- cgit From 9cd009b031a7cc076bb3cbb945c4ec528ea731a1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 23 Dec 2007 00:32:09 +0100 Subject: tiny simplification (This used to be commit 8bd248456205a82d57af21559a77a1030f4679b7) --- source3/lib/winbind_util.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/winbind_util.c b/source3/lib/winbind_util.c index f4e7ab19e8..f51a0171a2 100644 --- a/source3/lib/winbind_util.c +++ b/source3/lib/winbind_util.c @@ -105,8 +105,6 @@ bool winbind_sid_to_uid(uid_t *puid, const DOM_SID *sid) memcpy(&dom_sid, sid, sizeof(dom_sid)); result = wbcSidToUid(&dom_sid, puid); - if (result != WBC_ERR_SUCCESS) - return False; return (result == WBC_ERR_SUCCESS); } @@ -138,8 +136,6 @@ bool winbind_sid_to_gid(gid_t *pgid, const DOM_SID *sid) memcpy(&dom_sid, sid, sizeof(dom_sid)); result = wbcSidToGid(&dom_sid, pgid); - if (result != WBC_ERR_SUCCESS) - return False; return (result == WBC_ERR_SUCCESS); } -- cgit From 921d8782ccb92d2c9a394bb2d281d3762d75dde6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 25 Dec 2007 11:34:10 +0100 Subject: Fix the build (This used to be commit 72dc71710813ea9f1d8864c4401fef25a25577bd) --- source3/lib/netapi/serverinfo.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/serverinfo.c b/source3/lib/netapi/serverinfo.c index 276a98c15e..27c7c4b2fc 100644 --- a/source3/lib/netapi/serverinfo.c +++ b/source3/lib/netapi/serverinfo.c @@ -167,8 +167,7 @@ static WERROR NetServerSetInfoLocal_1005(struct libnetapi_ctx *ctx, return WERR_NOT_SUPPORTED; } - return libnet_smbconf_set_global_param(ctx, - "server string", + return libnet_smbconf_set_global_param("server string", info1005->comment); } -- cgit From 1c26f38c166f7493e329835b31bc34f2e585ed46 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 25 Dec 2007 12:00:53 +0100 Subject: Interface detection should not go through the socket wrapper Next try to get the build farm more in line again than it is now (This used to be commit 38e178df12d30672f74bf272338954c7917b59e3) --- source3/lib/interfaces.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/lib') diff --git a/source3/lib/interfaces.c b/source3/lib/interfaces.c index 722ab56abd..3797fc679d 100644 --- a/source3/lib/interfaces.c +++ b/source3/lib/interfaces.c @@ -84,6 +84,7 @@ #include #endif +#define SOCKET_WRAPPER_NOT_REPLACE #include "interfaces.h" #include "lib/replace/replace.h" -- cgit From 8b88fa53b5f1f344b30b3409acf765ee46005396 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 25 Dec 2007 18:37:42 +0100 Subject: Host SerNet-AIX has __ss_family instead of ss_family in sockaddr_storage (This used to be commit e33286f4a68352e55df081d06307f64f190773b3) --- source3/lib/replace/system/network.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/replace/system/network.h b/source3/lib/replace/system/network.h index 9087c02da1..b6ae3c7c6f 100644 --- a/source3/lib/replace/system/network.h +++ b/source3/lib/replace/system/network.h @@ -233,6 +233,10 @@ typedef unsigned short int sa_family_t; #endif #endif +#ifdef HAVE_AIX_SOCKADDR_STORAGE +#define ss_family __ss_family +#endif + #ifndef HAVE_STRUCT_ADDRINFO #define HAVE_STRUCT_ADDRINFO struct addrinfo { -- cgit From 07867ec373b98d6c0d3048983091ba4c49231196 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 26 Dec 2007 23:44:24 +0100 Subject: Fix some memleaks (This used to be commit 78b0b66cbac349625257260d2e45d918e0c93617) --- source3/lib/debug.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/debug.c b/source3/lib/debug.c index 87ec9ed8f5..9ea2dc151a 100644 --- a/source3/lib/debug.c +++ b/source3/lib/debug.c @@ -785,13 +785,13 @@ void check_log_size( void ) (void)x_vfprintf( dbf, format_str, ap ); va_end( ap ); errno = old_errno; - return( 0 ); + goto done; } /* prevent recursion by checking if reopen_logs() has temporaily set the debugf string to NULL */ if( debugf == NULL) - return( 0 ); + goto done; #ifdef WITH_SYSLOG if( !lp_syslog_only() ) @@ -806,7 +806,7 @@ void check_log_size( void ) x_setbuf( dbf, NULL ); } else { errno = old_errno; - return(0); + goto done; } } } @@ -855,10 +855,11 @@ void check_log_size( void ) (void)x_fflush( dbf ); } - errno = old_errno; - + done: TALLOC_FREE(tmp_debug_ctx); + errno = old_errno; + return( 0 ); } -- cgit From afc93255d183eefb68e45b8ec6275f6a62cf9795 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 26 Dec 2007 17:12:36 -0800 Subject: Add SMB encryption. Still fixing client decrypt but negotiation works. Jeremy. (This used to be commit d78045601af787731f0737b8627450018902b104) --- source3/lib/dummysmbd.c | 20 ++++++++++++++++++++ source3/lib/util.c | 38 +++++++++++++------------------------- source3/lib/util_sock.c | 30 +++++++++++++++++++++++++++--- 3 files changed, 60 insertions(+), 28 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/dummysmbd.c b/source3/lib/dummysmbd.c index e3b179b763..464ba92306 100644 --- a/source3/lib/dummysmbd.c +++ b/source3/lib/dummysmbd.c @@ -52,3 +52,23 @@ NTSTATUS can_delete_directory(struct connection_struct *conn, return NT_STATUS_OK; } +NTSTATUS srv_decrypt_buffer(char *buf) +{ + return NT_STATUS_OK; +} + +NTSTATUS srv_encrypt_buffer(char *buffer, char **buf_out) +{ + *buf_out = buffer; + return NT_STATUS_OK; +} + +void srv_free_enc_buffer(char *buf) +{ + ; +} + +bool srv_encryption_on(void) +{ + return false; +} diff --git a/source3/lib/util.c b/source3/lib/util.c index 11c14ea538..7f8a297fac 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -605,32 +605,30 @@ void show_msg(char *buf) } /******************************************************************* - Set the length and marker of an smb packet. + Set the length and marker of an encrypted smb packet. ********************************************************************/ -void smb_setlen(char *buf,int len) +void smb_set_enclen(char *buf,int len,uint16 enc_ctx_num) { _smb_setlen(buf,len); SCVAL(buf,4,0xFF); - SCVAL(buf,5,'S'); - SCVAL(buf,6,'M'); - SCVAL(buf,7,'B'); + SCVAL(buf,5,'E'); + SSVAL(buf,6,enc_ctx_num); } /******************************************************************* - Setup the word count and byte count for a smb message. + Set the length and marker of an smb packet. ********************************************************************/ -int set_message(char *buf,int num_words,int num_bytes,bool zero) +void smb_setlen(char *buf,int len) { - if (zero && (num_words || num_bytes)) { - memset(buf + smb_size,'\0',num_words*2 + num_bytes); - } - SCVAL(buf,smb_wct,num_words); - SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes); - smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4); - return (smb_size + num_words*2 + num_bytes); + _smb_setlen(buf,len); + + SCVAL(buf,4,0xFF); + SCVAL(buf,5,'S'); + SCVAL(buf,6,'M'); + SCVAL(buf,7,'B'); } /******************************************************************* @@ -641,20 +639,10 @@ int set_message_bcc(char *buf,int num_bytes) { int num_words = CVAL(buf,smb_wct); SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes); - smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4); + _smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4); return (smb_size + num_words*2 + num_bytes); } -/******************************************************************* - Setup only the byte count for a smb message, using the end of the - message as a marker. -********************************************************************/ - -int set_message_end(void *outbuf,void *end_ptr) -{ - return set_message_bcc((char *)outbuf,PTR_DIFF(end_ptr,smb_buf((char *)outbuf))); -} - /******************************************************************* Add a data blob to the end of a smb_buf, adjusting bcc and smb_len. Return the bytes added diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 8f1bd9e686..d16a8f079a 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1287,6 +1287,17 @@ bool receive_smb(int fd, char *buffer, unsigned int timeout, enum smb_read_error return false; } + if (srv_encryption_on()) { + NTSTATUS status = srv_decrypt_buffer(buffer); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("receive_smb: SMB decryption failed " + "on incoming packet! Error %s\n", + nt_errstr(status) )); + cond_set_smb_read_error(pre, SMB_READ_BAD_DECRYPT); + return false; + } + } + /* Check the incoming SMB signature. */ if (!srv_check_sign_mac(buffer, true)) { DEBUG(0, ("receive_smb: SMB Signature verification " @@ -1307,22 +1318,35 @@ bool send_smb(int fd, char *buffer) size_t len; size_t nwritten=0; ssize_t ret; + char *buf_out = buffer; /* Sign the outgoing packet if required. */ - srv_calculate_sign_mac(buffer); + srv_calculate_sign_mac(buf_out); + + if (srv_encryption_on()) { + NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("send_smb: SMB encryption failed " + "on outgoing packet! Error %s\n", + nt_errstr(status) )); + return false; + } + } - len = smb_len(buffer) + 4; + len = smb_len(buf_out) + 4; while (nwritten < len) { - ret = write_data(fd,buffer+nwritten,len - nwritten); + ret = write_data(fd,buf_out+nwritten,len - nwritten); if (ret <= 0) { DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n", (int)len,(int)ret, strerror(errno) )); + srv_free_enc_buffer(buf_out); return false; } nwritten += ret; } + srv_free_enc_buffer(buf_out); return true; } -- cgit From 3c99b7773ef62d13a7e3611be0603a5807315d9d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 28 Dec 2007 13:13:29 +0100 Subject: Convert csamuser to memcache (This used to be commit 476d3abf9c6142d99822212141fc3d843aca4798) --- source3/lib/memcache.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/lib') diff --git a/source3/lib/memcache.c b/source3/lib/memcache.c index 457586bd68..c06e7ceacc 100644 --- a/source3/lib/memcache.c +++ b/source3/lib/memcache.c @@ -46,6 +46,7 @@ static bool memcache_is_talloc(enum memcache_number n) switch (n) { case GETPWNAM_CACHE: + case PDB_GETPWSID_CACHE: result = true; break; default: -- cgit From 3ba59d461665a16cf87b991a8135821208457f67 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 28 Dec 2007 17:09:57 +0100 Subject: don't store cache_readonly in gencache tdb won't allow us to write anyway (This used to be commit 069cd6d63a61065be7926230235e198c456d38ae) --- source3/lib/gencache.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c index a50e5d01fa..663385cfe3 100644 --- a/source3/lib/gencache.c +++ b/source3/lib/gencache.c @@ -32,7 +32,6 @@ #define BLOB_TYPE_LEN 9 static TDB_CONTEXT *cache; -static bool cache_readonly; /** * @file gencache.c @@ -67,7 +66,6 @@ bool gencache_init(void) if (!cache && (errno == EACCES)) { cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT, O_RDONLY, 0644); if (cache) { - cache_readonly = True; DEBUG(5, ("gencache_init: Opening cache file %s read-only.\n", cache_fname)); } } @@ -95,7 +93,6 @@ bool gencache_shutdown(void) DEBUG(5, ("Closing cache file\n")); ret = tdb_close(cache); cache = NULL; - cache_readonly = False; return ret != -1; } @@ -123,10 +120,6 @@ bool gencache_set(const char *keystr, const char *value, time_t timeout) if (!gencache_init()) return False; - if (cache_readonly) { - return False; - } - asprintf(&valstr, CACHE_DATA_FMT, (int)timeout, value); if (!valstr) return False; @@ -161,10 +154,6 @@ bool gencache_del(const char *keystr) if (!gencache_init()) return False; - if (cache_readonly) { - return False; - } - DEBUG(10, ("Deleting cache entry (key = %s)\n", keystr)); ret = tdb_delete_bystring(cache, keystr); @@ -351,10 +340,6 @@ bool gencache_set_data_blob(const char *keystr, DATA_BLOB *blob, time_t timeout) return False; } - if (cache_readonly) { - return False; - } - asprintf(&valstr, "%12u/%s", (int)timeout, BLOB_TYPE); if (!valstr) { return False; -- cgit From 245537f9bd1bddc496da0155012c34a2c7a18668 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 28 Dec 2007 17:24:39 +0100 Subject: Convert get_root_nt_token to memcache (This used to be commit fada689893314bed2fc78588b3fd9b144f4c808a) --- source3/lib/memcache.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/lib') diff --git a/source3/lib/memcache.c b/source3/lib/memcache.c index c06e7ceacc..6dee61af50 100644 --- a/source3/lib/memcache.c +++ b/source3/lib/memcache.c @@ -47,6 +47,7 @@ static bool memcache_is_talloc(enum memcache_number n) switch (n) { case GETPWNAM_CACHE: case PDB_GETPWSID_CACHE: + case SINGLETON_CACHE_TALLOC: result = true; break; default: -- cgit From a59280792cab616f5b269960ab68bc44ccc1fd38 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 29 Dec 2007 22:16:31 +0100 Subject: Remove tiny code duplication sid_size did the same as ndr_size_dom_sid (This used to be commit 8aec5d09ba023413bd8ecbdfbc7d23904df94389) --- source3/lib/secace.c | 4 ++-- source3/lib/secdesc.c | 8 ++++---- source3/lib/util_sid.c | 18 +++--------------- 3 files changed, 9 insertions(+), 21 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/secace.c b/source3/lib/secace.c index 90ecc342cd..8760a6109a 100644 --- a/source3/lib/secace.c +++ b/source3/lib/secace.c @@ -59,7 +59,7 @@ void init_sec_ace(SEC_ACE *t, const DOM_SID *sid, enum security_ace_type type, { t->type = type; t->flags = flag; - t->size = sid_size(sid) + 8; + t->size = ndr_size_dom_sid(sid, 0) + 8; t->access_mask = mask; ZERO_STRUCTP(&t->trustee); @@ -86,7 +86,7 @@ NTSTATUS sec_ace_add_sid(TALLOC_CTX *ctx, SEC_ACE **pp_new, SEC_ACE *old, unsign (*pp_new)[i].type = SEC_ACE_TYPE_ACCESS_ALLOWED; (*pp_new)[i].flags = 0; - (*pp_new)[i].size = SEC_ACE_HEADER_SIZE + sid_size(sid); + (*pp_new)[i].size = SEC_ACE_HEADER_SIZE + ndr_size_dom_sid(sid, 0); (*pp_new)[i].access_mask = mask; sid_copy(&(*pp_new)[i].trustee, sid); return NT_STATUS_OK; diff --git a/source3/lib/secdesc.c b/source3/lib/secdesc.c index 123c3bcc9b..883fac57e4 100644 --- a/source3/lib/secdesc.c +++ b/source3/lib/secdesc.c @@ -46,10 +46,10 @@ size_t sec_desc_size(SEC_DESC *psd) /* don't align */ if (psd->owner_sid != NULL) - offset += sid_size(psd->owner_sid); + offset += ndr_size_dom_sid(psd->owner_sid, 0); if (psd->group_sid != NULL) - offset += sid_size(psd->group_sid); + offset += ndr_size_dom_sid(psd->group_sid, 0); if (psd->sacl != NULL) offset += psd->sacl->size; @@ -235,11 +235,11 @@ SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, } if (dst->owner_sid != NULL) { - offset += sid_size(dst->owner_sid); + offset += ndr_size_dom_sid(dst->owner_sid, 0); } if (dst->group_sid != NULL) { - offset += sid_size(dst->group_sid); + offset += ndr_size_dom_sid(dst->group_sid, 0); } *sd_size = (size_t)offset; diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c index 52f65aa77d..222b32ed3a 100644 --- a/source3/lib/util_sid.c +++ b/source3/lib/util_sid.c @@ -382,7 +382,7 @@ bool sid_linearize(char *outbuf, size_t len, const DOM_SID *sid) { size_t i; - if (len < sid_size(sid)) + if (len < ndr_size_dom_sid(sid, 0)) return False; SCVAL(outbuf,0,sid->sid_rev_num); @@ -494,18 +494,6 @@ bool sid_equal(const DOM_SID *sid1, const DOM_SID *sid2) return sid_compare(sid1, sid2) == 0; } -/***************************************************************** - Calculates size of a sid. -*****************************************************************/ - -size_t sid_size(const DOM_SID *sid) -{ - if (sid == NULL) - return 0; - - return sid->num_auths * sizeof(uint32) + 8; -} - /***************************************************************** Returns true if SID is internal (and non-mappable). *****************************************************************/ @@ -535,7 +523,7 @@ bool non_mappable_sid(DOM_SID *sid) char *sid_binstring(const DOM_SID *sid) { char *buf, *s; - int len = sid_size(sid); + int len = ndr_size_dom_sid(sid, 0); buf = (char *)SMB_MALLOC(len); if (!buf) return NULL; @@ -553,7 +541,7 @@ char *sid_binstring(const DOM_SID *sid) char *sid_binstring_hex(const DOM_SID *sid) { char *buf, *s; - int len = sid_size(sid); + int len = ndr_size_dom_sid(sid, 0); buf = (char *)SMB_MALLOC(len); if (!buf) return NULL; -- cgit From 7be5525792a2f4aa19c308afb516ef1fe02b7be2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 29 Dec 2007 22:54:51 +0100 Subject: Make [un]marshall_sec_desc use librpc/ndr (This used to be commit 387936ec3952f88d46df2d4943bbc4e408ad2bb5) --- source3/lib/secdesc.c | 54 +++++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 25 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/secdesc.c b/source3/lib/secdesc.c index 883fac57e4..5e5042e521 100644 --- a/source3/lib/secdesc.c +++ b/source3/lib/secdesc.c @@ -274,25 +274,21 @@ NTSTATUS marshall_sec_desc(TALLOC_CTX *mem_ctx, struct security_descriptor *secdesc, uint8 **data, size_t *len) { - prs_struct ps; - - if (!prs_init(&ps, sec_desc_size(secdesc), mem_ctx, MARSHALL)) { - return NT_STATUS_NO_MEMORY; - } + DATA_BLOB blob; + enum ndr_err_code ndr_err; - if (!sec_io_desc("security_descriptor", &secdesc, &ps, 1)) { - prs_mem_free(&ps); - return NT_STATUS_INVALID_PARAMETER; - } + ndr_err = ndr_push_struct_blob( + &blob, mem_ctx, secdesc, + (ndr_push_flags_fn_t)ndr_push_security_descriptor); - if (!(*data = (uint8 *)talloc_memdup(mem_ctx, ps.data_p, - prs_offset(&ps)))) { - prs_mem_free(&ps); - return NT_STATUS_NO_MEMORY; + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(0, ("ndr_push_security_descriptor failed: %s\n", + ndr_errstr(ndr_err))); + return ndr_map_error2ntstatus(ndr_err);; } - *len = prs_offset(&ps); - prs_mem_free(&ps); + *data = blob.data; + *len = blob.length; return NT_STATUS_OK; } @@ -302,25 +298,33 @@ NTSTATUS marshall_sec_desc(TALLOC_CTX *mem_ctx, NTSTATUS unmarshall_sec_desc(TALLOC_CTX *mem_ctx, uint8 *data, size_t len, struct security_descriptor **psecdesc) { - prs_struct ps; - struct security_descriptor *secdesc = NULL; + DATA_BLOB blob; + enum ndr_err_code ndr_err; + struct security_descriptor *result; - if (!(secdesc = TALLOC_ZERO_P(mem_ctx, struct security_descriptor))) { - return NT_STATUS_NO_MEMORY; + if ((data == NULL) || (len == 0)) { + return NT_STATUS_INVALID_PARAMETER; } - if (!prs_init(&ps, 0, secdesc, UNMARSHALL)) { + result = TALLOC_ZERO_P(mem_ctx, struct security_descriptor); + if (result == NULL) { return NT_STATUS_NO_MEMORY; } - prs_give_memory(&ps, (char *)data, len, False); + blob = data_blob_const(data, len); - if (!sec_io_desc("security_descriptor", &secdesc, &ps, 1)) { - return NT_STATUS_INVALID_PARAMETER; + ndr_err = ndr_pull_struct_blob( + &blob, result, result, + (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(0, ("ndr_pull_security_descriptor failed: %s\n", + ndr_errstr(ndr_err))); + TALLOC_FREE(result); + return ndr_map_error2ntstatus(ndr_err);; } - prs_mem_free(&ps); - *psecdesc = secdesc; + *psecdesc = result; return NT_STATUS_OK; } -- cgit From 7cbdb48475b0340154fad60cb4b7cc53dc2bbcfd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 29 Dec 2007 23:00:49 +0100 Subject: Remove tiny code duplication ndr_size_security_descriptor does the same as sec_desc_size (This used to be commit bc3bd7a8e7c6e9e27acb195c86abb92c0f53112f) --- source3/lib/secdesc.c | 29 ----------------------------- source3/lib/sharesec.c | 2 +- 2 files changed, 1 insertion(+), 30 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/secdesc.c b/source3/lib/secdesc.c index 5e5042e521..44ae23271e 100644 --- a/source3/lib/secdesc.c +++ b/source3/lib/secdesc.c @@ -31,35 +31,6 @@ const struct generic_mapping file_generic_mapping = { FILE_GENERIC_ALL }; -/******************************************************************* - Works out the linearization size of a SEC_DESC. -********************************************************************/ - -size_t sec_desc_size(SEC_DESC *psd) -{ - size_t offset; - - if (!psd) return 0; - - offset = SEC_DESC_HEADER_SIZE; - - /* don't align */ - - if (psd->owner_sid != NULL) - offset += ndr_size_dom_sid(psd->owner_sid, 0); - - if (psd->group_sid != NULL) - offset += ndr_size_dom_sid(psd->group_sid, 0); - - if (psd->sacl != NULL) - offset += psd->sacl->size; - - if (psd->dacl != NULL) - offset += psd->dacl->size; - - return offset; -} - /******************************************************************* Compares two SEC_DESC structures ********************************************************************/ diff --git a/source3/lib/sharesec.c b/source3/lib/sharesec.c index 0027a8813a..ba025dacc1 100644 --- a/source3/lib/sharesec.c +++ b/source3/lib/sharesec.c @@ -144,7 +144,7 @@ SEC_DESC *get_share_security( TALLOC_CTX *ctx, const char *servicename, } if (psd) - *psize = sec_desc_size(psd); + *psize = ndr_size_security_descriptor(psd, 0); return psd; } -- cgit From a5d2449fe1f25d74ac3a3d4eae66c43cd8dcbde9 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 2 Jan 2008 17:08:28 +0100 Subject: Use the proper boolean constants. Michael (This used to be commit f731fee408a809b6dc266d45e41f37e63bf4e48d) --- source3/lib/util_reg_smbconf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/util_reg_smbconf.c b/source3/lib/util_reg_smbconf.c index 154c67ab8f..fa58f28d03 100644 --- a/source3/lib/util_reg_smbconf.c +++ b/source3/lib/util_reg_smbconf.c @@ -57,7 +57,7 @@ done: */ bool registry_init_regdb(void) { - bool ret = False; + bool ret = false; int saved_errno = 0; static REGISTRY_HOOK smbconf_reg_hook = {KEY_SMBCONF, &smbconf_reg_ops}; @@ -78,7 +78,7 @@ bool registry_init_regdb(void) goto done; } - ret = True; + ret = true; done: return ret; -- cgit From 701a56a698b580b21bfb0df73401ffe2d05f6f19 Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Wed, 2 Jan 2008 14:50:59 -0600 Subject: Make sure that wbcLookupSid() and wbcLookupRids() use talloc()'d memory. Follows existing convention that all returned memory should be freed with wbcFreeMemory() and not directly with free(). Noticed by Volker. Txs. (This used to be commit 39c2059f66ee9eb471a503b9c776807b91c2a8f8) --- source3/lib/winbind_util.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/winbind_util.c b/source3/lib/winbind_util.c index f51a0171a2..2cabf5bcac 100644 --- a/source3/lib/winbind_util.c +++ b/source3/lib/winbind_util.c @@ -74,8 +74,8 @@ bool winbind_lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid, DEBUG(10, ("winbind_lookup_sid: SUCCESS: SID %s -> %s %s\n", sid_string_dbg(sid), domain_name, account_name)); - SAFE_FREE(domain_name); - SAFE_FREE(account_name); + wbcFreeMemory(domain_name); + wbcFreeMemory(account_name); if ((domain && !*domain) || (name && !*name)) { DEBUG(0,("winbind_lookup_sid: talloc() failed!\n")); @@ -192,8 +192,9 @@ bool winbind_lookup_rids(TALLOC_CTX *mem_ctx, ret = wbcLookupRids(&dom_sid, num_rids, rids, &dom_name, &namelist, &name_types); - if (ret != WBC_ERR_SUCCESS) + if (ret != WBC_ERR_SUCCESS) { return False; + } *domain_name = talloc_strdup(mem_ctx, dom_name); *names = TALLOC_ARRAY(mem_ctx, const char*, num_rids); @@ -202,11 +203,11 @@ bool winbind_lookup_rids(TALLOC_CTX *mem_ctx, for(i=0; i Date: Wed, 2 Jan 2008 14:54:25 -0600 Subject: use C99 bool return types (true & false). (This used to be commit f22c9d6296c754d472e8eab51caa058f55ef370e) --- source3/lib/winbind_util.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/winbind_util.c b/source3/lib/winbind_util.c index 2cabf5bcac..3cf068a6e0 100644 --- a/source3/lib/winbind_util.c +++ b/source3/lib/winbind_util.c @@ -35,12 +35,12 @@ bool winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid, result = wbcLookupName(dom_name, name, &dom_sid, &type); if (result != WBC_ERR_SUCCESS) - return False; + return false; memcpy(sid, &dom_sid, sizeof(DOM_SID)); *name_type = (enum lsa_SidType)type; - return True; + return true; } /* Call winbindd to convert sid to name */ @@ -59,7 +59,7 @@ bool winbind_lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid, result = wbcLookupSid(&dom_sid, &domain_name, &account_name, &type); if (result != WBC_ERR_SUCCESS) - return False; + return false; /* Copy out result */ @@ -79,11 +79,11 @@ bool winbind_lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid, if ((domain && !*domain) || (name && !*name)) { DEBUG(0,("winbind_lookup_sid: talloc() failed!\n")); - return False; + return false; } - return True; + return true; } /* Ping winbindd to see it is alive */ @@ -193,7 +193,7 @@ bool winbind_lookup_rids(TALLOC_CTX *mem_ctx, ret = wbcLookupRids(&dom_sid, num_rids, rids, &dom_name, &namelist, &name_types); if (ret != WBC_ERR_SUCCESS) { - return False; + return false; } *domain_name = talloc_strdup(mem_ctx, dom_name); @@ -209,7 +209,7 @@ bool winbind_lookup_rids(TALLOC_CTX *mem_ctx, wbcFreeMemory(namelist); wbcFreeMemory(name_types); - return True; + return true; } /* Ask Winbind to allocate a new uid for us */ @@ -239,7 +239,7 @@ bool winbind_allocate_gid(gid_t *gid) bool winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid, enum lsa_SidType *name_type) { - return False; + return false; } /* Call winbindd to convert sid to name */ @@ -248,42 +248,42 @@ bool winbind_lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid, const char **domain, const char **name, enum lsa_SidType *name_type) { - return False; + return false; } /* Ping winbindd to see it is alive */ bool winbind_ping(void) { - return False; + return false; } /* Call winbindd to convert SID to uid */ bool winbind_sid_to_uid(uid_t *puid, const DOM_SID *sid) { - return False; + return false; } /* Call winbindd to convert uid to sid */ bool winbind_uid_to_sid(DOM_SID *sid, uid_t uid) { - return False; + return false; } /* Call winbindd to convert SID to gid */ bool winbind_sid_to_gid(gid_t *pgid, const DOM_SID *sid) { - return False; + return false; } /* Call winbindd to convert gid to sid */ bool winbind_gid_to_sid(DOM_SID *sid, gid_t gid) { - return False; + return false; } /* Check for a trusted domain */ @@ -301,21 +301,21 @@ bool winbind_lookup_rids(TALLOC_CTX *mem_ctx, const char **domain_name, const char ***names, enum lsa_SidType **types) { - return False; + return false; } /* Ask Winbind to allocate a new uid for us */ bool winbind_allocate_uid(uid_t *uid) { - return False; + return false; } /* Ask Winbind to allocate a new gid for us */ bool winbind_allocate_gid(gid_t *gid) { - return False; + return false; } #endif /* WITH_WINBIND */ -- cgit From cc957c7f6d1956740feb7169b45f388d387e175a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 2 Jan 2008 17:37:39 -0800 Subject: Convert the little caches in util_sock.c to use the singleton memcache. Vl please check (passes make valgrindtest). Jeremy. (This used to be commit a4d613cde86caf5782c4bfc47122d6ba807990ac) --- source3/lib/util_sock.c | 165 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 118 insertions(+), 47 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index d16a8f079a..013a5fe29f 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1824,18 +1824,67 @@ static bool matchname(const char *remotehost, return false; } -static struct { - struct sockaddr_storage ss; - char *name; -} nc; +/******************************************************************* + Deal with the singleton cache. +******************************************************************/ + +struct name_addr_pair { + struct sockaddr_storage ss; + const char *name; +}; + +/******************************************************************* + Lookup a name/addr pair. Returns memory allocated from memcache. +******************************************************************/ + +static bool lookup_nc(struct name_addr_pair *nc) +{ + DATA_BLOB tmp; + + ZERO_STRUCTP(nc); + + if (!memcache_lookup( + NULL, SINGLETON_CACHE, + data_blob_string_const("get_peer_name"), + &tmp)) { + return false; + } + + memcpy(&nc->ss, tmp.data, sizeof(nc->ss)); + nc->name = (const char *)tmp.data + sizeof(nc->ss); + return true; +} + +/******************************************************************* + Save a name/addr pair. +******************************************************************/ + +static void store_nc(const struct name_addr_pair *nc) +{ + DATA_BLOB tmp; + size_t namelen = strlen(nc->name); + + tmp.length = sizeof(nc->ss) + namelen + 1; + tmp.data = (uint8_t *)SMB_MALLOC(tmp.length); + if (!tmp.data) { + return; + } + memcpy(tmp.data, &nc->ss, sizeof(nc->ss)); + memcpy(tmp.data+sizeof(nc->ss), nc->name, namelen+1); + + memcache_add(NULL, SINGLETON_CACHE, + data_blob_string_const("get_peer_name"), + tmp); + SAFE_FREE(tmp.data); +} /******************************************************************* Return the DNS name of the remote end of a socket. ******************************************************************/ -const char *get_peer_name(int fd, - bool force_lookup) +const char *get_peer_name(int fd, bool force_lookup) { + struct name_addr_pair nc; char addr_buf[INET6_ADDRSTRLEN]; struct sockaddr_storage ss; socklen_t length = sizeof(ss); @@ -1850,13 +1899,15 @@ const char *get_peer_name(int fd, possible */ if (!lp_hostname_lookups() && (force_lookup == false)) { length = sizeof(nc.ss); - p = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf), + nc.name = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf), &nc.ss, &length); - SAFE_FREE(nc.name); - nc.name = SMB_STRDUP(p); + store_nc(&nc); + lookup_nc(&nc); return nc.name ? nc.name : "UNKNOWN"; } + lookup_nc(&nc); + memset(&ss, '\0', sizeof(ss)); p = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf), &ss, &length); @@ -1865,9 +1916,7 @@ const char *get_peer_name(int fd, return nc.name ? nc.name : "UNKNOWN"; } - /* Not the same. Reset the cache. */ - zero_addr(&nc.ss); - SAFE_FREE(nc.name); + /* Not the same. We need to lookup. */ if (fd == -1) { return "UNKNOWN"; } @@ -1904,7 +1953,11 @@ const char *get_peer_name(int fd, strlcpy(name_buf, "UNKNOWN", sizeof(name_buf)); } - nc.name = SMB_STRDUP(name_buf); + nc.name = name_buf; + nc.ss = ss; + + store_nc(&nc); + lookup_nc(&nc); return nc.name ? nc.name : "UNKNOWN"; } @@ -2026,50 +2079,68 @@ out_umask: const char *get_mydnsfullname(void) { - static char *dnshostname_cache; - - if (dnshostname_cache == NULL || !*dnshostname_cache) { - struct addrinfo *res = NULL; - char my_hostname[HOST_NAME_MAX]; - bool ret; + struct addrinfo *res = NULL; + char my_hostname[HOST_NAME_MAX]; + bool ret; + DATA_BLOB tmp; - /* get my host name */ - if (gethostname(my_hostname, sizeof(my_hostname)) == -1) { - DEBUG(0,("get_mydnsfullname: gethostname failed\n")); - return NULL; - } + if (memcache_lookup(NULL, SINGLETON_CACHE, + data_blob_string_const("get_mydnsfullname"), + &tmp)) { + SMB_ASSERT(tmp.length > 0); + return (const char *)tmp.data; + } - /* Ensure null termination. */ - my_hostname[sizeof(my_hostname)-1] = '\0'; + /* get my host name */ + if (gethostname(my_hostname, sizeof(my_hostname)) == -1) { + DEBUG(0,("get_mydnsfullname: gethostname failed\n")); + return NULL; + } - ret = interpret_string_addr_internal(&res, - my_hostname, - AI_ADDRCONFIG|AI_CANONNAME); + /* Ensure null termination. */ + my_hostname[sizeof(my_hostname)-1] = '\0'; - if (!ret || res == NULL) { - DEBUG(3,("get_mydnsfullname: getaddrinfo failed for " - "name %s [%s]\n", + ret = interpret_string_addr_internal(&res, my_hostname, - gai_strerror(ret) )); - return NULL; - } + AI_ADDRCONFIG|AI_CANONNAME); - /* - * Make sure that getaddrinfo() returns the "correct" host name. - */ + if (!ret || res == NULL) { + DEBUG(3,("get_mydnsfullname: getaddrinfo failed for " + "name %s [%s]\n", + my_hostname, + gai_strerror(ret) )); + return NULL; + } - if (res->ai_canonname == NULL) { - DEBUG(3,("get_mydnsfullname: failed to get " - "canonical name for %s\n", - my_hostname)); - freeaddrinfo(res); - return NULL; - } + /* + * Make sure that getaddrinfo() returns the "correct" host name. + */ - dnshostname_cache = SMB_STRDUP(res->ai_canonname); + if (res->ai_canonname == NULL) { + DEBUG(3,("get_mydnsfullname: failed to get " + "canonical name for %s\n", + my_hostname)); freeaddrinfo(res); + return NULL; + } + + /* This copies the data, so we must do a lookup + * afterwards to find the value to return. + */ + + memcache_add(NULL, SINGLETON_CACHE, + data_blob_string_const("get_mydnsfullname"), + data_blob_string_const(res->ai_canonname)); + + freeaddrinfo(res); + + if (!memcache_lookup(NULL, SINGLETON_CACHE, + data_blob_string_const("get_mydnsfullname"), + &tmp)) { + return NULL; } - return dnshostname_cache; + + return (const char *)tmp.data; } /************************************************************ -- cgit From 149e86b8427359042830faddad10a103f51184da Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 3 Jan 2008 10:24:45 +0100 Subject: Trivial simplification ... things you come across when you review code (This used to be commit 1e006bcfb15d44ecb81b6994c588d30d87b48033) --- source3/lib/util_sock.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 013a5fe29f..b92cd3d624 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1864,8 +1864,7 @@ static void store_nc(const struct name_addr_pair *nc) DATA_BLOB tmp; size_t namelen = strlen(nc->name); - tmp.length = sizeof(nc->ss) + namelen + 1; - tmp.data = (uint8_t *)SMB_MALLOC(tmp.length); + tmp = data_blob(NULL, sizeof(nc->ss) + namelen + 1); if (!tmp.data) { return; } @@ -1875,7 +1874,7 @@ static void store_nc(const struct name_addr_pair *nc) memcache_add(NULL, SINGLETON_CACHE, data_blob_string_const("get_peer_name"), tmp); - SAFE_FREE(tmp.data); + data_blob_free(&tmp); } /******************************************************************* -- cgit From 6afaafe083ad23e51743ccd5245cf7384b2c4bd9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 3 Jan 2008 13:36:56 +0100 Subject: Let DsGetDCName figure out whether domain_name is a flat_name when unjoining. Guenther (This used to be commit 75165ba4e7acafaca42f6afd1fb8b56e00bcbed7) --- source3/lib/netapi/joindomain.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index e3d5eada02..60f48a7b5e 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -233,7 +233,6 @@ static WERROR NetUnjoinDomainLocal(struct libnetapi_ctx *mem_ctx, struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED | DS_WRITABLE_REQUIRED | - DS_IS_FLAT_NAME | DS_RETURN_DNS_NAME; if (lp_realm()) { domain = lp_realm(); -- cgit From 5655ae7a2468e8fc93b1a8d9ac4b2f35abbf3703 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 3 Jan 2008 14:15:05 +0100 Subject: Rename libnet_smbconf_set_global_param() to libnet_conf_set_global_parameter(). Now all functions are converted to the consistent naming scheme. Michael (This used to be commit a559533c0c8a80f3f4078bbc2675de395359485f) --- source3/lib/netapi/serverinfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/serverinfo.c b/source3/lib/netapi/serverinfo.c index 27c7c4b2fc..0e356e0ee7 100644 --- a/source3/lib/netapi/serverinfo.c +++ b/source3/lib/netapi/serverinfo.c @@ -167,8 +167,8 @@ static WERROR NetServerSetInfoLocal_1005(struct libnetapi_ctx *ctx, return WERR_NOT_SUPPORTED; } - return libnet_smbconf_set_global_param("server string", - info1005->comment); + return libnet_conf_set_global_parameter("server string", + info1005->comment); } static WERROR NetServerSetInfoLocal(struct libnetapi_ctx *ctx, -- cgit From be88a6738823e3a19c4e935dd970ab4c078ceaee Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 3 Jan 2008 16:41:38 +0100 Subject: Minor libnetapi join cosmetic cleanup. Guenther (This used to be commit 4deef80bed374af5032c0f3081d2ee3c70be99df) --- source3/lib/netapi/joindomain.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index 60f48a7b5e..d200c9b7b0 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -114,7 +114,7 @@ static WERROR NetJoinDomainRemote(struct libnetapi_ctx *ctx, if (!pipe_cli) { werr = ntstatus_to_werror(status); goto done; - }; + } if (password) { encode_wkssvc_join_password_buffer(ctx, @@ -300,7 +300,7 @@ static WERROR NetUnjoinDomainRemote(struct libnetapi_ctx *ctx, if (!pipe_cli) { werr = ntstatus_to_werror(status); goto done; - }; + } if (password) { encode_wkssvc_join_password_buffer(ctx, @@ -407,7 +407,7 @@ static WERROR NetGetJoinInformationRemote(struct libnetapi_ctx *ctx, if (!pipe_cli) { werr = ntstatus_to_werror(status); goto done; - }; + } status = rpccli_wkssvc_NetrGetJoinInformation(pipe_cli, ctx, server_name, -- cgit From cf6e59de2b475e14660a9b71daad2ab5699d53a7 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 4 Jan 2008 11:54:38 +0100 Subject: Fix some error strings in netdomjoin-gui. Guenther (This used to be commit aaea8f1ed744e9662f92a3840d86ad1aff943d18) --- .../examples/netdomjoin-gui/netdomjoin-gui.c | 43 ++++++++++++++++------ 1 file changed, 31 insertions(+), 12 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c index beb12be8b1..3abf6fd5dc 100644 --- a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c +++ b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c @@ -1,7 +1,7 @@ /* * Unix SMB/CIFS implementation. * Join Support (gtk + netapi) - * Copyright (C) Guenther Deschner 2007 + * Copyright (C) Guenther Deschner 2007-2008 * * 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 @@ -124,7 +124,6 @@ static void free_join_state(struct join_state *s) SAFE_FREE(s->my_fqdn); SAFE_FREE(s->my_dnsdomain); SAFE_FREE(s->my_hostname); - } static void do_cleanup(struct join_state *state) @@ -365,7 +364,8 @@ static void callback_do_join(GtkWidget *widget, uint32_t unjoin_flags = 0; gboolean domain_join = FALSE; gboolean try_unjoin = FALSE; - const char *domain_or_workgroup = NULL; + const char *new_workgroup_type = NULL; + const char *initial_workgroup_type = NULL; struct join_state *state = (struct join_state *)data; @@ -376,14 +376,33 @@ static void callback_do_join(GtkWidget *widget, gtk_widget_destroy(GTK_WIDGET(state->window_creds_prompt)); } + switch (state->name_type_initial) { + case NetSetupWorkgroupName: + initial_workgroup_type = "workgroup"; + break; + case NetSetupDomainName: + initial_workgroup_type = "domain"; + break; + default: + break; + } + + switch (state->name_type_new) { + case NetSetupWorkgroupName: + new_workgroup_type = "workgroup"; + break; + case NetSetupDomainName: + new_workgroup_type = "domain"; + break; + default: + break; + } + if (state->name_type_new == NetSetupDomainName) { domain_join = TRUE; join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE | WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE | WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED; /* for testing */ - domain_or_workgroup = "domain"; - } else { - domain_or_workgroup = "workgroup"; } if ((state->name_type_initial == NetSetupDomainName) && @@ -394,7 +413,7 @@ static void callback_do_join(GtkWidget *widget, } debug("callback_do_join: Joining a %s named %s using join_flags 0x%08x ", - domain_or_workgroup, + new_workgroup_type, state->name_buffer_new, join_flags); if (domain_join) { @@ -422,8 +441,8 @@ static void callback_do_join(GtkWidget *widget, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "The following error occured attempting to unjoin the %s: \"%s\": %s", - domain_or_workgroup, - state->name_buffer_new, + initial_workgroup_type, + state->name_buffer_initial, err_str); g_signal_connect_swapped(dialog, "response", @@ -451,7 +470,7 @@ static void callback_do_join(GtkWidget *widget, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "The following error occured attempting to join the %s: \"%s\": %s", - domain_or_workgroup, + new_workgroup_type, state->name_buffer_new, err_str); @@ -465,7 +484,7 @@ static void callback_do_join(GtkWidget *widget, } debug("callback_do_join: Successfully joined %s\n", - domain_or_workgroup); + new_workgroup_type); dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent), GTK_DIALOG_DESTROY_WITH_PARENT, @@ -473,7 +492,7 @@ static void callback_do_join(GtkWidget *widget, GTK_BUTTONS_OK, "Welcome to the %s %s.", state->name_buffer_new, - domain_or_workgroup); + new_workgroup_type); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); -- cgit From 564a54aa168a0866dbd8fb3ef512b1836be11442 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 4 Jan 2008 15:08:28 +0100 Subject: Minor cosmetic cleanup for netdomjoin-gui. Guenther (This used to be commit 02e3887f3962b469c965110b6141a6655f2347af) --- .../netapi/examples/netdomjoin-gui/logo-small.png | Bin 0 -> 4485 bytes .../examples/netdomjoin-gui/netdomjoin-gui.c | 55 ++++++++++++++------- 2 files changed, 37 insertions(+), 18 deletions(-) create mode 100644 source3/lib/netapi/examples/netdomjoin-gui/logo-small.png (limited to 'source3/lib') diff --git a/source3/lib/netapi/examples/netdomjoin-gui/logo-small.png b/source3/lib/netapi/examples/netdomjoin-gui/logo-small.png new file mode 100644 index 0000000000..f041198002 Binary files /dev/null and b/source3/lib/netapi/examples/netdomjoin-gui/logo-small.png differ diff --git a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c index 3abf6fd5dc..d12e66bb26 100644 --- a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c +++ b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c @@ -35,6 +35,7 @@ #define SAMBA_ICON_PATH "/usr/share/pixmaps/samba/samba.ico" #define SAMBA_IMAGE_PATH "/usr/share/pixmaps/samba/logo.png" +#define SAMBA_IMAGE_PATH_SMALL "/usr/share/pixmaps/samba/logo-small.png" #define WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED ( 0x00000020 ) #define WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE ( 0x00000004 ) @@ -224,7 +225,8 @@ static void callback_do_reboot(GtkWidget *widget, gtk_widget_destroy(dialog); #endif - gtk_label_set_text(GTK_LABEL(state->label_reboot), "Changes will take effect after you restart this computer"); + gtk_label_set_text(GTK_LABEL(state->label_reboot), + "Changes will take effect after you restart this computer"); debug("destroying do_change window\n"); gtk_widget_destroy(GTK_WIDGET(state->window_do_change)); @@ -247,11 +249,14 @@ static void callback_do_reboot(GtkWidget *widget, SAFE_FREE(buffer); state->name_type_new = type; #endif - gtk_label_set_text(GTK_LABEL(state->label_current_name_buffer), state->name_buffer_new); - if (state->name_type_new == 3) { - gtk_label_set_text(GTK_LABEL(state->label_current_name_type), "Domain:"); + gtk_label_set_text(GTK_LABEL(state->label_current_name_buffer), + state->name_buffer_new); + if (state->name_type_new == NetSetupDomainName) { + gtk_label_set_text(GTK_LABEL(state->label_current_name_type), + "Domain:"); } else { - gtk_label_set_text(GTK_LABEL(state->label_current_name_type), "Workgroup:"); + gtk_label_set_text(GTK_LABEL(state->label_current_name_type), + "Workgroup:"); } } } @@ -779,6 +784,8 @@ static void callback_do_change(GtkWidget *widget, debug("callback_do_change called\n"); +#if 0 + /* FIXME: add proper warnings for Samba as a DC */ if (state->server_role == 3) { GtkWidget *dialog; dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main), @@ -793,13 +800,14 @@ static void callback_do_change(GtkWidget *widget, gtk_widget_show(dialog); return; } +#endif state->button_ok = gtk_button_new_from_stock(GTK_STOCK_OK); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "Computer Name Changes"); gtk_window_set_resizable(GTK_WINDOW(window), FALSE); - gtk_widget_set_size_request(GTK_WIDGET(window), 480, 500); /* breite * höhe */ + gtk_widget_set_size_request(GTK_WIDGET(window), 480, 500); gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL); g_signal_connect(G_OBJECT(window), "delete_event", @@ -849,14 +857,17 @@ static void callback_do_change(GtkWidget *widget, char *str = NULL; entry_text = gtk_entry_get_text(GTK_ENTRY(entry)); if (state->name_type_initial == NetSetupDomainName) { - asprintf(&str, "%s.%s", entry_text, state->my_dnsdomain); + asprintf(&str, "%s.%s", entry_text, + state->my_dnsdomain); } else { asprintf(&str, "%s.", entry_text); } - gtk_label_set_text(GTK_LABEL(state->label_full_computer_name), str); + gtk_label_set_text(GTK_LABEL(state->label_full_computer_name), + str); free(str); gtk_misc_set_alignment(GTK_MISC(state->label_full_computer_name), 0, 0); - gtk_box_pack_start(GTK_BOX(box1), state->label_full_computer_name, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(box1), + state->label_full_computer_name, TRUE, TRUE, 0); gtk_widget_show(state->label_full_computer_name); } @@ -891,7 +902,8 @@ static void callback_do_change(GtkWidget *widget, G_CALLBACK(callback_continue), (gpointer)state); if (state->name_type_initial == NetSetupDomainName) { - gtk_entry_set_text(GTK_ENTRY(state->entry_domain), state->name_buffer_initial); + gtk_entry_set_text(GTK_ENTRY(state->entry_domain), + state->name_buffer_initial); gtk_widget_set_sensitive(state->entry_workgroup, FALSE); gtk_widget_set_sensitive(state->entry_domain, TRUE); } @@ -912,7 +924,8 @@ static void callback_do_change(GtkWidget *widget, G_CALLBACK(callback_do_join_workgroup), (gpointer)state); { - gtk_entry_set_max_length(GTK_ENTRY(state->entry_workgroup), MAX_NETBIOS_NAME_LEN); + gtk_entry_set_max_length(GTK_ENTRY(state->entry_workgroup), + MAX_NETBIOS_NAME_LEN); g_signal_connect(G_OBJECT(state->entry_workgroup), "changed", G_CALLBACK(callback_enter_workgroup_and_unlock), (gpointer)state); @@ -921,7 +934,8 @@ static void callback_do_change(GtkWidget *widget, (gpointer)state); if (state->name_type_initial == NetSetupWorkgroupName) { - gtk_entry_set_text(GTK_ENTRY(state->entry_workgroup), state->name_buffer_initial); + gtk_entry_set_text(GTK_ENTRY(state->entry_workgroup), + state->name_buffer_initial); gtk_widget_set_sensitive(GTK_WIDGET(state->entry_domain), FALSE); gtk_widget_set_sensitive(GTK_WIDGET(state->entry_workgroup), TRUE); } @@ -998,21 +1012,25 @@ static int draw_main_window(struct join_state *state) icon = gdk_pixbuf_new_from_file(SAMBA_ICON_PATH, &error); if (icon == NULL) { - g_print("failed to load logo from %s : %s\n", + g_print("failed to load icon from %s : %s\n", SAMBA_ICON_PATH, error->message); } #if 1 - image = gtk_image_new_from_file(SAMBA_IMAGE_PATH); + image = gtk_image_new_from_file(SAMBA_IMAGE_PATH_SMALL); #else image = gtk_image_new_from_file("/usr/share/pixmaps/redhat-system_settings.png"); #endif + if (image == NULL) { + g_print("failed to load logo from %s : %s\n", + SAMBA_IMAGE_PATH_SMALL, error->message); + } window = gtk_window_new(GTK_WINDOW_TOPLEVEL); state->window_main = window; gtk_window_set_title(GTK_WINDOW(window), "Samba - Join Domain dialogue"); - gtk_widget_set_size_request(GTK_WIDGET(window), 600, 600); /* breite * höhe */ + gtk_widget_set_size_request(GTK_WIDGET(window), 600, 600); gtk_window_set_resizable(GTK_WINDOW(window), FALSE); gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL); @@ -1034,14 +1052,15 @@ static int draw_main_window(struct join_state *state) { /* gtk_box_pack_start(GTK_BOX(main_vbox), image, TRUE, TRUE, 10); */ - gtk_misc_set_alignment(GTK_MISC(image), 0, 0); +/* gtk_misc_set_alignment(GTK_MISC(image), 0, 0); */ + gtk_widget_set_size_request(GTK_WIDGET(image), 150, 40); gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 10); gtk_widget_show(image); /* Label */ label = gtk_label_new("Samba uses the following information to identify your computer on the network."); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0); - gtk_widget_set_size_request(GTK_WIDGET(label), 500, 40); +/* gtk_misc_set_alignment(GTK_MISC(label), 0, 0); */ + gtk_widget_set_size_request(GTK_WIDGET(label), 400, 40); gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_widget_show(label); -- cgit From f78c318eb0b50862b2e6ed6783ee5279af91709c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 4 Jan 2008 15:18:42 +0100 Subject: Add debug switch to netdomjoin. Guenther (This used to be commit 2b221708c07967bccd68e8c7983791b4628405bb) --- source3/lib/netapi/examples/netdomjoin/netdomjoin.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/examples/netdomjoin/netdomjoin.c b/source3/lib/netapi/examples/netdomjoin/netdomjoin.c index e8b529927f..634d265597 100644 --- a/source3/lib/netapi/examples/netdomjoin/netdomjoin.c +++ b/source3/lib/netapi/examples/netdomjoin/netdomjoin.c @@ -1,7 +1,7 @@ /* * Unix SMB/CIFS implementation. * Join Support (cmdline + netapi) - * Copyright (C) Guenther Deschner 2007 + * Copyright (C) Guenther Deschner 2007-2008 * * 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 @@ -56,7 +56,10 @@ int main(int argc, char **argv) if (argc < 2) { printf("usage: netdomjoin\n"); - printf("\t[hostname=HOSTNAME] [domain=DOMAIN] \n"); + printf("\t[hostname] [domain=DOMAIN] " + " " + " " + "\n"); return 0; } @@ -87,6 +90,11 @@ int main(int argc, char **argv) str = get_string_param(argv[i]); libnetapi_set_password(ctx, str); } + if (strncasecmp(argv[i], "debug", strlen("debug"))== 0) { + const char *str = NULL; + str = get_string_param(argv[i]); + libnetapi_set_debuglevel(ctx, str); + } } status = NetJoinDomain(server_name, -- cgit From 0399df22f0f0999338e48d7b9598a7b2f7b9aab5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 4 Jan 2008 17:01:52 +0100 Subject: In libnet_join finally separate the admin from the machine pwd entirely. Guenther (This used to be commit d88bb94f0ef00ddbb48498797bd11448e0d74645) --- source3/lib/netapi/joindomain.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index d200c9b7b0..921f816cbe 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -1,7 +1,7 @@ /* * Unix SMB/CIFS implementation. * NetApi Join Support - * Copyright (C) Guenther Deschner 2007 + * Copyright (C) Guenther Deschner 2007-2008 * * 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 @@ -69,8 +69,8 @@ static WERROR NetJoinDomainLocal(struct libnetapi_ctx *mem_ctx, } if (password) { - r->in.password = talloc_strdup(mem_ctx, password); - W_ERROR_HAVE_NO_MEMORY(r->in.password); + r->in.admin_password = talloc_strdup(mem_ctx, password); + W_ERROR_HAVE_NO_MEMORY(r->in.admin_password); } r->in.join_flags = join_flags; @@ -254,8 +254,8 @@ static WERROR NetUnjoinDomainLocal(struct libnetapi_ctx *mem_ctx, } if (password) { - r->in.password = talloc_strdup(mem_ctx, password); - W_ERROR_HAVE_NO_MEMORY(r->in.password); + r->in.admin_password = talloc_strdup(mem_ctx, password); + W_ERROR_HAVE_NO_MEMORY(r->in.admin_password); } r->in.unjoin_flags = unjoin_flags; -- cgit From 28ef4878d937405340cc1984ef674ad0b670ef0c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 4 Jan 2008 17:11:14 +0100 Subject: Rename server_name to dc_name in libnet join structures. Guenther (This used to be commit ff5e15b1ba0d5c39ceef9f9995c107e510162564) --- source3/lib/netapi/joindomain.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index 921f816cbe..0d4452e1df 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -54,8 +54,9 @@ static WERROR NetJoinDomainLocal(struct libnetapi_ctx *mem_ctx, if (!NT_STATUS_IS_OK(status)) { return ntstatus_to_werror(status); } - r->in.server_name = talloc_strdup(mem_ctx, info->domain_controller_name); - W_ERROR_HAVE_NO_MEMORY(r->in.server_name); + r->in.dc_name = talloc_strdup(mem_ctx, + info->domain_controller_name); + W_ERROR_HAVE_NO_MEMORY(r->in.dc_name); } if (account_ou) { @@ -224,8 +225,8 @@ static WERROR NetUnjoinDomainLocal(struct libnetapi_ctx *mem_ctx, W_ERROR_NOT_OK_RETURN(werr); if (server_name) { - r->in.server_name = talloc_strdup(mem_ctx, server_name); - W_ERROR_HAVE_NO_MEMORY(r->in.server_name); + r->in.dc_name = talloc_strdup(mem_ctx, server_name); + W_ERROR_HAVE_NO_MEMORY(r->in.dc_name); } else { NTSTATUS status; @@ -244,8 +245,9 @@ static WERROR NetUnjoinDomainLocal(struct libnetapi_ctx *mem_ctx, if (!NT_STATUS_IS_OK(status)) { return ntstatus_to_werror(status); } - r->in.server_name = talloc_strdup(mem_ctx, info->domain_controller_name); - W_ERROR_HAVE_NO_MEMORY(r->in.server_name); + r->in.dc_name = talloc_strdup(mem_ctx, + info->domain_controller_name); + W_ERROR_HAVE_NO_MEMORY(r->in.dc_name); } if (account) { -- cgit From 9254bb4ef1c3c3a52ea8e935edb0e7a86ec3ea7a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Jan 2008 12:56:23 -0800 Subject: Refactor the crypto code after a very helpful conversation with Volker. Mostly making sure we have data on the incoming packet type, not stored in the smb header. Jeremy. (This used to be commit c4e5a505043965eec77b5bb9bc60957e8f3b97c8) --- source3/lib/dummysmbd.c | 21 -------------- source3/lib/util_sock.c | 74 ------------------------------------------------- 2 files changed, 95 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/dummysmbd.c b/source3/lib/dummysmbd.c index 464ba92306..dbe886e3d1 100644 --- a/source3/lib/dummysmbd.c +++ b/source3/lib/dummysmbd.c @@ -51,24 +51,3 @@ NTSTATUS can_delete_directory(struct connection_struct *conn, { return NT_STATUS_OK; } - -NTSTATUS srv_decrypt_buffer(char *buf) -{ - return NT_STATUS_OK; -} - -NTSTATUS srv_encrypt_buffer(char *buffer, char **buf_out) -{ - *buf_out = buffer; - return NT_STATUS_OK; -} - -void srv_free_enc_buffer(char *buf) -{ - ; -} - -bool srv_encryption_on(void) -{ - return false; -} diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index b92cd3d624..945506ea77 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1276,80 +1276,6 @@ ssize_t receive_smb_raw(int fd, return len; } -/**************************************************************************** - Wrapper for receive_smb_raw(). - Checks the MAC on signed packets. -****************************************************************************/ - -bool receive_smb(int fd, char *buffer, unsigned int timeout, enum smb_read_errors *pre) -{ - if (receive_smb_raw(fd, buffer, timeout, 0, pre) < 0) { - return false; - } - - if (srv_encryption_on()) { - NTSTATUS status = srv_decrypt_buffer(buffer); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("receive_smb: SMB decryption failed " - "on incoming packet! Error %s\n", - nt_errstr(status) )); - cond_set_smb_read_error(pre, SMB_READ_BAD_DECRYPT); - return false; - } - } - - /* Check the incoming SMB signature. */ - if (!srv_check_sign_mac(buffer, true)) { - DEBUG(0, ("receive_smb: SMB Signature verification " - "failed on incoming packet!\n")); - cond_set_smb_read_error(pre,SMB_READ_BAD_SIG); - return false; - } - - return true; -} - -/**************************************************************************** - Send an smb to a fd. -****************************************************************************/ - -bool send_smb(int fd, char *buffer) -{ - size_t len; - size_t nwritten=0; - ssize_t ret; - char *buf_out = buffer; - - /* Sign the outgoing packet if required. */ - srv_calculate_sign_mac(buf_out); - - if (srv_encryption_on()) { - NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("send_smb: SMB encryption failed " - "on outgoing packet! Error %s\n", - nt_errstr(status) )); - return false; - } - } - - len = smb_len(buf_out) + 4; - - while (nwritten < len) { - ret = write_data(fd,buf_out+nwritten,len - nwritten); - if (ret <= 0) { - DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n", - (int)len,(int)ret, strerror(errno) )); - srv_free_enc_buffer(buf_out); - return false; - } - nwritten += ret; - } - - srv_free_enc_buffer(buf_out); - return true; -} - /**************************************************************************** Open a socket of the specified type, port, and address for incoming data. ****************************************************************************/ -- cgit From 395c366237dec1a38a53248d2e8df17f877207aa Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 4 Jan 2008 22:56:31 +0100 Subject: Do not pass emtpy wkssvc_PasswordBuffers to rpc functions. Guenther (This used to be commit fe75e5ccdfc2609380367e59215637b0de1ef241) --- source3/lib/netapi/joindomain.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index 0d4452e1df..c7849c952f 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -90,13 +90,11 @@ static WERROR NetJoinDomainRemote(struct libnetapi_ctx *ctx, { struct cli_state *cli = NULL; struct rpc_pipe_client *pipe_cli = NULL; - struct wkssvc_PasswordBuffer encrypted_password; + struct wkssvc_PasswordBuffer *encrypted_password = NULL; NTSTATUS status; WERROR werr; unsigned int old_timeout = 0; - ZERO_STRUCT(encrypted_password); - status = cli_full_connection(&cli, NULL, server_name, NULL, 0, "IPC$", "IPC", @@ -129,7 +127,7 @@ static WERROR NetJoinDomainRemote(struct libnetapi_ctx *ctx, status = rpccli_wkssvc_NetrJoinDomain2(pipe_cli, ctx, server_name, domain_name, account_ou, Account, - &encrypted_password, + encrypted_password, join_flags, &werr); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); @@ -277,13 +275,11 @@ static WERROR NetUnjoinDomainRemote(struct libnetapi_ctx *ctx, { struct cli_state *cli = NULL; struct rpc_pipe_client *pipe_cli = NULL; - struct wkssvc_PasswordBuffer encrypted_password; + struct wkssvc_PasswordBuffer *encrypted_password = NULL; NTSTATUS status; WERROR werr; unsigned int old_timeout = 0; - ZERO_STRUCT(encrypted_password); - status = cli_full_connection(&cli, NULL, server_name, NULL, 0, "IPC$", "IPC", @@ -316,7 +312,7 @@ static WERROR NetUnjoinDomainRemote(struct libnetapi_ctx *ctx, status = rpccli_wkssvc_NetrUnjoinDomain2(pipe_cli, ctx, server_name, account, - &encrypted_password, + encrypted_password, unjoin_flags, &werr); if (!NT_STATUS_IS_OK(status)) { -- cgit From 9baa97a46ebb92a5968ceba0fb5c2de51e6fa8f0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 5 Jan 2008 00:23:35 -0800 Subject: Add general '-e' option to enable smb encryption on tools. Jeremy. (This used to be commit 757653966fc1384159bd2d57c5670cd8af0cae96) --- source3/lib/popt_common.c | 6 ++++++ source3/lib/util.c | 14 +++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/popt_common.c b/source3/lib/popt_common.c index b3a84a6f7c..5a9d39d181 100644 --- a/source3/lib/popt_common.c +++ b/source3/lib/popt_common.c @@ -414,6 +414,7 @@ static void get_credentials_file(const char *file) * -N,--no-pass * -S,--signing * -P --machine-pass + * -e --encrypt */ @@ -532,6 +533,10 @@ static void popt_common_credentials_callback(poptContext con, case 'N': set_cmdline_auth_info_password(""); break; + case 'e': + set_cmdline_auth_info_smb_encrypt(); + break; + } } @@ -543,5 +548,6 @@ struct poptOption popt_common_credentials[] = { { "authentication-file", 'A', POPT_ARG_STRING, NULL, 'A', "Get the credentials from a file", "FILE" }, { "signing", 'S', POPT_ARG_STRING, NULL, 'S', "Set the client signing state", "on|off|required" }, {"machine-pass", 'P', POPT_ARG_NONE, NULL, 'P', "Use stored machine account password" }, + {"encrypt", 'e', POPT_ARG_NONE, NULL, 'e', "Encrypt SMB transport (UNIX extended servers only)" }, POPT_TABLEEND }; diff --git a/source3/lib/util.c b/source3/lib/util.c index 7f8a297fac..81b9fc817b 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -289,7 +289,8 @@ static struct user_auth_info cmdline_auth_info = { NULL, /* password */ false, /* got_pass */ false, /* use_kerberos */ - Undefined /* signing state */ + Undefined, /* signing state */ + false /* smb_encrypt */ }; const char *get_cmdline_auth_info_username(void) @@ -362,11 +363,22 @@ void set_cmdline_auth_info_use_krb5_ticket(void) cmdline_auth_info.got_pass = true; } +/* This should only be used by lib/popt_common.c JRA */ +bool set_cmdline_auth_info_smb_encrypt(void) +{ + cmdline_auth_info.smb_encrypt = true; +} + bool get_cmdline_auth_info_got_pass(void) { return cmdline_auth_info.got_pass; } +bool get_cmdline_auth_info_smb_encrypt(void) +{ + return cmdline_auth_info.smb_encrypt; +} + bool get_cmdline_auth_info_copy(struct user_auth_info *info) { *info = cmdline_auth_info; -- cgit From 3d7a8a9fa14625279bcce03654465a88afe6db86 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 5 Jan 2008 01:16:09 -0800 Subject: Fix missing return - should be void. Jeremy. (This used to be commit 45ae90b77e53cd0cdf50939528dac4d2ca39b5c5) --- source3/lib/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/util.c b/source3/lib/util.c index 81b9fc817b..c69a1450a0 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -364,7 +364,7 @@ void set_cmdline_auth_info_use_krb5_ticket(void) } /* This should only be used by lib/popt_common.c JRA */ -bool set_cmdline_auth_info_smb_encrypt(void) +void set_cmdline_auth_info_smb_encrypt(void) { cmdline_auth_info.smb_encrypt = true; } -- cgit From 3ba8fbef29aabfcd78e1170fcbfcf7bc943af6f9 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 5 Jan 2008 23:09:25 +0100 Subject: selftest: Use platform-specific equivalents of LD_LIBRARY_PATH for Samba4's smbtorture. (This used to be commit 64ff1dad8664f14030c7d78c252d946216798a88) --- source3/lib/replace/libreplace_ld.m4 | 167 ++++++++++++++++++++++++++++++++--- 1 file changed, 154 insertions(+), 13 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/replace/libreplace_ld.m4 b/source3/lib/replace/libreplace_ld.m4 index fd85ef9fc4..cb8e21434e 100644 --- a/source3/lib/replace/libreplace_ld.m4 +++ b/source3/lib/replace/libreplace_ld.m4 @@ -1,3 +1,23 @@ +# +# This offers a nice overview how to build shared libraries on all platforms +# http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html +# + +AC_DEFUN([AC_LIBREPLACE_STLD], +[ + AC_PATH_PROG(PROG_AR, ar) + + STLD=${PROG_AR} + + AC_SUBST(STLD) +]) + +AC_DEFUN([AC_LIBREPLACE_STLD_FLAGS], +[ + STLD_FLAGS="-rcs" + AC_SUBST(STLD_FLAGS) +]) + AC_DEFUN([AC_LD_EXPORT_DYNAMIC], [ saved_LDFLAGS="$LDFLAGS" @@ -67,48 +87,102 @@ case "$host_os" in PICFLAG="-KPIC" ;; *darwin*) + PICFLAG="-fno-common" ;; esac AC_SUBST(PICFLAG) ]) -AC_DEFUN([AC_LD_SHLDFLAGS], +AC_DEFUN([AC_LIBREPLACE_LD_SHLIB_LINKER], +[ + LD_SHLIB_LINKER="${CC}" + + case "$host_os" in + *irix*) + LD_SHLIB_LINKER="${PROG_LD}" + ;; + esac + + AC_SUBST(LD_SHLIB_LINKER) +]) + +AC_DEFUN([AC_LIBREPLACE_LD_SHLIB_FLAGS], [ - SHLD_FLAGS="-shared" + LD_SHLIB_FLAGS="-shared" case "$host_os" in *linux*) - SHLD_FLAGS="-shared -Wl,-Bsymbolic" + LD_SHLIB_FLAGS="-shared -Wl,-Bsymbolic" ;; *solaris*) - SHLD_FLAGS="-G" + LD_SHLIB_FLAGS="-G" if test "${GCC}" = "no"; then ## ${CFLAGS} added for building 64-bit shared ## libs using Sun's Compiler - SHLD_FLAGS="-G \${CFLAGS}" + LD_SHLIB_FLAGS="-G \${CFLAGS}" fi ;; *sunos*) - SHLD_FLAGS="-G" + LD_SHLIB_FLAGS="-G" ;; *irix*) - SHLD_FLAGS="-shared" + LD_SHLIB_FLAGS="-shared" ;; *aix*) - SHLD_FLAGS="-Wl,-G,-bexpall,-bbigtoc" + LD_SHLIB_FLAGS="-Wl,-G,-bexpall,-bbigtoc" ;; *hpux*) if test "${GCC}" = "yes"; then - SHLD_FLAGS="-shared" + LD_SHLIB_FLAGS="-shared" else - SHLD_FLAGS="-b" + LD_SHLIB_FLAGS="-b" fi ;; + *osf*) + LD_SHLIB_FLAGS="-shared" + ;; *darwin*) - SHLD_FLAGS="-dynamiclib" + LD_SHLIB_FLAGS="-dynamiclib -Wl,-search_paths_first" ;; esac + AC_SUBST(LD_SHLIB_FLAGS) +]) + +AC_DEFUN([AC_LIBREPLACE_LD_SHLIB_DISALLOW_UNDEF_FLAG], +[ + LD_SHLIB_DISALLOW_UNDEF_FLAG="" + + # + # TODO: enforce error not only warnings + # + # NOTE: -Wl,--no-allow-shlib-undefined isn't what we want... + # as it bails out on broken system libraries + # + case "$host_os" in + *osf*) + LD_SHLIB_DISALLOW_UNDEF_FLAG="-warning_unresolved" + ;; + *darwin*) + LD_SHLIB_DISALLOW_UNDEF_FLAG="-undefined error" + ;; + esac + + AC_SUBST(LD_SHLIB_DISALLOW_UNDEF_FLAG) +]) + +AC_DEFUN([AC_LIBREPLACE_SHLD], +[ + AC_REQUIRE([AC_LIBREPLACE_LD_SHLIB_LINKER]) + SHLD="$LD_SHLIB_LINKER" + AC_SUBST(SHLD) +]) + +AC_DEFUN([AC_LIBREPLACE_SHLD_FLAGS], +[ + AC_REQUIRE([AC_LIBREPLACE_LD_SHLIB_FLAGS]) + AC_REQUIRE([AC_LIBREPLACE_LD_SHLIB_DISALLOW_UNDEF_FLAG]) + SHLD_FLAGS="$LD_SHLIB_FLAGS $LD_SHLIB_DISALLOW_UNDEF_FLAG" AC_SUBST(SHLD_FLAGS) ]) @@ -157,7 +231,7 @@ AC_DEFUN([AC_LD_SONAMEFLAG], SONAMEFLAG="-Wl,-soname," ;; *hpux*) - SONAMEFLAG="-Wl,+h " + SONAMEFLAG="-Wl,+h," ;; *osf*) SONAMEFLAG="-Wl,-soname," @@ -166,7 +240,74 @@ AC_DEFUN([AC_LD_SONAMEFLAG], SONAMEFLAG="-Wl,-soname," ;; *darwin*) - SONAMEFLAG="-install_name " + SONAMEFLAG="#" + ;; + *aix*) + # Not supported + SONAMEFLAG="#" ;; esac ]) + +AC_DEFUN([AC_LIBREPLACE_MDLD], +[ + AC_REQUIRE([AC_LIBREPLACE_LD_SHLIB_LINKER]) + MDLD="$LD_SHLIB_LINKER" + AC_SUBST(MDLD) +]) + +AC_DEFUN([AC_LIBREPLACE_LD_SHLIB_ALLOW_UNDEF_FLAG], +[ + LD_ALLOW_SHLIB_UNDEF_FLAG="" + + case "$host_os" in + *linux*) + LD_SHLIB_ALLOW_UNDEF_FLAG="-Wl,--allow-shlib-undefined" + ;; + *osf*) + LD_SHLIB_ALLOW_UNDEF_FLAG="-expect_unresolved '*'" + ;; + *darwin*) + LD_SHLIB_ALLOW_UNDEF_FLAG="-undefined dynamic_lookup" + ;; + esac + + AC_SUBST(LD_SHLIB_ALLOW_UNDEF_FLAG) +]) + +AC_DEFUN([AC_LIBREPLACE_MDLD_FLAGS], +[ + AC_REQUIRE([AC_LIBREPLACE_LD_SHLIB_FLAGS]) + AC_REQUIRE([AC_LIBREPLACE_LD_SHLIB_ALLOW_UNDEF_FLAG]) + MDLD_FLAGS="$LD_SHLIB_FLAGS $LD_SHLIB_ALLOW_UNDEF_FLAG" + AC_SUBST(MDLD_FLAGS) +]) + +AC_DEFUN([AC_LIBREPLACE_RUNTIME_LIB_PATH_VAR], +[ + case "$host_os" in + *linux*) + LIB_PATH_VAR=LD_LIBRARY_PATH + ;; + *solaris*) + LIB_PATH_VAR=LD_LIBRARY_PATH + ;; + *hpux*) + LIB_PATH_VAR=SHLIB_PATH + ;; + *osf*) + LIB_PATH_VAR=LD_LIBRARY_PATH + ;; + *aix*) + LIB_PATH_VAR=LIB_PATH + ;; + *irix*) + LIB_PATH_VAR=LD_LIBRARY_PATH + ;; + *darwin*) + LIB_PATH_VAR=DYLD_LIBRARY_PATH + ;; + esac + + AC_SUBST(LIB_PATH_VAR) +]) -- cgit From e6c3ac59c5adb433d6269cae7141e575da7fdc8d Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 7 Jan 2008 12:19:56 +0100 Subject: Failure while unjoining a domain is non-critical. Just continue joining to the workgroup in that case. Guenther (This used to be commit bf9ce2a928e3136d3bfe368f75d5b99273c5b04f) --- source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c index d12e66bb26..1e1681ba37 100644 --- a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c +++ b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c @@ -449,14 +449,8 @@ static void callback_do_join(GtkWidget *widget, initial_workgroup_type, state->name_buffer_initial, err_str); - - g_signal_connect_swapped(dialog, "response", - G_CALLBACK(gtk_widget_destroy), - dialog); - - gtk_widget_show(dialog); - - return; + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); } } -- cgit From 68ec31427735e3d127544e52d4107d1e97eeeada Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 7 Jan 2008 12:41:18 +0100 Subject: In gfree_debugsyms() free the format_bufr as well. Guenther (This used to be commit 48f09ca376f9fc7923309f3466e5d72f7c21a56f) --- source3/lib/debug.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/debug.c b/source3/lib/debug.c index 9ea2dc151a..6c1bfea04f 100644 --- a/source3/lib/debug.c +++ b/source3/lib/debug.c @@ -199,6 +199,8 @@ void gfree_debugsyms(void) if ( DEBUGLEVEL_CLASS_ISSET != &debug_all_class_isset_hack ) SAFE_FREE( DEBUGLEVEL_CLASS_ISSET ); + + SAFE_FREE(format_bufr); } /**************************************************************************** -- cgit From be7df54c3912a2db024f19d789d385e99ed98917 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 7 Jan 2008 12:44:25 +0100 Subject: Fix two memleaks in libnetapi. Guenther (This used to be commit d73bde99e8518607bb78b5625ce5fb1991d8e402) --- source3/lib/netapi/netapi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c index 032798d0f9..9c418f254c 100644 --- a/source3/lib/netapi/netapi.c +++ b/source3/lib/netapi/netapi.c @@ -1,7 +1,7 @@ /* * Unix SMB/CIFS implementation. * NetApi Support - * Copyright (C) Guenther Deschner 2007 + * Copyright (C) Guenther Deschner 2007-2008 * * 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 @@ -90,6 +90,9 @@ NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx) gfree_charcnv(); gfree_interfaces(); + gencache_shutdown(); + secrets_shutdown(); + TALLOC_FREE(ctx); TALLOC_FREE(frame); -- cgit From 02f67cfcfa09245e79ecbe41dfadd04f5418253a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 7 Jan 2008 14:15:48 +0100 Subject: Add free_local_machine_name(). Guenther (This used to be commit f3ebb4f96bb0364dae9924e798652e759b63bb52) --- source3/lib/substitute.c | 5 +++++ source3/lib/util.c | 1 + 2 files changed, 6 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/substitute.c b/source3/lib/substitute.c index 80feee9579..59b54c4dff 100644 --- a/source3/lib/substitute.c +++ b/source3/lib/substitute.c @@ -34,6 +34,11 @@ fstring remote_proto="UNKNOWN"; static char *local_machine; +void free_local_machine_name(void) +{ + SAFE_FREE(local_machine); +} + bool set_local_machine_name(const char *local_name, bool perm) { static bool already_perm = false; diff --git a/source3/lib/util.c b/source3/lib/util.c index c69a1450a0..25b2700ae3 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -183,6 +183,7 @@ void gfree_names(void) SAFE_FREE( smb_myworkgroup ); SAFE_FREE( smb_scope ); free_netbios_names_array(); + free_local_machine_name(); } void gfree_all( void ) -- cgit From fa1e5e95d505d28eb50398511f95ebf13a28b4e5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 7 Jan 2008 18:36:06 +0100 Subject: Add NET_API_STATUS_SUCCESS define. Guenther (This used to be commit a72ad63163a8c642ea762087a739e6d63c37647a) --- source3/lib/netapi/netapi.c | 18 +++++++++--------- source3/lib/netapi/netapi.h | 6 +++++- 2 files changed, 14 insertions(+), 10 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c index 9c418f254c..a37ed7c072 100644 --- a/source3/lib/netapi/netapi.c +++ b/source3/lib/netapi/netapi.c @@ -32,7 +32,7 @@ NET_API_STATUS libnetapi_init(struct libnetapi_ctx **context) if (stat_ctx && libnetapi_initialized) { *context = stat_ctx; - return W_ERROR_V(WERR_OK); + return NET_API_STATUS_SUCCESS; } frame = talloc_stackframe(); @@ -69,14 +69,14 @@ NET_API_STATUS libnetapi_init(struct libnetapi_ctx **context) *context = stat_ctx = ctx; - return W_ERROR_V(WERR_OK); + return NET_API_STATUS_SUCCESS; } NET_API_STATUS libnetapi_getctx(struct libnetapi_ctx **ctx) { if (stat_ctx) { *ctx = stat_ctx; - return W_ERROR_V(WERR_OK); + return NET_API_STATUS_SUCCESS; } return libnetapi_init(ctx); @@ -98,7 +98,7 @@ NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx) gfree_debugsyms(); - return W_ERROR_V(WERR_OK); + return NET_API_STATUS_SUCCESS; } NET_API_STATUS libnetapi_set_debuglevel(struct libnetapi_ctx *ctx, @@ -109,14 +109,14 @@ NET_API_STATUS libnetapi_set_debuglevel(struct libnetapi_ctx *ctx, if (!debug_parse_levels(debuglevel)) { return W_ERROR_V(WERR_GENERAL_FAILURE); } - return W_ERROR_V(WERR_OK); + return NET_API_STATUS_SUCCESS; } NET_API_STATUS libnetapi_get_debuglevel(struct libnetapi_ctx *ctx, const char **debuglevel) { *debuglevel = ctx->debuglevel; - return W_ERROR_V(WERR_OK); + return NET_API_STATUS_SUCCESS; } NET_API_STATUS libnetapi_set_username(struct libnetapi_ctx *ctx, @@ -127,7 +127,7 @@ NET_API_STATUS libnetapi_set_username(struct libnetapi_ctx *ctx, if (!ctx->username) { return W_ERROR_V(WERR_NOMEM); } - return W_ERROR_V(WERR_OK); + return NET_API_STATUS_SUCCESS; } NET_API_STATUS libnetapi_set_password(struct libnetapi_ctx *ctx, @@ -138,7 +138,7 @@ NET_API_STATUS libnetapi_set_password(struct libnetapi_ctx *ctx, if (!ctx->password) { return W_ERROR_V(WERR_NOMEM); } - return W_ERROR_V(WERR_OK); + return NET_API_STATUS_SUCCESS; } NET_API_STATUS libnetapi_set_workgroup(struct libnetapi_ctx *ctx, @@ -149,7 +149,7 @@ NET_API_STATUS libnetapi_set_workgroup(struct libnetapi_ctx *ctx, if (!ctx->workgroup) { return W_ERROR_V(WERR_NOMEM); } - return W_ERROR_V(WERR_OK); + return NET_API_STATUS_SUCCESS; } const char *libnetapi_errstr(struct libnetapi_ctx *ctx, diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h index 0dd6d95ceb..2c6e126949 100644 --- a/source3/lib/netapi/netapi.h +++ b/source3/lib/netapi/netapi.h @@ -1,7 +1,7 @@ /* * Unix SMB/CIFS implementation. * NetApi Support - * Copyright (C) Guenther Deschner 2007 + * Copyright (C) Guenther Deschner 2007-2008 * * 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 @@ -21,6 +21,10 @@ #define __LIB_NETAPI_H__ #define NET_API_STATUS uint32_t +#define NET_API_STATUS_SUCCESS 0 + +/**************************************************************** +****************************************************************/ struct libnetapi_ctx { const char *debuglevel; -- cgit From cc1982ab1cb436a9410699bac5bafa7c6077530a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 7 Jan 2008 18:37:04 +0100 Subject: Close registry in libnetapi_free(). Guenther (This used to be commit e7258a4408e40686ff090d0f8e120ce78acbd097) --- source3/lib/netapi/netapi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c index a37ed7c072..33ca67ec85 100644 --- a/source3/lib/netapi/netapi.c +++ b/source3/lib/netapi/netapi.c @@ -92,6 +92,7 @@ NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx) gencache_shutdown(); secrets_shutdown(); + regdb_close(); TALLOC_FREE(ctx); TALLOC_FREE(frame); -- cgit From 0b92d8bc79172dc587f53ce4b35a8fa3128ae0ea Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 7 Jan 2008 18:40:25 +0100 Subject: Free libnet_JoinCtx after joining. Guenther (This used to be commit 5abae9ef15fa9884c5c4a0e256274f70f6ecd779) --- source3/lib/netapi/joindomain.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index c7849c952f..8fe6193f40 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -77,7 +77,10 @@ static WERROR NetJoinDomainLocal(struct libnetapi_ctx *mem_ctx, r->in.join_flags = join_flags; r->in.modify_config = true; - return libnet_Join(mem_ctx, r); + werr = libnet_Join(mem_ctx, r); + TALLOC_FREE(r); + + return werr; } static WERROR NetJoinDomainRemote(struct libnetapi_ctx *ctx, -- cgit From 528d253cc834235213f29411a058485681260140 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 7 Jan 2008 18:41:49 +0100 Subject: Rearrange order of libnet join context init. Guenther (This used to be commit 89669c66f27fb47c9769d1058e29bff83f862752) --- source3/lib/netapi/joindomain.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index 8fe6193f40..ceb7ca10d9 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -33,13 +33,13 @@ static WERROR NetJoinDomainLocal(struct libnetapi_ctx *mem_ctx, struct libnet_JoinCtx *r = NULL; WERROR werr; - werr = libnet_init_JoinCtx(mem_ctx, &r); - W_ERROR_NOT_OK_RETURN(werr); - if (!domain_name) { return WERR_INVALID_PARAM; } + werr = libnet_init_JoinCtx(mem_ctx, &r); + W_ERROR_NOT_OK_RETURN(werr); + r->in.domain_name = talloc_strdup(mem_ctx, domain_name); W_ERROR_HAVE_NO_MEMORY(r->in.domain_name); -- cgit From 1fba8c801934233e754710dd477cafdab97841bd Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 7 Jan 2008 20:01:28 +0100 Subject: Let libnetapi use it's own krb5 cred cache in memory if necessary. Guenther (This used to be commit 863fb30038e384585502f0154a742481594b99d0) --- source3/lib/netapi/netapi.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c index 33ca67ec85..6d27b99d96 100644 --- a/source3/lib/netapi/netapi.c +++ b/source3/lib/netapi/netapi.c @@ -26,9 +26,13 @@ struct libnetapi_ctx *stat_ctx = NULL; TALLOC_CTX *frame = NULL; static bool libnetapi_initialized = false; +/**************************************************************** +****************************************************************/ + NET_API_STATUS libnetapi_init(struct libnetapi_ctx **context) { struct libnetapi_ctx *ctx = NULL; + char *krb5_cc_env = NULL; if (stat_ctx && libnetapi_initialized) { *context = stat_ctx; @@ -65,6 +69,12 @@ NET_API_STATUS libnetapi_init(struct libnetapi_ctx **context) BlockSignals(True, SIGPIPE); + krb5_cc_env = getenv(KRB5_ENV_CCNAME); + if (!krb5_cc_env || (strlen(krb5_cc_env) == 0)) { + ctx->krb5_cc_env = talloc_strdup(frame, "MEMORY:libnetapi"); + setenv(KRB5_ENV_CCNAME, ctx->krb5_cc_env, 1); + } + libnetapi_initialized = true; *context = stat_ctx = ctx; @@ -72,6 +82,9 @@ NET_API_STATUS libnetapi_init(struct libnetapi_ctx **context) return NET_API_STATUS_SUCCESS; } +/**************************************************************** +****************************************************************/ + NET_API_STATUS libnetapi_getctx(struct libnetapi_ctx **ctx) { if (stat_ctx) { @@ -82,6 +95,9 @@ NET_API_STATUS libnetapi_getctx(struct libnetapi_ctx **ctx) return libnetapi_init(ctx); } +/**************************************************************** +****************************************************************/ + NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx) { gfree_names(); @@ -94,6 +110,11 @@ NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx) secrets_shutdown(); regdb_close(); + if (ctx->krb5_cc_env && + (strequal(ctx->krb5_cc_env, getenv(KRB5_ENV_CCNAME)))) { + unsetenv(KRB5_ENV_CCNAME); + } + TALLOC_FREE(ctx); TALLOC_FREE(frame); @@ -102,6 +123,9 @@ NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx) return NET_API_STATUS_SUCCESS; } +/**************************************************************** +****************************************************************/ + NET_API_STATUS libnetapi_set_debuglevel(struct libnetapi_ctx *ctx, const char *debuglevel) { @@ -113,6 +137,9 @@ NET_API_STATUS libnetapi_set_debuglevel(struct libnetapi_ctx *ctx, return NET_API_STATUS_SUCCESS; } +/**************************************************************** +****************************************************************/ + NET_API_STATUS libnetapi_get_debuglevel(struct libnetapi_ctx *ctx, const char **debuglevel) { @@ -120,6 +147,9 @@ NET_API_STATUS libnetapi_get_debuglevel(struct libnetapi_ctx *ctx, return NET_API_STATUS_SUCCESS; } +/**************************************************************** +****************************************************************/ + NET_API_STATUS libnetapi_set_username(struct libnetapi_ctx *ctx, const char *username) { @@ -153,6 +183,9 @@ NET_API_STATUS libnetapi_set_workgroup(struct libnetapi_ctx *ctx, return NET_API_STATUS_SUCCESS; } +/**************************************************************** +****************************************************************/ + const char *libnetapi_errstr(struct libnetapi_ctx *ctx, NET_API_STATUS status) { -- cgit From 1b3520db8836437b9d4d48fab4df69126c1d9b5d Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 7 Jan 2008 20:03:32 +0100 Subject: Add krb5 cc env to libnetapi_ctx. Guenther (This used to be commit df2b078fa1658bdbff1280f7fe0b062d9eabd60c) --- source3/lib/netapi/netapi.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h index 2c6e126949..3c9d3b3853 100644 --- a/source3/lib/netapi/netapi.h +++ b/source3/lib/netapi/netapi.h @@ -31,8 +31,12 @@ struct libnetapi_ctx { char *username; char *workgroup; char *password; + char *krb5_cc_env; }; +/**************************************************************** +****************************************************************/ + NET_API_STATUS libnetapi_init(struct libnetapi_ctx **ctx); NET_API_STATUS libnetapi_getctx(struct libnetapi_ctx **ctx); NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx); -- cgit From 751fc874bec2cbc93b4a84067f3e7102f39bd76c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 7 Jan 2008 20:06:41 +0100 Subject: Add libnetapi_set_error_string and libnetapi_get_error_string. Guenther (This used to be commit f8806bad8134d544229c426f58bee143ba752cf8) --- source3/lib/netapi/netapi.c | 27 +++++++++++++++++++++++++-- source3/lib/netapi/netapi.h | 10 ++++++++-- 2 files changed, 33 insertions(+), 4 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c index 6d27b99d96..d5527dc4ff 100644 --- a/source3/lib/netapi/netapi.c +++ b/source3/lib/netapi/netapi.c @@ -130,7 +130,7 @@ NET_API_STATUS libnetapi_set_debuglevel(struct libnetapi_ctx *ctx, const char *debuglevel) { AllowDebugChange = true; - ctx->debuglevel = debuglevel; + ctx->debuglevel = talloc_strdup(ctx, debuglevel); if (!debug_parse_levels(debuglevel)) { return W_ERROR_V(WERR_GENERAL_FAILURE); } @@ -141,7 +141,7 @@ NET_API_STATUS libnetapi_set_debuglevel(struct libnetapi_ctx *ctx, ****************************************************************/ NET_API_STATUS libnetapi_get_debuglevel(struct libnetapi_ctx *ctx, - const char **debuglevel) + char **debuglevel) { *debuglevel = ctx->debuglevel; return NET_API_STATUS_SUCCESS; @@ -195,3 +195,26 @@ const char *libnetapi_errstr(struct libnetapi_ctx *ctx, return get_friendly_werror_msg(W_ERROR(status)); } + +/**************************************************************** +****************************************************************/ + +NET_API_STATUS libnetapi_set_error_string(struct libnetapi_ctx *ctx, + const char *error_string) +{ + TALLOC_FREE(ctx->error_string); + ctx->error_string = talloc_strdup(ctx, error_string); + if (!ctx->error_string) { + return W_ERROR_V(WERR_NOMEM); + } + return NET_API_STATUS_SUCCESS; + +} + +/**************************************************************** +****************************************************************/ + +const char *libnetapi_get_error_string(struct libnetapi_ctx *ctx) +{ + return ctx->error_string; +} diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h index 3c9d3b3853..46dd8e1a24 100644 --- a/source3/lib/netapi/netapi.h +++ b/source3/lib/netapi/netapi.h @@ -27,7 +27,8 @@ ****************************************************************/ struct libnetapi_ctx { - const char *debuglevel; + char *debuglevel; + char *error_string; char *username; char *workgroup; char *password; @@ -41,11 +42,16 @@ NET_API_STATUS libnetapi_init(struct libnetapi_ctx **ctx); NET_API_STATUS libnetapi_getctx(struct libnetapi_ctx **ctx); NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx); NET_API_STATUS libnetapi_set_debuglevel(struct libnetapi_ctx *ctx, const char *debuglevel); -NET_API_STATUS libnetapi_get_debuglevel(struct libnetapi_ctx *ctx, const char **debuglevel); +NET_API_STATUS libnetapi_get_debuglevel(struct libnetapi_ctx *ctx, char **debuglevel); NET_API_STATUS libnetapi_set_username(struct libnetapi_ctx *ctx, const char *username); NET_API_STATUS libnetapi_set_password(struct libnetapi_ctx *ctx, const char *password); NET_API_STATUS libnetapi_set_workgroup(struct libnetapi_ctx *ctx, const char *workgroup); const char *libnetapi_errstr(struct libnetapi_ctx *ctx, NET_API_STATUS status); +NET_API_STATUS libnetapi_set_error_string(struct libnetapi_ctx *ctx, const char *error_string); +const char *libnetapi_get_error_string(struct libnetapi_ctx *ctx); + +/**************************************************************** +****************************************************************/ /* wkssvc */ NET_API_STATUS NetJoinDomain(const char *server, -- cgit From d6659f8ac84d5b3f19fb16a739657240f835c358 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 7 Jan 2008 20:08:45 +0100 Subject: In the local path of NetJoinDomain, try to get error string from libnetjoin. Guenther (This used to be commit 0f0f0e13022da584b77e850fec2cef6169e1ac28) --- source3/lib/netapi/joindomain.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index ceb7ca10d9..aa8ec6e0b5 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -78,6 +78,9 @@ static WERROR NetJoinDomainLocal(struct libnetapi_ctx *mem_ctx, r->in.modify_config = true; werr = libnet_Join(mem_ctx, r); + if (!W_ERROR_IS_OK(werr) && r->out.error_string) { + libnetapi_set_error_string(mem_ctx, r->out.error_string); + } TALLOC_FREE(r); return werr; -- cgit From 74fc0bf9e5f4fe21b80a4b6df144d780e1bb943a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 7 Jan 2008 20:10:47 +0100 Subject: In libnetapi example, use libnetapi_get_error_string(). Guenther (This used to be commit b624db92d61809a44881abbdd09dfa3a74ff7a88) --- source3/lib/netapi/examples/netdomjoin/netdomjoin.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/examples/netdomjoin/netdomjoin.c b/source3/lib/netapi/examples/netdomjoin/netdomjoin.c index 634d265597..a0ac0b1e56 100644 --- a/source3/lib/netapi/examples/netdomjoin/netdomjoin.c +++ b/source3/lib/netapi/examples/netdomjoin/netdomjoin.c @@ -104,7 +104,12 @@ int main(int argc, char **argv) password, join_flags); if (status != 0) { - printf("Join failed with: %s\n", libnetapi_errstr(ctx, status)); + const char *errstr = NULL; + errstr = libnetapi_get_error_string(ctx); + if (!errstr) { + errstr = libnetapi_errstr(ctx, status); + } + printf("Join failed with: %s\n", errstr); } else { printf("Successfully joined\n"); } -- cgit From 8d261ee580f7d589920eb405a68aec04e6cc8e7a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 6 Jan 2008 17:25:20 +0100 Subject: talloc_stackframe only needs 1 talloc (This used to be commit c0c2084d40b79e949dab7c68626aa665b9ea1a8e) --- source3/lib/talloc_stack.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/talloc_stack.c b/source3/lib/talloc_stack.c index e6e4ed321a..cc7ce3a518 100644 --- a/source3/lib/talloc_stack.c +++ b/source3/lib/talloc_stack.c @@ -41,16 +41,18 @@ static int talloc_stacksize; static TALLOC_CTX **talloc_stack; -static int talloc_pop(int *ptr) +static int talloc_pop(TALLOC_CTX *frame) { - int tos = *ptr; int i; - for (i=talloc_stacksize-1; i>=tos; i--) { + for (i=talloc_stacksize-1; i>0; i--) { + if (frame == talloc_stack[i]) { + break; + } talloc_free(talloc_stack[i]); } - talloc_stacksize = tos; + talloc_stacksize = i; return 0; } @@ -64,7 +66,6 @@ static int talloc_pop(int *ptr) TALLOC_CTX *talloc_stackframe(void) { TALLOC_CTX **tmp, *top; - int *cleanup; if (!(tmp = TALLOC_REALLOC_ARRAY(NULL, talloc_stack, TALLOC_CTX *, talloc_stacksize + 1))) { @@ -77,12 +78,7 @@ TALLOC_CTX *talloc_stackframe(void) goto fail; } - if (!(cleanup = talloc(top, int))) { - goto fail; - } - - *cleanup = talloc_stacksize; - talloc_set_destructor(cleanup, talloc_pop); + talloc_set_destructor(top, talloc_pop); talloc_stack[talloc_stacksize++] = top; -- cgit From 6dc988c918d7909b6eec052e6c3511467e9be697 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 7 Jan 2008 00:14:24 +0100 Subject: Change db_tdb_fetch_locked to use only one talloc (This used to be commit 921c8657e2eeb71d5b9ae2675255a852b26cc30d) --- source3/lib/dbwrap_tdb.c | 88 +++++++++++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 35 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/dbwrap_tdb.c b/source3/lib/dbwrap_tdb.c index b24fd0618a..cce987d789 100644 --- a/source3/lib/dbwrap_tdb.c +++ b/source3/lib/dbwrap_tdb.c @@ -43,33 +43,50 @@ static int db_tdb_record_destr(struct db_record* data) return 0; } -static struct db_record *db_tdb_fetch_locked(struct db_context *db, - TALLOC_CTX *mem_ctx, TDB_DATA key) -{ - struct db_tdb_ctx *ctx = talloc_get_type_abort(db->private_data, - struct db_tdb_ctx); +struct tdb_fetch_locked_state { + TALLOC_CTX *mem_ctx; struct db_record *result; - TDB_DATA value; +}; - result = TALLOC_P(mem_ctx, struct db_record); - if (result == NULL) { - DEBUG(0, ("talloc failed\n")); - return NULL; +static int db_tdb_fetchlock_parse(TDB_DATA key, TDB_DATA data, + void *private_data) +{ + struct tdb_fetch_locked_state *state = + (struct tdb_fetch_locked_state *)private_data; + + state->result = (struct db_record *)talloc_size( + state->mem_ctx, + sizeof(struct db_record) + key.dsize + data.dsize); + + if (state->result == NULL) { + return 0; } - result->key.dsize = key.dsize; - result->key.dptr = (uint8 *)talloc_memdup(result, key.dptr, key.dsize); - if (result->key.dptr == NULL) { - DEBUG(0, ("talloc failed\n")); - TALLOC_FREE(result); - return NULL; + state->result->key.dsize = key.dsize; + state->result->key.dptr = ((uint8 *)state->result) + + sizeof(struct db_record); + memcpy(state->result->key.dptr, key.dptr, key.dsize); + + state->result->value.dsize = data.dsize; + + if (data.dsize > 0) { + state->result->value.dptr = state->result->key.dptr + key.dsize; + memcpy(state->result->value.dptr, data.dptr, data.dsize); } + else { + state->result->value.dptr = NULL; + } + + return 0; +} - result->value.dptr = NULL; - result->value.dsize = 0; - result->private_data = talloc_reference(result, ctx); - result->store = db_tdb_store; - result->delete_rec = db_tdb_delete; +static struct db_record *db_tdb_fetch_locked(struct db_context *db, + TALLOC_CTX *mem_ctx, TDB_DATA key) +{ + struct db_tdb_ctx *ctx = talloc_get_type_abort(db->private_data, + struct db_tdb_ctx); + struct tdb_fetch_locked_state state; + int res; if (DEBUGLEVEL >= 10) { char *keystr = hex_encode(NULL, key.dptr, key.dsize); @@ -81,32 +98,33 @@ static struct db_record *db_tdb_fetch_locked(struct db_context *db, if (tdb_chainlock(ctx->wtdb->tdb, key) != 0) { DEBUG(3, ("tdb_chainlock failed\n")); - TALLOC_FREE(result); return NULL; } - talloc_set_destructor(result, db_tdb_record_destr); + state.mem_ctx = mem_ctx; + state.result = NULL; - value = tdb_fetch(ctx->wtdb->tdb, key); + res = tdb_parse_record(ctx->wtdb->tdb, key, db_tdb_fetchlock_parse, + &state); - if (value.dptr == NULL) { - return result; + if (state.result == NULL) { + db_tdb_fetchlock_parse(key, tdb_null, &state); } - result->value.dsize = value.dsize; - result->value.dptr = (uint8 *)talloc_memdup(result, value.dptr, - value.dsize); - if (result->value.dptr == NULL) { - DEBUG(3, ("talloc failed\n")); - TALLOC_FREE(result); + if (state.result == NULL) { + tdb_chainunlock(ctx->wtdb->tdb, key); return NULL; } - SAFE_FREE(value.dptr); + talloc_set_destructor(state.result, db_tdb_record_destr); - DEBUG(10, ("Allocated locked data 0x%p\n", result)); + state.result->private_data = talloc_reference(state.result, ctx); + state.result->store = db_tdb_store; + state.result->delete_rec = db_tdb_delete; - return result; + DEBUG(10, ("Allocated locked data 0x%p\n", state.result)); + + return state.result; } static int db_tdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, -- cgit From c3c19615c16a2a2dc7d3620d7117b9f261e5c35a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 7 Jan 2008 00:41:26 +0100 Subject: make db_tdb_fetch use tdb_parse_record (This used to be commit 88d82d0623e71ae1ef4f8fdefba10e3a230ea526) --- source3/lib/dbwrap_tdb.c | 46 +++++++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 13 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/dbwrap_tdb.c b/source3/lib/dbwrap_tdb.c index cce987d789..83a0d111aa 100644 --- a/source3/lib/dbwrap_tdb.c +++ b/source3/lib/dbwrap_tdb.c @@ -70,7 +70,7 @@ static int db_tdb_fetchlock_parse(TDB_DATA key, TDB_DATA data, state->result->value.dsize = data.dsize; if (data.dsize > 0) { - state->result->value.dptr = state->result->key.dptr + key.dsize; + state->result->value.dptr = state->result->key.dptr+key.dsize; memcpy(state->result->value.dptr, data.dptr, data.dsize); } else { @@ -127,29 +127,49 @@ static struct db_record *db_tdb_fetch_locked(struct db_context *db, return state.result; } +struct tdb_fetch_state { + TALLOC_CTX *mem_ctx; + int result; + TDB_DATA data; +}; + +static int db_tdb_fetch_parse(TDB_DATA key, TDB_DATA data, + void *private_data) +{ + struct tdb_fetch_state *state = + (struct tdb_fetch_state *)private_data; + + state->data.dptr = (uint8 *)talloc_memdup(state->mem_ctx, data.dptr, + data.dsize); + if (state->data.dptr == NULL) { + state->result = -1; + return 0; + } + + state->data.dsize = data.dsize; + return 0; +} + static int db_tdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, TDB_DATA key, TDB_DATA *pdata) { struct db_tdb_ctx *ctx = talloc_get_type_abort( db->private_data, struct db_tdb_ctx); - TDB_DATA data; - - data = tdb_fetch(ctx->wtdb->tdb, key); + struct tdb_fetch_state state; - if (data.dptr == NULL) { - pdata->dptr = NULL; - pdata->dsize = 0; - return 0; - } + state.mem_ctx = mem_ctx; + state.result = 0; + state.data.dptr = NULL; + state.data.dsize = 0; - pdata->dptr = (uint8 *)talloc_memdup(mem_ctx, data.dptr, data.dsize); - SAFE_FREE(data.dptr); + tdb_parse_record(ctx->wtdb->tdb, key, db_tdb_fetch_parse, &state); - if (pdata->dptr == NULL) { + if (state.result == -1) { return -1; } - pdata->dsize = data.dsize; + + *pdata = state.data; return 0; } -- cgit From e3ea1e1391a10fb1f4708abab038c0cfc2b86b41 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 7 Jan 2008 22:48:19 +0100 Subject: Enable talloc reporting in libnetapi if DEVELOPER compiled. Guenther (This used to be commit 01e9151546a83e0c772a144efa85437ca0c8a307) --- source3/lib/netapi/netapi.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c index d5527dc4ff..61b51909c9 100644 --- a/source3/lib/netapi/netapi.c +++ b/source3/lib/netapi/netapi.c @@ -39,6 +39,9 @@ NET_API_STATUS libnetapi_init(struct libnetapi_ctx **context) return NET_API_STATUS_SUCCESS; } +#ifdef DEVELOPER + talloc_enable_leak_report(); +#endif frame = talloc_stackframe(); ctx = talloc_zero(frame, struct libnetapi_ctx); -- cgit From 62e9d503d82d645cf29af643732ad97c0eb8b340 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 7 Jan 2008 23:53:34 +0100 Subject: Remove redundant parameter fd from SMB_VFS_SYS_ACL_GET_FD(). Michael (This used to be commit 42663e8736e1a3dfb57e0aafdcbf5fec880da779) --- source3/lib/sysacls.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/sysacls.c b/source3/lib/sysacls.c index 3e61f42aa5..f23d03f706 100644 --- a/source3/lib/sysacls.c +++ b/source3/lib/sysacls.c @@ -364,9 +364,9 @@ SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle, return posixacl_sys_acl_get_file(handle, path_p, type); } -SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd) +SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp) { - return posixacl_sys_acl_get_fd(handle, fsp, fd); + return posixacl_sys_acl_get_fd(handle, fsp); } int sys_acl_set_file(vfs_handle_struct *handle, @@ -395,9 +395,9 @@ SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle, return aixacl_sys_acl_get_file(handle, path_p, type); } -SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd) +SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp) { - return aixacl_sys_acl_get_fd(handle, fsp, fd); + return aixacl_sys_acl_get_fd(handle, fsp); } int sys_acl_set_file(vfs_handle_struct *handle, @@ -426,9 +426,9 @@ SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle, return tru64acl_sys_acl_get_file(handle, path_p, type); } -SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd) +SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp) { - return tru64acl_sys_acl_get_fd(handle, fsp, fd); + return tru64acl_sys_acl_get_fd(handle, fsp); } int sys_acl_set_file(vfs_handle_struct *handle, @@ -457,9 +457,9 @@ SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle, return solarisacl_sys_acl_get_file(handle, path_p, type); } -SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd) +SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp) { - return solarisacl_sys_acl_get_fd(handle, fsp, fd); + return solarisacl_sys_acl_get_fd(handle, fsp); } int sys_acl_set_file(vfs_handle_struct *handle, @@ -488,9 +488,9 @@ SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle, return hpuxacl_sys_acl_get_file(handle, path_p, type); } -SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd) +SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp) { - return hpuxacl_sys_acl_get_fd(handle, fsp, fd); + return hpuxacl_sys_acl_get_fd(handle, fsp); } int sys_acl_set_file(vfs_handle_struct *handle, @@ -519,9 +519,9 @@ SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle, return irixacl_sys_acl_get_file(handle, path_p, type); } -SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd) +SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp) { - return irixacl_sys_acl_get_fd(handle, fsp, fd); + return irixacl_sys_acl_get_fd(handle, fsp); } int sys_acl_set_file(vfs_handle_struct *handle, @@ -555,7 +555,7 @@ SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle, return NULL; } -SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd) +SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp) { #ifdef ENOTSUP errno = ENOTSUP; -- cgit From 5921607f2647cec20a6bcebd17c5a0c53449c1ba Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 8 Jan 2008 01:54:19 +0100 Subject: Remove redundant parameter fd from SMB_VFS_SYS_ACL_SET_FD(). Michael (This used to be commit 9296e93588c0e795cae770765050247ac1474a74) --- source3/lib/sysacls.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/sysacls.c b/source3/lib/sysacls.c index f23d03f706..9c1256ed65 100644 --- a/source3/lib/sysacls.c +++ b/source3/lib/sysacls.c @@ -3,7 +3,7 @@ Samba system utilities for ACL support. Copyright (C) Jeremy Allison 2000. Copyright (C) Volker Lendecke 2006 - Copyright (C) Michael Adam 2006 + Copyright (C) Michael Adam 2006,2008 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 @@ -376,9 +376,9 @@ int sys_acl_set_file(vfs_handle_struct *handle, } int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, - int fd, SMB_ACL_T acl_d) + SMB_ACL_T acl_d) { - return posixacl_sys_acl_set_fd(handle, fsp, fd, acl_d); + return posixacl_sys_acl_set_fd(handle, fsp, acl_d); } int sys_acl_delete_def_file(vfs_handle_struct *handle, @@ -407,9 +407,9 @@ int sys_acl_set_file(vfs_handle_struct *handle, } int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, - int fd, SMB_ACL_T acl_d) + SMB_ACL_T acl_d) { - return aixacl_sys_acl_set_fd(handle, fsp, fd, acl_d); + return aixacl_sys_acl_set_fd(handle, fsp, acl_d); } int sys_acl_delete_def_file(vfs_handle_struct *handle, @@ -438,9 +438,9 @@ int sys_acl_set_file(vfs_handle_struct *handle, } int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, - int fd, SMB_ACL_T acl_d) + SMB_ACL_T acl_d) { - return tru64acl_sys_acl_set_fd(handle, fsp, fd, acl_d); + return tru64acl_sys_acl_set_fd(handle, fsp, acl_d); } int sys_acl_delete_def_file(vfs_handle_struct *handle, @@ -469,9 +469,9 @@ int sys_acl_set_file(vfs_handle_struct *handle, } int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, - int fd, SMB_ACL_T acl_d) + SMB_ACL_T acl_d) { - return solarisacl_sys_acl_set_fd(handle, fsp, fd, acl_d); + return solarisacl_sys_acl_set_fd(handle, fsp, acl_d); } int sys_acl_delete_def_file(vfs_handle_struct *handle, @@ -500,9 +500,9 @@ int sys_acl_set_file(vfs_handle_struct *handle, } int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, - int fd, SMB_ACL_T acl_d) + SMB_ACL_T acl_d) { - return hpuxacl_sys_acl_set_fd(handle, fsp, fd, acl_d); + return hpuxacl_sys_acl_set_fd(handle, fsp, acl_d); } int sys_acl_delete_def_file(vfs_handle_struct *handle, @@ -531,9 +531,9 @@ int sys_acl_set_file(vfs_handle_struct *handle, } int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, - int fd, SMB_ACL_T acl_d) + SMB_ACL_T acl_d) { - return irixacl_sys_acl_set_fd(handle, fsp, fd, acl_d); + return irixacl_sys_acl_set_fd(handle, fsp, acl_d); } int sys_acl_delete_def_file(vfs_handle_struct *handle, @@ -577,7 +577,7 @@ int sys_acl_set_file(vfs_handle_struct *handle, } int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, - int fd, SMB_ACL_T acl_d) + SMB_ACL_T acl_d) { #ifdef ENOTSUP errno = ENOTSUP; -- cgit From ab216a1b4ea585faa42be4908a24a475173683d2 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 8 Jan 2008 11:49:35 +0100 Subject: Fix crash bug when strequal is used too late in libnetapi_free. Guenther (This used to be commit ba2b8a310e1d6f78116350e24c17ae4db08b9bed) --- source3/lib/netapi/netapi.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c index 61b51909c9..3516105353 100644 --- a/source3/lib/netapi/netapi.c +++ b/source3/lib/netapi/netapi.c @@ -103,6 +103,14 @@ NET_API_STATUS libnetapi_getctx(struct libnetapi_ctx **ctx) NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx) { + + if (ctx->krb5_cc_env) { + char *env = getenv(KRB5_ENV_CCNAME); + if (env && (strequal(ctx->krb5_cc_env, env))) { + unsetenv(KRB5_ENV_CCNAME); + } + } + gfree_names(); gfree_loadparm(); gfree_case_tables(); @@ -113,11 +121,6 @@ NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx) secrets_shutdown(); regdb_close(); - if (ctx->krb5_cc_env && - (strequal(ctx->krb5_cc_env, getenv(KRB5_ENV_CCNAME)))) { - unsetenv(KRB5_ENV_CCNAME); - } - TALLOC_FREE(ctx); TALLOC_FREE(frame); -- cgit From a01dc30db7cb16c794f5daf23ad2df607f891626 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 8 Jan 2008 11:53:38 +0100 Subject: Add NetApiBufferFree() to libnetapi. Guenther (This used to be commit c49196954d38f0c2851abbfe25086cd6fe660a2e) --- source3/lib/netapi/netapi.c | 14 ++++++++++++++ source3/lib/netapi/netapi.h | 5 +++++ 2 files changed, 19 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c index 3516105353..d4cb3a9fe2 100644 --- a/source3/lib/netapi/netapi.c +++ b/source3/lib/netapi/netapi.c @@ -224,3 +224,17 @@ const char *libnetapi_get_error_string(struct libnetapi_ctx *ctx) { return ctx->error_string; } + +/**************************************************************** +****************************************************************/ + +NET_API_STATUS NetApiBufferFree(void *buffer) +{ + if (!buffer) { + return W_ERROR_V(WERR_INSUFFICIENT_BUFFER); + } + + talloc_free(buffer); + + return NET_API_STATUS_SUCCESS; +} diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h index 46dd8e1a24..4a40b32fc9 100644 --- a/source3/lib/netapi/netapi.h +++ b/source3/lib/netapi/netapi.h @@ -53,6 +53,11 @@ const char *libnetapi_get_error_string(struct libnetapi_ctx *ctx); /**************************************************************** ****************************************************************/ +NET_API_STATUS NetApiBufferFree(void *buffer); + +/**************************************************************** +****************************************************************/ + /* wkssvc */ NET_API_STATUS NetJoinDomain(const char *server, const char *domain, -- cgit From 200bba3ad6592952041daa9da9805941c6dd03ba Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 8 Jan 2008 11:54:51 +0100 Subject: Make name_buffer in NetGetJoinInformation() talloced. Guenther (This used to be commit 421905fb608df6736944ac21ac67abee24991521) --- source3/lib/netapi/joindomain.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index aa8ec6e0b5..e4fb63eebb 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -437,9 +437,9 @@ static WERROR NetGetJoinInformationLocal(struct libnetapi_ctx *ctx, uint16_t *name_type) { if ((lp_security() == SEC_ADS) && lp_realm()) { - *name_buffer = SMB_STRDUP(lp_realm()); + *name_buffer = talloc_strdup(ctx, lp_realm()); } else { - *name_buffer = SMB_STRDUP(lp_workgroup()); + *name_buffer = talloc_strdup(ctx, lp_workgroup()); } if (!*name_buffer) { return WERR_NOMEM; -- cgit From 67f2afe3c4cfd46aa20b7a7c568ac6b5ab16acb8 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 8 Jan 2008 11:55:45 +0100 Subject: Correctly free buffers in netdomjoin-gui. Guenther (This used to be commit 04d78d4d9a8cffe44c927036038aef1d6d6b44b2) --- source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c index 1e1681ba37..4a3588e9ab 100644 --- a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c +++ b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c @@ -249,6 +249,8 @@ static void callback_do_reboot(GtkWidget *widget, SAFE_FREE(buffer); state->name_type_new = type; #endif + NetApiBufferFree((void *)buffer); + gtk_label_set_text(GTK_LABEL(state->label_current_name_buffer), state->name_buffer_new); if (state->name_type_new == NetSetupDomainName) { @@ -1292,8 +1294,12 @@ static int initialize_join_state(struct join_state *state, if (status) { return status; } - state->name_buffer_initial = (char *)buffer; + state->name_buffer_initial = strdup(buffer); + if (!state->name_buffer_initial) { + return -1; + } state->name_type_initial = type; + NetApiBufferFree((void *)buffer); } { @@ -1311,6 +1317,7 @@ static int initialize_join_state(struct join_state *state, if (!state->comment) { return -1; } + NetApiBufferFree(buffer); } #if 0 { -- cgit From 5274d8cda30f712f01a048862d0fdc532878eba5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 8 Jan 2008 22:12:35 +0100 Subject: Only realloc the talloc stack if necessary (This used to be commit c7cb98d486ef8af1dc7111c2316fd73db9fef9f8) --- source3/lib/talloc_stack.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/talloc_stack.c b/source3/lib/talloc_stack.c index cc7ce3a518..d887b2d415 100644 --- a/source3/lib/talloc_stack.c +++ b/source3/lib/talloc_stack.c @@ -39,6 +39,7 @@ #include "includes.h" static int talloc_stacksize; +static int talloc_stack_arraysize; static TALLOC_CTX **talloc_stack; static int talloc_pop(TALLOC_CTX *frame) @@ -67,21 +68,25 @@ TALLOC_CTX *talloc_stackframe(void) { TALLOC_CTX **tmp, *top; - if (!(tmp = TALLOC_REALLOC_ARRAY(NULL, talloc_stack, TALLOC_CTX *, - talloc_stacksize + 1))) { - goto fail; - } + if (talloc_stack_arraysize < talloc_stacksize + 1) { + tmp = TALLOC_REALLOC_ARRAY(NULL, talloc_stack, TALLOC_CTX *, + talloc_stacksize + 1); + if (tmp == NULL) { + goto fail; + } + talloc_stack = tmp; + talloc_stack_arraysize = talloc_stacksize + 1; + } - talloc_stack = tmp; + top = talloc_new(talloc_stack); - if (!(top = talloc_new(talloc_stack))) { + if (top == NULL) { goto fail; } talloc_set_destructor(top, talloc_pop); talloc_stack[talloc_stacksize++] = top; - return top; fail: -- cgit From 0af2efcdc4cd669db2a2ee582674dc030c6371a9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 8 Jan 2008 22:42:27 +0100 Subject: Don't shrink a talloc area if we have less than 1k to gain (This used to be commit 28a72ebd4541fb54f284da49081345e54130c75a) --- source3/lib/talloc/talloc.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/talloc/talloc.c b/source3/lib/talloc/talloc.c index 4d72c0e871..6dbe21bbf1 100644 --- a/source3/lib/talloc/talloc.c +++ b/source3/lib/talloc/talloc.c @@ -787,6 +787,11 @@ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *n tc = talloc_chunk_from_ptr(ptr); + if ((size < tc->size) && ((tc->size - size) < 1024)) { + tc->size = size; + return ptr; + } + /* don't allow realloc on referenced pointers */ if (unlikely(tc->refs)) { return NULL; -- cgit From 148f1eee4338bbe485f9b9bcf9569f76f906b665 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 8 Jan 2008 23:18:03 +0100 Subject: Save one popular malloc (This used to be commit 2150663d9eaf5cdab08de2ad1fcc952d7e85936c) --- source3/lib/ms_fnmatch.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/ms_fnmatch.c b/source3/lib/ms_fnmatch.c index a839b42588..8b69f1c2d2 100644 --- a/source3/lib/ms_fnmatch.c +++ b/source3/lib/ms_fnmatch.c @@ -152,6 +152,8 @@ int ms_fnmatch(const char *pattern, const char *string, bool translate_pattern, smb_ucs2_t *s = NULL; int ret, count, i; struct max_n *max_n = NULL; + struct max_n *max_n_free = NULL; + struct max_n one_max_n; if (ISDOTDOT(string)) { string = "."; @@ -201,17 +203,27 @@ int ms_fnmatch(const char *pattern, const char *string, bool translate_pattern, } if (count != 0) { - max_n = SMB_CALLOC_ARRAY(struct max_n, count); - if (!max_n) { - SAFE_FREE(p); - SAFE_FREE(s); - return -1; + if (count == 1) { + /* + * We're doing this a LOT, so save the effort to allocate + */ + ZERO_STRUCT(one_max_n); + max_n = &one_max_n; + } + else { + max_n = SMB_CALLOC_ARRAY(struct max_n, count); + if (!max_n) { + SAFE_FREE(p); + SAFE_FREE(s); + return -1; + } + max_n_free = max_n; } } ret = ms_fnmatch_core(p, s, max_n, strrchr_w(s, UCS2_CHAR('.')), is_case_sensitive); - SAFE_FREE(max_n); + SAFE_FREE(max_n_free); SAFE_FREE(p); SAFE_FREE(s); return ret; -- cgit From ebb21268df233933938e64e83ed315313aedd544 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 9 Jan 2008 01:34:21 +0100 Subject: Fix talloctort: move size check after referenced ptr check. Michael (This used to be commit 45b219642c529865a898625eeb0433c60b233867) --- source3/lib/talloc/talloc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/talloc/talloc.c b/source3/lib/talloc/talloc.c index 6dbe21bbf1..476d765104 100644 --- a/source3/lib/talloc/talloc.c +++ b/source3/lib/talloc/talloc.c @@ -787,16 +787,16 @@ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *n tc = talloc_chunk_from_ptr(ptr); - if ((size < tc->size) && ((tc->size - size) < 1024)) { - tc->size = size; - return ptr; - } - /* don't allow realloc on referenced pointers */ if (unlikely(tc->refs)) { return NULL; } + if ((size < tc->size) && ((tc->size - size) < 1024)) { + tc->size = size; + return ptr; + } + /* by resetting magic we catch users of the old memory */ tc->flags |= TALLOC_FLAG_FREE; -- cgit From 2e3ac4d3fe65ee72111c03a9b6fabf06f8192a69 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 9 Jan 2008 01:35:43 +0100 Subject: Add a comment. Michael (This used to be commit 3a4bf4b7c3081048f0d5491dae6610388c268c2f) --- source3/lib/talloc/talloc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/lib') diff --git a/source3/lib/talloc/talloc.c b/source3/lib/talloc/talloc.c index 476d765104..3e976bc0fc 100644 --- a/source3/lib/talloc/talloc.c +++ b/source3/lib/talloc/talloc.c @@ -792,6 +792,7 @@ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *n return NULL; } + /* don't shrink if we have less than 1k to gain */ if ((size < tc->size) && ((tc->size - size) < 1024)) { tc->size = size; return ptr; -- cgit From f3603d5a5ab878d45b67bf0f33e2beca50d0af2d Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 9 Jan 2008 00:11:31 +0100 Subject: Convert add_sid_to_array() add_sid_to_array_unique() to return NTSTATUS. Michael (This used to be commit 6b2b9a60ef857ec31da5fea631535205fbdede4a) --- source3/lib/privileges.c | 6 ++-- source3/lib/util_reg_smbconf.c | 9 ++++-- source3/lib/util_sid.c | 70 +++++++++++++++++++++++++----------------- 3 files changed, 52 insertions(+), 33 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/privileges.c b/source3/lib/privileges.c index 63fb462e32..509da80785 100644 --- a/source3/lib/privileges.c +++ b/source3/lib/privileges.c @@ -184,8 +184,10 @@ static int priv_traverse_fn(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *s return 0; } - if (!add_sid_to_array( priv->mem_ctx, &sid, &priv->sids.list, - &priv->sids.count )) { + if (!NT_STATUS_IS_OK(add_sid_to_array(priv->mem_ctx, &sid, + &priv->sids.list, + &priv->sids.count))) + { return 0; } diff --git a/source3/lib/util_reg_smbconf.c b/source3/lib/util_reg_smbconf.c index fa58f28d03..472fef7a2d 100644 --- a/source3/lib/util_reg_smbconf.c +++ b/source3/lib/util_reg_smbconf.c @@ -30,18 +30,21 @@ extern REGISTRY_OPS smbconf_reg_ops; */ NT_USER_TOKEN *registry_create_admin_token(TALLOC_CTX *mem_ctx) { + NTSTATUS status; NT_USER_TOKEN *token = NULL; /* fake a user token: builtin administrators sid and the * disk operators privilege is all we need to access the * registry... */ - if (!(token = TALLOC_ZERO_P(mem_ctx, NT_USER_TOKEN))) { + token = TALLOC_ZERO_P(mem_ctx, NT_USER_TOKEN); + if (token == NULL) { DEBUG(1, ("talloc failed\n")); goto done; } token->privileges = se_disk_operators; - if (!add_sid_to_array(token, &global_sid_Builtin_Administrators, - &token->user_sids, &token->num_sids)) { + status = add_sid_to_array(token, &global_sid_Builtin_Administrators, + &token->user_sids, &token->num_sids); + if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Error adding builtin administrators sid " "to fake token.\n")); goto done; diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c index 222b32ed3a..37865238a5 100644 --- a/source3/lib/util_sid.c +++ b/source3/lib/util_sid.c @@ -573,20 +573,20 @@ DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, const DOM_SID *src) Add SID to an array SIDs ********************************************************************/ -bool add_sid_to_array(TALLOC_CTX *mem_ctx, const DOM_SID *sid, - DOM_SID **sids, size_t *num) +NTSTATUS add_sid_to_array(TALLOC_CTX *mem_ctx, const DOM_SID *sid, + DOM_SID **sids, size_t *num) { *sids = TALLOC_REALLOC_ARRAY(mem_ctx, *sids, DOM_SID, (*num)+1); if (*sids == NULL) { *num = 0; - return False; + return NT_STATUS_NO_MEMORY; } sid_copy(&((*sids)[*num]), sid); *num += 1; - return True; + return NT_STATUS_OK; } @@ -594,14 +594,14 @@ bool add_sid_to_array(TALLOC_CTX *mem_ctx, const DOM_SID *sid, Add SID to an array SIDs ensuring that it is not already there ********************************************************************/ -bool add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const DOM_SID *sid, - DOM_SID **sids, size_t *num_sids) +NTSTATUS add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const DOM_SID *sid, + DOM_SID **sids, size_t *num_sids) { size_t i; for (i=0; i<(*num_sids); i++) { if (sid_compare(sid, &(*sids)[i]) == 0) - return True; + return NT_STATUS_OK; } return add_sid_to_array(mem_ctx, sid, sids, num_sids); @@ -670,6 +670,7 @@ NTSTATUS sid_array_from_info3(TALLOC_CTX *mem_ctx, size_t *num_user_sids, bool include_user_group_rid) { + NTSTATUS status; DOM_SID sid; DOM_SID *sid_array = NULL; size_t num_sids = 0; @@ -677,35 +678,47 @@ NTSTATUS sid_array_from_info3(TALLOC_CTX *mem_ctx, if (include_user_group_rid) { - if (!sid_compose(&sid, &(info3->dom_sid.sid), - info3->user_rid) - || !add_sid_to_array(mem_ctx, &sid, - &sid_array, &num_sids)) { - DEBUG(3,("could not add user SID from rid 0x%x\n", - info3->user_rid)); + if (!sid_compose(&sid, &(info3->dom_sid.sid), info3->user_rid)) + { + DEBUG(3, ("could not compose user SID from rid 0x%x\n", + info3->user_rid)); return NT_STATUS_INVALID_PARAMETER; } + status = add_sid_to_array(mem_ctx, &sid, &sid_array, &num_sids); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3, ("could not append user SID from rid 0x%x\n", + info3->user_rid)); + return status; + } - if (!sid_compose(&sid, &(info3->dom_sid.sid), - info3->group_rid) - || !add_sid_to_array(mem_ctx, &sid, - &sid_array, &num_sids)) { - DEBUG(3,("could not append additional group rid 0x%x\n", - info3->group_rid)); - + if (!sid_compose(&sid, &(info3->dom_sid.sid), info3->group_rid)) + { + DEBUG(3, ("could not compose group SID from rid 0x%x\n", + info3->group_rid)); return NT_STATUS_INVALID_PARAMETER; } + status = add_sid_to_array(mem_ctx, &sid, &sid_array, &num_sids); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3, ("could not append group SID from rid 0x%x\n", + info3->group_rid)); + return status; + } } for (i = 0; i < info3->num_groups2; i++) { if (!sid_compose(&sid, &(info3->dom_sid.sid), - info3->gids[i].g_rid) - || !add_sid_to_array(mem_ctx, &sid, - &sid_array, &num_sids)) { - DEBUG(3,("could not append additional group rid 0x%x\n", - info3->gids[i].g_rid)); + info3->gids[i].g_rid)) + { + DEBUG(3, ("could not compose SID from additional group " + "rid 0x%x\n", info3->gids[i].g_rid)); return NT_STATUS_INVALID_PARAMETER; } + status = add_sid_to_array(mem_ctx, &sid, &sid_array, &num_sids); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3, ("could not append SID from additional group " + "rid 0x%x\n", info3->gids[i].g_rid)); + return status; + } } /* Copy 'other' sids. We need to do sid filtering here to @@ -715,11 +728,12 @@ NTSTATUS sid_array_from_info3(TALLOC_CTX *mem_ctx, */ for (i = 0; i < info3->num_other_sids; i++) { - if (!add_sid_to_array(mem_ctx, &info3->other_sids[i].sid, - &sid_array, &num_sids)) { + status = add_sid_to_array(mem_ctx, &info3->other_sids[i].sid, + &sid_array, &num_sids); + if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("could not add SID to array: %s\n", sid_string_dbg(&info3->other_sids[i].sid))); - return NT_STATUS_NO_MEMORY; + return status; } } -- cgit From f269ed866d01b9924264941268d902b893fbac83 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 9 Jan 2008 00:25:27 +0100 Subject: Move content of comment. Michael (This used to be commit ed4dd00c5ae8e4995ace9326f915ae4bd15d96b3) --- source3/lib/util_reg_smbconf.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/util_reg_smbconf.c b/source3/lib/util_reg_smbconf.c index 472fef7a2d..5fb862ac35 100644 --- a/source3/lib/util_reg_smbconf.c +++ b/source3/lib/util_reg_smbconf.c @@ -26,16 +26,16 @@ extern REGISTRY_OPS smbconf_reg_ops; /* * create a fake token just with enough rights to - * locally access the registry. + * locally access the registry: + * + * - builtin administrators sid + * - disk operators privilege */ NT_USER_TOKEN *registry_create_admin_token(TALLOC_CTX *mem_ctx) { NTSTATUS status; NT_USER_TOKEN *token = NULL; - /* fake a user token: builtin administrators sid and the - * disk operators privilege is all we need to access the - * registry... */ token = TALLOC_ZERO_P(mem_ctx, NT_USER_TOKEN); if (token == NULL) { DEBUG(1, ("talloc failed\n")); -- cgit From 22068a0c167b27cf1d74a32ac516df25dce0f70a Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 9 Jan 2008 01:17:13 +0100 Subject: Change registry_create_admin_token() to return NTSTATUS. Michael (This used to be commit 9cd30fb25c42e79946b5140994d0bf2ef4c62f90) --- source3/lib/util_reg_smbconf.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/util_reg_smbconf.c b/source3/lib/util_reg_smbconf.c index 5fb862ac35..6452b0b15b 100644 --- a/source3/lib/util_reg_smbconf.c +++ b/source3/lib/util_reg_smbconf.c @@ -31,14 +31,20 @@ extern REGISTRY_OPS smbconf_reg_ops; * - builtin administrators sid * - disk operators privilege */ -NT_USER_TOKEN *registry_create_admin_token(TALLOC_CTX *mem_ctx) +NTSTATUS registry_create_admin_token(TALLOC_CTX *mem_ctx, + NT_USER_TOKEN **ptoken) { NTSTATUS status; NT_USER_TOKEN *token = NULL; + if (ptoken == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + token = TALLOC_ZERO_P(mem_ctx, NT_USER_TOKEN); if (token == NULL) { DEBUG(1, ("talloc failed\n")); + status = NT_STATUS_NO_MEMORY; goto done; } token->privileges = se_disk_operators; @@ -49,8 +55,11 @@ NT_USER_TOKEN *registry_create_admin_token(TALLOC_CTX *mem_ctx) "to fake token.\n")); goto done; } + + *ptoken = token; + done: - return token; + return status; } /* -- cgit From 66d6eb27a4e14b41b5a6cbaa828b7ccc4b4244b8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 9 Jan 2008 23:00:48 +0100 Subject: Fix the max_dead_record calculations (This used to be commit 2a5c53220a5cc2b4a80fc7c6cb38e87789c5e797) --- source3/lib/tdb/common/open.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/tdb/common/open.c b/source3/lib/tdb/common/open.c index 0bd1c91a5e..6efa482ac2 100644 --- a/source3/lib/tdb/common/open.c +++ b/source3/lib/tdb/common/open.c @@ -178,9 +178,7 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, tdb->page_size = 0x2000; } - if (open_flags & TDB_VOLATILE) { - tdb->max_dead_records = 5; - } + tdb->max_dead_records = (open_flags & TDB_VOLATILE) ? 5 : 0; if ((open_flags & O_ACCMODE) == O_WRONLY) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't open tdb %s write-only\n", @@ -283,7 +281,6 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, tdb->map_size = st.st_size; tdb->device = st.st_dev; tdb->inode = st.st_ino; - tdb->max_dead_records = 0; tdb_mmap(tdb); if (locked) { if (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK, 0, 1) == -1) { -- cgit From 1ed4fcb271b7885c274bd88bafed8116779d8eb6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 5 Jan 2008 18:26:54 +0100 Subject: Implement talloc_pool() A talloc pool is a chunk of memory that can be used as a context for further talloc calls. Allocations with the pool as the parent just chew from that memory by incrementing a pointer. If the talloc pool is full, then we fall back to the normal system-level malloc(3) to get memory. The use case for talloc pools is the transient memory that is used for handling a single SMB request. Incrementing a pointer will be way faster than any malloc implementation. There is a downside of this: If you use talloc_steal() to move something out of the pool, the whole pool memory is kept around until the last object inside the pool is freed. So if you talloc_free() the pool, it might happen that the memory is freed later. So don't hang anything off a talloc pool that should live long. Volker (This used to be commit 287e29d988813007eeebc0c2bef3b46ab8bedee9) --- source3/lib/talloc/talloc.c | 176 +++++++++++++++++++++++++++++++++++++++-- source3/lib/talloc/talloc.h | 1 + source3/lib/talloc/testsuite.c | 37 +++++++++ 3 files changed, 207 insertions(+), 7 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/talloc/talloc.c b/source3/lib/talloc/talloc.c index 3e976bc0fc..178bbb97e4 100644 --- a/source3/lib/talloc/talloc.c +++ b/source3/lib/talloc/talloc.c @@ -60,6 +60,8 @@ #define TALLOC_MAGIC 0xe814ec70 #define TALLOC_FLAG_FREE 0x01 #define TALLOC_FLAG_LOOP 0x02 +#define TALLOC_FLAG_POOL 0x04 /* This is a talloc pool */ +#define TALLOC_FLAG_POOLMEM 0x08 /* This is allocated in a pool */ #define TALLOC_MAGIC_REFERENCE ((const char *)1) /* by default we abort when given a bad pointer (such as when talloc_free() is called @@ -109,6 +111,19 @@ struct talloc_chunk { const char *name; size_t size; unsigned flags; + + /* + * "pool" has dual use: + * + * For the talloc pool itself (i.e. TALLOC_FLAG_POOL is set), "pool" + * marks the end of the currently allocated area. + * + * For members of the pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool" + * is a pointer to the struct talloc_chunk of the pool that it was + * allocated from. This way children can quickly find the pool to chew + * from. + */ + void *pool; }; /* 16 byte alignment seems to keep everyone happy */ @@ -200,12 +215,82 @@ const char *talloc_parent_name(const void *ptr) return tc? tc->name : NULL; } +/* + A pool carries an in-pool object count count in the first 16 bytes. + bytes. This is done to support talloc_steal() to a parent outside of the + pool. The count includes the pool itself, so a talloc_free() on a pool will + only destroy the pool if the count has dropped to zero. A talloc_free() of a + pool member will reduce the count, and eventually also call free(3) on the + pool memory. + + The object count is not put into "struct talloc_chunk" because it is only + relevant for talloc pools and the alignment to 16 bytes would increase the + memory footprint of each talloc chunk by those 16 bytes. +*/ + +#define TALLOC_POOL_HDR_SIZE 16 + +static unsigned int *talloc_pool_objectcount(struct talloc_chunk *tc) +{ + return (unsigned int *)((char *)tc + sizeof(struct talloc_chunk)); +} + +/* + Allocate from a pool +*/ + +static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, + size_t size) +{ + struct talloc_chunk *pool_ctx = NULL; + size_t space_left; + struct talloc_chunk *result; + + if (parent == NULL) { + return NULL; + } + + if (parent->flags & TALLOC_FLAG_POOL) { + pool_ctx = parent; + } + else if (parent->flags & TALLOC_FLAG_POOLMEM) { + pool_ctx = (struct talloc_chunk *)parent->pool; + } + + if (pool_ctx == NULL) { + return NULL; + } + + space_left = ((char *)pool_ctx + TC_HDR_SIZE + pool_ctx->size) + - ((char *)pool_ctx->pool); + + /* + * Align size to 16 bytes + */ + size = ((size + 15) & ~15); + + if (space_left < size) { + return NULL; + } + + result = (struct talloc_chunk *)pool_ctx->pool; + + pool_ctx->pool = (void *)((char *)result + size); + + result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM; + result->pool = pool_ctx; + + *talloc_pool_objectcount(pool_ctx) += 1; + + return result; +} + /* Allocate a bit of memory as a child of an existing pointer */ static inline void *__talloc(const void *context, size_t size) { - struct talloc_chunk *tc; + struct talloc_chunk *tc = NULL; if (unlikely(context == NULL)) { context = null_context; @@ -215,11 +300,19 @@ static inline void *__talloc(const void *context, size_t size) return NULL; } - tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size); - if (unlikely(tc == NULL)) return NULL; + if (context != NULL) { + tc = talloc_alloc_pool(talloc_chunk_from_ptr(context), + TC_HDR_SIZE+size); + } + + if (tc == NULL) { + tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size); + if (unlikely(tc == NULL)) return NULL; + tc->flags = TALLOC_MAGIC; + tc->pool = NULL; + } tc->size = size; - tc->flags = TALLOC_MAGIC; tc->destructor = NULL; tc->child = NULL; tc->name = NULL; @@ -245,6 +338,29 @@ static inline void *__talloc(const void *context, size_t size) return TC_PTR_FROM_CHUNK(tc); } +/* + * Create a talloc pool + */ + +void *talloc_pool(const void *context, size_t size) +{ + void *result = __talloc(context, size + TALLOC_POOL_HDR_SIZE); + struct talloc_chunk *tc; + + if (unlikely(result == NULL)) { + return NULL; + } + + tc = talloc_chunk_from_ptr(result); + + tc->flags |= TALLOC_FLAG_POOL; + tc->pool = (char *)result + TALLOC_POOL_HDR_SIZE; + + *talloc_pool_objectcount(tc) = 1; + + return result; +} + /* setup a destructor to be called on free of a pointer the destructor should return 0 on success, or -1 on failure. @@ -420,7 +536,29 @@ static inline int _talloc_free(void *ptr) } tc->flags |= TALLOC_FLAG_FREE; - free(tc); + + if (tc->flags & (TALLOC_FLAG_POOL|TALLOC_FLAG_POOLMEM)) { + struct talloc_chunk *pool; + unsigned int *pool_object_count; + + pool = (tc->flags & TALLOC_FLAG_POOL) + ? tc : (struct talloc_chunk *)tc->pool; + + pool_object_count = talloc_pool_objectcount(pool); + + if (*pool_object_count == 0) { + TALLOC_ABORT("Pool object count zero!"); + } + + *pool_object_count -= 1; + + if (*pool_object_count == 0) { + free(pool); + } + } + else { + free(tc); + } return 0; } @@ -718,6 +856,10 @@ void talloc_free_children(void *ptr) talloc_steal(new_parent, child); } } + + if (tc->flags & TALLOC_FLAG_POOL) { + tc->pool = ((char *)tc + TC_HDR_SIZE + TALLOC_POOL_HDR_SIZE); + } } /* @@ -769,6 +911,7 @@ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *n { struct talloc_chunk *tc; void *new_ptr; + bool malloced = false; /* size zero is equivalent to free() */ if (unlikely(size == 0)) { @@ -808,7 +951,23 @@ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *n free(tc); } #else - new_ptr = realloc(tc, size + TC_HDR_SIZE); + if (tc->flags & TALLOC_FLAG_POOLMEM) { + + new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE); + *talloc_pool_objectcount(tc->pool) -= 1; + + if (new_ptr == NULL) { + new_ptr = malloc(TC_HDR_SIZE+size); + malloced = true; + } + + if (new_ptr) { + memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE); + } + } + else { + new_ptr = realloc(tc, size + TC_HDR_SIZE); + } #endif if (unlikely(!new_ptr)) { tc->flags &= ~TALLOC_FLAG_FREE; @@ -816,7 +975,10 @@ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *n } tc = (struct talloc_chunk *)new_ptr; - tc->flags &= ~TALLOC_FLAG_FREE; + tc->flags &= ~TALLOC_FLAG_FREE; + if (malloced) { + tc->flags &= ~TALLOC_FLAG_POOLMEM; + } if (tc->parent) { tc->parent->child = tc; } diff --git a/source3/lib/talloc/talloc.h b/source3/lib/talloc/talloc.h index e103391681..5431971655 100644 --- a/source3/lib/talloc/talloc.h +++ b/source3/lib/talloc/talloc.h @@ -116,6 +116,7 @@ typedef void TALLOC_CTX; /* The following definitions come from talloc.c */ void *_talloc(const void *context, size_t size); +void *talloc_pool(const void *context, size_t size); void _talloc_set_destructor(const void *ptr, int (*destructor)(void *)); int talloc_increase_ref_count(const void *ptr); size_t talloc_reference_count(const void *ptr); diff --git a/source3/lib/talloc/testsuite.c b/source3/lib/talloc/testsuite.c index e16c91f8b9..fedbda95aa 100644 --- a/source3/lib/talloc/testsuite.c +++ b/source3/lib/talloc/testsuite.c @@ -813,6 +813,25 @@ static bool test_speed(void) talloc_free(ctx); + ctx = talloc_pool(NULL, 1024); + + tv = timeval_current(); + count = 0; + do { + void *p1, *p2, *p3; + for (i=0;i Date: Wed, 9 Jan 2008 17:07:58 -0800 Subject: Add the calls to make use of talloc_pools in a talloc_stackframe. Jeremy. (This used to be commit d27e6c0548d21394f6399d3b737d175ffed8420d) --- source3/lib/talloc_stack.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/talloc_stack.c b/source3/lib/talloc_stack.c index d887b2d415..08ef2281ea 100644 --- a/source3/lib/talloc_stack.c +++ b/source3/lib/talloc_stack.c @@ -64,7 +64,7 @@ static int talloc_pop(TALLOC_CTX *frame) * not explicitly freed. */ -TALLOC_CTX *talloc_stackframe(void) +static TALLOC_CTX *talloc_stackframe_internal(size_t poolsize) { TALLOC_CTX **tmp, *top; @@ -78,7 +78,11 @@ TALLOC_CTX *talloc_stackframe(void) talloc_stack_arraysize = talloc_stacksize + 1; } - top = talloc_new(talloc_stack); + if (poolsize) { + top = talloc_pool(talloc_stack, poolsize); + } else { + top = talloc_new(talloc_stack); + } if (top == NULL) { goto fail; @@ -94,6 +98,16 @@ TALLOC_CTX *talloc_stackframe(void) return NULL; } +TALLOC_CTX *talloc_stackframe(void) +{ + return talloc_stackframe_internal(0); +} + +TALLOC_CTX *talloc_stackframe_pool(size_t poolsize) +{ + return talloc_stackframe_internal(poolsize); +} + /* * Get us the current top of the talloc stack. */ -- cgit From 980ac0984905d8c3f29dd62ed75fc9c7cb22cdd8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 9 Jan 2008 17:32:26 -0800 Subject: Fixup hot paths - add macro for toupper (c < 0x80). This now matches 3.0.x on my micro-tests. Jeremy. (This used to be commit 329b924cba8225002ca40db26c45b31d141a0925) --- source3/lib/charcnv.c | 18 ++++++++++++------ source3/lib/util_str.c | 21 ++++++++++++++++----- 2 files changed, 28 insertions(+), 11 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index 8a00b235cc..eeff805459 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -614,10 +614,16 @@ size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to, out: destlen = destlen - o_len; - if (ctx) { - ob = (char *)TALLOC_REALLOC(ctx,ob,destlen); - } else { - ob = (char *)SMB_REALLOC(ob,destlen); + /* Don't shrink unless we're reclaiming a lot of + * space. This is in the hot codepath and these + * reallocs *cost*. JRA. + */ + if (o_len > 1024) { + if (ctx) { + ob = (char *)TALLOC_REALLOC(ctx,ob,destlen); + } else { + ob = (char *)SMB_REALLOC(ob,destlen); + } } if (destlen && !ob) { @@ -778,7 +784,7 @@ char *strdup_upper(const char *s) while (*p) { if (*p & 0x80) break; - *q++ = toupper_ascii(*p); + *q++ = toupper_ascii_fast(*p); p++; } @@ -844,7 +850,7 @@ char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *s) while (*p) { if (*p & 0x80) break; - *q++ = toupper_ascii(*p); + *q++ = toupper_ascii_fast(*p); p++; } diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 7e21fe1195..3e3268104c 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -24,6 +24,17 @@ #include "includes.h" +char toupper_ascii_fast_table[128] = { + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f +}; + /** * @file * @brief String utilities. @@ -187,8 +198,8 @@ int StrCaseCmp(const char *s, const char *t) * from here on in */ break; - us = toupper_ascii(*ps); - ut = toupper_ascii(*pt); + us = toupper_ascii_fast(*ps); + ut = toupper_ascii_fast(*pt); if (us == ut) continue; else if (us < ut) @@ -246,8 +257,8 @@ int StrnCaseCmp(const char *s, const char *t, size_t len) * hard way from here on in */ break; - us = toupper_ascii(*ps); - ut = toupper_ascii(*pt); + us = toupper_ascii_fast(*ps); + ut = toupper_ascii_fast(*pt); if (us == ut) continue; else if (us < ut) @@ -1679,7 +1690,7 @@ void strupper_m(char *s) (ie. they match for the first 128 chars) */ while (*s && !(((unsigned char)s[0]) & 0x80)) { - *s = toupper_ascii((unsigned char)*s); + *s = toupper_ascii_fast((unsigned char)*s); s++; } -- cgit From 7579e08599dd2139617da5639144700774233c08 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 10 Jan 2008 09:53:51 +0100 Subject: Form a proper hierarchy in talloc_stack This way talloc_stackframe() can benefit from a pool put on the stack further up. No need to remove talloc_stackframe(). (This used to be commit be6fe381168321ae62e079cd977cbef675c532d4) --- source3/lib/talloc_stack.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/talloc_stack.c b/source3/lib/talloc_stack.c index 08ef2281ea..2722fb9676 100644 --- a/source3/lib/talloc_stack.c +++ b/source3/lib/talloc_stack.c @@ -66,7 +66,7 @@ static int talloc_pop(TALLOC_CTX *frame) static TALLOC_CTX *talloc_stackframe_internal(size_t poolsize) { - TALLOC_CTX **tmp, *top; + TALLOC_CTX **tmp, *top, *parent; if (talloc_stack_arraysize < talloc_stacksize + 1) { tmp = TALLOC_REALLOC_ARRAY(NULL, talloc_stack, TALLOC_CTX *, @@ -78,10 +78,17 @@ static TALLOC_CTX *talloc_stackframe_internal(size_t poolsize) talloc_stack_arraysize = talloc_stacksize + 1; } + if (talloc_stacksize == 0) { + parent = talloc_stack; + } + else { + parent = talloc_stack[talloc_stacksize-1]; + } + if (poolsize) { - top = talloc_pool(talloc_stack, poolsize); + top = talloc_pool(parent, poolsize); } else { - top = talloc_new(talloc_stack); + top = talloc_new(parent); } if (top == NULL) { -- cgit From 4803cc5d3ce7db872bd21f6a1232f7cabc46186e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 10 Jan 2008 11:34:07 +0100 Subject: Mark talloc_pool memory for valgrind (This used to be commit d89e42f1d2faa018c584025296d6be8195cbcf20) --- source3/lib/talloc/talloc.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/talloc/talloc.c b/source3/lib/talloc/talloc.c index 178bbb97e4..ea4480286e 100644 --- a/source3/lib/talloc/talloc.c +++ b/source3/lib/talloc/talloc.c @@ -245,6 +245,7 @@ static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, struct talloc_chunk *pool_ctx = NULL; size_t space_left; struct talloc_chunk *result; + size_t chunk_size; if (parent == NULL) { return NULL; @@ -267,15 +268,19 @@ static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent, /* * Align size to 16 bytes */ - size = ((size + 15) & ~15); + chunk_size = ((size + 15) & ~15); - if (space_left < size) { + if (space_left < chunk_size) { return NULL; } result = (struct talloc_chunk *)pool_ctx->pool; - pool_ctx->pool = (void *)((char *)result + size); +#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) + VALGRIND_MAKE_MEM_UNDEFINED(result, size); +#endif + + pool_ctx->pool = (void *)((char *)result + chunk_size); result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM; result->pool = pool_ctx; @@ -358,6 +363,10 @@ void *talloc_pool(const void *context, size_t size) *talloc_pool_objectcount(tc) = 1; +#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS) + VALGRIND_MAKE_MEM_NOACCESS(tc->pool, size); +#endif + return result; } @@ -859,6 +868,10 @@ void talloc_free_children(void *ptr) if (tc->flags & TALLOC_FLAG_POOL) { tc->pool = ((char *)tc + TC_HDR_SIZE + TALLOC_POOL_HDR_SIZE); +#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS) + VALGRIND_MAKE_MEM_NOACCESS( + tc->pool, tc->size - TALLOC_POOL_HDR_SIZE); +#endif } } -- cgit From 97a50593fe86456a72762ba4a768614de23c3f14 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 10 Jan 2008 11:35:17 +0100 Subject: talloc_free_children can only reset pool if it's empty (This used to be commit 0272b46515b4c4515d5cad8e86fab61d8e91e29e) --- source3/lib/talloc/talloc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/talloc/talloc.c b/source3/lib/talloc/talloc.c index ea4480286e..8683e361a6 100644 --- a/source3/lib/talloc/talloc.c +++ b/source3/lib/talloc/talloc.c @@ -866,7 +866,8 @@ void talloc_free_children(void *ptr) } } - if (tc->flags & TALLOC_FLAG_POOL) { + if ((tc->flags & TALLOC_FLAG_POOL) + && (*talloc_pool_objectcount(tc) == 1)) { tc->pool = ((char *)tc + TC_HDR_SIZE + TALLOC_POOL_HDR_SIZE); #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS) VALGRIND_MAKE_MEM_NOACCESS( -- cgit From 138954e70e18e53f1ae81bad4641380bc8ab3bd3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 10 Jan 2008 11:35:40 +0100 Subject: Fix a c++ warning (This used to be commit ee905a085fff5410d02c3e5fa2664e989de4afd4) --- source3/lib/talloc/talloc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/talloc/talloc.c b/source3/lib/talloc/talloc.c index 8683e361a6..9dcd8a2a83 100644 --- a/source3/lib/talloc/talloc.c +++ b/source3/lib/talloc/talloc.c @@ -968,7 +968,8 @@ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *n if (tc->flags & TALLOC_FLAG_POOLMEM) { new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE); - *talloc_pool_objectcount(tc->pool) -= 1; + *talloc_pool_objectcount((struct talloc_chunk *) + (tc->pool)) -= 1; if (new_ptr == NULL) { new_ptr = malloc(TC_HDR_SIZE+size); -- cgit From 9f67ee6334f36f30ddfc2e86459cb764bccf1edf Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 6 Jan 2008 14:17:15 +0100 Subject: use talloc_tos() in share_access_check() (This used to be commit ac2bb838d537ca563ad2fe770b3e1c2fe8b1d9e7) --- source3/lib/sharesec.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/sharesec.c b/source3/lib/sharesec.c index ba025dacc1..f6ff701d5b 100644 --- a/source3/lib/sharesec.c +++ b/source3/lib/sharesec.c @@ -228,25 +228,20 @@ bool share_access_check(const NT_USER_TOKEN *token, const char *sharename, { uint32 granted; NTSTATUS status; - TALLOC_CTX *mem_ctx = NULL; SEC_DESC *psd = NULL; size_t sd_size; bool ret = True; - if (!(mem_ctx = talloc_init("share_access_check"))) { - return False; - } - - psd = get_share_security(mem_ctx, sharename, &sd_size); + psd = get_share_security(talloc_tos(), sharename, &sd_size); if (!psd) { - TALLOC_FREE(mem_ctx); return True; } ret = se_access_check(psd, token, desired_access, &granted, &status); - talloc_destroy(mem_ctx); + TALLOC_FREE(psd); + return ret; } -- cgit From 5661ac6a389620ac543a384832de9ee9b64893c7 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 10 Jan 2008 13:30:43 +0100 Subject: Correctly abstract the transfer_file mechanism with callbacks and void ptrs. This removes the in_fsp and out_fsp global variables hack from smbd/vfs.c. Michael (This used to be commit b2e7cdc6e899ca3c16edbb6c8786ff9aa999fa6e) --- source3/lib/util.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/util.c b/source3/lib/util.c index 25b2700ae3..3509294e8e 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -905,8 +905,12 @@ int set_blocking(int fd, bool set) #define TRANSFER_BUF_SIZE 65536 #endif -ssize_t transfer_file_internal(int infd, int outfd, size_t n, ssize_t (*read_fn)(int, void *, size_t), - ssize_t (*write_fn)(int, const void *, size_t)) + +ssize_t transfer_file_internal(void *in_file, + void *out_file, + size_t n, + ssize_t (*read_fn)(void *, void *, size_t), + ssize_t (*write_fn)(void *, void *, size_t)) { char *buf; size_t total = 0; @@ -921,7 +925,7 @@ ssize_t transfer_file_internal(int infd, int outfd, size_t n, ssize_t (*read_fn) while (total < n) { num_to_read_thistime = MIN((n - total), TRANSFER_BUF_SIZE); - read_ret = (*read_fn)(infd, buf, num_to_read_thistime); + read_ret = (*read_fn)(in_file, buf, num_to_read_thistime); if (read_ret == -1) { DEBUG(0,("transfer_file_internal: read failure. Error = %s\n", strerror(errno) )); SAFE_FREE(buf); @@ -933,7 +937,7 @@ ssize_t transfer_file_internal(int infd, int outfd, size_t n, ssize_t (*read_fn) num_written = 0; while (num_written < read_ret) { - write_ret = (*write_fn)(outfd,buf + num_written, read_ret - num_written); + write_ret = (*write_fn)(out_file, buf + num_written, read_ret - num_written); if (write_ret == -1) { DEBUG(0,("transfer_file_internal: write failure. Error = %s\n", strerror(errno) )); @@ -953,9 +957,23 @@ ssize_t transfer_file_internal(int infd, int outfd, size_t n, ssize_t (*read_fn) return (ssize_t)total; } +static ssize_t sys_read_fn(void *file, void *buf, size_t len) +{ + int *fd = (int *)file; + + return sys_read(*fd, buf, len); +} + +static ssize_t sys_write_fn(void *file, void *buf, size_t len) +{ + int *fd = (int *)file; + + return sys_read(*fd, buf, len); +} + SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n) { - return (SMB_OFF_T)transfer_file_internal(infd, outfd, (size_t)n, sys_read, sys_write); + return (SMB_OFF_T)transfer_file_internal(&infd, &outfd, (size_t)n, sys_read_fn, sys_write_fn); } /******************************************************************* -- cgit From 9f6d0479d795ca4f8d91a3e170f66e29cf16a16b Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 10 Jan 2008 14:18:46 +0100 Subject: Fix a really silly typo. Michael (This used to be commit 7b0af7cdc97d4bbcbd73a9474871217511b92c3a) --- source3/lib/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/util.c b/source3/lib/util.c index 3509294e8e..d635078f37 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -968,7 +968,7 @@ static ssize_t sys_write_fn(void *file, void *buf, size_t len) { int *fd = (int *)file; - return sys_read(*fd, buf, len); + return sys_write(*fd, buf, len); } SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n) -- cgit From 386caead47e97b9fdc991b713cb597f1a1c4a365 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 10 Jan 2008 13:55:46 +0100 Subject: Reformat some code I just touched. Michael (This used to be commit 4ed238b1e46f7680a29ebdbfe9500d16718f9057) --- source3/lib/util.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/util.c b/source3/lib/util.c index d635078f37..44eaa85ab0 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -919,34 +919,41 @@ ssize_t transfer_file_internal(void *in_file, size_t num_to_read_thistime; size_t num_written = 0; - if ((buf = SMB_MALLOC_ARRAY(char, TRANSFER_BUF_SIZE)) == NULL) + if ((buf = SMB_MALLOC_ARRAY(char, TRANSFER_BUF_SIZE)) == NULL) { return -1; + } while (total < n) { num_to_read_thistime = MIN((n - total), TRANSFER_BUF_SIZE); read_ret = (*read_fn)(in_file, buf, num_to_read_thistime); if (read_ret == -1) { - DEBUG(0,("transfer_file_internal: read failure. Error = %s\n", strerror(errno) )); + DEBUG(0,("transfer_file_internal: read failure. " + "Error = %s\n", strerror(errno) )); SAFE_FREE(buf); return -1; } - if (read_ret == 0) + if (read_ret == 0) { break; + } num_written = 0; - + while (num_written < read_ret) { - write_ret = (*write_fn)(out_file, buf + num_written, read_ret - num_written); - + write_ret = (*write_fn)(out_file, buf + num_written, + read_ret - num_written); + if (write_ret == -1) { - DEBUG(0,("transfer_file_internal: write failure. Error = %s\n", strerror(errno) )); + DEBUG(0,("transfer_file_internal: " + "write failure. Error = %s\n", + strerror(errno) )); SAFE_FREE(buf); return -1; } - if (write_ret == 0) + if (write_ret == 0) { return (ssize_t)total; - + } + num_written += (size_t)write_ret; } @@ -954,7 +961,7 @@ ssize_t transfer_file_internal(void *in_file, } SAFE_FREE(buf); - return (ssize_t)total; + return (ssize_t)total; } static ssize_t sys_read_fn(void *file, void *buf, size_t len) @@ -971,9 +978,10 @@ static ssize_t sys_write_fn(void *file, void *buf, size_t len) return sys_write(*fd, buf, len); } -SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n) +SMB_OFF_T transfer_file(int infd, int outfd, SMB_OFF_T n) { - return (SMB_OFF_T)transfer_file_internal(&infd, &outfd, (size_t)n, sys_read_fn, sys_write_fn); + return (SMB_OFF_T)transfer_file_internal(&infd, &outfd, (size_t)n, + sys_read_fn, sys_write_fn); } /******************************************************************* -- cgit From ba2a2552822ded95358c11972005f2c353580439 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 10 Jan 2008 14:27:52 +0100 Subject: Move transfer_file and transfer_file_internal to a module of their own. Also, don't auto-generate prototypes of the (two) exported functions but make a start in having handwritten prototypes in dedicated header files (not in includes.h ... :-) Michael (This used to be commit 395f29d8b768a56af20b37f185eccdc5f37b68d5) --- source3/lib/util.c | 87 ------------------------------- source3/lib/util_transfer_file.c | 110 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 87 deletions(-) create mode 100644 source3/lib/util_transfer_file.c (limited to 'source3/lib') diff --git a/source3/lib/util.c b/source3/lib/util.c index 44eaa85ab0..0653fc9d3f 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -897,93 +897,6 @@ int set_blocking(int fd, bool set) #undef FLAG_TO_SET } -/**************************************************************************** - Transfer some data between two fd's. -****************************************************************************/ - -#ifndef TRANSFER_BUF_SIZE -#define TRANSFER_BUF_SIZE 65536 -#endif - - -ssize_t transfer_file_internal(void *in_file, - void *out_file, - size_t n, - ssize_t (*read_fn)(void *, void *, size_t), - ssize_t (*write_fn)(void *, void *, size_t)) -{ - char *buf; - size_t total = 0; - ssize_t read_ret; - ssize_t write_ret; - size_t num_to_read_thistime; - size_t num_written = 0; - - if ((buf = SMB_MALLOC_ARRAY(char, TRANSFER_BUF_SIZE)) == NULL) { - return -1; - } - - while (total < n) { - num_to_read_thistime = MIN((n - total), TRANSFER_BUF_SIZE); - - read_ret = (*read_fn)(in_file, buf, num_to_read_thistime); - if (read_ret == -1) { - DEBUG(0,("transfer_file_internal: read failure. " - "Error = %s\n", strerror(errno) )); - SAFE_FREE(buf); - return -1; - } - if (read_ret == 0) { - break; - } - - num_written = 0; - - while (num_written < read_ret) { - write_ret = (*write_fn)(out_file, buf + num_written, - read_ret - num_written); - - if (write_ret == -1) { - DEBUG(0,("transfer_file_internal: " - "write failure. Error = %s\n", - strerror(errno) )); - SAFE_FREE(buf); - return -1; - } - if (write_ret == 0) { - return (ssize_t)total; - } - - num_written += (size_t)write_ret; - } - - total += (size_t)read_ret; - } - - SAFE_FREE(buf); - return (ssize_t)total; -} - -static ssize_t sys_read_fn(void *file, void *buf, size_t len) -{ - int *fd = (int *)file; - - return sys_read(*fd, buf, len); -} - -static ssize_t sys_write_fn(void *file, void *buf, size_t len) -{ - int *fd = (int *)file; - - return sys_write(*fd, buf, len); -} - -SMB_OFF_T transfer_file(int infd, int outfd, SMB_OFF_T n) -{ - return (SMB_OFF_T)transfer_file_internal(&infd, &outfd, (size_t)n, - sys_read_fn, sys_write_fn); -} - /******************************************************************* Sleep for a specified number of milliseconds. ********************************************************************/ diff --git a/source3/lib/util_transfer_file.c b/source3/lib/util_transfer_file.c new file mode 100644 index 0000000000..1e3b76fc77 --- /dev/null +++ b/source3/lib/util_transfer_file.c @@ -0,0 +1,110 @@ +/* + * Unix SMB/CIFS implementation. + * Utility functions to transfer files. + * + * Copyright (C) Jeremy Allison 2001-2002 + * Copyright (C) Michael Adam 2008 + * + * 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 3 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, see . + */ + + +#include + +/**************************************************************************** + Transfer some data between two fd's. +****************************************************************************/ + +#ifndef TRANSFER_BUF_SIZE +#define TRANSFER_BUF_SIZE 65536 +#endif + + +ssize_t transfer_file_internal(void *in_file, + void *out_file, + size_t n, + ssize_t (*read_fn)(void *, void *, size_t), + ssize_t (*write_fn)(void *, const void *, size_t)) +{ + char *buf; + size_t total = 0; + ssize_t read_ret; + ssize_t write_ret; + size_t num_to_read_thistime; + size_t num_written = 0; + + if ((buf = SMB_MALLOC_ARRAY(char, TRANSFER_BUF_SIZE)) == NULL) { + return -1; + } + + while (total < n) { + num_to_read_thistime = MIN((n - total), TRANSFER_BUF_SIZE); + + read_ret = (*read_fn)(in_file, buf, num_to_read_thistime); + if (read_ret == -1) { + DEBUG(0,("transfer_file_internal: read failure. " + "Error = %s\n", strerror(errno) )); + SAFE_FREE(buf); + return -1; + } + if (read_ret == 0) { + break; + } + + num_written = 0; + + while (num_written < read_ret) { + write_ret = (*write_fn)(out_file, buf + num_written, + read_ret - num_written); + + if (write_ret == -1) { + DEBUG(0,("transfer_file_internal: " + "write failure. Error = %s\n", + strerror(errno) )); + SAFE_FREE(buf); + return -1; + } + if (write_ret == 0) { + return (ssize_t)total; + } + + num_written += (size_t)write_ret; + } + + total += (size_t)read_ret; + } + + SAFE_FREE(buf); + return (ssize_t)total; +} + +static ssize_t sys_read_fn(void *file, void *buf, size_t len) +{ + int *fd = (int *)file; + + return sys_read(*fd, buf, len); +} + +static ssize_t sys_write_fn(void *file, const void *buf, size_t len) +{ + int *fd = (int *)file; + + return sys_write(*fd, buf, len); +} + +SMB_OFF_T transfer_file(int infd, int outfd, SMB_OFF_T n) +{ + return (SMB_OFF_T)transfer_file_internal(&infd, &outfd, (size_t)n, + sys_read_fn, sys_write_fn); +} -- cgit From b7d222c690a8b5e2b15b694c95015f735eff9cda Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 10 Jan 2008 13:22:51 +0100 Subject: Tiny cosmetic fix (This used to be commit c82c1d462be6ddccd6e395b4a9630df91dacbda2) --- source3/lib/dbwrap_tdb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/dbwrap_tdb.c b/source3/lib/dbwrap_tdb.c index 83a0d111aa..710e45de6b 100644 --- a/source3/lib/dbwrap_tdb.c +++ b/source3/lib/dbwrap_tdb.c @@ -160,8 +160,7 @@ static int db_tdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, state.mem_ctx = mem_ctx; state.result = 0; - state.data.dptr = NULL; - state.data.dsize = 0; + state.data = tdb_null; tdb_parse_record(ctx->wtdb->tdb, key, db_tdb_fetch_parse, &state); -- cgit From 4eed7883bb0832157461cac1f0efcd6398746d7d Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 11 Jan 2008 14:47:23 +0100 Subject: Refactor libnetapi error string functions a bit. Guenther (This used to be commit 3b450a8bcc97b6d03c4b7b9373a3a382c0fcea30) --- source3/lib/netapi/netapi.c | 21 +++++++++++++++++---- source3/lib/netapi/netapi.h | 5 +++-- 2 files changed, 20 insertions(+), 6 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c index d4cb3a9fe2..ce00054e6e 100644 --- a/source3/lib/netapi/netapi.c +++ b/source3/lib/netapi/netapi.c @@ -192,8 +192,7 @@ NET_API_STATUS libnetapi_set_workgroup(struct libnetapi_ctx *ctx, /**************************************************************** ****************************************************************/ -const char *libnetapi_errstr(struct libnetapi_ctx *ctx, - NET_API_STATUS status) +const char *libnetapi_errstr(NET_API_STATUS status) { if (status & 0xc0000000) { return get_friendly_nt_error_msg(NT_STATUS(status)); @@ -220,9 +219,23 @@ NET_API_STATUS libnetapi_set_error_string(struct libnetapi_ctx *ctx, /**************************************************************** ****************************************************************/ -const char *libnetapi_get_error_string(struct libnetapi_ctx *ctx) +const char *libnetapi_get_error_string(struct libnetapi_ctx *ctx, + NET_API_STATUS status) { - return ctx->error_string; + struct libnetapi_ctx *tmp_ctx = ctx; + + if (!tmp_ctx) { + status = libnetapi_getctx(&tmp_ctx); + if (status != 0) { + return NULL; + } + } + + if (tmp_ctx->error_string) { + return tmp_ctx->error_string; + } + + return libnetapi_errstr(status); } /**************************************************************** diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h index 4a40b32fc9..61cece119f 100644 --- a/source3/lib/netapi/netapi.h +++ b/source3/lib/netapi/netapi.h @@ -46,9 +46,10 @@ NET_API_STATUS libnetapi_get_debuglevel(struct libnetapi_ctx *ctx, char **debugl NET_API_STATUS libnetapi_set_username(struct libnetapi_ctx *ctx, const char *username); NET_API_STATUS libnetapi_set_password(struct libnetapi_ctx *ctx, const char *password); NET_API_STATUS libnetapi_set_workgroup(struct libnetapi_ctx *ctx, const char *workgroup); -const char *libnetapi_errstr(struct libnetapi_ctx *ctx, NET_API_STATUS status); +const char *libnetapi_errstr(NET_API_STATUS status); NET_API_STATUS libnetapi_set_error_string(struct libnetapi_ctx *ctx, const char *error_string); -const char *libnetapi_get_error_string(struct libnetapi_ctx *ctx); +const char *libnetapi_get_error_string(struct libnetapi_ctx *ctx, NET_API_STATUS status); + /**************************************************************** ****************************************************************/ -- cgit From 7a87256cd1ac7962da9a5e37945ee5dd26a18c98 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 11 Jan 2008 14:47:52 +0100 Subject: Include some basic headers in netapi.h. Guenther (This used to be commit 23b92a6fa57858c8a23c737a9cd00c076ef5dadd) --- source3/lib/netapi/netapi.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h index 61cece119f..274a167d53 100644 --- a/source3/lib/netapi/netapi.h +++ b/source3/lib/netapi/netapi.h @@ -20,6 +20,16 @@ #ifndef __LIB_NETAPI_H__ #define __LIB_NETAPI_H__ +/**************************************************************** + include some basic headers +****************************************************************/ + +#include + +/**************************************************************** + NET_API_STATUS +****************************************************************/ + #define NET_API_STATUS uint32_t #define NET_API_STATUS_SUCCESS 0 -- cgit From efcf285e27e3f52cd6188f678d52977584c78972 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 11 Jan 2008 15:28:24 +0100 Subject: Fix libnetapi error string callers. Guenther (This used to be commit 1ad7a0a361edfa5ac738f011db1d6a9db256ac2c) --- source3/lib/netapi/examples/getdc/getdc.c | 2 +- source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c | 8 ++++---- source3/lib/netapi/examples/netdomjoin/netdomjoin.c | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/examples/getdc/getdc.c b/source3/lib/netapi/examples/getdc/getdc.c index 4f5c5332d5..cdd4d0b3b4 100644 --- a/source3/lib/netapi/examples/getdc/getdc.c +++ b/source3/lib/netapi/examples/getdc/getdc.c @@ -46,7 +46,7 @@ int main(int argc, char **argv) status = NetGetDCName(argv[1], argv[2], &buffer); if (status != 0) { - printf("GetDcName failed with: %s\n", libnetapi_errstr(ctx, status)); + printf("GetDcName failed with: %s\n", libnetapi_errstr(status)); } else { printf("%s\n", (char *)buffer); } diff --git a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c index 4a3588e9ab..9dc2a18138 100644 --- a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c +++ b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c @@ -147,13 +147,13 @@ static void callback_apply_description_change(GtkWidget *widget, status = NetServerSetInfo(NULL, 1005, (uint8_t *)&info1005, &parm_err); if (status) { debug("NetServerSetInfo failed with: %s\n", - libnetapi_errstr(state->ctx, status)); + libnetapi_errstr(status)); dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Failed to change computer description: %s.", - libnetapi_errstr(state->ctx, status)); + libnetapi_errstr(status)); g_signal_connect_swapped(dialog, "response", G_CALLBACK(gtk_widget_destroy), dialog); @@ -439,7 +439,7 @@ static void callback_do_join(GtkWidget *widget, state->password, unjoin_flags); if (status != 0) { - err_str = libnetapi_errstr(state->ctx, status); + err_str = libnetapi_errstr(status); g_print("callback_do_join: failed to unjoin (%s)\n", err_str); @@ -463,7 +463,7 @@ static void callback_do_join(GtkWidget *widget, state->password, join_flags); if (status != 0) { - err_str = libnetapi_errstr(state->ctx, status); + err_str = libnetapi_errstr(status); g_print("callback_do_join: failed to join (%s)\n", err_str); dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent), diff --git a/source3/lib/netapi/examples/netdomjoin/netdomjoin.c b/source3/lib/netapi/examples/netdomjoin/netdomjoin.c index a0ac0b1e56..29f66a17a2 100644 --- a/source3/lib/netapi/examples/netdomjoin/netdomjoin.c +++ b/source3/lib/netapi/examples/netdomjoin/netdomjoin.c @@ -105,9 +105,9 @@ int main(int argc, char **argv) join_flags); if (status != 0) { const char *errstr = NULL; - errstr = libnetapi_get_error_string(ctx); + errstr = libnetapi_get_error_string(ctx, status); if (!errstr) { - errstr = libnetapi_errstr(ctx, status); + errstr = libnetapi_errstr(status); } printf("Join failed with: %s\n", errstr); } else { -- cgit From c79ce2ffa3f7d00ce6a2cd6008c203e3042b0b02 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 11 Jan 2008 15:32:20 +0100 Subject: As long as DsGetDcName is not part of libnetapi, lowercase the fn name. Guenther (This used to be commit 19a980f52044a170618629e5b0484c1f6b586e5f) --- source3/lib/netapi/joindomain.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index e4fb63eebb..b268e41a2a 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -49,7 +49,7 @@ static WERROR NetJoinDomainLocal(struct libnetapi_ctx *mem_ctx, uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED | DS_WRITABLE_REQUIRED | DS_RETURN_DNS_NAME; - status = DsGetDcName(mem_ctx, NULL, domain_name, + status = dsgetdcname(mem_ctx, NULL, domain_name, NULL, NULL, flags, &info); if (!NT_STATUS_IS_OK(status)) { return ntstatus_to_werror(status); @@ -244,7 +244,7 @@ static WERROR NetUnjoinDomainLocal(struct libnetapi_ctx *mem_ctx, } else { domain = lp_workgroup(); } - status = DsGetDcName(mem_ctx, NULL, domain, + status = dsgetdcname(mem_ctx, NULL, domain, NULL, NULL, flags, &info); if (!NT_STATUS_IS_OK(status)) { return ntstatus_to_werror(status); -- cgit From 2ec41571a3efbea254cc3e132280a194c86a2f89 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 11 Jan 2008 15:08:37 -0800 Subject: Sync tdb with the tdb changes in ctdb. Spoke to tridge about this. Fixes insidious problem with order n^2 freelist merging. Jeremy. (This used to be commit c6609c042b128e7d63eb64cfdfb0f6b65cb59d76) --- source3/lib/tdb/common/freelist.c | 101 ++++++++--- source3/lib/tdb/common/io.c | 20 +- source3/lib/tdb/common/lock.c | 7 + source3/lib/tdb/common/open.c | 16 +- source3/lib/tdb/common/tdb.c | 72 +++++++- source3/lib/tdb/common/tdb_private.h | 8 +- source3/lib/tdb/common/transaction.c | 343 +++++++++++++++++------------------ source3/lib/tdb/common/traverse.c | 3 + source3/lib/tdb/configure.ac | 2 +- source3/lib/tdb/include/tdb.h | 4 + 10 files changed, 358 insertions(+), 218 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/tdb/common/freelist.c b/source3/lib/tdb/common/freelist.c index b109643f23..c086c151fa 100644 --- a/source3/lib/tdb/common/freelist.c +++ b/source3/lib/tdb/common/freelist.c @@ -27,6 +27,12 @@ #include "tdb_private.h" +/* 'right' merges can involve O(n^2) cost when combined with a + traverse, so they are disabled until we find a way to do them in + O(1) time +*/ +#define USE_RIGHT_MERGES 0 + /* read a freelist record and check for simple errors */ int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, struct list_struct *rec) { @@ -56,7 +62,7 @@ int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, struct list_struct } - +#if USE_RIGHT_MERGES /* Remove an element from the freelist. Must have alloc lock. */ static int remove_from_freelist(struct tdb_context *tdb, tdb_off_t off, tdb_off_t next) { @@ -75,6 +81,7 @@ static int remove_from_freelist(struct tdb_context *tdb, tdb_off_t off, tdb_off_ TDB_LOG((tdb, TDB_DEBUG_FATAL,"remove_from_freelist: not on list at off=%d\n", off)); return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); } +#endif /* update a record tailer (must hold allocation lock) */ @@ -93,8 +100,6 @@ static int update_tailer(struct tdb_context *tdb, tdb_off_t offset, neccessary. */ int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec) { - tdb_off_t right, left; - /* Allocation and tailer lock */ if (tdb_lock(tdb, -1, F_WRLCK) != 0) return -1; @@ -105,9 +110,10 @@ int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec) goto fail; } +#if USE_RIGHT_MERGES /* Look right first (I'm an Australian, dammit) */ - right = offset + sizeof(*rec) + rec->rec_len; - if (right + sizeof(*rec) <= tdb->map_size) { + if (offset + sizeof(*rec) + rec->rec_len + sizeof(*rec) <= tdb->map_size) { + tdb_off_t right = offset + sizeof(*rec) + rec->rec_len; struct list_struct r; if (tdb->methods->tdb_read(tdb, right, &r, sizeof(r), DOCONV()) == -1) { @@ -122,13 +128,18 @@ int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec) goto left; } rec->rec_len += sizeof(r) + r.rec_len; + if (update_tailer(tdb, offset, rec) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed at %u\n", offset)); + goto fail; + } } } - left: +#endif + /* Look left */ - left = offset - sizeof(tdb_off_t); - if (left > TDB_DATA_START(tdb->header.hash_size)) { + if (offset - sizeof(tdb_off_t) > TDB_DATA_START(tdb->header.hash_size)) { + tdb_off_t left = offset - sizeof(tdb_off_t); struct list_struct l; tdb_off_t leftsize; @@ -145,7 +156,12 @@ left: left = offset - leftsize; - /* Now read in record */ + if (leftsize > offset || + left < TDB_DATA_START(tdb->header.hash_size)) { + goto update; + } + + /* Now read in the left record */ if (tdb->methods->tdb_read(tdb, left, &l, sizeof(l), DOCONV()) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left read failed at %u (%u)\n", left, leftsize)); goto update; @@ -153,21 +169,24 @@ left: /* If it's free, expand to include it. */ if (l.magic == TDB_FREE_MAGIC) { - if (remove_from_freelist(tdb, left, l.next) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left free failed at %u\n", left)); - goto update; - } else { - offset = left; - rec->rec_len += leftsize; + /* we now merge the new record into the left record, rather than the other + way around. This makes the operation O(1) instead of O(n). This change + prevents traverse from being O(n^2) after a lot of deletes */ + l.rec_len += sizeof(*rec) + rec->rec_len; + if (tdb_rec_write(tdb, left, &l) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_left failed at %u\n", left)); + goto fail; } + if (update_tailer(tdb, left, &l) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed at %u\n", offset)); + goto fail; + } + tdb_unlock(tdb, -1, F_WRLCK); + return 0; } } update: - if (update_tailer(tdb, offset, rec) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed at %u\n", offset)); - goto fail; - } /* Now, prepend to free list */ rec->magic = TDB_FREE_MAGIC; @@ -261,6 +280,7 @@ tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct list_st tdb_off_t rec_ptr, last_ptr; tdb_len_t rec_len; } bestfit; + float multiplier = 1.0; if (tdb_lock(tdb, -1, F_WRLCK) == -1) return 0; @@ -295,18 +315,27 @@ tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct list_st bestfit.rec_len = rec->rec_len; bestfit.rec_ptr = rec_ptr; bestfit.last_ptr = last_ptr; - /* consider a fit to be good enough if - we aren't wasting more than half - the space */ - if (bestfit.rec_len < 2*length) { - break; - } } } /* move to the next record */ last_ptr = rec_ptr; rec_ptr = rec->next; + + /* if we've found a record that is big enough, then + stop searching if its also not too big. The + definition of 'too big' changes as we scan + through */ + if (bestfit.rec_len > 0 && + bestfit.rec_len < length * multiplier) { + break; + } + + /* this multiplier means we only extremely rarely + search more than 50 or so records. At 50 records we + accept records up to 11 times larger than what we + want */ + multiplier *= 1.05; } if (bestfit.rec_ptr != 0) { @@ -328,3 +357,25 @@ tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct list_st return 0; } + + +/* + return the size of the freelist - used to decide if we should repack +*/ +int tdb_freelist_size(struct tdb_context *tdb) +{ + tdb_off_t ptr; + int count=0; + + if (tdb_lock(tdb, -1, F_RDLCK) == -1) { + return -1; + } + + ptr = FREELIST_TOP; + while (tdb_ofs_read(tdb, ptr, &ptr) == 0 && ptr != 0) { + count++; + } + + tdb_unlock(tdb, -1, F_RDLCK); + return count; +} diff --git a/source3/lib/tdb/common/io.c b/source3/lib/tdb/common/io.c index 8ab0768883..172ab69d8c 100644 --- a/source3/lib/tdb/common/io.c +++ b/source3/lib/tdb/common/io.c @@ -101,8 +101,8 @@ static int tdb_write(struct tdb_context *tdb, tdb_off_t off, off+written); } if (written == -1) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_write failed at %d " "len=%d (%s)\n", off, len, strerror(errno))); return TDB_ERRCODE(TDB_ERR_IO, -1); @@ -111,8 +111,8 @@ static int tdb_write(struct tdb_context *tdb, tdb_off_t off, "write %d bytes at %d in two attempts\n", len, off)); errno = ENOSPC; - return TDB_ERRCODE(TDB_ERR_IO, -1); - } + return TDB_ERRCODE(TDB_ERR_IO, -1); + } } return 0; } @@ -230,7 +230,7 @@ void tdb_mmap(struct tdb_context *tdb) says to use for mmap expansion */ static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t addition) { - char buf[1024]; + char buf[8192]; if (tdb->read_only || tdb->traverse_read) { tdb->ecode = TDB_ERR_RDONLY; @@ -294,7 +294,7 @@ static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t ad int tdb_expand(struct tdb_context *tdb, tdb_off_t size) { struct list_struct rec; - tdb_off_t offset; + tdb_off_t offset, new_size; if (tdb_lock(tdb, -1, F_WRLCK) == -1) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "lock failed in tdb_expand\n")); @@ -304,9 +304,11 @@ int tdb_expand(struct tdb_context *tdb, tdb_off_t size) /* must know about any previous expansions by another process */ tdb->methods->tdb_oob(tdb, tdb->map_size + 1, 1); - /* always make room for at least 10 more records, and round - the database up to a multiple of the page size */ - size = TDB_ALIGN(tdb->map_size + size*10, tdb->page_size) - tdb->map_size; + /* always make room for at least 100 more records, and at + least 25% more space. Round the database up to a multiple + of the page size */ + new_size = MAX(tdb->map_size + size*100, tdb->map_size * 1.25); + size = TDB_ALIGN(new_size, tdb->page_size) - tdb->map_size; if (!(tdb->flags & TDB_INTERNAL)) tdb_munmap(tdb); diff --git a/source3/lib/tdb/common/lock.c b/source3/lib/tdb/common/lock.c index e3fe888c46..f156c0fa7b 100644 --- a/source3/lib/tdb/common/lock.c +++ b/source3/lib/tdb/common/lock.c @@ -505,6 +505,9 @@ int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key) /* record lock stops delete underneath */ int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off) { + if (tdb->global_lock.count) { + return 0; + } return off ? tdb->methods->tdb_brlock(tdb, off, F_RDLCK, F_SETLKW, 0, 1) : 0; } @@ -537,6 +540,10 @@ int tdb_unlock_record(struct tdb_context *tdb, tdb_off_t off) struct tdb_traverse_lock *i; uint32_t count = 0; + if (tdb->global_lock.count) { + return 0; + } + if (off == 0) return 0; for (i = &tdb->travlocks; i; i = i->next) diff --git a/source3/lib/tdb/common/open.c b/source3/lib/tdb/common/open.c index 6efa482ac2..6bd8fda2bf 100644 --- a/source3/lib/tdb/common/open.c +++ b/source3/lib/tdb/common/open.c @@ -35,7 +35,7 @@ static struct tdb_context *tdbs = NULL; static unsigned int default_tdb_hash(TDB_DATA *key) { uint32_t value; /* Used to compute the hash value. */ - uint32_t i; /* Used to cycle through random values. */ + uint32_t i; /* Used to cycle through random values. */ /* Set the initial value from the key size. */ for (value = 0x238F13AF * key->dsize, i=0; i < key->dsize; i++) @@ -90,7 +90,7 @@ static int tdb_new_database(struct tdb_context *tdb, int hash_size) size -= written; written = write(tdb->fd, newdb+written, size); if (written == size) { - ret = 0; + ret = 0; } else if (written >= 0) { /* a second incomplete write - we give up. * guessing the errno... */ @@ -152,6 +152,7 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, int rev = 0, locked = 0; unsigned char *vp; uint32_t vertest; + unsigned v; if (!(tdb = (struct tdb_context *)calloc(1, sizeof *tdb))) { /* Can't log this */ @@ -178,7 +179,9 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, tdb->page_size = 0x2000; } - tdb->max_dead_records = (open_flags & TDB_VOLATILE) ? 5 : 0; + if (open_flags & TDB_VOLATILE) { + tdb->max_dead_records = 5; + } if ((open_flags & O_ACCMODE) == O_WRONLY) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't open tdb %s write-only\n", @@ -213,6 +216,10 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, goto fail; /* errno set by open(2) */ } + /* on exec, don't inherit the fd */ + v = fcntl(tdb->fd, F_GETFD, 0); + fcntl(tdb->fd, F_SETFD, v | FD_CLOEXEC); + /* ensure there is only one process initialising at once */ if (tdb->methods->tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to get global lock on %s: %s\n", @@ -240,7 +247,7 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, /* its not a valid database - possibly initialise it */ if (!(open_flags & O_CREAT) || tdb_new_database(tdb, hash_size) == -1) { if (errno == 0) { - errno = EIO; /* ie bad format or something */ + errno = EIO; /* ie bad format or something */ } goto fail; } @@ -281,6 +288,7 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, tdb->map_size = st.st_size; tdb->device = st.st_dev; tdb->inode = st.st_ino; + tdb->max_dead_records = 0; tdb_mmap(tdb); if (locked) { if (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK, 0, 1) == -1) { diff --git a/source3/lib/tdb/common/tdb.c b/source3/lib/tdb/common/tdb.c index 0e9d1dbd74..bf3abb71ac 100644 --- a/source3/lib/tdb/common/tdb.c +++ b/source3/lib/tdb/common/tdb.c @@ -102,8 +102,7 @@ static tdb_off_t tdb_find(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, } /* As tdb_find, but if you succeed, keep the lock */ -tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, - uint32_t hash, int locktype, +tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype, struct list_struct *rec) { uint32_t rec_ptr; @@ -237,14 +236,15 @@ int tdb_exists(struct tdb_context *tdb, TDB_DATA key) } /* actually delete an entry in the database given the offset */ -int tdb_do_delete(struct tdb_context *tdb, tdb_off_t rec_ptr, struct list_struct*rec) +int tdb_do_delete(struct tdb_context *tdb, tdb_off_t rec_ptr, struct list_struct *rec) { tdb_off_t last_ptr, i; struct list_struct lastrec; if (tdb->read_only || tdb->traverse_read) return -1; - if (tdb_write_lock_record(tdb, rec_ptr) == -1) { + if (tdb->traverse_write != 0 || + tdb_write_lock_record(tdb, rec_ptr) == -1) { /* Someone traversing here: mark it as dead */ rec->magic = TDB_DEAD_MAGIC; return tdb_rec_write(tdb, rec_ptr, rec); @@ -666,6 +666,16 @@ int tdb_get_flags(struct tdb_context *tdb) return tdb->flags; } +void tdb_add_flags(struct tdb_context *tdb, unsigned flags) +{ + tdb->flags |= flags; +} + +void tdb_remove_flags(struct tdb_context *tdb, unsigned flags) +{ + tdb->flags &= ~flags; +} + /* enable sequence number handling on an open tdb @@ -674,3 +684,57 @@ void tdb_enable_seqnum(struct tdb_context *tdb) { tdb->flags |= TDB_SEQNUM; } + + +/* + wipe the entire database, deleting all records. This can be done + very fast by using a global lock. The entire data portion of the + file becomes a single entry in the freelist. + */ +int tdb_wipe_all(struct tdb_context *tdb) +{ + int i; + tdb_off_t offset = 0; + ssize_t data_len; + + if (tdb_lockall(tdb) != 0) { + return -1; + } + + /* wipe the hashes */ + for (i=0;iheader.hash_size;i++) { + if (tdb_ofs_write(tdb, TDB_HASH_TOP(i), &offset) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write hash %d\n", i)); + goto failed; + } + } + + /* wipe the freelist */ + if (tdb_ofs_write(tdb, FREELIST_TOP, &offset) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write freelist\n")); + goto failed; + } + + /* add all the rest of the file to the freelist */ + data_len = (tdb->map_size - TDB_DATA_START(tdb->header.hash_size)) - sizeof(struct list_struct); + if (data_len > 0) { + struct list_struct rec; + memset(&rec,'\0',sizeof(rec)); + rec.rec_len = data_len; + if (tdb_free(tdb, TDB_DATA_START(tdb->header.hash_size), &rec) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to add free record\n")); + goto failed; + } + } + + if (tdb_unlockall(tdb) != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to unlock\n")); + goto failed; + } + + return 0; + +failed: + tdb_unlockall(tdb); + return -1; +} diff --git a/source3/lib/tdb/common/tdb_private.h b/source3/lib/tdb/common/tdb_private.h index 58c30c1706..63a6d04e72 100644 --- a/source3/lib/tdb/common/tdb_private.h +++ b/source3/lib/tdb/common/tdb_private.h @@ -38,6 +38,10 @@ typedef uint32_t tdb_len_t; typedef uint32_t tdb_off_t; +#ifndef offsetof +#define offsetof(t,f) ((unsigned int)&((t *)0)->f) +#endif + #define TDB_MAGIC_FOOD "TDB file\n" #define TDB_VERSION (0x26011967 + 6) #define TDB_MAGIC (0x26011999U) @@ -54,7 +58,7 @@ typedef uint32_t tdb_off_t; #define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r)) #define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off_t)) #define TDB_HASHTABLE_SIZE(tdb) ((tdb->header.hash_size+1)*sizeof(tdb_off_t)) -#define TDB_DATA_START(hash_size) TDB_HASH_TOP(hash_size-1) +#define TDB_DATA_START(hash_size) (TDB_HASH_TOP(hash_size-1) + sizeof(tdb_off_t)) #define TDB_RECOVERY_HEAD offsetof(struct tdb_header, recovery_start) #define TDB_SEQNUM_OFS offsetof(struct tdb_header, sequence_number) #define TDB_PAD_BYTE 0x42 @@ -144,6 +148,7 @@ struct tdb_context { tdb_len_t map_size; /* how much space has been mapped */ int read_only; /* opened read-only */ int traverse_read; /* read-only traversal */ + int traverse_write; /* read-write traversal */ struct tdb_lock_type global_lock; int num_lockrecs; struct tdb_lock_type *lockrecs; /* only real locks, all with count>0 */ @@ -173,7 +178,6 @@ struct tdb_context { int tdb_munmap(struct tdb_context *tdb); void tdb_mmap(struct tdb_context *tdb); int tdb_lock(struct tdb_context *tdb, int list, int ltype); -int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype); int tdb_unlock(struct tdb_context *tdb, int list, int ltype); int tdb_brlock(struct tdb_context *tdb, tdb_off_t offset, int rw_type, int lck_type, int probe, size_t len); int tdb_transaction_lock(struct tdb_context *tdb, int ltype); diff --git a/source3/lib/tdb/common/transaction.c b/source3/lib/tdb/common/transaction.c index 7eaacf7a16..2da09face0 100644 --- a/source3/lib/tdb/common/transaction.c +++ b/source3/lib/tdb/common/transaction.c @@ -87,13 +87,6 @@ */ -struct tdb_transaction_el { - struct tdb_transaction_el *next, *prev; - tdb_off_t offset; - tdb_len_t length; - unsigned char *data; -}; - /* hold the context of any current transaction */ @@ -105,12 +98,12 @@ struct tdb_transaction { /* the original io methods - used to do IOs to the real db */ const struct tdb_methods *io_methods; - /* the list of transaction elements. We use a doubly linked - list with a last pointer to allow us to keep the list - ordered, with first element at the front of the list. It - needs to be doubly linked as the read/write traversals need - to be backwards, while the commit needs to be forwards */ - struct tdb_transaction_el *elements, *elements_last; + /* the list of transaction blocks. When a block is first + written to, it gets created in this list */ + uint8_t **blocks; + uint32_t num_blocks; + uint32_t block_size; /* bytes in each block */ + uint32_t last_block_size; /* number of valid bytes in the last block */ /* non-zero when an internal transaction error has occurred. All write operations will then fail until the @@ -134,52 +127,48 @@ struct tdb_transaction { static int transaction_read(struct tdb_context *tdb, tdb_off_t off, void *buf, tdb_len_t len, int cv) { - struct tdb_transaction_el *el; - - /* we need to walk the list backwards to get the most recent data */ - for (el=tdb->transaction->elements_last;el;el=el->prev) { - tdb_len_t partial; + uint32_t blk; - if (off+len <= el->offset) { - continue; - } - if (off >= el->offset + el->length) { - continue; + /* break it down into block sized ops */ + while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { + tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); + if (transaction_read(tdb, off, buf, len2, cv) != 0) { + return -1; } + len -= len2; + off += len2; + buf = (void *)(len2 + (char *)buf); + } - /* an overlapping read - needs to be split into up to - 2 reads and a memcpy */ - if (off < el->offset) { - partial = el->offset - off; - if (transaction_read(tdb, off, buf, partial, cv) != 0) { - goto fail; - } - len -= partial; - off += partial; - buf = (void *)(partial + (char *)buf); - } - if (off + len <= el->offset + el->length) { - partial = len; - } else { - partial = el->offset + el->length - off; - } - memcpy(buf, el->data + (off - el->offset), partial); - if (cv) { - tdb_convert(buf, len); - } - len -= partial; - off += partial; - buf = (void *)(partial + (char *)buf); - - if (len != 0 && transaction_read(tdb, off, buf, len, cv) != 0) { + if (len == 0) { + return 0; + } + + blk = off / tdb->transaction->block_size; + + /* see if we have it in the block list */ + if (tdb->transaction->num_blocks <= blk || + tdb->transaction->blocks[blk] == NULL) { + /* nope, do a real read */ + if (tdb->transaction->io_methods->tdb_read(tdb, off, buf, len, cv) != 0) { goto fail; } - return 0; } - /* its not in the transaction elements - do a real read */ - return tdb->transaction->io_methods->tdb_read(tdb, off, buf, len, cv); + /* it is in the block list. Now check for the last block */ + if (blk == tdb->transaction->num_blocks-1) { + if (len > tdb->transaction->last_block_size) { + goto fail; + } + } + + /* now copy it out of this block */ + memcpy(buf, tdb->transaction->blocks[blk] + (off % tdb->transaction->block_size), len); + if (cv) { + tdb_convert(buf, len); + } + return 0; fail: TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_read: failed at off=%d len=%d\n", off, len)); @@ -195,12 +184,8 @@ fail: static int transaction_write(struct tdb_context *tdb, tdb_off_t off, const void *buf, tdb_len_t len) { - struct tdb_transaction_el *el, *best_el=NULL; + uint32_t blk; - if (len == 0) { - return 0; - } - /* if the write is to a hash head, then update the transaction hash heads */ if (len == sizeof(tdb_off_t) && off >= FREELIST_TOP && @@ -209,106 +194,88 @@ static int transaction_write(struct tdb_context *tdb, tdb_off_t off, memcpy(&tdb->transaction->hash_heads[chain], buf, len); } - /* first see if we can replace an existing entry */ - for (el=tdb->transaction->elements_last;el;el=el->prev) { - tdb_len_t partial; - - if (best_el == NULL && off == el->offset+el->length) { - best_el = el; + /* break it up into block sized chunks */ + while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { + tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); + if (transaction_write(tdb, off, buf, len2) != 0) { + return -1; } - - if (off+len <= el->offset) { - continue; - } - if (off >= el->offset + el->length) { - continue; + len -= len2; + off += len2; + if (buf != NULL) { + buf = (const void *)(len2 + (const char *)buf); } + } - /* an overlapping write - needs to be split into up to - 2 writes and a memcpy */ - if (off < el->offset) { - partial = el->offset - off; - if (transaction_write(tdb, off, buf, partial) != 0) { - goto fail; - } - len -= partial; - off += partial; - buf = (const void *)(partial + (const char *)buf); - } - if (off + len <= el->offset + el->length) { - partial = len; + if (len == 0) { + return 0; + } + + blk = off / tdb->transaction->block_size; + off = off % tdb->transaction->block_size; + + if (tdb->transaction->num_blocks <= blk) { + uint8_t **new_blocks; + /* expand the blocks array */ + if (tdb->transaction->blocks == NULL) { + new_blocks = malloc((blk+1)*sizeof(uint8_t *)); } else { - partial = el->offset + el->length - off; + new_blocks = realloc(tdb->transaction->blocks, (blk+1)*sizeof(uint8_t *)); } - memcpy(el->data + (off - el->offset), buf, partial); - len -= partial; - off += partial; - buf = (const void *)(partial + (const char *)buf); - - if (len != 0 && transaction_write(tdb, off, buf, len) != 0) { + if (new_blocks == NULL) { + tdb->ecode = TDB_ERR_OOM; goto fail; } - - return 0; + memset(&new_blocks[tdb->transaction->num_blocks], 0, + (1+(blk - tdb->transaction->num_blocks))*sizeof(uint8_t *)); + tdb->transaction->blocks = new_blocks; + tdb->transaction->num_blocks = blk+1; + tdb->transaction->last_block_size = 0; } - /* see if we can append the new entry to an existing entry */ - if (best_el && best_el->offset + best_el->length == off && - (off+len < tdb->transaction->old_map_size || - off > tdb->transaction->old_map_size)) { - unsigned char *data = best_el->data; - el = best_el; - el->data = (unsigned char *)realloc(el->data, - el->length + len); - if (el->data == NULL) { + /* allocate and fill a block? */ + if (tdb->transaction->blocks[blk] == NULL) { + tdb->transaction->blocks[blk] = (uint8_t *)calloc(tdb->transaction->block_size, 1); + if (tdb->transaction->blocks[blk] == NULL) { tdb->ecode = TDB_ERR_OOM; tdb->transaction->transaction_error = 1; - el->data = data; - return -1; + return -1; } - if (buf) { - memcpy(el->data + el->length, buf, len); - } else { - memset(el->data + el->length, TDB_PAD_BYTE, len); + if (tdb->transaction->old_map_size > blk * tdb->transaction->block_size) { + tdb_len_t len2 = tdb->transaction->block_size; + if (len2 + (blk * tdb->transaction->block_size) > tdb->transaction->old_map_size) { + len2 = tdb->transaction->old_map_size - (blk * tdb->transaction->block_size); + } + if (tdb->transaction->io_methods->tdb_read(tdb, blk * tdb->transaction->block_size, + tdb->transaction->blocks[blk], + len2, 0) != 0) { + SAFE_FREE(tdb->transaction->blocks[blk]); + tdb->ecode = TDB_ERR_IO; + goto fail; + } + if (blk == tdb->transaction->num_blocks-1) { + tdb->transaction->last_block_size = len2; + } } - el->length += len; - return 0; } - - /* add a new entry at the end of the list */ - el = (struct tdb_transaction_el *)malloc(sizeof(*el)); - if (el == NULL) { - tdb->ecode = TDB_ERR_OOM; - tdb->transaction->transaction_error = 1; - return -1; - } - el->next = NULL; - el->prev = tdb->transaction->elements_last; - el->offset = off; - el->length = len; - el->data = (unsigned char *)malloc(len); - if (el->data == NULL) { - free(el); - tdb->ecode = TDB_ERR_OOM; - tdb->transaction->transaction_error = 1; - return -1; - } - if (buf) { - memcpy(el->data, buf, len); + + /* overwrite part of an existing block */ + if (buf == NULL) { + memset(tdb->transaction->blocks[blk] + off, 0, len); } else { - memset(el->data, TDB_PAD_BYTE, len); + memcpy(tdb->transaction->blocks[blk] + off, buf, len); } - if (el->prev) { - el->prev->next = el; - } else { - tdb->transaction->elements = el; + if (blk == tdb->transaction->num_blocks-1) { + if (len + off > tdb->transaction->last_block_size) { + tdb->transaction->last_block_size = len + off; + } } - tdb->transaction->elements_last = el; + return 0; fail: - TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: failed at off=%d len=%d\n", off, len)); - tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: failed at off=%d len=%d\n", + (blk*tdb->transaction->block_size) + off, len)); tdb->transaction->transaction_error = 1; return -1; } @@ -419,10 +386,14 @@ int tdb_transaction_start(struct tdb_context *tdb) return -1; } + /* a page at a time seems like a reasonable compromise between compactness and efficiency */ + tdb->transaction->block_size = tdb->page_size; + /* get the transaction write lock. This is a blocking lock. As discussed with Volker, there are a number of ways we could make this async, which we will probably do in the future */ if (tdb_transaction_lock(tdb, F_WRLCK) == -1) { + SAFE_FREE(tdb->transaction->blocks); SAFE_FREE(tdb->transaction); return -1; } @@ -460,21 +431,12 @@ int tdb_transaction_start(struct tdb_context *tdb) tdb->transaction->io_methods = tdb->methods; tdb->methods = &transaction_methods; - /* by calling this transaction write here, we ensure that we don't grow the - transaction linked list due to hash table updates */ - if (transaction_write(tdb, FREELIST_TOP, tdb->transaction->hash_heads, - TDB_HASHTABLE_SIZE(tdb)) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_start: failed to prime hash table\n")); - tdb->ecode = TDB_ERR_IO; - tdb->methods = tdb->transaction->io_methods; - goto fail; - } - return 0; fail: tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0); tdb_transaction_unlock(tdb); + SAFE_FREE(tdb->transaction->blocks); SAFE_FREE(tdb->transaction->hash_heads); SAFE_FREE(tdb->transaction); return -1; @@ -486,6 +448,8 @@ fail: */ int tdb_transaction_cancel(struct tdb_context *tdb) { + int i; + if (tdb->transaction == NULL) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_cancel: no transaction\n")); return -1; @@ -499,13 +463,13 @@ int tdb_transaction_cancel(struct tdb_context *tdb) tdb->map_size = tdb->transaction->old_map_size; - /* free all the transaction elements */ - while (tdb->transaction->elements) { - struct tdb_transaction_el *el = tdb->transaction->elements; - tdb->transaction->elements = el->next; - free(el->data); - free(el); + /* free all the transaction blocks */ + for (i=0;itransaction->num_blocks;i++) { + if (tdb->transaction->blocks[i] != NULL) { + free(tdb->transaction->blocks[i]); + } } + SAFE_FREE(tdb->transaction->blocks); /* remove any global lock created during the transaction */ if (tdb->global_lock.count != 0) { @@ -515,7 +479,6 @@ int tdb_transaction_cancel(struct tdb_context *tdb) /* remove any locks created during the transaction */ if (tdb->num_locks != 0) { - int i; for (i=0;inum_lockrecs;i++) { tdb_brlock(tdb,FREELIST_TOP+4*tdb->lockrecs[i].list, F_UNLCK,F_SETLKW, 0, 1); @@ -567,16 +530,24 @@ static int transaction_sync(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t */ static tdb_len_t tdb_recovery_size(struct tdb_context *tdb) { - struct tdb_transaction_el *el; tdb_len_t recovery_size = 0; + int i; recovery_size = sizeof(uint32_t); - for (el=tdb->transaction->elements;el;el=el->next) { - if (el->offset >= tdb->transaction->old_map_size) { + for (i=0;itransaction->num_blocks;i++) { + if (i * tdb->transaction->block_size >= tdb->transaction->old_map_size) { + break; + } + if (tdb->transaction->blocks[i] == NULL) { continue; } - recovery_size += 2*sizeof(tdb_off_t) + el->length; - } + recovery_size += 2*sizeof(tdb_off_t); + if (i == tdb->transaction->num_blocks-1) { + recovery_size += tdb->transaction->last_block_size; + } else { + recovery_size += tdb->transaction->block_size; + } + } return recovery_size; } @@ -669,7 +640,6 @@ static int tdb_recovery_allocate(struct tdb_context *tdb, static int transaction_setup_recovery(struct tdb_context *tdb, tdb_off_t *magic_offset) { - struct tdb_transaction_el *el; tdb_len_t recovery_size; unsigned char *data, *p; const struct tdb_methods *methods = tdb->transaction->io_methods; @@ -677,6 +647,7 @@ static int transaction_setup_recovery(struct tdb_context *tdb, tdb_off_t recovery_offset, recovery_max_size; tdb_off_t old_map_size = tdb->transaction->old_map_size; uint32_t magic, tailer; + int i; /* check that the recovery area has enough space @@ -704,30 +675,43 @@ static int transaction_setup_recovery(struct tdb_context *tdb, /* build the recovery data into a single blob to allow us to do a single large write, which should be more efficient */ p = data + sizeof(*rec); - for (el=tdb->transaction->elements;el;el=el->next) { - if (el->offset >= old_map_size) { + for (i=0;itransaction->num_blocks;i++) { + tdb_off_t offset; + tdb_len_t length; + + if (tdb->transaction->blocks[i] == NULL) { continue; } - if (el->offset + el->length > tdb->transaction->old_map_size) { + + offset = i * tdb->transaction->block_size; + length = tdb->transaction->block_size; + if (i == tdb->transaction->num_blocks-1) { + length = tdb->transaction->last_block_size; + } + + if (offset >= old_map_size) { + continue; + } + if (offset + length > tdb->transaction->old_map_size) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: transaction data over new region boundary\n")); free(data); tdb->ecode = TDB_ERR_CORRUPT; return -1; } - memcpy(p, &el->offset, 4); - memcpy(p+4, &el->length, 4); + memcpy(p, &offset, 4); + memcpy(p+4, &length, 4); if (DOCONV()) { tdb_convert(p, 8); } /* the recovery area contains the old data, not the new data, so we have to call the original tdb_read method to get it */ - if (methods->tdb_read(tdb, el->offset, p + 8, el->length, 0) != 0) { + if (methods->tdb_read(tdb, offset, p + 8, length, 0) != 0) { free(data); tdb->ecode = TDB_ERR_IO; return -1; } - p += 8 + el->length; + p += 8 + length; } /* and the tailer */ @@ -780,6 +764,7 @@ int tdb_transaction_commit(struct tdb_context *tdb) const struct tdb_methods *methods; tdb_off_t magic_offset = 0; uint32_t zero = 0; + int i; if (tdb->transaction == NULL) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: no transaction\n")); @@ -799,7 +784,7 @@ int tdb_transaction_commit(struct tdb_context *tdb) } /* check for a null transaction */ - if (tdb->transaction->elements == NULL) { + if (tdb->transaction->blocks == NULL) { tdb_transaction_cancel(tdb); return 0; } @@ -858,10 +843,21 @@ int tdb_transaction_commit(struct tdb_context *tdb) } /* perform all the writes */ - while (tdb->transaction->elements) { - struct tdb_transaction_el *el = tdb->transaction->elements; + for (i=0;itransaction->num_blocks;i++) { + tdb_off_t offset; + tdb_len_t length; - if (methods->tdb_write(tdb, el->offset, el->data, el->length) == -1) { + if (tdb->transaction->blocks[i] == NULL) { + continue; + } + + offset = i * tdb->transaction->block_size; + length = tdb->transaction->block_size; + if (i == tdb->transaction->num_blocks-1) { + length = tdb->transaction->last_block_size; + } + + if (methods->tdb_write(tdb, offset, tdb->transaction->blocks[i], length) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed during commit\n")); /* we've overwritten part of the data and @@ -876,11 +872,12 @@ int tdb_transaction_commit(struct tdb_context *tdb) TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed\n")); return -1; } - tdb->transaction->elements = el->next; - free(el->data); - free(el); + SAFE_FREE(tdb->transaction->blocks[i]); } + SAFE_FREE(tdb->transaction->blocks); + tdb->transaction->num_blocks = 0; + if (!(tdb->flags & TDB_NOSYNC)) { /* ensure the new data is on disk */ if (transaction_sync(tdb, 0, tdb->map_size) == -1) { diff --git a/source3/lib/tdb/common/traverse.c b/source3/lib/tdb/common/traverse.c index 27b2cfc54a..07b0c23858 100644 --- a/source3/lib/tdb/common/traverse.c +++ b/source3/lib/tdb/common/traverse.c @@ -241,7 +241,9 @@ int tdb_traverse(struct tdb_context *tdb, return -1; } + tdb->traverse_write++; ret = tdb_traverse_internal(tdb, fn, private_data, &tl); + tdb->traverse_write--; tdb_transaction_unlock(tdb); @@ -333,3 +335,4 @@ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey) TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n")); return key; } + diff --git a/source3/lib/tdb/configure.ac b/source3/lib/tdb/configure.ac index de8fc9c2b5..1085055bc9 100644 --- a/source3/lib/tdb/configure.ac +++ b/source3/lib/tdb/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ(2.50) AC_DEFUN([SMB_MODULE_DEFAULT], [echo -n ""]) AC_DEFUN([SMB_LIBRARY_ENABLE], [echo -n ""]) AC_DEFUN([SMB_ENABLE], [echo -n ""]) -AC_INIT(tdb, 1.1.0) +AC_INIT(tdb, 1.1.1) AC_CONFIG_SRCDIR([common/tdb.c]) AC_CONFIG_HEADER(include/config.h) AC_LIBREPLACE_ALL_CHECKS diff --git a/source3/lib/tdb/include/tdb.h b/source3/lib/tdb/include/tdb.h index fce6628b84..0008085de5 100644 --- a/source3/lib/tdb/include/tdb.h +++ b/source3/lib/tdb/include/tdb.h @@ -135,6 +135,8 @@ int tdb_get_seqnum(struct tdb_context *tdb); int tdb_hash_size(struct tdb_context *tdb); size_t tdb_map_size(struct tdb_context *tdb); int tdb_get_flags(struct tdb_context *tdb); +void tdb_add_flags(struct tdb_context *tdb, unsigned flag); +void tdb_remove_flags(struct tdb_context *tdb, unsigned flag); void tdb_enable_seqnum(struct tdb_context *tdb); void tdb_increment_seqnum_nonblock(struct tdb_context *tdb); @@ -153,6 +155,8 @@ void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *sigptr) void tdb_dump_all(struct tdb_context *tdb); int tdb_printfreelist(struct tdb_context *tdb); int tdb_validate_freelist(struct tdb_context *tdb, int *pnum_entries); +int tdb_wipe_all(struct tdb_context *tdb); +int tdb_freelist_size(struct tdb_context *tdb); extern TDB_DATA tdb_null; -- cgit From 360673e80e8d46167afb6c393773895b369ff290 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 12 Jan 2008 00:15:46 -0800 Subject: CID 458. Don't leak dlopen handles on failing to load module. Jeremy. (This used to be commit 8809eaeb154ea12543455f589e31172dc905d83a) --- source3/lib/module.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/module.c b/source3/lib/module.c index fa06d14b49..285bd9c4c0 100644 --- a/source3/lib/module.c +++ b/source3/lib/module.c @@ -57,6 +57,7 @@ static NTSTATUS do_smb_load_module(const char *module_name, bool is_probe) if (error) { DEBUG(0, ("Error trying to resolve symbol 'init_module' in %s: %s\n", module_name, error)); + sys_dlclose(handle); return NT_STATUS_UNSUCCESSFUL; } @@ -66,6 +67,7 @@ static NTSTATUS do_smb_load_module(const char *module_name, bool is_probe) if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Module '%s' initialization failed: %s\n", module_name, get_friendly_nt_error_msg(status))); + sys_dlclose(handle); } return status; -- cgit From 4af27ec877d67afc719bccd350dae33ef8dd62b5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 12 Jan 2008 10:38:17 +0100 Subject: Restructure dbwrap_rbt In this low-level code, play tricks to reduce the number of allocations to the possible minimum. I would not recommend this for higher-level code, but here it pays off. (This used to be commit 71b1e6ff1595fbaa8dd49b996c45541531c7e98c) --- source3/lib/dbwrap_rbt.c | 186 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 127 insertions(+), 59 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/dbwrap_rbt.c b/source3/lib/dbwrap_rbt.c index 93d73f29d1..633b695b52 100644 --- a/source3/lib/dbwrap_rbt.c +++ b/source3/lib/dbwrap_rbt.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. Database interface wrapper around red-black trees - Copyright (C) Volker Lendecke 2007 + Copyright (C) Volker Lendecke 2007, 2008 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 @@ -20,6 +20,8 @@ #include "includes.h" #include "rbtree.h" +#define ALIGN(_size_) (((_size_)+15)&~15) + struct db_rbt_ctx { struct rb_root tree; }; @@ -43,6 +45,35 @@ struct db_rbt_node { char data[]; }; +/* + * Hide the ugly pointer calculations in a function + */ + +static struct db_rbt_node *db_rbt2node(struct rb_node *node) +{ + return (struct db_rbt_node *) + ((char *)node - offsetof(struct db_rbt_node, rb_node)); +} + +/* + * Compare two keys + */ + +static int db_rbt_compare(TDB_DATA a, TDB_DATA b) +{ + int res; + + res = memcmp(a.dptr, b.dptr, MIN(a.dsize, b.dsize)); + + if ((res < 0) || ((res == 0) && (a.dsize < b.dsize))) { + return -1; + } + if ((res > 0) || ((res == 0) && (a.dsize > b.dsize))) { + return 1; + } + return 0; +} + /* * dissect a db_rbt_node into its implicit key and value parts */ @@ -58,9 +89,7 @@ static void db_rbt_parse_node(struct db_rbt_node *node, static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) { - struct db_rbt_rec *rec_priv = talloc_get_type_abort( - rec->private_data, struct db_rbt_rec); - + struct db_rbt_rec *rec_priv = (struct db_rbt_rec *)rec->private_data; struct db_rbt_node *node; struct rb_node ** p; @@ -133,22 +162,16 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) parent = (*p); - r = (struct db_rbt_node *) - ((char *)(*p) - offsetof(struct db_rbt_node, rb_node)); + r = db_rbt2node(*p); db_rbt_parse_node(r, &search_key, &search_val); - res = memcmp(this_key.dptr, search_key.dptr, - MIN(this_key.dsize, search_key.dsize)); + res = db_rbt_compare(this_key, search_key); - if ((res < 0) - || ((res == 0) - && (this_key.dsize < search_key.dsize))) { + if (res == -1) { p = &(*p)->rb_left; } - else if ((res > 0) - || ((res == 0) - && (this_key.dsize > search_key.dsize))) { + else if (res == 1) { p = &(*p)->rb_right; } else { @@ -164,8 +187,7 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) static NTSTATUS db_rbt_delete(struct db_record *rec) { - struct db_rbt_rec *rec_priv = talloc_get_type_abort( - rec->private_data, struct db_rbt_rec); + struct db_rbt_rec *rec_priv = (struct db_rbt_rec *)rec->private_data; if (rec_priv->node == NULL) { return NT_STATUS_OK; @@ -187,85 +209,128 @@ static struct db_record *db_rbt_fetch_locked(struct db_context *db_ctx, struct db_rbt_rec *rec_priv; struct db_record *result; struct rb_node *n; + size_t size; + bool found = false; + struct db_rbt_node *r = NULL; + TDB_DATA search_key = tdb_null, search_val = tdb_null; - result = talloc(mem_ctx, struct db_record); + n = ctx->tree.rb_node; - if (result == NULL) { - return NULL; + while (n != NULL) { + int res; + + r = db_rbt2node(n); + + db_rbt_parse_node(r, &search_key, &search_val); + + res = db_rbt_compare(key, search_key); + + if (res == -1) { + n = n->rb_left; + } + else if (res == 1) { + n = n->rb_right; + } + else { + found = true; + break; + } } - rec_priv = talloc(result, struct db_rbt_rec); + /* + * In this low-level routine, play tricks to reduce the number of + * tallocs to one. Not recommened for general use, but here it pays + * off. + */ - if (rec_priv == NULL) { - TALLOC_FREE(result); + size = ALIGN(sizeof(struct db_record)) + sizeof(struct db_rbt_rec); + + if (!found) { + /* + * We need to keep the key around for later store + */ + size += key.dsize; + } + + result = (struct db_record *)talloc_size(mem_ctx, size); + if (result == NULL) { return NULL; } + rec_priv = (struct db_rbt_rec *) + ((char *)result + ALIGN(sizeof(struct db_record))); rec_priv->db_ctx = ctx; result->store = db_rbt_store; result->delete_rec = db_rbt_delete; result->private_data = rec_priv; + if (found) { + rec_priv->node = r; + result->key = search_key; + result->value = search_val; + } + else { + rec_priv->node = NULL; + result->key.dptr = (uint8 *) + ((char *)rec_priv + sizeof(*rec_priv)); + result->key.dsize = key.dsize; + memcpy(result->key.dptr, key.dptr, key.dsize); + + result->value = tdb_null; + } + + return result; +} + +static int db_rbt_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, + TDB_DATA key, TDB_DATA *data) +{ + struct db_rbt_ctx *ctx = talloc_get_type_abort( + db->private_data, struct db_rbt_ctx); + + struct rb_node *n; + bool found = false; + struct db_rbt_node *r = NULL; + TDB_DATA search_key, search_val; + uint8_t *result; + n = ctx->tree.rb_node; while (n != NULL) { - struct db_rbt_node *r; - TDB_DATA search_key, search_val; int res; - r = (struct db_rbt_node *) - ((char *)n - offsetof(struct db_rbt_node, rb_node)); + r = db_rbt2node(n); db_rbt_parse_node(r, &search_key, &search_val); - res = memcmp(key.dptr, search_key.dptr, - MIN(key.dsize, search_key.dsize)); + res = db_rbt_compare(key, search_key); - if ((res < 0) - || ((res == 0) && (key.dsize < search_key.dsize))) { + if (res == -1) { n = n->rb_left; } - else if ((res > 0) - || ((res == 0) && (key.dsize > search_key.dsize))) { + else if (res == 1) { n = n->rb_right; } else { - rec_priv->node = r; - result->key = search_key; - result->value = search_val; - return result; + found = true; + break; } } - result->key.dsize = key.dsize; - result->key.dptr = (uint8_t *)talloc_memdup( - result, key.dptr, key.dsize); - - if (result->key.dptr == NULL) { - TALLOC_FREE(result); - return NULL; + if (!found) { + *data = tdb_null; + return 0; } - rec_priv->node = NULL; - result->value.dsize = 0; - result->value.dptr = NULL; - return result; -} - -static int db_rbt_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, - TDB_DATA key, TDB_DATA *data) -{ - struct db_record *rec; - - if (!(rec = db->fetch_locked(db, mem_ctx, key))) { + result = (uint8 *)talloc_memdup(mem_ctx, search_val.dptr, + search_val.dsize); + if (result == NULL) { return -1; } - data->dsize = rec->value.dsize; - data->dptr = (uint8 *)talloc_memdup(mem_ctx, rec->value.dptr, - rec->value.dsize); - TALLOC_FREE(rec); + data->dptr = result; + data->dsize = search_val.dsize; return 0; } @@ -275,6 +340,9 @@ static int db_rbt_traverse(struct db_context *db, void *private_data), void *private_data) { + /* + * Nobody uses this so far, and unused code is broken code :-) + */ return -1; } -- cgit From 1ee6d3e1ee56554d83437a8c79cb169a26732154 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 13 Jan 2008 01:40:05 +0100 Subject: Introduce a libnet_conf context created by libnet_conf_open(). The libnet_conf_ctx stores the information necessary to interoperate with the configuration. It is created by calling libnet_conf_open() and destroyed by calling libnet_conf_close(). The context is passed to all the libnet_conf functions. It currently stores the token to access the registry. Later, it could store more data, e.g. the server to connect to, credentials, and so on. For support of other backends than registry or support of remote configuration, only the open function will have to be changed. In net_conf, the calls to the actual net_conf functions is wrapped into a function that calls libnet_conf_open()/_close(). Thus an individual variant of net_conf_runfunction2() and functable2 is used to cope with functions being called by the wrapper with the additional libnet_conf_ctx argument. Michael (This used to be commit c2a9346faa26e79af5948197a1b322e545f0ed09) --- source3/lib/netapi/serverinfo.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/serverinfo.c b/source3/lib/netapi/serverinfo.c index 0e356e0ee7..67680ba55a 100644 --- a/source3/lib/netapi/serverinfo.c +++ b/source3/lib/netapi/serverinfo.c @@ -149,6 +149,10 @@ static WERROR NetServerSetInfoLocal_1005(struct libnetapi_ctx *ctx, uint8_t *buffer, uint32_t *parm_error) { + WERROR werr; + struct libnet_conf_ctx *conf_ctx; + TALLOC_CTX *mem_ctx; + struct srvsvc_NetSrvInfo1005 *info1005; if (!buffer) { @@ -167,8 +171,20 @@ static WERROR NetServerSetInfoLocal_1005(struct libnetapi_ctx *ctx, return WERR_NOT_SUPPORTED; } - return libnet_conf_set_global_parameter("server string", + mem_ctx = talloc_stackframe(); + werr = libnet_conf_open(mem_ctx, &conf_ctx); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + werr = libnet_conf_set_global_parameter(conf_ctx, + "server string", info1005->comment); + +done: + libnet_conf_close(conf_ctx); + TALLOC_FREE(mem_ctx); + return werr; } static WERROR NetServerSetInfoLocal(struct libnetapi_ctx *ctx, -- cgit From 5b6520044b7026baf1cff554b400f7ff1f024d77 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 9 Jan 2008 23:00:48 +0100 Subject: Fix the max_dead_record calculations (This used to be commit 4aaf4e7e73a5c7fa97ef730fbff5c7cb12df2d6c) --- source3/lib/tdb/common/open.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/tdb/common/open.c b/source3/lib/tdb/common/open.c index 6bd8fda2bf..94140a4baa 100644 --- a/source3/lib/tdb/common/open.c +++ b/source3/lib/tdb/common/open.c @@ -179,9 +179,7 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, tdb->page_size = 0x2000; } - if (open_flags & TDB_VOLATILE) { - tdb->max_dead_records = 5; - } + tdb->max_dead_records = (open_flags & TDB_VOLATILE) ? 5 : 0; if ((open_flags & O_ACCMODE) == O_WRONLY) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't open tdb %s write-only\n", @@ -288,7 +286,6 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, tdb->map_size = st.st_size; tdb->device = st.st_dev; tdb->inode = st.st_ino; - tdb->max_dead_records = 0; tdb_mmap(tdb); if (locked) { if (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK, 0, 1) == -1) { -- cgit From a1902700c45935f0a1071100810e91142ceb273e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 Jan 2008 15:38:43 +1100 Subject: merged tdb fix from ctdb tree (This used to be commit c91e9c785b5bf4b0c479edf8eb33da22bf615387) --- source3/lib/tdb/common/tdb.c | 47 ++++++++++++++++++++++ source3/lib/tdb/common/transaction.c | 75 ++++++++++++++++++++++++++++++++++++ source3/lib/tdb/include/tdb.h | 1 + 3 files changed, 123 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/tdb/common/tdb.c b/source3/lib/tdb/common/tdb.c index bf3abb71ac..fd4e1cc8af 100644 --- a/source3/lib/tdb/common/tdb.c +++ b/source3/lib/tdb/common/tdb.c @@ -715,6 +715,11 @@ int tdb_wipe_all(struct tdb_context *tdb) goto failed; } + if (tdb_ofs_write(tdb, TDB_RECOVERY_HEAD, &offset) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write recovery head\n")); + goto failed; + } + /* add all the rest of the file to the freelist */ data_len = (tdb->map_size - TDB_DATA_START(tdb->header.hash_size)) - sizeof(struct list_struct); if (data_len > 0) { @@ -738,3 +743,45 @@ failed: tdb_unlockall(tdb); return -1; } + + +/* + validate the integrity of all tdb hash chains. Useful when debugging + */ +int tdb_validate(struct tdb_context *tdb) +{ + int h; + for (h=-1;h<(int)tdb->header.hash_size;h++) { + tdb_off_t rec_ptr; + uint32_t count = 0; + if (tdb_ofs_read(tdb, TDB_HASH_TOP(h), &rec_ptr) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_validate: failed ofs_read at top of hash %d\n", h)); + return -1; + } + while (rec_ptr) { + struct list_struct r; + tdb_off_t size; + + if (tdb_rec_read(tdb, rec_ptr, &r) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_validate: failed rec_read h=%d rec_ptr=%u count=%u\n", + h, rec_ptr, count)); + return -1; + } + if (tdb_ofs_read(tdb, rec_ptr + sizeof(r) + r.rec_len - sizeof(tdb_off_t), &size) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_validate: failed ofs_read h=%d rec_ptr=%u count=%u\n", + h, rec_ptr, count)); + return -1; + } + if (size != r.rec_len + sizeof(r)) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_validate: failed size check size=%u h=%d rec_ptr=%u count=%u\n", + size, h, rec_ptr, count)); + return -1; + } + rec_ptr = r.next; + count++; + } + } + return 0; +} + + diff --git a/source3/lib/tdb/common/transaction.c b/source3/lib/tdb/common/transaction.c index 2da09face0..0ecfb9b7ff 100644 --- a/source3/lib/tdb/common/transaction.c +++ b/source3/lib/tdb/common/transaction.c @@ -87,6 +87,7 @@ */ + /* hold the context of any current transaction */ @@ -280,6 +281,63 @@ fail: return -1; } + +/* + write while in a transaction - this varient never expands the transaction blocks, it only + updates existing blocks. This means it cannot change the recovery size +*/ +static int transaction_write_existing(struct tdb_context *tdb, tdb_off_t off, + const void *buf, tdb_len_t len) +{ + uint32_t blk; + + /* break it up into block sized chunks */ + while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { + tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); + if (transaction_write_existing(tdb, off, buf, len2) != 0) { + return -1; + } + len -= len2; + off += len2; + if (buf != NULL) { + buf = (const void *)(len2 + (const char *)buf); + } + } + + if (len == 0) { + return 0; + } + + blk = off / tdb->transaction->block_size; + off = off % tdb->transaction->block_size; + + if (tdb->transaction->num_blocks <= blk || + tdb->transaction->blocks[blk] == NULL) { + return 0; + } + + /* overwrite part of an existing block */ + if (buf == NULL) { + memset(tdb->transaction->blocks[blk] + off, 0, len); + } else { + memcpy(tdb->transaction->blocks[blk] + off, buf, len); + } + if (blk == tdb->transaction->num_blocks-1) { + if (len + off > tdb->transaction->last_block_size) { + tdb->transaction->last_block_size = len + off; + } + } + + return 0; + +fail: + TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: failed at off=%d len=%d\n", + (blk*tdb->transaction->block_size) + off, len)); + tdb->transaction->transaction_error = 1; + return -1; +} + + /* accelerated hash chain head search, using the cached hash heads */ @@ -629,6 +687,10 @@ static int tdb_recovery_allocate(struct tdb_context *tdb, TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to write recovery head\n")); return -1; } + if (transaction_write_existing(tdb, TDB_RECOVERY_HEAD, &recovery_head, sizeof(tdb_off_t)) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to write recovery head\n")); + return -1; + } return 0; } @@ -726,6 +788,12 @@ static int transaction_setup_recovery(struct tdb_context *tdb, tdb->ecode = TDB_ERR_IO; return -1; } + if (transaction_write_existing(tdb, recovery_offset, data, sizeof(*rec) + recovery_size) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write secondary recovery data\n")); + free(data); + tdb->ecode = TDB_ERR_IO; + return -1; + } /* as we don't have ordered writes, we have to sync the recovery data before we update the magic to indicate that the recovery @@ -747,6 +815,11 @@ static int transaction_setup_recovery(struct tdb_context *tdb, tdb->ecode = TDB_ERR_IO; return -1; } + if (transaction_write_existing(tdb, *magic_offset, &magic, sizeof(magic)) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write secondary recovery magic\n")); + tdb->ecode = TDB_ERR_IO; + return -1; + } /* ensure the recovery magic marker is on disk */ if (transaction_sync(tdb, *magic_offset, sizeof(magic)) == -1) { @@ -778,6 +851,7 @@ int tdb_transaction_commit(struct tdb_context *tdb) return -1; } + if (tdb->transaction->nesting != 0) { tdb->transaction->nesting--; return 0; @@ -916,6 +990,7 @@ int tdb_transaction_commit(struct tdb_context *tdb) /* use a transaction cancel to free memory and remove the transaction locks */ tdb_transaction_cancel(tdb); + return 0; } diff --git a/source3/lib/tdb/include/tdb.h b/source3/lib/tdb/include/tdb.h index 0008085de5..daa2d43135 100644 --- a/source3/lib/tdb/include/tdb.h +++ b/source3/lib/tdb/include/tdb.h @@ -157,6 +157,7 @@ int tdb_printfreelist(struct tdb_context *tdb); int tdb_validate_freelist(struct tdb_context *tdb, int *pnum_entries); int tdb_wipe_all(struct tdb_context *tdb); int tdb_freelist_size(struct tdb_context *tdb); +int tdb_validate(struct tdb_context *tdb); extern TDB_DATA tdb_null; -- cgit From 63b1c765de439b295c73430be14f8656873bfad7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 Jan 2008 16:26:52 +1100 Subject: samba3 already has tdb_validate() (This used to be commit 9f002eeff9bcf33a00e5641cb14338e866a17afe) --- source3/lib/tdb/common/tdb.c | 42 ------------------------------------------ source3/lib/tdb/include/tdb.h | 1 - 2 files changed, 43 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/tdb/common/tdb.c b/source3/lib/tdb/common/tdb.c index fd4e1cc8af..ea5d9ccc60 100644 --- a/source3/lib/tdb/common/tdb.c +++ b/source3/lib/tdb/common/tdb.c @@ -743,45 +743,3 @@ failed: tdb_unlockall(tdb); return -1; } - - -/* - validate the integrity of all tdb hash chains. Useful when debugging - */ -int tdb_validate(struct tdb_context *tdb) -{ - int h; - for (h=-1;h<(int)tdb->header.hash_size;h++) { - tdb_off_t rec_ptr; - uint32_t count = 0; - if (tdb_ofs_read(tdb, TDB_HASH_TOP(h), &rec_ptr) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_validate: failed ofs_read at top of hash %d\n", h)); - return -1; - } - while (rec_ptr) { - struct list_struct r; - tdb_off_t size; - - if (tdb_rec_read(tdb, rec_ptr, &r) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_validate: failed rec_read h=%d rec_ptr=%u count=%u\n", - h, rec_ptr, count)); - return -1; - } - if (tdb_ofs_read(tdb, rec_ptr + sizeof(r) + r.rec_len - sizeof(tdb_off_t), &size) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_validate: failed ofs_read h=%d rec_ptr=%u count=%u\n", - h, rec_ptr, count)); - return -1; - } - if (size != r.rec_len + sizeof(r)) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_validate: failed size check size=%u h=%d rec_ptr=%u count=%u\n", - size, h, rec_ptr, count)); - return -1; - } - rec_ptr = r.next; - count++; - } - } - return 0; -} - - diff --git a/source3/lib/tdb/include/tdb.h b/source3/lib/tdb/include/tdb.h index daa2d43135..0008085de5 100644 --- a/source3/lib/tdb/include/tdb.h +++ b/source3/lib/tdb/include/tdb.h @@ -157,7 +157,6 @@ int tdb_printfreelist(struct tdb_context *tdb); int tdb_validate_freelist(struct tdb_context *tdb, int *pnum_entries); int tdb_wipe_all(struct tdb_context *tdb); int tdb_freelist_size(struct tdb_context *tdb); -int tdb_validate(struct tdb_context *tdb); extern TDB_DATA tdb_null; -- cgit From 19e4e99bfb02b8fa722883b04237ad714d402cb3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 14 Jan 2008 11:06:46 -0800 Subject: From Alexander Bokovoy names is a 'const char **names' here, passed from upper level. Passing 'names' as a talloc context will break things as 'names' is usually likely is a local variable, not a talloc'd. And we want to have array elements on a context of the array anyway. Jeremy. (This used to be commit 22a4129fabf70e01cc638c2f7347c28201838830) --- source3/lib/winbind_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/winbind_util.c b/source3/lib/winbind_util.c index 3cf068a6e0..14356b09cf 100644 --- a/source3/lib/winbind_util.c +++ b/source3/lib/winbind_util.c @@ -201,7 +201,7 @@ bool winbind_lookup_rids(TALLOC_CTX *mem_ctx, *types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_rids); for(i=0; i Date: Tue, 15 Jan 2008 17:20:50 -0800 Subject: Port from ctdb: minor fix to transaction_write_existing: tridge. Jeremy. (This used to be commit 874425c8f680fb2f737b46a3177b239e69302af5) --- source3/lib/tdb/common/transaction.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/tdb/common/transaction.c b/source3/lib/tdb/common/transaction.c index 0ecfb9b7ff..ea0e3a93f3 100644 --- a/source3/lib/tdb/common/transaction.c +++ b/source3/lib/tdb/common/transaction.c @@ -316,25 +316,15 @@ static int transaction_write_existing(struct tdb_context *tdb, tdb_off_t off, return 0; } - /* overwrite part of an existing block */ - if (buf == NULL) { - memset(tdb->transaction->blocks[blk] + off, 0, len); - } else { - memcpy(tdb->transaction->blocks[blk] + off, buf, len); - } - if (blk == tdb->transaction->num_blocks-1) { - if (len + off > tdb->transaction->last_block_size) { - tdb->transaction->last_block_size = len + off; - } + if (blk == tdb->transaction->num_blocks-1 && + off + len > tdb->transaction->last_block_size) { + len = tdb->transaction->last_block_size - off; } - return 0; + /* overwrite part of an existing block */ + memcpy(tdb->transaction->blocks[blk] + off, buf, len); -fail: - TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: failed at off=%d len=%d\n", - (blk*tdb->transaction->block_size) + off, len)); - tdb->transaction->transaction_error = 1; - return -1; + return 0; } -- cgit From 68694369fc96354452979b07425f3f48c4f73bbe Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Wed, 16 Jan 2008 12:09:48 +0300 Subject: Merge CTDB-related fixes from samba-ctdb 3.0 branch (http://samba.org/~tridge/3_0-ctdb) Signed-off-by: Alexander Bokovoy (This used to be commit 0c8e23afbbb2d081fc23908bafcad04650bfacea) --- source3/lib/conn_tdb.c | 2 +- source3/lib/ctdbd_conn.c | 36 +++++++++ source3/lib/dbwrap.c | 12 ++- source3/lib/dbwrap_ctdb.c | 178 ++++++++++++++++++++++++++----------------- source3/lib/dbwrap_file.c | 5 +- source3/lib/dbwrap_tdb.c | 21 ++--- source3/lib/dbwrap_util.c | 90 ++++++++++++++++++++++ source3/lib/messages_ctdbd.c | 4 + source3/lib/util.c | 13 ++++ 9 files changed, 276 insertions(+), 85 deletions(-) create mode 100644 source3/lib/dbwrap_util.c (limited to 'source3/lib') diff --git a/source3/lib/conn_tdb.c b/source3/lib/conn_tdb.c index dd0a354a85..22d85c873d 100644 --- a/source3/lib/conn_tdb.c +++ b/source3/lib/conn_tdb.c @@ -34,7 +34,7 @@ static struct db_context *connections_db_ctx(bool rw) } else { db_ctx = db_open(NULL, lock_path("connections.tdb"), 0, - TDB_DEFAULT, O_RDONLY, 0); + TDB_CLEAR_IF_FIRST|TDB_DEFAULT, O_RDONLY, 0); } return db_ctx; diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c index 899bbcfcce..18e9879601 100644 --- a/source3/lib/ctdbd_conn.c +++ b/source3/lib/ctdbd_conn.c @@ -1203,6 +1203,42 @@ NTSTATUS ctdbd_register_reconfigure(struct ctdbd_connection *conn) return register_with_ctdbd(conn, CTDB_SRVID_RECONFIGURE); } +/* + persstent store. Used when we update a record in a persistent database + */ +NTSTATUS ctdbd_persistent_store(struct ctdbd_connection *conn, uint32_t db_id, TDB_DATA key, TDB_DATA data) +{ + int cstatus=0; + struct ctdb_rec_data *rec; + TDB_DATA recdata; + size_t length; + NTSTATUS status; + + length = offsetof(struct ctdb_rec_data, data) + key.dsize + data.dsize; + + rec = (struct ctdb_rec_data *)talloc_size(conn, length); + NT_STATUS_HAVE_NO_MEMORY(rec); + + rec->length = length; + rec->reqid = db_id; + rec->keylen = key.dsize; + rec->datalen= data.dsize; + memcpy(&rec->data[0], key.dptr, key.dsize); + memcpy(&rec->data[key.dsize], data.dptr, data.dsize); + + recdata.dptr = (uint8_t *)rec; + recdata.dsize = length; + + status = ctdbd_control(conn, CTDB_CURRENT_NODE, + CTDB_CONTROL_PERSISTENT_STORE, + 0, recdata, NULL, NULL, &cstatus); + if (cstatus != 0) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + return status; +} + + #else NTSTATUS ctdbd_init_connection(TALLOC_CTX *mem_ctx, diff --git a/source3/lib/dbwrap.c b/source3/lib/dbwrap.c index 4e16d18682..001424a6c0 100644 --- a/source3/lib/dbwrap.c +++ b/source3/lib/dbwrap.c @@ -20,7 +20,9 @@ */ #include "includes.h" - +#ifdef CLUSTER_SUPPORT +#include "ctdb_private.h" +#endif /* * Fall back using fetch_locked if no genuine fetch operation is provided */ @@ -46,10 +48,16 @@ struct db_context *db_open(TALLOC_CTX *mem_ctx, int open_flags, mode_t mode) { struct db_context *result = NULL; +#ifdef CLUSTER_SUPPORT + const char *sockname = lp_ctdbd_socket(); +#endif #ifdef CLUSTER_SUPPORT + if(!sockname || !*sockname) { + sockname = CTDB_PATH; + } - if (lp_clustering()) { + if (lp_clustering() && socket_exist(sockname)) { const char *partname; /* ctdb only wants the file part of the name */ partname = strrchr(name, '/'); diff --git a/source3/lib/dbwrap_ctdb.c b/source3/lib/dbwrap_ctdb.c index 90d0b260c5..f497f871d2 100644 --- a/source3/lib/dbwrap_ctdb.c +++ b/source3/lib/dbwrap_ctdb.c @@ -18,16 +18,14 @@ */ #include "includes.h" - #ifdef CLUSTER_SUPPORT - #include "ctdb.h" #include "ctdb_private.h" +#include "ctdbd_conn.h" struct db_ctdb_ctx { struct tdb_wrap *wtdb; uint32 db_id; - struct ctdbd_connection *conn; }; struct db_ctdb_rec { @@ -35,8 +33,6 @@ struct db_ctdb_rec { struct ctdb_ltdb_header header; }; -static struct ctdbd_connection *db_ctdbd_conn(struct db_ctdb_ctx *ctx); - static NTSTATUS db_ctdb_store(struct db_record *rec, TDB_DATA data, int flag) { struct db_ctdb_rec *crec = talloc_get_type_abort( @@ -60,6 +56,42 @@ static NTSTATUS db_ctdb_store(struct db_record *rec, TDB_DATA data, int flag) return (ret == 0) ? NT_STATUS_OK : NT_STATUS_INTERNAL_DB_CORRUPTION; } + +/* for persistent databases the store is a bit different. We have to + ask the ctdb daemon to push the record to all nodes after the + store */ +static NTSTATUS db_ctdb_store_persistent(struct db_record *rec, TDB_DATA data, int flag) +{ + struct db_ctdb_rec *crec = talloc_get_type_abort( + rec->private_data, struct db_ctdb_rec); + TDB_DATA cdata; + int ret; + NTSTATUS status; + + cdata.dsize = sizeof(crec->header) + data.dsize; + + if (!(cdata.dptr = SMB_MALLOC_ARRAY(uint8, cdata.dsize))) { + return NT_STATUS_NO_MEMORY; + } + + crec->header.rsn++; + + memcpy(cdata.dptr, &crec->header, sizeof(crec->header)); + memcpy(cdata.dptr + sizeof(crec->header), data.dptr, data.dsize); + + ret = tdb_store(crec->ctdb_ctx->wtdb->tdb, rec->key, cdata, TDB_REPLACE); + status = (ret == 0) ? NT_STATUS_OK : NT_STATUS_INTERNAL_DB_CORRUPTION; + + /* now tell ctdbd to update this record on all other nodes */ + if (NT_STATUS_IS_OK(status)) { + status = ctdbd_persistent_store(messaging_ctdbd_connection(), crec->ctdb_ctx->db_id, rec->key, cdata); + } + + SAFE_FREE(cdata.dptr); + + return status; +} + static NTSTATUS db_ctdb_delete(struct db_record *rec) { struct db_ctdb_rec *crec = talloc_get_type_abort( @@ -110,6 +142,7 @@ static struct db_record *db_ctdb_fetch_locked(struct db_context *db, struct db_ctdb_rec *crec; NTSTATUS status; TDB_DATA ctdb_data; + int migrate_attempts = 0; if (!(result = talloc(mem_ctx, struct db_record))) { DEBUG(0, ("talloc failed\n")); @@ -153,7 +186,11 @@ again: return NULL; } - result->store = db_ctdb_store; + if (db->persistent) { + result->store = db_ctdb_store_persistent; + } else { + result->store = db_ctdb_store; + } result->delete_rec = db_ctdb_delete; talloc_set_destructor(result, db_ctdb_record_destr); @@ -175,12 +212,14 @@ again: tdb_chainunlock(ctx->wtdb->tdb, key); talloc_set_destructor(result, NULL); + migrate_attempts += 1; + DEBUG(10, ("ctdb_data.dptr = %p, dmaster = %u (%u)\n", ctdb_data.dptr, ctdb_data.dptr ? ((struct ctdb_ltdb_header *)ctdb_data.dptr)->dmaster : -1, get_my_vnn())); - status = ctdbd_migrate(db_ctdbd_conn(ctx), ctx->db_id, key); + status = ctdbd_migrate(messaging_ctdbd_connection(),ctx->db_id, key); if (!NT_STATUS_IS_OK(status)) { DEBUG(5, ("ctdb_migrate failed: %s\n", nt_errstr(status))); @@ -191,6 +230,11 @@ again: goto again; } + if (migrate_attempts > 10) { + DEBUG(0, ("db_ctdb_fetch_locked needed %d attempts\n", + migrate_attempts)); + } + memcpy(&crec->header, ctdb_data.dptr, sizeof(crec->header)); result->value.dsize = ctdb_data.dsize - sizeof(crec->header); @@ -226,10 +270,12 @@ static int db_ctdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, /* * See if we have a valid record and we are the dmaster. If so, we can * take the shortcut and just return it. + * we bypass the dmaster check for persistent databases */ if ((ctdb_data.dptr != NULL) && (ctdb_data.dsize >= sizeof(struct ctdb_ltdb_header)) && - ((struct ctdb_ltdb_header *)ctdb_data.dptr)->dmaster == get_my_vnn()) { + (db->persistent || + ((struct ctdb_ltdb_header *)ctdb_data.dptr)->dmaster == get_my_vnn())) { /* we are the dmaster - avoid the ctdb protocol op */ data->dsize = ctdb_data.dsize - sizeof(struct ctdb_ltdb_header); @@ -254,8 +300,7 @@ static int db_ctdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, SAFE_FREE(ctdb_data.dptr); /* we weren't able to get it locally - ask ctdb to fetch it for us */ - status = ctdbd_fetch(db_ctdbd_conn(ctx), ctx->db_id, key, mem_ctx, - data); + status = ctdbd_fetch(messaging_ctdbd_connection(),ctx->db_id, key, mem_ctx, data); if (!NT_STATUS_IS_OK(status)) { DEBUG(5, ("ctdbd_fetch failed: %s\n", nt_errstr(status))); return -1; @@ -283,6 +328,22 @@ static void traverse_callback(TDB_DATA key, TDB_DATA data, void *private_data) talloc_free(tmp_ctx); } +static int traverse_persistent_callback(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, + void *private_data) +{ + struct traverse_state *state = (struct traverse_state *)private_data; + struct db_record *rec; + TALLOC_CTX *tmp_ctx = talloc_new(state->db); + int ret = 0; + /* we have to give them a locked record to prevent races */ + rec = db_ctdb_fetch_locked(state->db, tmp_ctx, kbuf); + if (rec && rec->value.dsize > 0) { + ret = state->fn(rec, state->private_data); + } + talloc_free(tmp_ctx); + return ret; +} + static int db_ctdb_traverse(struct db_context *db, int (*fn)(struct db_record *rec, void *private_data), @@ -296,6 +357,13 @@ static int db_ctdb_traverse(struct db_context *db, state.fn = fn; state.private_data = private_data; + if (db->persistent) { + /* for persistent databases we don't need to do a ctdb traverse, + we can do a faster local traverse */ + return tdb_traverse(ctx->wtdb->tdb, traverse_persistent_callback, &state); + } + + ctdbd_traverse(ctx->db_id, traverse_callback, &state); return 0; } @@ -322,6 +390,27 @@ static void traverse_read_callback(TDB_DATA key, TDB_DATA data, void *private_da state->fn(&rec, state->private_data); } +static int traverse_persistent_callback_read(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, + void *private_data) +{ + struct traverse_state *state = (struct traverse_state *)private_data; + struct db_record rec; + rec.key = kbuf; + rec.value = dbuf; + rec.store = db_ctdb_store_deny; + rec.delete_rec = db_ctdb_delete_deny; + rec.private_data = state->db; + + if (rec.value.dsize <= sizeof(struct ctdb_ltdb_header)) { + /* a deleted record */ + return 0; + } + rec.value.dsize -= sizeof(struct ctdb_ltdb_header); + rec.value.dptr += sizeof(struct ctdb_ltdb_header); + + return state->fn(&rec, state->private_data); +} + static int db_ctdb_traverse_read(struct db_context *db, int (*fn)(struct db_record *rec, void *private_data), @@ -335,6 +424,12 @@ static int db_ctdb_traverse_read(struct db_context *db, state.fn = fn; state.private_data = private_data; + if (db->persistent) { + /* for persistent databases we don't need to do a ctdb traverse, + we can do a faster local traverse */ + return tdb_traverse_read(ctx->wtdb->tdb, traverse_persistent_callback_read, &state); + } + ctdbd_traverse(ctx->db_id, traverse_read_callback, &state); return 0; } @@ -346,41 +441,6 @@ static int db_ctdb_get_seqnum(struct db_context *db) return tdb_get_seqnum(ctx->wtdb->tdb); } -/* - * Get the ctdbd connection for a database. If possible, re-use the messaging - * ctdbd connection - */ -static struct ctdbd_connection *db_ctdbd_conn(struct db_ctdb_ctx *ctx) -{ - struct ctdbd_connection *result; - - result = messaging_ctdbd_connection(); - - if (result != NULL) { - - if (ctx->conn == NULL) { - /* - * Someone has initialized messaging since we - * initialized our own connection, we don't need it - * anymore. - */ - TALLOC_FREE(ctx->conn); - } - - return result; - } - - if (ctx->conn == NULL) { - NTSTATUS status; - status = ctdbd_init_connection(ctx, &ctx->conn); - if (!NT_STATUS_IS_OK(status)) { - return NULL; - } - set_my_vnn(ctdbd_vnn(ctx->conn)); - } - - return ctx->conn; -} struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx, const char *name, @@ -390,7 +450,6 @@ struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx, struct db_context *result; struct db_ctdb_ctx *db_ctdb; char *db_path; - NTSTATUS status; if (!lp_clustering()) { DEBUG(10, ("Clustering disabled -- no ctdb\n")); @@ -409,20 +468,15 @@ struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx, return NULL; } - db_ctdb->conn = NULL; - - status = ctdbd_db_attach(db_ctdbd_conn(db_ctdb), name, - &db_ctdb->db_id, tdb_flags); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("ctdbd_db_attach failed for %s: %s\n", name, - nt_errstr(status))); + if (!NT_STATUS_IS_OK(ctdbd_db_attach(messaging_ctdbd_connection(),name, &db_ctdb->db_id, tdb_flags))) { + DEBUG(0, ("ctdbd_db_attach failed for %s\n", name)); TALLOC_FREE(result); return NULL; } - db_path = ctdbd_dbpath(db_ctdbd_conn(db_ctdb), db_ctdb, - db_ctdb->db_id); + db_path = ctdbd_dbpath(messaging_ctdbd_connection(), db_ctdb, db_ctdb->db_id); + + result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0); /* only pass through specific flags */ tdb_flags &= TDB_SEQNUM; @@ -447,16 +501,4 @@ struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx, return result; } - -#else - -struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx, - const char *name, - int hash_size, int tdb_flags, - int open_flags, mode_t mode) -{ - DEBUG(0, ("no clustering compiled in\n")); - return NULL; -} - #endif diff --git a/source3/lib/dbwrap_file.c b/source3/lib/dbwrap_file.c index 5b41f5941b..e3779de1e4 100644 --- a/source3/lib/dbwrap_file.c +++ b/source3/lib/dbwrap_file.c @@ -17,10 +17,6 @@ along with this program. If not, see . */ -/* - * Be aware that this is just sample code that has not seen too much testing - */ - #include "includes.h" struct db_file_ctx { @@ -367,6 +363,7 @@ struct db_context *db_open_file(TALLOC_CTX *mem_ctx, result->fetch_locked = db_file_fetch_locked; result->traverse = db_file_traverse; result->traverse_read = db_file_traverse; + result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0); ctx->locked_record = NULL; if (!(ctx->dirname = talloc_strdup(ctx, name))) { diff --git a/source3/lib/dbwrap_tdb.c b/source3/lib/dbwrap_tdb.c index 710e45de6b..e87ceb428f 100644 --- a/source3/lib/dbwrap_tdb.c +++ b/source3/lib/dbwrap_tdb.c @@ -31,6 +31,11 @@ static int db_tdb_record_destr(struct db_record* data) struct db_tdb_ctx *ctx = talloc_get_type_abort(data->private_data, struct db_tdb_ctx); + /* This hex_encode() call allocates memory on data context. By way how current + __talloc_free() code works, it is OK to allocate in the destructor as + the children of data will be freed after call to the destructor and this + new 'child' will be caught and freed correctly. + */ DEBUG(10, (DEBUGLEVEL > 10 ? "Unlocking key %s\n" : "Unlocking key %.20s\n", hex_encode(data, (unsigned char *)data->key.dptr, @@ -88,8 +93,9 @@ static struct db_record *db_tdb_fetch_locked(struct db_context *db, struct tdb_fetch_locked_state state; int res; - if (DEBUGLEVEL >= 10) { - char *keystr = hex_encode(NULL, key.dptr, key.dsize); + /* Do not accidently allocate/deallocate w/o need when debug level is lower than needed */ + if(DEBUGLEVEL >= 10) { + char *keystr = hex_encode(NULL, (unsigned char*)key.dptr, key.dsize); DEBUG(10, (DEBUGLEVEL > 10 ? "Locking key %s\n" : "Locking key %.20s\n", keystr)); @@ -191,15 +197,9 @@ static NTSTATUS db_tdb_delete(struct db_record *rec) { struct db_tdb_ctx *ctx = talloc_get_type_abort(rec->private_data, struct db_tdb_ctx); - int res; - - res = tdb_delete(ctx->wtdb->tdb, rec->key); - if (res == 0) { - return NT_STATUS_OK; - } - - return map_nt_error_from_tdb(tdb_error(ctx->wtdb->tdb)); + return (tdb_delete(ctx->wtdb->tdb, rec->key) == 0) ? + NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } struct db_tdb_traverse_ctx { @@ -318,6 +318,7 @@ struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx, result->traverse = db_tdb_traverse; result->traverse_read = db_tdb_traverse_read; result->get_seqnum = db_tdb_get_seqnum; + result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0); return result; fail: diff --git a/source3/lib/dbwrap_util.c b/source3/lib/dbwrap_util.c new file mode 100644 index 0000000000..002d572019 --- /dev/null +++ b/source3/lib/dbwrap_util.c @@ -0,0 +1,90 @@ +/* + Unix SMB/CIFS implementation. + Utility functions for the dbwrap API + Copyright (C) Volker Lendecke 2007 + + 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" + +int32_t dbwrap_fetch_int32(struct db_context *db, const char *keystr) +{ + TDB_DATA dbuf; + int32 ret; + + if (db->fetch(db, NULL, string_term_tdb_data(keystr), &dbuf) != 0) { + return -1; + } + + if ((dbuf.dptr == NULL) || (dbuf.dsize != sizeof(int32_t))) { + TALLOC_FREE(dbuf.dptr); + return -1; + } + + ret = IVAL(dbuf.dptr, 0); + TALLOC_FREE(dbuf.dptr); + return ret; +} + +int dbwrap_store_int32(struct db_context *db, const char *keystr, int32_t v) +{ + struct db_record *rec; + int32 v_store; + NTSTATUS status; + + rec = db->fetch_locked(db, NULL, string_term_tdb_data(keystr)); + if (rec == NULL) { + return -1; + } + + SIVAL(&v_store, 0, v); + + status = rec->store(rec, make_tdb_data((const uint8 *)&v_store, + sizeof(v_store)), + TDB_REPLACE); + TALLOC_FREE(rec); + return NT_STATUS_IS_OK(status) ? 0 : -1; +} + +uint32_t dbwrap_change_uint32_atomic(struct db_context *db, const char *keystr, + uint32_t *oldval, uint32_t change_val) +{ + struct db_record *rec; + uint32 val = -1; + TDB_DATA data; + + if (!(rec = db->fetch_locked(db, NULL, + string_term_tdb_data(keystr)))) { + return -1; + } + + if ((rec->value.dptr != NULL) + && (rec->value.dsize == sizeof(val))) { + val = IVAL(rec->value.dptr, 0); + } + + val += change_val; + + data.dsize = sizeof(val); + data.dptr = (uint8 *)&val; + + rec->store(rec, data, TDB_REPLACE); + + TALLOC_FREE(rec); + + return 0; +} + diff --git a/source3/lib/messages_ctdbd.c b/source3/lib/messages_ctdbd.c index 6e9b934a75..f1a02e6af9 100644 --- a/source3/lib/messages_ctdbd.c +++ b/source3/lib/messages_ctdbd.c @@ -22,6 +22,10 @@ #ifdef CLUSTER_SUPPORT #include "librpc/gen_ndr/messaging.h" +#include "ctdb.h" +#include "ctdb_private.h" +#include "ctdbd_conn.h" + struct messaging_ctdbd_context { struct ctdbd_connection *conn; diff --git a/source3/lib/util.c b/source3/lib/util.c index 0653fc9d3f..bc3eaa8d5e 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -505,6 +505,19 @@ bool file_exist(const char *fname,SMB_STRUCT_STAT *sbuf) return((S_ISREG(sbuf->st_mode)) || (S_ISFIFO(sbuf->st_mode))); } +/******************************************************************* + Check if a unix domain socket exists - call vfs_file_exist for samba files. +********************************************************************/ + +bool socket_exist(const char *fname) +{ + SMB_STRUCT_STAT st; + if (sys_stat(fname,&st) != 0) + return(False); + + return S_ISSOCK(st.st_mode); +} + /******************************************************************* Check a files mod time. ********************************************************************/ -- cgit From 7bfceba4bc49f5f5c8d2836dfd76e1ec15459631 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 16 Jan 2008 17:05:38 +0100 Subject: Use lp_config_backend_is_registry() instead of lp_include_registry_globals(). Michael (This used to be commit c5a7d421c512a6221b0300549d7b5de0368d252e) --- source3/lib/netapi/serverinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/serverinfo.c b/source3/lib/netapi/serverinfo.c index 67680ba55a..6cd074615b 100644 --- a/source3/lib/netapi/serverinfo.c +++ b/source3/lib/netapi/serverinfo.c @@ -167,7 +167,7 @@ static WERROR NetServerSetInfoLocal_1005(struct libnetapi_ctx *ctx, return WERR_INVALID_PARAM; } - if (!lp_include_registry_globals()) { + if (!lp_config_backend_is_registry()) { return WERR_NOT_SUPPORTED; } -- cgit From 8c41366a98ea96224adc2c108b940075431944fd Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 16 Jan 2008 17:31:44 +0100 Subject: Add "config backend" to the parameters forbidden in registry config. Make registry based configs more fool-proof. Michael (This used to be commit 2ea55c03b25eb5e98be3449e12004a7246319acd) --- source3/lib/util_reg.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/lib') diff --git a/source3/lib/util_reg.c b/source3/lib/util_reg.c index 956f0475a5..2d7d70c63f 100644 --- a/source3/lib/util_reg.c +++ b/source3/lib/util_reg.c @@ -130,6 +130,7 @@ bool registry_smbconf_valname_forbidden(const char *valname) "include", "lock directory", "lock dir", + "config backend", NULL }; const char **forbidden = NULL; -- cgit From b0950557f90129b5cd51faf74dbf5d58a8f4d6b9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 16 Jan 2008 20:25:57 +0100 Subject: Fix a missing prototype warning (This used to be commit 871cee04f26da97756804b38acfd366b6011dc9e) --- source3/lib/tdb/common/tdb_private.h | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/lib') diff --git a/source3/lib/tdb/common/tdb_private.h b/source3/lib/tdb/common/tdb_private.h index 63a6d04e72..dd69903015 100644 --- a/source3/lib/tdb/common/tdb_private.h +++ b/source3/lib/tdb/common/tdb_private.h @@ -178,6 +178,7 @@ struct tdb_context { int tdb_munmap(struct tdb_context *tdb); void tdb_mmap(struct tdb_context *tdb); int tdb_lock(struct tdb_context *tdb, int list, int ltype); +int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype); int tdb_unlock(struct tdb_context *tdb, int list, int ltype); int tdb_brlock(struct tdb_context *tdb, tdb_off_t offset, int rw_type, int lck_type, int probe, size_t len); int tdb_transaction_lock(struct tdb_context *tdb, int ltype); -- cgit From c308d76305d0a598ce03c516ff0c3b3a8875c89c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 16 Jan 2008 20:29:41 +0100 Subject: Fix some C++ warnings (This used to be commit 625241c4773ae5c80dd0cb0c07a86aff633c1ede) --- source3/lib/tdb/common/transaction.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/tdb/common/transaction.c b/source3/lib/tdb/common/transaction.c index ea0e3a93f3..c3e7a4e2c0 100644 --- a/source3/lib/tdb/common/transaction.c +++ b/source3/lib/tdb/common/transaction.c @@ -219,9 +219,12 @@ static int transaction_write(struct tdb_context *tdb, tdb_off_t off, uint8_t **new_blocks; /* expand the blocks array */ if (tdb->transaction->blocks == NULL) { - new_blocks = malloc((blk+1)*sizeof(uint8_t *)); + new_blocks = (uint8_t **)malloc( + (blk+1)*sizeof(uint8_t *)); } else { - new_blocks = realloc(tdb->transaction->blocks, (blk+1)*sizeof(uint8_t *)); + new_blocks = (uint8_t **)realloc( + tdb->transaction->blocks, + (blk+1)*sizeof(uint8_t *)); } if (new_blocks == NULL) { tdb->ecode = TDB_ERR_OOM; -- cgit From 7084854bd94c84250becc7e4e13035fde2d7a728 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 16 Jan 2008 21:04:52 +0100 Subject: Next try to fix the max dead record calculation (This used to be commit 4f95c58040f46f343f55f9a5db2655a5e3b62c00) --- source3/lib/tdb/common/open.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/tdb/common/open.c b/source3/lib/tdb/common/open.c index 94140a4baa..2a438971d4 100644 --- a/source3/lib/tdb/common/open.c +++ b/source3/lib/tdb/common/open.c @@ -179,7 +179,7 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, tdb->page_size = 0x2000; } - tdb->max_dead_records = (open_flags & TDB_VOLATILE) ? 5 : 0; + tdb->max_dead_records = (tdb_flags & TDB_VOLATILE) ? 5 : 0; if ((open_flags & O_ACCMODE) == O_WRONLY) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't open tdb %s write-only\n", -- cgit From 5b37e815b429f0a8c114e36892385d8b0d86ea6a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 16 Jan 2008 21:18:26 +0100 Subject: Don't try ftruncate when the tdb is opened read-only Tridge, Jeremy, please check! Thanks, Volker (This used to be commit e4f46d527411c54e8f26c05033b744c751810c32) --- source3/lib/tdb/common/open.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/lib') diff --git a/source3/lib/tdb/common/open.c b/source3/lib/tdb/common/open.c index 2a438971d4..b19e4cea29 100644 --- a/source3/lib/tdb/common/open.c +++ b/source3/lib/tdb/common/open.c @@ -227,6 +227,7 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, /* we need to zero database if we are the only one with it open */ if ((tdb_flags & TDB_CLEAR_IF_FIRST) && + (!tdb->read_only) && (locked = (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0, 1) == 0))) { open_flags |= O_CREAT; if (ftruncate(tdb->fd, 0) == -1) { -- cgit From bd8abea49fed09e131ab5162821b0ed05c1ab1b0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Jan 2008 13:21:46 -0800 Subject: Fix IPv6 bug #5204, which caused krb5 DNS lookups for a name '['. Jeremy. (This used to be commit f2aa921505e49f894bfed4e5e2f9fc01918b1bb0) --- source3/lib/util_sock.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 945506ea77..10428113ae 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -475,6 +475,29 @@ bool is_address_any(const struct sockaddr_storage *psa) return false; } +/**************************************************************************** + Get a port number in host byte order from a sockaddr_storage. +****************************************************************************/ + +uint16_t get_sockaddr_port(const struct sockaddr_storage *pss) +{ + uint16_t port = 0; + + if (pss->ss_family != AF_INET) { +#if defined(HAVE_IPV6) + /* IPv6 */ + const struct sockaddr_in6 *sa6 = + (const struct sockaddr_in6 *)pss; + port = ntohs(sa6->sin6_port); +#endif + } else { + const struct sockaddr_in *sa = + (const struct sockaddr_in *)pss; + port = ntohs(sa->sin_port); + } + return port; +} + /**************************************************************************** Print out an IPv4 or IPv6 address from a struct sockaddr_storage. ****************************************************************************/ @@ -518,7 +541,7 @@ char *print_canonical_sockaddr(TALLOC_CTX *ctx, char *dest = NULL; int ret; - ret = getnameinfo((const struct sockaddr *)pss, + ret = sys_getnameinfo((const struct sockaddr *)pss, sizeof(struct sockaddr_storage), addr, sizeof(addr), NULL, 0, @@ -1847,7 +1870,7 @@ const char *get_peer_name(int fd, bool force_lookup) } /* Look up the remote host name. */ - ret = getnameinfo((struct sockaddr *)&ss, + ret = sys_getnameinfo((struct sockaddr *)&ss, length, name_buf, sizeof(name_buf), -- cgit From d1abd4d866b59fa67605fc469d6406a981455fbe Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 17 Jan 2008 10:39:15 +0100 Subject: Use new pidl-generated netlogon client calls in NetApi GetDcName(). Guenther (This used to be commit 733e07a06ce3c903ff5837df6a5119f6d6e3eccb) --- source3/lib/netapi/examples/getdc/getdc.c | 4 +-- source3/lib/netapi/getdc.c | 42 +++++-------------------------- 2 files changed, 8 insertions(+), 38 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/examples/getdc/getdc.c b/source3/lib/netapi/examples/getdc/getdc.c index cdd4d0b3b4..272ba1088e 100644 --- a/source3/lib/netapi/examples/getdc/getdc.c +++ b/source3/lib/netapi/examples/getdc/getdc.c @@ -29,7 +29,7 @@ int main(int argc, char **argv) { NET_API_STATUS status; struct libnetapi_ctx *ctx = NULL; - uint8_t *buffer; + uint8_t *buffer = NULL; if (argc < 3) { printf("usage: getdc \n"); @@ -50,7 +50,7 @@ int main(int argc, char **argv) } else { printf("%s\n", (char *)buffer); } - + NetApiBufferFree(buffer); libnetapi_free(ctx); return status; diff --git a/source3/lib/netapi/getdc.c b/source3/lib/netapi/getdc.c index 85a0ae52ef..484af04a55 100644 --- a/source3/lib/netapi/getdc.c +++ b/source3/lib/netapi/getdc.c @@ -22,22 +22,6 @@ #include "lib/netapi/netapi.h" #include "libnet/libnet.h" -#if 0 -#include "librpc/gen_ndr/cli_netlogon.h" -#endif - -NTSTATUS rpccli_netr_GetDcName(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - const char *logon_server, - const char *domainname, - const char **dcname); -NTSTATUS rpccli_netr_GetAnyDCName(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - const char *logon_server, - const char *domainname, - const char **dcname, - WERROR *werror); - static WERROR NetGetDCNameLocal(struct libnetapi_ctx *ctx, const char *server_name, const char *domain_name, @@ -76,17 +60,11 @@ static WERROR NetGetDCNameRemote(struct libnetapi_ctx *ctx, goto done; }; -#if 0 - werr = rpccli_netr_GetDcName(pipe_cli, ctx, - server_name, - domain_name, - (const char **)&buffer); -#else - werr = rpccli_netlogon_getdcname(pipe_cli, ctx, - server_name, - domain_name, - (char **)buffer); -#endif + status = rpccli_netr_GetDcName(pipe_cli, ctx, + server_name, + domain_name, + (const char **)buffer); + werr = ntstatus_to_werror(status); done: if (cli) { cli_shutdown(cli); @@ -175,22 +153,14 @@ static WERROR NetGetAnyDCNameRemote(struct libnetapi_ctx *ctx, goto done; }; -#if 0 status = rpccli_netr_GetAnyDCName(pipe_cli, ctx, server_name, domain_name, - (const char **)&buffer, + (const char **)buffer, &werr); if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); goto done; } -#else - werr = rpccli_netlogon_getanydcname(pipe_cli, ctx, - server_name, - domain_name, - (char **)buffer); -#endif done: if (cli) { cli_shutdown(cli); -- cgit From c2ff6c94f2f9ddc2c4b03f7907f7d6e0de951c24 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 18 Jan 2008 01:56:01 +0100 Subject: Improve libnetapi_set_error_string(). Guenther (This used to be commit 96f645553ae5c75aabfe588e1a67f3d4bfacb5cb) --- source3/lib/netapi/netapi.c | 11 ++++++++--- source3/lib/netapi/netapi.h | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 39 insertions(+), 7 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c index ce00054e6e..5c3f7ec465 100644 --- a/source3/lib/netapi/netapi.c +++ b/source3/lib/netapi/netapi.c @@ -205,15 +205,20 @@ const char *libnetapi_errstr(NET_API_STATUS status) ****************************************************************/ NET_API_STATUS libnetapi_set_error_string(struct libnetapi_ctx *ctx, - const char *error_string) + const char *format, ...) { + va_list args; + TALLOC_FREE(ctx->error_string); - ctx->error_string = talloc_strdup(ctx, error_string); + + va_start(args, format); + ctx->error_string = talloc_vasprintf(ctx, format, args); + va_end(args); + if (!ctx->error_string) { return W_ERROR_V(WERR_NOMEM); } return NET_API_STATUS_SUCCESS; - } /**************************************************************** diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h index 274a167d53..67bb8a8fca 100644 --- a/source3/lib/netapi/netapi.h +++ b/source3/lib/netapi/netapi.h @@ -57,46 +57,73 @@ NET_API_STATUS libnetapi_set_username(struct libnetapi_ctx *ctx, const char *use NET_API_STATUS libnetapi_set_password(struct libnetapi_ctx *ctx, const char *password); NET_API_STATUS libnetapi_set_workgroup(struct libnetapi_ctx *ctx, const char *workgroup); const char *libnetapi_errstr(NET_API_STATUS status); -NET_API_STATUS libnetapi_set_error_string(struct libnetapi_ctx *ctx, const char *error_string); +NET_API_STATUS libnetapi_set_error_string(struct libnetapi_ctx *ctx, const char *format, ...); const char *libnetapi_get_error_string(struct libnetapi_ctx *ctx, NET_API_STATUS status); /**************************************************************** + NetApiBufferFree ****************************************************************/ NET_API_STATUS NetApiBufferFree(void *buffer); /**************************************************************** + NetJoinDomain ****************************************************************/ -/* wkssvc */ NET_API_STATUS NetJoinDomain(const char *server, const char *domain, const char *account_ou, const char *account, const char *password, uint32_t join_options); + +/**************************************************************** + NetUnjoinDomain +****************************************************************/ + NET_API_STATUS NetUnjoinDomain(const char *server_name, const char *account, const char *password, uint32_t unjoin_flags); + +/**************************************************************** + NetGetJoinInformation +****************************************************************/ + NET_API_STATUS NetGetJoinInformation(const char *server_name, const char **name_buffer, uint16_t *name_type); -/* srvsvc */ +/**************************************************************** + NetServerGetInfo +****************************************************************/ + NET_API_STATUS NetServerGetInfo(const char *server_name, uint32_t level, uint8_t **buffer); + +/**************************************************************** + NetServerSetInfo +****************************************************************/ + NET_API_STATUS NetServerSetInfo(const char *server_name, uint32_t level, uint8_t *buffer, uint32_t *parm_error); -/* netlogon */ +/**************************************************************** + NetGetDCName +****************************************************************/ + NET_API_STATUS NetGetDCName(const char *server_name, const char *domain_name, uint8_t **buffer); + +/**************************************************************** + NetGetAnyDCName +****************************************************************/ + NET_API_STATUS NetGetAnyDCName(const char *server_name, const char *domain_name, uint8_t **buffer); -- cgit From bb97b272a975e4af7738c58e7af4b8e3047d4b77 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 18 Jan 2008 02:30:09 +0100 Subject: Fix local hostname detection in netdomjoin-gui. Guenther (This used to be commit 30458116b389889cad845eb96b54c3edc833e722) --- .../examples/netdomjoin-gui/netdomjoin-gui.c | 37 ++++++++++++++++------ 1 file changed, 27 insertions(+), 10 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c index 9dc2a18138..6e958b4c73 100644 --- a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c +++ b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -1263,28 +1264,44 @@ static int initialize_join_state(struct join_state *state, { char my_hostname[HOST_NAME_MAX]; const char *p = NULL; + struct hostent *hp = NULL; + if (gethostname(my_hostname, sizeof(my_hostname)) == -1) { return -1; } - state->my_fqdn = strdup(my_hostname); + p = strchr(my_hostname, '.'); + if (p) { + my_hostname[strlen(my_hostname)-strlen(p)] = '\0'; + } + state->my_hostname = strdup(my_hostname); + if (!state->my_hostname) { + return -1; + } + debug("state->my_hostname: %s\n", state->my_hostname); + + hp = gethostbyname(my_hostname); + if (!hp || !hp->h_name || !*hp->h_name) { + return -1; + } + + state->my_fqdn = strdup(hp->h_name); if (!state->my_fqdn) { return -1; } + debug("state->my_fqdn: %s\n", state->my_fqdn); - p = strchr(my_hostname, '.'); + p = strchr(state->my_fqdn, '.'); if (p) { - my_hostname[strlen(my_hostname) - strlen(p)] = '\0'; - state->my_hostname = strdup(my_hostname); - if (!state->my_hostname) { - return -1; - } p++; state->my_dnsdomain = strdup(p); - if (!state->my_dnsdomain) { - return -1; - } + } else { + state->my_dnsdomain = strdup(""); + } + if (!state->my_dnsdomain) { + return -1; } + debug("state->my_dnsdomain: %s\n", state->my_dnsdomain); } { -- cgit From cfb7e254662dd957da7e193010f87544b96c2f17 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 18 Jan 2008 02:30:53 +0100 Subject: Add some more debugging into netdomjoin-gui. Guenther (This used to be commit d4c5b323229c6f43c824e3559084c98e370730a5) --- source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c index 6e958b4c73..73b14d4d87 100644 --- a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c +++ b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c @@ -440,7 +440,7 @@ static void callback_do_join(GtkWidget *widget, state->password, unjoin_flags); if (status != 0) { - err_str = libnetapi_errstr(status); + err_str = libnetapi_get_error_string(state->ctx, status); g_print("callback_do_join: failed to unjoin (%s)\n", err_str); @@ -464,7 +464,7 @@ static void callback_do_join(GtkWidget *widget, state->password, join_flags); if (status != 0) { - err_str = libnetapi_errstr(status); + err_str = libnetapi_get_error_string(state->ctx, status); g_print("callback_do_join: failed to join (%s)\n", err_str); dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent), @@ -1308,9 +1308,12 @@ static int initialize_join_state(struct join_state *state, const char *buffer = NULL; uint16_t type = 0; status = NetGetJoinInformation(NULL, &buffer, &type); - if (status) { + if (status != 0) { + printf("NetGetJoinInformation failed with: %s\n", + libnetapi_get_error_string(state->ctx, status)); return status; } + debug("NetGetJoinInformation gave: %s and %d\n", buffer, type); state->name_buffer_initial = strdup(buffer); if (!state->name_buffer_initial) { return -1; @@ -1324,7 +1327,9 @@ static int initialize_join_state(struct join_state *state, uint8_t *buffer = NULL; status = NetServerGetInfo(NULL, 1005, &buffer); - if (status) { + if (status != 0) { + printf("NetServerGetInfo failed with: %s\n", + libnetapi_get_error_string(state->ctx, status)); return status; } -- cgit From b1424846c60848d685853fcf632ab766543e05ee Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 18 Jan 2008 02:38:35 +0100 Subject: Cosmetics and error string reporting for libnetapi. Guenther (This used to be commit 4ca33928512bd71268bafd41d2b608e814a7295f) --- source3/lib/netapi/getdc.c | 30 ++++++++++++++++++++-- source3/lib/netapi/joindomain.c | 57 ++++++++++++++++++++++++++++++++++++----- source3/lib/netapi/serverinfo.c | 43 +++++++++++++++++++++++++------ 3 files changed, 114 insertions(+), 16 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/getdc.c b/source3/lib/netapi/getdc.c index 484af04a55..1084ddc3c8 100644 --- a/source3/lib/netapi/getdc.c +++ b/source3/lib/netapi/getdc.c @@ -22,6 +22,9 @@ #include "lib/netapi/netapi.h" #include "libnet/libnet.h" +/******************************************************************** +********************************************************************/ + static WERROR NetGetDCNameLocal(struct libnetapi_ctx *ctx, const char *server_name, const char *domain_name, @@ -30,6 +33,9 @@ static WERROR NetGetDCNameLocal(struct libnetapi_ctx *ctx, return WERR_NOT_SUPPORTED; } +/******************************************************************** +********************************************************************/ + static WERROR NetGetDCNameRemote(struct libnetapi_ctx *ctx, const char *server_name, const char *domain_name, @@ -73,6 +79,9 @@ static WERROR NetGetDCNameRemote(struct libnetapi_ctx *ctx, return werr; } +/******************************************************************** +********************************************************************/ + static WERROR libnetapi_NetGetDCName(struct libnetapi_ctx *ctx, const char *server_name, const char *domain_name, @@ -91,6 +100,10 @@ static WERROR libnetapi_NetGetDCName(struct libnetapi_ctx *ctx, buffer); } +/**************************************************************** + NetGetDCName +****************************************************************/ + NET_API_STATUS NetGetDCName(const char *server_name, const char *domain_name, uint8_t **buffer) @@ -112,9 +125,12 @@ NET_API_STATUS NetGetDCName(const char *server_name, return W_ERROR_V(werr); } - return 0; + return NET_API_STATUS_SUCCESS; } +/******************************************************************** +********************************************************************/ + static WERROR NetGetAnyDCNameLocal(struct libnetapi_ctx *ctx, const char *server_name, const char *domain_name, @@ -123,6 +139,9 @@ static WERROR NetGetAnyDCNameLocal(struct libnetapi_ctx *ctx, return WERR_NOT_SUPPORTED; } +/******************************************************************** +********************************************************************/ + static WERROR NetGetAnyDCNameRemote(struct libnetapi_ctx *ctx, const char *server_name, const char *domain_name, @@ -170,6 +189,9 @@ static WERROR NetGetAnyDCNameRemote(struct libnetapi_ctx *ctx, } +/******************************************************************** +********************************************************************/ + static WERROR libnetapi_NetGetAnyDCName(struct libnetapi_ctx *ctx, const char *server_name, const char *domain_name, @@ -188,6 +210,10 @@ static WERROR libnetapi_NetGetAnyDCName(struct libnetapi_ctx *ctx, buffer); } +/**************************************************************** + NetGetAnyDCName +****************************************************************/ + NET_API_STATUS NetGetAnyDCName(const char *server_name, const char *domain_name, uint8_t **buffer) @@ -209,5 +235,5 @@ NET_API_STATUS NetGetAnyDCName(const char *server_name, return W_ERROR_V(werr); } - return 0; + return NET_API_STATUS_SUCCESS; } diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index b268e41a2a..43662b3ffa 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -22,6 +22,9 @@ #include "lib/netapi/netapi.h" #include "libnet/libnet.h" +/**************************************************************** +****************************************************************/ + static WERROR NetJoinDomainLocal(struct libnetapi_ctx *mem_ctx, const char *server_name, const char *domain_name, @@ -52,6 +55,8 @@ static WERROR NetJoinDomainLocal(struct libnetapi_ctx *mem_ctx, status = dsgetdcname(mem_ctx, NULL, domain_name, NULL, NULL, flags, &info); if (!NT_STATUS_IS_OK(status)) { + libnetapi_set_error_string(mem_ctx, + "%s", get_friendly_nt_error_msg(status)); return ntstatus_to_werror(status); } r->in.dc_name = talloc_strdup(mem_ctx, @@ -79,13 +84,16 @@ static WERROR NetJoinDomainLocal(struct libnetapi_ctx *mem_ctx, werr = libnet_Join(mem_ctx, r); if (!W_ERROR_IS_OK(werr) && r->out.error_string) { - libnetapi_set_error_string(mem_ctx, r->out.error_string); + libnetapi_set_error_string(mem_ctx, "%s", r->out.error_string); } TALLOC_FREE(r); return werr; } +/**************************************************************** +****************************************************************/ + static WERROR NetJoinDomainRemote(struct libnetapi_ctx *ctx, const char *server_name, const char *domain_name, @@ -149,6 +157,9 @@ static WERROR NetJoinDomainRemote(struct libnetapi_ctx *ctx, return werr; } +/**************************************************************** +****************************************************************/ + static WERROR libnetapi_NetJoinDomain(struct libnetapi_ctx *ctx, const char *server_name, const char *domain_name, @@ -181,6 +192,10 @@ static WERROR libnetapi_NetJoinDomain(struct libnetapi_ctx *ctx, join_flags); } +/**************************************************************** + NetJoinDomain +****************************************************************/ + NET_API_STATUS NetJoinDomain(const char *server_name, const char *domain_name, const char *account_ou, @@ -208,9 +223,12 @@ NET_API_STATUS NetJoinDomain(const char *server_name, return W_ERROR_V(werr); } - return 0; + return NET_API_STATUS_SUCCESS; } +/**************************************************************** +****************************************************************/ + static WERROR NetUnjoinDomainLocal(struct libnetapi_ctx *mem_ctx, const char *server_name, const char *account, @@ -232,7 +250,6 @@ static WERROR NetUnjoinDomainLocal(struct libnetapi_ctx *mem_ctx, r->in.dc_name = talloc_strdup(mem_ctx, server_name); W_ERROR_HAVE_NO_MEMORY(r->in.dc_name); } else { - NTSTATUS status; const char *domain = NULL; struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; @@ -247,6 +264,8 @@ static WERROR NetUnjoinDomainLocal(struct libnetapi_ctx *mem_ctx, status = dsgetdcname(mem_ctx, NULL, domain, NULL, NULL, flags, &info); if (!NT_STATUS_IS_OK(status)) { + libnetapi_set_error_string(mem_ctx, + "%s", get_friendly_nt_error_msg(status)); return ntstatus_to_werror(status); } r->in.dc_name = talloc_strdup(mem_ctx, @@ -266,13 +285,22 @@ static WERROR NetUnjoinDomainLocal(struct libnetapi_ctx *mem_ctx, r->in.unjoin_flags = unjoin_flags; r->in.modify_config = true; + r->in.debug = true; r->in.domain_sid = &domain_sid; - return libnet_Unjoin(mem_ctx, r); + werr = libnet_Unjoin(mem_ctx, r); + if (!W_ERROR_IS_OK(werr) && r->out.error_string) { + libnetapi_set_error_string(mem_ctx, "%s", r->out.error_string); + } + TALLOC_FREE(r); + return werr; } +/**************************************************************** +****************************************************************/ + static WERROR NetUnjoinDomainRemote(struct libnetapi_ctx *ctx, const char *server_name, const char *account, @@ -335,6 +363,9 @@ static WERROR NetUnjoinDomainRemote(struct libnetapi_ctx *ctx, return werr; } +/**************************************************************** +****************************************************************/ + static WERROR libnetapi_NetUnjoinDomain(struct libnetapi_ctx *ctx, const char *server_name, const char *account, @@ -357,6 +388,10 @@ static WERROR libnetapi_NetUnjoinDomain(struct libnetapi_ctx *ctx, unjoin_flags); } +/**************************************************************** + NetUnjoinDomain +****************************************************************/ + NET_API_STATUS NetUnjoinDomain(const char *server_name, const char *account, const char *password, @@ -380,9 +415,12 @@ NET_API_STATUS NetUnjoinDomain(const char *server_name, return W_ERROR_V(werr); } - return 0; + return NET_API_STATUS_SUCCESS; } +/**************************************************************** +****************************************************************/ + static WERROR NetGetJoinInformationRemote(struct libnetapi_ctx *ctx, const char *server_name, const char **name_buffer, @@ -431,6 +469,9 @@ static WERROR NetGetJoinInformationRemote(struct libnetapi_ctx *ctx, return werr; } +/**************************************************************** +****************************************************************/ + static WERROR NetGetJoinInformationLocal(struct libnetapi_ctx *ctx, const char *server_name, const char **name_buffer, @@ -478,6 +519,10 @@ static WERROR libnetapi_NetGetJoinInformation(struct libnetapi_ctx *ctx, name_type); } +/**************************************************************** + NetGetJoinInformation +****************************************************************/ + NET_API_STATUS NetGetJoinInformation(const char *server_name, const char **name_buffer, uint16_t *name_type) @@ -499,5 +544,5 @@ NET_API_STATUS NetGetJoinInformation(const char *server_name, return W_ERROR_V(werr); } - return 0; + return NET_API_STATUS_SUCCESS; } diff --git a/source3/lib/netapi/serverinfo.c b/source3/lib/netapi/serverinfo.c index 6cd074615b..7fa166e411 100644 --- a/source3/lib/netapi/serverinfo.c +++ b/source3/lib/netapi/serverinfo.c @@ -22,6 +22,9 @@ #include "lib/netapi/netapi.h" #include "libnet/libnet.h" +/**************************************************************** +****************************************************************/ + static WERROR NetServerGetInfoLocal_1005(struct libnetapi_ctx *ctx, uint8_t **buffer) { @@ -36,6 +39,9 @@ static WERROR NetServerGetInfoLocal_1005(struct libnetapi_ctx *ctx, return WERR_OK; } +/**************************************************************** +****************************************************************/ + static WERROR NetServerGetInfoLocal(struct libnetapi_ctx *ctx, const char *server_name, uint32_t level, @@ -51,6 +57,9 @@ static WERROR NetServerGetInfoLocal(struct libnetapi_ctx *ctx, return WERR_UNKNOWN_LEVEL; } +/**************************************************************** +****************************************************************/ + static WERROR NetServerGetInfoRemote(struct libnetapi_ctx *ctx, const char *server_name, uint32_t level, @@ -102,6 +111,9 @@ static WERROR NetServerGetInfoRemote(struct libnetapi_ctx *ctx, return werr; } +/**************************************************************** +****************************************************************/ + static WERROR libnetapi_NetServerGetInfo(struct libnetapi_ctx *ctx, const char *server_name, uint32_t level, @@ -121,6 +133,10 @@ static WERROR libnetapi_NetServerGetInfo(struct libnetapi_ctx *ctx, } +/**************************************************************** + NetServerGetInfo +****************************************************************/ + NET_API_STATUS NetServerGetInfo(const char *server_name, uint32_t level, uint8_t **buffer) @@ -142,17 +158,18 @@ NET_API_STATUS NetServerGetInfo(const char *server_name, return W_ERROR_V(werr); } - return 0; + return NET_API_STATUS_SUCCESS; } +/**************************************************************** +****************************************************************/ + static WERROR NetServerSetInfoLocal_1005(struct libnetapi_ctx *ctx, uint8_t *buffer, uint32_t *parm_error) { WERROR werr; struct libnet_conf_ctx *conf_ctx; - TALLOC_CTX *mem_ctx; - struct srvsvc_NetSrvInfo1005 *info1005; if (!buffer) { @@ -171,8 +188,7 @@ static WERROR NetServerSetInfoLocal_1005(struct libnetapi_ctx *ctx, return WERR_NOT_SUPPORTED; } - mem_ctx = talloc_stackframe(); - werr = libnet_conf_open(mem_ctx, &conf_ctx); + werr = libnet_conf_open(ctx, &conf_ctx); if (!W_ERROR_IS_OK(werr)) { goto done; } @@ -181,12 +197,14 @@ static WERROR NetServerSetInfoLocal_1005(struct libnetapi_ctx *ctx, "server string", info1005->comment); -done: + done: libnet_conf_close(conf_ctx); - TALLOC_FREE(mem_ctx); return werr; } +/**************************************************************** +****************************************************************/ + static WERROR NetServerSetInfoLocal(struct libnetapi_ctx *ctx, const char *server_name, uint32_t level, @@ -203,6 +221,9 @@ static WERROR NetServerSetInfoLocal(struct libnetapi_ctx *ctx, return WERR_UNKNOWN_LEVEL; } +/**************************************************************** +****************************************************************/ + static WERROR NetServerSetInfoRemote(struct libnetapi_ctx *ctx, const char *server_name, uint32_t level, @@ -263,6 +284,9 @@ static WERROR NetServerSetInfoRemote(struct libnetapi_ctx *ctx, return werr; } +/**************************************************************** +****************************************************************/ + static WERROR libnetapi_NetServerSetInfo(struct libnetapi_ctx *ctx, const char *server_name, uint32_t level, @@ -284,6 +308,9 @@ static WERROR libnetapi_NetServerSetInfo(struct libnetapi_ctx *ctx, parm_error); } +/**************************************************************** + NetServerSetInfo +****************************************************************/ NET_API_STATUS NetServerSetInfo(const char *server_name, uint32_t level, @@ -308,5 +335,5 @@ NET_API_STATUS NetServerSetInfo(const char *server_name, return W_ERROR_V(werr); } - return 0; + return NET_API_STATUS_SUCCESS; } -- cgit From b18fd380bd142933b7c1a341629aac61c8799d22 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 18 Jan 2008 02:50:33 +0100 Subject: Add NetGetJoinableOUs() to libnetapi (incl. example). Guenther (This used to be commit 8858e403e1940c362d307b4d4125f977abb0b96a) --- source3/lib/netapi/examples/Makefile.in | 16 +- .../examples/getjoinableous/getjoinableous.c | 104 +++++++++++ source3/lib/netapi/joindomain.c | 192 +++++++++++++++++++++ 3 files changed, 309 insertions(+), 3 deletions(-) create mode 100644 source3/lib/netapi/examples/getjoinableous/getjoinableous.c (limited to 'source3/lib') diff --git a/source3/lib/netapi/examples/Makefile.in b/source3/lib/netapi/examples/Makefile.in index c2f453dedc..86e1b1bc2f 100644 --- a/source3/lib/netapi/examples/Makefile.in +++ b/source3/lib/netapi/examples/Makefile.in @@ -5,7 +5,7 @@ KRB5LIBS=@KRB5_LIBS@ LDAP_LIBS=@LDAP_LIBS@ LIBS=@LIBS@ -lnetapi DEVELOPER_CFLAGS=@DEVELOPER_CFLAGS@ -FLAGS=@CFLAGS@ $(GTK_FLAGS) +FLAGS=-I../ -L../../../bin @CFLAGS@ $(GTK_FLAGS) CC=@CC@ LDFLAGS=@PIE_LDFLAGS@ @LDFLAGS@ DYNEXP=@DYNEXP@ @@ -36,8 +36,12 @@ MAKEDIR = || exec false; \ GETDC_OBJ = getdc/getdc.o NETDOMJOIN_OBJ = netdomjoin/netdomjoin.o NETDOMJOIN_GUI_OBJ = netdomjoin-gui/netdomjoin-gui.o +GETJOINABLEOUS_OBJ = getjoinableous/getjoinableous.o -PROGS = bin/getdc@EXEEXT@ bin/netdomjoin@EXEEXT@ bin/netdomjoin-gui@EXEEXT@ +PROGS = bin/getdc@EXEEXT@ \ + bin/netdomjoin@EXEEXT@ \ + bin/netdomjoin-gui@EXEEXT@ \ + bin/getjoinableous@EXEEXT@ all: $(PROGS) @@ -45,6 +49,10 @@ bin/getdc@EXEEXT@: $(GETDC_OBJ) @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(GETDC_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) +bin/getjoinableous@EXEEXT@: $(GETJOINABLEOUS_OBJ) + @echo Linking $@ + @$(CC) $(FLAGS) -o $@ $(GETJOINABLEOUS_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) + bin/netdomjoin@EXEEXT@: $(NETDOMJOIN_OBJ) @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(NETDOMJOIN_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) @@ -54,4 +62,6 @@ bin/netdomjoin-gui@EXEEXT@: $(NETDOMJOIN_GUI_OBJ) @$(CC) $(FLAGS) $(GTK_FLAGS) -o $@ $(NETDOMJOIN_GUI_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(GTK_LIBS) clean: - @rm -f $(PROGS) + -rm -f $(PROGS) + -rm -f core */*~ *~ \ + */*.o */*/*.o */*/*/*.o \ diff --git a/source3/lib/netapi/examples/getjoinableous/getjoinableous.c b/source3/lib/netapi/examples/getjoinableous/getjoinableous.c new file mode 100644 index 0000000000..5a3366c9dc --- /dev/null +++ b/source3/lib/netapi/examples/getjoinableous/getjoinableous.c @@ -0,0 +1,104 @@ +/* + * Unix SMB/CIFS implementation. + * Join Support (cmdline + netapi) + * Copyright (C) Guenther Deschner 2008 + * + * 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 3 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, see . + */ + +#include +#include + +#include + +char *get_string_param(const char *param) +{ + char *p; + + p = strchr(param, '='); + if (!p) { + return NULL; + } + + return (p+1); +} + +int main(int argc, char **argv) +{ + NET_API_STATUS status; + const char *server_name = NULL; + const char *domain_name = NULL; + const char *account = NULL; + const char *password = NULL; + const char **ous = NULL; + uint32_t num_ous = 0; + struct libnetapi_ctx *ctx = NULL; + int i; + + status = libnetapi_init(&ctx); + if (status != 0) { + return status; + } + + if (argc < 2) { + printf("usage: getjoinableous\n"); + printf("\t [domain=DOMAIN] \n"); + return 0; + } + + if (argc > 2) { + server_name = argv[1]; + } + + for (i=0; idomain_controller_name); + if (!ads) { + return WERR_GENERAL_FAILURE; + } + + SAFE_FREE(ads->auth.user_name); + if (account) { + ads->auth.user_name = SMB_STRDUP(account); + } else if (ctx->username) { + ads->auth.user_name = SMB_STRDUP(ctx->username); + } + + SAFE_FREE(ads->auth.password); + if (password) { + ads->auth.password = SMB_STRDUP(password); + } else if (ctx->password) { + ads->auth.password = SMB_STRDUP(ctx->password); + } + + ads_status = ads_connect(ads); + if (!ADS_ERR_OK(ads_status)) { + ads_destroy(&ads); + return WERR_DEFAULT_JOIN_REQUIRED; + } + + ads_status = ads_get_joinable_ous(ads, ctx, + (char ***)ous, + (size_t *)ou_count); + if (!ADS_ERR_OK(ads_status)) { + ads_destroy(&ads); + return WERR_DEFAULT_JOIN_REQUIRED; + } + + ads_destroy(&ads); + return WERR_OK; +} + +/**************************************************************** +****************************************************************/ + +static WERROR NetGetJoinableOUsRemote(struct libnetapi_ctx *ctx, + const char *server_name, + const char *domain, + const char *account, + const char *password, + uint32_t *ou_count, + const char ***ous) +{ + struct cli_state *cli = NULL; + struct rpc_pipe_client *pipe_cli = NULL; + struct wkssvc_PasswordBuffer *encrypted_password = NULL; + NTSTATUS status; + WERROR werr; + + status = cli_full_connection(&cli, NULL, server_name, + NULL, 0, + "IPC$", "IPC", + ctx->username, + ctx->workgroup, + ctx->password, + 0, Undefined, NULL); + + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); + goto done; + } + + pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_WKSSVC, + &status); + if (!pipe_cli) { + werr = ntstatus_to_werror(status); + goto done; + } + + if (password) { + encode_wkssvc_join_password_buffer(ctx, + password, + &cli->user_session_key, + &encrypted_password); + } + + status = rpccli_wkssvc_NetrGetJoinableOus2(pipe_cli, ctx, + server_name, + domain, + account, + encrypted_password, + ou_count, + ous, + &werr); + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); + goto done; + } + + done: + if (cli) { + cli_shutdown(cli); + } + + return werr; +} + +/**************************************************************** +****************************************************************/ + +static WERROR libnetapi_NetGetJoinableOUs(struct libnetapi_ctx *ctx, + const char *server_name, + const char *domain, + const char *account, + const char *password, + uint32_t *ou_count, + const char ***ous) +{ + if (!server_name || is_myname_or_ipaddr(server_name)) { + return NetGetJoinableOUsLocal(ctx, + server_name, + domain, + account, + password, + ou_count, + ous); + } + + return NetGetJoinableOUsRemote(ctx, + server_name, + domain, + account, + password, + ou_count, + ous); +} + +/**************************************************************** + NetGetJoinableOUs +****************************************************************/ + +NET_API_STATUS NetGetJoinableOUs(const char *server_name, + const char *domain, + const char *account, + const char *password, + uint32_t *ou_count, + const char ***ous) +{ + struct libnetapi_ctx *ctx = NULL; + NET_API_STATUS status; + WERROR werr; + + status = libnetapi_getctx(&ctx); + if (status != 0) { + return status; + } + + werr = libnetapi_NetGetJoinableOUs(ctx, + server_name, + domain, + account, + password, + ou_count, + ous); + if (!W_ERROR_IS_OK(werr)) { + return W_ERROR_V(werr); + } + + return NET_API_STATUS_SUCCESS; +} -- cgit From 313a21b4d946550426705c70231c59d8bc4005f1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 18 Jan 2008 15:46:15 +1100 Subject: merged changes from v4-0-test (This used to be commit 8c89d60924b0380231da834cd3c097b4f8cdc369) --- source3/lib/tdb/common/freelist.c | 85 ++++++++++++++++++------------------ source3/lib/tdb/common/tdb_private.h | 1 - 2 files changed, 43 insertions(+), 43 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/tdb/common/freelist.c b/source3/lib/tdb/common/freelist.c index c086c151fa..2f2a4c379b 100644 --- a/source3/lib/tdb/common/freelist.c +++ b/source3/lib/tdb/common/freelist.c @@ -208,62 +208,61 @@ update: } + /* the core of tdb_allocate - called when we have decided which free list entry to use + + Note that we try to allocate by grabbing data from the end of an existing record, + not the beginning. This is so the left merge in a free is more likely to be + able to free up the record without fragmentation */ -static tdb_off_t tdb_allocate_ofs(struct tdb_context *tdb, tdb_len_t length, tdb_off_t rec_ptr, - struct list_struct *rec, tdb_off_t last_ptr) +static tdb_off_t tdb_allocate_ofs(struct tdb_context *tdb, + tdb_len_t length, tdb_off_t rec_ptr, + struct list_struct *rec, tdb_off_t last_ptr) { - struct list_struct newrec; - tdb_off_t newrec_ptr; +#define MIN_REC_SIZE (sizeof(struct list_struct) + sizeof(tdb_off_t) + 8) - memset(&newrec, '\0', sizeof(newrec)); + if (rec->rec_len < length + MIN_REC_SIZE) { + /* we have to grab the whole record */ - /* found it - now possibly split it up */ - if (rec->rec_len > length + MIN_REC_SIZE) { - /* Length of left piece */ - length = TDB_ALIGN(length, TDB_ALIGNMENT); - - /* Right piece to go on free list */ - newrec.rec_len = rec->rec_len - (sizeof(*rec) + length); - newrec_ptr = rec_ptr + sizeof(*rec) + length; - - /* And left record is shortened */ - rec->rec_len = length; - } else { - newrec_ptr = 0; + /* unlink it from the previous record */ + if (tdb_ofs_write(tdb, last_ptr, &rec->next) == -1) { + return 0; + } + + /* mark it not free */ + rec->magic = TDB_MAGIC; + if (tdb_rec_write(tdb, rec_ptr, rec) == -1) { + return 0; + } + return rec_ptr; + } + + /* we're going to just shorten the existing record */ + rec->rec_len -= (length + sizeof(*rec)); + if (tdb_rec_write(tdb, rec_ptr, rec) == -1) { + return 0; } - - /* Remove allocated record from the free list */ - if (tdb_ofs_write(tdb, last_ptr, &rec->next) == -1) { + if (update_tailer(tdb, rec_ptr, rec) == -1) { return 0; } - - /* Update header: do this before we drop alloc - lock, otherwise tdb_free() might try to - merge with us, thinking we're free. - (Thanks Jeremy Allison). */ + + /* and setup the new record */ + rec_ptr += sizeof(*rec) + rec->rec_len; + + memset(rec, '\0', sizeof(*rec)); + rec->rec_len = length; rec->magic = TDB_MAGIC; + if (tdb_rec_write(tdb, rec_ptr, rec) == -1) { return 0; } - - /* Did we create new block? */ - if (newrec_ptr) { - /* Update allocated record tailer (we - shortened it). */ - if (update_tailer(tdb, rec_ptr, rec) == -1) { - return 0; - } - - /* Free new record */ - if (tdb_free(tdb, newrec_ptr, &newrec) == -1) { - return 0; - } + + if (update_tailer(tdb, rec_ptr, rec) == -1) { + return 0; } - - /* all done - return the new record offset */ + return rec_ptr; } @@ -287,6 +286,7 @@ tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct list_st /* Extra bytes required for tailer */ length += sizeof(tdb_off_t); + length = TDB_ALIGN(length, TDB_ALIGNMENT); again: last_ptr = FREELIST_TOP; @@ -343,7 +343,8 @@ tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct list_st goto fail; } - newrec_ptr = tdb_allocate_ofs(tdb, length, bestfit.rec_ptr, rec, bestfit.last_ptr); + newrec_ptr = tdb_allocate_ofs(tdb, length, bestfit.rec_ptr, + rec, bestfit.last_ptr); tdb_unlock(tdb, -1, F_WRLCK); return newrec_ptr; } diff --git a/source3/lib/tdb/common/tdb_private.h b/source3/lib/tdb/common/tdb_private.h index dd69903015..ffac89ff0e 100644 --- a/source3/lib/tdb/common/tdb_private.h +++ b/source3/lib/tdb/common/tdb_private.h @@ -49,7 +49,6 @@ typedef uint32_t tdb_off_t; #define TDB_DEAD_MAGIC (0xFEE1DEAD) #define TDB_RECOVERY_MAGIC (0xf53bc0e7U) #define TDB_ALIGNMENT 4 -#define MIN_REC_SIZE (2*sizeof(struct list_struct) + TDB_ALIGNMENT) #define DEFAULT_HASH_SIZE 131 #define FREELIST_TOP (sizeof(struct tdb_header)) #define TDB_ALIGN(x,a) (((x) + (a)-1) & ~((a)-1)) -- cgit From 9dd8940e5f4d89da67b66fb1932a95cc6fda63a5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 18 Jan 2008 03:14:08 +0100 Subject: Add header for NetGetJoinableOUs to libnetapi. Guenther (This used to be commit f297ea259d58f7a12924b7111ab79818188cff46) --- source3/lib/netapi/netapi.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h index 67bb8a8fca..c2f1b488db 100644 --- a/source3/lib/netapi/netapi.h +++ b/source3/lib/netapi/netapi.h @@ -95,6 +95,17 @@ NET_API_STATUS NetGetJoinInformation(const char *server_name, const char **name_buffer, uint16_t *name_type); +/**************************************************************** + NetGetJoinableOUs +****************************************************************/ + +NET_API_STATUS NetGetJoinableOUs(const char *server_name, + const char *domain, + const char *account, + const char *password, + uint32_t *ou_count, + const char ***ous); + /**************************************************************** NetServerGetInfo ****************************************************************/ -- cgit From db40120c73f4d4cbb132f94cd3c5859fbdad0f5a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 18 Jan 2008 08:48:44 +0100 Subject: Fix the build w/o ADS. Guenther (This used to be commit 645f2376d40fabdc787902ac7506ad7234616619) --- source3/lib/netapi/joindomain.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index cbfc6c01e3..133aff3dd8 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -558,6 +558,7 @@ static WERROR NetGetJoinableOUsLocal(struct libnetapi_ctx *ctx, uint32_t *ou_count, const char ***ous) { +#ifdef WITH_ADS NTSTATUS status; ADS_STATUS ads_status; ADS_STRUCT *ads = NULL; @@ -608,6 +609,9 @@ static WERROR NetGetJoinableOUsLocal(struct libnetapi_ctx *ctx, ads_destroy(&ads); return WERR_OK; +#else + return WERR_NOT_SUPPORTED; +#endif } /**************************************************************** -- cgit From 928f899948d25a133c9622a2ac8208e4499ba260 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 15 Nov 2007 14:46:47 +0100 Subject: r25970: libreplace: fix AC_N_DEFINE() so that some appears in config.h metze (cherry picked from commit a07c983fde52607806745914bb41039afb5618cc) (This used to be commit 3db37038b3e5a59a9baa85f6bcd32ac6e5ec2da1) --- source3/lib/replace/libreplace_macros.m4 | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/replace/libreplace_macros.m4 b/source3/lib/replace/libreplace_macros.m4 index 92fecd3db8..54e6b7ac75 100644 --- a/source3/lib/replace/libreplace_macros.m4 +++ b/source3/lib/replace/libreplace_macros.m4 @@ -248,11 +248,18 @@ m4_define([AH_CHECK_FUNC_EXT], dnl Define an AC_DEFINE with ifndef guard. dnl AC_N_DEFINE(VARIABLE [, VALUE]) -define(AC_N_DEFINE, -[cat >> confdefs.h <<\EOF -[#ifndef] $1 -[#define] $1 ifelse($#, 2, [$2], $#, 3, [$2], 1) -[#endif] +AC_DEFUN([AC_N_DEFINE], +[ +AH_VERBATIM([$1], [ +#ifndef $1 +# undef $1 +#endif +]) + + cat >>confdefs.h <<\EOF +#ifndef $1 +[#define] $1 m4_if($#, 1, 1, [$2]) +#endif EOF ]) -- cgit From 2e0dc77bdad8e6c88920cfb8624a8dac981dd4c8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 15 Nov 2007 14:55:48 +0100 Subject: r25971: libreplace: remove AC_EXTENSION_FLAG as it's the same as AC_N_DEFINE metze (cherry picked from commit 05b4619c5beff474488d1abe5e647acd94a3e20c) (This used to be commit 58932ca791024bd9a543ff5e21bc26970ceed477) --- source3/lib/replace/libreplace_cc.m4 | 4 ++-- source3/lib/replace/libreplace_macros.m4 | 13 ------------- 2 files changed, 2 insertions(+), 15 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/replace/libreplace_cc.m4 b/source3/lib/replace/libreplace_cc.m4 index a01bf1b290..a0722b2fcf 100644 --- a/source3/lib/replace/libreplace_cc.m4 +++ b/source3/lib/replace/libreplace_cc.m4 @@ -48,8 +48,8 @@ LIBREPLACE_C99_STRUCT_INIT([],[AC_MSG_WARN([c99 structure initializer are not su AC_PROG_INSTALL AC_ISC_POSIX -AC_EXTENSION_FLAG(_XOPEN_SOURCE_EXTENDED) -AC_EXTENSION_FLAG(_OSF_SOURCE) +AC_N_DEFINE(_XOPEN_SOURCE_EXTENDED) +AC_N_DEFINE(_OSF_SOURCE) AC_SYS_LARGEFILE diff --git a/source3/lib/replace/libreplace_macros.m4 b/source3/lib/replace/libreplace_macros.m4 index 54e6b7ac75..1856eacf66 100644 --- a/source3/lib/replace/libreplace_macros.m4 +++ b/source3/lib/replace/libreplace_macros.m4 @@ -87,19 +87,6 @@ fi rm -f conftest* ])]) -AC_DEFUN([AC_EXTENSION_FLAG], -[ - cat >>confdefs.h <<\EOF -#ifndef $1 -# define $1 1 -#endif -EOF -AH_VERBATIM([$1], [#ifndef $1 -# define $1 1 -#endif]) -]) - - dnl see if a declaration exists for a function or variable dnl defines HAVE_function_DECL if it exists dnl AC_HAVE_DECL(var, includes) -- cgit From f75898d5b5712bcd8cb45cd54893932c1d0e5b36 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 15 Nov 2007 15:43:14 +0100 Subject: r25974: libreplace: see what the build-farm says if we use _XOPEN_SOURCE=600 On Tru64 this brings in socklen_t and some other socket stuff metze (cherry picked from commit d42f2e5759332f1f0c6c1269bd29ac62ddb11016) (This used to be commit af3772e22f5e6e0158783086e9791ffc95ee5368) --- source3/lib/replace/libreplace_cc.m4 | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/lib') diff --git a/source3/lib/replace/libreplace_cc.m4 b/source3/lib/replace/libreplace_cc.m4 index a0722b2fcf..3f0a337083 100644 --- a/source3/lib/replace/libreplace_cc.m4 +++ b/source3/lib/replace/libreplace_cc.m4 @@ -49,6 +49,7 @@ AC_PROG_INSTALL AC_ISC_POSIX AC_N_DEFINE(_XOPEN_SOURCE_EXTENDED) +AC_N_DEFINE(_XOPEN_SOURCE,600) AC_N_DEFINE(_OSF_SOURCE) AC_SYS_LARGEFILE -- cgit From 0e1348869e50715f889a97a375abc7ae1af13d69 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 15 Nov 2007 16:40:32 +0100 Subject: r25976: libreplace: not all platforms like _XOPEN_SOURCE=600 - Only use _XOPEN_SOURCE=600 on Tru64 - _OSF_SOURCE is also Tru64 specific metze (cherry picked from commit d19ab62081ce4ee4273ff752ad0443782a994826) (This used to be commit dbff70b2ebe7cc09f7fbe5a0319f978dfcfa1da9) --- source3/lib/replace/libreplace_cc.m4 | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/replace/libreplace_cc.m4 b/source3/lib/replace/libreplace_cc.m4 index 3f0a337083..bf5056838d 100644 --- a/source3/lib/replace/libreplace_cc.m4 +++ b/source3/lib/replace/libreplace_cc.m4 @@ -49,8 +49,6 @@ AC_PROG_INSTALL AC_ISC_POSIX AC_N_DEFINE(_XOPEN_SOURCE_EXTENDED) -AC_N_DEFINE(_XOPEN_SOURCE,600) -AC_N_DEFINE(_OSF_SOURCE) AC_SYS_LARGEFILE @@ -78,6 +76,11 @@ case "$host_os" in CFLAGS="$CFLAGS -D_LINUX_SOURCE_COMPAT -qmaxmem=32000" fi ;; + *osf*) + # this brings in socklen_t + AC_N_DEFINE(_XOPEN_SOURCE,600) + AC_N_DEFINE(_OSF_SOURCE) + ;; # # VOS may need to have POSIX support and System V compatibility enabled. # -- cgit From a2bfb1749ca7bc0c713d3508c1324799245c7d1a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Nov 2007 14:42:14 +0100 Subject: r26102: libreplace: remove system/printing.h as it only contains samba3 stuff metze (cherry picked from commit 1ecb4ec01b0506c95a5f90a62040329e7a39ee93) (This used to be commit ff8a001f0d3f2655efafed41f2f0b14552a5c7e7) --- source3/lib/replace/system/printing.h | 50 ----------------------------------- source3/lib/replace/test/testsuite.c | 1 - 2 files changed, 51 deletions(-) delete mode 100644 source3/lib/replace/system/printing.h (limited to 'source3/lib') diff --git a/source3/lib/replace/system/printing.h b/source3/lib/replace/system/printing.h deleted file mode 100644 index 7eb02d004a..0000000000 --- a/source3/lib/replace/system/printing.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef _system_printing_h -#define _system_printing_h - -/* - Unix SMB/CIFS implementation. - - printing system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifdef AIX -#define DEFAULT_PRINTING PRINT_AIX -#define PRINTCAP_NAME "/etc/qconfig" -#endif - -#ifdef HPUX -#define DEFAULT_PRINTING PRINT_HPUX -#endif - -#ifdef QNX -#define DEFAULT_PRINTING PRINT_QNX -#endif - -#ifndef DEFAULT_PRINTING -#define DEFAULT_PRINTING PRINT_BSD -#endif -#ifndef PRINTCAP_NAME -#define PRINTCAP_NAME "/etc/printcap" -#endif - -#endif diff --git a/source3/lib/replace/test/testsuite.c b/source3/lib/replace/test/testsuite.c index 269a2ff5d6..5b95ae395c 100644 --- a/source3/lib/replace/test/testsuite.c +++ b/source3/lib/replace/test/testsuite.c @@ -37,7 +37,6 @@ #include "system/locale.h" #include "system/network.h" #include "system/passwd.h" -#include "system/printing.h" #include "system/readline.h" #include "system/select.h" #include "system/shmem.h" -- cgit From 1e5418edbc370e87293c324eae54372a495bb932 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 20 Dec 2007 15:59:39 +0100 Subject: r26550: libreplace: fallback to __ss_family of struct sockaddr_storage metze (cherry picked from commit 11bdc9bed80b9842ac1ab8f22509a5d191cddc91) (This used to be commit c11122afda52ce787dd1d3357bd85b6ce36b8ca4) --- source3/lib/replace/libreplace.m4 | 20 ++++++++++++++++++++ source3/lib/replace/system/network.h | 9 +++++++++ 2 files changed, 29 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/replace/libreplace.m4 b/source3/lib/replace/libreplace.m4 index 7a5283a4d6..f866b3648f 100644 --- a/source3/lib/replace/libreplace.m4 +++ b/source3/lib/replace/libreplace.m4 @@ -153,6 +153,26 @@ AC_HAVE_TYPE([struct sockaddr_in6], [ #include ]) +if test x"$ac_cv_type_struct_sockaddr_storage" = x"yes"; then +AC_CHECK_MEMBER(struct sockaddr_storage.ss_family, + AC_DEFINE(HAVE_SS_FAMILY, 1, [Defined if struct sockaddr_storage has ss_family field]),, + [ +#include +#include +#include + ]) + +if test x"$ac_cv_member_struct_sockaddr_storage_ss_family" != x"yes"; then +AC_CHECK_MEMBER(struct sockaddr_storage.__ss_family, + AC_DEFINE(HAVE___SS_FAMILY, 1, [Defined if struct sockaddr_storage has __ss_family field]),, + [ +#include +#include +#include + ]) +fi +fi + AC_CHECK_FUNCS(seteuid setresuid setegid setresgid chroot bzero strerror) AC_CHECK_FUNCS(vsyslog setlinebuf mktime ftruncate chsize rename) AC_CHECK_FUNCS(waitpid strlcpy strlcat initgroups memmove strdup) diff --git a/source3/lib/replace/system/network.h b/source3/lib/replace/system/network.h index b6ae3c7c6f..2f387de5cf 100644 --- a/source3/lib/replace/system/network.h +++ b/source3/lib/replace/system/network.h @@ -227,9 +227,18 @@ typedef unsigned short int sa_family_t; #ifdef HAVE_STRUCT_SOCKADDR_IN6 #define sockaddr_storage sockaddr_in6 #define ss_family sin6_family +#define HAVE_SS_FAMILY 1 #else #define sockaddr_storage sockaddr_in #define ss_family sin_family +#define HAVE_SS_FAMILY 1 +#endif +#endif + +#ifndef HAVE_SS_FAMILY +#ifdef HAVE___SS_FAMILY +#define ss_family __ss_family +#define HAVE_SS_FAMILY 1 #endif #endif -- cgit From f8ad02305fca3357e924c9c0e462b05b1452ae16 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 13 Jan 2008 04:46:11 +0100 Subject: Try to fix the build on Tru64; avoid single quotes because they get expanded by perl in the build system. (cherry picked from commit bba8914af56cb161c275fbbdea2479d6f8bd703c) (This used to be commit a0e663ff2c6548e48c9710e3fb314f3bbabb59d0) --- source3/lib/replace/libreplace_ld.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/replace/libreplace_ld.m4 b/source3/lib/replace/libreplace_ld.m4 index cb8e21434e..0ca6f7a34d 100644 --- a/source3/lib/replace/libreplace_ld.m4 +++ b/source3/lib/replace/libreplace_ld.m4 @@ -265,7 +265,7 @@ AC_DEFUN([AC_LIBREPLACE_LD_SHLIB_ALLOW_UNDEF_FLAG], LD_SHLIB_ALLOW_UNDEF_FLAG="-Wl,--allow-shlib-undefined" ;; *osf*) - LD_SHLIB_ALLOW_UNDEF_FLAG="-expect_unresolved '*'" + LD_SHLIB_ALLOW_UNDEF_FLAG="-Wl,-expect_unresolved,*" ;; *darwin*) LD_SHLIB_ALLOW_UNDEF_FLAG="-undefined dynamic_lookup" -- cgit From a0e04a94170ffb54e8a809ed869a08af898fb723 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Jan 2008 22:24:07 +0100 Subject: libreplace: Escape asterisk. (cherry picked from commit df36c78549b40ee5e47d5cc79de2eb79f58c567a) (This used to be commit 174a45ec18fff064d89f6a12b044973ab3c10c54) --- source3/lib/replace/libreplace_ld.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/replace/libreplace_ld.m4 b/source3/lib/replace/libreplace_ld.m4 index 0ca6f7a34d..2aec698967 100644 --- a/source3/lib/replace/libreplace_ld.m4 +++ b/source3/lib/replace/libreplace_ld.m4 @@ -265,7 +265,7 @@ AC_DEFUN([AC_LIBREPLACE_LD_SHLIB_ALLOW_UNDEF_FLAG], LD_SHLIB_ALLOW_UNDEF_FLAG="-Wl,--allow-shlib-undefined" ;; *osf*) - LD_SHLIB_ALLOW_UNDEF_FLAG="-Wl,-expect_unresolved,*" + LD_SHLIB_ALLOW_UNDEF_FLAG="-Wl,-expect_unresolved,\"*\"" ;; *darwin*) LD_SHLIB_ALLOW_UNDEF_FLAG="-undefined dynamic_lookup" -- cgit From db449a4c5f807b11ec723b11a2db32d09162e163 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Jan 2008 16:34:06 +0100 Subject: Revert "Host SerNet-AIX has __ss_family instead of ss_family in sockaddr_storage" This reverts commit e33286f4a68352e55df081d06307f64f190773b3. 393bab185e0e9f02aac5740becc2aba2762133c8 is the v4-0-test fix for the same problem. metze (This used to be commit b8a57a24c390355c4950ca499c1d96aff80abad7) --- source3/lib/replace/system/network.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/replace/system/network.h b/source3/lib/replace/system/network.h index 2f387de5cf..fe6e46817f 100644 --- a/source3/lib/replace/system/network.h +++ b/source3/lib/replace/system/network.h @@ -242,10 +242,6 @@ typedef unsigned short int sa_family_t; #endif #endif -#ifdef HAVE_AIX_SOCKADDR_STORAGE -#define ss_family __ss_family -#endif - #ifndef HAVE_STRUCT_ADDRINFO #define HAVE_STRUCT_ADDRINFO struct addrinfo { -- cgit From 805caafd44cbc5fff49711b1a15fb64cc99f3ad3 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Sat, 19 Jan 2008 02:12:35 +0100 Subject: util_str: Don't return memory from talloc_tos(), use mem_ctx instead. (This used to be commit ab0ee6e9a6a9eee317228f0c2bde254ad9a59b85) --- source3/lib/afs.c | 23 +++++++++++++---------- source3/lib/util_str.c | 6 +++--- 2 files changed, 16 insertions(+), 13 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/afs.c b/source3/lib/afs.c index a7d6f6c9f7..b3d590bf24 100644 --- a/source3/lib/afs.c +++ b/source3/lib/afs.c @@ -42,20 +42,23 @@ static char *afs_encode_token(const char *cell, const DATA_BLOB ticket, const struct ClearToken *ct) { char *base64_ticket; - char *result; + char *result = NULL; DATA_BLOB key = data_blob(ct->HandShakeKey, 8); char *base64_key; + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_init("afs_encode_token"); + if (mem_ctx == NULL) + goto done; - base64_ticket = base64_encode_data_blob(ticket); + base64_ticket = base64_encode_data_blob(mem_ctx, ticket); if (base64_ticket == NULL) - return NULL; + goto done; - base64_key = base64_encode_data_blob(key); - if (base64_key == NULL) { - TALLOC_FREE(base64_ticket); - return NULL; - } + base64_key = base64_encode_data_blob(mem_ctx, key); + if (base64_key == NULL) + goto done; asprintf(&result, "%s\n%u\n%s\n%u\n%u\n%u\n%s\n", cell, ct->AuthHandle, base64_key, ct->ViceId, ct->BeginTimestamp, @@ -63,8 +66,8 @@ static char *afs_encode_token(const char *cell, const DATA_BLOB ticket, DEBUG(10, ("Got ticket string:\n%s\n", result)); - TALLOC_FREE(base64_ticket); - TALLOC_FREE(base64_key); +done: + TALLOC_FREE(mem_ctx); return result; } diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 3e3268104c..bcb9197141 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -2415,13 +2415,13 @@ void base64_decode_inplace(char *s) } /** - * Encode a base64 string into a malloc()ed string caller to free. + * Encode a base64 string into a talloc()ed string caller to free. * * From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c * with adjustments **/ -char *base64_encode_data_blob(DATA_BLOB data) +char *base64_encode_data_blob(TALLOC_CTX *mem_ctx, DATA_BLOB data) { int bits = 0; int char_count = 0; @@ -2434,7 +2434,7 @@ char *base64_encode_data_blob(DATA_BLOB data) out_cnt = 0; len = data.length; output_len = data.length * 2; - result = TALLOC_ARRAY(talloc_tos(), char, output_len); /* get us plenty of space */ + result = TALLOC_ARRAY(mem_ctx, char, output_len); /* get us plenty of space */ SMB_ASSERT(result != NULL); while (len-- && out_cnt < (data.length * 2) - 5) { -- cgit From 398c323f7544e815cfeb2b750f9ff28061c294f3 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Sat, 19 Jan 2008 12:27:31 +0100 Subject: afs: Use talloc_stackframe() instead of talloc_init() Thanks to vl for pointing this out. (This used to be commit 76cf5a979bf3014b1de660520e538546b3676b23) --- source3/lib/afs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/afs.c b/source3/lib/afs.c index b3d590bf24..9f5d81f442 100644 --- a/source3/lib/afs.c +++ b/source3/lib/afs.c @@ -48,7 +48,7 @@ static char *afs_encode_token(const char *cell, const DATA_BLOB ticket, char *base64_key; TALLOC_CTX *mem_ctx; - mem_ctx = talloc_init("afs_encode_token"); + mem_ctx = talloc_stackframe(); if (mem_ctx == NULL) goto done; -- cgit From a0bd9d97a3a701fdb1f9a48ce925f63b786a8070 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 19 Jan 2008 15:14:45 +0100 Subject: Tiny memory leak in lib/version.c Hi, while implementing the extra_info version stuff, it occured to me that samba_version_string() potentially allocates memory which is unused but never free'd. If SAMBA_VERSION_VENDOR_PATCH is defined, a second call to asprintf takes place. The result is stored in tmp_version. Afterwards, samba_version is set to tmp_version without free'ing samba_version first. Looks like a simple free(samba_version) is missing. Patch against 3.2-test below. Ok, this only happens once over the lifetime of the application, so it's no big deal, but I though it doesn't hurt to mention it. Corinna * lib/version.c (samba_version_string): Free samba_version before setting to tmp_version. (This used to be commit 373a23d48f2dd24e65dbf814ea58b4add2322128) --- source3/lib/version.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/lib') diff --git a/source3/lib/version.c b/source3/lib/version.c index 204c2044a8..cbb70ae8a6 100644 --- a/source3/lib/version.c +++ b/source3/lib/version.c @@ -51,6 +51,7 @@ const char *samba_version_string(void) */ assert(res != -1); + free(samba_version); samba_version = tmp_version; #endif -- cgit From 07e07f696ad10f3a5d7a0d9de656ff13600ac97d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Jan 2008 19:31:02 +0100 Subject: Use SAFE_FREE instead of free (This used to be commit 999647329028147d7c29a3348202641b3e03430e) --- source3/lib/version.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/version.c b/source3/lib/version.c index cbb70ae8a6..3cae02ad2e 100644 --- a/source3/lib/version.c +++ b/source3/lib/version.c @@ -51,7 +51,8 @@ const char *samba_version_string(void) */ assert(res != -1); - free(samba_version); + SAFE_FREE(samba_version); + samba_version = tmp_version; #endif -- cgit From 14e7c292bc76b0edb8cafcaa728a612fa806fa6d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Jan 2008 22:44:55 +0100 Subject: Add an error mapping for ENOATTR (This used to be commit 9f0d778490415b05224f36287df999672ee16928) --- source3/lib/errmap_unix.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/errmap_unix.c b/source3/lib/errmap_unix.c index 885a1c55b2..8194cf80cc 100644 --- a/source3/lib/errmap_unix.c +++ b/source3/lib/errmap_unix.c @@ -92,6 +92,9 @@ const struct unix_error_map unix_dos_nt_errmap[] = { #ifdef EWOULDBLOCK { EWOULDBLOCK, ERRDOS, 111, NT_STATUS_NETWORK_BUSY }, #endif +#ifdef ENOATTR + { ENOATTR, ERRDOS, ERRbadfile, NT_STATUS_NOT_FOUND }, +#endif { 0, 0, 0, NT_STATUS_OK } }; -- cgit From 2411c6cb90e485bd289b8b654db1c632556bfb2d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Jan 2008 23:10:09 +0100 Subject: Add "split_ntfs_stream_name()" together with a torture test (This used to be commit d813bd9e02d9baf916eb96c478be89f0c435e07c) --- source3/lib/util.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/util.c b/source3/lib/util.c index bc3eaa8d5e..11f3660df8 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -3273,3 +3273,93 @@ void *talloc_zeronull(const void *context, size_t size, const char *name) return talloc_named_const(context, size, name); } #endif + +/* Split a path name into filename and stream name components. Canonicalise + * such that an implicit $DATA token is always explicit. + * + * The "specification" of this function can be found in the + * run_local_stream_name() function in torture.c, I've tried those + * combinations against a W2k3 server. + */ + +NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname, + char **pbase, char **pstream) +{ + char *base = NULL; + char *stream = NULL; + char *sname; /* stream name */ + const char *stype; /* stream type */ + + DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname)); + + sname = strchr_m(fname, ':'); + + if (lp_posix_pathnames() || (sname == NULL)) { + if (pbase != NULL) { + base = talloc_strdup(mem_ctx, fname); + NT_STATUS_HAVE_NO_MEMORY(base); + } + goto done; + } + + if (pbase != NULL) { + base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname)); + NT_STATUS_HAVE_NO_MEMORY(base); + } + + sname += 1; + + stype = strchr_m(sname, ':'); + + if (stype == NULL) { + sname = talloc_strdup(mem_ctx, sname); + stype = "$DATA"; + } + else { + if (StrCaseCmp(stype, ":$DATA") != 0) { + /* + * If there is an explicit stream type, so far we only + * allow $DATA. Is there anything else allowed? -- vl + */ + DEBUG(10, ("[%s] is an invalid stream type\n", stype)); + TALLOC_FREE(base); + return NT_STATUS_OBJECT_NAME_INVALID; + } + sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname)); + stype += 1; + } + + if (sname == NULL) { + TALLOC_FREE(base); + return NT_STATUS_NO_MEMORY; + } + + if (sname[0] == '\0') { + /* + * no stream name, so no stream + */ + goto done; + } + + if (pstream != NULL) { + stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype); + if (stream == NULL) { + TALLOC_FREE(sname); + TALLOC_FREE(base); + return NT_STATUS_NO_MEMORY; + } + /* + * upper-case the type field + */ + strupper_m(strchr_m(stream, ':')+1); + } + + done: + if (pbase != NULL) { + *pbase = base; + } + if (pstream != NULL) { + *pstream = stream; + } + return NT_STATUS_OK; +} -- cgit From 014bfd35f8c57370b27a1d07c335e2d9813a1333 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jan 2008 00:44:14 +0100 Subject: Some systems do not have XATTR_ defined (This used to be commit 2cac1d3919a96c480f34c93d8b9b07782d46ed23) --- source3/lib/system.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/system.c b/source3/lib/system.c index eb6dcae6fb..fa50955ef6 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -1917,11 +1917,6 @@ int sys_fremovexattr (int filedes, const char *name) #endif } -#if !defined(HAVE_SETXATTR) -#define XATTR_CREATE 0x1 /* set value, fail if attr already exists */ -#define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */ -#endif - int sys_setxattr (const char *path, const char *name, const void *value, size_t size, int flags) { #if defined(HAVE_SETXATTR) -- cgit From 33f3eeaa00974860dfc45962d5fd34cf05396c76 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jan 2008 17:35:25 +0100 Subject: Fix some "set but never used" warnings (This used to be commit 4a6dadc5178f4861e9c032321939db3b639734b5) --- source3/lib/dbwrap_tdb.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/dbwrap_tdb.c b/source3/lib/dbwrap_tdb.c index e87ceb428f..18f9495931 100644 --- a/source3/lib/dbwrap_tdb.c +++ b/source3/lib/dbwrap_tdb.c @@ -91,7 +91,6 @@ static struct db_record *db_tdb_fetch_locked(struct db_context *db, struct db_tdb_ctx *ctx = talloc_get_type_abort(db->private_data, struct db_tdb_ctx); struct tdb_fetch_locked_state state; - int res; /* Do not accidently allocate/deallocate w/o need when debug level is lower than needed */ if(DEBUGLEVEL >= 10) { @@ -110,8 +109,7 @@ static struct db_record *db_tdb_fetch_locked(struct db_context *db, state.mem_ctx = mem_ctx; state.result = NULL; - res = tdb_parse_record(ctx->wtdb->tdb, key, db_tdb_fetchlock_parse, - &state); + tdb_parse_record(ctx->wtdb->tdb, key, db_tdb_fetchlock_parse, &state); if (state.result == NULL) { db_tdb_fetchlock_parse(key, tdb_null, &state); -- cgit From 99dfd664881f92dd1972f872c7471c5665869b86 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 21 Jan 2008 00:40:10 +0100 Subject: Rename lib/util_reg_smbconf.c to registry/reg_init_smbconf.c This actually is a counterpart to reg_init_full, in that is does open and initialize the registry too, but only registeres the backends necessary to access the SMBCONF key. Michael (This used to be commit 01bda3ab359fb3868c1dc849044f613bf2bc563e) --- source3/lib/util_reg_smbconf.c | 97 ------------------------------------------ 1 file changed, 97 deletions(-) delete mode 100644 source3/lib/util_reg_smbconf.c (limited to 'source3/lib') diff --git a/source3/lib/util_reg_smbconf.c b/source3/lib/util_reg_smbconf.c deleted file mode 100644 index 6452b0b15b..0000000000 --- a/source3/lib/util_reg_smbconf.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * Registry helper routines - * Copyright (C) Michael Adam 2007 - * - * 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 3 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, see . - */ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_REGISTRY - -extern REGISTRY_OPS smbconf_reg_ops; - -/* - * create a fake token just with enough rights to - * locally access the registry: - * - * - builtin administrators sid - * - disk operators privilege - */ -NTSTATUS registry_create_admin_token(TALLOC_CTX *mem_ctx, - NT_USER_TOKEN **ptoken) -{ - NTSTATUS status; - NT_USER_TOKEN *token = NULL; - - if (ptoken == NULL) { - return NT_STATUS_INVALID_PARAMETER; - } - - token = TALLOC_ZERO_P(mem_ctx, NT_USER_TOKEN); - if (token == NULL) { - DEBUG(1, ("talloc failed\n")); - status = NT_STATUS_NO_MEMORY; - goto done; - } - token->privileges = se_disk_operators; - status = add_sid_to_array(token, &global_sid_Builtin_Administrators, - &token->user_sids, &token->num_sids); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Error adding builtin administrators sid " - "to fake token.\n")); - goto done; - } - - *ptoken = token; - -done: - return status; -} - -/* - * init the smbconf portion of the registry. - * for use in places where not the whole registry is needed, - * e.g. utils/net_conf.c and loadparm.c - */ -bool registry_init_regdb(void) -{ - bool ret = false; - int saved_errno = 0; - static REGISTRY_HOOK smbconf_reg_hook = {KEY_SMBCONF, &smbconf_reg_ops}; - - DEBUG(10, ("registry_init_regdb called\n")); - - if (!regdb_init()) { - saved_errno = errno; - DEBUG(1, ("Can't open the registry")); - if (saved_errno) { - DEBUGADD(1, (": %s", strerror(saved_errno))); - } - DEBUGADD(1, (".\n")); - goto done; - } - reghook_cache_init(); - if (!reghook_cache_add(&smbconf_reg_hook)) { - DEBUG(1, ("Error adding smbconf reghooks to reghook cache.\n")); - goto done; - } - - ret = true; - -done: - return ret; -} -- cgit From 7b6a439efe8a077bf333a9badde021eb9a54b227 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Mon, 21 Jan 2008 13:18:38 +0100 Subject: util_sock: Fix memcache bug in get_mydnsfullname. get_mydnsfullname relied on memcache_add(); memcache_lookup() working. When run from ntlm_auth, the global_cache variable in memcache is NULL, so the add and lookup both fail. In that case, just return the result of the getaddrinfo call. Jeremy, please check. (This used to be commit 1db41ff52565e9f336a22fb9ffd80d51677e023b) --- source3/lib/util_sock.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 10428113ae..f524d0d826 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -2080,14 +2080,14 @@ const char *get_mydnsfullname(void) data_blob_string_const("get_mydnsfullname"), data_blob_string_const(res->ai_canonname)); - freeaddrinfo(res); - if (!memcache_lookup(NULL, SINGLETON_CACHE, data_blob_string_const("get_mydnsfullname"), &tmp)) { - return NULL; + tmp = data_blob_string_const(res->ai_canonname); } + freeaddrinfo(res); + return (const char *)tmp.data; } -- cgit From 36e3e75e0683eb9fd14d8a282d9a2324f01fddf7 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Mon, 21 Jan 2008 18:01:55 +0100 Subject: util_sock: Don't return a pointer to freed memory. Fix a bug in my bugfix. Thanks to vl for spotting that one. (This used to be commit 24f68b90cca111256a7b03f7062cb57c2b08a0d6) --- source3/lib/util_sock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index f524d0d826..a3975f6c1f 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -2083,7 +2083,8 @@ const char *get_mydnsfullname(void) if (!memcache_lookup(NULL, SINGLETON_CACHE, data_blob_string_const("get_mydnsfullname"), &tmp)) { - tmp = data_blob_string_const(res->ai_canonname); + tmp = data_blob_talloc(talloc_tos(), res->ai_canonname, + strlen(res->ai_canonname) + 1); } freeaddrinfo(res); -- cgit From f5df4a100accd163dcd4f41e3bbcd17bb655d1fe Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 Jan 2008 12:21:55 +0100 Subject: libreplace: getpwent_r/getgrent_r on IRIX are similar to solaris but use size_t metze (This used to be commit 2f460915111066d79f5dc9b4ae4d003918d06852) --- source3/lib/replace/system/config.m4 | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/replace/system/config.m4 b/source3/lib/replace/system/config.m4 index 799187af7d..1c05733126 100644 --- a/source3/lib/replace/system/config.m4 +++ b/source3/lib/replace/system/config.m4 @@ -73,6 +73,18 @@ AC_VERIFY_C_PROTOTYPE([struct passwd *getpwent_r(struct passwd *src, char *buf, #include #include ]) +AC_VERIFY_C_PROTOTYPE([struct passwd *getpwent_r(struct passwd *src, char *buf, size_t buflen)], + [ + #ifndef HAVE_GETPWENT_R_DECL + #error missing getpwent_r prototype + #endif + return NULL; + ],[ + AC_DEFINE(SOLARIS_GETPWENT_R, 1, [getpwent_r irix (similar to solaris) function prototype]) + ],[],[ + #include + #include + ]) AC_CHECK_FUNCS(getgrnam_r getgrgid_r getgrent_r) AC_HAVE_DECL(getgrent_r, [ #include @@ -91,6 +103,19 @@ AC_VERIFY_C_PROTOTYPE([struct group *getgrent_r(struct group *src, char *buf, in #include ]) +AC_VERIFY_C_PROTOTYPE([struct group *getgrent_r(struct group *src, char *buf, size_t buflen)], + [ + #ifndef HAVE_GETGRENT_R_DECL + #error missing getgrent_r prototype + #endif + return NULL; + ],[ + AC_DEFINE(SOLARIS_GETGRENT_R, 1, [getgrent_r irix (similar to solaris) function prototype]) + ],[],[ + #include + #include + ]) + # locale AC_CHECK_HEADERS(ctype.h locale.h) -- cgit From 559603ad693ede382c566cb8bbd8e6bd8d5750a6 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 22 Jan 2008 11:33:17 +0100 Subject: Get Samba version or capability information from Windows On Jan 21 16:18, Danilo Almeida wrote: > Corina wrote: > > > + time_t samba_gitcommitdate; > > And: > > > + SIVAL(pdata,28,extended_info.samba_gitcommitdate); > > + memcpy(pdata+32,extended_info.samba_version_string,32); > > Note that you are dropping bits on a system w/64-bit time_t, and that this has the 2038 problem. Right. I changed samba_gitcommitdate from time_t to NTTIME and shortened samba_version_string to 28 bytes. New patch below. Thanks, Corinna (This used to be commit 28aa1c199d3a22cda34afcaab49c0561eeb0abcb) --- source3/lib/version.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/version.c b/source3/lib/version.c index 3cae02ad2e..38c4f45ac6 100644 --- a/source3/lib/version.c +++ b/source3/lib/version.c @@ -59,3 +59,32 @@ const char *samba_version_string(void) return samba_version; #endif } + +void samba_extended_info_version(struct smb_extended_info *extended_info) +{ + assert(extended_info != NULL); + + extended_info->samba_magic = SAMBA_EXTENDED_INFO_MAGIC; + extended_info->samba_version = ((SAMBA_VERSION_MAJOR & 0xff) << 24) + | ((SAMBA_VERSION_MINOR & 0xff) << 16) + | ((SAMBA_VERSION_RELEASE & 0xff) << 8); +#ifdef SAMBA_VERSION_REVISION + extended_info->samba_version |= (tolower(*SAMBA_VERSION_REVISION) - 'a' + 1) & 0xff; +#endif +#ifdef SAMBA_VERSION_RC_RELEASE + extended_info->samba_subversion |= (SAMBA_VERSION_RC_RELEASE & 0xff) << 24; +#else +#ifdef SAMBA_VERSION_PRE_RELEASE + extended_info->samba_subversion |= (SAMBA_VERSION_PRE_RELEASE & 0xff) << 16; +#endif +#endif +#ifdef SAMBA_VERSION_VENDOR_PATCH + extended_info->samba_subversion |= (SAMBA_VERSION_VENDOR_PATCH & 0xffff); +#endif + /* FIXME: samba_gitcommitdate should contain the git commit date. */ + unix_to_nt_time(&extended_info->samba_gitcommitdate, time(NULL)); + + snprintf (extended_info->samba_version_string, + SAMBA_EXTENDED_INFO_VERSION_STRING_LENGTH, + "%s", samba_version_string()); +} -- cgit From 1d99598ca3f21dd863c8d63698f8af2b3b77759b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 22 Jan 2008 12:46:51 +0100 Subject: Avoid use of uninitialized memory (This used to be commit 85123aacdb13e97c3f44aeded1c80e13af53d83d) --- source3/lib/version.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/version.c b/source3/lib/version.c index 38c4f45ac6..dff45f6259 100644 --- a/source3/lib/version.c +++ b/source3/lib/version.c @@ -84,7 +84,10 @@ void samba_extended_info_version(struct smb_extended_info *extended_info) /* FIXME: samba_gitcommitdate should contain the git commit date. */ unix_to_nt_time(&extended_info->samba_gitcommitdate, time(NULL)); + memset(extended_info->samba_version_string, 0, + sizeof(extended_info->samba_version_string)); + snprintf (extended_info->samba_version_string, - SAMBA_EXTENDED_INFO_VERSION_STRING_LENGTH, + sizeof(extended_info->samba_version_string), "%s", samba_version_string()); } -- cgit From d4d962f691d13f36226157c38f706ee4d10b9150 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 22 Jan 2008 13:00:22 +0100 Subject: Move samba_extended_info_version to smbd/trans2.c This is right now only used there, and in version.c it gave linker errors because some binaries (e.g. smbmnt) don't link in time.o (This used to be commit 1f0eaaa5911f893c822465a26fe49ab65afb0730) --- source3/lib/version.c | 32 -------------------------------- 1 file changed, 32 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/version.c b/source3/lib/version.c index dff45f6259..3cae02ad2e 100644 --- a/source3/lib/version.c +++ b/source3/lib/version.c @@ -59,35 +59,3 @@ const char *samba_version_string(void) return samba_version; #endif } - -void samba_extended_info_version(struct smb_extended_info *extended_info) -{ - assert(extended_info != NULL); - - extended_info->samba_magic = SAMBA_EXTENDED_INFO_MAGIC; - extended_info->samba_version = ((SAMBA_VERSION_MAJOR & 0xff) << 24) - | ((SAMBA_VERSION_MINOR & 0xff) << 16) - | ((SAMBA_VERSION_RELEASE & 0xff) << 8); -#ifdef SAMBA_VERSION_REVISION - extended_info->samba_version |= (tolower(*SAMBA_VERSION_REVISION) - 'a' + 1) & 0xff; -#endif -#ifdef SAMBA_VERSION_RC_RELEASE - extended_info->samba_subversion |= (SAMBA_VERSION_RC_RELEASE & 0xff) << 24; -#else -#ifdef SAMBA_VERSION_PRE_RELEASE - extended_info->samba_subversion |= (SAMBA_VERSION_PRE_RELEASE & 0xff) << 16; -#endif -#endif -#ifdef SAMBA_VERSION_VENDOR_PATCH - extended_info->samba_subversion |= (SAMBA_VERSION_VENDOR_PATCH & 0xffff); -#endif - /* FIXME: samba_gitcommitdate should contain the git commit date. */ - unix_to_nt_time(&extended_info->samba_gitcommitdate, time(NULL)); - - memset(extended_info->samba_version_string, 0, - sizeof(extended_info->samba_version_string)); - - snprintf (extended_info->samba_version_string, - sizeof(extended_info->samba_version_string), - "%s", samba_version_string()); -} -- cgit From a60b913a37d577d6bb52fbdb0987eb7c9ea9edcc Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 23 Jan 2008 00:30:28 +0100 Subject: Fix tab_depth: it should not create an extra debug header. In pstring removal 4ae4b23586, the behaviour of tab_depth was changed to create an extra debug header (by using the DEBUGLVL macro). This extracts the debug level check from DEBUGLVL into a macro CHECK_DEBUGLVL without the debug header creation and uses this instead of DEBUGLVL in tab_depth. Michael (This used to be commit cbc7d921fa696e6c3c5197ad9f87442ba679df82) --- source3/lib/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/util.c b/source3/lib/util.c index 11f3660df8..e5ac3752f5 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -2182,7 +2182,7 @@ void dump_data_pw(const char *msg, const uchar * data, size_t len) const char *tab_depth(int level, int depth) { - if( DEBUGLVL(level) ) { + if( CHECK_DEBUGLVL(level) ) { dbgtext("%*s", depth*4, ""); } return ""; -- cgit From 587cf54c61c9f1f7bcae431a82035fd942716c32 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 23 Jan 2008 11:04:10 +0100 Subject: strtok -> strtok_r (This used to be commit fd34ce437057bb34cdc37f4b066e424000d36789) --- source3/lib/afs_settoken.c | 29 +++++++++++++++-------------- source3/lib/debug.c | 5 +++-- 2 files changed, 18 insertions(+), 16 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/afs_settoken.c b/source3/lib/afs_settoken.c index aeef1c3520..444f09efca 100644 --- a/source3/lib/afs_settoken.c +++ b/source3/lib/afs_settoken.c @@ -53,20 +53,21 @@ static bool afs_decode_token(const char *string, char **cell, { DATA_BLOB blob; struct ClearToken result_ct; + char *saveptr; char *s = SMB_STRDUP(string); char *t; - if ((t = strtok(s, "\n")) == NULL) { - DEBUG(10, ("strtok failed\n")); + if ((t = strtok_r(s, "\n", &saveptr)) == NULL) { + DEBUG(10, ("strtok_r failed\n")); return False; } *cell = SMB_STRDUP(t); - if ((t = strtok(NULL, "\n")) == NULL) { - DEBUG(10, ("strtok failed\n")); + if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) { + DEBUG(10, ("strtok_r failed\n")); return False; } @@ -75,8 +76,8 @@ static bool afs_decode_token(const char *string, char **cell, return False; } - if ((t = strtok(NULL, "\n")) == NULL) { - DEBUG(10, ("strtok failed\n")); + if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) { + DEBUG(10, ("strtok_r failed\n")); return False; } @@ -93,8 +94,8 @@ static bool afs_decode_token(const char *string, char **cell, data_blob_free(&blob); - if ((t = strtok(NULL, "\n")) == NULL) { - DEBUG(10, ("strtok failed\n")); + if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) { + DEBUG(10, ("strtok_r failed\n")); return False; } @@ -103,8 +104,8 @@ static bool afs_decode_token(const char *string, char **cell, return False; } - if ((t = strtok(NULL, "\n")) == NULL) { - DEBUG(10, ("strtok failed\n")); + if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) { + DEBUG(10, ("strtok_r failed\n")); return False; } @@ -113,8 +114,8 @@ static bool afs_decode_token(const char *string, char **cell, return False; } - if ((t = strtok(NULL, "\n")) == NULL) { - DEBUG(10, ("strtok failed\n")); + if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) { + DEBUG(10, ("strtok_r failed\n")); return False; } @@ -123,8 +124,8 @@ static bool afs_decode_token(const char *string, char **cell, return False; } - if ((t = strtok(NULL, "\n")) == NULL) { - DEBUG(10, ("strtok failed\n")); + if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) { + DEBUG(10, ("strtok_r failed\n")); return False; } diff --git a/source3/lib/debug.c b/source3/lib/debug.c index 6c1bfea04f..51bb0d7541 100644 --- a/source3/lib/debug.c +++ b/source3/lib/debug.c @@ -429,8 +429,9 @@ static bool debug_parse_params(char **params) /* Fill in new debug class levels */ for (; i < debug_num_classes && params[i]; i++) { - if ((class_name=strtok(params[i],":")) && - (class_level=strtok(NULL, "\0")) && + char *saveptr; + if ((class_name = strtok_r(params[i],":", &saveptr)) && + (class_level = strtok_r(NULL, "\0", &saveptr)) && ((ndx = debug_lookup_classname(class_name)) != -1)) { DEBUGLEVEL_CLASS[ndx] = atoi(class_level); DEBUGLEVEL_CLASS_ISSET[ndx] = True; -- cgit From a925a53f61ebdc6b4386b7c0853f2f87cbe2e166 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 23 Jan 2008 16:42:31 +0100 Subject: read_socket_with_timeout has timeout=0 handling (This used to be commit 7101026061c470ed962267b43ac0aa67cc761a64) --- source3/lib/util_sock.c | 39 +-------------------------------------- 1 file changed, 1 insertion(+), 38 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index a3975f6c1f..fb8f41513b 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1054,44 +1054,7 @@ ssize_t read_socket_with_timeout(int fd, ssize_t read_data(int fd,char *buffer,size_t N, enum smb_read_errors *pre) { - ssize_t ret; - size_t total=0; - char addr[INET6_ADDRSTRLEN]; - - set_smb_read_error(pre,SMB_READ_OK); - - while (total < N) { - ret = sys_read(fd,buffer + total,N - total); - - if (ret == 0) { - DEBUG(10,("read_data: read of %d returned 0. " - "Error = %s\n", - (int)(N - total), strerror(errno) )); - set_smb_read_error(pre,SMB_READ_EOF); - return 0; - } - - if (ret == -1) { - if (fd == get_client_fd()) { - /* Try and give an error message saying - * what client failed. */ - DEBUG(0,("read_data: read failure for %d " - "bytes to client %s. Error = %s\n", - (int)(N - total), - get_peer_addr(fd,addr,sizeof(addr)), - strerror(errno) )); - } else { - DEBUG(0,("read_data: read failure for %d. " - "Error = %s\n", - (int)(N - total), - strerror(errno) )); - } - set_smb_read_error(pre,SMB_READ_ERROR); - return -1; - } - total += ret; - } - return (ssize_t)total; + return read_socket_with_timeout(fd, buffer, N, N, 0, pre); } /**************************************************************************** -- cgit From 9344628bef74ac759197601dc5dd44514b836e3e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 23 Jan 2008 17:37:59 +0100 Subject: More read_data -> read_socket_with_timeout (This used to be commit f1d7de462cf0f64648a3a1fc6f0c64a7bbdb3c2a) --- source3/lib/util_sock.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index fb8f41513b..1a7cc02229 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1126,12 +1126,7 @@ ssize_t read_smb_length_return_keepalive(int fd, bool ok = false; while (!ok) { - if (timeout > 0) { - ok = (read_socket_with_timeout(fd,inbuf,4,4, - timeout,pre) == 4); - } else { - ok = (read_data(fd,inbuf,4,pre) == 4); - } + ok = (read_socket_with_timeout(fd,inbuf,4,4,timeout,pre) == 4); if (!ok) { return -1; } @@ -1237,16 +1232,8 @@ ssize_t receive_smb_raw(int fd, len = MIN(len,maxlen); } - if (timeout > 0) { - ret = read_socket_with_timeout(fd, - buffer+4, - len, - len, - timeout, - pre); - } else { - ret = read_data(fd,buffer+4,len,pre); - } + ret = read_socket_with_timeout(fd, buffer+4, len, len, timeout, + pre); if (ret != len) { cond_set_smb_read_error(pre,SMB_READ_ERROR); -- cgit From a30361ede36af7ef9d8f6d723798a07b360c813b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 25 Jan 2008 15:45:38 +0100 Subject: No need to close registry on libnetapi_free() anymore. Guenther (This used to be commit 6bf75652ef07f5a534cef5034b7aad4fdcbcd265) --- source3/lib/netapi/netapi.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c index 5c3f7ec465..47b3ba93cf 100644 --- a/source3/lib/netapi/netapi.c +++ b/source3/lib/netapi/netapi.c @@ -119,7 +119,6 @@ NET_API_STATUS libnetapi_free(struct libnetapi_ctx *ctx) gencache_shutdown(); secrets_shutdown(); - regdb_close(); TALLOC_FREE(ctx); TALLOC_FREE(frame); -- cgit From c04b738a136485a8f1df21fbccd1c418ee6fd444 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 25 Jan 2008 15:46:11 +0100 Subject: Add LIBNETAPI_LOCAL_SERVER() macro. Guenther (This used to be commit 4bdcf07bcc3aaf7c3f7245cfdda06433bcf4ae60) --- source3/lib/netapi/netapi.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h index c2f1b488db..002fc37762 100644 --- a/source3/lib/netapi/netapi.h +++ b/source3/lib/netapi/netapi.h @@ -36,6 +36,11 @@ /**************************************************************** ****************************************************************/ +#define LIBNETAPI_LOCAL_SERVER(x) (!x || is_myname_or_ipaddr(x)) + +/**************************************************************** +****************************************************************/ + struct libnetapi_ctx { char *debuglevel; char *error_string; -- cgit From 31a6f807842259ded10dff549f2f57d77ee79c6e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Jan 2008 09:21:44 +0100 Subject: Remove a pointless while loop (This used to be commit f591bd68eafdbaefcaa95510cc4cb9a74cef0562) --- source3/lib/util_sock.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 1a7cc02229..ce1569d021 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1123,20 +1123,16 @@ ssize_t read_smb_length_return_keepalive(int fd, { ssize_t len=0; int msg_type; - bool ok = false; - while (!ok) { - ok = (read_socket_with_timeout(fd,inbuf,4,4,timeout,pre) == 4); - if (!ok) { - return -1; - } + if (read_socket_with_timeout(fd, inbuf, 4, 4, timeout, pre) != 4) { + return -1; + } - len = smb_len(inbuf); - msg_type = CVAL(inbuf,0); + len = smb_len(inbuf); + msg_type = CVAL(inbuf,0); - if (msg_type == SMBkeepalive) { - DEBUG(5,("Got keepalive packet\n")); - } + if (msg_type == SMBkeepalive) { + DEBUG(5,("Got keepalive packet\n")); } DEBUG(10,("got smb length of %lu\n",(unsigned long)len)); -- cgit From e2ad28509c4e31fa4d397290b61e376d55e3abb2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Jan 2008 09:28:19 +0100 Subject: Tiny simplification (This used to be commit e78f6872bfc19ce0476b8d79c856a8d9c646a913) --- source3/lib/util_sock.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index ce1569d021..ced1130536 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -1150,16 +1150,15 @@ ssize_t read_smb_length_return_keepalive(int fd, ssize_t read_smb_length(int fd, char *inbuf, unsigned int timeout, enum smb_read_errors *pre) { ssize_t len; + uint8_t msgtype = SMBkeepalive; - for(;;) { - len = read_smb_length_return_keepalive(fd, inbuf, timeout, pre); - - if(len < 0) + while (msgtype == SMBkeepalive) { + len = read_smb_length_return_keepalive(fd, inbuf, timeout, + pre); + if (len < 0) { return len; - - /* Ignore session keepalives. */ - if(CVAL(inbuf,0) != SMBkeepalive) - break; + } + msgtype = CVAL(inbuf, 0); } DEBUG(10,("read_smb_length: got smb length of %lu\n", -- cgit From 54db1839878641be1a9987ad3e0ddedbd6123b7c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 27 Jan 2008 17:31:56 +1100 Subject: Adding missing calls to va_end(). Just a small commit to get a handle on this git thingy. This patch fixes some missing calls to va_end() to match various calls to va_start() and VA_COPY(). Tim. (This used to be commit ec367f307dff7948722b9ac97beb960efd91991f) --- source3/lib/dprintf.c | 8 +++++++- source3/lib/util.c | 1 + source3/lib/util_tdb.c | 1 + source3/lib/xfile.c | 8 +++++++- 4 files changed, 16 insertions(+), 2 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/dprintf.c b/source3/lib/dprintf.c index 18b261623e..a3bb5be43a 100644 --- a/source3/lib/dprintf.c +++ b/source3/lib/dprintf.c @@ -47,7 +47,10 @@ lang_msg_free(msgstr); - if (ret <= 0) return ret; + if (ret <= 0) { + va_end(ap2); + return ret; + } /* now we have the string in unix format, convert it to the display charset, but beware of it growing */ @@ -56,6 +59,7 @@ again: p2 = (char *)SMB_MALLOC(maxlen); if (!p2) { SAFE_FREE(p); + va_end(ap2); return -1; } clen = convert_string(CH_UNIX, CH_DISPLAY, p, ret, p2, maxlen, True); @@ -72,6 +76,8 @@ again: ret = fwrite(p2, 1, clen, f); SAFE_FREE(p2); + va_end(ap2); + return ret; } diff --git a/source3/lib/util.c b/source3/lib/util.c index e5ac3752f5..dba7142bad 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -2431,6 +2431,7 @@ char *smb_xstrndup(const char *s, size_t n) if (n == -1 || ! *ptr) { smb_panic("smb_xvasprintf: out of memory"); } + va_end(ap2); return n; } diff --git a/source3/lib/util_tdb.c b/source3/lib/util_tdb.c index ce2cb427d1..dd5ebcd7ab 100644 --- a/source3/lib/util_tdb.c +++ b/source3/lib/util_tdb.c @@ -656,6 +656,7 @@ int tdb_unpack(const uint8 *buf, int bufsize, const char *fmt, ...) return PTR_DIFF(buf, buf0); no_space: + va_end(ap); return -1; } diff --git a/source3/lib/xfile.c b/source3/lib/xfile.c index c98522200b..ee6e581332 100644 --- a/source3/lib/xfile.c +++ b/source3/lib/xfile.c @@ -223,9 +223,15 @@ size_t x_fwrite(const void *p, size_t size, size_t nmemb, XFILE *f) VA_COPY(ap2, ap); len = vasprintf(&p, format, ap2); - if (len <= 0) return len; + if (len <= 0) { + va_end(ap2); + return len; + } ret = x_fwrite(p, 1, len, f); SAFE_FREE(p); + + va_end(ap2); + return ret; } -- cgit From fe478af26aacd1b3ae7e24c4c82e03f576d71691 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 27 Jan 2008 10:22:42 +0100 Subject: We need to leave the corepath around In case we need to dump core, in line 191 we dereference corepath to be able to chdir there. Jeremy, please check! Volker (This used to be commit 3959b1954b02405ec174497fa17e345ca6d5ee94) --- source3/lib/fault.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/lib') diff --git a/source3/lib/fault.c b/source3/lib/fault.c index 33e1401d7a..1964955f1b 100644 --- a/source3/lib/fault.c +++ b/source3/lib/fault.c @@ -132,7 +132,6 @@ void dump_core_setup(const char *progname) sys_chown(corepath,getuid(),getgid()); chmod(corepath,0700); - SAFE_FREE(corepath); SAFE_FREE(logbase); #ifdef HAVE_GETRLIMIT -- cgit From 5ab43ae0d8e66a1fd4c877089df52282367be7dd Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 26 Jan 2008 01:39:33 +0100 Subject: Eliminate remote tree of dsgetdcname (which will happen in libnetapi then). Guenther (This used to be commit fd490d236b1fb73a75c457b75128c9b98719418f) --- source3/lib/netapi/joindomain.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index 133aff3dd8..55f334b5e1 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -52,7 +52,7 @@ static WERROR NetJoinDomainLocal(struct libnetapi_ctx *mem_ctx, uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED | DS_WRITABLE_REQUIRED | DS_RETURN_DNS_NAME; - status = dsgetdcname(mem_ctx, NULL, domain_name, + status = dsgetdcname(mem_ctx, domain_name, NULL, NULL, flags, &info); if (!NT_STATUS_IS_OK(status)) { libnetapi_set_error_string(mem_ctx, @@ -261,7 +261,7 @@ static WERROR NetUnjoinDomainLocal(struct libnetapi_ctx *mem_ctx, } else { domain = lp_workgroup(); } - status = dsgetdcname(mem_ctx, NULL, domain, + status = dsgetdcname(mem_ctx, domain, NULL, NULL, flags, &info); if (!NT_STATUS_IS_OK(status)) { libnetapi_set_error_string(mem_ctx, @@ -566,7 +566,7 @@ static WERROR NetGetJoinableOUsLocal(struct libnetapi_ctx *ctx, uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED | DS_RETURN_DNS_NAME; - status = dsgetdcname(ctx, NULL, domain, + status = dsgetdcname(ctx, domain, NULL, NULL, flags, &info); if (!NT_STATUS_IS_OK(status)) { libnetapi_set_error_string(ctx, "%s", -- cgit From 6b5980e47e86df77e43324e705d8509dea4ac0d4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 31 Jan 2008 09:48:20 +1100 Subject: merged tdb transaction fix (This used to be commit 1a1c7954368a7f168a57f86f4f857cf70258e37a) --- source3/lib/tdb/common/transaction.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/tdb/common/transaction.c b/source3/lib/tdb/common/transaction.c index c3e7a4e2c0..4e2127be64 100644 --- a/source3/lib/tdb/common/transaction.c +++ b/source3/lib/tdb/common/transaction.c @@ -321,6 +321,9 @@ static int transaction_write_existing(struct tdb_context *tdb, tdb_off_t off, if (blk == tdb->transaction->num_blocks-1 && off + len > tdb->transaction->last_block_size) { + if (off >= tdb->transaction->last_block_size) { + return 0; + } len = tdb->transaction->last_block_size - off; } -- cgit From 2e0a1fcf3f461f134c910e83ab82115c00827231 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 31 Jan 2008 14:10:22 +0100 Subject: Re-run make idl. Guenther (This used to be commit b658270518140c457536b0c7db06a646d7077529) --- source3/lib/netapi/getdc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/lib') diff --git a/source3/lib/netapi/getdc.c b/source3/lib/netapi/getdc.c index 1084ddc3c8..2626eb0af4 100644 --- a/source3/lib/netapi/getdc.c +++ b/source3/lib/netapi/getdc.c @@ -69,8 +69,8 @@ static WERROR NetGetDCNameRemote(struct libnetapi_ctx *ctx, status = rpccli_netr_GetDcName(pipe_cli, ctx, server_name, domain_name, - (const char **)buffer); - werr = ntstatus_to_werror(status); + (const char **)buffer, + &werr); done: if (cli) { cli_shutdown(cli); -- cgit From 00075c49245d5f96139b7c09f37a2b39aa10559f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 1 Feb 2008 14:23:56 +0100 Subject: NetBSD does not support AI_ADDRCONFIG (This used to be commit fb3f7f4046fa195baf5116598772d9016238637f) --- source3/lib/replace/system/network.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/lib') diff --git a/source3/lib/replace/system/network.h b/source3/lib/replace/system/network.h index fe6e46817f..aff8a841da 100644 --- a/source3/lib/replace/system/network.h +++ b/source3/lib/replace/system/network.h @@ -137,8 +137,15 @@ const char *rep_inet_ntop(int af, const void *src, char *dst, socklen_t size); #endif #ifndef AI_ADDRCONFIG +/* + * logic copied from AI_NUMERICHOST + */ +#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO) +#define AI_ADDRCONFIG 0 +#else #define AI_ADDRCONFIG 0x0020 #endif +#endif #ifndef AI_NUMERICSERV /* -- cgit