const char *printer, struct GUID guid)
{
TALLOC_CTX *tmp_ctx;
- struct auth_serversupplied_info *session_info = NULL;
+ struct auth_session_info *session_info = NULL;
const char *guid_str;
DATA_BLOB blob;
NTSTATUS status;
talloc_free(tmp_ctx);
}
+WERROR nt_printer_guid_get(TALLOC_CTX *mem_ctx,
+ const struct auth_session_info *session_info,
+ struct messaging_context *msg_ctx,
+ const char *printer, struct GUID *guid)
+{
+ TALLOC_CTX *tmp_ctx;
+ enum winreg_Type type;
+ DATA_BLOB blob;
+ uint32_t len;
+ NTSTATUS status;
+ WERROR result;
+
+ tmp_ctx = talloc_new(mem_ctx);
+ if (tmp_ctx == NULL) {
+ DEBUG(0, ("out of memory?!\n"));
+ return WERR_NOMEM;
+ }
+
+ result = winreg_get_printer_dataex_internal(tmp_ctx, session_info,
+ msg_ctx, printer,
+ SPOOL_DSSPOOLER_KEY,
+ "objectGUID",
+ &type,
+ &blob.data,
+ &len);
+ if (!W_ERROR_IS_OK(result)) {
+ DEBUG(0, ("Failed to get GUID for printer %s\n", printer));
+ goto out_ctx_free;
+ }
+ blob.length = (size_t)len;
+
+ /* We used to store the guid as REG_BINARY, then swapped
+ to REG_SZ for Vista compatibility so check for both */
+
+ switch (type) {
+ case REG_SZ: {
+ bool ok;
+ const char *guid_str;
+ ok = pull_reg_sz(tmp_ctx, &blob, &guid_str);
+ if (!ok) {
+ DEBUG(0, ("Failed to unmarshall GUID for printer %s\n",
+ printer));
+ result = WERR_REG_CORRUPT;
+ goto out_ctx_free;
+ }
+ status = GUID_from_string(guid_str, guid);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("bad GUID for printer %s\n", printer));
+ result = ntstatus_to_werror(status);
+ goto out_ctx_free;
+ }
+ break;
+ }
+ case REG_BINARY:
+ if (blob.length != sizeof(struct GUID)) {
+ DEBUG(0, ("bad GUID for printer %s\n", printer));
+ result = WERR_REG_CORRUPT;
+ goto out_ctx_free;
+ }
+ memcpy(guid, blob.data, sizeof(struct GUID));
+ break;
+ default:
+ DEBUG(0,("GUID value stored as invalid type (%d)\n", type));
+ result = WERR_REG_CORRUPT;
+ goto out_ctx_free;
+ break;
+ }
+ result = WERR_OK;
+
+out_ctx_free:
+ talloc_free(tmp_ctx);
+ return result;
+}
+
+static WERROR nt_printer_info_to_mods(TALLOC_CTX *ctx,
+ struct spoolss_PrinterInfo2 *info2,
+ ADS_MODLIST *mods)
+{
+ char *info_str;
+
+ ads_mod_str(ctx, mods, SPOOL_REG_PRINTERNAME, info2->sharename);
+ ads_mod_str(ctx, mods, SPOOL_REG_SHORTSERVERNAME, lp_netbios_name());
+ ads_mod_str(ctx, mods, SPOOL_REG_SERVERNAME, get_mydnsfullname());
+
+ info_str = talloc_asprintf(ctx, "\\\\%s\\%s",
+ get_mydnsfullname(), info2->sharename);
+ if (info_str == NULL) {
+ return WERR_NOMEM;
+ }
+ ads_mod_str(ctx, mods, SPOOL_REG_UNCNAME, info_str);
+
+ info_str = talloc_asprintf(ctx, "%d", 4);
+ if (info_str == NULL) {
+ return WERR_NOMEM;
+ }
+ ads_mod_str(ctx, mods, SPOOL_REG_VERSIONNUMBER, info_str);
+
+ /* empty strings in the mods list result in an attrubute error */
+ if (strlen(info2->drivername) != 0)
+ ads_mod_str(ctx, mods, SPOOL_REG_DRIVERNAME, info2->drivername);
+ if (strlen(info2->location) != 0)
+ ads_mod_str(ctx, mods, SPOOL_REG_LOCATION, info2->location);
+ if (strlen(info2->comment) != 0)
+ ads_mod_str(ctx, mods, SPOOL_REG_DESCRIPTION, info2->comment);
+ if (strlen(info2->portname) != 0)
+ ads_mod_str(ctx, mods, SPOOL_REG_PORTNAME, info2->portname);
+ if (strlen(info2->sepfile) != 0)
+ ads_mod_str(ctx, mods, SPOOL_REG_PRINTSEPARATORFILE, info2->sepfile);
+
+ info_str = talloc_asprintf(ctx, "%u", info2->starttime);
+ if (info_str == NULL) {
+ return WERR_NOMEM;
+ }
+ ads_mod_str(ctx, mods, SPOOL_REG_PRINTSTARTTIME, info_str);
+
+ info_str = talloc_asprintf(ctx, "%u", info2->untiltime);
+ if (info_str == NULL) {
+ return WERR_NOMEM;
+ }
+ ads_mod_str(ctx, mods, SPOOL_REG_PRINTENDTIME, info_str);
+
+ info_str = talloc_asprintf(ctx, "%u", info2->priority);
+ if (info_str == NULL) {
+ return WERR_NOMEM;
+ }
+ ads_mod_str(ctx, mods, SPOOL_REG_PRIORITY, info_str);
+
+ if (info2->attributes & PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS) {
+ ads_mod_str(ctx, mods, SPOOL_REG_PRINTKEEPPRINTEDJOBS, "TRUE");
+ } else {
+ ads_mod_str(ctx, mods, SPOOL_REG_PRINTKEEPPRINTEDJOBS, "FALSE");
+ }
+
+ switch (info2->attributes & 0x3) {
+ case 0:
+ ads_mod_str(ctx, mods, SPOOL_REG_PRINTSPOOLING,
+ SPOOL_REGVAL_PRINTWHILESPOOLING);
+ break;
+ case 1:
+ ads_mod_str(ctx, mods, SPOOL_REG_PRINTSPOOLING,
+ SPOOL_REGVAL_PRINTAFTERSPOOLED);
+ break;
+ case 2:
+ ads_mod_str(ctx, mods, SPOOL_REG_PRINTSPOOLING,
+ SPOOL_REGVAL_PRINTDIRECT);
+ break;
+ default:
+ DEBUG(3, ("unsupported printer attributes %x\n",
+ info2->attributes));
+ }
+
+ return WERR_OK;
+}
+
static WERROR nt_printer_publish_ads(struct messaging_context *msg_ctx,
ADS_STRUCT *ads,
struct spoolss_PrinterInfo2 *pinfo2)
DEBUG(5, ("publishing printer %s\n", printer));
/* figure out where to publish */
- ads_find_machine_acct(ads, &res, lp_netbios_name());
+ ads_rc = ads_find_machine_acct(ads, &res, lp_netbios_name());
+ if (!ADS_ERR_OK(ads_rc)) {
+ DEBUG(0, ("failed to find machine account for %s\n",
+ lp_netbios_name()));
+ TALLOC_FREE(ctx);
+ return WERR_NOT_FOUND;
+ }
/* We use ldap_get_dn here as we need the answer
* in utf8 to call ldap_explode_dn(). JRA. */
srv_dn_utf8 = ldap_get_dn((LDAP *)ads->ldap.ld, (LDAPMessage *)res);
+ ads_msgfree(ads, res);
if (!srv_dn_utf8) {
TALLOC_FREE(ctx);
return WERR_SERVER_UNAVAILABLE;
}
- ads_msgfree(ads, res);
srv_cn_utf8 = ldap_explode_dn(srv_dn_utf8, 1);
if (!srv_cn_utf8) {
TALLOC_FREE(ctx);
mods = ads_init_mods(ctx);
if (mods == NULL) {
- SAFE_FREE(prt_dn);
TALLOC_FREE(ctx);
return WERR_NOMEM;
}
- ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME, printer);
+ win_rc = nt_printer_info_to_mods(ctx, pinfo2, &mods);
+ if (!W_ERROR_IS_OK(win_rc)) {
+ TALLOC_FREE(ctx);
+ return win_rc;
+ }
/* publish it */
ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx, &mods);
***************************************************************************/
WERROR nt_printer_publish(TALLOC_CTX *mem_ctx,
- const struct auth_serversupplied_info *session_info,
+ const struct auth_session_info *session_info,
struct messaging_context *msg_ctx,
struct spoolss_PrinterInfo2 *pinfo2,
int action)
ADS_STATUS ads_rc;
ADS_STRUCT *ads = NULL;
WERROR win_rc;
+ char *old_krb5ccname = NULL;
sinfo2 = talloc_zero(mem_ctx, struct spoolss_SetPrinterInfo2);
if (!sinfo2) {
pinfo2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED;
break;
case DSPRINT_UNPUBLISH:
- pinfo2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED;
+ pinfo2->attributes &= (~PRINTER_ATTRIBUTE_PUBLISHED);
break;
default:
win_rc = WERR_NOT_SUPPORTED;
win_rc = WERR_SERVER_UNAVAILABLE;
goto done;
}
+ old_krb5ccname = getenv(KRB5_ENV_CCNAME);
setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
SAFE_FREE(ads->auth.password);
ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
done:
ads_destroy(&ads);
+ ads_kdestroy("MEMORY:prtpub_cache");
+ unsetenv(KRB5_ENV_CCNAME);
+ if (old_krb5ccname) {
+ setenv(KRB5_ENV_CCNAME, old_krb5ccname, 0);
+ }
return win_rc;
}
int snum;
int n_services = lp_numservices();
TALLOC_CTX *tmp_ctx = NULL;
- struct auth_serversupplied_info *session_info = NULL;
+ struct auth_session_info *session_info = NULL;
struct spoolss_PrinterInfo2 *pinfo2;
NTSTATUS status;
WERROR result;
+ char *old_krb5ccname = NULL;
tmp_ctx = talloc_new(NULL);
if (!tmp_ctx) return WERR_NOMEM;
DEBUG(3, ("ads_init() failed\n"));
return WERR_SERVER_UNAVAILABLE;
}
+ old_krb5ccname = getenv(KRB5_ENV_CCNAME);
setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
SAFE_FREE(ads->auth.password);
ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
}
result = winreg_get_printer_internal(tmp_ctx, session_info, msg_ctx,
- lp_servicename(snum),
+ lp_servicename(talloc_tos(), snum),
&pinfo2);
if (!W_ERROR_IS_OK(result)) {
continue;
done:
ads_destroy(&ads);
ads_kdestroy("MEMORY:prtpub_cache");
+ unsetenv(KRB5_ENV_CCNAME);
+ if (old_krb5ccname) {
+ setenv(KRB5_ENV_CCNAME, old_krb5ccname, 0);
+ }
talloc_free(tmp_ctx);
return result;
}
bool is_printer_published(TALLOC_CTX *mem_ctx,
- const struct auth_serversupplied_info *session_info,
+ const struct auth_session_info *session_info,
struct messaging_context *msg_ctx,
- const char *servername, char *printer, struct GUID *guid,
+ const char *servername,
+ const char *printer,
struct spoolss_PrinterInfo2 **info2)
{
struct spoolss_PrinterInfo2 *pinfo2 = NULL;
- enum winreg_Type type;
- uint8_t *data;
- uint32_t data_size;
WERROR result;
- NTSTATUS status;
+ struct dcerpc_binding_handle *b;
- result = winreg_get_printer_internal(mem_ctx, session_info, msg_ctx,
- printer, &pinfo2);
+ result = winreg_printer_binding_handle(mem_ctx,
+ session_info,
+ msg_ctx,
+ &b);
if (!W_ERROR_IS_OK(result)) {
return false;
}
- if (!(pinfo2->attributes & PRINTER_ATTRIBUTE_PUBLISHED)) {
- TALLOC_FREE(pinfo2);
+ result = winreg_get_printer(mem_ctx, b,
+ printer, &pinfo2);
+ if (!W_ERROR_IS_OK(result)) {
return false;
}
- if (!guid) {
- goto done;
- }
-
- /* fetching printer guids really ought to be a separate function. */
-
- result = winreg_get_printer_dataex_internal(mem_ctx, session_info, msg_ctx,
- printer,
- SPOOL_DSSPOOLER_KEY, "objectGUID",
- &type, &data, &data_size);
- if (!W_ERROR_IS_OK(result)) {
+ if (!(pinfo2->attributes & PRINTER_ATTRIBUTE_PUBLISHED)) {
TALLOC_FREE(pinfo2);
return false;
}
- /* We used to store the guid as REG_BINARY, then swapped
- to REG_SZ for Vista compatibility so check for both */
-
- switch (type) {
- case REG_SZ:
- status = GUID_from_string((char *)data, guid);
- if (!NT_STATUS_IS_OK(status)) {
- TALLOC_FREE(pinfo2);
- return false;
- }
- break;
-
- case REG_BINARY:
- if (data_size != sizeof(struct GUID)) {
- TALLOC_FREE(pinfo2);
- return false;
- }
- memcpy(guid, data, sizeof(struct GUID));
- break;
- default:
- DEBUG(0,("is_printer_published: GUID value stored as "
- "invaluid type (%d)\n", type));
- break;
- }
-
-done:
if (info2) {
*info2 = talloc_move(mem_ctx, &pinfo2);
}
return true;
}
#else
+WERROR nt_printer_guid_get(TALLOC_CTX *mem_ctx,
+ const struct auth_session_info *session_info,
+ struct messaging_context *msg_ctx,
+ const char *printer, struct GUID *guid)
+{
+ return WERR_NOT_SUPPORTED;
+}
+
WERROR nt_printer_publish(TALLOC_CTX *mem_ctx,
- const struct auth_serversupplied_info *session_info,
+ const struct auth_session_info *session_info,
struct messaging_context *msg_ctx,
struct spoolss_PrinterInfo2 *pinfo2,
int action)
}
bool is_printer_published(TALLOC_CTX *mem_ctx,
- const struct auth_serversupplied_info *session_info,
+ const struct auth_session_info *session_info,
struct messaging_context *msg_ctx,
- const char *servername, char *printer, struct GUID *guid,
+ const char *servername,
+ const char *printer,
struct spoolss_PrinterInfo2 **info2)
{
return False;