From b04a260e4e8b5d317e36d758f16aff090d567d7c Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 15 Apr 2010 15:18:26 +0200 Subject: s3-spoolss: Added a function to update the ChangeID of a printer. 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 | 98 +++++++++++++++++++++++++++++++++++ source3/rpc_server/srv_spoolss_util.h | 22 ++++++++ 2 files changed, 120 insertions(+) (limited to 'source3') diff --git a/source3/rpc_server/srv_spoolss_util.c b/source3/rpc_server/srv_spoolss_util.c index b7abae0ff8..3e35eb98ff 100644 --- a/source3/rpc_server/srv_spoolss_util.c +++ b/source3/rpc_server/srv_spoolss_util.c @@ -155,6 +155,40 @@ static const struct spoolss_FormInfo1 builtin_forms1[] = { static helper functions ********************************************************************/ +/**************************************************************************** + Update the changeid time. +****************************************************************************/ +/** + * @internal + * + * @brief Update the ChangeID time of a printer. + * + * This is SO NASTY as some drivers need this to change, others need it + * static. This value will change every second, and I must hope that this + * is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF + * UTAH ! JRA. + * + * @return The ChangeID. + */ +static uint32_t winreg_printer_rev_changeid(void) +{ + struct timeval tv; + + get_process_uptime(&tv); + +#if 1 /* JERRY */ + /* Return changeid as msec since spooler restart */ + return tv.tv_sec * 1000 + tv.tv_usec / 1000; +#else + /* + * This setting seems to work well but is too untested + * to replace the above calculation. Left in for experiementation + * of the reader --jerry (Tue Mar 12 09:15:05 CST 2002) + */ + return tv.tv_sec * 10 + tv.tv_usec / 100000; +#endif +} + /** * @internal * @@ -1352,6 +1386,70 @@ done: return result; } +WERROR winreg_printer_update_changeid(TALLOC_CTX *mem_ctx, + struct auth_serversupplied_info *server_info, + const char *printer) +{ + uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + struct rpc_pipe_client *winreg_pipe = NULL; + struct policy_handle hive_hnd, key_hnd; + char *path; + WERROR result; + 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; + } + + ZERO_STRUCT(hive_hnd); + ZERO_STRUCT(key_hnd); + + 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_printer_update_changeid: Could not open key %s: %s\n", + path, win_errstr(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; +} + /* * The special behaviour of the spoolss forms is documented at the website: * diff --git a/source3/rpc_server/srv_spoolss_util.h b/source3/rpc_server/srv_spoolss_util.h index ea5d4a1ed0..e8cea01495 100644 --- a/source3/rpc_server/srv_spoolss_util.h +++ b/source3/rpc_server/srv_spoolss_util.h @@ -188,6 +188,28 @@ WERROR winreg_delete_printer_key(TALLOC_CTX *mem_ctx, const char *printer, const char *key); +/** + * @brief Update the ChangeID of a printer. + * + * The ChangeID **must** be increasing over the lifetime of client's spoolss + * service in order for the client's cache to show updates. + * + * If a form is updated of a printer, the we need to update the ChangeID of the + * pritner. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] server_info The server supplied session info. + * + * @param[in] printer The printer name. + * + * @return On success WERR_OK, a corresponding DOS error is + * something went wrong. + */ +WERROR winreg_printer_update_changeid(TALLOC_CTX *mem_ctx, + struct auth_serversupplied_info *server_info, + const char *printer); + /** * @internal * -- cgit