diff options
-rw-r--r-- | source3/libads/ldap.c | 67 | ||||
-rw-r--r-- | source3/libads/ldap_printer.c | 40 |
2 files changed, 91 insertions, 16 deletions
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 293c885342..8dee73bde2 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -106,6 +106,23 @@ void ads_msgfree(ADS_STRUCT *ads, void *msg) } /* + free up memory from various ads requests +*/ +void ads_memfree(ADS_STRUCT *ads, void *mem) +{ + if (!mem) return; + ldap_memfree(mem); +} + +/* + get a dn from search results +*/ +char *ads_get_dn(ADS_STRUCT *ads, void *res) +{ + return ldap_get_dn(ads->ld, res); +} + +/* find a machine account given a hostname */ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) @@ -123,6 +140,24 @@ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host) } /* + duplicate an already-assembled list of values so that it can be + freed as part of the standard msgfree call +*/ +static char **ads_dup_values(char **values) +{ + char **newvals; + int i; +#define ADS_MAX_NUM_VALUES 32 + + for (i=0; values[i] && i<ADS_MAX_NUM_VALUES; i++); + newvals = malloc((i+1)*sizeof(char *)); + for (i=0; values[i] && i<ADS_MAX_NUM_VALUES; i++) + newvals[i] = values[i]; + newvals[i] = NULL; + return newvals; +} + +/* initialize a list of mods - returns (void **) instead of (LDAPMod **) so proto.h works on non-ldap systems */ @@ -163,13 +198,17 @@ static BOOL ads_mod_list_add(void **mods, int mod_op, char *name, char **values) BOOL ads_mod_add_list(void **mods, char *name, char **values) { - return ads_mod_list_add(mods, LDAP_MOD_ADD, name, values); + char **newvals = ads_dup_values(values); + return ads_mod_list_add(mods, LDAP_MOD_ADD, name, newvals); } BOOL ads_mod_repl_list(void **mods, char *name, char **values) { - if (values && *values) - return ads_mod_list_add(mods, LDAP_MOD_REPLACE, name, values); + char **newvals; + if (values && *values) { + newvals = ads_dup_values(values); + return ads_mod_list_add(mods, LDAP_MOD_REPLACE, name, newvals); + } else return ads_mod_list_add(mods, LDAP_MOD_DELETE, name, NULL); } @@ -204,15 +243,16 @@ BOOL ads_mod_list_add_var(void **mods, int mod_op, char *name, ...) BOOL ads_mod_repl(void **mods, char *name, char *val) { - if (val) - return ads_mod_list_add_var(mods, LDAP_MOD_REPLACE, name, val); - else - return ads_mod_list_add_var(mods, LDAP_MOD_DELETE, name, NULL); + if (val) + return ads_mod_list_add_var(mods, LDAP_MOD_REPLACE, + name, val, NULL); + else + return ads_mod_list_add_var(mods, LDAP_MOD_DELETE, name, NULL); } BOOL ads_mod_add(void **mods, char *name, char *val) { - return ads_mod_list_add_var(mods, LDAP_MOD_ADD, name, val); + return ads_mod_list_add_var(mods, LDAP_MOD_ADD, name, val, NULL); } void ads_mod_list_end(void **mods) @@ -239,7 +279,7 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, void **mods) for(i=0;mods[i]>0;i++); /* make sure the end of the list is NULL */ mods[i] = NULL; - ret = ldap_add_s(ads->ld, mod_dn, (LDAPMod **) mods); + ret = ldap_modify_s(ads->ld, mod_dn, (LDAPMod **) mods); return ADS_ERROR(ret); } @@ -293,6 +333,11 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ...) return ADS_ERROR(ret); } +ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) +{ + return ADS_ERROR(ldap_delete(ads->ld, del_dn)); +} + /* build an org unit string if org unit is Computers or blank then assume a container, otherwise @@ -508,9 +553,9 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) return status; } - hostnameDN = ldap_get_dn(ads->ld, (LDAPMessage *)res); + hostnameDN = ads_get_dn(ads, (LDAPMessage *)res); rc = ldap_delete_s(ads->ld, hostnameDN); - ldap_memfree(hostnameDN); + ads_memfree(ads, hostnameDN); if (rc != LDAP_SUCCESS) { return ADS_ERROR(rc); } diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 54cd7d8e94..74dc02397c 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -23,6 +23,35 @@ #ifdef HAVE_ADS /* + find a printer given the name and the hostname + Note that results "res" may be allocated on return so that the + results can be used. It should be freed using ads_msgfree. +*/ +ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res, + char *printer, char *servername) +{ + ADS_STATUS status; + char *srv_dn, *exp; + const char *attrs[] = {"*", "nTSecurityDescriptor", NULL}; + + status = ads_find_machine_acct(ads, res, servername); + if (!ADS_ERR_OK(status)) { + DEBUG(1, ("ads_add_printer: cannot find host %s in ads\n", + servername)); + return status; + } + srv_dn = ldap_get_dn(ads->ld, *res); + ads_msgfree(ads, *res); + + asprintf(&exp, "(printerName=%s)", printer); + status = ads_do_search(ads, srv_dn, LDAP_SCOPE_SUBTREE, + exp, &attrs, res); + + free(exp); + return status; +} + +/* modify an entire printer entry in the directory */ ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, @@ -32,7 +61,7 @@ ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, ADS_STATUS status; /* allocate the list */ - mods = ads_mod_list_start(sizeof(prt) / sizeof(char *)); + mods = ads_mod_list_start(sizeof(ADS_PRINTER_ENTRY) / sizeof(char *)); /* add the attributes to the list - required ones first */ ads_mod_repl(mods, "printerName", prt->printerName); @@ -40,7 +69,8 @@ ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, ads_mod_repl(mods, "shortServerName", prt->shortServerName); ads_mod_repl(mods, "uNCName", prt->uNCName); ads_mod_repl(mods, "versionNumber", prt->versionNumber); - /* now the optional ones */ + /* now the optional ones - not ready yet, since it will + fail if the attributes don't exist already ads_mod_repl_list(mods, "description", prt->description); ads_mod_repl(mods, "driverName", prt->driverName); ads_mod_repl(mods, "location", prt->location); @@ -49,7 +79,7 @@ ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn, ads_mod_repl(mods, "printEndTime", prt->printEndTime); ads_mod_repl_list(mods, "printBinNames", prt->printBinNames); - /* and many others */ + ... and many others */ /* do the ldap modify */ status = ads_gen_mod(ads, prt_dn, mods); @@ -93,7 +123,7 @@ ADS_STATUS ads_add_printer(ADS_STRUCT *ads, const ADS_PRINTER_ENTRY *prt) char *host_dn, *prt_dn; const char *attrs[] = {"*", "nTSecurityDescriptor", NULL}; - status = ads_find_machine_acct(ads, (void **)&res, + status = ads_find_machine_acct(ads, (void **)&res, prt->shortServerName); if (!ADS_ERR_OK(status)) { DEBUG(1, ("ads_add_printer: cannot find host %s in ads\n", @@ -107,7 +137,7 @@ ADS_STATUS ads_add_printer(ADS_STRUCT *ads, const ADS_PRINTER_ENTRY *prt) asprintf(&prt_dn, "cn=%s-%s,%s", prt->shortServerName, prt->printerName, host_dn); - status = ads_search_dn(ads, res, prt_dn, attrs); + status = ads_search_dn(ads, &res, prt_dn, attrs); if (ADS_ERR_OK(status) && ads_count_replies(ads, res)) { DEBUG(1, ("ads_add_printer: printer %s already exists\n", |