s3-printing: remove unused get_local_printer_publishing_data() call.
[amitay/samba.git] / source3 / libads / ldap_printer.c
index b2ee5f22655120aeb6d1c516d857c43c39ee21cc..fff50cfe8b131909b3c7fae525d25748f334b300 100644 (file)
@@ -1,11 +1,11 @@
 /* 
    Unix SMB/CIFS implementation.
    ads (active directory) printer utility library
-   Copyright (C) Jim McDonough 2002
+   Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
    
    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 2 of the License, or
+   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,
    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, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
+#include "../librpc/gen_ndr/cli_spoolss.h"
+#include "rpc_client/cli_spoolss.h"
+#include "registry.h"
+#include "registry/reg_objects.h"
+#include "nt_printing.h"
 
 #ifdef HAVE_ADS
 
     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,
-                                     const char *printer, const char *servername)
+ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, LDAPMessage **res,
+                                      const char *printer,
+                                      const char *servername)
 {
        ADS_STATUS status;
-       char *srv_dn, **srv_cn, *exp;
+       char *srv_dn, **srv_cn, *s = NULL;
        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",
+               DEBUG(1, ("ads_find_printer_on_server: cannot find host %s in ads\n",
                          servername));
                return status;
        }
-       srv_dn = ldap_get_dn(ads->ld, *res);
+       if (ads_count_replies(ads, *res) != 1) {
+               if (res) {
+                       ads_msgfree(ads, *res);
+                       *res = NULL;
+               }
+               return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
+       }
+       srv_dn = ldap_get_dn(ads->ldap.ld, *res);
+       if (srv_dn == NULL) {
+               if (res) {
+                       ads_msgfree(ads, *res);
+                       *res = NULL;
+               }
+               return ADS_ERROR(LDAP_NO_MEMORY);
+       }
        srv_cn = ldap_explode_dn(srv_dn, 1);
-       ads_msgfree(ads, *res);
+       if (srv_cn == NULL) {
+               ldap_memfree(srv_dn);
+               if (res) {
+                       ads_msgfree(ads, *res);
+                       *res = NULL;
+               }
+               return ADS_ERROR(LDAP_INVALID_DN_SYNTAX);
+       }
+       if (res) {
+               ads_msgfree(ads, *res);
+               *res = NULL;
+       }
 
-       asprintf(&exp, "(cn=%s-%s)", srv_cn[0], printer);
-       status = ads_search(ads, res, exp, attrs);
+       if (asprintf(&s, "(cn=%s-%s)", srv_cn[0], printer) == -1) {
+               ldap_memfree(srv_dn);
+               return ADS_ERROR(LDAP_NO_MEMORY);
+       }
+       status = ads_search(ads, res, s, attrs);
 
        ldap_memfree(srv_dn);
        ldap_value_free(srv_cn);
-       free(exp);
+       SAFE_FREE(s);
        return status;  
 }
 
+ ADS_STATUS ads_find_printers(ADS_STRUCT *ads, LDAPMessage **res)
+{
+       const char *ldap_expr;
+       const char *attrs[] = { "objectClass", "printerName", "location", "driverName",
+                               "serverName", "description", NULL };
+
+       /* For the moment only display all printers */
+
+       ldap_expr = "(&(!(showInAdvancedViewOnly=TRUE))(uncName=*)"
+               "(objectCategory=printQueue))";
+
+       return ads_search(ads, res, ldap_expr, attrs);
+}
+
 /*
   modify a printer entry in the directory
 */
