summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/rpc_server/srv_spoolss_util.c259
-rw-r--r--source3/rpc_server/srv_spoolss_util.h20
2 files changed, 279 insertions, 0 deletions
diff --git a/source3/rpc_server/srv_spoolss_util.c b/source3/rpc_server/srv_spoolss_util.c
index df34dea07f..1035b20b2f 100644
--- a/source3/rpc_server/srv_spoolss_util.c
+++ b/source3/rpc_server/srv_spoolss_util.c
@@ -29,6 +29,13 @@
#define TOP_LEVEL_CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control\\Print"
#define TOP_LEVEL_CONTROL_FORMS_KEY TOP_LEVEL_CONTROL_KEY "\\Forms"
+#define EMPTY_STRING ""
+
+#define CHECK_ERROR(result) \
+ if (W_ERROR_IS_OK(result)) continue; \
+ if (W_ERROR_EQUAL(result, WERR_NOT_FOUND)) result = WERR_OK; \
+ if (!W_ERROR_IS_OK(result)) break
+
/* FLAGS, NAME, with, height, left, top, right, bottom */
static const struct spoolss_FormInfo1 builtin_forms1[] = {
{ SPOOLSS_FORM_BUILTIN, "Letter", {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
@@ -1856,6 +1863,258 @@ done:
return result;
}
+WERROR winreg_get_printer(TALLOC_CTX *mem_ctx,
+ struct auth_serversupplied_info *server_info,
+ const char *printer,
+ struct spoolss_PrinterInfo2 **pinfo2)
+{
+ struct spoolss_PrinterInfo2 *info2;
+ uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+ struct rpc_pipe_client *winreg_pipe = NULL;
+ struct policy_handle hive_hnd, key_hnd;
+ struct spoolss_PrinterEnumValues *enum_values = NULL;
+ struct spoolss_PrinterEnumValues *v;
+ enum ndr_err_code ndr_err;
+ DATA_BLOB blob;
+ uint32_t num_values = 0;
+ uint32_t i;
+ char *path;
+ WERROR result = WERR_OK;
+ TALLOC_CTX *tmp_ctx;
+
+ tmp_ctx = talloc_new(mem_ctx);
+ if (tmp_ctx == NULL) {
+ return WERR_NOMEM;
+ }
+
+ path = winreg_printer_data_keyname(tmp_ctx, printer);
+ if (path == NULL) {
+ TALLOC_FREE(tmp_ctx);
+ return WERR_NOMEM;
+ }
+
+ result = winreg_printer_openkey(tmp_ctx,
+ server_info,
+ &winreg_pipe,
+ path,
+ "",
+ false,
+ access_mask,
+ &hive_hnd,
+ &key_hnd);
+ if (!W_ERROR_IS_OK(result)) {
+ DEBUG(0, ("winreg_get_printer: Could not open key %s: %s\n",
+ path, win_errstr(result)));
+ goto done;
+ }
+
+ result = winreg_printer_enumvalues(tmp_ctx,
+ winreg_pipe,
+ &key_hnd,
+ &num_values,
+ &enum_values);
+ if (!W_ERROR_IS_OK(result)) {
+ DEBUG(0, ("winreg_get_printer: Could not enumerate values in %s: %s\n",
+ path, win_errstr(result)));
+ goto done;
+ }
+
+ info2 = talloc_zero(tmp_ctx, struct spoolss_PrinterInfo2);
+ if (info2 == NULL) {
+ result = WERR_NOMEM;
+ goto done;
+ }
+
+ info2->servername = talloc_asprintf(info2, "\\\\%s", global_myname());
+ if (info2->servername == NULL) {
+ result = WERR_NOMEM;
+ goto done;
+ }
+
+ info2->printername = EMPTY_STRING;
+ info2->sharename = EMPTY_STRING;
+ info2->portname = EMPTY_STRING;
+ info2->drivername = EMPTY_STRING;
+ info2->comment = EMPTY_STRING;
+ info2->location = EMPTY_STRING;
+ info2->sepfile = EMPTY_STRING;
+ info2->printprocessor = EMPTY_STRING;
+ info2->datatype = EMPTY_STRING;
+ info2->parameters = EMPTY_STRING;
+
+ for (i = 0; i < num_values; i++) {
+ v = &enum_values[i];
+
+ result = winreg_enumval_to_sz(info2,
+ v,
+ "Name",
+ &info2->printername);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_sz(info2,
+ v,
+ "Share Name",
+ &info2->sharename);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_sz(info2,
+ v,
+ "Port",
+ &info2->portname);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_sz(info2,
+ v,
+ "Description",
+ &info2->comment);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_sz(info2,
+ v,
+ "Location",
+ &info2->location);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_sz(info2,
+ v,
+ "Separator File",
+ &info2->sepfile);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_sz(info2,
+ v,
+ "Print Processor",
+ &info2->printprocessor);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_sz(info2,
+ v,
+ "Datatype",
+ &info2->datatype);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_sz(info2,
+ v,
+ "Parameters",
+ &info2->parameters);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_dword(info2,
+ v,
+ "Attributes",
+ &info2->attributes);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_dword(info2,
+ v,
+ "Priority",
+ &info2->priority);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_dword(info2,
+ v,
+ "Default Priority",
+ &info2->defaultpriority);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_dword(info2,
+ v,
+ "StartTime",
+ &info2->starttime);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_dword(info2,
+ v,
+ "UntilTime",
+ &info2->untiltime);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_dword(info2,
+ v,
+ "Status",
+ &info2->status);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_dword(info2,
+ v,
+ "StartTime",
+ &info2->starttime);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_blob(info2,
+ v,
+ "Default DevMode",
+ &blob);
+ if (W_ERROR_IS_OK(result)) {
+ info2->devmode = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
+ if (info2->devmode == NULL) {
+ result = WERR_NOMEM;
+ goto done;
+ }
+ ndr_err = ndr_pull_struct_blob(&blob,
+ info2,
+ NULL,
+ info2->devmode,
+ (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeviceMode);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(0, ("winreg_get_printer: Failed to unmarshall device mode\n"));
+ result = WERR_NOMEM;
+ goto done;
+ }
+ }
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_blob(info2,
+ v,
+ "Security",
+ &blob);
+ if (W_ERROR_IS_OK(result)) {
+ info2->secdesc = talloc_zero(mem_ctx, struct spoolss_security_descriptor);
+ if (info2->secdesc == NULL) {
+ result = WERR_NOMEM;
+ goto done;
+ }
+ ndr_err = ndr_pull_struct_blob(&blob,
+ mem_ctx,
+ NULL,
+ info2->secdesc,
+ (ndr_pull_flags_fn_t) ndr_pull_security_descriptor);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(0, ("winreg_get_printer: Failed to unmarshall security descriptor\n"));
+ result = WERR_NOMEM;
+ goto done;
+ }
+ }
+ CHECK_ERROR(result);
+ }
+
+ if (!W_ERROR_IS_OK(result)) {
+ DEBUG(0, ("winreg_get_printer: winreg_enumval_to_TYPE() failed "
+ "for %s: %s\n",
+ v->value_name,
+ win_errstr(result)));
+ goto done;
+ }
+
+ if (pinfo2) {
+ *pinfo2 = talloc_move(mem_ctx, &info2);
+ }
+
+ result = WERR_OK;
+done:
+ if (winreg_pipe != NULL) {
+ if (is_valid_policy_hnd(&key_hnd)) {
+ rpccli_winreg_CloseKey(winreg_pipe, tmp_ctx, &key_hnd, NULL);
+ }
+ if (is_valid_policy_hnd(&hive_hnd)) {
+ rpccli_winreg_CloseKey(winreg_pipe, tmp_ctx, &hive_hnd, NULL);
+ }
+ }
+
+ TALLOC_FREE(tmp_ctx);
+ return result;
+}
+
/* Set printer data over the winreg pipe. */
WERROR winreg_set_printer_dataex(TALLOC_CTX *mem_ctx,
struct auth_serversupplied_info *server_info,
diff --git a/source3/rpc_server/srv_spoolss_util.h b/source3/rpc_server/srv_spoolss_util.h
index 1590db2c64..4b5117e937 100644
--- a/source3/rpc_server/srv_spoolss_util.h
+++ b/source3/rpc_server/srv_spoolss_util.h
@@ -102,6 +102,26 @@ WERROR winreg_update_printer(TALLOC_CTX *mem_ctx,
struct spoolss_DeviceMode *devmode,
struct security_descriptor *secdesc);
+
+/**
+ * @brief Get the inforamtion of a printer stored in the registry.
+ *
+ * @param[in] mem_ctx The talloc memory context to use.
+ *
+ * @param[in] server_info The server supplied session info.
+ *
+ * @param[in] printer The name of the printer to get.
+ *
+ * @param[out] pinfo2 A pointer to store a PRINTER_INFO_2 structure.
+ *
+ * @return On success WERR_OK, a corresponding DOS error is
+ * something went wrong.
+ */
+WERROR winreg_get_printer(TALLOC_CTX *mem_ctx,
+ struct auth_serversupplied_info *server_info,
+ const char *printer,
+ struct spoolss_PrinterInfo2 **pinfo2);
+
/**
* @internal
*