Minor bug fixes, plus support to remove a printer. Commented out optional attributes...
authorJim McDonough <jmcd@samba.org>
Sat, 2 Feb 2002 02:04:01 +0000 (02:04 +0000)
committerJim McDonough <jmcd@samba.org>
Sat, 2 Feb 2002 02:04:01 +0000 (02:04 +0000)
(This used to be commit 538c19a6983e0423b94f743184263cd8ef9c701e)

source3/libads/ldap.c
source3/libads/ldap_printer.c

index 293c885342b85da7ae411cc62ed110d235a93b76..8dee73bde2ab7a51c6768fa460498434231191f7 100644 (file)
@@ -105,6 +105,23 @@ void ads_msgfree(ADS_STRUCT *ads, void *msg)
        ldap_msgfree(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 
 */
@@ -122,6 +139,24 @@ ADS_STATUS ads_find_machine_acct(ADS_STRUCT *ads, void **res, const char *host)
        return status;
 }
 
+/*
+  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);
        }
index 54cd7d8e94b80cdf36db4a984dc08e4e59c2dc71..74dc02397c2fcb0996b56620b1d602da9db00546 100644 (file)
 
 #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
 */
@@ -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",