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 2 of the License, or (at your option) any later version.
+ 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
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, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
* Author: Andrew Tridgell
*/
-#include "includes.h"
-#include "ldb/include/includes.h"
+#include "ldb_private.h"
/*
create a new ldb_message in a given memory context (NULL for top level)
{
struct ldb_message_element *els;
- if (! ldb_valid_attr_name(attr_name)) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
els = talloc_realloc(msg, msg->elements,
struct ldb_message_element, msg->num_elements+1);
if (!els) {
const struct ldb_message_element *el,
int flags)
{
+ /* We have to copy this, just in case *el is a pointer into
+ * what ldb_msg_add_empty() is about to realloc() */
+ struct ldb_message_element el_copy = *el;
if (ldb_msg_add_empty(msg, el->name, flags, NULL) != 0) {
return LDB_ERR_OPERATIONS_ERROR;
}
- msg->elements[msg->num_elements-1] = *el;
+ msg->elements[msg->num_elements-1] = el_copy;
msg->elements[msg->num_elements-1].flags = flags;
return LDB_SUCCESS;
convenience functions to return common types from a message
these return the first value if the attribute is multi-valued
*/
-const struct ldb_val *ldb_msg_find_ldb_val(const struct ldb_message *msg, const char *attr_name)
+const struct ldb_val *ldb_msg_find_ldb_val(const struct ldb_message *msg,
+ const char *attr_name)
{
struct ldb_message_element *el = ldb_msg_find_element(msg, attr_name);
if (!el || el->num_values == 0) {
if (!v || !v->data) {
return default_value;
}
- if (strcasecmp((const char *)v->data, "FALSE") == 0) {
+ if (v->length == 5 && strncasecmp((const char *)v->data, "FALSE", 5) == 0) {
return 0;
}
- if (strcasecmp((const char *)v->data, "TRUE") == 0) {
+ if (v->length == 4 && strncasecmp((const char *)v->data, "TRUE", 4) == 0) {
return 1;
}
return default_value;
return (const char *)v->data;
}
-struct ldb_dn *ldb_msg_find_attr_as_dn(void *mem_ctx,
+struct ldb_dn *ldb_msg_find_attr_as_dn(struct ldb_context *ldb,
+ void *mem_ctx,
const struct ldb_message *msg,
const char *attr_name)
{
+ struct ldb_dn *res_dn;
const struct ldb_val *v;
v = ldb_msg_find_ldb_val(msg, attr_name);
if (!v || !v->data) {
return NULL;
}
- return ldb_dn_explode(mem_ctx, (const char *)v->data);
+ res_dn = ldb_dn_from_ldb_val(mem_ctx, ldb, v);
+ if ( ! ldb_dn_validate(res_dn)) {
+ talloc_free(res_dn);
+ return NULL;
+ }
+ return res_dn;
}
/*
if (msg2 == NULL) return NULL;
*msg2 = *msg;
- msg2->private_data = NULL;
msg2->elements = talloc_array(msg2, struct ldb_message_element,
msg2->num_elements);
/* TODO: return also an error string */
ldb_asprintf_errstring(ldb, "Element %s has empty attribute in ldb message (%s)!",
msg->elements[i].name,
- ldb_dn_linearize(mem_ctx, msg->dn));
+ ldb_dn_get_linearized(msg->dn));
talloc_free(mem_ctx);
return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
}
/*
copy an attribute list. This only copies the array, not the elements
- (ie. the elements are left as the same pointers)
+ (ie. the elements are left as the same pointers). The new attribute is added to the list.
*/
const char **ldb_attr_list_copy_add(TALLOC_CTX *mem_ctx, const char * const *attrs, const char *new_attr)
{
const char **ret;
int i;
- for (i=0;attrs[i];i++) /* noop */ ;
+ bool found = false;
+ for (i=0;attrs[i];i++) {
+ if (ldb_attr_cmp(attrs[i], new_attr) == 0) {
+ found = true;
+ }
+ }
+ if (found) {
+ return ldb_attr_list_copy(mem_ctx, attrs);
+ }
ret = talloc_array(mem_ctx, const char *, i+2);
if (ret == NULL) {
return NULL;
int ldb_attr_in_list(const char * const *attrs, const char *attr)
{
int i;
- for (i=0;attrs[i];i++) {
+ for (i=0;attrs && attrs[i];i++) {
if (ldb_attr_cmp(attrs[i], attr) == 0) {
return 1;
}
return ldb_msg_rename_attr(msg, attr, replace);
}
+/*
+ remove the specified element in a search result
+*/
+void ldb_msg_remove_element(struct ldb_message *msg, struct ldb_message_element *el)
+{
+ int n = (el - msg->elements);
+ if (n != msg->num_elements-1) {
+ memmove(el, el+1, ((msg->num_elements-1) - n)*sizeof(*el));
+ }
+ msg->num_elements--;
+}
+
/*
remove the specified attribute in a search result
{
struct ldb_message_element *el = ldb_msg_find_element(msg, attr);
if (el) {
- int n = (el - msg->elements);
- if (n != msg->num_elements-1) {
- memmove(el, el+1, ((msg->num_elements-1) - n)*sizeof(*el));
- }
- msg->num_elements--;
+ ldb_msg_remove_element(msg, el);
}
}
/*
- return a LDAP formatted time string
+ return a LDAP formatted GeneralizedTime string
*/
char *ldb_timestring(TALLOC_CTX *mem_ctx, time_t t)
{
struct tm *tm = gmtime(&t);
+ char *ts;
+ int r;
if (!tm) {
return NULL;
}
+ /* we now excatly how long this string will be */
+ ts = talloc_array(mem_ctx, char, 18);
+
/* formatted like: 20040408072012.0Z */
- return talloc_asprintf(mem_ctx,
- "%04u%02u%02u%02u%02u%02u.0Z",
- tm->tm_year+1900, tm->tm_mon+1,
- tm->tm_mday, tm->tm_hour, tm->tm_min,
- tm->tm_sec);
-}
+ r = snprintf(ts, 18,
+ "%04u%02u%02u%02u%02u%02u.0Z",
+ tm->tm_year+1900, tm->tm_mon+1,
+ tm->tm_mday, tm->tm_hour, tm->tm_min,
+ tm->tm_sec);
+
+ if (r != 17) {
+ talloc_free(ts);
+ return NULL;
+ }
+ return ts;
+}
/*
- convert a LDAP time string to a time_t. Return 0 if unable to convert
+ convert a LDAP GeneralizedTime string to a time_t. Return 0 if unable to convert
*/
time_t ldb_string_to_time(const char *s)
{
return timegm(&tm);
}
+/*
+ return a LDAP formatted UTCTime string
+*/
+char *ldb_timestring_utc(TALLOC_CTX *mem_ctx, time_t t)
+{
+ struct tm *tm = gmtime(&t);
+ char *ts;
+ int r;
+
+ if (!tm) {
+ return NULL;
+ }
+
+ /* we now excatly how long this string will be */
+ ts = talloc_array(mem_ctx, char, 14);
+
+ /* formatted like: 20040408072012.0Z => 040408072012Z */
+ r = snprintf(ts, 14,
+ "%02u%02u%02u%02u%02u%02uZ",
+ (tm->tm_year+1900)%100, tm->tm_mon+1,
+ tm->tm_mday, tm->tm_hour, tm->tm_min,
+ tm->tm_sec);
+
+ if (r != 13) {
+ talloc_free(ts);
+ return NULL;
+ }
+
+ return ts;
+}
+
+/*
+ convert a LDAP UTCTime string to a time_t. Return 0 if unable to convert
+*/
+time_t ldb_string_utc_to_time(const char *s)
+{
+ struct tm tm;
+
+ if (s == NULL) return 0;
+
+ memset(&tm, 0, sizeof(tm));
+ if (sscanf(s, "%02u%02u%02u%02u%02u%02u",
+ &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
+ &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
+ return 0;
+ }
+ if (tm.tm_year < 50) {
+ tm.tm_year += 100;
+ }
+ tm.tm_mon -= 1;
+
+ return timegm(&tm);
+}
+
/*
dump a set of results to a file. Useful from within gdb