[PATCH 3/6] s3-spoolss: Add port registry functions
Justin Chevrier
jchevrier at gmail.com
Wed Aug 31 13:03:11 MDT 2011
Signed-off-by: Justin Chevrier <jchevrier at gmail.com>
---
source3/registry/reg_backend_db.c | 2 +-
source3/rpc_client/cli_winreg_spoolss.c | 615 +++++++++++++++++++++++++
source3/rpc_client/cli_winreg_spoolss.h | 108 +++++
source3/rpc_server/spoolss/srv_spoolss_util.c | 51 ++
source3/rpc_server/spoolss/srv_spoolss_util.h | 15 +
5 files changed, 790 insertions(+), 1 deletions(-)
diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c
index 58e7b33..9a1a3fb 100644
--- a/source3/registry/reg_backend_db.c
+++ b/source3/registry/reg_backend_db.c
@@ -89,7 +89,7 @@ static const char *builtin_registry_paths[] = {
KEY_GP_USER_POLICY,
KEY_GP_USER_WIN_POLICY,
"HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\GPExtensions",
- "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors",
+ "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors\\Standard TCP/IP Port\\Ports",
KEY_PROD_OPTIONS,
"HKLM\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration",
KEY_TCPIP_PARAMS,
diff --git a/source3/rpc_client/cli_winreg_spoolss.c b/source3/rpc_client/cli_winreg_spoolss.c
index 2a6a8d1..3159e0b 100644
--- a/source3/rpc_client/cli_winreg_spoolss.c
+++ b/source3/rpc_client/cli_winreg_spoolss.c
@@ -36,6 +36,8 @@
#define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers"
#define TOP_LEVEL_CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control\\Print"
#define TOP_LEVEL_CONTROL_FORMS_KEY TOP_LEVEL_CONTROL_KEY "\\Forms"
+#define TOP_LEVEL_PORT_KEY "\\Monitors\\Standard TCP/IP Port"
+#define TOP_LEVEL_PORT_PORTS_KEY TOP_LEVEL_CONTROL_KEY TOP_LEVEL_PORT_KEY "\\Ports"
#define EMPTY_STRING ""
@@ -3979,3 +3981,616 @@ done:
TALLOC_FREE(tmp_ctx);
return result;
}
+
+/**
+ * @brief Create the registry keyname for the given port.
+ *
+ * @param[in] mem_ctx The memory context to use.
+ *
+ * @param[in] port The name of the port to get the registry key.
+ *
+ * @return The registry key or NULL on error.
+ */
+static char *winreg_port_data_keyname(TALLOC_CTX *mem_ctx, const char *port) {
+ return talloc_asprintf(mem_ctx, "%s\\%s", TOP_LEVEL_PORT_PORTS_KEY, port);
+}
+
+WERROR winreg_update_port(TALLOC_CTX *mem_ctx,
+ struct dcerpc_binding_handle *winreg_handle,
+ const char *portname,
+ uint32_t data1_mask,
+ struct spoolss_PortData1 *data1)
+{
+ uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+ struct policy_handle hive_hnd, key_hnd;
+ int snum = lp_servicenumber(portname);
+ enum ndr_err_code ndr_err;
+ DATA_BLOB blob;
+ char *path;
+ WERROR result = WERR_OK;
+ NTSTATUS status;
+ TALLOC_CTX *tmp_ctx;
+
+ tmp_ctx = talloc_stackframe();
+ if (tmp_ctx == NULL) {
+ return WERR_NOMEM;
+ }
+
+ path = winreg_port_data_keyname(tmp_ctx, portname);
+ if (path == NULL) {
+ TALLOC_FREE(tmp_ctx);
+ return WERR_NOMEM;
+ }
+
+ ZERO_STRUCT(hive_hnd);
+ ZERO_STRUCT(key_hnd);
+
+ result = winreg_printer_openkey(tmp_ctx,
+ winreg_handle,
+ path,
+ "",
+ true,
+ access_mask,
+ &hive_hnd,
+ &key_hnd);
+ if (!W_ERROR_IS_OK(result)) {
+ DEBUG(0, ("winreg_update_port: Could not open key %s: %s\n",
+ path, win_errstr(result)));
+ goto done;
+ }
+
+ if (data1_mask & SPOOLSS_PORT_DATA_DBLSPOOL) {
+ status = dcerpc_winreg_set_dword(tmp_ctx,
+ winreg_handle,
+ &key_hnd,
+ "Double Spool",
+ data1->dblspool,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ result = ntstatus_to_werror(status);
+ }
+ if (!W_ERROR_IS_OK(result)) {
+ goto done;
+ }
+ }
+ if (data1_mask & SPOOLSS_PORT_DATA_HOSTNAME) {
+ status = dcerpc_winreg_set_sz(tmp_ctx,
+ winreg_handle,
+ &key_hnd,
+ "HostName",
+ data1->hostaddress,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ result = ntstatus_to_werror(status);
+ }
+ if (!W_ERROR_IS_OK(result)) {
+ goto done;
+ }
+ }
+ if (data1_mask & SPOOLSS_PORT_DATA_HWADDRESS) {
+ status = dcerpc_winreg_set_sz(tmp_ctx,
+ winreg_handle,
+ &key_hnd,
+ "HWAddress",
+ data1->hardware_address,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ result = ntstatus_to_werror(status);
+ }
+ if (!W_ERROR_IS_OK(result)) {
+ goto done;
+ }
+ }
+ if (data1_mask & SPOOLSS_PORT_DATA_IPADDRESS) {
+ status = dcerpc_winreg_set_sz(tmp_ctx,
+ winreg_handle,
+ &key_hnd,
+ "IPAddress",
+ data1->ip_address,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ result = ntstatus_to_werror(status);
+ }
+ if (!W_ERROR_IS_OK(result)) {
+ goto done;
+ }
+ }
+ if (data1_mask & SPOOLSS_PORT_DATA_PORTNUMBER) {
+ status = dcerpc_winreg_set_dword(tmp_ctx,
+ winreg_handle,
+ &key_hnd,
+ "PortNumber",
+ data1->port_number,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ result = ntstatus_to_werror(status);
+ }
+ if (!W_ERROR_IS_OK(result)) {
+ goto done;
+ }
+ }
+ if (data1_mask & SPOOLSS_PORT_DATA_PROTOCOL) {
+ status = dcerpc_winreg_set_dword(tmp_ctx,
+ winreg_handle,
+ &key_hnd,
+ "Protocol",
+ data1->protocol,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ result = ntstatus_to_werror(status);
+ }
+ if (!W_ERROR_IS_OK(result)) {
+ goto done;
+ }
+ }
+ if (data1_mask & SPOOLSS_PORT_DATA_QUEUE) {
+ status = dcerpc_winreg_set_sz(tmp_ctx,
+ winreg_handle,
+ &key_hnd,
+ "Queue",
+ data1->queue,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ result = ntstatus_to_werror(status);
+ }
+ if (!W_ERROR_IS_OK(result)) {
+ goto done;
+ }
+ }
+ if (data1_mask & SPOOLSS_PORT_DATA_SNMPCOMMUNITY) {
+ status = dcerpc_winreg_set_sz(tmp_ctx,
+ winreg_handle,
+ &key_hnd,
+ "SNMP Community",
+ data1->snmpcommunity,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ result = ntstatus_to_werror(status);
+ }
+ if (!W_ERROR_IS_OK(result)) {
+ goto done;
+ }
+ }
+ if (data1_mask & SPOOLSS_PORT_DATA_SNMPENABLED) {
+ status = dcerpc_winreg_set_dword(tmp_ctx,
+ winreg_handle,
+ &key_hnd,
+ "SNMP Enabled",
+ data1->snmp_enabled,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ result = ntstatus_to_werror(status);
+ }
+ if (!W_ERROR_IS_OK(result)) {
+ goto done;
+ }
+ }
+ if (data1_mask & SPOOLSS_PORT_DATA_SNMPINDEX) {
+ status = dcerpc_winreg_set_dword(tmp_ctx,
+ winreg_handle,
+ &key_hnd,
+ "SNMP Index",
+ data1->snmp_dev_index,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ result = ntstatus_to_werror(status);
+ }
+ if (!W_ERROR_IS_OK(result)) {
+ goto done;
+ }
+ }
+ if (data1_mask & SPOOLSS_PORT_DATA_VERSION) {
+ status = dcerpc_winreg_set_dword(tmp_ctx,
+ winreg_handle,
+ &key_hnd,
+ "Version",
+ data1->version,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ result = ntstatus_to_werror(status);
+ }
+ if (!W_ERROR_IS_OK(result)) {
+ goto done;
+ }
+ }
+
+ result = WERR_OK;
+done:
+ if (winreg_handle != NULL) {
+ WERROR ignore;
+
+ if (is_valid_policy_hnd(&key_hnd)) {
+ dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+ }
+ if (is_valid_policy_hnd(&hive_hnd)) {
+ dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+ }
+ }
+
+ TALLOC_FREE(tmp_ctx);
+ return result;
+}
+
+WERROR winreg_get_port(TALLOC_CTX *mem_ctx,
+ struct dcerpc_binding_handle *winreg_handle,
+ const char *port,
+ struct spoolss_PortData1 **pdata1)
+{
+ struct spoolss_PortData1 *data1;
+ uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+ struct policy_handle hive_hnd, key_hnd;
+ struct spoolss_PrinterEnumValues enum_value;
+ struct spoolss_PrinterEnumValues *v = NULL;
+ enum ndr_err_code ndr_err;
+ uint32_t num_values = 0;
+ uint32_t i;
+ char *path;
+ NTSTATUS status;
+ WERROR result = WERR_OK;
+ TALLOC_CTX *tmp_ctx;
+
+ const char **enum_names = NULL;
+ enum winreg_Type *enum_types = NULL;
+ DATA_BLOB *enum_data_blobs = NULL;
+
+ tmp_ctx = talloc_stackframe();
+ if (tmp_ctx == NULL) {
+ return WERR_NOMEM;
+ }
+
+ path = winreg_port_data_keyname(tmp_ctx, port);
+ if (path == NULL) {
+ TALLOC_FREE(tmp_ctx);
+ return WERR_NOMEM;
+ }
+
+ result = winreg_printer_openkey(tmp_ctx,
+ winreg_handle,
+ path,
+ "",
+ false,
+ access_mask,
+ &hive_hnd,
+ &key_hnd);
+ if (!W_ERROR_IS_OK(result)) {
+ DEBUG(2, ("winreg_get_port: Could not open key %s: %s\n",
+ path, win_errstr(result)));
+ goto done;
+ }
+
+ status = dcerpc_winreg_enumvals(tmp_ctx,
+ winreg_handle,
+ &key_hnd,
+ &num_values,
+ &enum_names,
+ &enum_types,
+ &enum_data_blobs,
+ &result);
+
+ if (!NT_STATUS_IS_OK(status)){
+ result = ntstatus_to_werror(status);
+ }
+
+ if (!W_ERROR_IS_OK(result)) {
+ DEBUG(0, ("winreg_get_port: Could not enumerate values in %s: %s\n",
+ path, win_errstr(result)));
+ goto done;
+ }
+
+ data1 = talloc_zero(tmp_ctx, struct spoolss_PortData1);
+ if (data1 == NULL) {
+ result = WERR_NOMEM;
+ goto done;
+ }
+
+ FILL_STRING(data1, port, data1->portname);
+ FILL_STRING(data1, EMPTY_STRING, data1->hostaddress);
+ FILL_STRING(data1, EMPTY_STRING, data1->hardware_address);
+ FILL_STRING(data1, EMPTY_STRING, data1->ip_address);
+ FILL_STRING(data1, EMPTY_STRING, data1->queue);
+ FILL_STRING(data1, EMPTY_STRING, data1->snmpcommunity);
+ FILL_STRING(data1, EMPTY_STRING, data1->device_type);
+
+ for (i = 0; i < num_values; i++) {
+ enum_value.value_name = enum_names[i];
+ enum_value.value_name_len = 2*strlen_m_term(enum_names[i]);
+ enum_value.type = enum_types[i];
+ enum_value.data_length = enum_data_blobs[i].length;
+ enum_value.data = NULL;
+ if (enum_value.data_length != 0){
+ enum_value.data = &enum_data_blobs[i];
+ }
+ v = &enum_value;
+
+ result = winreg_enumval_to_dword(data1,
+ v,
+ "Double Spool",
+ &data1->dblspool);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_sz(data1,
+ v,
+ "HostName",
+ &data1->hostaddress);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_sz(data1,
+ v,
+ "HWAddress",
+ &data1->hardware_address);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_sz(data1,
+ v,
+ "IPAddress",
+ &data1->ip_address);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_dword(data1,
+ v,
+ "PortNumber",
+ &data1->port_number);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_dword(data1,
+ v,
+ "Protocol",
+ &data1->protocol);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_sz(data1,
+ v,
+ "Queue",
+ &data1->queue);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_sz(data1,
+ v,
+ "SNMP Community",
+ &data1->snmpcommunity);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_dword(data1,
+ v,
+ "SNMP Enabled",
+ &data1->snmp_enabled);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_dword(data1,
+ v,
+ "SNMP Index",
+ &data1->snmp_dev_index);
+ CHECK_ERROR(result);
+
+ result = winreg_enumval_to_dword(data1,
+ v,
+ "Version",
+ &data1->version);
+ CHECK_ERROR(result);
+ }
+
+ if (pdata1) {
+ *pdata1 = talloc_move(mem_ctx, &data1);
+ }
+
+ result = WERR_OK;
+done:
+ if (winreg_handle != NULL) {
+ WERROR ignore;
+
+ if (is_valid_policy_hnd(&key_hnd)) {
+ dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+ }
+ if (is_valid_policy_hnd(&hive_hnd)) {
+ dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+ }
+ }
+
+ TALLOC_FREE(tmp_ctx);
+ return result;
+}
+
+WERROR winreg_create_port(TALLOC_CTX *mem_ctx,
+ struct dcerpc_binding_handle *winreg_handle,
+ const char *portname,
+ const char *ipaddress)
+{
+ uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+ struct policy_handle hive_hnd, key_hnd;
+ struct spoolss_PortData1 *data1;
+ struct winreg_String wkey, wkeyclass;
+ const char *path;
+ uint32_t i;
+ uint32_t data1_mask = 0;
+ WERROR result = WERR_OK;
+ TALLOC_CTX *tmp_ctx;
+
+ tmp_ctx = talloc_stackframe();
+ if (tmp_ctx == NULL) {
+ return WERR_NOMEM;
+ }
+
+ path = winreg_port_data_keyname(tmp_ctx, portname);
+ if (path == NULL) {
+ TALLOC_FREE(tmp_ctx);
+ return WERR_NOMEM;
+ }
+
+ ZERO_STRUCT(hive_hnd);
+ ZERO_STRUCT(key_hnd);
+
+ result = winreg_printer_openkey(tmp_ctx,
+ winreg_handle,
+ path,
+ "",
+ false,
+ access_mask,
+ &hive_hnd,
+ &key_hnd);
+ if (W_ERROR_IS_OK(result)) {
+ DEBUG(2, ("winreg_create_port: Skipping, %s already exists\n", path));
+ goto done;
+ } else if (W_ERROR_EQUAL(result, WERR_BADFILE)) {
+ DEBUG(2, ("winreg_create_port: Creating default values in %s\n", path));
+ } else if (!W_ERROR_IS_OK(result)) {
+ DEBUG(0, ("winreg_create_port: Could not open key %s: %s\n",
+ path, win_errstr(result)));
+ goto done;
+ }
+
+ /* Create the main key */
+ result = winreg_printer_openkey(tmp_ctx,
+ winreg_handle,
+ path,
+ "",
+ true,
+ access_mask,
+ &hive_hnd,
+ &key_hnd);
+ if (!W_ERROR_IS_OK(result)) {
+ DEBUG(0, ("winreg_create_port: Could not create key %s: %s\n",
+ path, win_errstr(result)));
+ goto done;
+ }
+
+ if (is_valid_policy_hnd(&key_hnd)) {
+ dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result);
+ }
+
+ data1 = talloc_zero(tmp_ctx, struct spoolss_PortData1);
+ if (data1 == NULL) {
+ result = WERR_NOMEM;
+ goto done;
+ }
+
+ data1->hostaddress = "";
+ data1_mask |= SPOOLSS_PORT_DATA_HOSTNAME;
+
+ data1->hardware_address = "";
+ data1_mask |= SPOOLSS_PORT_DATA_HWADDRESS;
+
+ data1->ip_address = ipaddress;
+ data1_mask |= SPOOLSS_PORT_DATA_IPADDRESS;
+
+ data1->port_number = 9100;
+ data1_mask |= SPOOLSS_PORT_DATA_PORTNUMBER;
+
+ data1->protocol = 1;
+ data1_mask |= SPOOLSS_PORT_DATA_PROTOCOL;
+
+ data1->snmpcommunity = "public";
+ data1_mask |= SPOOLSS_PORT_DATA_SNMPCOMMUNITY;
+
+ data1->snmp_enabled = 1;
+ data1_mask |= SPOOLSS_PORT_DATA_SNMPENABLED;
+
+ data1->snmp_dev_index = 1;
+ data1_mask |= SPOOLSS_PORT_DATA_SNMPINDEX;
+
+ data1->version = 1;
+ data1_mask |= SPOOLSS_PORT_DATA_VERSION;
+
+ result = winreg_update_port(tmp_ctx,
+ winreg_handle,
+ portname,
+ data1_mask,
+ data1);
+
+done:
+ if (winreg_handle != NULL) {
+ WERROR ignore;
+
+ if (is_valid_policy_hnd(&key_hnd)) {
+ dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+ }
+ if (is_valid_policy_hnd(&hive_hnd)) {
+ dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+ }
+ }
+
+ talloc_free(tmp_ctx);
+ return result;
+}
+
+/* Enumerate the subkeys of a given key */
+WERROR winreg_enum_ports_key(TALLOC_CTX *mem_ctx,
+ struct dcerpc_binding_handle *winreg_handle,
+ uint32_t *pnum_subkeys,
+ const char ***psubkeys)
+{
+ uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+ struct policy_handle hive_hnd, key_hnd;
+ char *path;
+ const char **subkeys = NULL;
+ uint32_t num_subkeys = -1;
+
+ WERROR result = WERR_OK;
+ NTSTATUS status;
+
+ TALLOC_CTX *tmp_ctx;
+
+ tmp_ctx = talloc_stackframe();
+ if (tmp_ctx == NULL) {
+ return WERR_NOMEM;
+ }
+
+ path = TOP_LEVEL_PORT_PORTS_KEY;
+
+ if (path == NULL) {
+ TALLOC_FREE(tmp_ctx);
+ return WERR_NOMEM;
+ }
+
+ ZERO_STRUCT(hive_hnd);
+ ZERO_STRUCT(key_hnd);
+
+ result = winreg_printer_openkey(tmp_ctx,
+ winreg_handle,
+ path,
+ "",
+ false,
+ access_mask,
+ &hive_hnd,
+ &key_hnd);
+ if (!W_ERROR_IS_OK(result)) {
+ DEBUG(2, ("winreg_enum_ports: Could not open key %s: %s\n",
+ path, win_errstr(result)));
+ goto done;
+ }
+
+ status = dcerpc_winreg_enum_keys(tmp_ctx,
+ winreg_handle,
+ &key_hnd,
+ &num_subkeys,
+ &subkeys,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ result = ntstatus_to_werror(status);
+ }
+ if (!W_ERROR_IS_OK(result)) {
+ DEBUG(0, ("winreg_enum_ports: Could not enumerate subkeys in %s: %s\n",
+ path, win_errstr(result)));
+ goto done;
+ }
+
+ *pnum_subkeys = num_subkeys;
+ if (psubkeys) {
+ *psubkeys = talloc_move(mem_ctx, &subkeys);
+ }
+
+ result = WERR_OK;
+done:
+ if (winreg_handle != NULL) {
+ WERROR ignore;
+
+ if (is_valid_policy_hnd(&key_hnd)) {
+ dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
+ }
+ if (is_valid_policy_hnd(&hive_hnd)) {
+ dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
+ }
+ }
+
+ TALLOC_FREE(tmp_ctx);
+ return result;
+}
diff --git a/source3/rpc_client/cli_winreg_spoolss.h b/source3/rpc_client/cli_winreg_spoolss.h
index aa4d98f..6cd6863 100644
--- a/source3/rpc_client/cli_winreg_spoolss.h
+++ b/source3/rpc_client/cli_winreg_spoolss.h
@@ -24,6 +24,34 @@
struct dcerpc_binding_handle;
+enum spoolss_PortData1Mask {
+ SPOOLSS_PORT_DATA_DBLSPOOL = (int)(0x00000001),
+ SPOOLSS_PORT_DATA_HOSTNAME = (int)(0x00000002),
+ SPOOLSS_PORT_DATA_HWADDRESS = (int)(0x00000004),
+ SPOOLSS_PORT_DATA_IPADDRESS = (int)(0x00000008),
+ SPOOLSS_PORT_DATA_PORTNUMBER = (int)(0x00000010),
+ SPOOLSS_PORT_DATA_PROTOCOL = (int)(0x00000020),
+ SPOOLSS_PORT_DATA_QUEUE = (int)(0x00000040),
+ SPOOLSS_PORT_DATA_SNMPCOMMUNITY = (int)(0x00000080),
+ SPOOLSS_PORT_DATA_SNMPENABLED = (int)(0x00000100),
+ SPOOLSS_PORT_DATA_SNMPINDEX = (int)(0x00000200),
+ SPOOLSS_PORT_DATA_VERSION = (int)(0x00000400),
+};
+
+#define SPOOLSS_PORT_DATA_ALL SPOOLSS_PORT_DATA_DBLSPOOL | \
+ SPOOLSS_PORT_DATA_HOSTNAME | \
+ SPOOLSS_PORT_DATA_HWADDRESS | \
+ SPOOLSS_PORT_DATA_IPADDRESS | \
+ SPOOLSS_PORT_DATA_PORTNUMBER | \
+ SPOOLSS_PORT_DATA_PROTOCOL | \
+ SPOOLSS_PORT_DATA_QUEUE | \
+ SPOOLSS_PORT_DATA_SNMPCOMMUNITY | \
+ SPOOLSS_PORT_DATA_SNMPENABLED | \
+ SPOOLSS_PORT_DATA_SNMPINDEX | \
+ SPOOLSS_PORT_DATA_VERSION
+
+
+
enum spoolss_PrinterInfo2Mask {
SPOOLSS_PRINTER_INFO_ATTRIBUTES = (int)(0x00000001),
SPOOLSS_PRINTER_INFO_AVERAGEPPM = (int)(0x00000002),
@@ -566,4 +594,84 @@ WERROR winreg_get_driver_list(TALLOC_CTX *mem_ctx,
uint32_t *num_drivers,
const char ***drivers);
+/**
+ * @brief Get the inforamtion of a port stored in the registry.
+ *
+ * @param[in] mem_ctx The talloc memory context to use.
+ *
+ * @param[in] b The dcerpc binding handle
+ *
+ * @param[in] port The name of the port to get.
+ *
+ * @param[out] pdata1 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_port(TALLOC_CTX *mem_ctx,
+ struct dcerpc_binding_handle *b,
+ const char *port,
+ struct spoolss_PortData1 **pdata1);
+
+/**
+ * @brief Create a new port in the registry.
+ *
+ * @param[in] mem_ctx The talloc memory context to use.
+ *
+ * @param[in] b The dcerpc binding handle
+ *
+ * @param[in] portname The name of the port to get.
+ *
+ * @param[in] ipaddress The IP address of the port
+ *
+ * @return On success WERR_OK, a corresponding DOS error is
+ * something went wrong.
+ */
+WERROR winreg_create_port(TALLOC_CTX *mem_ctx,
+ struct dcerpc_binding_handle *b,
+ const char *portname,
+ const char *ipaddress);
+
+/**
+ * @brief Update the information of a port in the registry.
+ *
+ * @param[in] mem_ctx The talloc memory context to use.
+ *
+ * @param[in] b The dcerpc binding handle
+ *
+ * @param[in] portname The name of the port to get.
+ *
+ * @param[in] data1_mask A bitmask which defines which values should be set.
+ *
+ * @param[out] data1 The structure that holds the port information
+ *
+ * @return On success WERR_OK, a corresponding DOS error is
+ * something went wrong.
+ */
+WERROR winreg_update_port(TALLOC_CTX *mem_ctx,
+ struct dcerpc_binding_handle *b,
+ const char *portname,
+ uint32_t data1_mask,
+ struct spoolss_PortData1 *data1);
+
+/**
+ * @brief Enumerate a list of ports from the registry.
+ *
+ * @param[in] mem_ctx The talloc memory context to use.
+ *
+ * @param[in] b The dcerpc binding handle
+ *
+ * @param[out] pnum_subkeys A pointer to store the number of subkeys found.
+ *
+ * @param[in] psubkeys A pointer to an array to store the names of the subkeys
+ * found.
+ *
+ * @return On success WERR_OK, a corresponding DOS error is
+ * something went wrong.
+ */
+WERROR winreg_enum_ports_key(TALLOC_CTX *mem_ctx,
+ struct dcerpc_binding_handle *b,
+ uint32_t *pnum_subkeys,
+ const char ***psubkeys);
+
#endif /* _RPC_CLIENT_CLI_WINREG_SPOOLSS_H_ */
diff --git a/source3/rpc_server/spoolss/srv_spoolss_util.c b/source3/rpc_server/spoolss/srv_spoolss_util.c
index 8f346a9..ed7bfa1 100644
--- a/source3/rpc_server/spoolss/srv_spoolss_util.c
+++ b/source3/rpc_server/spoolss/srv_spoolss_util.c
@@ -754,3 +754,54 @@ WERROR winreg_enum_printer_key_internal(TALLOC_CTX *mem_ctx,
talloc_free(tmp_ctx);
return result;
}
+
+WERROR winreg_enum_ports_key_internal(TALLOC_CTX *mem_ctx,
+ const struct auth_session_info *session_info,
+ struct messaging_context *msg_ctx,
+ uint32_t *pnum_subkeys,
+ const char ***psubkeys)
+{
+ WERROR result;
+ struct dcerpc_binding_handle *b;
+
+ result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+ W_ERROR_NOT_OK_RETURN(result);
+
+ return winreg_enum_ports_key(mem_ctx, b,
+ pnum_subkeys,
+ psubkeys);
+}
+
+WERROR winreg_get_port_internal(TALLOC_CTX *mem_ctx,
+ const struct auth_session_info *session_info,
+ struct messaging_context *msg_ctx,
+ const char *port,
+ struct spoolss_PortData1 **pdata1)
+{
+ WERROR result;
+ struct dcerpc_binding_handle *b;
+
+ result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+ W_ERROR_NOT_OK_RETURN(result);
+
+ return winreg_get_port(mem_ctx, b,
+ port,
+ pdata1);
+}
+
+WERROR winreg_create_port_internal(TALLOC_CTX *mem_ctx,
+ const struct auth_session_info *session_info,
+ struct messaging_context *msg_ctx,
+ const char *portname,
+ const char *ipaddress)
+{
+ WERROR result;
+ struct dcerpc_binding_handle *b;
+
+ result = winreg_printer_binding_handle(mem_ctx, session_info, msg_ctx, &b);
+ W_ERROR_NOT_OK_RETURN(result);
+
+ return winreg_create_port(mem_ctx, b,
+ portname,
+ ipaddress);
+}
diff --git a/source3/rpc_server/spoolss/srv_spoolss_util.h b/source3/rpc_server/spoolss/srv_spoolss_util.h
index 8d6fb78..a43c133 100644
--- a/source3/rpc_server/spoolss/srv_spoolss_util.h
+++ b/source3/rpc_server/spoolss/srv_spoolss_util.h
@@ -157,4 +157,19 @@ WERROR winreg_enum_printer_key_internal(TALLOC_CTX *mem_ctx,
const char *key,
uint32_t *pnum_subkeys,
const char ***psubkeys);
+WERROR winreg_enum_ports_key_internal(TALLOC_CTX *mem_ctx,
+ const struct auth_session_info *session_info,
+ struct messaging_context *msg_ctx,
+ uint32_t *pnum_subkeys,
+ const char ***psubkeys);
+WERROR winreg_get_port_internal(TALLOC_CTX *mem_ctx,
+ const struct auth_session_info *session_info,
+ struct messaging_context *msg_ctx,
+ const char *port,
+ struct spoolss_PortData1 **pdata1);
+WERROR winreg_create_port_internal(TALLOC_CTX *mem_ctx,
+ const struct auth_session_info *session_info,
+ struct messaging_context *msg_ctx,
+ const char *portname,
+ const char *ipaddress);
#endif /* _SRV_SPOOLSS_UITL_H */
--
1.7.3.4
More information about the samba-technical
mailing list