summaryrefslogtreecommitdiff
path: root/source3/lib
diff options
context:
space:
mode:
Diffstat (limited to 'source3/lib')
-rw-r--r--source3/lib/dbwrap_ctdb.c32
-rw-r--r--source3/lib/idmap_cache.c260
-rw-r--r--source3/lib/interface.c7
-rw-r--r--source3/lib/util_str.c5
4 files changed, 285 insertions, 19 deletions
diff --git a/source3/lib/dbwrap_ctdb.c b/source3/lib/dbwrap_ctdb.c
index 7c1ef8fed8..63a5ce4de6 100644
--- a/source3/lib/dbwrap_ctdb.c
+++ b/source3/lib/dbwrap_ctdb.c
@@ -2,17 +2,17 @@
Unix SMB/CIFS implementation.
Database interface wrapper around ctdbd
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 <http://www.gnu.org/licenses/>.
*/
@@ -76,7 +76,7 @@ static NTSTATUS tdb_error_to_ntstatus(struct tdb_context *tdb)
/*
form a ctdb_rec_data record from a key/data pair
-
+
note that header may be NULL. If not NULL then it is included in the data portion
of the record
*/
@@ -130,7 +130,8 @@ static struct ctdb_marshall_buffer *db_ctdb_marshall_add(TALLOC_CTX *mem_ctx,
}
if (m == NULL) {
- m = talloc_zero_size(mem_ctx, offsetof(struct ctdb_marshall_buffer, data));
+ m = (struct ctdb_marshall_buffer *)talloc_zero_size(
+ mem_ctx, offsetof(struct ctdb_marshall_buffer, data));
if (m == NULL) {
return NULL;
}
@@ -140,7 +141,8 @@ static struct ctdb_marshall_buffer *db_ctdb_marshall_add(TALLOC_CTX *mem_ctx,
m_size = talloc_get_size(m);
r_size = talloc_get_size(r);
- m2 = talloc_realloc_size(mem_ctx, m, m_size + r_size);
+ m2 = (struct ctdb_marshall_buffer *)talloc_realloc_size(
+ mem_ctx, m, m_size + r_size);
if (m2 == NULL) {
talloc_free(m);
return NULL;
@@ -166,7 +168,7 @@ static TDB_DATA db_ctdb_marshall_finish(struct ctdb_marshall_buffer *m)
/*
loop over a marshalling buffer
-
+
- pass r==NULL to start
- loop the number of times indicated by m->count
*/
@@ -184,7 +186,7 @@ static struct ctdb_rec_data *db_ctdb_marshall_loop_next(struct ctdb_marshall_buf
if (reqid != NULL) {
*reqid = r->reqid;
}
-
+
if (key != NULL) {
key->dptr = &r->data[0];
key->dsize = r->keylen;
@@ -228,7 +230,7 @@ static int db_ctdb_transaction_fetch_start(struct db_ctdb_transaction_handle *h)
struct db_ctdb_ctx *ctx = h->ctx;
TDB_DATA data;
- key.dptr = discard_const(keyname);
+ key.dptr = (uint8_t *)discard_const(keyname);
key.dsize = strlen(keyname);
again:
@@ -483,16 +485,16 @@ static int db_ctdb_transaction_store(struct db_ctdb_transaction_handle *h,
return -1;
}
}
-
+
h->m_write = db_ctdb_marshall_add(h, h->m_write, h->ctx->db_id, 0, key, &header, data);
if (h->m_write == NULL) {
DEBUG(0,(__location__ " Failed to add to marshalling record\n"));
talloc_free(tmp_ctx);
return -1;
}
-
+
rec.dsize = data.dsize + sizeof(struct ctdb_ltdb_header);
- rec.dptr = talloc_size(tmp_ctx, rec.dsize);
+ rec.dptr = (uint8_t *)talloc_size(tmp_ctx, rec.dsize);
if (rec.dptr == NULL) {
DEBUG(0,(__location__ " Failed to alloc record\n"));
talloc_free(tmp_ctx);
@@ -504,7 +506,7 @@ static int db_ctdb_transaction_store(struct db_ctdb_transaction_handle *h,
ret = tdb_store(h->ctx->wtdb->tdb, key, rec, TDB_REPLACE);
talloc_free(tmp_ctx);
-
+
return ret;
}
@@ -590,7 +592,7 @@ static int ctdb_replay_transaction(struct db_ctdb_transaction_handle *h)
talloc_free(tmp_ctx);
}
}
-
+
return 0;
failed:
@@ -868,7 +870,7 @@ again:
(int)crec->ctdb_ctx->db_id, keystr));
TALLOC_FREE(keystr);
}
-
+
if (tdb_chainlock(ctx->wtdb->tdb, key) != 0) {
DEBUG(3, ("tdb_chainlock failed\n"));
TALLOC_FREE(result);
diff --git a/source3/lib/idmap_cache.c b/source3/lib/idmap_cache.c
new file mode 100644
index 0000000000..6377635a65
--- /dev/null
+++ b/source3/lib/idmap_cache.c
@@ -0,0 +1,260 @@
+/*
+ Unix SMB/CIFS implementation.
+ ID Mapping Cache
+
+ Copyright (C) Volker Lendecke 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 <http://www.gnu.org/licenses/>.*/
+
+#include "includes.h"
+
+/**
+ * Find a sid2uid mapping
+ * @param[in] sid the sid to map
+ * @param[out] puid where to put the result
+ * @param[out] expired is the cache entry expired?
+ * @retval Was anything in the cache at all?
+ *
+ * If *puid == -1 this was a negative mapping.
+ */
+
+bool idmap_cache_find_sid2uid(const struct dom_sid *sid, uid_t *puid,
+ bool *expired)
+{
+ fstring sidstr;
+ char *key;
+ char *value;
+ char *endptr;
+ time_t timeout;
+ uid_t uid;
+ bool ret;
+
+ key = talloc_asprintf(talloc_tos(), "IDMAP/SID2UID/%s",
+ sid_to_fstring(sidstr, sid));
+ if (key == NULL) {
+ return false;
+ }
+ ret = gencache_get(key, &value, &timeout);
+ TALLOC_FREE(key);
+ if (!ret) {
+ return false;
+ }
+ uid = strtol(value, &endptr, 10);
+ ret = (*endptr == '\0');
+ SAFE_FREE(value);
+ if (ret) {
+ *puid = uid;
+ *expired = (timeout <= time(NULL));
+ }
+ return ret;
+}
+
+/**
+ * Find a uid2sid mapping
+ * @param[in] uid the uid to map
+ * @param[out] sid where to put the result
+ * @param[out] expired is the cache entry expired?
+ * @retval Was anything in the cache at all?
+ *
+ * If "is_null_sid(sid)", this was a negative mapping.
+ */
+
+bool idmap_cache_find_uid2sid(uid_t uid, struct dom_sid *sid, bool *expired)
+{
+ char *key;
+ char *value;
+ time_t timeout;
+ bool ret = true;
+
+ key = talloc_asprintf(talloc_tos(), "IDMAP/UID2SID/%d", (int)uid);
+ if (key == NULL) {
+ return false;
+ }
+ ret = gencache_get(key, &value, &timeout);
+ TALLOC_FREE(key);
+ if (!ret) {
+ return false;
+ }
+ ZERO_STRUCTP(sid);
+ if (value[0] != '-') {
+ ret = string_to_sid(sid, value);
+ }
+ SAFE_FREE(value);
+ if (ret) {
+ *expired = (timeout <= time(NULL));
+ }
+ return ret;
+}
+
+/**
+ * Store a mapping in the idmap cache
+ * @param[in] sid the sid to map
+ * @param[in] uid the uid to map
+ *
+ * If both parameters are valid values, then a positive mapping in both
+ * directions is stored. If "is_null_sid(sid)" is true, then this will be a
+ * negative mapping of uid, we want to cache that for this uid we could not
+ * find anything. Likewise if "uid==-1", then we want to cache that we did not
+ * find a mapping for the sid passed here.
+ */
+
+void idmap_cache_set_sid2uid(const struct dom_sid *sid, uid_t uid)
+{
+ time_t now = time(NULL);
+ time_t timeout;
+ fstring sidstr, key, value;
+
+ if (!is_null_sid(sid)) {
+ fstr_sprintf(key, "IDMAP/SID2UID/%s",
+ sid_to_fstring(sidstr, sid));
+ fstr_sprintf(value, "%d", (int)uid);
+ timeout = (uid == -1)
+ ? lp_idmap_negative_cache_time()
+ : lp_idmap_cache_time();
+ gencache_set(key, value, now + timeout);
+ }
+ if (uid != -1) {
+ fstr_sprintf(key, "IDMAP/UID2SID/%d", (int)uid);
+ if (is_null_sid(sid)) {
+ /* negative uid mapping */
+ fstrcpy(value, "-");
+ timeout = lp_idmap_negative_cache_time();
+ }
+ else {
+ sid_to_fstring(value, sid);
+ timeout = lp_idmap_cache_time();
+ }
+ gencache_set(key, value, now + timeout);
+ }
+}
+
+/**
+ * Find a sid2gid mapping
+ * @param[in] sid the sid to map
+ * @param[out] pgid where to put the result
+ * @param[out] expired is the cache entry expired?
+ * @retval Was anything in the cache at all?
+ *
+ * If *pgid == -1 this was a negative mapping.
+ */
+
+bool idmap_cache_find_sid2gid(const struct dom_sid *sid, gid_t *pgid,
+ bool *expired)
+{
+ fstring sidstr;
+ char *key;
+ char *value;
+ char *endptr;
+ time_t timeout;
+ gid_t gid;
+ bool ret;
+
+ key = talloc_asprintf(talloc_tos(), "IDMAP/SID2GID/%s",
+ sid_to_fstring(sidstr, sid));
+ if (key == NULL) {
+ return false;
+ }
+ ret = gencache_get(key, &value, &timeout);
+ TALLOC_FREE(key);
+ if (!ret) {
+ return false;
+ }
+ gid = strtol(value, &endptr, 10);
+ ret = (*endptr == '\0');
+ SAFE_FREE(value);
+ if (ret) {
+ *pgid = gid;
+ *expired = (timeout <= time(NULL));
+ }
+ return ret;
+}
+
+/**
+ * Find a gid2sid mapping
+ * @param[in] gid the gid to map
+ * @param[out] sid where to put the result
+ * @param[out] expired is the cache entry expired?
+ * @retval Was anything in the cache at all?
+ *
+ * If "is_null_sid(sid)", this was a negative mapping.
+ */
+
+bool idmap_cache_find_gid2sid(gid_t gid, struct dom_sid *sid, bool *expired)
+{
+ char *key;
+ char *value;
+ time_t timeout;
+ bool ret = true;
+
+ key = talloc_asprintf(talloc_tos(), "IDMAP/GID2SID/%d", (int)gid);
+ if (key == NULL) {
+ return false;
+ }
+ ret = gencache_get(key, &value, &timeout);
+ TALLOC_FREE(key);
+ if (!ret) {
+ return false;
+ }
+ ZERO_STRUCTP(sid);
+ if (value[0] != '-') {
+ ret = string_to_sid(sid, value);
+ }
+ SAFE_FREE(value);
+ if (ret) {
+ *expired = (timeout <= time(NULL));
+ }
+ return ret;
+}
+
+/**
+ * Store a mapping in the idmap cache
+ * @param[in] sid the sid to map
+ * @param[in] gid the gid to map
+ *
+ * If both parameters are valid values, then a positive mapping in both
+ * directions is stored. If "is_null_sid(sid)" is true, then this will be a
+ * negative mapping of gid, we want to cache that for this gid we could not
+ * find anything. Likewise if "gid==-1", then we want to cache that we did not
+ * find a mapping for the sid passed here.
+ */
+
+void idmap_cache_set_sid2gid(const struct dom_sid *sid, gid_t gid)
+{
+ time_t now = time(NULL);
+ time_t timeout;
+ fstring sidstr, key, value;
+
+ if (!is_null_sid(sid)) {
+ fstr_sprintf(key, "IDMAP/SID2GID/%s",
+ sid_to_fstring(sidstr, sid));
+ fstr_sprintf(value, "%d", (int)gid);
+ timeout = (gid == -1)
+ ? lp_idmap_negative_cache_time()
+ : lp_idmap_cache_time();
+ gencache_set(key, value, now + timeout);
+ }
+ if (gid != -1) {
+ fstr_sprintf(key, "IDMAP/GID2SID/%d", (int)gid);
+ if (is_null_sid(sid)) {
+ /* negative gid mapping */
+ fstrcpy(value, "-");
+ timeout = lp_idmap_negative_cache_time();
+ }
+ else {
+ sid_to_fstring(value, sid);
+ timeout = lp_idmap_cache_time();
+ }
+ gencache_set(key, value, now + timeout);
+ }
+}
diff --git a/source3/lib/interface.c b/source3/lib/interface.c
index eb0af9ef34..2e7c2706a0 100644
--- a/source3/lib/interface.c
+++ b/source3/lib/interface.c
@@ -131,15 +131,18 @@ int iface_count(void)
}
/****************************************************************************
- How many interfaces do we have (v4 only) ?
+ How many non-loopback IPv4 interfaces do we have ?
**************************************************************************/
-int iface_count_v4(void)
+int iface_count_v4_nl(void)
{
int ret = 0;
struct interface *i;
for (i=local_interfaces;i;i=i->next) {
+ if (is_loopback_addr(&i->ip)) {
+ continue;
+ }
if (i->ip.ss_family == AF_INET) {
ret++;
}
diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c
index 5f26cc80f8..9f952abf10 100644
--- a/source3/lib/util_str.c
+++ b/source3/lib/util_str.c
@@ -2008,6 +2008,7 @@ bool str_list_sub_basic( char **list, const char *smb_name,
bool str_list_substitute(char **list, const char *pattern, const char *insert)
{
+ TALLOC_CTX *ctx = list;
char *p, *s, *t;
ssize_t ls, lp, li, ld, i, d;
@@ -2030,7 +2031,7 @@ bool str_list_substitute(char **list, const char *pattern, const char *insert)
t = *list;
d = p -t;
if (ld) {
- t = (char *) SMB_MALLOC(ls +ld +1);
+ t = TALLOC_ARRAY(ctx, char, ls +ld +1);
if (!t) {
DEBUG(0,("str_list_substitute: "
"Unable to allocate memory"));
@@ -2038,7 +2039,7 @@ bool str_list_substitute(char **list, const char *pattern, const char *insert)
}
memcpy(t, *list, d);
memcpy(t +d +li, p +lp, ls -d -lp +1);
- SAFE_FREE(*list);
+ TALLOC_FREE(*list);
*list = t;
ls += ld;
s = t +d +li;