Cleanup size_t return values in callers of convert_string_allocate
[metze/samba/wip.git] / source3 / printing / nt_printing.c
index bbe312ca277a4308d0f187998b1ab6e1ddf7eaba..3a7f1174bd9b5ff13370f2023d560b1afacb6b96 100644 (file)
@@ -72,6 +72,15 @@ const struct generic_mapping printserver_std_mapping = {
        SERVER_ALL_ACCESS
 };
 
+/* Map generic permissions to job object specific permissions */
+
+const struct generic_mapping job_generic_mapping = {
+       JOB_READ,
+       JOB_WRITE,
+       JOB_EXECUTE,
+       JOB_ALL_ACCESS
+};
+
 /* We need one default form to support our default printer. Msoft adds the
 forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
 array index). Letter is always first, so (for the current code) additions
@@ -344,7 +353,6 @@ static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
        int result, i;
        uint32 sd_size;
        size_t size_new_sec;
-       DOM_SID sid;
 
        if (!data.dptr || data.dsize == 0) {
                return 0;
@@ -358,7 +366,7 @@ static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
 
        ZERO_STRUCT( ps );
 
-       prs_init( &ps, 0, ctx, UNMARSHALL );
+       prs_init_empty( &ps, ctx, UNMARSHALL );
        prs_give_memory( &ps, (char *)data.dptr, data.dsize, False );
 
        if ( !sec_io_desc_buf( "sec_desc_upg_fn", &sd_orig, &ps, 1 ) ) {
@@ -405,10 +413,10 @@ static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
 
        /* create a new SEC_DESC with the appropriate owner and group SIDs */
 
