r23779: Change from v2 or later to v3 or later.
[amitay/samba.git] / source3 / libads / ldap_printer.c
index 1edc933683b8b0a902d4d3d1bd84c20f0e67daa7..cf6e1e08b017a05a659e77b9c081fe6b88c0cb42 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,
     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;
        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;
        }
+       if (ads_count_replies(ads, *res) != 1) {
+               return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
+       }
        srv_dn = ldap_get_dn(ads->ld, *res);
+       if (srv_dn == NULL) {
+               return ADS_ERROR(LDAP_NO_MEMORY);
+       }
        srv_cn = ldap_explode_dn(srv_dn, 1);
+       if (srv_cn == NULL) {
+               ldap_memfree(srv_dn);
+               return ADS_ERROR(LDAP_INVALID_DN_SYNTAX);
+       }
        ads_msgfree(ads, *res);
 
-       asprintf(&exp, "(cn=%s-%s)", srv_cn[0], printer);
-       status = ads_search(ads, res, exp, attrs);
+       asprintf(&s, "(cn=%s-%s)", srv_cn[0], printer);
+       status = ads_search(ads, res, s, attrs);
 
        ldap_memfree(srv_dn);
        ldap_value_free(srv_cn);
-       free(exp);
+       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
 */
@@ -85,8 +110,7 @@ static BOOL map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods,
                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);
+               pull_ucs2_talloc(ctx, &str_value, (const smb_ucs2_t *) value->data_p);
                status = ads_mod_str(ctx, mods, value->valuename, str_value);
                return ADS_ERR_OK(status);
        }
@@ -106,6 +130,9 @@ static BOOL map_dword(TALLOC_CTX *ctx, ADS_MODLIST *mods,
        if (value->type != REG_DWORD)
                return False;
        str_value = talloc_asprintf(ctx, "%d", *((uint32 *) value->data_p));
+       if (!str_value) {
+               return False;
+       }
        status = ads_mod_str(ctx, mods, value->valuename, str_value);
        return ADS_ERR_OK(status);
 }
@@ -123,6 +150,9 @@ static BOOL map_bool(TALLOC_CTX *ctx, ADS_MODLIST *mods,
                return False;
        str_value =  talloc_asprintf(ctx, "%s", 
                                     *(value->data_p) ? "TRUE" : "FALSE");
+       if (!str_value) {
+               return False;
+       }
        status = ads_mod_str(ctx, mods, value->valuename, str_value);
        return ADS_ERR_OK(status);
 }
@@ -148,16 +178,17 @@ static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods,
        };
 
        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 += pull_ucs2_talloc(ctx, &str_values[i],
+                                                   cur_str);
 
                status = ads_mod_strlist(ctx, mods, value->valuename, 
                                         (const char **) str_values);
@@ -167,7 +198,7 @@ static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods,
 }
 
 struct valmap_to_ads {
-       char *valname;
+       const char *valname;
        BOOL (*fn)(TALLOC_CTX *, ADS_MODLIST *, const REGISTRY_VALUE *);
 };
 
