• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt/router/samba-3.5.8/source4/ntptr/simple_ldb/
1/*
2   Unix SMB/CIFS implementation.
3
4   Simple LDB NTPTR backend
5
6   Copyright (C) Stefan (metze) Metzmacher 2005
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 3 of the License, or
11   (at your option) any later version.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program.  If not, see <http://www.gnu.org/licenses/>.
20*/
21/*
22  This implements a NTPTR backend that store
23  all objects (Printers, Ports, Monitors, PrinterDrivers ...)
24  in a ldb database, but doesn't do real printing.
25
26  This is just used for testing how some of
27  the SPOOLSS protocol details should work
28*/
29
30#include "includes.h"
31#include "ntptr/ntptr.h"
32#include "librpc/gen_ndr/ndr_spoolss.h"
33#include "lib/ldb/include/ldb.h"
34#include "auth/auth.h"
35#include "dsdb/samdb/samdb.h"
36#include "ldb_wrap.h"
37#include "../lib/util/util_ldb.h"
38#include "rpc_server/common/common.h"
39#include "param/param.h"
40
41/*
42  connect to the SPOOLSS database
43  return a ldb_context pointer on success, or NULL on failure
44 */
45static struct ldb_context *sptr_db_connect(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, struct loadparm_context *lp_ctx)
46{
47	return ldb_wrap_connect(mem_ctx, ev_ctx, lp_ctx, lp_spoolss_url(lp_ctx), system_session(mem_ctx, lp_ctx),
48				NULL, 0, NULL);
49}
50
51static int sptr_db_search(struct ldb_context *ldb,
52			  TALLOC_CTX *mem_ctx,
53			  struct ldb_dn *basedn,
54			  struct ldb_message ***res,
55			  const char * const *attrs,
56			  const char *format, ...) PRINTF_ATTRIBUTE(6,7);
57
58static int sptr_db_search(struct ldb_context *ldb,
59			  TALLOC_CTX *mem_ctx,
60			  struct ldb_dn *basedn,
61			  struct ldb_message ***res,
62			  const char * const *attrs,
63			  const char *format, ...)
64{
65	va_list ap;
66	int count;
67
68	va_start(ap, format);
69	count = gendb_search_v(ldb, mem_ctx, basedn, res, attrs, format, ap);
70	va_end(ap);
71
72	return count;
73}
74
75#define SET_STRING(ldb, mod, attr, value) do { \
76	if (value == NULL) return WERR_INVALID_PARAM; \
77	if (samdb_msg_add_string(ldb, (TALLOC_CTX *)mod, mod, attr, value) != 0) { \
78		return WERR_NOMEM; \
79	} \
80} while (0)
81
82#define SET_UINT(ldb, mod, attr, value) do { \
83	if (samdb_msg_add_uint(ldb, (TALLOC_CTX *)mod, mod, attr, value) != 0) { \
84		return WERR_NOMEM; \
85	} \
86} while (0)
87
88static NTSTATUS sptr_init_context(struct ntptr_context *ntptr)
89{
90	struct ldb_context *sptr_db = sptr_db_connect(ntptr, ntptr->ev_ctx, ntptr->lp_ctx);
91	NT_STATUS_HAVE_NO_MEMORY(sptr_db);
92
93	ntptr->private_data = sptr_db;
94
95	return NT_STATUS_OK;
96}
97
98/* PrintServer functions */
99static WERROR sptr_OpenPrintServer(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
100				   struct spoolss_OpenPrinterEx *r,
101				   const char *server_name,
102				   struct ntptr_GenericHandle **_server)
103{
104	struct ntptr_GenericHandle *server;
105
106	/* TODO: do access check here! */
107
108	server = talloc(mem_ctx, struct ntptr_GenericHandle);
109	W_ERROR_HAVE_NO_MEMORY(server);
110
111	server->type		= NTPTR_HANDLE_SERVER;
112	server->ntptr		= ntptr;
113	server->object_name	= talloc_strdup(server, server_name);
114	W_ERROR_HAVE_NO_MEMORY(server->object_name);
115	server->access_mask	= 0;
116	server->private_data	= NULL;
117
118	*_server = server;
119	return WERR_OK;
120}
121
122/*
123 * PrintServer PrinterData functions
124 */
125
126static WERROR sptr_PrintServerData(struct ntptr_GenericHandle *server,
127				   TALLOC_CTX *mem_ctx,
128				   const char *value_name,
129				   union spoolss_PrinterData *r,
130				   enum winreg_Type *type)
131{
132	struct dcerpc_server_info *server_info = lp_dcerpc_server_info(mem_ctx, server->ntptr->lp_ctx);
133	if (strcmp("W3SvcInstalled", value_name) == 0) {
134		*type		= REG_DWORD;
135		r->value	= 0;
136		return WERR_OK;
137	} else if (strcmp("BeepEnabled", value_name) == 0) {
138		*type		= REG_DWORD;
139		r->value	= 0;
140		return WERR_OK;
141	} else if (strcmp("EventLog", value_name) == 0) {
142		*type		= REG_DWORD;
143		r->value	= 0;
144		return WERR_OK;
145	} else if (strcmp("NetPopup", value_name) == 0) {
146		*type		= REG_DWORD;
147		r->value	= 0;
148		return WERR_OK;
149	} else if (strcmp("NetPopupToComputer", value_name) == 0) {
150		*type		= REG_DWORD;
151		r->value	= 0;
152		return  WERR_OK;
153	} else if (strcmp("MajorVersion", value_name) == 0) {
154		*type		= REG_DWORD;
155		r->value	= 3;
156		return WERR_OK;
157	} else if (strcmp("MinorVersion", value_name) == 0) {
158		*type		= REG_DWORD;
159		r->value	= 0;
160		return WERR_OK;
161	} else if (strcmp("DefaultSpoolDirectory", value_name) == 0) {
162		*type		= REG_SZ;
163		r->string	= talloc_strdup(mem_ctx, "C:\\PRINTERS");
164		W_ERROR_HAVE_NO_MEMORY(r->string);
165		return  WERR_OK;
166	} else if (strcmp("Architecture", value_name) == 0) {
167		*type		= REG_SZ;
168		r->string	= talloc_strdup(mem_ctx, SPOOLSS_ARCHITECTURE_NT_X86);
169		W_ERROR_HAVE_NO_MEMORY(r->string);
170		return  WERR_OK;
171	} else if (strcmp("DsPresent", value_name) == 0) {
172		*type		= REG_DWORD;
173		r->value	= 1;
174		return WERR_OK;
175	} else if (strcmp("OSVersion", value_name) == 0) {
176		DATA_BLOB blob;
177		enum ndr_err_code ndr_err;
178		struct spoolss_OSVersion os;
179
180		os.major		= server_info->version_major;
181		os.minor		= server_info->version_minor;
182		os.build		= server_info->version_build;
183		os.extra_string		= "";
184
185		ndr_err = ndr_push_struct_blob(&blob, mem_ctx, lp_iconv_convenience(server->ntptr->lp_ctx), &os, (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
186		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
187			return WERR_GENERAL_FAILURE;
188		}
189
190		*type		= REG_BINARY;
191		r->binary	= blob;
192		return WERR_OK;
193	} else if (strcmp("OSVersionEx", value_name) == 0) {
194		DATA_BLOB blob;
195		enum ndr_err_code ndr_err;
196		struct spoolss_OSVersionEx os_ex;
197
198		os_ex.major		= server_info->version_major;
199		os_ex.minor		= server_info->version_minor;
200		os_ex.build		= server_info->version_build;
201		os_ex.extra_string	= "";
202		os_ex.service_pack_major= 0;
203		os_ex.service_pack_minor= 0;
204		os_ex.suite_mask	= 0;
205		os_ex.product_type	= 0;
206		os_ex.reserved		= 0;
207
208		ndr_err = ndr_push_struct_blob(&blob, mem_ctx, lp_iconv_convenience(server->ntptr->lp_ctx), &os_ex, (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersionEx);
209		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
210			return WERR_GENERAL_FAILURE;
211		}
212
213		*type		= REG_BINARY;
214		r->binary	= blob;
215		return WERR_OK;
216	} else if (strcmp("DNSMachineName", value_name) == 0) {
217		if (!lp_realm(server->ntptr->lp_ctx)) return WERR_INVALID_PARAM;
218
219		*type		= REG_SZ;
220		r->string	= talloc_asprintf(mem_ctx, "%s.%s",
221						   lp_netbios_name(server->ntptr->lp_ctx),
222						   lp_realm(server->ntptr->lp_ctx));
223		W_ERROR_HAVE_NO_MEMORY(r->string);
224		return WERR_OK;
225	}
226
227	return WERR_INVALID_PARAM;
228}
229
230static WERROR sptr_GetPrintServerData(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
231				      struct spoolss_GetPrinterData *r)
232{
233	WERROR result;
234	union spoolss_PrinterData data;
235	DATA_BLOB blob;
236	enum ndr_err_code ndr_err;
237
238	result = sptr_PrintServerData(server, mem_ctx, r->in.value_name, &data, r->out.type);
239	if (!W_ERROR_IS_OK(result)) {
240		return result;
241	}
242
243	ndr_err = ndr_push_union_blob(&blob, mem_ctx, lp_iconv_convenience(server->ntptr->lp_ctx),
244				      &data, *r->out.type, (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterData);
245	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
246		return WERR_GENERAL_FAILURE;
247	}
248
249	*r->out.needed = blob.length;
250
251	if (r->in.offered >= *r->out.needed) {
252		memcpy(r->out.data, blob.data, blob.length);
253	}
254
255	return WERR_OK;
256}
257
258/* PrintServer Form functions */
259static WERROR sptr_EnumPrintServerForms(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
260					struct spoolss_EnumForms *r)
261{
262	struct ldb_context *sptr_db = talloc_get_type(server->ntptr->private_data, struct ldb_context);
263	struct ldb_message **msgs;
264	int count;
265	int i;
266	union spoolss_FormInfo *info;
267
268	count = sptr_db_search(sptr_db, mem_ctx,
269				ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,CN=PrintServer"),
270				&msgs, NULL, "(&(objectClass=form))");
271
272	if (count == 0) return WERR_OK;
273	if (count < 0) return WERR_GENERAL_FAILURE;
274
275	info = talloc_array(mem_ctx, union spoolss_FormInfo, count);
276	W_ERROR_HAVE_NO_MEMORY(info);
277
278	switch (r->in.level) {
279	case 1:
280		for (i=0; i < count; i++) {
281			info[i].info1.flags		= samdb_result_uint(msgs[i], "flags", SPOOLSS_FORM_BUILTIN);
282
283			info[i].info1.form_name		= samdb_result_string(msgs[i], "form-name", NULL);
284			W_ERROR_HAVE_NO_MEMORY(info[i].info1.form_name);
285
286			info[i].info1.size.width	= samdb_result_uint(msgs[i], "size-width", 0);
287			info[i].info1.size.height	= samdb_result_uint(msgs[i], "size-height", 0);
288
289			info[i].info1.area.left		= samdb_result_uint(msgs[i], "area-left", 0);
290			info[i].info1.area.top		= samdb_result_uint(msgs[i], "area-top", 0);
291			info[i].info1.area.right	= samdb_result_uint(msgs[i], "area-right", 0);
292			info[i].info1.area.bottom	= samdb_result_uint(msgs[i], "area-bottom", 0);
293		}
294		break;
295	default:
296		return WERR_UNKNOWN_LEVEL;
297	}
298
299	*r->out.info	= info;
300	*r->out.count	= count;
301	return WERR_OK;
302}
303
304static WERROR sptr_AddPrintServerForm(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
305				      struct spoolss_AddForm *r)
306{
307	struct ldb_context *sptr_db = talloc_get_type(server->ntptr->private_data, struct ldb_context);
308	struct ldb_message *msg,**msgs;
309	const char * const attrs[] = {"flags", NULL };
310	int count, ret;
311
312	/* TODO: do checks access here
313	 * if (!(server->access_mask & desired_access)) {
314	 *	return WERR_FOOBAR;
315	 * }
316	 */
317
318	switch (r->in.level) {
319	case 1:
320		if (!r->in.info.info1) {
321			return WERR_FOOBAR;
322		}
323		count = sptr_db_search(sptr_db, mem_ctx,
324				       ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,CN=PrintServer"),
325				       &msgs, attrs, "(&(form-name=%s)(objectClass=form))",
326				       r->in.info.info1->form_name);
327
328		if (count == 1) return WERR_FOOBAR;
329		if (count > 1) return WERR_FOOBAR;
330		if (count < 0) return WERR_GENERAL_FAILURE;
331
332		if (r->in.info.info1->flags != SPOOLSS_FORM_USER) {
333			return WERR_FOOBAR;
334		}
335
336		msg = ldb_msg_new(mem_ctx);
337		W_ERROR_HAVE_NO_MEMORY(msg);
338
339		/* add core elements to the ldb_message for the Form */
340		msg->dn = ldb_dn_new_fmt(msg, sptr_db, "form-name=%s,CN=Forms,CN=PrintServer", r->in.info.info1->form_name);
341		SET_STRING(sptr_db, msg, "objectClass", "form");
342
343		SET_UINT(sptr_db, msg, "flags", r->in.info.info1->flags);
344
345		SET_STRING(sptr_db, msg, "form-name", r->in.info.info1->form_name);
346
347		SET_UINT(sptr_db, msg, "size-width", r->in.info.info1->size.width);
348		SET_UINT(sptr_db, msg, "size-height", r->in.info.info1->size.height);
349
350		SET_UINT(sptr_db, msg, "area-left", r->in.info.info1->area.left);
351		SET_UINT(sptr_db, msg, "area-top", r->in.info.info1->area.top);
352		SET_UINT(sptr_db, msg, "area-right", r->in.info.info1->area.right);
353		SET_UINT(sptr_db, msg, "area-bottom", r->in.info.info1->area.bottom);
354		break;
355	default:
356		return WERR_UNKNOWN_LEVEL;
357	}
358
359	ret = ldb_add(sptr_db, msg);
360	if (ret != 0) {
361		return WERR_FOOBAR;
362	}
363
364	return WERR_OK;
365}
366
367static WERROR sptr_SetPrintServerForm(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
368				      struct spoolss_SetForm *r)
369{
370	struct ldb_context *sptr_db = talloc_get_type(server->ntptr->private_data, struct ldb_context);
371	struct ldb_message *msg,**msgs;
372	const char * const attrs[] = { "flags", NULL};
373	int count, ret;
374	enum spoolss_FormFlags flags;
375
376	/* TODO: do checks access here
377	 * if (!(server->access_mask & desired_access)) {
378	 *	return WERR_FOOBAR;
379	 * }
380	 */
381
382	switch (r->in.level) {
383	case 1:
384		if (!r->in.info.info1) {
385			return WERR_FOOBAR;
386		}
387
388		count = sptr_db_search(sptr_db, mem_ctx,
389				       ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,CN=PrintServer"),
390				       &msgs, attrs, "(&(form-name=%s)(objectClass=form))",
391				       r->in.info.info1->form_name);
392
393		if (count == 0) return WERR_FOOBAR;
394		if (count > 1) return WERR_FOOBAR;
395		if (count < 0) return WERR_GENERAL_FAILURE;
396
397		flags = samdb_result_uint(msgs[0], "flags", SPOOLSS_FORM_BUILTIN);
398		if (flags != SPOOLSS_FORM_USER) {
399			return WERR_FOOBAR;
400		}
401
402		msg = ldb_msg_new(mem_ctx);
403		W_ERROR_HAVE_NO_MEMORY(msg);
404
405		/* add core elements to the ldb_message for the user */
406		msg->dn = msgs[0]->dn;
407
408		SET_UINT(sptr_db, msg, "flags", r->in.info.info1->flags);
409
410		SET_STRING(sptr_db, msg, "form-name", r->in.info.info1->form_name);
411
412		SET_UINT(sptr_db, msg, "size-width", r->in.info.info1->size.width);
413		SET_UINT(sptr_db, msg, "size-height", r->in.info.info1->size.height);
414
415		SET_UINT(sptr_db, msg, "area-left", r->in.info.info1->area.left);
416		SET_UINT(sptr_db, msg, "area-top", r->in.info.info1->area.top);
417		SET_UINT(sptr_db, msg, "area-right", r->in.info.info1->area.right);
418		SET_UINT(sptr_db, msg, "area-bottom", r->in.info.info1->area.bottom);
419		break;
420	default:
421		return WERR_UNKNOWN_LEVEL;
422	}
423
424	ret = samdb_replace(sptr_db, mem_ctx, msg);
425	if (ret != 0) {
426		return WERR_FOOBAR;
427	}
428
429	return WERR_OK;
430}
431
432static WERROR sptr_DeletePrintServerForm(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
433					 struct spoolss_DeleteForm *r)
434{
435	struct ldb_context *sptr_db = talloc_get_type(server->ntptr->private_data, struct ldb_context);
436	struct ldb_message **msgs;
437	const char * const attrs[] = { "flags", NULL};
438	int count, ret;
439	enum spoolss_FormFlags flags;
440
441	/* TODO: do checks access here
442	 * if (!(server->access_mask & desired_access)) {
443	 *	return WERR_FOOBAR;
444	 * }
445	 */
446
447	if (!r->in.form_name) {
448		return WERR_FOOBAR;
449	}
450
451	count = sptr_db_search(sptr_db, mem_ctx,
452			       ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,CN=PrintServer"),
453			       &msgs, attrs, "(&(form-name=%s)(objectclass=form))",
454			       r->in.form_name);
455
456	if (count == 0) return WERR_FOOBAR;
457	if (count > 1) return WERR_FOOBAR;
458	if (count < 0) return WERR_GENERAL_FAILURE;
459
460	flags = samdb_result_uint(msgs[0], "flags", SPOOLSS_FORM_BUILTIN);
461	if (flags != SPOOLSS_FORM_USER) {
462		return WERR_FOOBAR;
463	}
464
465	ret = ldb_delete(sptr_db, msgs[0]->dn);
466	if (ret != 0) {
467		return WERR_FOOBAR;
468	}
469
470	return WERR_OK;
471}
472
473/* PrintServer Driver functions */
474static WERROR sptr_EnumPrinterDrivers(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
475				      struct spoolss_EnumPrinterDrivers *r)
476{
477	return WERR_OK;
478}
479
480static WERROR sptr_GetPrinterDriverDirectory(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
481					     struct spoolss_GetPrinterDriverDirectory *r)
482{
483	union spoolss_DriverDirectoryInfo *info;
484	const char *prefix;
485	const char *postfix;
486
487	/*
488	 * NOTE: normally r->in.level is 1, but both w2k3 and nt4 sp6a
489	 *        are ignoring the r->in.level completely, so we do :-)
490	 */
491
492	/*
493	 * TODO: check the server name is ours
494	 * - if it's a invalid UNC then return WERR_INVALID_NAME
495	 * - if it's the wrong host name return WERR_INVALID_PARAM
496	 * - if it's "" then we need to return a local WINDOWS path
497	 */
498	if (!r->in.server || !r->in.server[0]) {
499		prefix = "C:\\DRIVERS";
500	} else {
501		prefix = talloc_asprintf(mem_ctx, "%s\\print$", r->in.server);
502		W_ERROR_HAVE_NO_MEMORY(prefix);
503	}
504
505	if (r->in.environment && strcmp(SPOOLSS_ARCHITECTURE_NT_X86, r->in.environment) == 0) {
506		postfix = "W32X86";
507	} else {
508		return WERR_INVALID_ENVIRONMENT;
509	}
510
511	info = talloc(mem_ctx, union spoolss_DriverDirectoryInfo);
512	W_ERROR_HAVE_NO_MEMORY(info);
513
514	info->info1.directory_name	= talloc_asprintf(mem_ctx, "%s\\%s", prefix, postfix);
515	W_ERROR_HAVE_NO_MEMORY(info->info1.directory_name);
516
517	r->out.info = info;
518	return WERR_OK;
519}
520
521/* Printer functions */
522static WERROR sptr_EnumPrinters(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
523				struct spoolss_EnumPrinters *r)
524{
525	struct ldb_context *sptr_db = talloc_get_type(ntptr->private_data, struct ldb_context);
526	struct ldb_message **msgs;
527	int count;
528	int i;
529	union spoolss_PrinterInfo *info;
530
531	count = sptr_db_search(sptr_db, mem_ctx, NULL, &msgs, NULL,
532			       "(&(objectclass=printer))");
533
534	if (count == 0) return WERR_OK;
535	if (count < 0) return WERR_GENERAL_FAILURE;
536
537	info = talloc_array(mem_ctx, union spoolss_PrinterInfo, count);
538	W_ERROR_HAVE_NO_MEMORY(info);
539
540	switch(r->in.level) {
541	case 1:
542		for (i = 0; i < count; i++) {
543			info[i].info1.flags		= samdb_result_uint(msgs[i], "flags", 0);
544
545			info[i].info1.name		= samdb_result_string(msgs[i], "name", "");
546			W_ERROR_HAVE_NO_MEMORY(info[i].info1.name);
547
548			info[i].info1.description	= samdb_result_string(msgs[i], "description", "");
549			W_ERROR_HAVE_NO_MEMORY(info[i].info1.description);
550
551			info[i].info1.comment		= samdb_result_string(msgs[i], "comment", NULL);
552		}
553		break;
554	case 2:
555		for (i = 0; i < count; i++) {
556			info[i].info2.servername	= samdb_result_string(msgs[i], "servername", "");
557			W_ERROR_HAVE_NO_MEMORY(info[i].info2.servername);
558
559			info[i].info2.printername	= samdb_result_string(msgs[i], "printername", "");
560			W_ERROR_HAVE_NO_MEMORY(info[i].info2.printername);
561
562			info[i].info2.sharename		= samdb_result_string(msgs[i], "sharename", "");
563			W_ERROR_HAVE_NO_MEMORY(info[i].info2.sharename);
564
565			info[i].info2.portname		= samdb_result_string(msgs[i], "portname", "");
566			W_ERROR_HAVE_NO_MEMORY(info[i].info2.portname);
567
568			info[i].info2.drivername	= samdb_result_string(msgs[i], "drivername", "");
569			W_ERROR_HAVE_NO_MEMORY(info[i].info2.drivername);
570
571			info[i].info2.comment		= samdb_result_string(msgs[i], "comment", NULL);
572
573			info[i].info2.location		= samdb_result_string(msgs[i], "location", NULL);
574
575			info[i].info2.devmode		= NULL;
576
577			info[i].info2.sepfile		= samdb_result_string(msgs[i], "sepfile", NULL);
578
579			info[i].info2.printprocessor	= samdb_result_string(msgs[i], "printprocessor", "");
580			W_ERROR_HAVE_NO_MEMORY(info[i].info2.printprocessor);
581
582			info[i].info2.datatype		= samdb_result_string(msgs[i], "datatype", "");
583			W_ERROR_HAVE_NO_MEMORY(info[i].info2.datatype);
584
585			info[i].info2.parameters	= samdb_result_string(msgs[i], "parameters", NULL);
586
587			info[i].info2.secdesc		= NULL;
588
589			info[i].info2.attributes	= samdb_result_uint(msgs[i], "attributes", 0);
590			info[i].info2.priority		= samdb_result_uint(msgs[i], "priority", 0);
591			info[i].info2.defaultpriority	= samdb_result_uint(msgs[i], "defaultpriority", 0);
592			info[i].info2.starttime		= samdb_result_uint(msgs[i], "starttime", 0);
593			info[i].info2.untiltime		= samdb_result_uint(msgs[i], "untiltime", 0);
594			info[i].info2.status		= samdb_result_uint(msgs[i], "status", 0);
595			info[i].info2.cjobs		= samdb_result_uint(msgs[i], "cjobs", 0);
596			info[i].info2.averageppm	= samdb_result_uint(msgs[i], "averageppm", 0);
597		}
598		break;
599	case 4:
600		for (i = 0; i < count; i++) {
601			info[i].info4.printername	= samdb_result_string(msgs[i], "printername", "");
602			W_ERROR_HAVE_NO_MEMORY(info[i].info2.printername);
603
604			info[i].info4.servername	= samdb_result_string(msgs[i], "servername", "");
605			W_ERROR_HAVE_NO_MEMORY(info[i].info2.servername);
606
607			info[i].info4.attributes	= samdb_result_uint(msgs[i], "attributes", 0);
608		}
609		break;
610	case 5:
611		for (i = 0; i < count; i++) {
612			info[i].info5.printername	= samdb_result_string(msgs[i], "name", "");
613			W_ERROR_HAVE_NO_MEMORY(info[i].info5.printername);
614
615			info[i].info5.portname		= samdb_result_string(msgs[i], "port", "");
616			W_ERROR_HAVE_NO_MEMORY(info[i].info5.portname);
617
618			info[i].info5.attributes	= samdb_result_uint(msgs[i], "attributes", 0);
619			info[i].info5.device_not_selected_timeout = samdb_result_uint(msgs[i], "device_not_selected_timeout", 0);
620			info[i].info5.transmission_retry_timeout  = samdb_result_uint(msgs[i], "transmission_retry_timeout", 0);
621		}
622		break;
623	default:
624		return WERR_UNKNOWN_LEVEL;
625	}
626
627	*r->out.info	= info;
628	*r->out.count	= count;
629	return WERR_OK;
630}
631
632static WERROR sptr_OpenPrinter(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
633			       struct spoolss_OpenPrinterEx *r,
634			       const char *printer_name,
635			       struct ntptr_GenericHandle **printer)
636{
637	return WERR_INVALID_PRINTER_NAME;
638}
639
640/* port functions */
641static WERROR sptr_EnumPorts(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
642			     struct spoolss_EnumPorts *r)
643{
644	struct ldb_context *sptr_db = talloc_get_type(ntptr->private_data, struct ldb_context);
645	struct ldb_message **msgs;
646	int count;
647	int i;
648	union spoolss_PortInfo *info;
649
650	count = sptr_db_search(sptr_db, mem_ctx, NULL, &msgs, NULL,
651			       "(&(objectclass=port))");
652
653	if (count == 0) return WERR_OK;
654	if (count < 0) return WERR_GENERAL_FAILURE;
655
656	info = talloc_array(mem_ctx, union spoolss_PortInfo, count);
657	W_ERROR_HAVE_NO_MEMORY(info);
658
659	switch (r->in.level) {
660	case 1:
661		for (i = 0; i < count; i++) {
662			info[i].info1.port_name		= samdb_result_string(msgs[i], "port-name", "");
663			W_ERROR_HAVE_NO_MEMORY(info[i].info1.port_name);
664		}
665		break;
666	case 2:
667		for (i=0; i < count; i++) {
668			info[i].info2.port_name		= samdb_result_string(msgs[i], "port-name", "");
669			W_ERROR_HAVE_NO_MEMORY(info[i].info2.port_name);
670
671			info[i].info2.monitor_name	= samdb_result_string(msgs[i], "monitor-name", "");
672			W_ERROR_HAVE_NO_MEMORY(info[i].info2.monitor_name);
673
674			info[i].info2.description	= samdb_result_string(msgs[i], "description", "");
675			W_ERROR_HAVE_NO_MEMORY(info[i].info2.description);
676
677			info[i].info2.port_type		= samdb_result_uint(msgs[i], "port-type", SPOOLSS_PORT_TYPE_WRITE);
678			info[i].info2.reserved		= samdb_result_uint(msgs[i], "reserved", 0);
679		}
680		break;
681	default:
682		return WERR_UNKNOWN_LEVEL;
683	}
684
685	*r->out.info	= info;
686	*r->out.count	= count;
687	return WERR_OK;
688}
689
690/* monitor functions */
691static WERROR sptr_EnumMonitors(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
692				struct spoolss_EnumMonitors *r)
693{
694	struct ldb_context *sptr_db = talloc_get_type(ntptr->private_data, struct ldb_context);
695	struct ldb_message **msgs;
696	int count;
697	int i;
698	union spoolss_MonitorInfo *info;
699
700	count = sptr_db_search(sptr_db, mem_ctx, NULL, &msgs, NULL,
701			       "(&(objectclass=monitor))");
702
703	if (count == 0) return WERR_OK;
704	if (count < 0) return WERR_GENERAL_FAILURE;
705
706	info = talloc_array(mem_ctx, union spoolss_MonitorInfo, count);
707	W_ERROR_HAVE_NO_MEMORY(info);
708
709	switch (r->in.level) {
710	case 1:
711		for (i = 0; i < count; i++) {
712			info[i].info1.monitor_name	= samdb_result_string(msgs[i], "monitor-name", "");
713			W_ERROR_HAVE_NO_MEMORY(info[i].info1.monitor_name);
714		}
715		break;
716	case 2:
717		for (i=0; i < count; i++) {
718			info[i].info2.monitor_name	= samdb_result_string(msgs[i], "monitor-name", "");
719			W_ERROR_HAVE_NO_MEMORY(info[i].info2.monitor_name);
720
721			info[i].info2.environment	= samdb_result_string(msgs[i], "environment", "");
722			W_ERROR_HAVE_NO_MEMORY(info[i].info2.environment);
723
724			info[i].info2.dll_name		= samdb_result_string(msgs[i], "dll-name", "");
725			W_ERROR_HAVE_NO_MEMORY(info[i].info2.dll_name);
726		}
727		break;
728	default:
729		return WERR_UNKNOWN_LEVEL;
730	}
731
732	*r->out.info	= info;
733	*r->out.count	= count;
734	return WERR_OK;
735}
736
737/* Printer Form functions */
738static WERROR sptr_GetPrinterForm(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
739				  struct spoolss_GetForm *r)
740{
741	struct ldb_context *sptr_db = talloc_get_type(printer->ntptr->private_data, struct ldb_context);
742	struct ldb_message **msgs;
743	struct ldb_dn *base_dn;
744	int count;
745	union spoolss_FormInfo *info;
746
747	/* TODO: do checks access here
748	 * if (!(printer->access_mask & desired_access)) {
749	 *	return WERR_FOOBAR;
750	 * }
751	 */
752
753	base_dn = ldb_dn_new_fmt(mem_ctx, sptr_db, "CN=Forms,CN=%s,CN=Printers", printer->object_name);
754	W_ERROR_HAVE_NO_MEMORY(base_dn);
755
756	count = sptr_db_search(sptr_db, mem_ctx, base_dn, &msgs, NULL,
757			       "(&(form-name=%s)(objectClass=form))",
758			       r->in.form_name);
759
760	if (count == 0) return WERR_FOOBAR;
761	if (count > 1) return WERR_FOOBAR;
762	if (count < 0) return WERR_GENERAL_FAILURE;
763
764	info = talloc(mem_ctx, union spoolss_FormInfo);
765	W_ERROR_HAVE_NO_MEMORY(info);
766
767	switch (r->in.level) {
768	case 1:
769		info->info1.flags	= samdb_result_uint(msgs[0], "flags", SPOOLSS_FORM_BUILTIN);
770
771		info->info1.form_name	= samdb_result_string(msgs[0], "form-name", NULL);
772		W_ERROR_HAVE_NO_MEMORY(info->info1.form_name);
773
774		info->info1.size.width	= samdb_result_uint(msgs[0], "size-width", 0);
775		info->info1.size.height	= samdb_result_uint(msgs[0], "size-height", 0);
776
777		info->info1.area.left	= samdb_result_uint(msgs[0], "area-left", 0);
778		info->info1.area.top	= samdb_result_uint(msgs[0], "area-top", 0);
779		info->info1.area.right	= samdb_result_uint(msgs[0], "area-right", 0);
780		info->info1.area.bottom	= samdb_result_uint(msgs[0], "area-bottom", 0);
781		break;
782	default:
783		return WERR_UNKNOWN_LEVEL;
784	}
785
786	r->out.info	= info;
787	return WERR_OK;
788}
789
790static WERROR sptr_GetPrintProcessorDirectory(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
791					      struct spoolss_GetPrintProcessorDirectory *r)
792{
793	union spoolss_PrintProcessorDirectoryInfo *info;
794	const char *prefix;
795	const char *postfix;
796
797	/*
798	 * NOTE: normally r->in.level is 1, but both w2k3 and nt4 sp6a
799	 *        are ignoring the r->in.level completely, so we do :-)
800	 */
801
802	/*
803	 * TODO: check the server name is ours
804	 * - if it's a invalid UNC then return WERR_INVALID_NAME
805	 * - if it's the wrong host name return WERR_INVALID_PARAM
806	 * - if it's "" then we need to return a local WINDOWS path
807	 */
808	if (!r->in.server || !r->in.server[0]) {
809		prefix = "C:\\PRTPROCS";
810	} else {
811		prefix = talloc_asprintf(mem_ctx, "%s\\prnproc$", r->in.server);
812		W_ERROR_HAVE_NO_MEMORY(prefix);
813	}
814
815	if (r->in.environment && strcmp(SPOOLSS_ARCHITECTURE_NT_X86, r->in.environment) == 0) {
816		postfix = "W32X86";
817	} else {
818		return WERR_INVALID_ENVIRONMENT;
819	}
820
821	info = talloc(mem_ctx, union spoolss_PrintProcessorDirectoryInfo);
822	W_ERROR_HAVE_NO_MEMORY(info);
823
824	info->info1.directory_name	= talloc_asprintf(mem_ctx, "%s\\%s", prefix, postfix);
825	W_ERROR_HAVE_NO_MEMORY(info->info1.directory_name);
826
827	r->out.info = info;
828	return WERR_OK;
829}
830
831
832/*
833  initialialise the simble ldb backend, registering ourselves with the ntptr subsystem
834 */
835static const struct ntptr_ops ntptr_simple_ldb_ops = {
836	.name				= "simple_ldb",
837	.init_context			= sptr_init_context,
838
839	/* PrintServer functions */
840	.OpenPrintServer		= sptr_OpenPrintServer,
841/*	.XcvDataPrintServer		= sptr_XcvDataPrintServer,
842*/
843	/* PrintServer PrinterData functions */
844/*	.EnumPrintServerData		= sptr_EnumPrintServerData,
845*/	.GetPrintServerData		= sptr_GetPrintServerData,
846/*	.SetPrintServerData		= sptr_SetPrintServerData,
847	.DeletePrintServerData		= sptr_DeletePrintServerData,
848*/
849	/* PrintServer Form functions */
850	.EnumPrintServerForms		= sptr_EnumPrintServerForms,
851	.AddPrintServerForm		= sptr_AddPrintServerForm,
852	.SetPrintServerForm		= sptr_SetPrintServerForm,
853	.DeletePrintServerForm		= sptr_DeletePrintServerForm,
854
855	/* PrintServer Driver functions */
856	.EnumPrinterDrivers		= sptr_EnumPrinterDrivers,
857/*	.AddPrinterDriver		= sptr_AddPrinterDriver,
858	.DeletePrinterDriver		= sptr_DeletePrinterDriver,
859*/	.GetPrinterDriverDirectory	= sptr_GetPrinterDriverDirectory,
860
861	/* Port functions */
862	.EnumPorts			= sptr_EnumPorts,
863/*	.OpenPort			= sptr_OpenPort,
864	.XcvDataPort			= sptr_XcvDataPort,
865*/
866	/* Monitor functions */
867	.EnumMonitors			= sptr_EnumMonitors,
868/*	.OpenMonitor			= sptr_OpenMonitor,
869	.XcvDataMonitor			= sptr_XcvDataMonitor,
870*/
871	/* PrintProcessor functions */
872/*	.EnumPrintProcessors		= sptr_EnumPrintProcessors,
873*/
874	.GetPrintProcessorDirectory	= sptr_GetPrintProcessorDirectory,
875
876	/* Printer functions */
877	.EnumPrinters			= sptr_EnumPrinters,
878	.OpenPrinter			= sptr_OpenPrinter,
879/*	.AddPrinter			= sptr_AddPrinter,
880	.GetPrinter			= sptr_GetPrinter,
881	.SetPrinter			= sptr_SetPrinter,
882	.DeletePrinter			= sptr_DeletePrinter,
883	.XcvDataPrinter			= sptr_XcvDataPrinter,
884*/
885	/* Printer Driver functions */
886/*	.GetPrinterDriver		= sptr_GetPrinterDriver,
887*/
888	/* Printer PrinterData functions */
889/*	.EnumPrinterData		= sptr_EnumPrinterData,
890	.GetPrinterData			= sptr_GetPrinterData,
891	.SetPrinterData			= sptr_SetPrinterData,
892	.DeletePrinterData		= sptr_DeletePrinterData,
893*/
894	/* Printer Form functions */
895/*	.EnumPrinterForms		= sptr_EnumPrinterForms,
896	.AddPrinterForm			= sptr_AddPrinterForm,
897*/	.GetPrinterForm			= sptr_GetPrinterForm,
898/*	.SetPrinterForm			= sptr_SetPrinterForm,
899	.DeletePrinterForm		= sptr_DeletePrinterForm,
900*/
901	/* Printer Job functions */
902/*	.EnumJobs			= sptr_EnumJobs,
903	.AddJob				= sptr_AddJob,
904	.ScheduleJob			= sptr_ScheduleJob,
905	.GetJob				= sptr_GetJob,
906	.SetJob				= sptr_SetJob,
907*/
908	/* Printer Printing functions */
909/*	.StartDocPrinter		= sptr_StartDocPrinter,
910	.EndDocPrinter			= sptr_EndDocPrinter,
911	.StartPagePrinter		= sptr_StartPagePrinter,
912	.EndPagePrinter			= sptr_EndPagePrinter,
913	.WritePrinter			= sptr_WritePrinter,
914	.ReadPrinter			= sptr_ReadPrinter,
915*/};
916
917NTSTATUS ntptr_simple_ldb_init(void)
918{
919	NTSTATUS ret;
920
921	ret = ntptr_register(&ntptr_simple_ldb_ops);
922	if (!NT_STATUS_IS_OK(ret)) {
923		DEBUG(0,("Failed to register NTPTR '%s' backend!\n",
924			 ntptr_simple_ldb_ops.name));
925	}
926
927	return ret;
928}
929