r5539: more bad name checks and don't check for \\localhost and \\127.0.0.1
[samba.git] / source4 / torture / rpc / spoolss.c
index 8e4ea15677ed32c10749a99e3e0b24b376b101a8..869b0abc6c3538a1244e13168ae5439d1c645f0d 100644 (file)
@@ -27,7 +27,7 @@ static BOOL test_GetPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 {
        NTSTATUS status;
        struct spoolss_GetPrinter r;
-       uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7};
+       uint16_t levels[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
        int i;
        BOOL ret = True;
        
@@ -482,8 +482,12 @@ static BOOL test_GetPrinterDataEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        printf("Testing GetPrinterDataEx\n");
 
        status = dcerpc_spoolss_GetPrinterDataEx(p, mem_ctx, &r);
-
        if (!NT_STATUS_IS_OK(status)) {
+               if (NT_STATUS_EQUAL(status,NT_STATUS_NET_WRITE_FAULT) &&
+                   p->last_fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
+                       printf("GetPrinterDataEx not supported by server\n");
+                       return True;
+               }
                printf("GetPrinterDataEx failed - %s\n", nt_errstr(status));
                return False;
        }
@@ -640,34 +644,111 @@ static BOOL test_SecondaryClosePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct
        return ret;
 }
 
+static BOOL test_OpenPrinter_badname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, const char *name)
+{
+       NTSTATUS status;
+       struct spoolss_OpenPrinter op;
+       struct spoolss_OpenPrinterEx opEx;
+       struct policy_handle handle;
+       BOOL ret = True;
+
+       op.in.printername       = name;
+       op.in.datatype          = NULL;
+       op.in.devmode_ctr.size  = 0;
+       op.in.devmode_ctr.devmode= NULL;
+       op.in.access_mask       = 0;
+       op.out.handle           = &handle;
+
+       printf("\nTesting OpenPrinter(%s) with bad name\n", op.in.printername);
+
+       status = dcerpc_spoolss_OpenPrinter(p, mem_ctx, &op);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("OpenPrinter failed - %s\n", nt_errstr(status));
+               ret = False;
+       }
+       if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME,op.out.result)) {
+               printf("OpenPrinter(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
+                       name, win_errstr(op.out.result));
+       }
+
+       if (W_ERROR_IS_OK(op.out.result)) {
+               ret &=test_ClosePrinter(p, mem_ctx, &handle);
+       }
+
+       opEx.in.printername             = name;
+       opEx.in.datatype                = NULL;
+       opEx.in.devmode_ctr.size        = 0;
+       opEx.in.devmode_ctr.devmode     = NULL;
+       opEx.in.access_mask             = 0;
+       opEx.in.level                   = 1;
+       opEx.in.userlevel.level1        = NULL;
+       opEx.out.handle                 = &handle;
+
+       printf("\nTesting OpenPrinterEx(%s) with bad name\n", opEx.in.printername);
+
+       status = dcerpc_spoolss_OpenPrinterEx(p, mem_ctx, &opEx);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("OpenPrinter failed - %s\n", nt_errstr(status));
+               ret = False;
+       }
+       if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME,opEx.out.result)) {
+               printf("OpenPrinterEx(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n",
+                       name, win_errstr(opEx.out.result));
+       }
+
+       if (W_ERROR_IS_OK(opEx.out.result)) {
+               ret &=test_ClosePrinter(p, mem_ctx, &handle);
+       }
+
+       return ret;
+}
+
+static BOOL test_OpenPrinter_badnames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
+{
+       BOOL ret = True;
+       char *name;
+
+       ret &= test_OpenPrinter_badname(p, mem_ctx, "__INVALID_PRINTER__");
+       ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\__INVALID_HOST__");
+       ret &= test_OpenPrinter_badname(p, mem_ctx, "");
+       ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\\\");
+       ret &= test_OpenPrinter_badname(p, mem_ctx, "\\\\\\__INVALID_PRINTER__");
+
+       name = talloc_asprintf(mem_ctx, "\\\\%s\\", dcerpc_server_name(p));
+       ret &= test_OpenPrinter_badname(p, mem_ctx, name);
+       talloc_free(name);
+
+       name = talloc_asprintf(mem_ctx, "\\\\%s\\__INVALID_PRINTER__", dcerpc_server_name(p));
+       ret &= test_OpenPrinter_badname(p, mem_ctx, name);
+       talloc_free(name);
+
+       return ret;
+}
+
 static BOOL test_OpenPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                             const char *name)
 {
        NTSTATUS status;
        struct spoolss_OpenPrinter r;
        struct policy_handle handle;
-       DATA_BLOB blob;
        BOOL ret = True;
 
-       blob = data_blob(NULL, 0);
-
-       r.in.server = talloc_asprintf(mem_ctx, "\\\\%s\\%s", dcerpc_server_name(p), name);
-       r.in.printer = NULL;
-       r.in.buffer = &blob;
-       r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;    
-       r.out.handle = &handle;
+       r.in.printername        = talloc_asprintf(mem_ctx, "\\\\%s\\%s", dcerpc_server_name(p), name);
+       r.in.datatype           = NULL;
+       r.in.devmode_ctr.size   = 0;
+       r.in.devmode_ctr.devmode= NULL;
+       r.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
+       r.out.handle            = &handle;
 
-       printf("\nTesting OpenPrinter(%s)\n", r.in.server);
+       printf("\nTesting OpenPrinter(%s)\n", r.in.printername);
 
        status = dcerpc_spoolss_OpenPrinter(p, mem_ctx, &r);
        if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(r.out.result)) {
                printf("OpenPrinter failed - %s/%s\n", 
                       nt_errstr(status), win_errstr(r.out.result));
-               /* don't consider failing this an error until we understand it */
-               return True;
+               return False;
        }
 
