mirror of
https://github.com/samba-team/samba.git
synced 2025-01-29 21:47:30 +03:00
Store printer guid in the dsspooler registry key so we don't have to
query the directory server every time someone asks (This used to be commit f0fc4e30f6284565de404a20450a587cd3fe00a5)
This commit is contained in:
parent
72e16f233d
commit
5f9348d4fc
@ -2508,16 +2508,10 @@ static BOOL map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2)
|
||||
char *ascii_str;
|
||||
int i;
|
||||
|
||||
for (i=0; i < info2->data.num_keys; i++)
|
||||
if (!(StrCaseCmp(SPOOL_DSSPOOLER_KEY,
|
||||
info2->data.keys[i].name)))
|
||||
ctr = &info2->data.keys[i].values;
|
||||
if ((i = lookup_printerkey(&info2->data, SPOOL_DSSPOOLER_KEY)) < 0)
|
||||
i = add_new_printer_key(&info2->data, SPOOL_DSSPOOLER_KEY);
|
||||
ctr = &info2->data.keys[i].values;
|
||||
|
||||
if (!ctr) {
|
||||
add_new_printer_key(&info2->data, SPOOL_DSSPOOLER_KEY);
|
||||
ctr = &info2->data.keys[info2->data.num_keys - 1].values;
|
||||
}
|
||||
|
||||
map_sz_into_ctr(ctr, SPOOL_REG_PRINTERNAME, info2->sharename);
|
||||
map_sz_into_ctr(ctr, SPOOL_REG_SHORTSERVERNAME, global_myname());
|
||||
|
||||
@ -2561,6 +2555,136 @@ static BOOL map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2)
|
||||
return True;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ADS
|
||||
static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2, GUID guid)
|
||||
{
|
||||
int i;
|
||||
REGVAL_CTR *ctr=NULL;
|
||||
|
||||
/* find the DsSpooler key */
|
||||
if ((i = lookup_printerkey(&info2->data, SPOOL_DSSPOOLER_KEY)) < 0)
|
||||
i = add_new_printer_key(&info2->data, SPOOL_DSSPOOLER_KEY);
|
||||
ctr = &info2->data.keys[i].values;
|
||||
|
||||
regval_ctr_delvalue(ctr, "objectGUID");
|
||||
regval_ctr_addvalue(ctr, "objectGUID", REG_BINARY,
|
||||
(char *) &guid, sizeof(GUID));
|
||||
}
|
||||
|
||||
static WERROR publish_it(NT_PRINTER_INFO_LEVEL *printer)
|
||||
{
|
||||
ADS_STATUS ads_rc;
|
||||
TALLOC_CTX *ctx = talloc_init();
|
||||
ADS_MODLIST mods = ads_init_mods(ctx);
|
||||
char *prt_dn = NULL, *srv_dn, **srv_cn;
|
||||
void *res = NULL;
|
||||
ADS_STRUCT *ads;
|
||||
const char *attrs[] = {"objectGUID", NULL};
|
||||
GUID guid;
|
||||
WERROR win_rc = WERR_OK;
|
||||
|
||||
ZERO_STRUCT(guid);
|
||||
/* set the DsSpooler info and attributes */
|
||||
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, ("err %d saving data\n",
|
||||
W_ERROR_V(win_rc)));
|
||||
return win_rc;
|
||||
}
|
||||
|
||||
/* Build the ads mods */
|
||||
get_local_printer_publishing_data(ctx, &mods,
|
||||
&printer->info_2->data);
|
||||
ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME,
|
||||
printer->info_2->sharename);
|
||||
|
||||
/* connect to the ADS server */
|
||||
ads = ads_init(NULL, NULL, lp_ads_server());
|
||||
if (!ads) {
|
||||
DEBUG(3, ("ads_init() failed\n"));
|
||||
return WERR_SERVER_UNAVAILABLE;
|
||||
}
|
||||
ads_rc = ads_connect(ads);
|
||||
if (!ADS_ERR_OK(ads_rc)) {
|
||||
DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
|
||||
ads_destroy(&ads);
|
||||
return WERR_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
/* figure out where to publish */
|
||||
ads_find_machine_acct(ads, &res, global_myname());
|
||||
srv_dn = ldap_get_dn(ads->ld, res);
|
||||
ads_msgfree(ads, res);
|
||||
srv_cn = ldap_explode_dn(srv_dn, 1);
|
||||
asprintf(&prt_dn, "cn=%s-%s,%s", srv_cn[0],
|
||||
printer->info_2->sharename, srv_dn);
|
||||
ads_memfree(ads, srv_dn);
|
||||
|
||||
/* publish it */
|
||||
ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods);
|
||||
if (LDAP_ALREADY_EXISTS == ads_rc.err.rc)
|
||||
ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx,&mods);
|
||||
|
||||
/* retreive the guid and store it locally */
|
||||
if (ADS_ERR_OK(ads_search_dn(ads, &res, prt_dn, attrs))) {
|
||||
ads_memfree(ads, prt_dn);
|
||||
ads_pull_guid(ads, res, &guid);
|
||||
ads_msgfree(ads, res);
|
||||
store_printer_guid(printer->info_2, guid);
|
||||
win_rc = mod_a_printer(*printer, 2);
|
||||
}
|
||||
|
||||
safe_free(prt_dn);
|
||||
ads_destroy(&ads);
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
WERROR unpublish_it(NT_PRINTER_INFO_LEVEL *printer)
|
||||
{
|
||||
ADS_STATUS ads_rc;
|
||||
ADS_STRUCT *ads;
|
||||
void *res;
|
||||
char *prt_dn = NULL;
|
||||
WERROR win_rc;
|
||||
|
||||
printer->info_2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED;
|
||||
win_rc = mod_a_printer(*printer, 2);
|
||||
if (!W_ERROR_IS_OK(win_rc)) {
|
||||
DEBUG(3, ("err %d saving data\n",
|
||||
W_ERROR_V(win_rc)));
|
||||
return win_rc;
|
||||
}
|
||||
|
||||
ads = ads_init(NULL, NULL, lp_ads_server());
|
||||
if (!ads) {
|
||||
DEBUG(3, ("ads_init() failed\n"));
|
||||
return WERR_SERVER_UNAVAILABLE;
|
||||
}
|
||||
ads_rc = ads_connect(ads);
|
||||
if (!ADS_ERR_OK(ads_rc)) {
|
||||
DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
|
||||
ads_destroy(&ads);
|
||||
return WERR_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
/* remove the printer from the directory */
|
||||
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)) {
|
||||
prt_dn = ads_get_dn(ads, res);
|
||||
ads_msgfree(ads, res);
|
||||
ads_rc = ads_del_dn(ads, prt_dn);
|
||||
ads_memfree(ads, prt_dn);
|
||||
}
|
||||
|
||||
ads_destroy(&ads);
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Publish a printer in the directory
|
||||
*
|
||||
@ -2570,87 +2694,69 @@ static BOOL map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2)
|
||||
|
||||
WERROR nt_printer_publish(int snum, int action)
|
||||
{
|
||||
#ifdef HAVE_ADS
|
||||
NT_PRINTER_INFO_LEVEL *printer = NULL;
|
||||
WERROR win_rc;
|
||||
ADS_STATUS ads_rc;
|
||||
TALLOC_CTX *ctx = talloc_init();
|
||||
ADS_MODLIST mods = ads_init_mods(ctx);
|
||||
char *prt_dn = NULL, *srv_dn, **srv_cn;
|
||||
void *res = NULL;
|
||||
ADS_STRUCT *ads;
|
||||
|
||||
win_rc = get_a_printer(&printer, 2, lp_servicename(snum));
|
||||
if (!W_ERROR_IS_OK(win_rc))
|
||||
return win_rc;
|
||||
|
||||
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",
|
||||
W_ERROR_V(win_rc)));
|
||||
free_a_printer(&printer, 2);
|
||||
return win_rc;
|
||||
}
|
||||
|
||||
get_local_printer_publishing_data(ctx, &mods,
|
||||
&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) {
|
||||
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)) {
|
||||
prt_dn = ads_get_dn(ads, res);
|
||||
ads_msgfree(ads, res);
|
||||
ads_rc = ads_del_dn(ads, prt_dn);
|
||||
ads_memfree(ads, prt_dn);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
srv_cn = ldap_explode_dn(srv_dn, 1);
|
||||
asprintf(&prt_dn, "cn=%s-%s,%s", srv_cn[0],
|
||||
printer->info_2->sharename, srv_dn);
|
||||
ads_memfree(ads, srv_dn);
|
||||
|
||||
ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods);
|
||||
if (LDAP_ALREADY_EXISTS == ads_rc.err.rc)
|
||||
ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx,&mods);
|
||||
safe_free(prt_dn);
|
||||
ads_destroy(&ads);
|
||||
switch(action) {
|
||||
case SPOOL_DS_PUBLISH:
|
||||
case SPOOL_DS_UPDATE:
|
||||
win_rc = publish_it(printer);
|
||||
break;
|
||||
case SPOOL_DS_UNPUBLISH:
|
||||
win_rc = unpublish_it(printer);
|
||||
break;
|
||||
default:
|
||||
win_rc = WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
free_a_printer(&printer, 2);
|
||||
return WERR_OK;
|
||||
#else
|
||||
return WERR_OK;
|
||||
#endif
|
||||
return win_rc;
|
||||
}
|
||||
|
||||
BOOL is_printer_published(int snum, GUID *guid)
|
||||
{
|
||||
NT_PRINTER_INFO_LEVEL *printer = NULL;
|
||||
REGVAL_CTR *ctr;
|
||||
REGISTRY_VALUE *guid_val;
|
||||
WERROR win_rc;
|
||||
int i;
|
||||
|
||||
|
||||
win_rc = get_a_printer(&printer, 2, lp_servicename(snum));
|
||||
if (!W_ERROR_IS_OK(win_rc))
|
||||
return False;
|
||||
|
||||
if (!(printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED))
|
||||
return False;
|
||||
|
||||
if ((i = lookup_printerkey(&printer->info_2->data,
|
||||
SPOOL_DSSPOOLER_KEY)) < 0)
|
||||
return False;
|
||||
|
||||
ctr = &printer->info_2->data.keys[i].values;
|
||||
|
||||
guid_val = regval_ctr_getvalue(ctr, "objectGUID");
|
||||
if (regval_size(guid_val) == sizeof(GUID))
|
||||
memcpy(guid, regval_data_p(guid_val), sizeof(GUID));
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
#else
|
||||
WERROR nt_printer_publish(int snum, int action)
|
||||
{
|
||||
return WERR_OK;
|
||||
}
|
||||
BOOL is_printer_published(int snum, GUID *guid)
|
||||
{
|
||||
return False;
|
||||
}
|
||||
#endif
|
||||
/****************************************************************************
|
||||
***************************************************************************/
|
||||
|
||||
|
@ -4154,44 +4154,19 @@ static BOOL construct_printer_info_5(PRINTER_INFO_5 *printer, int snum)
|
||||
|
||||
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;
|
||||
}
|
||||
if (is_printer_published(snum, &guid)) {
|
||||
asprintf(&guid_str, "{%s}", uuid_string_static(guid));
|
||||
strupper(guid_str);
|
||||
init_unistr(&printer->guid, guid_str);
|
||||
printer->action = SPOOL_DS_PUBLISH;
|
||||
} else {
|
||||
init_unistr(&printer->guid, "");
|
||||
printer->action = SPOOL_DS_UNPUBLISH;
|
||||
}
|
||||
|
||||
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, "");
|
||||
#endif
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user