summaryrefslogtreecommitdiff
path: root/source3/rpc_server
diff options
context:
space:
mode:
authorAndreas Schneider <asn@redhat.com>2010-03-12 17:31:21 +0100
committerGünther Deschner <gd@samba.org>2010-04-07 15:16:52 +0200
commite498338f6f29ffdcca0f3108968e04f635c797d4 (patch)
tree7efa5ef9e4ab6f5e5d40d1fb315fe0a317efe768 /source3/rpc_server
parent511dba5ae8529f8a3e661a2d9d0e6426e38fbee8 (diff)
downloadsamba-e498338f6f29ffdcca0f3108968e04f635c797d4.tar.gz
samba-e498338f6f29ffdcca0f3108968e04f635c797d4.tar.bz2
samba-e498338f6f29ffdcca0f3108968e04f635c797d4.zip
s3-spoolss: Added a enum_printer_dataex function using the winreg pipe.
Signed-off-by: Günther Deschner <gd@samba.org>
Diffstat (limited to 'source3/rpc_server')
-rw-r--r--source3/rpc_server/srv_spoolss_util.c240
-rw-r--r--source3/rpc_server/srv_spoolss_util.h24
2 files changed, 264 insertions, 0 deletions
diff --git a/source3/rpc_server/srv_spoolss_util.c b/source3/rpc_server/srv_spoolss_util.c
index 237215411a..4c5f78526f 100644
--- a/source3/rpc_server/srv_spoolss_util.c
+++ b/source3/rpc_server/srv_spoolss_util.c
@@ -24,6 +24,10 @@
#include "../librpc/gen_ndr/srv_winreg.h"
#include "../librpc/gen_ndr/cli_winreg.h"
+/********************************************************************
+ static helper functions
+********************************************************************/
+
/**
* @internal
*
@@ -166,6 +170,170 @@ static WERROR winreg_printer_openkey(TALLOC_CTX *mem_ctx,
return WERR_OK;
}
+/**
+ * @internal
+ *
+ * @brief Enumerate values of an opened key handle and retrieve the data.
+ *
+ * @param[in] mem_ctx The memory context to use.
+ *
+ * @param[in] pipe_handle The pipe handle for the rpc connection.
+ *
+ * @param[in] key_hnd The opened key handle.
+ *
+ * @param[out] pnum_values A pointer to store he number of values found.
+ *
+ * @param[out] pnum_values A pointer to store the number of values we found.
+ *
+ * @return WERR_OK on success, the corresponding DOS error
+ * code if something gone wrong.
+ */
+static WERROR winreg_printer_enumvalues(TALLOC_CTX *mem_ctx,
+ struct rpc_pipe_client *pipe_handle,
+ struct policy_handle *key_hnd,
+ uint32_t *pnum_values,
+ struct spoolss_PrinterEnumValues **penum_values)
+{
+ TALLOC_CTX *tmp_ctx;
+ uint32_t num_subkeys, max_subkeylen, max_classlen;
+ uint32_t num_values, max_valnamelen, max_valbufsize;
+ uint32_t secdescsize;
+ uint32_t i;
+ NTTIME last_changed_time;
+ struct winreg_String classname;
+
+ struct spoolss_PrinterEnumValues *enum_values;
+
+ WERROR result = WERR_OK;
+ NTSTATUS status;
+
+ tmp_ctx = talloc_new(mem_ctx);
+ if (tmp_ctx == NULL) {
+ return WERR_NOMEM;
+ }
+
+ ZERO_STRUCT(classname);
+
+ status = rpccli_winreg_QueryInfoKey(pipe_handle,
+ tmp_ctx,
+ key_hnd,
+ &classname,
+ &num_subkeys,
+ &max_subkeylen,
+ &max_classlen,
+ &num_values,
+ &max_valnamelen,
+ &max_valbufsize,
+ &secdescsize,
+ &last_changed_time,
+ &result);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("winreg_printer_enumvalues: Could not query info: %s\n",
+ nt_errstr(status)));
+ if (!W_ERROR_IS_OK(result)) {
+ goto error;
+ }
+ result = ntstatus_to_werror(status);
+ goto error;
+ }
+
+ if (num_values == 0) {
+ *pnum_values = 0;
+ TALLOC_FREE(tmp_ctx);
+ return WERR_OK;
+ }
+
+ enum_values = TALLOC_ARRAY(tmp_ctx, struct spoolss_PrinterEnumValues, num_values);
+ if (enum_values == NULL) {
+ result = WERR_NOMEM;
+ goto error;
+ }
+
+ for (i = 0; i < num_values; i++) {
+ struct spoolss_PrinterEnumValues val;
+ struct winreg_ValNameBuf name_buf;
+ enum winreg_Type type = REG_NONE;
+ uint8_t *data = NULL;
+ uint32_t data_size;
+ uint32_t length;
+ char n = '\0';;
+
+ name_buf.name = &n;
+ name_buf.size = max_valnamelen + 2;
+ name_buf.length = 0;
+
+ data_size = max_valbufsize;
+ data = (uint8_t *) TALLOC(tmp_ctx, data_size);
+ length = 0;
+
+ status = rpccli_winreg_EnumValue(pipe_handle,
+ tmp_ctx,
+ key_hnd,
+ i,
+ &name_buf,
+ &type,
+ data,
+ &data_size,
+ &length,
+ &result);
+ if (W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS) ) {
+ result = WERR_OK;
+ status = NT_STATUS_OK;
+ break;
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("winreg_printer_enumvalues: Could not enumerate values: %s\n",
+ nt_errstr(status)));
+ if (!W_ERROR_IS_OK(result)) {
+ goto error;
+ }
+ result = ntstatus_to_werror(status);
+ goto error;
+ }
+
+ if (name_buf.name == NULL) {
+ result = WERR_INVALID_PARAMETER;
+ goto error;
+ }
+
+ val.value_name = talloc_strdup(enum_values, name_buf.name);
+ if (val.value_name == NULL) {
+ result = WERR_NOMEM;
+ goto error;
+ }
+ val.value_name_len = strlen_m_term(val.value_name) * 2;
+
+ val.type = type;
+ val.data_length = data_size;
+ if (val.data_length) {
+ val.data = talloc(enum_values, DATA_BLOB);
+ if (val.data == NULL) {
+ result = WERR_NOMEM;
+ goto error;
+ }
+ *val.data = data_blob_talloc(enum_values, data, data_size);
+ }
+
+ enum_values[i] = val;
+ }
+
+ *pnum_values = num_values;
+ if (penum_values) {
+ *penum_values = talloc_move(mem_ctx, &enum_values);
+ }
+
+ result = WERR_OK;
+
+ error:
+ TALLOC_FREE(tmp_ctx);
+ return result;
+}
+
+/********************************************************************
+ Public winreg function for spoolss
+********************************************************************/
+
/* Set printer data over the winreg pipe. */
WERROR winreg_set_printer_dataex(struct pipes_struct *p,
const char *printer,
@@ -357,3 +525,75 @@ done:
TALLOC_FREE(tmp_ctx);
return result;
}
+
+/* Enumerate on the values of a given key and provide the data. */
+WERROR winreg_enum_printer_dataex(struct pipes_struct *p,
+ const char *printer,
+ const char *key,
+ uint32_t *pnum_values,
+ struct spoolss_PrinterEnumValues **penum_values)
+{
+ 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;
+ uint32_t num_values = 0;
+
+ WERROR result = WERR_OK;
+
+ TALLOC_CTX *tmp_ctx;
+
+ tmp_ctx = talloc_new(p->mem_ctx);
+ if (tmp_ctx == NULL) {
+ return WERR_NOMEM;
+ }
+
+ ZERO_STRUCT(hive_hnd);
+ ZERO_STRUCT(key_hnd);
+
+ result = winreg_printer_openkey(tmp_ctx,
+ p->server_info,
+ &winreg_pipe,
+ printer,
+ key,
+ false,
+ access_mask,
+ &hive_hnd,
+ &key_hnd);
+ if (!W_ERROR_IS_OK(result)) {
+ DEBUG(0, ("winreg_enum_printer_dataex: Could not open key %s: %s\n",
+ key, 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_enum_printer_dataex: Could not enumerate values in %s: %s\n",
+ key, win_errstr(result)));
+ goto done;
+ }
+
+ *pnum_values = num_values;
+ if (penum_values) {
+ *penum_values = talloc_move(p->mem_ctx, &enum_values);
+ }
+
+ 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;
+}
diff --git a/source3/rpc_server/srv_spoolss_util.h b/source3/rpc_server/srv_spoolss_util.h
index f63616f58f..9be4a2be5d 100644
--- a/source3/rpc_server/srv_spoolss_util.h
+++ b/source3/rpc_server/srv_spoolss_util.h
@@ -82,4 +82,28 @@ WERROR winreg_get_printer_dataex(struct pipes_struct *p,
uint8_t **data,
uint32_t *data_size);
+/**
+ * @internal
+ *
+ * @brief Enumerate on the values of a given key and provide the data.
+ *
+ * @param[in] p The pipes structure to be able to open a new pipe.
+ *
+ * @param[in] printer The printer name.
+ *
+ * @param[in] key The key of the printer data to get the value.
+ *
+ * @param[out] pnum_values A pointer to store the number of values we found.
+ *
+ * @param[out] penum_values A pointer to store the values and its data.
+ *
+ * @return WERR_OK on success, the corresponding DOS error
+ * code if something gone wrong.
+ */
+WERROR winreg_enum_printer_dataex(struct pipes_struct *p,
+ const char *printer,
+ const char *key,
+ uint32_t *pnum_values,
+ struct spoolss_PrinterEnumValues **penum_values);
+
#endif /* _SRV_SPOOLSS_UITL_H */