@@ -177,58 +208,59 @@ struct valmap_to_ads {
 static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods, 
                              REGISTRY_VALUE *value)
 {
-       struct valmap_to_ads map[] = {
-               {"assetNumber", map_sz},
-               {"bytesPerMinute", map_dword},
-               {"defaultPriority", map_dword},
-               {"driverName", map_sz},
-               {"driverVersion", map_dword},
-               {"flags", map_dword},
-               {"location", map_sz},
-               {"operatingSystem", map_sz},
-               {"operatingSystemHotfix", map_sz},
-               {"operatingSystemServicePack", map_sz},
-               {"operatingSystemVersion", map_sz},
-               {"portName", map_multi_sz},
-               {"printAttributes", map_dword},
-               {"printBinNames", map_multi_sz},
-               {"printCollate", map_bool},
-               {"printColor", map_bool},
-               {"printDuplexSupported", map_bool},
-               {"printEndTime", map_dword},
-               {"printFormName", map_sz},
-               {"printKeepPrintedJobs", map_bool},
-               {"printLanguage", map_multi_sz},
-               {"printMACAddress", map_sz},
-               {"printMaxCopies", map_sz},
-               {"printMaxResolutionSupported", map_dword},
-               {"printMaxXExtent", map_dword},
-               {"printMaxYExtent", map_dword},
-               {"printMediaReady", map_multi_sz},
-               {"printMediaSupported", map_multi_sz},
-               {"printMemory", map_dword},
-               {"printMinXExtent", map_dword},
-               {"printMinYExtent", map_dword},
-               {"printNetworkAddress", map_sz},
-               {"printNotify", map_sz},
-               {"printNumberUp", map_dword},
-               {"printOrientationsSupported", map_multi_sz},
-               {"printOwner", map_sz},
-               {"printPagesPerMinute", map_dword},
-               {"printRate", map_dword},
-               {"printRateUnit", map_sz},
-               {"printSeparatorFile", map_sz},
-               {"printShareName", map_sz},
-               {"printSpooling", map_sz},
-               {"printStaplingSupported", map_bool},
-               {"printStartTime", map_dword},
-               {"printStatus", map_sz},
-               {"priority", map_dword},
-               {"serverName", map_sz},
-               {"shortServerName", map_sz},
-               {"uNCName", map_sz},
-               {"url", map_sz},
-               {"versionNumber", map_dword},
+       const struct valmap_to_ads map[] = {
+               {SPOOL_REG_ASSETNUMBER, map_sz},
+               {SPOOL_REG_BYTESPERMINUTE, map_dword},
+               {SPOOL_REG_DEFAULTPRIORITY, map_dword},
+               {SPOOL_REG_DESCRIPTION, map_sz},
+               {SPOOL_REG_DRIVERNAME, map_sz},
+               {SPOOL_REG_DRIVERVERSION, map_dword},
+               {SPOOL_REG_FLAGS, map_dword},
+               {SPOOL_REG_LOCATION, map_sz},
+               {SPOOL_REG_OPERATINGSYSTEM, map_sz},
+               {SPOOL_REG_OPERATINGSYSTEMHOTFIX, map_sz},
+               {SPOOL_REG_OPERATINGSYSTEMSERVICEPACK, map_sz},
+               {SPOOL_REG_OPERATINGSYSTEMVERSION, map_sz},
+               {SPOOL_REG_PORTNAME, map_multi_sz},
+               {SPOOL_REG_PRINTATTRIBUTES, map_dword},
+               {SPOOL_REG_PRINTBINNAMES, map_multi_sz},
+               {SPOOL_REG_PRINTCOLLATE, map_bool},
+               {SPOOL_REG_PRINTCOLOR, map_bool},
+               {SPOOL_REG_PRINTDUPLEXSUPPORTED, map_bool},
+               {SPOOL_REG_PRINTENDTIME, map_dword},
+               {SPOOL_REG_PRINTFORMNAME, map_sz},
+               {SPOOL_REG_PRINTKEEPPRINTEDJOBS, map_bool},
+               {SPOOL_REG_PRINTLANGUAGE, map_multi_sz},
+               {SPOOL_REG_PRINTMACADDRESS, map_sz},
+               {SPOOL_REG_PRINTMAXCOPIES, map_sz},
+               {SPOOL_REG_PRINTMAXRESOLUTIONSUPPORTED, map_dword},
+               {SPOOL_REG_PRINTMAXXEXTENT, map_dword},
+               {SPOOL_REG_PRINTMAXYEXTENT, map_dword},
+               {SPOOL_REG_PRINTMEDIAREADY, map_multi_sz},
+               {SPOOL_REG_PRINTMEDIASUPPORTED, map_multi_sz},
+               {SPOOL_REG_PRINTMEMORY, map_dword},
+               {SPOOL_REG_PRINTMINXEXTENT, map_dword},
+               {SPOOL_REG_PRINTMINYEXTENT, map_dword},
+               {SPOOL_REG_PRINTNETWORKADDRESS, map_sz},
+               {SPOOL_REG_PRINTNOTIFY, map_sz},
+               {SPOOL_REG_PRINTNUMBERUP, map_dword},
+               {SPOOL_REG_PRINTORIENTATIONSSUPPORTED, map_multi_sz},
+               {SPOOL_REG_PRINTOWNER, map_sz},
+               {SPOOL_REG_PRINTPAGESPERMINUTE, map_dword},
+               {SPOOL_REG_PRINTRATE, map_dword},
+               {SPOOL_REG_PRINTRATEUNIT, map_sz},
+               {SPOOL_REG_PRINTSEPARATORFILE, map_sz},
+               {SPOOL_REG_PRINTSHARENAME, map_sz},
+               {SPOOL_REG_PRINTSPOOLING, map_sz},
+               {SPOOL_REG_PRINTSTAPLINGSUPPORTED, map_bool},
+               {SPOOL_REG_PRINTSTARTTIME, map_dword},
+               {SPOOL_REG_PRINTSTATUS, map_sz},
+               {SPOOL_REG_PRIORITY, map_dword},
+               {SPOOL_REG_SERVERNAME, map_sz},
+               {SPOOL_REG_SHORTSERVERNAME, map_sz},
+               {SPOOL_REG_UNCNAME, map_sz},
+               {SPOOL_REG_URL, map_sz},
+               {SPOOL_REG_VERSIONNUMBER, map_dword},
                {NULL, NULL}
        };
        int i;
@@ -246,76 +278,72 @@ 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;
-       uint32 needed, i;
+       REGVAL_CTR *dsdriver_ctr, *dsspooler_ctr;
+       uint32 i;
        POLICY_HND pol;
 
-       asprintf(&servername, "\\\\%s", cli->desthost);
+       asprintf(&servername, "\\\\%s", cli->cli->desthost);
        asprintf(&printername, "%s\\%s", servername, printer);
        if (!servername || !printername) {
                DEBUG(3, ("Insufficient memory\n"));
                return WERR_NOMEM;
        }
        
-       result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, 
+       result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, 
                                             "", MAXIMUM_ALLOWED_ACCESS, 
-                                            servername, cli->user_name, &pol);
+                                            servername, cli->cli->user_name, &pol);
        if (!W_ERROR_IS_OK(result)) {
                DEBUG(3, ("Unable to open printer %s, error is %s.\n",
                          printername, dos_errstr(result)));
                return result;
        }
        
