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
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
This implements a NTPTR backend that store
#include "ntptr/ntptr.h"
#include "librpc/gen_ndr/ndr_spoolss.h"
#include "lib/ldb/include/ldb.h"
-#include "db_wrap.h"
#include "auth/auth.h"
#include "dsdb/samdb/samdb.h"
+#include "ldb_wrap.h"
+#include "../lib/util/util_ldb.h"
+#include "rpc_server/common/common.h"
+#include "param/param.h"
/*
connect to the SPOOLSS database
return a ldb_context pointer on success, or NULL on failure
*/
-static struct ldb_context *sptr_db_connect(TALLOC_CTX *mem_ctx)
+static struct ldb_context *sptr_db_connect(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, struct loadparm_context *lp_ctx)
{
- return ldb_wrap_connect(mem_ctx, lp_spoolss_url(), system_session(mem_ctx),
- NULL, 0, NULL);
+ return ldb_wrap_connect(mem_ctx, ev_ctx, lp_ctx, lp_spoolss_url(lp_ctx), system_session(lp_ctx),
+ NULL, 0);
}
static int sptr_db_search(struct ldb_context *ldb,
TALLOC_CTX *mem_ctx,
- const struct ldb_dn *basedn,
+ struct ldb_dn *basedn,
struct ldb_message ***res,
const char * const *attrs,
const char *format, ...) PRINTF_ATTRIBUTE(6,7);
static int sptr_db_search(struct ldb_context *ldb,
TALLOC_CTX *mem_ctx,
- const struct ldb_dn *basedn,
+ struct ldb_dn *basedn,
struct ldb_message ***res,
const char * const *attrs,
const char *format, ...)
static NTSTATUS sptr_init_context(struct ntptr_context *ntptr)
{
- struct ldb_context *sptr_db = sptr_db_connect(ntptr);
+ struct ldb_context *sptr_db = sptr_db_connect(ntptr, ntptr->ev_ctx, ntptr->lp_ctx);
NT_STATUS_HAVE_NO_MEMORY(sptr_db);
ntptr->private_data = sptr_db;
/*
* PrintServer PrinterData functions
*/
-static WERROR sptr_GetPrintServerData(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
- struct spoolss_GetPrinterData *r)
+
+static WERROR sptr_PrintServerData(struct ntptr_GenericHandle *server,
+ TALLOC_CTX *mem_ctx,
+ const char *value_name,
+ union spoolss_PrinterData *r,
+ enum winreg_Type *type)
{
- if (strcmp("W3SvcInstalled", r->in.value_name) == 0) {
- r->out.type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
- r->out.data.value = 0;
+ struct dcerpc_server_info *server_info = lp_dcerpc_server_info(mem_ctx, server->ntptr->lp_ctx);
+ if (strcmp("W3SvcInstalled", value_name) == 0) {
+ *type = REG_DWORD;
+ r->value = 0;
return WERR_OK;
- } else if (strcmp("BeepEnabled", r->in.value_name) == 0) {
- r->out.type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
- r->out.data.value = 0;
+ } else if (strcmp("BeepEnabled", value_name) == 0) {
+ *type = REG_DWORD;
+ r->value = 0;
return WERR_OK;
- } else if (strcmp("EventLog", r->in.value_name) == 0) {
- r->out.type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
- r->out.data.value = 0;
+ } else if (strcmp("EventLog", value_name) == 0) {
+ *type = REG_DWORD;
+ r->value = 0;
return WERR_OK;
- } else if (strcmp("NetPopup", r->in.value_name) == 0) {
- r->out.type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
- r->out.data.value = 0;
+ } else if (strcmp("NetPopup", value_name) == 0) {
+ *type = REG_DWORD;
+ r->value = 0;
return WERR_OK;
- } else if (strcmp("NetPopupToComputer", r->in.value_name) == 0) {
- r->out.type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
- r->out.data.value = 0;
+ } else if (strcmp("NetPopupToComputer", value_name) == 0) {
+ *type = REG_DWORD;
+ r->value = 0;
return WERR_OK;
- } else if (strcmp("MajorVersion", r->in.value_name) == 0) {
- r->out.type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
- r->out.data.value = 3;
+ } else if (strcmp("MajorVersion", value_name) == 0) {
+ *type = REG_DWORD;
+ r->value = 3;
return WERR_OK;
- } else if (strcmp("MinorVersion", r->in.value_name) == 0) {
- r->out.type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
- r->out.data.value = 0;
+ } else if (strcmp("MinorVersion", value_name) == 0) {
+ *type = REG_DWORD;
+ r->value = 0;
return WERR_OK;
- } else if (strcmp("DefaultSpoolDirectory", r->in.value_name) == 0) {
- r->out.type = SPOOLSS_PRINTER_DATA_TYPE_STRING;
- r->out.data.string = "C:\\PRINTERS";
+ } else if (strcmp("DefaultSpoolDirectory", value_name) == 0) {
+ *type = REG_SZ;
+ r->string = "C:\\PRINTERS";
return WERR_OK;
- } else if (strcmp("Architecture", r->in.value_name) == 0) {
- r->out.type = SPOOLSS_PRINTER_DATA_TYPE_STRING;
- r->out.data.string = SPOOLSS_ARCHITECTURE_NT_X86;
+ } else if (strcmp("Architecture", value_name) == 0) {
+ *type = REG_SZ;
+ r->string = SPOOLSS_ARCHITECTURE_NT_X86;
return WERR_OK;
- } else if (strcmp("DsPresent", r->in.value_name) == 0) {
- r->out.type = SPOOLSS_PRINTER_DATA_TYPE_UINT32;
- r->out.data.value = 1;
+ } else if (strcmp("DsPresent", value_name) == 0) {
+ *type = REG_DWORD;
+ r->value = 1;
return WERR_OK;
- } else if (strcmp("OSVersion", r->in.value_name) == 0) {
+ } else if (strcmp("OSVersion", value_name) == 0) {
DATA_BLOB blob;
- NTSTATUS status;
+ enum ndr_err_code ndr_err;
struct spoolss_OSVersion os;
- os.major = dcesrv_common_get_version_major(mem_ctx, NULL);
- os.minor = dcesrv_common_get_version_minor(mem_ctx, NULL);
- os.build = dcesrv_common_get_version_build(mem_ctx, NULL);
+ os.major = server_info->version_major;
+ os.minor = server_info->version_minor;
+ os.build = server_info->version_build;
os.extra_string = "";
- status = ndr_push_struct_blob(&blob, mem_ctx, &os, (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
- if (!NT_STATUS_IS_OK(status)) {
+ ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &os, (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
return WERR_GENERAL_FAILURE;
}
- r->out.type = SPOOLSS_PRINTER_DATA_TYPE_BINARY;
- r->out.data.binary = blob;
+ *type = REG_BINARY;
+ r->binary = blob;
return WERR_OK;
- } else if (strcmp("OSVersionEx", r->in.value_name) == 0) {
+ } else if (strcmp("OSVersionEx", value_name) == 0) {
DATA_BLOB blob;
- NTSTATUS status;
+ enum ndr_err_code ndr_err;
struct spoolss_OSVersionEx os_ex;
- os_ex.major = dcesrv_common_get_version_major(mem_ctx, NULL);
- os_ex.minor = dcesrv_common_get_version_minor(mem_ctx, NULL);
- os_ex.build = dcesrv_common_get_version_build(mem_ctx, NULL);
- os_ex.extra_string = "";
- os_ex.unknown2 = 0;
- os_ex.unknown3 = 0;
-
- status = ndr_push_struct_blob(&blob, mem_ctx, &os_ex, (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersionEx);
- if (!NT_STATUS_IS_OK(status)) {
+ os_ex.major = server_info->version_major;
+ os_ex.minor = server_info->version_minor;
+ os_ex.build = server_info->version_build;
+ os_ex.extra_string = "";
+ os_ex.service_pack_major= 0;
+ os_ex.service_pack_minor= 0;
+ os_ex.suite_mask = 0;
+ os_ex.product_type = 0;
+ os_ex.reserved = 0;
+
+ ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &os_ex, (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersionEx);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
return WERR_GENERAL_FAILURE;
}
- r->out.type = SPOOLSS_PRINTER_DATA_TYPE_BINARY;
- r->out.data.binary = blob;
+ *type = REG_BINARY;
+ r->binary = blob;
return WERR_OK;
- } else if (strcmp("DNSMachineName", r->in.value_name) == 0) {
- if (!lp_realm()) return WERR_INVALID_PARAM;
-
- r->out.type = SPOOLSS_PRINTER_DATA_TYPE_STRING;
- r->out.data.string = talloc_asprintf(mem_ctx, "%s.%s",
- lp_netbios_name(),
- lp_realm());
- W_ERROR_HAVE_NO_MEMORY(r->out.data.string);
+ } else if (strcmp("DNSMachineName", value_name) == 0) {
+ const char *dnsdomain = lp_dnsdomain(server->ntptr->lp_ctx);
+
+ if (dnsdomain == NULL) return WERR_INVALID_PARAM;
+
+ *type = REG_SZ;
+ r->string = talloc_asprintf(mem_ctx, "%s.%s",
+ lp_netbios_name(server->ntptr->lp_ctx),
+ dnsdomain);
+ W_ERROR_HAVE_NO_MEMORY(r->string);
return WERR_OK;
}
return WERR_INVALID_PARAM;
}
+static WERROR sptr_GetPrintServerData(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
+ struct spoolss_GetPrinterData *r)
+{
+ WERROR result;
+ union spoolss_PrinterData data;
+ DATA_BLOB blob;
+ enum ndr_err_code ndr_err;
+
+ result = sptr_PrintServerData(server, mem_ctx, r->in.value_name, &data, r->out.type);
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
+ }
+
+ ndr_err = ndr_push_union_blob(&blob, mem_ctx,
+ &data, *r->out.type, (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterData);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return WERR_GENERAL_FAILURE;
+ }
+
+ *r->out.needed = blob.length;
+
+ if (r->in.offered >= *r->out.needed) {
+ memcpy(r->out.data, blob.data, blob.length);
+ }
+
+ return WERR_OK;
+}
+
/* PrintServer Form functions */
static WERROR sptr_EnumPrintServerForms(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
struct spoolss_EnumForms *r)
union spoolss_FormInfo *info;
count = sptr_db_search(sptr_db, mem_ctx,
- ldb_dn_explode(mem_ctx, "CN=Forms,CN=PrintServer"),
+ ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,CN=PrintServer"),
&msgs, NULL, "(&(objectClass=form))");
if (count == 0) return WERR_OK;
return WERR_UNKNOWN_LEVEL;
}
- r->out.info = info;
- r->out.count = count;
+ *r->out.info = info;
+ *r->out.count = count;
return WERR_OK;
}
return WERR_FOOBAR;
}
count = sptr_db_search(sptr_db, mem_ctx,
- ldb_dn_explode(mem_ctx, "CN=Forms,CN=PrintServer"),
+ ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,CN=PrintServer"),
&msgs, attrs, "(&(form-name=%s)(objectClass=form))",
r->in.info.info1->form_name);
W_ERROR_HAVE_NO_MEMORY(msg);
/* add core elements to the ldb_message for the Form */
- msg->dn = ldb_dn_build_child(msg,
- "form-name", r->in.info.info1->form_name,
- ldb_dn_explode(msg, "CN=Forms,CN=PrintServer"));
+ msg->dn = ldb_dn_new_fmt(msg, sptr_db, "form-name=%s,CN=Forms,CN=PrintServer", r->in.info.info1->form_name);
SET_STRING(sptr_db, msg, "objectClass", "form");
SET_UINT(sptr_db, msg, "flags", r->in.info.info1->flags);
return WERR_UNKNOWN_LEVEL;
}
- ret = samdb_add(sptr_db, mem_ctx, msg);
+ ret = ldb_add(sptr_db, msg);
if (ret != 0) {
return WERR_FOOBAR;
}
}
count = sptr_db_search(sptr_db, mem_ctx,
- ldb_dn_explode(mem_ctx, "CN=Forms,CN=PrintServer"),
+ ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,CN=PrintServer"),
&msgs, attrs, "(&(form-name=%s)(objectClass=form))",
r->in.info.info1->form_name);
return WERR_UNKNOWN_LEVEL;
}
- ret = samdb_replace(sptr_db, mem_ctx, msg);
+ ret = dsdb_replace(sptr_db, msg, 0);
if (ret != 0) {
return WERR_FOOBAR;
}
}
count = sptr_db_search(sptr_db, mem_ctx,
- ldb_dn_explode(mem_ctx, "CN=Forms,CN=PrintServer"),
+ ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,CN=PrintServer"),
&msgs, attrs, "(&(form-name=%s)(objectclass=form))",
r->in.form_name);
return WERR_FOOBAR;
}
- ret = samdb_delete(sptr_db, mem_ctx, msgs[0]->dn);
+ ret = ldb_delete(sptr_db, msgs[0]->dn);
if (ret != 0) {
return WERR_FOOBAR;
}
return WERR_UNKNOWN_LEVEL;
}
- r->out.info = info;
- r->out.count = count;
+ *r->out.info = info;
+ *r->out.count = count;
return WERR_OK;
}
return WERR_UNKNOWN_LEVEL;
}
- r->out.info = info;
- r->out.count = count;
+ *r->out.info = info;
+ *r->out.count = count;
return WERR_OK;
}
return WERR_UNKNOWN_LEVEL;
}
- r->out.info = info;
- r->out.count = count;
- return WERR_OK;
+ *r->out.info = info;
+ *r->out.count = count;
return WERR_OK;
}
{
struct ldb_context *sptr_db = talloc_get_type(printer->ntptr->private_data, struct ldb_context);
struct ldb_message **msgs;
- const struct ldb_dn *base_dn;
+ struct ldb_dn *base_dn;
int count;
union spoolss_FormInfo *info;
* }
*/
- base_dn = ldb_dn_string_compose(mem_ctx, NULL, "CN=Forms, CN=%s, CN=Printers", printer->object_name);
+ base_dn = ldb_dn_new_fmt(mem_ctx, sptr_db, "CN=Forms,CN=%s,CN=Printers", printer->object_name);
W_ERROR_HAVE_NO_MEMORY(base_dn);
count = sptr_db_search(sptr_db, mem_ctx, base_dn, &msgs, NULL,
return WERR_OK;
}
+static WERROR sptr_GetPrintProcessorDirectory(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
+ struct spoolss_GetPrintProcessorDirectory *r)
+{
+ union spoolss_PrintProcessorDirectoryInfo *info;
+ const char *prefix;
+ const char *postfix;
+
+ /*
+ * NOTE: normally r->in.level is 1, but both w2k3 and nt4 sp6a
+ * are ignoring the r->in.level completely, so we do :-)
+ */
+
+ /*
+ * TODO: check the server name is ours
+ * - if it's a invalid UNC then return WERR_INVALID_NAME
+ * - if it's the wrong host name return WERR_INVALID_PARAM
+ * - if it's "" then we need to return a local WINDOWS path
+ */
+ if (!r->in.server || !r->in.server[0]) {
+ prefix = "C:\\PRTPROCS";
+ } else {
+ prefix = talloc_asprintf(mem_ctx, "%s\\prnproc$", r->in.server);
+ W_ERROR_HAVE_NO_MEMORY(prefix);
+ }
+
+ if (r->in.environment && strcmp(SPOOLSS_ARCHITECTURE_NT_X86, r->in.environment) == 0) {
+ postfix = "W32X86";
+ } else {
+ return WERR_INVALID_ENVIRONMENT;
+ }
+
+ info = talloc(mem_ctx, union spoolss_PrintProcessorDirectoryInfo);
+ W_ERROR_HAVE_NO_MEMORY(info);
+
+ info->info1.directory_name = talloc_asprintf(mem_ctx, "%s\\%s", prefix, postfix);
+ W_ERROR_HAVE_NO_MEMORY(info->info1.directory_name);
+
+ r->out.info = info;
+ return WERR_OK;
+}
+
/*
initialialise the simble ldb backend, registering ourselves with the ntptr subsystem
/* PrintServer functions */
.OpenPrintServer = sptr_OpenPrintServer,
-
+/* .XcvDataPrintServer = sptr_XcvDataPrintServer,
+*/
/* PrintServer PrinterData functions */
/* .EnumPrintServerData = sptr_EnumPrintServerData,
*/ .GetPrintServerData = sptr_GetPrintServerData,
/* Port functions */
.EnumPorts = sptr_EnumPorts,
/* .OpenPort = sptr_OpenPort,
+ .XcvDataPort = sptr_XcvDataPort,
*/
/* Monitor functions */
.EnumMonitors = sptr_EnumMonitors,
/* .OpenMonitor = sptr_OpenMonitor,
+ .XcvDataMonitor = sptr_XcvDataMonitor,
*/
/* PrintProcessor functions */
/* .EnumPrintProcessors = sptr_EnumPrintProcessors,
*/
+ .GetPrintProcessorDirectory = sptr_GetPrintProcessorDirectory,
+
/* Printer functions */
.EnumPrinters = sptr_EnumPrinters,
.OpenPrinter = sptr_OpenPrinter,
.GetPrinter = sptr_GetPrinter,
.SetPrinter = sptr_SetPrinter,
.DeletePrinter = sptr_DeletePrinter,
+ .XcvDataPrinter = sptr_XcvDataPrinter,
*/
/* Printer Driver functions */
/* .GetPrinterDriver = sptr_GetPrinterDriver,