endpoint server for the iremotewinspool pipe
- Copyright (C) YOUR NAME HERE YEAR
+ Copyright (C) Guenther Deschner 2016
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include "auth.h"
#include "libcli/security/privileges.h"
#include "libcli/security/dom_sid.h"
+#include "rpc_server/spoolss/srv_spoolss_handle.h"
+#include "librpc/rpc/dcesrv_core.h"
+
+enum iremotewinspool_handle_type {
+ IREMOTEWINSPOOL_GDI_HANDLE,
+ IREMOTEWINSPOOL_PRINTER_HANDLE,
+ IREMOTEWINSPOOL_RMNTFY_HANDLE
+};
+
+struct iremotewinspool_handle {
+ uint32_t type;
+ struct winspool_PrintPropertiesCollection *pNotifyFilter;
+};
static bool winspool_is_privileged_user(struct auth_session_info *session_info)
{
_winspool_SyncRegisterForRemoteNotifications
****************************************************************/
+static bool property_present_in_collection(struct winspool_PrintPropertiesCollection *r,
+ const char *name)
+{
+ int i;
+
+ for (i=0; i < r->numberOfProperties; i++) {
+ if (strequal(r->propertiesCollection[i].propertyName, name)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static bool validate_notify_filter(struct winspool_PrintPropertiesCollection *r)
+{
+ bool ok;
+
+ if (r->numberOfProperties < 4) {
+ return false;
+ }
+
+ ok = property_present_in_collection(r, "RemoteNotifyFilter Flags");
+ if (!ok) {
+ return false;
+ }
+
+ ok = property_present_in_collection(r, "RemoteNotifyFilter Options");
+ if (!ok) {
+ return false;
+ }
+
+ ok = property_present_in_collection(r, "RemoteNotifyFilter Color");
+ if (!ok) {
+ return false;
+ }
+
+ ok = property_present_in_collection(r, "RemoteNotifyFilter NotifyOptions");
+ if (!ok) {
+ return false;
+ }
+
+ return true;
+}
+
HRESULT _winspool_SyncRegisterForRemoteNotifications(struct pipes_struct *p,
struct winspool_SyncRegisterForRemoteNotifications *r)
{
- p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
- return HRES_ERROR_NOT_SUPPORTED;
+ struct iremotewinspool_handle *h;
+ bool ok;
+ NTSTATUS status;
+
+ (void)find_policy_by_hnd(p,
+ &r->in.hPrinter,
+ SPLHND_SERVER,
+ struct printer_handle,
+ &status);
+ if (!NT_STATUS_IS_OK(status)) {
+ return HRESULT_FROM_WERROR(WERR_INVALID_HANDLE);
+ }
+
+ ok = validate_notify_filter(r->in.pNotifyFilter);
+ if (!ok) {
+ p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
+ return HRES_E_ACCESSDENIED;
+ }
+
+ h = talloc_zero(p->mem_ctx, struct iremotewinspool_handle);
+ if (h == NULL) {
+ return HRES_E_OUTOFMEMORY;
+ }
+
+ h->type = IREMOTEWINSPOOL_RMNTFY_HANDLE;
+ h->pNotifyFilter = talloc_steal(h, r->in.pNotifyFilter);
+
+ ok = create_policy_hnd(p, r->out.phRpcHandle,
+ IREMOTEWINSPOOL_RMNTFY_HANDLE, h);
+ if (!ok) {
+ return HRES_E_INVALIDARG;
+ }
+
+ return HRES_ERROR(0);
}