s3-spoolss: in spoolss_EnumPrinters r->in.server is a *unique* pointer!
[abartlet/samba.git/.git] / source3 / rpc_server / srv_spoolss_nt.c
index 7a4c9c92638312517ee221446acd4d04b59b2cba..30bedc69e15059f8d5a23ca985bd2266fdd3f962 100644 (file)
@@ -2270,8 +2270,8 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
 
        if (!StrCaseCmp(value, "Architecture")) {
                *type = REG_SZ;
-
-               data->string = talloc_strdup(mem_ctx, "Windows NT x86");
+               data->string = talloc_strdup(mem_ctx,
+                       lp_parm_const_string(GLOBAL_SECTION_SNUM, "spoolss", "architecture", SPOOLSS_ARCHITECTURE_NT_X86));
                W_ERROR_HAVE_NO_MEMORY(data->string);
 
                return WERR_OK;
@@ -4281,7 +4281,7 @@ static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
 WERROR _spoolss_EnumPrinters(pipes_struct *p,
                             struct spoolss_EnumPrinters *r)
 {
-       const char *name;
+       const char *name = NULL;
        WERROR result;
 
        /* that's an [in out] buffer */
@@ -4309,8 +4309,10 @@ WERROR _spoolss_EnumPrinters(pipes_struct *p,
         * Level 5: same as Level 2
         */
 
-       name = talloc_strdup_upper(p->mem_ctx, r->in.server);
-       W_ERROR_HAVE_NO_MEMORY(name);
+       if (name) {
+               name = talloc_strdup_upper(p->mem_ctx, r->in.server);
+               W_ERROR_HAVE_NO_MEMORY(name);
+       }
 
        switch (r->in.level) {
        case 0:
@@ -4842,6 +4844,8 @@ static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
 
        return WERR_OK;
 }
+
+#if 0 /* disabled until marshalling issues are resolved - gd */
 /********************************************************************
  ********************************************************************/
 
@@ -4960,7 +4964,7 @@ static WERROR spoolss_DriverFileInfo_from_driver(TALLOC_CTX *mem_ctx,
 }
 
 /********************************************************************
- * fill a spoolss_DriverInfo101 sttruct
+ * fill a spoolss_DriverInfo101 struct
  ********************************************************************/
 
 static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
@@ -5015,7 +5019,7 @@ static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
 
        return WERR_OK;
 }
-
+#endif
 /********************************************************************
  ********************************************************************/
 
@@ -5090,9 +5094,11 @@ static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
        case 8:
                result = fill_printer_driver_info8(mem_ctx, &r->info8, driver, servername);
                break;
+#if 0 /* disabled until marshalling issues are resolved - gd */
        case 101:
                result = fill_printer_driver_info101(mem_ctx, &r->info101, driver, servername);
                break;
+#endif
        default:
                result = WERR_UNKNOWN_LEVEL;
                break;
@@ -6110,6 +6116,27 @@ static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
        return WERR_OK;
 }
 
+/****************************************************************************
+fill_job_info3
+****************************************************************************/
+
+static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
+                            struct spoolss_JobInfo3 *r,
+                            const print_queue_struct *queue,
+                            const print_queue_struct *next_queue,
+                            int position, int snum,
+                            const NT_PRINTER_INFO_LEVEL *ntprinter)
+{
+       r->job_id               = queue->job;
+       r->next_job_id          = 0;
+       if (next_queue) {
+               r->next_job_id  = next_queue->job;
+       }
+       r->reserved             = 0;
+
+       return WERR_OK;
+}
+
 /****************************************************************************
  Enumjobs at level 1.
 ****************************************************************************/
@@ -6208,6 +6235,57 @@ static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
        return WERR_OK;
 }
 
+/****************************************************************************
+ Enumjobs at level 3.
+****************************************************************************/
+
+static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
+                             const print_queue_struct *queue,
+                             uint32_t num_queues, int snum,
+                              const NT_PRINTER_INFO_LEVEL *ntprinter,
+                             union spoolss_JobInfo **info_p,
+                             uint32_t *count)
+{
+       union spoolss_JobInfo *info;
+       int i;
+       WERROR result = WERR_OK;
+
+       info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
+       W_ERROR_HAVE_NO_MEMORY(info);
+
+       *count = num_queues;
+
+       for (i=0; i<*count; i++) {
+               const print_queue_struct *next_queue = NULL;
+
+               if (i+1 < *count) {
+                       next_queue = &queue[i+1];
+               }
+
+               result = fill_job_info3(info,
+                                       &info[i].info3,
+                                       &queue[i],
+                                       next_queue,
+                                       i,
+                                       snum,
+                                       ntprinter);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto out;
+               }
+       }
+
+ out:
+       if (!W_ERROR_IS_OK(result)) {
+               TALLOC_FREE(info);
+               *count = 0;
+               return result;
+       }
+
+       *info_p = info;
+
+       return WERR_OK;
+}
+
 /****************************************************************
  _spoolss_EnumJobs
 ****************************************************************/
@@ -6264,6 +6342,10 @@ WERROR _spoolss_EnumJobs(pipes_struct *p,
                result = enumjobs_level2(p->mem_ctx, queue, count, snum,
                                         ntprinter, r->out.info, r->out.count);
                break;
+       case 3:
+               result = enumjobs_level3(p->mem_ctx, queue, count, snum,
+                                        ntprinter, r->out.info, r->out.count);
+               break;
        default:
                result = WERR_UNKNOWN_LEVEL;
                break;
@@ -7056,6 +7138,15 @@ static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
                return WERR_NOMEM;
        }
 
+       /* samba does not have a concept of local, non-shared printers yet, so
+        * make sure we always setup sharename - gd */
+       if ((printer->info_2->sharename[0] == '\0') && (printer->info_2->printername != '\0')) {
+               DEBUG(5, ("spoolss_addprinterex_level_2: "
+                       "no sharename has been set, setting printername %s as sharename\n",
+                       printer->info_2->printername));
+               fstrcpy(printer->info_2->sharename, printer->info_2->printername);
+       }
+
        /* check to see if the printer already exists */
 
        if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
@@ -7065,6 +7156,37 @@ static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
                return WERR_PRINTER_ALREADY_EXISTS;
        }
 
+       if (!lp_force_printername(GLOBAL_SECTION_SNUM)) {
+               if ((snum = print_queue_snum(printer->info_2->printername)) != -1) {
+                       DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
+                               printer->info_2->printername));
+                       free_a_printer(&printer, 2);
+                       return WERR_PRINTER_ALREADY_EXISTS;
+               }
+       }
+
+       /* validate printer info struct */
+       if (!info_ctr->info.info2->printername ||
+           strlen(info_ctr->info.info2->printername) == 0) {
+               free_a_printer(&printer,2);
+               return WERR_INVALID_PRINTER_NAME;
+       }
+       if (!info_ctr->info.info2->portname ||
+           strlen(info_ctr->info.info2->portname) == 0) {
+               free_a_printer(&printer,2);
+               return WERR_UNKNOWN_PORT;
+       }
+       if (!info_ctr->info.info2->drivername ||
+           strlen(info_ctr->info.info2->drivername) == 0) {
+               free_a_printer(&printer,2);
+               return WERR_UNKNOWN_PRINTER_DRIVER;
+       }
+       if (!info_ctr->info.info2->printprocessor ||
+           strlen(info_ctr->info.info2->printprocessor) == 0) {
+               free_a_printer(&printer,2);
+               return WERR_UNKNOWN_PRINTPROCESSOR;
+       }
+
        /* FIXME!!!  smbd should check to see if the driver is installed before
           trying to add a printer like this  --jerry */