@@ -75,91 +122,106 @@ ADS_STATUS ads_add_printer_entry(ADS_STRUCT *ads, char *prt_dn,
 /*
   map a REG_SZ to an ldap mod
 */
-static BOOL map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, 
-                           const REGISTRY_VALUE *value)
+static bool map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, 
+                  struct regval_blob *value)
 {
        char *str_value = NULL;
+       size_t converted_size;
        ADS_STATUS status;
 
-       if (value->type != REG_SZ)
-               return False;
+       if (regval_type(value) != REG_SZ)
+               return false;
 
-       if (value->size && *((smb_ucs2_t *) value->data_p)) {
-               pull_ucs2_talloc(ctx, (void **) &str_value, 
-                                (const smb_ucs2_t *) value->data_p);
-               status = ads_mod_str(ctx, mods, value->valuename, str_value);
+       if (regval_size(value) && *((smb_ucs2_t *) regval_data_p(value))) {
+               if (!pull_ucs2_talloc(ctx, &str_value,
+                                     (const smb_ucs2_t *) regval_data_p(value),
+                                     &converted_size))
+               {
+                       return false;
+               }
+               status = ads_mod_str(ctx, mods, regval_name(value), str_value);
                return ADS_ERR_OK(status);
        }
-       return True;
+       return true;
                
 }
 
 /*
   map a REG_DWORD to an ldap mod
 */
-static BOOL map_dword(TALLOC_CTX *ctx, ADS_MODLIST *mods, 
-                     const REGISTRY_VALUE *value)
+static bool map_dword(TALLOC_CTX *ctx, ADS_MODLIST *mods, 
+                     struct regval_blob *value)
 {
        char *str_value = NULL;
        ADS_STATUS status;
 
-       if (value->type != REG_DWORD)
+       if (regval_type(value) != REG_DWORD)
+               return False;
+       str_value = talloc_asprintf(ctx, "%d", *((uint32 *) regval_data_p(value)));
+       if (!str_value) {
                return False;
-       str_value = talloc_asprintf(ctx, "%d", *((uint32 *) value->data_p));
-       status = ads_mod_str(ctx, mods, value->valuename, str_value);
+       }
+       status = ads_mod_str(ctx, mods, regval_name(value), str_value);
        return ADS_ERR_OK(status);
 }
 
 /*
   map a boolean REG_BINARY to an ldap mod
 */
-static BOOL map_bool(TALLOC_CTX *ctx, ADS_MODLIST *mods,
-                    const REGISTRY_VALUE *value)
+static bool map_bool(TALLOC_CTX *ctx, ADS_MODLIST *mods,
+                    struct regval_blob *value)
 {
        char *str_value;
        ADS_STATUS status;
 
-       if ((value->type != REG_BINARY) || (value->size != 1))
+       if ((regval_type(value) != REG_BINARY) || (regval_size(value) != 1))
                return False;
        str_value =  talloc_asprintf(ctx, "%s", 
-                                    *(value->data_p) ? "TRUE" : "FALSE");
-       status = ads_mod_str(ctx, mods, value->valuename, str_value);
+                                    *(regval_data_p(value)) ? "TRUE" : "FALSE");
+       if (!str_value) {
+               return False;
+       }
+       status = ads_mod_str(ctx, mods, regval_name(value), str_value);
        return ADS_ERR_OK(status);
 }
 
 /*
   map a REG_MULTI_SZ to an ldap mod
 */