-
        if (!test_GetPrinter(p, mem_ctx, &handle)) {
                ret = False;
        }
@@ -679,7 +760,7 @@ static BOOL test_OpenPrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        if (!test_ClosePrinter(p, mem_ctx, &handle)) {
                ret = False;
        }
-       
+
        return ret;
 }
 
@@ -690,18 +771,20 @@ static BOOL call_OpenPrinterEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        struct spoolss_UserLevel1 userlevel1;
        NTSTATUS status;
 
-       if (name && name[0])
+       if (name && name[0]) {
                r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s", 
                                                   dcerpc_server_name(p), name);
-       else
+       } else {
                r.in.printername = talloc_asprintf(mem_ctx, "\\\\%s", 
                                                   dcerpc_server_name(p));
+       }
 
-       r.in.datatype = NULL;
-       r.in.devmode_ctr.size = 0;
-       r.in.devmode_ctr.devmode = NULL;
-       r.in.access_mask = 0x02000000;
-       r.in.level = 1;
+       r.in.datatype           = NULL;
+       r.in.devmode_ctr.size   = 0;
+       r.in.devmode_ctr.devmode= NULL;
+       r.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
+       r.in.level              = 1;
+       r.in.userlevel.level1   = &userlevel1;
        r.out.handle = handle;
 
        userlevel1.size = 1234;
@@ -711,7 +794,6 @@ static BOOL call_OpenPrinterEx(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
        userlevel1.major = 2;
        userlevel1.minor = 3;
        userlevel1.processor = 4;
-       r.in.userlevel.level1 = &userlevel1;
 
        printf("Testing OpenPrinterEx(%s)\n", r.in.printername);
 
@@ -788,12 +870,12 @@ static BOOL test_EnumPrinters(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
                union spoolss_PrinterInfo *info;
                int j;
 
-               r.in.flags = 0x02;
-               r.in.server = "";
-               r.in.level = levels[i];
-               r.in.buffer = NULL;
-               r.in.buf_size = &buf_size;
-               r.out.buf_size = &buf_size;
+               r.in.flags      = PRINTER_ENUM_LOCAL;
+               r.in.server     = "";
+               r.in.level      = levels[i];
+               r.in.buffer     = NULL;
+               r.in.buf_size   = &buf_size;
+               r.out.buf_size  = &buf_size;
 
                printf("\nTesting EnumPrinters level %u\n", r.in.level);
 
@@ -803,14 +885,14 @@ static BOOL test_EnumPrinters(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
                        ret = False;
                        continue;
                }
-               
+
                if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
                        DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, buf_size);
                        data_blob_clear(&blob);
                        r.in.buffer = &blob;
                        status = dcerpc_spoolss_EnumPrinters(p, mem_ctx, &r);
                }
-               
+
                if (!NT_STATUS_IS_OK(status) ||
                    !W_ERROR_IS_OK(r.out.result)) {
                        printf("EnumPrinters failed - %s/%s\n", 
@@ -840,10 +922,11 @@ static BOOL test_EnumPrinters(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
                        }
                }
        }
-       
+
        return ret;
 }
 
+#if 0
 static BOOL test_GetPrinterDriver2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
                                   struct policy_handle *handle, 
                                   const char *driver_name)
@@ -883,19 +966,18 @@ static BOOL test_GetPrinterDriver2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
 
        return True;
 }
+#endif
        
 static BOOL test_EnumPrinterDrivers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
 {
        struct spoolss_EnumPrinterDrivers r;
        NTSTATUS status;
-       uint16_t levels[] = {1, 2, 3};
+       uint16_t levels[] = {1, 2, 3, 4, 5, 6};
        int i;
        BOOL ret = True;
 
        for (i=0;i<ARRAY_SIZE(levels);i++) {
                uint32_t buf_size;
-               union spoolss_DriverInfo *info;
-               uint32_t j;
 
                r.in.server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
                r.in.environment = "Windows NT x86";
@@ -929,6 +1011,7 @@ static BOOL test_EnumPrinterDrivers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
                    !W_ERROR_IS_OK(r.out.result)) {
                        printf("EnumPrinterDrivers failed - %s/%s\n", 
                               nt_errstr(status), win_errstr(r.out.result));
+                       ret = False;
                        break;
                }
 
@@ -936,19 +1019,6 @@ static BOOL test_EnumPrinterDrivers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
                        printf("No printer drivers returned");
                        break;
                }
-
-               info = *r.out.info;
-
-               if (r.in.level != 1) continue;
-
-               for (j=0;j<r.out.count;j++) {
-                       struct policy_handle handle;
-
-                       if (!call_OpenPrinterEx(p, mem_ctx, "",&handle)) {
-                               continue;
-                       }
-                       ret &=test_GetPrinterDriver2(p, mem_ctx, &handle, info[j].info1.driver_name);
-               }
        }
 
        return ret;
@@ -971,18 +1041,14 @@ BOOL torture_rpc_spoolss(void)
 
        mem_ctx = talloc_init("torture_rpc_spoolss");
 
-       if (!test_EnumPorts(p, mem_ctx)) {
-               ret = False;
-       }
+       ret &= test_OpenPrinter_badnames(p, mem_ctx);
 
-       if (!test_EnumPrinters(p, mem_ctx)) {
-               ret = False;
-       }
+       ret &= test_EnumPorts(p, mem_ctx);
+
+       ret &= test_EnumPrinters(p, mem_ctx);
+
+       ret &= test_EnumPrinterDrivers(p, mem_ctx);
 
-       if (!test_EnumPrinterDrivers(p, mem_ctx)) {
-               ret = False;
-       }
-printf("blub\n");
        talloc_free(mem_ctx);
 
         torture_rpc_close(p);