diff options
author | Jim McDonough <jmcd@samba.org> | 2002-02-02 22:06:10 +0000 |
---|---|---|
committer | Jim McDonough <jmcd@samba.org> | 2002-02-02 22:06:10 +0000 |
commit | 81b54940b7e9a3a3f6586972b1c9aa687e07426d (patch) | |
tree | 358efc0f0b4bbd8dd2f6df8d2a90f211128e774a /source3 | |
parent | c8bc0fa4a7be25cb926750a56085e1e98ed9046b (diff) | |
download | samba-81b54940b7e9a3a3f6586972b1c9aa687e07426d.tar.gz samba-81b54940b7e9a3a3f6586972b1c9aa687e07426d.tar.bz2 samba-81b54940b7e9a3a3f6586972b1c9aa687e07426d.zip |
merge in some changes from Alexey Kotovich. Return ADS_STATUS instead of BOOLs. Add support for bervals in mod lists. Also put undocumented AD ldap control in to allow modifications when an attribute does not yet exist.
(This used to be commit 1a2d27b21e61be5a314f7d6c4ea0dff06a5307be)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/libads/ldap.c | 121 |
1 files changed, 88 insertions, 33 deletions
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 8dee73bde2..75c7982105 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -37,7 +37,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) ads->ld = ldap_open(ads->ldap_server, ads->ldap_port); if (!ads->ld) { - return ADS_ERROR_SYSTEM(errno) + return ADS_ERROR_SYSTEM(errno); } status = ads_server_info(ads); if (!ADS_ERR_OK(status)) { @@ -150,7 +150,8 @@ static char **ads_dup_values(char **values) #define ADS_MAX_NUM_VALUES 32 for (i=0; values[i] && i<ADS_MAX_NUM_VALUES; i++); - newvals = malloc((i+1)*sizeof(char *)); + if (!(newvals = malloc((i+1)*sizeof(char *)))) + return NULL; for (i=0; values[i] && i<ADS_MAX_NUM_VALUES; i++) newvals[i] = values[i]; newvals[i] = NULL; @@ -162,16 +163,17 @@ static char **ads_dup_values(char **values) so proto.h works on non-ldap systems */ -void **ads_mod_list_start(int num_mods) +void **ads_init_mods(int num_mods) { LDAPMod **mods; if (num_mods < 1) return NULL; - mods = malloc(sizeof(LDAPMod *) * (num_mods + 1)); - memset(mods, 0, sizeof(LDAPMod *) * num_mods); - mods[num_mods] = (LDAPMod *) -1; + if ((mods = calloc(1, sizeof(LDAPMod *) * (num_mods + 1)))) + /* -1 is safety to make sure we don't go over the end. + need to reset it to NULL before doing ldap modify */ + mods[num_mods] = (LDAPMod *) -1; return (void **) mods; } @@ -179,7 +181,7 @@ void **ads_mod_list_start(int num_mods) /* add an attribute to the list, with values list already constructed */ -static BOOL ads_mod_list_add(void **mods, int mod_op, char *name, char **values) +static ADS_STATUS ads_modlist_add(void **mods, int mod_op, char *name, char **values) { int curmod; LDAPMod **modlist = (LDAPMod **) mods; @@ -187,39 +189,46 @@ static BOOL ads_mod_list_add(void **mods, int mod_op, char *name, char **values) /* find the first empty slot */ for (curmod=0; modlist[curmod] > 0; curmod++); if (modlist[curmod] == (LDAPMod *) -1) - return False; + return ADS_ERROR(LDAP_NO_MEMORY); - modlist[curmod] = malloc(sizeof(LDAPMod)); + if (!(modlist[curmod] = malloc(sizeof(LDAPMod)))) + return ADS_ERROR(LDAP_NO_MEMORY); modlist[curmod]->mod_type = name; modlist[curmod]->mod_values = values; modlist[curmod]->mod_op = mod_op; - return True; + return ADS_ERROR(LDAP_SUCCESS); } -BOOL ads_mod_add_list(void **mods, char *name, char **values) +ADS_STATUS ads_mod_add_list(void **mods, char *name, char **values) { char **newvals = ads_dup_values(values); - return ads_mod_list_add(mods, LDAP_MOD_ADD, name, newvals); + if (newvals) + return ads_modlist_add(mods, LDAP_MOD_ADD, name, newvals); + else + return ADS_ERROR(LDAP_NO_MEMORY); } -BOOL ads_mod_repl_list(void **mods, char *name, char **values) +ADS_STATUS ads_mod_repl_list(void **mods, char *name, char **values) { char **newvals; if (values && *values) { - newvals = ads_dup_values(values); - return ads_mod_list_add(mods, LDAP_MOD_REPLACE, name, newvals); + if (!(newvals = ads_dup_values(values))) + return ADS_ERROR(LDAP_NO_MEMORY); + else + return ads_modlist_add(mods, LDAP_MOD_REPLACE, + name, newvals); } else - return ads_mod_list_add(mods, LDAP_MOD_DELETE, name, NULL); + return ads_modlist_add(mods, LDAP_MOD_DELETE, name, NULL); } /* add an attribute to the list, with values list to be built from args */ -BOOL ads_mod_list_add_var(void **mods, int mod_op, char *name, ...) +ADS_STATUS ads_mod_add_var(void **mods, int mod_op, char *name, ...) { va_list ap; - int num_vals, i; + int num_vals, i, do_op; char *value, **values; /* count the number of values */ @@ -227,45 +236,75 @@ BOOL ads_mod_list_add_var(void **mods, int mod_op, char *name, ...) for (num_vals=0; va_arg(ap, char *); num_vals++); va_end(ap); + if (num_vals) { + if (!(values = malloc(sizeof(char *) * (num_vals + 1)))) + return ADS_ERROR(LDAP_NO_MEMORY); + va_start(ap, name); + for (i=0; (value = (char *) va_arg(ap, char *)) && + i < num_vals; i++) + values[i] = value; + va_end(ap); + values[i] = NULL; + do_op = mod_op; + } else { + do_op = LDAP_MOD_DELETE; + values = NULL; + } + return ads_modlist_add(mods, do_op, name, values); +} + +ADS_STATUS ads_mod_add_ber(void **mods, int mod_op, char *name, ...) +{ + va_list ap; + int num_vals, i, do_op; + char *value, **values; + + /* count the number of values */ + va_start(ap, name); + for (num_vals=0; va_arg(ap, struct berval *); num_vals++); + va_end(ap); if (num_vals) { - values = malloc(sizeof(char *) * (num_vals + 1)); + if (!(values = malloc(sizeof(struct berval) * (num_vals + 1)))) + return ADS_ERROR(LDAP_NO_MEMORY); va_start(ap, name); for (i=0; (value = (char *) va_arg(ap, char *)) && i < num_vals; i++) values[i] = value; va_end(ap); values[i] = NULL; - } else + do_op = mod_op; + } else { + do_op = LDAP_MOD_DELETE; values = NULL; - return ads_mod_list_add(mods, mod_op, name, values); + } + do_op |= LDAP_MOD_BVALUES; + return ads_modlist_add(mods, do_op, name, values); } -BOOL ads_mod_repl(void **mods, char *name, char *val) +ADS_STATUS ads_mod_repl(void **mods, char *name, char *val) { if (val) - return ads_mod_list_add_var(mods, LDAP_MOD_REPLACE, + return ads_mod_add_var(mods, LDAP_MOD_REPLACE, name, val, NULL); else - return ads_mod_list_add_var(mods, LDAP_MOD_DELETE, name, NULL); + return ads_mod_add_var(mods, LDAP_MOD_DELETE, name, NULL); } -BOOL ads_mod_add(void **mods, char *name, char *val) +ADS_STATUS ads_mod_add(void **mods, char *name, char *val) { - return ads_mod_list_add_var(mods, LDAP_MOD_ADD, name, val, NULL); + return ads_mod_add_var(mods, LDAP_MOD_ADD, name, val, NULL); } -void ads_mod_list_end(void **mods) +void ads_free_mods(void **mods) { int i; LDAPMod **modlist = (LDAPMod **) mods; if (modlist) { for (i = 0; modlist[i]; i++) { - if (modlist[i]->mod_values) { - free(modlist[i]->mod_values); - } - free(modlist[i]); + SAFE_FREE(modlist[i]->mod_values); + SAFE_FREE(modlist[i]); } free(modlist); } @@ -274,12 +313,28 @@ void ads_mod_list_end(void **mods) ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, void **mods) { int ret,i; - + LDAPControl control; + LDAPControl *controls[2]; + char bv_val = (char) 1; + + /* + this control seems to be necessary to have any modify + that contains a currently non-existent attribute (but + allowable for the object) to run + */ + control.ldctl_oid = "1.2.840.113556.1.4.1413"; + control.ldctl_value.bv_len = 1; + control.ldctl_value.bv_val = &bv_val; + control.ldctl_iscritical = (char) 0; + controls[0] = &control; + controls[1] = NULL; + /* find the end of the list, marked by NULL or -1 */ for(i=0;mods[i]>0;i++); /* make sure the end of the list is NULL */ mods[i] = NULL; - ret = ldap_modify_s(ads->ld, mod_dn, (LDAPMod **) mods); + ret = ldap_modify_ext_s(ads->ld, mod_dn, (LDAPMod **) mods, + controls, NULL); return ADS_ERROR(ret); } |