s3-registry: only include registry headers when really needed.
[amitay/samba.git] / source3 / printing / nt_printing.c
index 1f306512af512823a0101f4b5ab26314fd503ef7..8e8695c20e6583c81de865c347686ada89012c8e 100644 (file)
@@ -20,6 +20,9 @@
  */
 
 #include "includes.h"
+#include "librpc/gen_ndr/messaging.h"
+#include "printing/pcap.h"
+#include "registry.h"
 
 static TDB_CONTEXT *tdb_forms; /* used for forms files */
 static TDB_CONTEXT *tdb_drivers; /* used for driver files */
@@ -402,7 +405,7 @@ static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
                return 0;
        }
 
-       if ( !(sd_store = sec_desc_merge( ctx, sd_new, sd_orig )) ) {
+       if ( !(sd_store = sec_desc_merge_buf( ctx, sd_new, sd_orig )) ) {
                DEBUG(0,("sec_desc_upg_fn: Failed to update sec_desc for %s\n", key.dptr ));
                return 0;
        }
@@ -618,7 +621,7 @@ bool nt_printing_init(struct messaging_context *msg_ctx)
 
        /* of course, none of the message callbacks matter if you don't
           tell messages.c that you interested in receiving PRINT_GENERAL
-          msgs.  This is done in claim_connection() */
+          msgs.  This is done in serverid_register() */
 
 
        if ( lp_security() == SEC_ADS ) {
@@ -918,7 +921,7 @@ bool delete_a_form(nt_forms_struct **list, const char *del_name, int *count, WER
 
        if (n == *count) {
                DEBUG(10,("delete_a_form, [%s] not found\n", del_name));
-               *ret = WERR_INVALID_PARAM;
+               *ret = WERR_INVALID_FORM_NAME;
                return False;
        }
 
@@ -1315,6 +1318,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
                FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
                INTERNAL_OPEN_ONLY,                     /* oplock_request */
                0,                                      /* allocation_size */
+               0,                                      /* private_flags */
                NULL,                                   /* sd */
                NULL,                                   /* ea_list */
                &fsp,                                   /* result */
@@ -1367,6 +1371,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
                FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
                INTERNAL_OPEN_ONLY,                     /* oplock_request */
                0,                                      /* allocation_size */
+               0,                                      /* private_flags */
                NULL,                                   /* sd */
                NULL,                                   /* ea_list */
                &fsp,                                   /* result */
@@ -1524,6 +1529,7 @@ static uint32 get_correct_cversion(struct pipes_struct *p,
                0,                                      /* create_options */
                FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
                INTERNAL_OPEN_ONLY,                     /* oplock_request */
+               0,                                      /* private_flags */
                0,                                      /* allocation_size */
                NULL,                                   /* sd */
                NULL,                                   /* ea_list */
@@ -1602,7 +1608,7 @@ static uint32 get_correct_cversion(struct pipes_struct *p,
 ****************************************************************************/
 
 #define strip_driver_path(_mem_ctx, _element) do { \
-       if ((_p = strrchr((_element), '\\')) != NULL) { \
+       if (_element && ((_p = strrchr((_element), '\\')) != NULL)) { \
                (_element) = talloc_asprintf((_mem_ctx), "%s", _p+1); \
                W_ERROR_HAVE_NO_MEMORY((_element)); \
        } \
@@ -1623,6 +1629,10 @@ static WERROR clean_up_driver_struct_level(TALLOC_CTX *mem_ctx,
        WERROR err;
        char *_p;
 
+       if (!*driver_path || !*data_file || !*config_file) {
+               return WERR_INVALID_PARAM;
+       }
+
        /* clean up the driver name.
         * we can get .\driver.dll
         * or worse c:\windows\system\driver.dll !
@@ -1632,7 +1642,9 @@ static WERROR clean_up_driver_struct_level(TALLOC_CTX *mem_ctx,
        strip_driver_path(mem_ctx, *driver_path);
        strip_driver_path(mem_ctx, *data_file);
        strip_driver_path(mem_ctx, *config_file);
-       strip_driver_path(mem_ctx, *help_file);
+       if (help_file) {
+               strip_driver_path(mem_ctx, *help_file);
+       }
 
        if (dependent_files && dependent_files->string) {
                for (i=0; dependent_files->string[i]; i++) {
@@ -2541,6 +2553,167 @@ done:
        return ret;
 }
 
+/****************************************************************************
+ Create and allocate a default devicemode.
+****************************************************************************/
+
+WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx,
+                                     const char *devicename,
+                                     struct spoolss_DeviceMode **devmode)
+{
+       struct spoolss_DeviceMode *dm;
+       char *dname;
+
+       dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
+       if (dm == NULL) {
+               return WERR_NOMEM;
+       }
+
+       dname = talloc_asprintf(dm, "%s", devicename);
+       if (dname == NULL) {
+               return WERR_NOMEM;
+       }
+       if (strlen(dname) > MAXDEVICENAME) {
+               dname[MAXDEVICENAME] = '\0';
+       }
+       dm->devicename = dname;
+
+       dm->formname = talloc_strdup(dm, "Letter");
+       if (dm->formname == NULL) {
+               return WERR_NOMEM;
+       }
+
+       dm->specversion          = DMSPEC_NT4_AND_ABOVE;
+       dm->driverversion        = 0x0400;
+       dm->size                 = 0x00DC;
+       dm->__driverextra_length = 0;
+       dm->fields               = DEVMODE_FORMNAME |
+                                  DEVMODE_TTOPTION |
+                                  DEVMODE_PRINTQUALITY |
+                                  DEVMODE_DEFAULTSOURCE |
+                                  DEVMODE_COPIES |
+                                  DEVMODE_SCALE |
+                                  DEVMODE_PAPERSIZE |
+                                  DEVMODE_ORIENTATION;
+       dm->orientation          = DMORIENT_PORTRAIT;
+       dm->papersize            = DMPAPER_LETTER;
+       dm->paperlength          = 0;
+       dm->paperwidth           = 0;
+       dm->scale                = 0x64;
+       dm->copies               = 1;
+       dm->defaultsource        = DMBIN_FORMSOURCE;
+       dm->printquality         = DMRES_HIGH;           /* 0x0258 */
+       dm->color                = DMRES_MONOCHROME;
+       dm->duplex               = DMDUP_SIMPLEX;
+       dm->yresolution          = 0;
+       dm->ttoption             = DMTT_SUBDEV;
+       dm->collate              = DMCOLLATE_FALSE;
+       dm->icmmethod            = 0;
+       dm->icmintent            = 0;
+       dm->mediatype            = 0;
+       dm->dithertype           = 0;
+
+       dm->logpixels            = 0;
+       dm->bitsperpel           = 0;
+       dm->pelswidth            = 0;
+       dm->pelsheight           = 0;
+       dm->displayflags         = 0;
+       dm->displayfrequency     = 0;
+       dm->reserved1            = 0;
+       dm->reserved2            = 0;
+       dm->panningwidth         = 0;
+       dm->panningheight        = 0;
+
+       dm->driverextra_data.data = NULL;
+       dm->driverextra_data.length = 0;
+
+        *devmode = dm;
+       return WERR_OK;
+}
+
+WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx,
+                                     struct spoolss_security_descriptor **secdesc)
+{
+       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_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_RID_ADMINISTRATOR);
+
+               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(mem_ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
+               psd = make_sec_desc(mem_ctx,
+                                   SEC_DESC_REVISION,
+                                   SEC_DESC_SELF_RELATIVE,
+                                   &global_sid_Builtin_Administrators,
+                                   &global_sid_Builtin_Administrators,
+                                   NULL,
+                                   psa,
+                                   &sd_size);
+       }
+
+       if (psd == NULL) {
+               DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
+               return WERR_NOMEM;
+       }
+
+       DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
+                (unsigned int)sd_size));
+
+       *secdesc = psd;
+
+       return WERR_OK;
+}
 
 /****************************************************************************
  Malloc and return an NT devicemode.
@@ -3353,7 +3526,7 @@ bool is_printer_published(Printer_entry *print_hnd, int snum,
                case REG_SZ:
                        blob = data_blob_const(regval_data_p(guid_val),
                                               regval_size(guid_val));
-                       pull_reg_sz(talloc_tos(), &blob, (const char **)&guid_str);
+                       pull_reg_sz(talloc_tos(), NULL, &blob, (const char **)&guid_str);
                        ret = NT_STATUS_IS_OK(GUID_from_string( guid_str, guid ));
                        talloc_free(guid_str);
                        break;
@@ -3828,8 +4001,17 @@ static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 *info,
        if (get_loc_com && (enum printing_types)lp_printing(snum) == PRINT_CUPS ) {
                /* Pull the location and comment strings from cups if we don't
                   already have one */
-               if ( !strlen(info->location) || !strlen(info->comment) )
-                       cups_pull_comment_location( info );
+               if ( !strlen(info->location) || !strlen(info->comment) ) {
+                       char *comment = NULL;
+                       char *location = NULL;
+                       if (cups_pull_comment_location(info, info->sharename,
+                                                      &comment, &location)) {
+                               strlcpy(info->comment, comment, sizeof(info->comment));
+                               fstrcpy(info->location, location);
+                               TALLOC_FREE(comment);
+                               TALLOC_FREE(location);
+                       }
+               }
        }
 #endif
 
@@ -3950,8 +4132,17 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info,
        if (get_loc_com && (enum printing_types)lp_printing(snum) == PRINT_CUPS ) {
                /* Pull the location and comment strings from cups if we don't
                   already have one */
-               if ( !strlen(info->location) || !strlen(info->comment) )
-                       cups_pull_comment_location( info );
+               if ( !strlen(info->location) || !strlen(info->comment) ) {
+                       char *location = NULL;
+                       comment = NULL;
+                       if (cups_pull_comment_location(info, info->sharename,
+                                                      &comment, &location)) {
+                               strlcpy(info->comment, comment, sizeof(info->comment));
+                               fstrcpy(info->location, location);
+                               TALLOC_FREE(comment);
+                               TALLOC_FREE(location);
+                       }
+               }
        }
 #endif
 
@@ -4633,17 +4824,13 @@ uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
 /****************************************************************************
 ****************************************************************************/
 
-uint32_t add_a_printer_driver(TALLOC_CTX *mem_ctx,
-                             struct spoolss_AddDriverInfoCtr *r,
-                             char **driver_name,
-                             uint32_t *version)
+bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r,
+                             struct spoolss_DriverInfo8 *_info8)
 {
        struct spoolss_DriverInfo8 info8;
 
        ZERO_STRUCT(info8);
 
-       DEBUG(10,("adding a printer at level [%d]\n", r->level));
-
        switch (r->level) {
        case 3:
                info8.version           = r->info.info3->version;
@@ -4715,6 +4902,27 @@ uint32_t add_a_printer_driver(TALLOC_CTX *mem_ctx,
                info8.min_inbox_driver_ver_version = r->info.info8->min_inbox_driver_ver_version;
                break;
        default:
+               return false;
+       }
+
+       *_info8 = info8;
+
+       return true;
+}
+
+
+uint32_t add_a_printer_driver(TALLOC_CTX *mem_ctx,
+                             struct spoolss_AddDriverInfoCtr *r,
+                             char **driver_name,
+                             uint32_t *version)
+{
+       struct spoolss_DriverInfo8 info8;
+
+       ZERO_STRUCT(info8);
+
+       DEBUG(10,("adding a printer at level [%d]\n", r->level));
+
+       if (!driver_info_ctr_to_info8(r, &info8)) {
                return -1;
        }
 
@@ -5398,8 +5606,8 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
        if ( IS_DC ) {
                DOM_SID domadmins_sid;
 
-               sid_copy(&domadmins_sid, get_global_sam_sid());
-               sid_append_rid(&domadmins_sid, DOMAIN_GROUP_RID_ADMINS);
+               sid_compose(&domadmins_sid, get_global_sam_sid(),
+                           DOMAIN_RID_ADMINS);
 
                sa = PRINTER_ACE_FULL_CONTROL;
                init_sec_ace(&ace[i++], &domadmins_sid,
@@ -5409,7 +5617,7 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
                        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);
+               sid_append_rid(&adm_sid, DOMAIN_RID_ADMINISTRATOR);
 
                sa = PRINTER_ACE_FULL_CONTROL;
                init_sec_ace(&ace[i++], &adm_sid,
@@ -5518,7 +5726,7 @@ bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **s
 
                        /* Create new sd */
 
-                       sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
+                       sid_append_rid(&owner_sid, DOMAIN_RID_ADMINISTRATOR);
 
                        psd = make_sec_desc(ctx, (*secdesc_ctr)->sd->revision, (*secdesc_ctr)->sd->type,
                                            &owner_sid,
@@ -5717,7 +5925,7 @@ bool print_access_check(struct auth_serversupplied_info *server_info, int snum,
 
         /* see if we need to try the printer admin list */
 
-        if ((access_granted == 0) &&
+        if (!NT_STATUS_IS_OK(status) &&
            (token_contains_name_in_list(uidtoname(server_info->utok.uid),
                                         NULL, NULL, server_info->ptok,
                                         lp_printer_admin(snum)))) {