Index: samba-3.0.24/source/rpc_server/srv_spoolss_nt.c =================================================================== --- samba-3.0.24.orig/source/rpc_server/srv_spoolss_nt.c 2007-02-04 12:59:21.000000000 -0600 +++ samba-3.0.24/source/rpc_server/srv_spoolss_nt.c 2007-02-15 11:02:09.000000000 -0600 @@ -5848,6 +5848,12 @@ goto done; } + if (!secdesc_ctr) { + DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n")); + result = WERR_INVALID_PARAM; + goto done; + } + /* Check the user has permissions to change the security descriptor. By experimentation with two NT machines, the user requires Full Access to the printer to change security @@ -9378,6 +9384,15 @@ /* housekeeping information in the reply */ + /* Fix from Martin Zielinski - ensure + * the hand marshalled container size is a multiple + * of 4 bytes for RPC alignment. + */ + + if (needed % 4) { + needed += 4-(needed % 4); + } + r_u->needed = needed; r_u->returned = num_entries; Index: samba-3.0.24/source/printing/nt_printing.c =================================================================== --- samba-3.0.24.orig/source/printing/nt_printing.c 2007-02-04 13:09:01.000000000 -0600 +++ samba-3.0.24/source/printing/nt_printing.c 2007-02-15 11:02:09.000000000 -0600 @@ -2984,11 +2984,15 @@ return True; } +/***************************************************************** + ****************************************************************/ + static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2, struct uuid guid) { int i; REGVAL_CTR *ctr=NULL; + UNISTR2 unistr_guid; /* find the DsSpooler key */ if ((i = lookup_printerkey(info2->data, SPOOL_DSSPOOLER_KEY)) < 0) @@ -2996,8 +3000,18 @@ ctr = info2->data->keys[i].values; regval_ctr_delvalue(ctr, "objectGUID"); - regval_ctr_addvalue(ctr, "objectGUID", REG_BINARY, - (char *) &guid, sizeof(struct uuid)); + + /* We used to store this as a REG_BINARY but that causes + Vista to whine */ + + ZERO_STRUCT( unistr_guid ); + init_unistr2( &unistr_guid, smb_uuid_string_static(guid), + UNI_STR_TERMINATE ); + + regval_ctr_addvalue(ctr, "objectGUID", REG_SZ, + (char *)unistr_guid.buffer, + unistr_guid.uni_max_len*2); + } static WERROR nt_printer_publish_ads(ADS_STRUCT *ads, @@ -3254,6 +3268,7 @@ REGISTRY_VALUE *guid_val; WERROR win_rc; int i; + BOOL ret = False; win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum)); @@ -3267,12 +3282,36 @@ return False; } - /* fetching printer guids really ought to be a separate function.. */ - if (guid && regval_size(guid_val) == sizeof(struct uuid)) - memcpy(guid, regval_data_p(guid_val), sizeof(struct uuid)); + /* fetching printer guids really ought to be a separate function. */ + + if ( guid ) { + fstring guid_str; + + /* We used to store the guid as REG_BINARY, then swapped + to REG_SZ for Vista compatibility so check for both */ + + switch ( regval_type(guid_val) ){ + case REG_SZ: + rpcstr_pull( guid_str, regval_data_p(guid_val), + sizeof(guid_str)-1, -1, STR_TERMINATE ); + ret = smb_string_to_uuid( guid_str, guid ); + break; + case REG_BINARY: + if ( regval_size(guid_val) != sizeof(struct uuid) ) { + ret = False; + break; + } + memcpy(guid, regval_data_p(guid_val), sizeof(struct uuid)); + break; + default: + DEBUG(0,("is_printer_published: GUID value stored as " + "invaluid type (%d)\n", regval_type(guid_val) )); + break; + } + } free_a_printer(&printer, 2); - return True; + return ret; } #else WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action) @@ -3539,13 +3578,43 @@ break; } - /* add the new value */ + DEBUG(8,("specific: [%s:%s], len: %d\n", keyname, valuename, size)); + + /* Vista doesn't like unknown REG_BINARY values in DsSpooler. + Thanks to Martin Zielinski for the hint. */ + + if ( type == REG_BINARY && + strequal( keyname, SPOOL_DSSPOOLER_KEY ) && + strequal( valuename, "objectGUID" ) ) + { + struct uuid guid; + UNISTR2 unistr_guid; + + ZERO_STRUCT( unistr_guid ); + + /* convert the GUID to a UNICODE string */ + + memcpy( &guid, data_p, sizeof(struct uuid) ); + + init_unistr2( &unistr_guid, smb_uuid_string_static(guid), + UNI_STR_TERMINATE ); + + regval_ctr_addvalue( printer_data->keys[key_index].values, + valuename, REG_SZ, + (const char *)unistr_guid.buffer, + unistr_guid.uni_str_len*2 ); + + } else { + /* add the value */ + + regval_ctr_addvalue( printer_data->keys[key_index].values, + valuename, type, (const char *)data_p, + size ); + } - regval_ctr_addvalue( printer_data->keys[key_index].values, valuename, type, (const char *)data_p, size ); SAFE_FREE(data_p); /* 'B' option to tdbpack does a malloc() */ - DEBUG(8,("specific: [%s:%s], len: %d\n", keyname, valuename, size)); } return len; Index: samba-3.0.24/source/rpc_server/srv_spoolss.c =================================================================== --- samba-3.0.24.orig/source/rpc_server/srv_spoolss.c 2006-04-19 21:29:27.000000000 -0500 +++ samba-3.0.24/source/rpc_server/srv_spoolss.c 2007-02-15 11:02:09.000000000 -0600 @@ -1477,6 +1477,15 @@ ZERO_STRUCT(r_u); if(!spoolss_io_q_addprinterdriverex("", &q_u, data, 0)) { + if (q_u.level != 3 && q_u.level != 6) { + /* Clever hack from Martin Zielinski + * to allow downgrade from level 8 (Vista). + */ + DEBUG(3,("api_spoolss_addprinterdriverex: unknown SPOOL_Q_ADDPRINTERDRIVEREX level %u.\n", + (unsigned int)q_u.level )); + setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_INVALID_TAG)); + return True; + } DEBUG(0,("spoolss_io_q_addprinterdriverex: unable to unmarshall SPOOL_Q_ADDPRINTERDRIVEREX.\n")); return False; } Index: samba-3.0.24/source/rpc_parse/parse_spoolss.c =================================================================== --- samba-3.0.24.orig/source/rpc_parse/parse_spoolss.c 2007-02-15 11:02:19.000000000 -0600 +++ samba-3.0.24/source/rpc_parse/parse_spoolss.c 2007-02-15 11:02:25.000000000 -0600 @@ -3893,7 +3893,16 @@ } case 3: { - ptr_sec_desc = q_u->info.info_3->secdesc_ptr; + /* FIXME ! Our parsing here is wrong I think, + * but for a level3 it makes no sense for + * ptr_sec_desc to be NULL. JRA. Based on + * a Vista sniff from Martin Zielinski . + */ + if (UNMARSHALLING(ps)) { + ptr_sec_desc = 1; + } else { + ptr_sec_desc = q_u->info.info_3->secdesc_ptr; + } break; } }