s3-iremotewinspool: implement _winspool_SyncRegisterForRemoteNotifications
authorGünther Deschner <gd@samba.org>
Wed, 31 Aug 2016 16:47:52 +0000 (18:47 +0200)
committerGünther Deschner <gd@samba.org>
Tue, 24 Oct 2023 13:36:28 +0000 (15:36 +0200)
Guenther

Signed-off-by: Guenther Deschner <gd@samba.org>
source3/rpc_server/spoolss/srv_iremotewinspool_nt.c

index fd5cce62e53312f0696ce9dc82c4430aa8e16ebb..fc94de6998382f3d7f5b32605ed1a61eecae7c46 100644 (file)
@@ -3,7 +3,7 @@
 
    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)
 {
@@ -751,11 +764,88 @@ WERROR _winspool_AsyncEnumPerMachineConnections(struct pipes_struct *p,
  _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);
 }