-static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods,
-                        const REGISTRY_VALUE *value)
+static bool map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods,
+                        struct regval_blob *value)
 {
        char **str_values = NULL;
-       smb_ucs2_t *cur_str = (smb_ucs2_t *) value->data_p;
+       size_t converted_size;
+       smb_ucs2_t *cur_str = (smb_ucs2_t *) regval_data_p(value);
         uint32 size = 0, num_vals = 0, i=0;
        ADS_STATUS status;
 
-       if (value->type != REG_MULTI_SZ)
+       if (regval_type(value) != REG_MULTI_SZ)
                return False;
 
-       while(cur_str && *cur_str && (size < value->size)) {            
+       while(cur_str && *cur_str && (size < regval_size(value))) {
                size += 2 * (strlen_w(cur_str) + 1);
                cur_str += strlen_w(cur_str) + 1;
                num_vals++;
        };
 
        if (num_vals) {
-               str_values = talloc(ctx, 
-                                   (num_vals + 1) * sizeof(smb_ucs2_t *));
+               str_values = TALLOC_ARRAY(ctx, char *, num_vals + 1);
+               if (!str_values) {
+                       return False;
+               }
                memset(str_values, '\0', 
-                      (num_vals + 1) * sizeof(smb_ucs2_t *));
+                      (num_vals + 1) * sizeof(char *));
 
-               cur_str = (smb_ucs2_t *) value->data_p;
-               for (i=0; i < num_vals; i++)
-                       cur_str += pull_ucs2_talloc(ctx, 
-                                                   (void **) &str_values[i], 
-                                                   cur_str);
+               cur_str = (smb_ucs2_t *) regval_data_p(value);
+               for (i=0; i < num_vals; i++) {
+                       cur_str += pull_ucs2_talloc(ctx, &str_values[i],
+                                                   cur_str, &converted_size) ?
+                           converted_size : (size_t)-1;
+               }
 
-               status = ads_mod_strlist(ctx, mods, value->valuename, 
+               status = ads_mod_strlist(ctx, mods, regval_name(value),
                                         (const char **) str_values);
                return ADS_ERR_OK(status);
        } 
@@ -167,17 +229,17 @@ static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods,
 }
 
 struct valmap_to_ads {
-       char *valname;
-       BOOL (*fn)(TALLOC_CTX *, ADS_MODLIST *, const REGISTRY_VALUE *);
+       const char *valname;
+       bool (*fn)(TALLOC_CTX *, ADS_MODLIST *, struct regval_blob *);
 };
 
 /*
   map a REG_SZ to an ldap mod
 */
 static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods, 
-                             REGISTRY_VALUE *value)
+                             struct regval_blob *value)
 {
-       struct valmap_to_ads map[] = {
+       const struct valmap_to_ads map[] = {
                {SPOOL_REG_ASSETNUMBER, map_sz},
                {SPOOL_REG_BYTESPERMINUTE, map_dword},
                {SPOOL_REG_DEFAULTPRIORITY, map_dword},
@@ -235,11 +297,11 @@ static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods,
        int i;
 
        for (i=0; map[i].valname; i++) {
-               if (StrCaseCmp(map[i].valname, value->valuename) == 0) {
+               if (StrCaseCmp(map[i].valname, regval_name(value)) == 0) {
                        if (!map[i].fn(ctx, mods, value)) {
-                               DEBUG(5, ("Add of value %s to modlist failed\n", value->valuename));
+                               DEBUG(5, ("Add of value %s to modlist failed\n", regval_name(value)));
                        } else {
-                               DEBUG(7, ("Mapped value %s\n", value->valuename));
+                               DEBUG(7, ("Mapped value %s\n", regval_name(value)));
                        }
                        
                }
@@ -247,97 +309,92 @@ static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods,
 }
 
 
-WERROR get_remote_printer_publishing_data(struct cli_state *cli, 
+WERROR get_remote_printer_publishing_data(struct rpc_pipe_client *cli, 
                                          TALLOC_CTX *mem_ctx,
                                          ADS_MODLIST *mods,
-                                         char *printer)
+                                         const char *printer)
 {
        WERROR result;
-       char *printername, *servername;
-       REGVAL_CTR dsdriver_ctr, dsspooler_ctr;
-       BOOL got_dsdriver = False, got_dsspooler = False;
-       uint32 needed, i;
-       POLICY_HND pol;
-
-       asprintf(&servername, "\\\\%s", cli->desthost);
-       asprintf(&printername, "%s\\%s", servername, printer);
-       if (!servername || !printername) {
+       char *printername;
+       struct spoolss_PrinterEnumValues *info;
+       uint32_t count;
+       uint32 i;
+       struct policy_handle pol;
+
+       if ((asprintf(&printername, "%s\\%s", cli->srv_name_slash, printer) == -1)) {
                DEBUG(3, ("Insufficient memory\n"));
                return WERR_NOMEM;
        }
-       
-       result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, 
-                                            "", MAXIMUM_ALLOWED_ACCESS, 
-                                            servername, cli->user_name, &pol);
+
+       result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
+                                              printername,
+                                              SEC_FLAG_MAXIMUM_ALLOWED,
+                                              &pol);
        if (!W_ERROR_IS_OK(result)) {
                DEBUG(3, ("Unable to open printer %s, error is %s.\n",
-                         printername, dos_errstr(result)));
+                         printername, win_errstr(result)));
+               SAFE_FREE(printername);
                return result;
        }
-       
-       result = cli_spoolss_enumprinterdataex(cli, mem_ctx, 0, &needed, 
-                                              &pol, SPOOL_DSDRIVER_KEY, NULL);
 
-       if (W_ERROR_V(result) == ERRmoredata)
-               result = cli_spoolss_enumprinterdataex(cli, mem_ctx, needed, 
-                                                      NULL, &pol, 
-                                                      SPOOL_DSDRIVER_KEY,
-                                                      &dsdriver_ctr);
+       result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol,
+                                                 SPOOL_DSDRIVER_KEY,
+                                                 0,
+                                                 &count,
+                                                 &info);
 
        if (!W_ERROR_IS_OK(result)) {
                DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
-                         printername, dos_errstr(result)));
+                         printername, win_errstr(result)));
        } else {
-
                /* Have the data we need now, so start building */
-               got_dsdriver = True;
-               for (i=0; i < dsdriver_ctr.num_values; i++)
-                       map_regval_to_ads(mem_ctx, mods, 
-                                         dsdriver_ctr.values[i]);
-       }
-       
-       result = cli_spoolss_enumprinterdataex(cli, mem_ctx, 0, &needed, 
-                                              &pol, SPOOL_DSSPOOLER_KEY, 
-                                              NULL);
+               for (i=0; i < count; i++) {
+                       struct regval_blob *v;
+
+                       v = regval_compose(mem_ctx, info[i].value_name,
+                                          info[i].type,
+                                          info[i].data->data,
+                                          info[i].data->length);
+                       if (v == NULL) {
+                               return WERR_NOMEM;
+                       }
 
-       if (W_ERROR_V(result) == ERRmoredata)
-               result = cli_spoolss_enumprinterdataex(cli, mem_ctx, needed, 
-                                                      NULL, &pol, 
-                                                      SPOOL_DSSPOOLER_KEY,
-                                                      &dsspooler_ctr);
+                       map_regval_to_ads(mem_ctx, mods, v);
+                       talloc_free(v);
+               }
+       }
 