-       result = cli_spoolss_enumprinterdataex(cli, mem_ctx, 0, &needed, 
-                                              &pol, "DsDriver", NULL);
+       if ( !(dsdriver_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) ) 
+               return WERR_NOMEM;
 
-       if (W_ERROR_V(result) == ERRmoredata)
-               result = cli_spoolss_enumprinterdataex(cli, mem_ctx, needed, 
-                                                      NULL, &pol, "DsDriver",
-                                                      &dsdriver_ctr);
+       result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSDRIVER_KEY, dsdriver_ctr);
 
        if (!W_ERROR_IS_OK(result)) {
                DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
                          printername, dos_errstr(result)));
-               cli_spoolss_close_printer(cli, mem_ctx, &pol);
-               return result;
-       }
+       } else {
+               uint32 num_values = regval_ctr_numvals( dsdriver_ctr );
 
-       /* Have the data we need now, so start building */
-
-       for (i=0; i < dsdriver_ctr.num_values; i++)
-               map_regval_to_ads(mem_ctx, mods, dsdriver_ctr.values[i]);
+               /* Have the data we need now, so start building */
+               for (i=0; i < num_values; i++) {
+                       map_regval_to_ads(mem_ctx, mods, dsdriver_ctr->values[i]);
+               }
+       }
        
-       result = cli_spoolss_enumprinterdataex(cli, mem_ctx, 0, &needed, 
-                                              &pol, "DsSpooler", NULL);
+       if ( !(dsspooler_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) )
+               return WERR_NOMEM;
 
-       if (W_ERROR_V(result) == ERRmoredata)
-               result = cli_spoolss_enumprinterdataex(cli, mem_ctx, needed, 
-                                                      NULL, &pol, "DsSpooler",
-                                                      &dsspooler_ctr);
+       result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSSPOOLER_KEY, dsspooler_ctr);
 
        if (!W_ERROR_IS_OK(result)) {
                DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
                          printername, dos_errstr(result)));
-               regval_ctr_destroy(&dsdriver_ctr);
-               cli_spoolss_close_printer(cli, mem_ctx, &pol);
-               return result;
+       } else {
+               uint32 num_values = regval_ctr_numvals( dsspooler_ctr );
+
+               for (i=0; i<num_values; i++) {
+                       map_regval_to_ads(mem_ctx, mods, dsspooler_ctr->values[i]);
+               }
        }
-       for (i=0; i < dsspooler_ctr.num_values; i++)
-               map_regval_to_ads(mem_ctx, mods, dsspooler_ctr.values[i]);
        
-       ads_mod_str(mem_ctx, mods, "printerName", printername);
+       ads_mod_str(mem_ctx, mods, SPOOL_REG_PRINTERNAME, printer);
+
+       TALLOC_FREE( dsdriver_ctr );
+       TALLOC_FREE( dsspooler_ctr );
 
-       regval_ctr_destroy(&dsdriver_ctr);
-       regval_ctr_destroy(&dsspooler_ctr);
-       cli_spoolss_close_printer(cli, mem_ctx, &pol);
+       rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
 
        return result;
 }
@@ -327,12 +355,11 @@ BOOL get_local_printer_publishing_data(TALLOC_CTX *mem_ctx,
        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]);
+               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
-