s3-secrets: only include secrets.h when needed.
[samba.git] / source3 / rpc_server / srv_spoolss_util.c
index b70090f44b34659bda4350b808134b199bc062df..ab6be2f69d02c9345a071b70111bdc3a215408d4 100644 (file)
  */
 
 #include "includes.h"
+#include "nt_printing.h"
 #include "srv_spoolss_util.h"
+#include "../librpc/gen_ndr/ndr_spoolss.h"
 #include "../librpc/gen_ndr/srv_winreg.h"
 #include "../librpc/gen_ndr/cli_winreg.h"
+#include "../librpc/gen_ndr/ndr_security.h"
+#include "secrets.h"
 
 #define TOP_LEVEL_PRINT_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print"
 #define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers"
 
 #define EMPTY_STRING ""
 
+#define FILL_STRING(mem_ctx, in, out) \
+       do { \
+               if (in && strlen(in)) { \
+                       out = talloc_strdup(mem_ctx, in); \
+               } else { \
+                       out = talloc_strdup(mem_ctx, ""); \
+               } \
+               W_ERROR_HAVE_NO_MEMORY(out); \
+       } while (0);
+
 #define CHECK_ERROR(result) \
        if (W_ERROR_IS_OK(result)) continue; \
        if (W_ERROR_EQUAL(result, WERR_NOT_FOUND)) result = WERR_OK; \
 
 /*        FLAGS,                NAME,                              with,   height,   left, top, right, bottom */
 static const struct spoolss_FormInfo1 builtin_forms1[] = {
-       { SPOOLSS_FORM_BUILTIN, "Letter",                         {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
-       { SPOOLSS_FORM_BUILTIN, "Letter Small",                   {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
-       { SPOOLSS_FORM_BUILTIN, "Tabloid",                        {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
-       { SPOOLSS_FORM_BUILTIN, "Ledger",                         {0x696b8,0x44368}, {0x0,0x0,0x696b8,0x44368} },
-       { SPOOLSS_FORM_BUILTIN, "Legal",                          {0x34b5c,0x56d10}, {0x0,0x0,0x34b5c,0x56d10} },
-       { SPOOLSS_FORM_BUILTIN, "Statement",                      {0x221b4,0x34b5c}, {0x0,0x0,0x221b4,0x34b5c} },
-       { SPOOLSS_FORM_BUILTIN, "Executive",                      {0x2cf56,0x411cc}, {0x0,0x0,0x2cf56,0x411cc} },
+       { SPOOLSS_FORM_BUILTIN, "10x11",                          {0x3e030,0x44368}, {0x0,0x0,0x3e030,0x44368} },
+       { SPOOLSS_FORM_BUILTIN, "10x14",                          {0x3e030,0x56d10}, {0x0,0x0,0x3e030,0x56d10} },
+       { SPOOLSS_FORM_BUILTIN, "11x17",                          {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
+       { SPOOLSS_FORM_BUILTIN, "12x11",                          {0x4a724,0x443e1}, {0x0,0x0,0x4a724,0x443e1} },
+       { SPOOLSS_FORM_BUILTIN, "15x11",                          {0x5d048,0x44368}, {0x0,0x0,0x5d048,0x44368} },
+       { SPOOLSS_FORM_BUILTIN, "6 3/4 Envelope",                 {0x167ab,0x284ec}, {0x0,0x0,0x167ab,0x284ec} },
+       { SPOOLSS_FORM_BUILTIN, "9x11",                           {0x37cf8,0x44368}, {0x0,0x0,0x37cf8,0x44368} },
+       { SPOOLSS_FORM_BUILTIN, "A0",                             {0xcd528,0x122488},{0x0,0x0,0xcd528,0x122488} },
+       { SPOOLSS_FORM_BUILTIN, "A1",                             {0x91050,0xcd528}, {0x0,0x0,0x91050,0xcd528} },
+       { SPOOLSS_FORM_BUILTIN, "A2",                             {0x668a0,0x91050}, {0x0,0x0,0x668a0,0x91050} },
+       { SPOOLSS_FORM_BUILTIN, "A3 Extra Transverse",            {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
+       { SPOOLSS_FORM_BUILTIN, "A3 Extra",                       {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
+       { SPOOLSS_FORM_BUILTIN, "A3 Rotated",                     {0x668a0,0x48828}, {0x0,0x0,0x668a0,0x48828} },
+       { SPOOLSS_FORM_BUILTIN, "A3 Transverse",                  {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
        { SPOOLSS_FORM_BUILTIN, "A3",                             {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
-       { SPOOLSS_FORM_BUILTIN, "A4",                             {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
+       { SPOOLSS_FORM_BUILTIN, "A4 Extra",                       {0x397c2,0x4eb16}, {0x0,0x0,0x397c2,0x4eb16} },
+       { SPOOLSS_FORM_BUILTIN, "A4 Plus",                        {0x33450,0x50910}, {0x0,0x0,0x33450,0x50910} },
+       { SPOOLSS_FORM_BUILTIN, "A4 Rotated",                     {0x48828,0x33450}, {0x0,0x0,0x48828,0x33450} },
        { SPOOLSS_FORM_BUILTIN, "A4 Small",                       {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
+       { SPOOLSS_FORM_BUILTIN, "A4 Transverse",                  {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
+       { SPOOLSS_FORM_BUILTIN, "A4",                             {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
+       { SPOOLSS_FORM_BUILTIN, "A5 Extra",                       {0x2a7b0,0x395f8}, {0x0,0x0,0x2a7b0,0x395f8} },
+       { SPOOLSS_FORM_BUILTIN, "A5 Rotated",                     {0x33450,0x24220}, {0x0,0x0,0x33450,0x24220} },
+       { SPOOLSS_FORM_BUILTIN, "A5 Transverse",                  {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
        { SPOOLSS_FORM_BUILTIN, "A5",                             {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
+       { SPOOLSS_FORM_BUILTIN, "A6 Rotated",                     {0x24220,0x19a28}, {0x0,0x0,0x24220,0x19a28} },
+       { SPOOLSS_FORM_BUILTIN, "A6",                             {0x19a28,0x24220}, {0x0,0x0,0x19a28,0x24220} },
+       { SPOOLSS_FORM_BUILTIN, "B4 (ISO)",                       {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
+       { SPOOLSS_FORM_BUILTIN, "B4 (JIS) Rotated",               {0x58de0,0x3ebe8}, {0x0,0x0,0x58de0,0x3ebe8} },
        { SPOOLSS_FORM_BUILTIN, "B4 (JIS)",                       {0x3ebe8,0x58de0}, {0x0,0x0,0x3ebe8,0x58de0} },
+       { SPOOLSS_FORM_BUILTIN, "B5 (ISO) Extra",                 {0x31128,0x43620}, {0x0,0x0,0x31128,0x43620} },
+       { SPOOLSS_FORM_BUILTIN, "B5 (JIS) Rotated",               {0x3ebe8,0x2c6f0}, {0x0,0x0,0x3ebe8,0x2c6f0} },
+       { SPOOLSS_FORM_BUILTIN, "B5 (JIS) Transverse",            {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
        { SPOOLSS_FORM_BUILTIN, "B5 (JIS)",                       {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
-       { SPOOLSS_FORM_BUILTIN, "Folio",                          {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
-       { SPOOLSS_FORM_BUILTIN, "Quarto",                         {0x347d8,0x43238}, {0x0,0x0,0x347d8,0x43238} },
-       { SPOOLSS_FORM_BUILTIN, "10x14",                          {0x3e030,0x56d10}, {0x0,0x0,0x3e030,0x56d10} },
-       { SPOOLSS_FORM_BUILTIN, "11x17",                          {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
-       { SPOOLSS_FORM_BUILTIN, "Note",                           {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
-       { SPOOLSS_FORM_BUILTIN, "Envelope #9",                    {0x18079,0x37091}, {0x0,0x0,0x18079,0x37091} },
+       { SPOOLSS_FORM_BUILTIN, "B6 (JIS) Rotated",               {0x2c6f0,0x1f400}, {0x0,0x0,0x2c6f0,0x1f400} },
+       { SPOOLSS_FORM_BUILTIN, "B6 (JIS)",                       {0x1f400,0x2c6f0}, {0x0,0x0,0x1f400,0x2c6f0} },
+       { SPOOLSS_FORM_BUILTIN, "C size sheet",                   {0x696b8,0x886d0}, {0x0,0x0,0x696b8,0x886d0} },
+       { SPOOLSS_FORM_BUILTIN, "D size sheet",                   {0x886d0,0xd2d70}, {0x0,0x0,0x886d0,0xd2d70} },
+       { SPOOLSS_FORM_BUILTIN, "Double Japan Postcard Rotated",  {0x24220,0x30d40}, {0x0,0x0,0x24220,0x30d40} },
+       { SPOOLSS_FORM_BUILTIN, "E size sheet",                   {0xd2d70,0x110da0},{0x0,0x0,0xd2d70,0x110da0} },
        { SPOOLSS_FORM_BUILTIN, "Envelope #10",                   {0x19947,0x3ae94}, {0x0,0x0,0x19947,0x3ae94} },
        { SPOOLSS_FORM_BUILTIN, "Envelope #11",                   {0x1be7c,0x40565}, {0x0,0x0,0x1be7c,0x40565} },
        { SPOOLSS_FORM_BUILTIN, "Envelope #12",                   {0x1d74a,0x44368}, {0x0,0x0,0x1d74a,0x44368} },
        { SPOOLSS_FORM_BUILTIN, "Envelope #14",                   {0x1f018,0x47504}, {0x0,0x0,0x1f018,0x47504} },
-       { SPOOLSS_FORM_BUILTIN, "C size sheet",                   {0x696b8,0x886d0}, {0x0,0x0,0x696b8,0x886d0} },
-       { SPOOLSS_FORM_BUILTIN, "D size sheet",                   {0x886d0,0xd2d70}, {0x0,0x0,0x886d0,0xd2d70} },
-       { SPOOLSS_FORM_BUILTIN, "E size sheet",                   {0xd2d70,0x110da0},{0x0,0x0,0xd2d70,0x110da0} },
-       { SPOOLSS_FORM_BUILTIN, "Envelope DL",                    {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
-       { SPOOLSS_FORM_BUILTIN, "Envelope C5",                    {0x278d0,0x37e88}, {0x0,0x0,0x278d0,0x37e88} },
+       { SPOOLSS_FORM_BUILTIN, "Envelope #9",                    {0x18079,0x37091}, {0x0,0x0,0x18079,0x37091} },
+       { SPOOLSS_FORM_BUILTIN, "Envelope B4",                    {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
+       { SPOOLSS_FORM_BUILTIN, "Envelope B5",                    {0x2af80,0x3d090}, {0x0,0x0,0x2af80,0x3d090} },
+       { SPOOLSS_FORM_BUILTIN, "Envelope B6",                    {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
        { SPOOLSS_FORM_BUILTIN, "Envelope C3",                    {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} },
        { SPOOLSS_FORM_BUILTIN, "Envelope C4",                    {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
+       { SPOOLSS_FORM_BUILTIN, "Envelope C5",                    {0x278d0,0x37e88}, {0x0,0x0,0x278d0,0x37e88} },
        { SPOOLSS_FORM_BUILTIN, "Envelope C6",                    {0x1bd50,0x278d0}, {0x0,0x0,0x1bd50,0x278d0} },
        { SPOOLSS_FORM_BUILTIN, "Envelope C65",                   {0x1bd50,0x37e88}, {0x0,0x0,0x1bd50,0x37e88} },
-       { SPOOLSS_FORM_BUILTIN, "Envelope B4",                    {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
-       { SPOOLSS_FORM_BUILTIN, "Envelope B5",                    {0x2af80,0x3d090}, {0x0,0x0,0x2af80,0x3d090} },
-       { SPOOLSS_FORM_BUILTIN, "Envelope B6",                    {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
-       { SPOOLSS_FORM_BUILTIN, "Envelope",                       {0x1adb0,0x38270}, {0x0,0x0,0x1adb0,0x38270} },
+       { SPOOLSS_FORM_BUILTIN, "Envelope DL",                    {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
+       { SPOOLSS_FORM_BUILTIN, "Envelope Invite",                {0x35b60,0x35b60}, {0x0,0x0,0x35b60,0x35b60} },
        { SPOOLSS_FORM_BUILTIN, "Envelope Monarch",               {0x18079,0x2e824}, {0x0,0x0,0x18079,0x2e824} },
-       { SPOOLSS_FORM_BUILTIN, "6 3/4 Envelope",                 {0x167ab,0x284ec}, {0x0,0x0,0x167ab,0x284ec} },
-       { SPOOLSS_FORM_BUILTIN, "US Std Fanfold",                 {0x5c3e1,0x44368}, {0x0,0x0,0x5c3e1,0x44368} },
-       { SPOOLSS_FORM_BUILTIN, "German Std Fanfold",             {0x34b5c,0x4a6a0}, {0x0,0x0,0x34b5c,0x4a6a0} },
+       { SPOOLSS_FORM_BUILTIN, "Envelope",                       {0x1adb0,0x38270}, {0x0,0x0,0x1adb0,0x38270} },
+       { SPOOLSS_FORM_BUILTIN, "Executive",                      {0x2cf56,0x411cc}, {0x0,0x0,0x2cf56,0x411cc} },
+       { SPOOLSS_FORM_BUILTIN, "Folio",                          {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
        { SPOOLSS_FORM_BUILTIN, "German Legal Fanfold",           {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
-       { SPOOLSS_FORM_BUILTIN, "B4 (ISO)",                       {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
+       { SPOOLSS_FORM_BUILTIN, "German Std Fanfold",             {0x34b5c,0x4a6a0}, {0x0,0x0,0x34b5c,0x4a6a0} },
+       { SPOOLSS_FORM_BUILTIN, "Japan Envelope Chou #3 Rotated", {0x395f8,0x1d4c0}, {0x0,0x0,0x395f8,0x1d4c0} },
+       { SPOOLSS_FORM_BUILTIN, "Japan Envelope Chou #4 Rotated", {0x320c8,0x15f90}, {0x0,0x0,0x320c8,0x15f90} },
+       { SPOOLSS_FORM_BUILTIN, "Japan Envelope Kaku #2 Rotated", {0x510e0,0x3a980}, {0x0,0x0,0x510e0,0x3a980} },
+       { SPOOLSS_FORM_BUILTIN, "Japan Envelope Kaku #3 Rotated", {0x43a08,0x34bc0}, {0x0,0x0,0x43a08,0x34bc0} },
+       { SPOOLSS_FORM_BUILTIN, "Japan Envelope You #4 Rotated",  {0x395f8,0x19a28}, {0x0,0x0,0x395f8,0x19a28} },
+       { SPOOLSS_FORM_BUILTIN, "Japan Envelope You #4",          {0x19a28,0x395f8}, {0x0,0x0,0x19a28,0x395f8} },
+       { SPOOLSS_FORM_BUILTIN, "Japanese Double Postcard",       {0x30d40,0x24220}, {0x0,0x0,0x30d40,0x24220} },
+       { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Chou #3",      {0x1d4c0,0x395f8}, {0x0,0x0,0x1d4c0,0x395f8} },
+       { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Chou #4",      {0x15f90,0x320c8}, {0x0,0x0,0x15f90,0x320c8} },
+       { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Kaku #2",      {0x3a980,0x510e0}, {0x0,0x0,0x3a980,0x510e0} },
+       { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Kaku #3",      {0x34bc0,0x43a08}, {0x0,0x0,0x34bc0,0x43a08} },
+       { SPOOLSS_FORM_BUILTIN, "Japanese Postcard Rotated",      {0x24220,0x186a0}, {0x0,0x0,0x24220,0x186a0} },
        { SPOOLSS_FORM_BUILTIN, "Japanese Postcard",              {0x186a0,0x24220}, {0x0,0x0,0x186a0,0x24220} },
-       { SPOOLSS_FORM_BUILTIN, "9x11",                           {0x37cf8,0x44368}, {0x0,0x0,0x37cf8,0x44368} },
-       { SPOOLSS_FORM_BUILTIN, "10x11",                          {0x3e030,0x44368}, {0x0,0x0,0x3e030,0x44368} },
-       { SPOOLSS_FORM_BUILTIN, "15x11",                          {0x5d048,0x44368}, {0x0,0x0,0x5d048,0x44368} },
-       { SPOOLSS_FORM_BUILTIN, "Envelope Invite",                {0x35b60,0x35b60}, {0x0,0x0,0x35b60,0x35b60} },
-       { SPOOLSS_FORM_BUILTIN, "Reserved48",                     {0x1,0x1},         {0x0,0x0,0x1,0x1} },
-       { SPOOLSS_FORM_BUILTIN, "Reserved49",                     {0x1,0x1},         {0x0,0x0,0x1,0x1} },
-       { SPOOLSS_FORM_BUILTIN, "Letter Extra",                   {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
+       { SPOOLSS_FORM_BUILTIN, "Ledger",                         {0x696b8,0x44368}, {0x0,0x0,0x696b8,0x44368} },
        { SPOOLSS_FORM_BUILTIN, "Legal Extra",                    {0x3ae94,0x5d048}, {0x0,0x0,0x3ae94,0x5d048} },
-       { SPOOLSS_FORM_BUILTIN, "Tabloid Extra",                  {0x4a6a0,0x6f9f0}, {0x0,0x0,0x4a6a0,0x6f9f0} },
-       { SPOOLSS_FORM_BUILTIN, "A4 Extra",                       {0x397c2,0x4eb16}, {0x0,0x0,0x397c2,0x4eb16} },
-       { SPOOLSS_FORM_BUILTIN, "Letter Transverse",              {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
-       { SPOOLSS_FORM_BUILTIN, "A4 Transverse",                  {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
+       { SPOOLSS_FORM_BUILTIN, "Legal",                          {0x34b5c,0x56d10}, {0x0,0x0,0x34b5c,0x56d10} },
        { SPOOLSS_FORM_BUILTIN, "Letter Extra Transverse",        {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
-       { SPOOLSS_FORM_BUILTIN, "Super A",                        {0x376b8,0x56ea0}, {0x0,0x0,0x376b8,0x56ea0} },
-       { SPOOLSS_FORM_BUILTIN, "Super B",                        {0x4a768,0x76e58}, {0x0,0x0,0x4a768,0x76e58} },
+       { SPOOLSS_FORM_BUILTIN, "Letter Extra",                   {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
        { SPOOLSS_FORM_BUILTIN, "Letter Plus",                    {0x34b5c,0x4eb16}, {0x0,0x0,0x34b5c,0x4eb16} },
-       { SPOOLSS_FORM_BUILTIN, "A4 Plus",                        {0x33450,0x50910}, {0x0,0x0,0x33450,0x50910} },
-       { SPOOLSS_FORM_BUILTIN, "A5 Transverse",                  {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
-       { SPOOLSS_FORM_BUILTIN, "B5 (JIS) Transverse",            {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
-       { SPOOLSS_FORM_BUILTIN, "A3 Extra",                       {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
-       { SPOOLSS_FORM_BUILTIN, "A5 Extra",                       {0x2a7b0,0x395f8}, {0x0,0x0,0x2a7b0,0x395f8} },
-       { SPOOLSS_FORM_BUILTIN, "B5 (ISO) Extra",                 {0x31128,0x43620}, {0x0,0x0,0x31128,0x43620} },
-       { SPOOLSS_FORM_BUILTIN, "A2",                             {0x668a0,0x91050}, {0x0,0x0,0x668a0,0x91050} },
-       { SPOOLSS_FORM_BUILTIN, "A3 Transverse",                  {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
-       { SPOOLSS_FORM_BUILTIN, "A3 Extra Transverse",            {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
-       { SPOOLSS_FORM_BUILTIN, "Japanese Double Postcard",       {0x30d40,0x24220}, {0x0,0x0,0x30d40,0x24220} },
-       { SPOOLSS_FORM_BUILTIN, "A6",                             {0x19a28,0x24220}, {0x0,0x0,0x19a28,0x24220} },
-       { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Kaku #2",      {0x3a980,0x510e0}, {0x0,0x0,0x3a980,0x510e0} },
-       { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Kaku #3",      {0x34bc0,0x43a08}, {0x0,0x0,0x34bc0,0x43a08} },
-       { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Chou #3",      {0x1d4c0,0x395f8}, {0x0,0x0,0x1d4c0,0x395f8} },
-       { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Chou #4",      {0x15f90,0x320c8}, {0x0,0x0,0x15f90,0x320c8} },
        { SPOOLSS_FORM_BUILTIN, "Letter Rotated",                 {0x44368,0x34b5c}, {0x0,0x0,0x44368,0x34b5c} },
-       { SPOOLSS_FORM_BUILTIN, "A3 Rotated",                     {0x668a0,0x48828}, {0x0,0x0,0x668a0,0x48828} },
-       { SPOOLSS_FORM_BUILTIN, "A4 Rotated",                     {0x48828,0x33450}, {0x0,0x0,0x48828,0x33450} },
-       { SPOOLSS_FORM_BUILTIN, "A5 Rotated",                     {0x33450,0x24220}, {0x0,0x0,0x33450,0x24220} },
-       { SPOOLSS_FORM_BUILTIN, "B4 (JIS) Rotated",               {0x58de0,0x3ebe8}, {0x0,0x0,0x58de0,0x3ebe8} },
-       { SPOOLSS_FORM_BUILTIN, "B5 (JIS) Rotated",               {0x3ebe8,0x2c6f0}, {0x0,0x0,0x3ebe8,0x2c6f0} },
-       { SPOOLSS_FORM_BUILTIN, "Japanese Postcard Rotated",      {0x24220,0x186a0}, {0x0,0x0,0x24220,0x186a0} },
-       { SPOOLSS_FORM_BUILTIN, "Double Japan Postcard Rotated",  {0x24220,0x30d40}, {0x0,0x0,0x24220,0x30d40} },
-       { SPOOLSS_FORM_BUILTIN, "A6 Rotated",                     {0x24220,0x19a28}, {0x0,0x0,0x24220,0x19a28} },
-       { SPOOLSS_FORM_BUILTIN, "Japan Envelope Kaku #2 Rotated", {0x510e0,0x3a980}, {0x0,0x0,0x510e0,0x3a980} },
-       { SPOOLSS_FORM_BUILTIN, "Japan Envelope Kaku #3 Rotated", {0x43a08,0x34bc0}, {0x0,0x0,0x43a08,0x34bc0} },
-       { SPOOLSS_FORM_BUILTIN, "Japan Envelope Chou #3 Rotated", {0x395f8,0x1d4c0}, {0x0,0x0,0x395f8,0x1d4c0} },
-       { SPOOLSS_FORM_BUILTIN, "Japan Envelope Chou #4 Rotated", {0x320c8,0x15f90}, {0x0,0x0,0x320c8,0x15f90} },
-       { SPOOLSS_FORM_BUILTIN, "B6 (JIS)",                       {0x1f400,0x2c6f0}, {0x0,0x0,0x1f400,0x2c6f0} },
-       { SPOOLSS_FORM_BUILTIN, "B6 (JIS) Rotated",               {0x2c6f0,0x1f400}, {0x0,0x0,0x2c6f0,0x1f400} },
-       { SPOOLSS_FORM_BUILTIN, "12x11",                          {0x4a724,0x443e1}, {0x0,0x0,0x4a724,0x443e1} },
-       { SPOOLSS_FORM_BUILTIN, "Japan Envelope You #4",          {0x19a28,0x395f8}, {0x0,0x0,0x19a28,0x395f8} },
-       { SPOOLSS_FORM_BUILTIN, "Japan Envelope You #4 Rotated",  {0x395f8,0x19a28}, {0x0,0x0,0x395f8,0x19a28} },
+       { SPOOLSS_FORM_BUILTIN, "Letter Small",                   {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
+       { SPOOLSS_FORM_BUILTIN, "Letter Transverse",              {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
+       { SPOOLSS_FORM_BUILTIN, "Letter",                         {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
+       { SPOOLSS_FORM_BUILTIN, "Note",                           {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
+       { SPOOLSS_FORM_BUILTIN, "PRC 16K Rotated",                {0x3f7a0,0x2de60}, {0x0,0x0,0x3f7a0,0x2de60} },
        { SPOOLSS_FORM_BUILTIN, "PRC 16K",                        {0x2de60,0x3f7a0}, {0x0,0x0,0x2de60,0x3f7a0} },
+       { SPOOLSS_FORM_BUILTIN, "PRC 32K Rotated",                {0x2cec0,0x1fbd0}, {0x0,0x0,0x2cec0,0x1fbd0} },
        { SPOOLSS_FORM_BUILTIN, "PRC 32K",                        {0x1fbd0,0x2cec0}, {0x0,0x0,0x1fbd0,0x2cec0} },
+       { SPOOLSS_FORM_BUILTIN, "PRC 32K(Big) Rotated",           {0x318f8,0x222e0}, {0x0,0x0,0x318f8,0x222e0} },
        { SPOOLSS_FORM_BUILTIN, "PRC 32K(Big)",                   {0x222e0,0x318f8}, {0x0,0x0,0x222e0,0x318f8} },
+       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #1 Rotated",        {0x28488,0x18e70}, {0x0,0x0,0x28488,0x18e70} },
        { SPOOLSS_FORM_BUILTIN, "PRC Envelope #1",                {0x18e70,0x28488}, {0x0,0x0,0x18e70,0x28488} },
-       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #2",                {0x18e70,0x2af80}, {0x0,0x0,0x18e70,0x2af80} },
-       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #3",                {0x1e848,0x2af80}, {0x0,0x0,0x1e848,0x2af80} },
-       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #4",                {0x1adb0,0x32c80}, {0x0,0x0,0x1adb0,0x32c80} },
-       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #5",                {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
-       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #6",                {0x1d4c0,0x38270}, {0x0,0x0,0x1d4c0,0x38270} },
-       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #7",                {0x27100,0x38270}, {0x0,0x0,0x27100,0x38270} },
-       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #8",                {0x1d4c0,0x4b708}, {0x0,0x0,0x1d4c0,0x4b708} },
-       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #9",                {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
+       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #10 Rotated",       {0x6fd10,0x4f1a0}, {0x0,0x0,0x6fd10,0x4f1a0} },
        { SPOOLSS_FORM_BUILTIN, "PRC Envelope #10",               {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} },
-       { SPOOLSS_FORM_BUILTIN, "PRC 16K Rotated",                {0x3f7a0,0x2de60}, {0x0,0x0,0x3f7a0,0x2de60} },
-       { SPOOLSS_FORM_BUILTIN, "PRC 32K Rotated",                {0x2cec0,0x1fbd0}, {0x0,0x0,0x2cec0,0x1fbd0} },
-       { SPOOLSS_FORM_BUILTIN, "PRC 32K(Big) Rotated",           {0x318f8,0x222e0}, {0x0,0x0,0x318f8,0x222e0} },
-       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #1 Rotated",        {0x28488,0x18e70}, {0x0,0x0,0x28488,0x18e70} },
        { SPOOLSS_FORM_BUILTIN, "PRC Envelope #2 Rotated",        {0x2af80,0x18e70}, {0x0,0x0,0x2af80,0x18e70} },
+       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #2",                {0x18e70,0x2af80}, {0x0,0x0,0x18e70,0x2af80} },
        { SPOOLSS_FORM_BUILTIN, "PRC Envelope #3 Rotated",        {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
+       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #3",                {0x1e848,0x2af80}, {0x0,0x0,0x1e848,0x2af80} },
        { SPOOLSS_FORM_BUILTIN, "PRC Envelope #4 Rotated",        {0x32c80,0x1adb0}, {0x0,0x0,0x32c80,0x1adb0} },
+       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #4",                {0x1adb0,0x32c80}, {0x0,0x0,0x1adb0,0x32c80} },
        { SPOOLSS_FORM_BUILTIN, "PRC Envelope #5 Rotated",        {0x35b60,0x1adb0}, {0x0,0x0,0x35b60,0x1adb0} },
+       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #5",                {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
        { SPOOLSS_FORM_BUILTIN, "PRC Envelope #6 Rotated",        {0x38270,0x1d4c0}, {0x0,0x0,0x38270,0x1d4c0} },
+       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #6",                {0x1d4c0,0x38270}, {0x0,0x0,0x1d4c0,0x38270} },
        { SPOOLSS_FORM_BUILTIN, "PRC Envelope #7 Rotated",        {0x38270,0x27100}, {0x0,0x0,0x38270,0x27100} },
+       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #7",                {0x27100,0x38270}, {0x0,0x0,0x27100,0x38270} },
        { SPOOLSS_FORM_BUILTIN, "PRC Envelope #8 Rotated",        {0x4b708,0x1d4c0}, {0x0,0x0,0x4b708,0x1d4c0} },
+       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #8",                {0x1d4c0,0x4b708}, {0x0,0x0,0x1d4c0,0x4b708} },
        { SPOOLSS_FORM_BUILTIN, "PRC Envelope #9 Rotated",        {0x4f1a0,0x37e88}, {0x0,0x0,0x4f1a0,0x37e88} },
-       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #10 Rotated",       {0x6fd10,0x4f1a0}, {0x0,0x0,0x6fd10,0x4f1a0} }
+       { SPOOLSS_FORM_BUILTIN, "PRC Envelope #9",                {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
+       { SPOOLSS_FORM_BUILTIN, "Quarto",                         {0x347d8,0x43238}, {0x0,0x0,0x347d8,0x43238} },
+       { SPOOLSS_FORM_BUILTIN, "Reserved48",                     {0x1,0x1},         {0x0,0x0,0x1,0x1} },
+       { SPOOLSS_FORM_BUILTIN, "Reserved49",                     {0x1,0x1},         {0x0,0x0,0x1,0x1} },
+       { SPOOLSS_FORM_BUILTIN, "Statement",                      {0x221b4,0x34b5c}, {0x0,0x0,0x221b4,0x34b5c} },
+       { SPOOLSS_FORM_BUILTIN, "Super A",                        {0x376b8,0x56ea0}, {0x0,0x0,0x376b8,0x56ea0} },
+       { SPOOLSS_FORM_BUILTIN, "Super B",                        {0x4a768,0x76e58}, {0x0,0x0,0x4a768,0x76e58} },
+       { SPOOLSS_FORM_BUILTIN, "Tabloid Extra",                  {0x4a6a0,0x6f9f0}, {0x0,0x0,0x4a6a0,0x6f9f0} },
+       { SPOOLSS_FORM_BUILTIN, "Tabloid",                        {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
+       { SPOOLSS_FORM_BUILTIN, "US Std Fanfold",                 {0x5c3e1,0x44368}, {0x0,0x0,0x5c3e1,0x44368} }
 };
 
 /********************************************************************
@@ -196,149 +212,6 @@ static uint32_t winreg_printer_rev_changeid(void)
 #endif
 }
 
-static struct spoolss_security_descriptor *winreg_printer_create_default_secdesc(TALLOC_CTX *ctx)
-{
-       SEC_ACE ace[5]; /* max number of ace entries */
-       int i = 0;
-       uint32_t sa;
-       SEC_ACL *psa = NULL;
-       SEC_DESC *psd = NULL;
-       DOM_SID adm_sid;
-       size_t sd_size;
-
-       /* Create an ACE where Everyone is allowed to print */
-
-       sa = PRINTER_ACE_PRINT;
-       init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
-                    sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
-
-       /* Add the domain admins group if we are a DC */
-
-       if ( IS_DC ) {
-               DOM_SID domadmins_sid;
-
-               sid_compose(&domadmins_sid, get_global_sam_sid(),
-                           DOMAIN_GROUP_RID_ADMINS);
-
-               sa = PRINTER_ACE_FULL_CONTROL;
-               init_sec_ace(&ace[i++], &domadmins_sid,
-                       SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
-                       SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
-               init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
-                       sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
-       }
-       else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {
-               sid_append_rid(&adm_sid, DOMAIN_USER_RID_ADMIN);
-
-               sa = PRINTER_ACE_FULL_CONTROL;
-               init_sec_ace(&ace[i++], &adm_sid,
-                       SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
-                       SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
-               init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
-                       sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
-       }
-
-       /* add BUILTIN\Administrators as FULL CONTROL */
-
-       sa = PRINTER_ACE_FULL_CONTROL;
-       init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
-               SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
-               SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
-       init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
-               SEC_ACE_TYPE_ACCESS_ALLOWED,
-               sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
-
-       /* Make the security descriptor owned by the BUILTIN\Administrators */
-
-       /* The ACL revision number in rpc_secdesc.h differs from the one
-          created by NT when setting ACE entries in printer
-          descriptors.  NT4 complains about the property being edited by a
-          NT5 machine. */
-
-       if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
-               psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
-                       &global_sid_Builtin_Administrators,
-                       &global_sid_Builtin_Administrators,
-                       NULL, psa, &sd_size);
-       }
-
-       if (!psd) {
-               DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
-               return NULL;
-       }
-
-       DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
-                (unsigned int)sd_size));
-
-       return psd;
-}
-
-static struct spoolss_DeviceMode *winreg_printer_create_default_devmode(TALLOC_CTX *mem_ctx,
-               const char *default_devicename)
-{
-       char adevice[MAXDEVICENAME];
-       struct spoolss_DeviceMode *devmode;
-
-       devmode = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
-       if (devmode == NULL) {
-               return NULL;
-       }
-
-       slprintf(adevice, sizeof(adevice), "%s", default_devicename);
-       devmode->devicename = talloc_strdup(mem_ctx, adevice);
-       if (devmode->devicename == NULL) {
-               return NULL;
-       }
-
-       devmode->formname = "Letter";
-
-       devmode->specversion          = DMSPEC_NT4_AND_ABOVE;
-       devmode->driverversion        = 0x0400;
-       devmode->size                 = 0x00DC;
-       devmode->__driverextra_length = 0;
-       devmode->fields               = DEVMODE_FORMNAME |
-                                       DEVMODE_TTOPTION |
-                                       DEVMODE_PRINTQUALITY |
-                                       DEVMODE_DEFAULTSOURCE |
-                                       DEVMODE_COPIES |
-                                       DEVMODE_SCALE |
-                                       DEVMODE_PAPERSIZE |
-                                       DEVMODE_ORIENTATION;
-       devmode->orientation          = DMORIENT_PORTRAIT;
-       devmode->papersize            = DMPAPER_LETTER;
-       devmode->paperlength          = 0;
-       devmode->paperwidth           = 0;
-       devmode->scale                = 0x64;
-       devmode->copies               = 1;
-       devmode->defaultsource        = DMBIN_FORMSOURCE;
-       devmode->printquality         = DMRES_HIGH;           /* 0x0258 */
-       devmode->color                = DMRES_MONOCHROME;
-       devmode->duplex               = DMDUP_SIMPLEX;
-       devmode->yresolution          = 0;
-       devmode->ttoption             = DMTT_SUBDEV;
-       devmode->collate              = DMCOLLATE_FALSE;
-       devmode->icmmethod            = 0;
-       devmode->icmintent            = 0;
-       devmode->mediatype            = 0;
-       devmode->dithertype           = 0;
-
-       devmode->logpixels            = 0;
-       devmode->bitsperpel           = 0;
-       devmode->pelswidth            = 0;
-       devmode->pelsheight           = 0;
-       devmode->displayflags         = 0;
-       devmode->displayfrequency     = 0;
-       devmode->reserved1            = 0;
-       devmode->reserved2            = 0;
-       devmode->panningwidth         = 0;
-       devmode->panningheight        = 0;
-
-       devmode->driverextra_data.data = NULL;
-       devmode->driverextra_data.length = 0;
-
-       return devmode;
-}
-
 /**
  * @internal
  *
@@ -387,7 +260,6 @@ static WERROR winreg_printer_openkey(TALLOC_CTX *mem_ctx,
        /* create winreg connection */
        status = rpc_pipe_open_internal(mem_ctx,
                                        &ndr_table_winreg.syntax_id,
-                                       rpc_winreg_dispatch,
                                        server_info,
                                        &pipe_handle);
        if (!NT_STATUS_IS_OK(status)) {
@@ -526,7 +398,7 @@ static WERROR winreg_printer_enumvalues(TALLOC_CTX *mem_ctx,
        WERROR result = WERR_OK;
        NTSTATUS status;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -572,7 +444,7 @@ static WERROR winreg_printer_enumvalues(TALLOC_CTX *mem_ctx,
                struct spoolss_PrinterEnumValues val;
                struct winreg_ValNameBuf name_buf;
                enum winreg_Type type = REG_NONE;
-               uint8_t *data = NULL;
+               uint8_t *data;
                uint32_t data_size;
                uint32_t length;
                char n = '\0';;
@@ -582,7 +454,10 @@ static WERROR winreg_printer_enumvalues(TALLOC_CTX *mem_ctx,
                name_buf.length = 0;
 
                data_size = max_valbufsize;
-               data = (uint8_t *) TALLOC(tmp_ctx, data_size);
+               data = NULL;
+               if (data_size) {
+                       data = (uint8_t *) TALLOC(tmp_ctx, data_size);
+               }
                length = 0;
 
                status = rpccli_winreg_EnumValue(pipe_handle,
@@ -592,7 +467,7 @@ static WERROR winreg_printer_enumvalues(TALLOC_CTX *mem_ctx,
                                                 &name_buf,
                                                 &type,
                                                 data,
-                                                &data_size,
+                                                data_size ? &data_size : NULL,
                                                 &length,
                                                 &result);
                if (W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) {
@@ -686,7 +561,7 @@ static WERROR winreg_printer_enumkeys(TALLOC_CTX *mem_ctx,
        WERROR result = WERR_OK;
        NTSTATUS status;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -919,7 +794,7 @@ static WERROR winreg_printer_write_sz(TALLOC_CTX *mem_ctx,
        if (data == NULL) {
                blob = data_blob_string_const("");
        } else {
-               if (!push_reg_sz(mem_ctx, NULL, &blob, data)) {
+               if (!push_reg_sz(mem_ctx, &blob, data)) {
                        DEBUG(0, ("winreg_printer_write_sz: Could not marshall string %s for %s\n",
                                data, wvalue.name));
                        return WERR_NOMEM;
@@ -1008,6 +883,77 @@ static WERROR winreg_printer_write_binary(TALLOC_CTX *mem_ctx,
        return result;
 }
 
+static WERROR winreg_printer_query_binary(TALLOC_CTX *mem_ctx,
+                                         struct rpc_pipe_client *pipe_handle,
+                                         struct policy_handle *key_handle,
+                                         const char *value,
+                                         DATA_BLOB *data)
+{
+       struct winreg_String wvalue;
+       enum winreg_Type type;
+       WERROR result = WERR_OK;
+       uint32_t value_len = 0;
+       uint32_t data_size = 0;
+       NTSTATUS status;
+       DATA_BLOB blob;
+
+       wvalue.name = value;
+       status = rpccli_winreg_QueryValue(pipe_handle,
+                                         mem_ctx,
+                                         key_handle,
+                                         &wvalue,
+                                         &type,
+                                         NULL,
+                                         &data_size,
+                                         &value_len,
+                                         &result);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(2, ("winreg_printer_query_binary: Could not query value %s: %s\n",
+                         wvalue.name, nt_errstr(status)));
+               if (!W_ERROR_IS_OK(result)) {
+                       goto done;
+               }
+               result = ntstatus_to_werror(status);
+               goto done;
+       }
+
+       if (type != REG_BINARY) {
+               result = WERR_INVALID_DATATYPE;
+               goto done;
+       }
+       blob = data_blob_talloc(mem_ctx, NULL, data_size);
+       if (blob.data == NULL) {
+               result = WERR_NOMEM;
+               goto done;
+       }
+       value_len = 0;
+
+       status = rpccli_winreg_QueryValue(pipe_handle,
+                                         mem_ctx,
+                                         key_handle,
+                                         &wvalue,
+                                         &type,
+                                         blob.data,
+                                         &data_size,
+                                         &value_len,
+                                         &result);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(2, ("winreg_printer_query_binary: Could not query value %s: %s\n",
+                         wvalue.name, nt_errstr(status)));
+               if (!W_ERROR_IS_OK(result)) {
+                       result = ntstatus_to_werror(status);
+               }
+               goto done;
+       }
+
+       if (data) {
+               data->data = blob.data;
+               data->length = blob.length;
+       }
+done:
+       return result;
+}
+
 static WERROR winreg_printer_query_dword(TALLOC_CTX *mem_ctx,
                                         struct rpc_pipe_client *pipe_handle,
                                         struct policy_handle *key_handle,
@@ -1018,6 +964,7 @@ static WERROR winreg_printer_query_dword(TALLOC_CTX *mem_ctx,
        enum winreg_Type type;
        WERROR result = WERR_OK;
        uint32_t value_len = 0;
+       uint32_t data_size = 0;
        NTSTATUS status;
        DATA_BLOB blob;
 
@@ -1028,11 +975,11 @@ static WERROR winreg_printer_query_dword(TALLOC_CTX *mem_ctx,
                                          &wvalue,
                                          &type,
                                          NULL,
-                                         (uint32_t *) &blob.length,
+                                         &data_size,
                                          &value_len,
                                          &result);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("winreg_printer_query_dword: Could not query value %s: %s\n",
+               DEBUG(2, ("winreg_printer_query_dword: Could not query value %s: %s\n",
                          wvalue.name, nt_errstr(status)));
                if (!W_ERROR_IS_OK(result)) {
                        goto done;
@@ -1046,12 +993,12 @@ static WERROR winreg_printer_query_dword(TALLOC_CTX *mem_ctx,
                goto done;
        }
 
-       if (blob.length != 4) {
+       if (data_size != 4) {
                result = WERR_INVALID_DATA;
                goto done;
        }
 
-       blob.data = (uint8_t *) TALLOC(mem_ctx, blob.length);
+       blob = data_blob_talloc(mem_ctx, NULL, data_size);
        if (blob.data == NULL) {
                result = WERR_NOMEM;
                goto done;
@@ -1064,11 +1011,11 @@ static WERROR winreg_printer_query_dword(TALLOC_CTX *mem_ctx,
                                          &wvalue,
                                          &type,
                                          blob.data,
-                                         (uint32_t *) &blob.length,
+                                         &data_size,
                                          &value_len,
                                          &result);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("winreg_printer_query_dword: Could not query value %s: %s\n",
+               DEBUG(2, ("winreg_printer_query_dword: Could not query value %s: %s\n",
                          wvalue.name, nt_errstr(status)));
                if (!W_ERROR_IS_OK(result)) {
                        result = ntstatus_to_werror(status);
@@ -1095,7 +1042,7 @@ static WERROR winreg_printer_write_multi_sz(TALLOC_CTX *mem_ctx,
        NTSTATUS status;
 
        wvalue.name = value;
-       if (!push_reg_multi_sz(mem_ctx, NULL, &blob, data)) {
+       if (!push_reg_multi_sz(mem_ctx, &blob, data)) {
                return WERR_NOMEM;
        }
        status = rpccli_winreg_SetValue(pipe_handle,
@@ -1163,6 +1110,11 @@ static WERROR winreg_enumval_to_dword(TALLOC_CTX *mem_ctx,
                return WERR_INVALID_DATATYPE;
        }
 
+       if (v->data_length == 0) {
+               *dw = 0;
+               return WERR_OK;
+       }
+
        *dw = IVAL(v->data->data, 0);
        return WERR_OK;
 }
@@ -1180,7 +1132,15 @@ static WERROR winreg_enumval_to_sz(TALLOC_CTX *mem_ctx,
                return WERR_INVALID_DATATYPE;
        }
 
-       if (!pull_reg_sz(mem_ctx, NULL, v->data, _str)) {
+       if (v->data_length == 0) {
+               *_str = talloc_strdup(mem_ctx, EMPTY_STRING);
+               if (*_str == NULL) {
+                       return WERR_NOMEM;
+               }
+               return WERR_OK;
+       }
+
+       if (!pull_reg_sz(mem_ctx, v->data, _str)) {
                return WERR_NOMEM;
        }
 
@@ -1201,30 +1161,19 @@ static WERROR winreg_enumval_to_multi_sz(TALLOC_CTX *mem_ctx,
                return WERR_INVALID_DATATYPE;
        }
 
-       if (!pull_reg_multi_sz(mem_ctx, NULL, v->data, array)) {
-               return WERR_NOMEM;
-       }
-
-       return WERR_OK;
-}
-
-static WERROR winreg_enumval_to_blob(TALLOC_CTX *mem_ctx,
-                                    struct spoolss_PrinterEnumValues *v,
-                                    const char *valuename,
-                                    DATA_BLOB *blob)
-{
-       /* just return if it is not the one we are looking for */
-       if (strcmp(valuename, v->value_name) != 0) {
-               return WERR_NOT_FOUND;
+       if (v->data_length == 0) {
+               *array = talloc_array(mem_ctx, const char *, 1);
+               if (*array == NULL) {
+                       return WERR_NOMEM;
+               }
+               *array[0] = NULL;
+               return WERR_OK;
        }
 
-       if (v->type != REG_BINARY) {
-               return WERR_INVALID_DATATYPE;
+       if (!pull_reg_multi_sz(mem_ctx, v->data, array)) {
+               return WERR_NOMEM;
        }
 
-       blob->data = v->data->data;
-       blob->length = v->data_length;
-
        return WERR_OK;
 }
 
@@ -1251,7 +1200,7 @@ static WERROR winreg_printer_write_date(TALLOC_CTX *mem_ctx,
        }
 
        wvalue.name = value;
-       if (!push_reg_sz(mem_ctx, NULL, &blob, str)) {
+       if (!push_reg_sz(mem_ctx, &blob, str)) {
                return WERR_NOMEM;
        }
        status = rpccli_winreg_SetValue(pipe_handle,
@@ -1318,7 +1267,7 @@ static WERROR winreg_printer_write_ver(TALLOC_CTX *mem_ctx,
        }
 
        wvalue.name = value;
-       if (!push_reg_sz(mem_ctx, NULL, &blob, str)) {
+       if (!push_reg_sz(mem_ctx, &blob, str)) {
                return WERR_NOMEM;
        }
        status = rpccli_winreg_SetValue(pipe_handle,
@@ -1362,24 +1311,23 @@ static WERROR winreg_printer_ver_to_dword(const char *str, uint64_t *data)
 
 WERROR winreg_create_printer(TALLOC_CTX *mem_ctx,
                             struct auth_serversupplied_info *server_info,
+                            const char *servername,
                             const char *sharename)
 {
        uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
        struct rpc_pipe_client *winreg_pipe = NULL;
        struct policy_handle hive_hnd, key_hnd;
        struct spoolss_SetPrinterInfo2 *info2;
-       struct spoolss_DeviceMode *devmode = NULL;
        struct security_descriptor *secdesc;
        struct winreg_String wkey, wkeyclass;
        const char *path;
-       const char *subkeys[] = { "DsDriver", "DsSpooler", "PrinterDriverData" };
+       const char *subkeys[] = { SPOOL_DSDRIVER_KEY, SPOOL_DSSPOOLER_KEY, SPOOL_PRINTERDATA_KEY };
        uint32_t i, count = ARRAY_SIZE(subkeys);
-       int snum = lp_servicenumber(sharename);
        uint32_t info2_mask = 0;
        WERROR result = WERR_OK;
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -1470,6 +1418,119 @@ WERROR winreg_create_printer(TALLOC_CTX *mem_ctx,
                        goto done;
                }
 
+               switch (i) {
+               case 1: {
+                       const char *dnssuffix;
+                       const char *longname;
+                       const char *uncname;
+
+                       result = winreg_printer_write_sz(tmp_ctx,
+                                                        winreg_pipe,
+                                                        &key_hnd,
+                                                        SPOOL_REG_PRINTERNAME,
+                                                        sharename);
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto done;
+                       }
+
+                       result = winreg_printer_write_sz(tmp_ctx,
+                                                        winreg_pipe,
+                                                        &key_hnd,
+                                                        SPOOL_REG_SHORTSERVERNAME,
+                                                        global_myname());
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto done;
+                       }
+
+                       /* We make the assumption that the netbios name
+                        * is the same as the DNS name since the former
+                        * will be what we used to join the domain
+                        */
+                       dnssuffix = get_mydnsdomname(tmp_ctx);
+                       if (dnssuffix != NULL && dnssuffix[0] != '\0') {
+                               longname = talloc_asprintf(tmp_ctx, "%s.%s", global_myname(), dnssuffix);
+                       } else {
+                               longname = talloc_strdup(tmp_ctx, global_myname());
+                       }
+                       if (longname == NULL) {
+                               result = WERR_NOMEM;
+                               goto done;
+                       }
+
+                       result = winreg_printer_write_sz(tmp_ctx,
+                                                        winreg_pipe,
+                                                        &key_hnd,
+                                                        SPOOL_REG_SERVERNAME,
+                                                        longname);
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto done;
+                       }
+
+                       uncname = talloc_asprintf(tmp_ctx, "\\\\%s\\%s",
+                                                 longname, sharename);
+                       if (uncname == NULL) {
+                               result = WERR_NOMEM;
+                               goto done;
+                       }
+
+                       result = winreg_printer_write_sz(tmp_ctx,
+                                                        winreg_pipe,
+                                                        &key_hnd,
+                                                        SPOOL_REG_UNCNAME,
+                                                        uncname);
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto done;
+                       }
+
+                       result = winreg_printer_write_dword(tmp_ctx,
+                                                           winreg_pipe,
+                                                           &key_hnd,
+                                                           SPOOL_REG_VERSIONNUMBER,
+                                                           4);
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto done;
+                       }
+
+                       result = winreg_printer_write_dword(tmp_ctx,
+                                                           winreg_pipe,
+                                                           &key_hnd,
+                                                           SPOOL_REG_PRINTSTARTTIME,
+                                                           0);
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto done;
+                       }
+
+                       result = winreg_printer_write_dword(tmp_ctx,
+                                                           winreg_pipe,
+                                                           &key_hnd,
+                                                           SPOOL_REG_PRINTENDTIME,
+                                                           0);
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto done;
+                       }
+
+                       result = winreg_printer_write_dword(tmp_ctx,
+                                                           winreg_pipe,
+                                                           &key_hnd,
+                                                           SPOOL_REG_PRIORITY,
+                                                           1);
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto done;
+                       }
+
+                       result = winreg_printer_write_dword(tmp_ctx,
+                                                           winreg_pipe,
+                                                           &key_hnd,
+                                                           SPOOL_REG_PRINTKEEPPRINTEDJOBS,
+                                                           0);
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto done;
+                       }
+               } /* case 1 */
+               default:
+                       break;
+               }
+
                if (is_valid_policy_hnd(&key_hnd)) {
                        rpccli_winreg_CloseKey(winreg_pipe, tmp_ctx, &key_hnd, NULL);
                }
@@ -1480,7 +1541,16 @@ WERROR winreg_create_printer(TALLOC_CTX *mem_ctx,
                goto done;
        }
 
-       info2->printername = sharename;
+       if (servername != NULL) {
+               info2->printername = talloc_asprintf(tmp_ctx, "\\\\%s\\%s",
+                                                    servername, sharename);
+       } else {
+               info2->printername = sharename;
+       }
+       if (info2->printername == NULL) {
+               result = WERR_NOMEM;
+               goto done;
+       }
        info2_mask |= SPOOLSS_PRINTER_INFO_PRINTERNAME;
 
        info2->sharename = sharename;
@@ -1507,37 +1577,29 @@ WERROR winreg_create_printer(TALLOC_CTX *mem_ctx,
        info2->untiltime = 0; /* Minutes since 12:00am GMT */
        info2_mask |= SPOOLSS_PRINTER_INFO_UNTILTIME;
 
-       info2->priority = 1;
-       info2_mask |= SPOOLSS_PRINTER_INFO_PRIORITY;
-
-       info2->defaultpriority = 1;
-       info2_mask |= SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY;
-
-       /* info2->setuptime = (uint32_t) time(NULL); */
-
-       if (lp_default_devmode(snum)) {
-               devmode = winreg_printer_create_default_devmode(tmp_ctx,
-                                                               info2->printername);
-               if (devmode == NULL) {
-                       result = WERR_NOMEM;
-                       goto done;
-               }
-
-               info2_mask |= SPOOLSS_PRINTER_INFO_DEVMODE;
-       }
+       info2->priority = 1;
+       info2_mask |= SPOOLSS_PRINTER_INFO_PRIORITY;
 
-       secdesc = winreg_printer_create_default_secdesc(tmp_ctx);
-       if (secdesc == NULL) {
-               result = WERR_NOMEM;
+       info2->defaultpriority = 1;
+       info2_mask |= SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY;
+
+       result = spoolss_create_default_secdesc(tmp_ctx, &secdesc);
+       if (!W_ERROR_IS_OK(result)) {
                goto done;
        }
        info2_mask |= SPOOLSS_PRINTER_INFO_SECDESC;
 
+       /*
+        * Don't write a default Device Mode to the registry! The Device Mode is
+        * only written to disk with a SetPrinter level 2 or 8.
+        */
+
        result = winreg_update_printer(tmp_ctx,
                                       server_info,
+                                      sharename,
                                       info2_mask,
                                       info2,
-                                      devmode,
+                                      NULL,
                                       secdesc);
 
 done:
@@ -1556,6 +1618,7 @@ done:
 
 WERROR winreg_update_printer(TALLOC_CTX *mem_ctx,
                             struct auth_serversupplied_info *server_info,
+                            const char *sharename,
                             uint32_t info2_mask,
                             struct spoolss_SetPrinterInfo2 *info2,
                             struct spoolss_DeviceMode *devmode,
@@ -1564,18 +1627,19 @@ WERROR winreg_update_printer(TALLOC_CTX *mem_ctx,
        uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
        struct rpc_pipe_client *winreg_pipe = NULL;
        struct policy_handle hive_hnd, key_hnd;
+       int snum = lp_servicenumber(sharename);
        enum ndr_err_code ndr_err;
        DATA_BLOB blob;
        char *path;
        WERROR result = WERR_OK;
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
 
-       path = winreg_printer_data_keyname(tmp_ctx, info2->sharename);
+       path = winreg_printer_data_keyname(tmp_ctx, sharename);
        if (path == NULL) {
                TALLOC_FREE(tmp_ctx);
                return WERR_NOMEM;
@@ -1657,7 +1721,20 @@ WERROR winreg_update_printer(TALLOC_CTX *mem_ctx,
        }
 
        if (info2_mask & SPOOLSS_PRINTER_INFO_DEVMODE) {
-               ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, NULL, devmode,
+               /*
+                * Some client drivers freak out if there is a NULL devmode
+                * (probably the driver is not checking before accessing
+                * the devmode pointer)   --jerry
+                */
+               if (devmode == NULL && lp_default_devmode(snum) && info2 != NULL) {
+                       result = spoolss_create_default_devmode(tmp_ctx,
+                                                               info2->printername,
+                                                               &devmode);
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto done;
+                       }
+               }
+               ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, devmode,
                                (ndr_push_flags_fn_t) ndr_push_spoolss_DeviceMode);
                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
                        DEBUG(0, ("winreg_update_printer: Failed to marshall device mode\n"));
@@ -1775,21 +1852,15 @@ WERROR winreg_update_printer(TALLOC_CTX *mem_ctx,
                 * AddPrinter{Ex} then create a default descriptor.
                 */
                if (secdesc == NULL) {
-                       secdesc = winreg_printer_create_default_secdesc(tmp_ctx);
-               }
-               ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, NULL, secdesc,
-                               (ndr_push_flags_fn_t) ndr_push_security_descriptor);
-               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-                       DEBUG(0, ("winreg_update_printer: Failed to marshall security descriptor\n"));
-                       result = WERR_NOMEM;
-                       goto done;
+                       result = spoolss_create_default_secdesc(tmp_ctx, &secdesc);
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto done;
+                       }
                }
-
-               result = winreg_printer_write_binary(tmp_ctx,
-                                                    winreg_pipe,
-                                                    &key_hnd,
-                                                    "Security",
-                                                    blob);
+               result = winreg_set_printer_secdesc(tmp_ctx,
+                                                   server_info,
+                                                   sharename,
+                                                   secdesc);
                if (!W_ERROR_IS_OK(result)) {
                        goto done;
                }
@@ -1876,6 +1947,7 @@ done:
 
 WERROR winreg_get_printer(TALLOC_CTX *mem_ctx,
                          struct auth_serversupplied_info *server_info,
+                         const char *servername,
                          const char *printer,
                          struct spoolss_PrinterInfo2 **pinfo2)
 {
@@ -1887,13 +1959,14 @@ WERROR winreg_get_printer(TALLOC_CTX *mem_ctx,
        struct spoolss_PrinterEnumValues *v;
        enum ndr_err_code ndr_err;
        DATA_BLOB blob;
+       int snum = lp_servicenumber(printer);
        uint32_t num_values = 0;
        uint32_t i;
        char *path;
        WERROR result = WERR_OK;
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -1914,7 +1987,7 @@ WERROR winreg_get_printer(TALLOC_CTX *mem_ctx,
                                        &hive_hnd,
                                        &key_hnd);
        if (!W_ERROR_IS_OK(result)) {
-               DEBUG(0, ("winreg_get_printer: Could not open key %s: %s\n",
+               DEBUG(2, ("winreg_get_printer: Could not open key %s: %s\n",
                          path, win_errstr(result)));
                goto done;
        }
@@ -1936,23 +2009,26 @@ WERROR winreg_get_printer(TALLOC_CTX *mem_ctx,
                goto done;
        }
 
-       info2->servername = talloc_asprintf(info2, "\\\\%s", global_myname());
-       if (info2->servername == NULL) {
-               result = WERR_NOMEM;
-               goto done;
+       FILL_STRING(info2, EMPTY_STRING, info2->servername);
+       FILL_STRING(info2, EMPTY_STRING, info2->printername);
+       FILL_STRING(info2, EMPTY_STRING, info2->sharename);
+       FILL_STRING(info2, EMPTY_STRING, info2->portname);
+       FILL_STRING(info2, EMPTY_STRING, info2->drivername);
+       FILL_STRING(info2, EMPTY_STRING, info2->comment);
+       FILL_STRING(info2, EMPTY_STRING, info2->location);
+       FILL_STRING(info2, EMPTY_STRING, info2->sepfile);
+       FILL_STRING(info2, EMPTY_STRING, info2->printprocessor);
+       FILL_STRING(info2, EMPTY_STRING, info2->datatype);
+       FILL_STRING(info2, EMPTY_STRING, info2->parameters);
+
+       if (servername != NULL && servername[0] != '\0') {
+               info2->servername = talloc_asprintf(info2, "\\\\%s", servername);
+               if (info2->servername == NULL) {
+                       result = WERR_NOMEM;
+                       goto done;
+               }
        }
 
-       info2->printername    = EMPTY_STRING;
-       info2->sharename      = EMPTY_STRING;
-       info2->portname       = EMPTY_STRING;
-       info2->drivername     = EMPTY_STRING;
-       info2->comment        = EMPTY_STRING;
-       info2->location       = EMPTY_STRING;
-       info2->sepfile        = EMPTY_STRING;
-       info2->printprocessor = EMPTY_STRING;
-       info2->datatype       = EMPTY_STRING;
-       info2->parameters     = EMPTY_STRING;
-
        for (i = 0; i < num_values; i++) {
                v = &enum_values[i];
 
@@ -2057,62 +2133,94 @@ WERROR winreg_get_printer(TALLOC_CTX *mem_ctx,
                                                 "StartTime",
                                                 &info2->starttime);
                CHECK_ERROR(result);
+       }
 
-               result = winreg_enumval_to_blob(info2,
-                                               v,
-                                               "Default DevMode",
-                                               &blob);
-               if (W_ERROR_IS_OK(result)) {
-                       info2->devmode = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
-                       if (info2->devmode == NULL) {
-                               result = WERR_NOMEM;
-                               goto done;
-                       }
-                       ndr_err = ndr_pull_struct_blob(&blob,
-                                                      info2,
-                                                      NULL,
-                                                      info2->devmode,
-                                                      (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeviceMode);
-                       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-                               DEBUG(0, ("winreg_get_printer: Failed to unmarshall device mode\n"));
+       if (!W_ERROR_IS_OK(result)) {
+               DEBUG(0, ("winreg_get_printer: winreg_enumval_to_TYPE() failed "
+                                       "for %s: %s\n",
+                                       v->value_name,
+                                       win_errstr(result)));
+               goto done;
+       }
+
+       /* Create the printername */
+       if (info2->servername != NULL && info2->servername[0] != '\0') {
+               if (lp_force_printername(snum)) {
+                       const char *p = talloc_asprintf(info2, "%s\\%s",
+                                                       info2->servername,
+                                                       info2->sharename);
+                               if (p == NULL) {
+                                       result = WERR_NOMEM;
+                                       goto done;
+                               }
+                               info2->printername = p;
+               } else {
+                       char *p = talloc_asprintf(info2, "%s\\%s",
+                                                 info2->servername,
+                                                 info2->printername);
+                       if (p == NULL) {
                                result = WERR_NOMEM;
                                goto done;
                        }
+                       info2->printername = p;
                }
-               CHECK_ERROR(result);
+       }
 
-               result = winreg_enumval_to_blob(info2,
-                                               v,
-                                               "Security",
-                                               &blob);
-               if (W_ERROR_IS_OK(result)) {
-                       info2->secdesc = talloc_zero(mem_ctx, struct spoolss_security_descriptor);
-                       if (info2->secdesc == NULL) {
-                               result = WERR_NOMEM;
-                               goto done;
-                       }
-                       ndr_err = ndr_pull_struct_blob(&blob,
-                                                      mem_ctx,
-                                                      NULL,
-                                                      info2->secdesc,
-                                                      (ndr_pull_flags_fn_t) ndr_pull_security_descriptor);
-                       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-                               DEBUG(0, ("winreg_get_printer: Failed to unmarshall security descriptor\n"));
-                               result = WERR_NOMEM;
-                               goto done;
-                       }
+       /* Construct the Device Mode */
+       result = winreg_printer_query_binary(tmp_ctx,
+                                            winreg_pipe,
+                                            &key_hnd,
+                                            "Default DevMode",
+                                            &blob);
+       if (W_ERROR_IS_OK(result)) {
+               info2->devmode = talloc_zero(info2, struct spoolss_DeviceMode);
+               if (info2->devmode == NULL) {
+                       result = WERR_NOMEM;
+                       goto done;
+               }
+               ndr_err = ndr_pull_struct_blob(&blob,
+                                              info2->devmode,
+                                              info2->devmode,
+                                              (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeviceMode);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       DEBUG(0, ("winreg_get_printer: Failed to unmarshall device mode\n"));
+                       result = WERR_NOMEM;
+                       goto done;
+               }
+       }
+
+       if (info2->devmode == NULL && lp_default_devmode(snum)) {
+               result = spoolss_create_default_devmode(info2,
+                                                       info2->printername,
+                                                       &info2->devmode);
+               if (!W_ERROR_IS_OK(result)) {
+                       goto done;
+               }
+       }
+
+       if (info2->devmode != NULL) {
+               info2->devmode->devicename = talloc_strdup(info2->devmode,
+                                                          info2->printername);
+               if (info2->devmode->devicename == NULL) {
+                       DEBUG(0, ("winreg_get_printer: Failed to set devicename\n"));
+                       result = WERR_NOMEM;
+                       goto done;
                }
-               CHECK_ERROR(result);
        }
 
+       result = winreg_get_printer_secdesc(info2,
+                                           server_info,
+                                           printer,
+                                           &info2->secdesc);
        if (!W_ERROR_IS_OK(result)) {
-               DEBUG(0, ("winreg_get_printer: winreg_enumval_to_TYPE() failed "
-                                       "for %s: %s\n",
-                                       v->value_name,
-                                       win_errstr(result)));
                goto done;
        }
 
+       /* Fix for OS/2 drivers. */
+       if (get_remote_arch() == RA_OS2) {
+               spoolss_map_to_os2_driver(info2, &info2->drivername);
+       }
+
        if (pinfo2) {
                *pinfo2 = talloc_move(mem_ctx, &info2);
        }
@@ -2132,6 +2240,284 @@ done:
        return result;
 }
 
+WERROR winreg_get_printer_secdesc(TALLOC_CTX *mem_ctx,
+                                 struct auth_serversupplied_info *server_info,
+                                 const char *sharename,
+                                 struct spoolss_security_descriptor **psecdesc)
+{
+       struct spoolss_security_descriptor *secdesc;
+       uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+       struct rpc_pipe_client *winreg_pipe = NULL;
+       struct policy_handle hive_hnd, key_hnd;
+       enum ndr_err_code ndr_err;
+       const char *path;
+       DATA_BLOB blob;
+       TALLOC_CTX *tmp_ctx;
+       WERROR result;
+
+       tmp_ctx = talloc_stackframe();
+       if (tmp_ctx == NULL) {
+               return WERR_NOMEM;
+       }
+
+       path = winreg_printer_data_keyname(tmp_ctx, sharename);
+       if (path == NULL) {
+               talloc_free(tmp_ctx);
+               return WERR_NOMEM;
+       }
+
+       ZERO_STRUCT(hive_hnd);
+       ZERO_STRUCT(key_hnd);
+
+       result = winreg_printer_openkey(tmp_ctx,
+                                       server_info,
+                                       &winreg_pipe,
+                                       path,
+                                       "",
+                                       false,
+                                       access_mask,
+                                       &hive_hnd,
+                                       &key_hnd);
+       if (!W_ERROR_IS_OK(result)) {
+               if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
+                       goto create_default;
+               }
+               goto done;
+       }
+
+       result = winreg_printer_query_binary(tmp_ctx,
+                                            winreg_pipe,
+                                            &key_hnd,
+                                            "Security",
+                                            &blob);
+       if (!W_ERROR_IS_OK(result)) {
+               if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
+                       goto create_default;
+               }
+               goto done;
+       }
+
+       secdesc = talloc_zero(tmp_ctx, struct spoolss_security_descriptor);
+       if (secdesc == NULL) {
+               result = WERR_NOMEM;
+               goto done;
+       }
+       ndr_err = ndr_pull_struct_blob(&blob,
+                                      secdesc,
+                                      secdesc,
+                                      (ndr_pull_flags_fn_t) ndr_pull_security_descriptor);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               DEBUG(0, ("winreg_get_secdesc: Failed to unmarshall security descriptor\n"));
+               result = WERR_NOMEM;
+               goto done;
+       }
+
+       if (psecdesc) {
+               *psecdesc = talloc_move(mem_ctx, &secdesc);
+       }
+
+       result = WERR_OK;
+       goto done;
+
+create_default:
+       result = spoolss_create_default_secdesc(tmp_ctx, &secdesc);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+
+       /* If security descriptor is owned by S-1-1-0 and winbindd is up,
+          this security descriptor has been created when winbindd was
+          down.  Take ownership of security descriptor. */
+       if (sid_equal(secdesc->owner_sid, &global_sid_World)) {
+               struct dom_sid owner_sid;
+
+               /* Change sd owner to workgroup administrator */
+
+               if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {
+                       struct spoolss_security_descriptor *new_secdesc;
+                       size_t size;
+
+                       /* Create new sd */
+                       sid_append_rid(&owner_sid, DOMAIN_RID_ADMINISTRATOR);
+
+                       new_secdesc = make_sec_desc(tmp_ctx,
+                                                   secdesc->revision,
+                                                   secdesc->type,
+                                                   &owner_sid,
+                                                   secdesc->group_sid,
+                                                   secdesc->sacl,
+                                                   secdesc->dacl,
+                                                   &size);
+
+                       if (new_secdesc == NULL) {
+                               result = WERR_NOMEM;
+                               goto done;
+                       }
+
+                       /* Swap with other one */
+                       secdesc = new_secdesc;
+               }
+       }
+
+       ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, secdesc,
+                       (ndr_push_flags_fn_t) ndr_push_security_descriptor);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               DEBUG(0, ("winreg_set_secdesc: Failed to marshall security descriptor\n"));
+               result = WERR_NOMEM;
+               goto done;
+       }
+
+       result = winreg_printer_write_binary(tmp_ctx,
+                                            winreg_pipe,
+                                            &key_hnd,
+                                            "Security",
+                                            blob);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+
+       if (psecdesc) {
+               *psecdesc = talloc_move(mem_ctx, &secdesc);
+       }
+
+       result = WERR_OK;
+done:
+       if (winreg_pipe != NULL) {
+               if (is_valid_policy_hnd(&key_hnd)) {
+                       rpccli_winreg_CloseKey(winreg_pipe, tmp_ctx, &key_hnd, NULL);
+               }
+               if (is_valid_policy_hnd(&hive_hnd)) {
+                       rpccli_winreg_CloseKey(winreg_pipe, tmp_ctx, &hive_hnd, NULL);
+               }
+       }
+
+       talloc_free(tmp_ctx);
+       return result;
+}
+
+WERROR winreg_set_printer_secdesc(TALLOC_CTX *mem_ctx,
+                                 struct auth_serversupplied_info *server_info,
+                                 const char *sharename,
+                                 const struct spoolss_security_descriptor *secdesc)
+{
+       const struct spoolss_security_descriptor *new_secdesc = secdesc;
+       struct spoolss_security_descriptor *old_secdesc;
+       uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+       struct rpc_pipe_client *winreg_pipe = NULL;
+       struct policy_handle hive_hnd, key_hnd;
+       enum ndr_err_code ndr_err;
+       const char *path;
+       DATA_BLOB blob;
+       TALLOC_CTX *tmp_ctx;
+       WERROR result;
+
+       tmp_ctx = talloc_stackframe();
+       if (tmp_ctx == NULL) {
+               return WERR_NOMEM;
+       }
+
+       path = winreg_printer_data_keyname(tmp_ctx, sharename);
+       if (path == NULL) {
+               talloc_free(tmp_ctx);
+               return WERR_NOMEM;
+       }
+
+       /*
+        * The old owner and group sids of the security descriptor are not
+        * present when new ACEs are added or removed by changing printer
+        * permissions through NT.  If they are NULL in the new security
+        * descriptor then copy them over from the old one.
+        */
+       if (!secdesc->owner_sid || !secdesc->group_sid) {
+               struct dom_sid *owner_sid, *group_sid;
+               struct security_acl *dacl, *sacl;
+               size_t size;
+
+               result = winreg_get_printer_secdesc(tmp_ctx,
+                                                   server_info,
+                                                   sharename,
+                                                   &old_secdesc);
+               if (!W_ERROR_IS_OK(result)) {
+                       talloc_free(tmp_ctx);
+                       return result;
+               }
+
+               /* Pick out correct owner and group sids */
+               owner_sid = secdesc->owner_sid ?
+                           secdesc->owner_sid :
+                           old_secdesc->owner_sid;
+
+               group_sid = secdesc->group_sid ?
+                           secdesc->group_sid :
+                           old_secdesc->group_sid;
+
+               dacl = secdesc->dacl ?
+                      secdesc->dacl :
+                      old_secdesc->dacl;
+
+               sacl = secdesc->sacl ?
+                      secdesc->sacl :
+                      old_secdesc->sacl;
+
+               /* Make a deep copy of the security descriptor */
+               new_secdesc = make_sec_desc(tmp_ctx,
+                                           secdesc->revision,
+                                           secdesc->type,
+                                           owner_sid,
+                                           group_sid,
+                                           sacl,
+                                           dacl,
+                                           &size);
+               if (new_secdesc == NULL) {
+                       talloc_free(tmp_ctx);
+                       return WERR_NOMEM;
+               }
+       }
+
+       ZERO_STRUCT(hive_hnd);
+       ZERO_STRUCT(key_hnd);
+
+       result = winreg_printer_openkey(tmp_ctx,
+                                       server_info,
+                                       &winreg_pipe,
+                                       path,
+                                       "",
+                                       false,
+                                       access_mask,
+                                       &hive_hnd,
+                                       &key_hnd);
+       if (!W_ERROR_IS_OK(result)) {
+               goto done;
+       }
+
+       ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, new_secdesc,
+                       (ndr_push_flags_fn_t) ndr_push_security_descriptor);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               DEBUG(0, ("winreg_set_secdesc: Failed to marshall security descriptor\n"));
+               result = WERR_NOMEM;
+               goto done;
+       }
+
+       result = winreg_printer_write_binary(tmp_ctx,
+                                            winreg_pipe,
+                                            &key_hnd,
+                                            "Security",
+                                            blob);
+
+done:
+       if (winreg_pipe != NULL) {
+               if (is_valid_policy_hnd(&key_hnd)) {
+                       rpccli_winreg_CloseKey(winreg_pipe, tmp_ctx, &key_hnd, NULL);
+               }
+               if (is_valid_policy_hnd(&hive_hnd)) {
+                       rpccli_winreg_CloseKey(winreg_pipe, tmp_ctx, &hive_hnd, NULL);
+               }
+       }
+
+       talloc_free(tmp_ctx);
+       return result;
+}
+
 /* Set printer data over the winreg pipe. */
 WERROR winreg_set_printer_dataex(TALLOC_CTX *mem_ctx,
                                 struct auth_serversupplied_info *server_info,
@@ -2151,7 +2537,7 @@ WERROR winreg_set_printer_dataex(TALLOC_CTX *mem_ctx,
        NTSTATUS status;
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -2239,7 +2625,7 @@ WERROR winreg_get_printer_dataex(TALLOC_CTX *mem_ctx,
        NTSTATUS status;
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -2263,7 +2649,7 @@ WERROR winreg_get_printer_dataex(TALLOC_CTX *mem_ctx,
                                        &hive_hnd,
                                        &key_hnd);
        if (!W_ERROR_IS_OK(result)) {
-               DEBUG(0, ("winreg_get_printer_dataex: Could not open key %s: %s\n",
+               DEBUG(2, ("winreg_get_printer_dataex: Could not open key %s: %s\n",
                          key, win_errstr(result)));
                goto done;
        }
@@ -2359,7 +2745,7 @@ WERROR winreg_enum_printer_dataex(TALLOC_CTX *mem_ctx,
 
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -2380,7 +2766,7 @@ WERROR winreg_enum_printer_dataex(TALLOC_CTX *mem_ctx,
                                        &hive_hnd,
                                        &key_hnd);
        if (!W_ERROR_IS_OK(result)) {
-               DEBUG(0, ("winreg_enum_printer_dataex: Could not open key %s: %s\n",
+               DEBUG(2, ("winreg_enum_printer_dataex: Could not open key %s: %s\n",
                          key, win_errstr(result)));
                goto done;
        }
@@ -2433,7 +2819,7 @@ WERROR winreg_delete_printer_dataex(TALLOC_CTX *mem_ctx,
 
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -2512,7 +2898,7 @@ WERROR winreg_enum_printer_key(TALLOC_CTX *mem_ctx,
 
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -2536,7 +2922,7 @@ WERROR winreg_enum_printer_key(TALLOC_CTX *mem_ctx,
                                        &hive_hnd,
                                        &key_hnd);
        if (!W_ERROR_IS_OK(result)) {
-               DEBUG(0, ("winreg_enum_printer_key: Could not open key %s: %s\n",
+               DEBUG(2, ("winreg_enum_printer_key: Could not open key %s: %s\n",
                          key, win_errstr(result)));
                goto done;
        }
@@ -2586,7 +2972,7 @@ WERROR winreg_delete_printer_key(TALLOC_CTX *mem_ctx,
        WERROR result;
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -2671,7 +3057,7 @@ WERROR winreg_printer_update_changeid(TALLOC_CTX *mem_ctx,
        WERROR result;
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -2737,7 +3123,7 @@ WERROR winreg_printer_get_changeid(TALLOC_CTX *mem_ctx,
        WERROR result;
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -2761,12 +3147,13 @@ WERROR winreg_printer_get_changeid(TALLOC_CTX *mem_ctx,
                                        &hive_hnd,
                                        &key_hnd);
        if (!W_ERROR_IS_OK(result)) {
-               DEBUG(0, ("winreg_printer_get_changeid: Could not open key %s: %s\n",
+               DEBUG(2, ("winreg_printer_get_changeid: Could not open key %s: %s\n",
                          path, win_errstr(result)));
                goto done;
        }
 
-       DEBUG(0, ("winreg_printer_get_changeid: get changeid from %s\n", path));
+       DEBUG(10, ("winreg_printer_get_changeid: get changeid from %s\n", path));
+
        result = winreg_printer_query_dword(tmp_ctx,
                                            winreg_pipe,
                                            &key_hnd,
@@ -2818,7 +3205,7 @@ WERROR winreg_printer_addform1(TALLOC_CTX *mem_ctx,
        NTSTATUS status;
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -2918,7 +3305,7 @@ WERROR winreg_printer_enumforms1(TALLOC_CTX *mem_ctx,
        WERROR result;
        TALLOC_CTX *tmp_ctx;
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -2991,7 +3378,7 @@ WERROR winreg_printer_enumforms1(TALLOC_CTX *mem_ctx,
                val.info1.area.right  = IVAL(enum_values[i].data->data, 16);
                val.info1.area.bottom = IVAL(enum_values[i].data->data, 20);
                /* skip form index      IVAL(enum_values[i].data->data, 24)));*/
-               val.info1.flags       = IVAL(enum_values[i].data->data, 28);
+               val.info1.flags       = (enum spoolss_FormFlags) IVAL(enum_values[i].data->data, 28);
 
                info[i + num_builtin] = val;
        }
@@ -3036,7 +3423,7 @@ WERROR winreg_printer_deleteform1(TALLOC_CTX *mem_ctx,
                }
        }
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -3121,7 +3508,7 @@ WERROR winreg_printer_setform1(TALLOC_CTX *mem_ctx,
                }
        }
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -3226,7 +3613,7 @@ WERROR winreg_printer_getform1(TALLOC_CTX *mem_ctx,
                }
        }
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -3244,7 +3631,7 @@ WERROR winreg_printer_getform1(TALLOC_CTX *mem_ctx,
                                        &hive_hnd,
                                        &key_hnd);
        if (!W_ERROR_IS_OK(result)) {
-               DEBUG(0, ("winreg_printer_getform1: Could not open key %s: %s\n",
+               DEBUG(2, ("winreg_printer_getform1: Could not open key %s: %s\n",
                          TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
                goto done;
        }
@@ -3314,7 +3701,7 @@ WERROR winreg_printer_getform1(TALLOC_CTX *mem_ctx,
        r->area.right  = IVAL(data_in, 16);
        r->area.bottom = IVAL(data_in, 20);
        /* skip index    IVAL(data_in, 24)));*/
-       r->flags       = IVAL(data_in, 28);
+       r->flags       = (enum spoolss_FormFlags) IVAL(data_in, 28);
 
        result = WERR_OK;
 done:
@@ -3353,7 +3740,7 @@ WERROR winreg_add_driver(TALLOC_CTX *mem_ctx,
                goto done;
        }
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -3577,7 +3964,7 @@ WERROR winreg_get_driver(TALLOC_CTX *mem_ctx,
        ZERO_STRUCT(key_hnd);
        ZERO_STRUCT(i8);
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -3638,7 +4025,19 @@ WERROR winreg_get_driver(TALLOC_CTX *mem_ctx,
        }
 
        info8 = talloc_zero(tmp_ctx, struct spoolss_DriverInfo8);
-       if (!info8) {
+       if (info8 == NULL) {
+               result = WERR_NOMEM;
+               goto done;
+       }
+
+       info8->driver_name = talloc_strdup(info8, driver_name);
+       if (info8->driver_name == NULL) {
+               result = WERR_NOMEM;
+               goto done;
+       }
+
+       info8->architecture = talloc_strdup(info8, architecture);
+       if (info8->architecture == NULL) {
                result = WERR_NOMEM;
                goto done;
        }
@@ -3647,13 +4046,15 @@ WERROR winreg_get_driver(TALLOC_CTX *mem_ctx,
 
        for (i = 0; i < num_values; i++) {
                const char *tmp_str;
+               uint32_t tmp = 0;
 
                v = &enum_values[i];
 
                result = winreg_enumval_to_dword(info8, v,
                                                 "Version",
-                                                &info8->version);
+                                                &tmp);
                CHECK_ERROR(result);
+               info8->version = tmp;
 
                result = winreg_enumval_to_sz(info8, v,
                                              "Driver",
@@ -3820,7 +4221,7 @@ WERROR winreg_del_driver(TALLOC_CTX *mem_ctx,
        ZERO_STRUCT(hive_hnd);
        ZERO_STRUCT(key_hnd);
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -3896,18 +4297,22 @@ WERROR winreg_get_driver_list(TALLOC_CTX *mem_ctx,
                              const char *architecture,
                              uint32_t version,
                              uint32_t *num_drivers,
-                             const char ***drivers)
+                             const char ***drivers_p)
 {
        uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
        struct rpc_pipe_client *winreg_pipe = NULL;
        struct policy_handle hive_hnd, key_hnd;
+       const char **drivers;
        TALLOC_CTX *tmp_ctx;
        WERROR result;
 
+       *num_drivers = 0;
+       *drivers_p = NULL;
+
        ZERO_STRUCT(hive_hnd);
        ZERO_STRUCT(key_hnd);
 
-       tmp_ctx = talloc_new(mem_ctx);
+       tmp_ctx = talloc_stackframe();
        if (tmp_ctx == NULL) {
                return WERR_NOMEM;
        }
@@ -3927,6 +4332,7 @@ WERROR winreg_get_driver_list(TALLOC_CTX *mem_ctx,
                DEBUG(5, ("winreg_get_driver_list: "
                          "Could not open key (%s,%u): %s\n",
                          architecture, version, win_errstr(result)));
+               result = WERR_OK;
                goto done;
        }
 
@@ -3934,7 +4340,7 @@ WERROR winreg_get_driver_list(TALLOC_CTX *mem_ctx,
                                         winreg_pipe,
                                         &key_hnd,
                                         num_drivers,
-                                        drivers);
+                                        &drivers);
        if (!W_ERROR_IS_OK(result)) {
                DEBUG(0, ("winreg_get_driver_list: "
                          "Could not enumerate drivers for (%s,%u): %s\n",
@@ -3942,6 +4348,8 @@ WERROR winreg_get_driver_list(TALLOC_CTX *mem_ctx,
                goto done;
        }
 
+       *drivers_p = talloc_steal(mem_ctx, drivers);
+
        result = WERR_OK;
 done:
        if (winreg_pipe != NULL) {