diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index 3a6d6eb9ec6..249053403d1 100755 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -371,6 +371,7 @@ PRINTER_MESSAGE_INFO; #define PRINTER_ATTRIBUTE_ENABLE_BIDI 0x00000800 #define PRINTER_ATTRIBUTE_RAW_ONLY 0x00001000 +#define PRINTER_ATTRIBUTE_PUBLISHED 0x00002000 #define NO_PRIORITY 0 #define MAX_PRIORITY 99 @@ -991,8 +992,8 @@ PRINTER_INFO_5; #define SPOOL_DS_PUBLISH 1 #define SPOOL_DS_UPDATE 2 -#define SPOOL_DS_UNPUBLISH 3 -#define SPOOL_DS_REPUBLISH 4 +#define SPOOL_DS_UNPUBLISH 4 +#define SPOOL_DS_PENDING 0x80000000 typedef struct printer_info_7 { diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index fcb96dd174e..af9a6451fe3 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -1581,6 +1581,32 @@ BOOL ads_pull_uint32(ADS_STRUCT *ads, return True; } +/** + * pull a single objectGUID from an ADS result + * @param ads connection to ADS server + * @param msg results of search + * @param guid 37-byte area to receive text guid + * @return boolean indicating success + **/ +BOOL ads_pull_guid(ADS_STRUCT *ads, + void *msg, GUID *guid) +{ + char **values; + + values = ldap_get_values(ads->ld, msg, "objectGUID"); + if (!values) return False; + + if (values[0]) { + memcpy(guid, values[0], sizeof(GUID)); + ldap_value_free(values); + return True; + } + ldap_value_free(values); + return False; + +} + + /** * pull a single DOM_SID from a ADS result * @param ads connection to ads server diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index cdcca6bbfed..532ab0794cd 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -2540,7 +2540,8 @@ static BOOL map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2) map_dword_into_ctr(ctr, SPOOL_REG_PRIORITY, info2->priority); map_bool_into_ctr(ctr, SPOOL_REG_PRINTKEEPPRINTEDJOBS, - (info2->attributes & 0x100)); + (info2->attributes & + PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS)); switch (info2->attributes & 0x3) { case 0: @@ -2583,11 +2584,12 @@ WERROR nt_printer_publish(int snum, int action) if (!W_ERROR_IS_OK(win_rc)) return win_rc; - if ((SPOOL_DS_PUBLISH == action) || (SPOOL_DS_UPDATE == action) || - (SPOOL_DS_REPUBLISH == action)) { + if ((SPOOL_DS_PUBLISH == action) || (SPOOL_DS_UPDATE == action)) { if (!(map_nt_printer_info2_to_dsspooler(printer->info_2))) return WERR_NOMEM; + printer->info_2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED; + win_rc = mod_a_printer(*printer, 2); if (!W_ERROR_IS_OK(win_rc)) { DEBUG(3, ("nt_printer_publish: err %d saving data\n", @@ -2600,13 +2602,22 @@ WERROR nt_printer_publish(int snum, int action) &printer->info_2->data); ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME, lp_servicename(snum)); + } else { + printer->info_2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED; + win_rc = mod_a_printer(*printer, 2); + if (!W_ERROR_IS_OK(win_rc)) { + DEBUG(3, ("nt_printer_publish: err %d saving data\n", + W_ERROR_V(win_rc))); + free_a_printer(&printer, 2); + return win_rc; + } } ads = ads_init(NULL, NULL, lp_ads_server()); ads_rc = ads_connect(ads); - if ((SPOOL_DS_UNPUBLISH == action) || (SPOOL_DS_REPUBLISH == action)) { + if (SPOOL_DS_UNPUBLISH == action) { ads_rc = ads_find_printer_on_server(ads, &res, printer->info_2->sharename, global_myname()); if (ADS_ERR_OK(ads_rc) && ads_count_replies(ads, res)) { @@ -2617,8 +2628,7 @@ WERROR nt_printer_publish(int snum, int action) } } - if ((SPOOL_DS_PUBLISH == action) || (SPOOL_DS_UPDATE == action) || - (SPOOL_DS_REPUBLISH == action)) { + if ((SPOOL_DS_PUBLISH == action) || (SPOOL_DS_UPDATE == action)) { ads_find_machine_acct(ads, &res, global_myname()); srv_dn = ldap_get_dn(ads->ld, res); ads_msgfree(ads, res); diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index fd223304498..0e3d69924b6 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -4148,14 +4148,50 @@ static BOOL construct_printer_info_5(PRINTER_INFO_5 *printer, int snum) } /******************************************************************** - * construct_printer_info_5 - * fill a printer_info_5 struct + * construct_printer_info_7 + * fill a printer_info_7 struct ********************************************************************/ -static BOOL construct_printer_info_7(PRINTER_INFO_7 *printer) +static BOOL construct_printer_info_7(PRINTER_INFO_7 *printer, int snum) { +#ifdef HAVE_ADS + char *guid_str = NULL; + GUID guid; + ADS_STRUCT *ads; + ADS_STATUS ads_rc; + void *res = NULL; + char *prt_dn; + const char *attrs[] = {"objectGUID", NULL}; + + printer->action = SPOOL_DS_UNPUBLISH; + + ads = ads_init(NULL, NULL, lp_ads_server()); + ads_rc = ads_connect(ads); + ads_rc = ads_find_printer_on_server(ads, &res, lp_servicename(snum), + global_myname()); + if (ADS_ERR_OK(ads_rc) && ads_count_replies(ads, res)) { + prt_dn = ads_get_dn(ads, res); + ads_msgfree(ads, res); + if (prt_dn && + ADS_ERR_OK(ads_search_dn(ads, &res, prt_dn, attrs))) { + ads_rc = ads_search_dn(ads, &res, prt_dn, attrs); + ads_memfree(ads, prt_dn); + ads_pull_guid(ads, res, &guid); + printer->action = SPOOL_DS_PUBLISH; + } + } + + ads_msgfree(ads, res); + + asprintf(&guid_str, "{%s}", uuid_string_static(guid)); + strupper(guid_str); + init_unistr(&printer->guid, guid_str); + +#else + printer->action = SPOOL_DS_UNPUBLISH; init_unistr(&printer->guid, ""); - printer->action = 0; +#endif + return True; } @@ -4722,7 +4758,7 @@ static WERROR getprinter_level_7(int snum, NEW_BUFFER *buffer, uint32 offered, u if((printer=(PRINTER_INFO_7*)malloc(sizeof(PRINTER_INFO_7)))==NULL) return WERR_NOMEM; - if (!construct_printer_info_7(printer)) + if (!construct_printer_info_7(printer, snum)) return WERR_NOMEM; /* check the required size. */