+       result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol,
+                                                 SPOOL_DSSPOOLER_KEY,
+                                                 0,
+                                                 &count,
+                                                 &info);
        if (!W_ERROR_IS_OK(result)) {
                DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
-                         printername, dos_errstr(result)));
+                         printername, win_errstr(result)));
        } else {
-               got_dsspooler = True;
-               for (i=0; i < dsspooler_ctr.num_values; i++)
-                       map_regval_to_ads(mem_ctx, mods, 
-                                         dsspooler_ctr.values[i]);
+               for (i=0; i < count; i++) {
+                       struct regval_blob *v;
+
+                       v = regval_compose(mem_ctx, info[i].value_name,
+                                          info[i].type,
+                                          info[i].data->data,
+                                          info[i].data->length);
+                       if (v == NULL) {
+                               return WERR_NOMEM;
+                       }
+
+                       map_regval_to_ads(mem_ctx, mods, v);
+                       talloc_free(v);
+               }
        }
-       
+
        ads_mod_str(mem_ctx, mods, SPOOL_REG_PRINTERNAME, printer);
 
-       if (got_dsdriver) regval_ctr_destroy(&dsdriver_ctr);
-       if (got_dsspooler) regval_ctr_destroy(&dsspooler_ctr);
-       cli_spoolss_close_printer(cli, mem_ctx, &pol);
+       rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
+       SAFE_FREE(printername);
 
        return result;
 }
 
-BOOL get_local_printer_publishing_data(TALLOC_CTX *mem_ctx,
-                                      ADS_MODLIST *mods,
-                                      NT_PRINTER_DATA *data)
-{
-       uint32 key,val;
-
-       for (key=0; key < data->num_keys; key++) {
-               REGVAL_CTR ctr = data->keys[key].values;
-               for (val=0; val < ctr.num_values; val++)
-                       map_regval_to_ads(mem_ctx, mods, ctr.values[val]);
-       }
-       return True;
-}
-
 #endif
-