From a61297647db696d193c081522f44ff09bf260bce Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 15 Apr 2010 17:53:39 +0200 Subject: s3-spoolss: Added a winreg_update_printer function. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Günther Deschner --- source3/rpc_server/srv_spoolss_util.c | 309 ++++++++++++++++++++++++++++++++++ source3/rpc_server/srv_spoolss_util.h | 76 +++++++++ 2 files changed, 385 insertions(+) (limited to 'source3') diff --git a/source3/rpc_server/srv_spoolss_util.c b/source3/rpc_server/srv_spoolss_util.c index f06b30bcc7..4b2bab2876 100644 --- a/source3/rpc_server/srv_spoolss_util.c +++ b/source3/rpc_server/srv_spoolss_util.c @@ -1210,6 +1210,315 @@ static WERROR winreg_printer_ver_to_dword(const char *str, uint64_t *data) Public winreg function for spoolss ********************************************************************/ +WERROR winreg_update_printer(TALLOC_CTX *mem_ctx, + struct auth_serversupplied_info *server_info, + uint32_t info2_mask, + struct spoolss_SetPrinterInfo2 *info2, + struct spoolss_DeviceMode *devmode, + struct security_descriptor *secdesc) +{ + uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + struct rpc_pipe_client *winreg_pipe = NULL; + struct policy_handle hive_hnd, key_hnd; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + 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, info2->sharename); + if (path == NULL) { + TALLOC_FREE(tmp_ctx); + return WERR_NOMEM; + } + + ZERO_STRUCT(hive_hnd); + ZERO_STRUCT(key_hnd); + + result = winreg_printer_openkey(tmp_ctx, + server_info, + &winreg_pipe, + path, + "", + true, + access_mask, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_update_printer: Could not open key %s: %s\n", + path, win_errstr(result))); + goto done; + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_ATTRIBUTES) { + result = winreg_printer_write_dword(tmp_ctx, + winreg_pipe, + &key_hnd, + "Attributes", + info2->attributes); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + +#if 0 + if (info2_mask & SPOOLSS_PRINTER_INFO_AVERAGEPPM) { + result = winreg_printer_write_dword(tmp_ctx, + winreg_pipe, + &key_hnd, + "AveragePpm", + info2->attributes); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } +#endif + + if (info2_mask & SPOOLSS_PRINTER_INFO_COMMENT) { + result = winreg_printer_write_sz(tmp_ctx, + winreg_pipe, + &key_hnd, + "Description", + info2->comment); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_DATATYPE) { + result = winreg_printer_write_sz(tmp_ctx, + winreg_pipe, + &key_hnd, + "Datatype", + info2->datatype); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY) { + result = winreg_printer_write_dword(tmp_ctx, + winreg_pipe, + &key_hnd, + "Default Priority", + info2->defaultpriority); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_DEVMODE) { + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, NULL, devmode, + (ndr_push_flags_fn_t) ndr_push_spoolss_DeviceMode); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(0, ("winreg_update_printer: Failed to marshall device mode\n")); + result = WERR_NOMEM; + goto done; + } + + result = winreg_printer_write_binary(tmp_ctx, + winreg_pipe, + &key_hnd, + "Default DevMode", + blob); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_LOCATION) { + result = winreg_printer_write_sz(tmp_ctx, + winreg_pipe, + &key_hnd, + "Location", + info2->location); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_PARAMETERS) { + result = winreg_printer_write_sz(tmp_ctx, + winreg_pipe, + &key_hnd, + "Parameters", + info2->parameters); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_PORTNAME) { + result = winreg_printer_write_sz(tmp_ctx, + winreg_pipe, + &key_hnd, + "Port", + info2->portname); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_PRINTERNAME) { + /* + * in addprinter: no servername and the printer is the name + * in setprinter: servername is \\server + * and printer is \\server\\printer + * + * Samba manages only local printers. + * we currently don't support things like i + * path=\\other_server\printer + * + * We only store the printername, not \\server\printername + */ + const char *p = strrchr(info2->printername, '\\'); + if (p == NULL) { + p = info2->printername; + } else { + p++; + } + result = winreg_printer_write_sz(tmp_ctx, + winreg_pipe, + &key_hnd, + "Name", + p); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_PRINTPROCESSOR) { + result = winreg_printer_write_sz(tmp_ctx, + winreg_pipe, + &key_hnd, + "Print Processor", + info2->printprocessor); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_PRIORITY) { + result = winreg_printer_write_dword(tmp_ctx, + winreg_pipe, + &key_hnd, + "Priority", + info2->priority); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_SECDESC) { + /* + * We need a security descriptor, if it isn't specified by + * AddPrinter{Ex} then create a default descriptor. + */ + if (secdesc == NULL) { + secdesc = winreg_printer_create_default_secdesc(tmp_ctx); + } + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, NULL, secdesc, + (ndr_push_flags_fn_t) ndr_push_security_descriptor); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(0, ("winreg_update_printer: Failed to marshall security descriptor\n")); + result = WERR_NOMEM; + goto done; + } + + result = winreg_printer_write_binary(tmp_ctx, + winreg_pipe, + &key_hnd, + "Security", + blob); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_SEPFILE) { + result = winreg_printer_write_sz(tmp_ctx, + winreg_pipe, + &key_hnd, + "Separator File", + info2->sepfile); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_SHARENAME) { + result = winreg_printer_write_sz(tmp_ctx, + winreg_pipe, + &key_hnd, + "Share Name", + info2->sharename); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_STARTTIME) { + result = winreg_printer_write_dword(tmp_ctx, + winreg_pipe, + &key_hnd, + "StartTime", + info2->starttime); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_STATUS) { + result = winreg_printer_write_dword(tmp_ctx, + winreg_pipe, + &key_hnd, + "Status", + info2->status); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + if (info2_mask & SPOOLSS_PRINTER_INFO_UNTILTIME) { + result = winreg_printer_write_dword(tmp_ctx, + winreg_pipe, + &key_hnd, + "UntilTime", + info2->untiltime); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + } + + result = winreg_printer_write_dword(tmp_ctx, + winreg_pipe, + &key_hnd, + "ChangeID", + winreg_printer_rev_changeid()); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + 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 35a47283e2..ede313fc3f 100644 --- a/source3/rpc_server/srv_spoolss_util.h +++ b/source3/rpc_server/srv_spoolss_util.h @@ -22,6 +22,82 @@ #ifndef _SRV_SPOOLSS_UITL_H #define _SRV_SPOOLSS_UITL_H + +enum spoolss_PrinterInfo2Mask { + SPOOLSS_PRINTER_INFO_ATTRIBUTES = (int)(0x00000001), + SPOOLSS_PRINTER_INFO_AVERAGEPPM = (int)(0x00000002), + SPOOLSS_PRINTER_INFO_CJOBS = (int)(0x00000004), + SPOOLSS_PRINTER_INFO_COMMENT = (int)(0x00000008), + SPOOLSS_PRINTER_INFO_DATATYPE = (int)(0x00000010), + SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY = (int)(0x00000020), + SPOOLSS_PRINTER_INFO_DEVMODE = (int)(0x00000040), + SPOOLSS_PRINTER_INFO_DRIVERNAME = (int)(0x00000080), + SPOOLSS_PRINTER_INFO_LOCATION = (int)(0x00000100), + SPOOLSS_PRINTER_INFO_NAME = (int)(0x00000200), + SPOOLSS_PRINTER_INFO_PARAMETERS = (int)(0x00000400), + SPOOLSS_PRINTER_INFO_PORTNAME = (int)(0x00000800), + SPOOLSS_PRINTER_INFO_PRINTERNAME = (int)(0x00001000), + SPOOLSS_PRINTER_INFO_PRINTPROCESSOR = (int)(0x00002000), + SPOOLSS_PRINTER_INFO_PRIORITY = (int)(0x00004000), + SPOOLSS_PRINTER_INFO_SECDESC = (int)(0x00008000), + SPOOLSS_PRINTER_INFO_SEPFILE = (int)(0x00010000), + SPOOLSS_PRINTER_INFO_SERVERNAME = (int)(0x00020000), + SPOOLSS_PRINTER_INFO_SHARENAME = (int)(0x00040000), + SPOOLSS_PRINTER_INFO_STARTTIME = (int)(0x00080000), + SPOOLSS_PRINTER_INFO_STATUS = (int)(0x00100000), + SPOOLSS_PRINTER_INFO_UNTILTIME = (int)(0x00200000) +}; + +#define SPOOLSS_PRINTER_INFO_ALL SPOOLSS_PRINTER_INFO_ATTRIBUTES | \ + SPOOLSS_PRINTER_INFO_AVERAGEPPM | \ + SPOOLSS_PRINTER_INFO_CJOBS | \ + SPOOLSS_PRINTER_INFO_COMMENT | \ + SPOOLSS_PRINTER_INFO_DATATYPE | \ + SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY | \ + SPOOLSS_PRINTER_INFO_DEVMODE | \ + SPOOLSS_PRINTER_INFO_DRIVERNAME | \ + SPOOLSS_PRINTER_INFO_LOCATION | \ + SPOOLSS_PRINTER_INFO_NAME | \ + SPOOLSS_PRINTER_INFO_PARAMETERS | \ + SPOOLSS_PRINTER_INFO_PORTNAME | \ + SPOOLSS_PRINTER_INFO_PRINTERNAME | \ + SPOOLSS_PRINTER_INFO_PRINTPROCESSOR | \ + SPOOLSS_PRINTER_INFO_PRIORITY | \ + SPOOLSS_PRINTER_INFO_SECDESC | \ + SPOOLSS_PRINTER_INFO_SEPFILE | \ + SPOOLSS_PRINTER_INFO_SERVERNAME | \ + SPOOLSS_PRINTER_INFO_SHARENAME | \ + SPOOLSS_PRINTER_INFO_STARTTIME | \ + SPOOLSS_PRINTER_INFO_STATUS | \ + SPOOLSS_PRINTER_INFO_UNTILTIME + +/** + * @internal + * + * @brief Update the information of a printer in the registry. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] server_info The server supplied session info. + * + * @param[in] info2_mask A bitmask which defines which values should be set. + * + * @param[in] info2 A SetPrinterInfo2 structure with the data to set. + * + * @param[in] devmode A device mode structure with the data to set. + * + * @param[in] secdesc A security descriptor structure with the data to set. + * + * @return On success WERR_OK, a corresponding DOS error is + * something went wrong. + */ +WERROR winreg_update_printer(TALLOC_CTX *mem_ctx, + struct auth_serversupplied_info *server_info, + uint32_t info2_mask, + struct spoolss_SetPrinterInfo2 *info2, + struct spoolss_DeviceMode *devmode, + struct security_descriptor *secdesc); + /** * @internal * -- cgit