-       string_to_sid(&sid, "S-1-5-32-544" );
        new_sec = make_sec_desc( ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
-               &sid, &sid,
-               NULL, NULL, &size_new_sec );
+                                &global_sid_Builtin_Administrators,
+                                &global_sid_Builtin_Administrators,
+                                NULL, NULL, &size_new_sec );
        if (!new_sec) {
                prs_mem_free( &ps );
                return 0;
@@ -429,8 +437,12 @@ static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
 
        /* store it back */
        
-       sd_size = sec_desc_size(sd_store->sd) + sizeof(SEC_DESC_BUF);
-       prs_init(&ps, sd_size, ctx, MARSHALL);
+       sd_size = ndr_size_security_descriptor(sd_store->sd, 0)
+               + sizeof(SEC_DESC_BUF);
+       if ( !prs_init(&ps, sd_size, ctx, MARSHALL) ) {
+               DEBUG(0,("sec_desc_upg_fn: Failed to allocate prs memory for %s\n", key.dptr ));
+               return 0;
+       }
 
        if ( !sec_io_desc_buf( "sec_desc_upg_fn", &sd_store, &ps, 1 ) ) {
                DEBUG(0,("sec_desc_upg_fn: Failed to parse new sec_desc for %s\n", key.dptr ));
@@ -1096,7 +1108,7 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
        }
 
        /* Skip OEM header (if any) and the DOS stub to start of Windows header */
-       if (SMB_VFS_LSEEK(fsp, fsp->fh->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
+       if (SMB_VFS_LSEEK(fsp, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
                DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
                                fname, errno));
                /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
@@ -1117,7 +1129,7 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
                unsigned int section_table_bytes;
 
                /* Just skip over optional header to get to section table */
-               if (SMB_VFS_LSEEK(fsp, fsp->fh->fd,
+               if (SMB_VFS_LSEEK(fsp,
                                SVAL(buf,PE_HEADER_OPTIONAL_HEADER_SIZE)-(NE_HEADER_SIZE-PE_HEADER_SIZE),
                                SEEK_CUR) == (SMB_OFF_T)-1) {
                        DEBUG(3,("get_file_version: File [%s] Windows optional header too short, errno = %d\n",
@@ -1163,7 +1175,7 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
                                }
 
                                /* Seek to the start of the .rsrc section info */
-                               if (SMB_VFS_LSEEK(fsp, fsp->fh->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
+                               if (SMB_VFS_LSEEK(fsp, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
                                        DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
                                                        fname, errno));
                                        goto error_exit;
@@ -1259,7 +1271,7 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
                                 * twice, as it is simpler to read the code. */
                                if (strcmp(&buf[i], VS_SIGNATURE) == 0) {
                                        /* Compute skip alignment to next long address */
-                                       int skip = -(SMB_VFS_LSEEK(fsp, fsp->fh->fd, 0, SEEK_CUR) - (byte_count - i) +
+                                       int skip = -(SMB_VFS_LSEEK(fsp, 0, SEEK_CUR) - (byte_count - i) +
                                                                 sizeof(VS_SIGNATURE)) & 3;
                                        if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue;
 
@@ -1359,7 +1371,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
                        DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
                                         old_file));
                        use_version = false;
-                       if (SMB_VFS_FSTAT(fsp, fsp->fh->fd, &st) == -1) {
+                       if (SMB_VFS_FSTAT(fsp, &st) == -1) {
                                 goto error_exit;
                        }
                        old_create_time = st.st_mtime;
@@ -1399,7 +1411,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
                        DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
                                         new_file));
                        use_version = false;
-                       if (SMB_VFS_FSTAT(fsp, fsp->fh->fd, &st) == -1) {
+                       if (SMB_VFS_FSTAT(fsp, &st) == -1) {
                                goto error_exit;
                        }
                        new_create_time = st.st_mtime;
@@ -1866,7 +1878,7 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
                goto err_exit;
        }
 
-       create_directory(conn, new_dir);
+       create_directory(conn, NULL, new_dir);
 
        /* For each driver file, archi\filexxx.yyy, if there is a duplicate file
         * listed for this driver which has already been moved, skip it (note:
@@ -3208,7 +3220,8 @@ static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2,
           Vista to whine */
 
        ZERO_STRUCT( unistr_guid );     
-       init_unistr2( &unistr_guid, smb_uuid_string_static(guid),
+       
+       init_unistr2( &unistr_guid, smb_uuid_string(talloc_tos(), guid),
                      UNI_STR_TERMINATE );
 
        regval_ctr_addvalue(ctr, "objectGUID", REG_SZ, 
@@ -3229,6 +3242,7 @@ static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
        const char *attrs[] = {"objectGUID", NULL};
        struct GUID guid;
        WERROR win_rc = WERR_OK;
+       size_t converted_size;
 
        DEBUG(5, ("publishing printer %s\n", printer->info_2->printername));
 
@@ -3251,13 +3265,13 @@ static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
                return WERR_SERVER_UNAVAILABLE;
        }
        /* Now convert to CH_UNIX. */
-       if (pull_utf8_allocate(&srv_dn, srv_dn_utf8) == (size_t)-1) {
+       if (!pull_utf8_allocate(&srv_dn, srv_dn_utf8, &converted_size)) {
                ldap_memfree(srv_dn_utf8);
                ldap_memfree(srv_cn_utf8);
                ads_destroy(&ads);
                return WERR_SERVER_UNAVAILABLE;
        }
-       if (pull_utf8_allocate(&srv_cn_0, srv_cn_utf8[0]) == (size_t)-1) {
+       if (!pull_utf8_allocate(&srv_cn_0, srv_cn_utf8[0], &converted_size)) {
                ldap_memfree(srv_dn_utf8);
                ldap_memfree(srv_cn_utf8);
                ads_destroy(&ads);
@@ -3313,8 +3327,13 @@ static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
 
        /* publish it */
        ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx, &mods);
-       if (ads_rc.err.rc == LDAP_NO_SUCH_OBJECT)
+       if (ads_rc.err.rc == LDAP_NO_SUCH_OBJECT) {
+               int i;
+               for (i=0; mods[i] != 0; i++)
+                       ;
+               mods[i] = (LDAPMod *)-1;
                ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods);
+       }
 
        if (!ADS_ERR_OK(ads_rc))
                DEBUG(3, ("error publishing %s: %s\n", printer->info_2->sharename, ads_errstr(ads_rc)));
@@ -3821,7 +3840,8 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, const uint8 *buf, int bu
 
                        memcpy( &guid, data_p, sizeof(struct GUID) );
 
-                       init_unistr2( &unistr_guid, smb_uuid_string_static(guid), 
+                       init_unistr2( &unistr_guid,
+                                     smb_uuid_string(talloc_tos(), guid), 
                                      UNI_STR_TERMINATE );
 
                        regval_ctr_addvalue( printer_data->keys[key_index].values, 
@@ -3847,10 +3867,46 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, const uint8 *buf, int bu
 /****************************************************************************
  ***************************************************************************/
 
+static char *last_from;
+static char *last_to;
+
+static const char *get_last_from(void)
+{
+       if (!last_from) {
+               return "";
+       }
+       return last_from;
+}
+
+static const char *get_last_to(void)
+{
+       if (!last_to) {
+               return "";
+       }
+       return last_to;
+}
+
+static bool set_last_from_to(const char *from, const char *to)
+{
+       char *orig_from = last_from;
+       char *orig_to = last_to;
+
+       last_from = SMB_STRDUP(from);
+       last_to = SMB_STRDUP(to);
+
+       SAFE_FREE(orig_from);
+       SAFE_FREE(orig_to);
+
+       if (!last_from || !last_to) {
+               SAFE_FREE(last_from);
+               SAFE_FREE(last_to);
+               return false;
+       }
+       return true;
+}
+
 static void map_to_os2_driver(fstring drivername)
 {
-       static bool initialised=False;
-       static fstring last_from,last_to;
        char *mapfile = lp_os2_driver_map();
        char **lines = NULL;
        int numlines = 0;
@@ -3862,14 +3918,10 @@ static void map_to_os2_driver(fstring drivername)
        if (!*mapfile)
                return;
 
-       if (!initialised) {
-               *last_from = *last_to = 0;
-               initialised = True;
-       }
-
-       if (strequal(drivername,last_from)) {
-               DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,last_to));
-               fstrcpy(drivername,last_to);
+       if (strequal(drivername,get_last_from())) {
+               DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",
+                       drivername,get_last_to()));
+               fstrcpy(drivername,get_last_to());
                return;
        }
 
@@ -3918,8 +3970,7 @@ static void map_to_os2_driver(fstring drivername)
 
                if (strequal(nt_name,drivername)) {
                        DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name));
-                       fstrcpy(last_from,drivername);
-                       fstrcpy(last_to,os2_name);
+                       set_last_from_to(drivername,os2_name);
                        fstrcpy(drivername,os2_name);
                        file_lines_free(lines);
                        return;
@@ -3932,7 +3983,11 @@ static void map_to_os2_driver(fstring drivername)
 /****************************************************************************
  Get a default printer info 2 struct.
 ****************************************************************************/
-static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 *info, const char *servername, const char* sharename)
+
+static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 *info,
+                               const char *servername,
+                               const char* sharename,
+                               bool get_loc_com)
 {
        int snum = lp_servicenumber(sharename);
 
@@ -3954,12 +4009,12 @@ static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 *info, const char
 
        DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info->drivername));
 
-       pstrcpy(info->comment, "");
+       strlcpy(info->comment, "", sizeof(info->comment));
        fstrcpy(info->printprocessor, "winprint");
        fstrcpy(info->datatype, "RAW");
 
 #ifdef HAVE_CUPS
-       if ( (enum printing_types)lp_printing(snum) == PRINT_CUPS ) {           
+       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) )
@@ -4008,19 +4063,25 @@ fail:
 
 /****************************************************************************
 ****************************************************************************/
-static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info, const char *servername, const char *sharename)
+
+static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info,
+                               const char *servername,
+                               const char *sharename,
+                               bool get_loc_com)
 {
        int len = 0;
        int snum = lp_servicenumber(sharename);
        TDB_DATA kbuf, dbuf;
        fstring printername;
        char adevice[MAXDEVICENAME];
+       char *comment = NULL;
 
        kbuf = make_printer_tdbkey(talloc_tos(), sharename);
 
        dbuf = tdb_fetch(tdb_printers, kbuf);
        if (!dbuf.dptr) {
-               return get_a_printer_2_default(info, servername, sharename);
+               return get_a_printer_2_default(info, servername,
+                                       sharename, get_loc_com);
        }
 
        len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
@@ -4040,13 +4101,18 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info, const char *servern
                        info->sharename,
                        info->portname,
                        info->drivername,
-                       info->comment,
+                       &comment,
                        info->location,
                        info->sepfile,
                        info->printprocessor,
                        info->datatype,
                        info->parameters);
 
+       if (comment) {
+               strlcpy(info->comment, comment, sizeof(info->comment));
+               SAFE_FREE(comment);
+       }
+
        /* Samba has to have shared raw drivers. */
        info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
        info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
@@ -4063,7 +4129,7 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info, const char *servern
        fstrcpy(info->printername, printername);
 
 #ifdef HAVE_CUPS
-       if ( (enum printing_types)lp_printing(snum) == PRINT_CUPS ) {           
+       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) )
@@ -4506,7 +4572,7 @@ static bool convert_driver_init( TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode, uin
 
        ZERO_STRUCT(devmode);
 
-       prs_init(&ps, 0, ctx, UNMARSHALL);
+       prs_init_empty(&ps, ctx, UNMARSHALL);
        ps.data_p      = (char *)data;
        ps.buffer_size = data_len;
 
@@ -4647,8 +4713,8 @@ WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, uint8 *dat
 
 ****************************************************************************/
 
-WERROR get_a_printer( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, 
-                       const char *sharename)
+static WERROR get_a_printer_internal( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, 
+                       const char *sharename, bool get_loc_com)
 {
        WERROR result;
        fstring servername;
@@ -4676,11 +4742,11 @@ WERROR get_a_printer( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_print
                                                    sizeof(servername)-1 );
                        }
 
-                       result = get_a_printer_2( (*pp_printer)->info_2, servername, sharename );
-       
-                       
+                       result = get_a_printer_2( (*pp_printer)->info_2,
+                                       servername, sharename, get_loc_com);
+
                        /* we have a new printer now.  Save it with this handle */
-                       
+
                        if ( !W_ERROR_IS_OK(result) ) {
                                TALLOC_FREE( *pp_printer );
                                DEBUG(10,("get_a_printer: [%s] level %u returning %s\n", 
@@ -4700,6 +4766,24 @@ WERROR get_a_printer( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_print
        return WERR_OK;
 }
 
+WERROR get_a_printer( Printer_entry *print_hnd,
+                       NT_PRINTER_INFO_LEVEL **pp_printer,
+                       uint32 level,
+                       const char *sharename)
+{
+       return get_a_printer_internal(print_hnd, pp_printer, level,
+                                       sharename, true);
+}
+
+WERROR get_a_printer_search( Printer_entry *print_hnd,
+                       NT_PRINTER_INFO_LEVEL **pp_printer,
+                       uint32 level,
+                       const char *sharename)
+{
+       return get_a_printer_internal(print_hnd, pp_printer, level,
+                                       sharename, false);
+}
+
 /****************************************************************************
  Deletes a NT_PRINTER_INFO_LEVEL struct.
 ****************************************************************************/
@@ -4918,10 +5002,15 @@ bool printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3 )
 static bool drv_file_in_use( char* file, NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
 {
        int i = 0;
-       
+
        if ( !info )
                return False;
-               
+
+       /* mz: skip files that are in the list but already deleted */
+       if (!file || !file[0]) {
+               return false;
+       }
+
        if ( strequal(file, info->driverpath) )
                return True;
 
@@ -5034,6 +5123,12 @@ static bool trim_overlap_drv_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *src,
   
   Upon return, *info has been modified to only contain the driver files
   which are not in use
+
+  Fix from mz:
+
+  This needs to check all drivers to ensure that all files in use
+  have been removed from *info, not just the ones in the first
+  match.
 ****************************************************************************/
 
 bool printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
@@ -5043,7 +5138,8 @@ bool printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
        uint32                          version;
        fstring                         *list = NULL;
        NT_PRINTER_DRIVER_INFO_LEVEL    driver;
-       
+       bool in_use = false;
+
        if ( !info )
                return False;
        
@@ -5078,9 +5174,10 @@ bool printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
                        
                if ( !strequal(info->name, driver.info_3->name) ) {
                        if ( trim_overlap_drv_files(info, driver.info_3) ) {
-                               free_a_printer_driver(driver, 3);
-                               SAFE_FREE( list );
-                               return True;
+                               /* mz: Do not instantly return -
+                                * we need to ensure this file isn't
+                                * also in use by other drivers. */
+                               in_use = true;
                        }
                }
 
@@ -5096,7 +5193,7 @@ bool printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
        if ( DEBUGLEVEL >= 20 )
                dump_a_printer_driver( driver, 3 );
 
-       return False;
+       return in_use;
 }
 
 /****************************************************************************
@@ -5286,6 +5383,7 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr)
        SEC_DESC_BUF *new_secdesc_ctr = NULL;
        SEC_DESC_BUF *old_secdesc_ctr = NULL;
        prs_struct ps;
+       bool prs_init_done = false;
        TALLOC_CTX *mem_ctx = NULL;
        TDB_DATA kbuf;
        WERROR status;
@@ -5350,8 +5448,15 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr)
 
        /* Store the security descriptor in a tdb */
 
-       prs_init(&ps, (uint32)sec_desc_size(new_secdesc_ctr->sd) +
-                sizeof(SEC_DESC_BUF), mem_ctx, MARSHALL);
+       if (!prs_init(&ps,
+               (uint32)ndr_size_security_descriptor(new_secdesc_ctr->sd, 0)
+               + sizeof(SEC_DESC_BUF), mem_ctx, MARSHALL) ) {
+               status = WERR_NOMEM;
+               goto out;
+       }
+
+
+       prs_init_done = true;
 
        if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr,
                             &ps, 1)) {
@@ -5372,7 +5477,9 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr)
 
  out:
 
-       prs_mem_free(&ps);
+       if (prs_init_done) {
+               prs_mem_free(&ps);
+       }
        if (mem_ctx)
                talloc_destroy(mem_ctx);
        return status;
@@ -5495,8 +5602,9 @@ bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **s
 
                /* Save default security descriptor for later */
 
-               prs_init(&ps, (uint32)sec_desc_size((*secdesc_ctr)->sd) +
-                               sizeof(SEC_DESC_BUF), ctx, MARSHALL);
+               if (!prs_init(&ps, (uint32)ndr_size_security_descriptor((*secdesc_ctr)->sd, 0) +
+                       sizeof(SEC_DESC_BUF), ctx, MARSHALL))
+                       return False;
 
                if (sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
                        tdb_prs_store(tdb_printers, kbuf, &ps);
@@ -5561,11 +5669,8 @@ bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **s
                           sharename, the_acl->num_aces));
 
                for (i = 0; i < the_acl->num_aces; i++) {
-                       fstring sid_str;
-
-                       sid_to_string(sid_str, &the_acl->aces[i].trustee);
-
-                       DEBUG(10, ("%s %d %d 0x%08x\n", sid_str,
+                       DEBUG(10, ("%s %d %d 0x%08x\n",
+                                  sid_string_dbg(&the_acl->aces[i].trustee),
                                   the_acl->aces[i].type, the_acl->aces[i].flags, 
                                   the_acl->aces[i].access_mask)); 
                }
@@ -5624,6 +5729,17 @@ void map_printer_permissions(SEC_DESC *sd)
        }
 }
 
+void map_job_permissions(SEC_DESC *sd)
+{
+       int i;
+
+       for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
+               se_map_generic(&sd->dacl->aces[i].access_mask,
+                              &job_generic_mapping);
+       }
+}
+
+
 /****************************************************************************
  Check a user has permissions to perform the given operation.  We use the
  permission constants defined in include/rpc_spoolss.h to check the various
@@ -5705,19 +5821,12 @@ bool print_access_check(struct current_user *user, int snum, int access_type)
                        return False;
                }
 
-               /* Now this is the bit that really confuses me.  The access
-                  type needs to be changed from JOB_ACCESS_ADMINISTER to
-                  PRINTER_ACCESS_ADMINISTER for this to work.  Something
-                  to do with the child (job) object becoming like a
-                  printer??  -tpot */
-
-               access_type = PRINTER_ACCESS_ADMINISTER;
+               map_job_permissions(secdesc->sd);
+       } else {
+               map_printer_permissions(secdesc->sd);
        }
-       
-       /* Check access */
-       
-       map_printer_permissions(secdesc->sd);
 
+       /* Check access */
        result = se_access_check(secdesc->sd, user->nt_user_token, access_type,
                                 &access_granted, &status);