~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/ntptr/simple_ldb/ntptr_simple_ldb.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 */
 
45
static 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
 
 
51
static 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
 
 
58
static 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
 
 
88
static 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 */
 
99
static 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
static WERROR sptr_GetPrintServerData(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
 
126
                                      struct spoolss_GetPrinterData *r)
 
127
{
 
128
        struct dcerpc_server_info *server_info = lp_dcerpc_server_info(mem_ctx, server->ntptr->lp_ctx);
 
129
        if (strcmp("W3SvcInstalled", r->in.value_name) == 0) {
 
130
                *r->out.type            = REG_DWORD;
 
131
                r->out.data->value      = 0;
 
132
                return WERR_OK;
 
133
        } else if (strcmp("BeepEnabled", r->in.value_name) == 0) {
 
134
                *r->out.type            = REG_DWORD;
 
135
                r->out.data->value      = 0;
 
136
                return WERR_OK;
 
137
        } else if (strcmp("EventLog", r->in.value_name) == 0) {
 
138
                *r->out.type            = REG_DWORD;
 
139
                r->out.data->value      = 0;
 
140
                return WERR_OK;
 
141
        } else if (strcmp("NetPopup", r->in.value_name) == 0) {
 
142
                *r->out.type            = REG_DWORD;
 
143
                r->out.data->value      = 0;
 
144
                return WERR_OK;
 
145
        } else if (strcmp("NetPopupToComputer", r->in.value_name) == 0) {
 
146
                *r->out.type            = REG_DWORD;
 
147
                r->out.data->value      = 0;
 
148
                return  WERR_OK;
 
149
        } else if (strcmp("MajorVersion", r->in.value_name) == 0) {
 
150
                *r->out.type            = REG_DWORD;
 
151
                r->out.data->value      = 3;
 
152
                return WERR_OK;
 
153
        } else if (strcmp("MinorVersion", r->in.value_name) == 0) {
 
154
                *r->out.type            = REG_DWORD;
 
155
                r->out.data->value      = 0;
 
156
                return WERR_OK;
 
157
        } else if (strcmp("DefaultSpoolDirectory", r->in.value_name) == 0) {
 
158
                *r->out.type            = REG_SZ;
 
159
                r->out.data->string     = "C:\\PRINTERS";
 
160
                return  WERR_OK;
 
161
        } else if (strcmp("Architecture", r->in.value_name) == 0) {
 
162
                *r->out.type            = REG_SZ;
 
163
                r->out.data->string     = SPOOLSS_ARCHITECTURE_NT_X86;
 
164
                return  WERR_OK;
 
165
        } else if (strcmp("DsPresent", r->in.value_name) == 0) {
 
166
                *r->out.type            = REG_DWORD;
 
167
                r->out.data->value      = 1;
 
168
                return WERR_OK;
 
169
        } else if (strcmp("OSVersion", r->in.value_name) == 0) {
 
170
                DATA_BLOB blob;
 
171
                enum ndr_err_code ndr_err;
 
172
                struct spoolss_OSVersion os;
 
173
 
 
174
                os.major                = server_info->version_major;
 
175
                os.minor                = server_info->version_minor;
 
176
                os.build                = server_info->version_build;
 
177
                os.extra_string         = "";
 
178
 
 
179
                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);
 
180
                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 
181
                        return WERR_GENERAL_FAILURE;
 
182
                }
 
183
 
 
184
                *r->out.type            = REG_BINARY;
 
185
                r->out.data->binary     = blob;
 
186
                return WERR_OK;
 
187
        } else if (strcmp("OSVersionEx", r->in.value_name) == 0) {
 
188
                DATA_BLOB blob;
 
189
                enum ndr_err_code ndr_err;
 
190
                struct spoolss_OSVersionEx os_ex;
 
191
 
 
192
                os_ex.major             = server_info->version_major;
 
193
                os_ex.minor             = server_info->version_minor;
 
194
                os_ex.build             = server_info->version_build;
 
195
                os_ex.extra_string              = "";
 
196
                os_ex.unknown2          = 0;
 
197
                os_ex.unknown3          = 0;
 
198
 
 
199
                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);
 
200
                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 
201
                        return WERR_GENERAL_FAILURE;
 
202
                }
 
203
 
 
204
                *r->out.type            = REG_BINARY;
 
205
                r->out.data->binary     = blob;
 
206
                return WERR_OK;
 
207
        } else if (strcmp("DNSMachineName", r->in.value_name) == 0) {
 
208
                if (!lp_realm(server->ntptr->lp_ctx)) return WERR_INVALID_PARAM;
 
209
 
 
210
                *r->out.type            = REG_SZ;
 
211
                r->out.data->string     = talloc_asprintf(mem_ctx, "%s.%s",
 
212
                                                                   lp_netbios_name(server->ntptr->lp_ctx),
 
213
                                                                   lp_realm(server->ntptr->lp_ctx));
 
214
                W_ERROR_HAVE_NO_MEMORY(r->out.data->string);
 
215
                return WERR_OK;
 
216
        }
 
217
 
 
218
        return WERR_INVALID_PARAM;
 
219
}
 
220
 
 
221
/* PrintServer Form functions */
 
222
static WERROR sptr_EnumPrintServerForms(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
 
223
                                        struct spoolss_EnumForms *r)
 
224
{
 
225
        struct ldb_context *sptr_db = talloc_get_type(server->ntptr->private_data, struct ldb_context);
 
226
        struct ldb_message **msgs;
 
227
        int count;
 
228
        int i;
 
229
        union spoolss_FormInfo *info;
 
230
 
 
231
        count = sptr_db_search(sptr_db, mem_ctx,
 
232
                                ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,CN=PrintServer"),
 
233
                                &msgs, NULL, "(&(objectClass=form))");
 
234
 
 
235
        if (count == 0) return WERR_OK;
 
236
        if (count < 0) return WERR_GENERAL_FAILURE;
 
237
 
 
238
        info = talloc_array(mem_ctx, union spoolss_FormInfo, count);
 
239
        W_ERROR_HAVE_NO_MEMORY(info);
 
240
 
 
241
        switch (r->in.level) {
 
242
        case 1:
 
243
                for (i=0; i < count; i++) {
 
244
                        info[i].info1.flags             = samdb_result_uint(msgs[i], "flags", SPOOLSS_FORM_BUILTIN);
 
245
 
 
246
                        info[i].info1.form_name         = samdb_result_string(msgs[i], "form-name", NULL);
 
247
                        W_ERROR_HAVE_NO_MEMORY(info[i].info1.form_name);
 
248
 
 
249
                        info[i].info1.size.width        = samdb_result_uint(msgs[i], "size-width", 0);
 
250
                        info[i].info1.size.height       = samdb_result_uint(msgs[i], "size-height", 0);
 
251
 
 
252
                        info[i].info1.area.left         = samdb_result_uint(msgs[i], "area-left", 0);
 
253
                        info[i].info1.area.top          = samdb_result_uint(msgs[i], "area-top", 0);
 
254
                        info[i].info1.area.right        = samdb_result_uint(msgs[i], "area-right", 0);
 
255
                        info[i].info1.area.bottom       = samdb_result_uint(msgs[i], "area-bottom", 0);
 
256
                }
 
257
                break;
 
258
        default:
 
259
                return WERR_UNKNOWN_LEVEL;
 
260
        }
 
261
 
 
262
        *r->out.info    = info;
 
263
        *r->out.count   = count;
 
264
        return WERR_OK;
 
265
}
 
266
 
 
267
static WERROR sptr_AddPrintServerForm(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
 
268
                                      struct spoolss_AddForm *r)
 
269
{
 
270
        struct ldb_context *sptr_db = talloc_get_type(server->ntptr->private_data, struct ldb_context);
 
271
        struct ldb_message *msg,**msgs;
 
272
        const char * const attrs[] = {"flags", NULL };
 
273
        int count, ret;
 
274
 
 
275
        /* TODO: do checks access here
 
276
         * if (!(server->access_mask & desired_access)) {
 
277
         *      return WERR_FOOBAR;
 
278
         * }
 
279
         */
 
280
 
 
281
        switch (r->in.level) {
 
282
        case 1:
 
283
                if (!r->in.info.info1) {
 
284
                        return WERR_FOOBAR;
 
285
                }
 
286
                count = sptr_db_search(sptr_db, mem_ctx,
 
287
                                       ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,CN=PrintServer"),
 
288
                                       &msgs, attrs, "(&(form-name=%s)(objectClass=form))",
 
289
                                       r->in.info.info1->form_name);
 
290
 
 
291
                if (count == 1) return WERR_FOOBAR;
 
292
                if (count > 1) return WERR_FOOBAR;
 
293
                if (count < 0) return WERR_GENERAL_FAILURE;
 
294
 
 
295
                if (r->in.info.info1->flags != SPOOLSS_FORM_USER) {
 
296
                        return WERR_FOOBAR;
 
297
                }
 
298
 
 
299
                msg = ldb_msg_new(mem_ctx);
 
300
                W_ERROR_HAVE_NO_MEMORY(msg);
 
301
 
 
302
                /* add core elements to the ldb_message for the Form */
 
303
                msg->dn = ldb_dn_new_fmt(msg, sptr_db, "form-name=%s,CN=Forms,CN=PrintServer", r->in.info.info1->form_name);
 
304
                SET_STRING(sptr_db, msg, "objectClass", "form");
 
305
 
 
306
                SET_UINT(sptr_db, msg, "flags", r->in.info.info1->flags);
 
307
 
 
308
                SET_STRING(sptr_db, msg, "form-name", r->in.info.info1->form_name);
 
309
 
 
310
                SET_UINT(sptr_db, msg, "size-width", r->in.info.info1->size.width);
 
311
                SET_UINT(sptr_db, msg, "size-height", r->in.info.info1->size.height);
 
312
 
 
313
                SET_UINT(sptr_db, msg, "area-left", r->in.info.info1->area.left);
 
314
                SET_UINT(sptr_db, msg, "area-top", r->in.info.info1->area.top);
 
315
                SET_UINT(sptr_db, msg, "area-right", r->in.info.info1->area.right);
 
316
                SET_UINT(sptr_db, msg, "area-bottom", r->in.info.info1->area.bottom);
 
317
                break;
 
318
        default:
 
319
                return WERR_UNKNOWN_LEVEL;
 
320
        }
 
321
 
 
322
        ret = ldb_add(sptr_db, msg);
 
323
        if (ret != 0) {
 
324
                return WERR_FOOBAR;
 
325
        }
 
326
 
 
327
        return WERR_OK;
 
328
}
 
329
 
 
330
static WERROR sptr_SetPrintServerForm(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
 
331
                                      struct spoolss_SetForm *r)
 
332
{
 
333
        struct ldb_context *sptr_db = talloc_get_type(server->ntptr->private_data, struct ldb_context);
 
334
        struct ldb_message *msg,**msgs;
 
335
        const char * const attrs[] = { "flags", NULL};
 
336
        int count, ret;
 
337
        enum spoolss_FormFlags flags;
 
338
 
 
339
        /* TODO: do checks access here
 
340
         * if (!(server->access_mask & desired_access)) {
 
341
         *      return WERR_FOOBAR;
 
342
         * }
 
343
         */
 
344
 
 
345
        switch (r->in.level) {
 
346
        case 1:
 
347
                if (!r->in.info.info1) {
 
348
                        return WERR_FOOBAR;
 
349
                }
 
350
 
 
351
                count = sptr_db_search(sptr_db, mem_ctx,
 
352
                                       ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,CN=PrintServer"),
 
353
                                       &msgs, attrs, "(&(form-name=%s)(objectClass=form))",
 
354
                                       r->in.info.info1->form_name);
 
355
 
 
356
                if (count == 0) return WERR_FOOBAR;
 
357
                if (count > 1) return WERR_FOOBAR;
 
358
                if (count < 0) return WERR_GENERAL_FAILURE;
 
359
 
 
360
                flags = samdb_result_uint(msgs[0], "flags", SPOOLSS_FORM_BUILTIN);
 
361
                if (flags != SPOOLSS_FORM_USER) {
 
362
                        return WERR_FOOBAR;
 
363
                }
 
364
 
 
365
                msg = ldb_msg_new(mem_ctx);
 
366
                W_ERROR_HAVE_NO_MEMORY(msg);
 
367
 
 
368
                /* add core elements to the ldb_message for the user */
 
369
                msg->dn = msgs[0]->dn;
 
370
 
 
371
                SET_UINT(sptr_db, msg, "flags", r->in.info.info1->flags);
 
372
 
 
373
                SET_STRING(sptr_db, msg, "form-name", r->in.info.info1->form_name);
 
374
 
 
375
                SET_UINT(sptr_db, msg, "size-width", r->in.info.info1->size.width);
 
376
                SET_UINT(sptr_db, msg, "size-height", r->in.info.info1->size.height);
 
377
 
 
378
                SET_UINT(sptr_db, msg, "area-left", r->in.info.info1->area.left);
 
379
                SET_UINT(sptr_db, msg, "area-top", r->in.info.info1->area.top);
 
380
                SET_UINT(sptr_db, msg, "area-right", r->in.info.info1->area.right);
 
381
                SET_UINT(sptr_db, msg, "area-bottom", r->in.info.info1->area.bottom);
 
382
                break;
 
383
        default:
 
384
                return WERR_UNKNOWN_LEVEL;
 
385
        }
 
386
 
 
387
        ret = samdb_replace(sptr_db, mem_ctx, msg);
 
388
        if (ret != 0) {
 
389
                return WERR_FOOBAR;
 
390
        }
 
391
 
 
392
        return WERR_OK;
 
393
}
 
394
 
 
395
static WERROR sptr_DeletePrintServerForm(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx,
 
396
                                         struct spoolss_DeleteForm *r)
 
397
{
 
398
        struct ldb_context *sptr_db = talloc_get_type(server->ntptr->private_data, struct ldb_context);
 
399
        struct ldb_message **msgs;
 
400
        const char * const attrs[] = { "flags", NULL};
 
401
        int count, ret;
 
402
        enum spoolss_FormFlags flags;
 
403
 
 
404
        /* TODO: do checks access here
 
405
         * if (!(server->access_mask & desired_access)) {
 
406
         *      return WERR_FOOBAR;
 
407
         * }
 
408
         */
 
409
 
 
410
        if (!r->in.form_name) {
 
411
                return WERR_FOOBAR;
 
412
        }
 
413
 
 
414
        count = sptr_db_search(sptr_db, mem_ctx,
 
415
                               ldb_dn_new(mem_ctx, sptr_db, "CN=Forms,CN=PrintServer"),
 
416
                               &msgs, attrs, "(&(form-name=%s)(objectclass=form))",
 
417
                               r->in.form_name);
 
418
 
 
419
        if (count == 0) return WERR_FOOBAR;
 
420
        if (count > 1) return WERR_FOOBAR;
 
421
        if (count < 0) return WERR_GENERAL_FAILURE;
 
422
 
 
423
        flags = samdb_result_uint(msgs[0], "flags", SPOOLSS_FORM_BUILTIN);
 
424
        if (flags != SPOOLSS_FORM_USER) {
 
425
                return WERR_FOOBAR;
 
426
        }
 
427
 
 
428
        ret = ldb_delete(sptr_db, msgs[0]->dn);
 
429
        if (ret != 0) {
 
430
                return WERR_FOOBAR;
 
431
        }
 
432
 
 
433
        return WERR_OK;
 
434
}
 
435
 
 
436
/* PrintServer Driver functions */
 
437
static WERROR sptr_EnumPrinterDrivers(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
 
438
                                      struct spoolss_EnumPrinterDrivers *r)
 
439
{
 
440
        return WERR_OK;
 
441
}
 
442
 
 
443
static WERROR sptr_GetPrinterDriverDirectory(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
 
444
                                             struct spoolss_GetPrinterDriverDirectory *r)
 
445
{
 
446
        union spoolss_DriverDirectoryInfo *info;
 
447
        const char *prefix;
 
448
        const char *postfix;
 
449
 
 
450
        /*
 
451
         * NOTE: normally r->in.level is 1, but both w2k3 and nt4 sp6a
 
452
         *        are ignoring the r->in.level completely, so we do :-)
 
453
         */
 
454
       
 
455
        /*
 
456
         * TODO: check the server name is ours
 
457
         * - if it's a invalid UNC then return WERR_INVALID_NAME
 
458
         * - if it's the wrong host name return WERR_INVALID_PARAM
 
459
         * - if it's "" then we need to return a local WINDOWS path
 
460
         */
 
461
        if (!r->in.server || !r->in.server[0]) {
 
462
                prefix = "C:\\DRIVERS";
 
463
        } else {
 
464
                prefix = talloc_asprintf(mem_ctx, "%s\\print$", r->in.server);
 
465
                W_ERROR_HAVE_NO_MEMORY(prefix);
 
466
        }
 
467
 
 
468
        if (r->in.environment && strcmp(SPOOLSS_ARCHITECTURE_NT_X86, r->in.environment) == 0) {
 
469
                postfix = "W32X86";
 
470
        } else {
 
471
                return WERR_INVALID_ENVIRONMENT;
 
472
        }
 
473
 
 
474
        info = talloc(mem_ctx, union spoolss_DriverDirectoryInfo);
 
475
        W_ERROR_HAVE_NO_MEMORY(info);
 
476
 
 
477
        info->info1.directory_name      = talloc_asprintf(mem_ctx, "%s\\%s", prefix, postfix);
 
478
        W_ERROR_HAVE_NO_MEMORY(info->info1.directory_name);
 
479
 
 
480
        r->out.info = info;
 
481
        return WERR_OK;
 
482
}
 
483
 
 
484
/* Printer functions */
 
485
static WERROR sptr_EnumPrinters(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
 
486
                                struct spoolss_EnumPrinters *r)
 
487
{
 
488
        struct ldb_context *sptr_db = talloc_get_type(ntptr->private_data, struct ldb_context);
 
489
        struct ldb_message **msgs;
 
490
        int count;
 
491
        int i;
 
492
        union spoolss_PrinterInfo *info;
 
493
 
 
494
        count = sptr_db_search(sptr_db, mem_ctx, NULL, &msgs, NULL,
 
495
                               "(&(objectclass=printer))");
 
496
 
 
497
        if (count == 0) return WERR_OK;
 
498
        if (count < 0) return WERR_GENERAL_FAILURE;
 
499
 
 
500
        info = talloc_array(mem_ctx, union spoolss_PrinterInfo, count);
 
501
        W_ERROR_HAVE_NO_MEMORY(info);
 
502
 
 
503
        switch(r->in.level) {
 
504
        case 1:
 
505
                for (i = 0; i < count; i++) {
 
506
                        info[i].info1.flags             = samdb_result_uint(msgs[i], "flags", 0);
 
507
 
 
508
                        info[i].info1.name              = samdb_result_string(msgs[i], "name", "");
 
509
                        W_ERROR_HAVE_NO_MEMORY(info[i].info1.name);
 
510
 
 
511
                        info[i].info1.description       = samdb_result_string(msgs[i], "description", "");
 
512
                        W_ERROR_HAVE_NO_MEMORY(info[i].info1.description);
 
513
 
 
514
                        info[i].info1.comment           = samdb_result_string(msgs[i], "comment", NULL);
 
515
                }
 
516
                break;
 
517
        case 2:
 
518
                for (i = 0; i < count; i++) {
 
519
                        info[i].info2.servername        = samdb_result_string(msgs[i], "servername", "");
 
520
                        W_ERROR_HAVE_NO_MEMORY(info[i].info2.servername);
 
521
 
 
522
                        info[i].info2.printername       = samdb_result_string(msgs[i], "printername", "");
 
523
                        W_ERROR_HAVE_NO_MEMORY(info[i].info2.printername);
 
524
 
 
525
                        info[i].info2.sharename         = samdb_result_string(msgs[i], "sharename", "");
 
526
                        W_ERROR_HAVE_NO_MEMORY(info[i].info2.sharename);
 
527
 
 
528
                        info[i].info2.portname          = samdb_result_string(msgs[i], "portname", "");
 
529
                        W_ERROR_HAVE_NO_MEMORY(info[i].info2.portname);
 
530
 
 
531
                        info[i].info2.drivername        = samdb_result_string(msgs[i], "drivername", "");
 
532
                        W_ERROR_HAVE_NO_MEMORY(info[i].info2.drivername);
 
533
 
 
534
                        info[i].info2.comment           = samdb_result_string(msgs[i], "comment", NULL);
 
535
 
 
536
                        info[i].info2.location          = samdb_result_string(msgs[i], "location", NULL);
 
537
 
 
538
                        info[i].info2.devmode           = NULL;
 
539
 
 
540
                        info[i].info2.sepfile           = samdb_result_string(msgs[i], "sepfile", NULL);
 
541
 
 
542
                        info[i].info2.printprocessor    = samdb_result_string(msgs[i], "printprocessor", "");
 
543
                        W_ERROR_HAVE_NO_MEMORY(info[i].info2.printprocessor);
 
544
 
 
545
                        info[i].info2.datatype          = samdb_result_string(msgs[i], "datatype", "");
 
546
                        W_ERROR_HAVE_NO_MEMORY(info[i].info2.datatype);
 
547
 
 
548
                        info[i].info2.parameters        = samdb_result_string(msgs[i], "parameters", NULL);
 
549
 
 
550
                        info[i].info2.secdesc           = NULL;
 
551
 
 
552
                        info[i].info2.attributes        = samdb_result_uint(msgs[i], "attributes", 0);
 
553
                        info[i].info2.priority          = samdb_result_uint(msgs[i], "priority", 0);
 
554
                        info[i].info2.defaultpriority   = samdb_result_uint(msgs[i], "defaultpriority", 0);
 
555
                        info[i].info2.starttime         = samdb_result_uint(msgs[i], "starttime", 0);
 
556
                        info[i].info2.untiltime         = samdb_result_uint(msgs[i], "untiltime", 0);
 
557
                        info[i].info2.status            = samdb_result_uint(msgs[i], "status", 0);
 
558
                        info[i].info2.cjobs             = samdb_result_uint(msgs[i], "cjobs", 0);
 
559
                        info[i].info2.averageppm        = samdb_result_uint(msgs[i], "averageppm", 0);
 
560
                }
 
561
                break;
 
562
        case 4:
 
563
                for (i = 0; i < count; i++) {
 
564
                        info[i].info4.printername       = samdb_result_string(msgs[i], "printername", "");
 
565
                        W_ERROR_HAVE_NO_MEMORY(info[i].info2.printername);
 
566
 
 
567
                        info[i].info4.servername        = samdb_result_string(msgs[i], "servername", "");
 
568
                        W_ERROR_HAVE_NO_MEMORY(info[i].info2.servername);
 
569
 
 
570
                        info[i].info4.attributes        = samdb_result_uint(msgs[i], "attributes", 0);
 
571
                }
 
572
                break;
 
573
        case 5:
 
574
                for (i = 0; i < count; i++) {
 
575
                        info[i].info5.printername       = samdb_result_string(msgs[i], "name", "");
 
576
                        W_ERROR_HAVE_NO_MEMORY(info[i].info5.printername);
 
577
 
 
578
                        info[i].info5.portname          = samdb_result_string(msgs[i], "port", "");
 
579
                        W_ERROR_HAVE_NO_MEMORY(info[i].info5.portname);
 
580
 
 
581
                        info[i].info5.attributes        = samdb_result_uint(msgs[i], "attributes", 0);
 
582
                        info[i].info5.device_not_selected_timeout = samdb_result_uint(msgs[i], "device_not_selected_timeout", 0);
 
583
                        info[i].info5.transmission_retry_timeout  = samdb_result_uint(msgs[i], "transmission_retry_timeout", 0);
 
584
                }
 
585
                break;
 
586
        default:
 
587
                return WERR_UNKNOWN_LEVEL;
 
588
        }
 
589
 
 
590
        *r->out.info    = info;
 
591
        *r->out.count   = count;
 
592
        return WERR_OK;
 
593
}
 
594
 
 
595
static WERROR sptr_OpenPrinter(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
 
596
                               struct spoolss_OpenPrinterEx *r,
 
597
                               const char *printer_name,
 
598
                               struct ntptr_GenericHandle **printer)
 
599
{
 
600
        return WERR_INVALID_PRINTER_NAME;
 
601
}
 
602
 
 
603
/* port functions */
 
604
static WERROR sptr_EnumPorts(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
 
605
                             struct spoolss_EnumPorts *r)
 
606
{
 
607
        struct ldb_context *sptr_db = talloc_get_type(ntptr->private_data, struct ldb_context);
 
608
        struct ldb_message **msgs;
 
609
        int count;
 
610
        int i;
 
611
        union spoolss_PortInfo *info;
 
612
 
 
613
        count = sptr_db_search(sptr_db, mem_ctx, NULL, &msgs, NULL,
 
614
                               "(&(objectclass=port))");
 
615
 
 
616
        if (count == 0) return WERR_OK;
 
617
        if (count < 0) return WERR_GENERAL_FAILURE;
 
618
 
 
619
        info = talloc_array(mem_ctx, union spoolss_PortInfo, count);
 
620
        W_ERROR_HAVE_NO_MEMORY(info);
 
621
 
 
622
        switch (r->in.level) {
 
623
        case 1:
 
624
                for (i = 0; i < count; i++) {
 
625
                        info[i].info1.port_name         = samdb_result_string(msgs[i], "port-name", "");
 
626
                        W_ERROR_HAVE_NO_MEMORY(info[i].info1.port_name);
 
627
                }
 
628
                break;
 
629
        case 2:
 
630
                for (i=0; i < count; i++) {
 
631
                        info[i].info2.port_name         = samdb_result_string(msgs[i], "port-name", "");
 
632
                        W_ERROR_HAVE_NO_MEMORY(info[i].info2.port_name);
 
633
 
 
634
                        info[i].info2.monitor_name      = samdb_result_string(msgs[i], "monitor-name", "");
 
635
                        W_ERROR_HAVE_NO_MEMORY(info[i].info2.monitor_name);
 
636
 
 
637
                        info[i].info2.description       = samdb_result_string(msgs[i], "description", "");
 
638
                        W_ERROR_HAVE_NO_MEMORY(info[i].info2.description);
 
639
 
 
640
                        info[i].info2.port_type         = samdb_result_uint(msgs[i], "port-type", SPOOLSS_PORT_TYPE_WRITE);
 
641
                        info[i].info2.reserved          = samdb_result_uint(msgs[i], "reserved", 0);
 
642
                }
 
643
                break;
 
644
        default:
 
645
                return WERR_UNKNOWN_LEVEL;
 
646
        }
 
647
 
 
648
        *r->out.info    = info;
 
649
        *r->out.count   = count;
 
650
        return WERR_OK;
 
651
}
 
652
 
 
653
/* monitor functions */
 
654
static WERROR sptr_EnumMonitors(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
 
655
                                struct spoolss_EnumMonitors *r)
 
656
{
 
657
        struct ldb_context *sptr_db = talloc_get_type(ntptr->private_data, struct ldb_context);
 
658
        struct ldb_message **msgs;
 
659
        int count;
 
660
        int i;
 
661
        union spoolss_MonitorInfo *info;
 
662
 
 
663
        count = sptr_db_search(sptr_db, mem_ctx, NULL, &msgs, NULL,
 
664
                               "(&(objectclass=monitor))");
 
665
 
 
666
        if (count == 0) return WERR_OK;
 
667
        if (count < 0) return WERR_GENERAL_FAILURE;
 
668
 
 
669
        info = talloc_array(mem_ctx, union spoolss_MonitorInfo, count);
 
670
        W_ERROR_HAVE_NO_MEMORY(info);
 
671
 
 
672
        switch (r->in.level) {
 
673
        case 1:
 
674
                for (i = 0; i < count; i++) {
 
675
                        info[i].info1.monitor_name      = samdb_result_string(msgs[i], "monitor-name", "");
 
676
                        W_ERROR_HAVE_NO_MEMORY(info[i].info1.monitor_name);
 
677
                }
 
678
                break;
 
679
        case 2:
 
680
                for (i=0; i < count; i++) {
 
681
                        info[i].info2.monitor_name      = samdb_result_string(msgs[i], "monitor-name", "");
 
682
                        W_ERROR_HAVE_NO_MEMORY(info[i].info2.monitor_name);
 
683
 
 
684
                        info[i].info2.environment       = samdb_result_string(msgs[i], "environment", "");
 
685
                        W_ERROR_HAVE_NO_MEMORY(info[i].info2.environment);
 
686
 
 
687
                        info[i].info2.dll_name          = samdb_result_string(msgs[i], "dll-name", "");
 
688
                        W_ERROR_HAVE_NO_MEMORY(info[i].info2.dll_name);
 
689
                }
 
690
                break;
 
691
        default:
 
692
                return WERR_UNKNOWN_LEVEL;
 
693
        }
 
694
 
 
695
        *r->out.info    = info;
 
696
        *r->out.count   = count;
 
697
        return WERR_OK;
 
698
}
 
699
 
 
700
/* Printer Form functions */
 
701
static WERROR sptr_GetPrinterForm(struct ntptr_GenericHandle *printer, TALLOC_CTX *mem_ctx,
 
702
                                  struct spoolss_GetForm *r)
 
703
{
 
704
        struct ldb_context *sptr_db = talloc_get_type(printer->ntptr->private_data, struct ldb_context);
 
705
        struct ldb_message **msgs;
 
706
        struct ldb_dn *base_dn;
 
707
        int count;
 
708
        union spoolss_FormInfo *info;
 
709
 
 
710
        /* TODO: do checks access here
 
711
         * if (!(printer->access_mask & desired_access)) {
 
712
         *      return WERR_FOOBAR;
 
713
         * }
 
714
         */
 
715
 
 
716
        base_dn = ldb_dn_new_fmt(mem_ctx, sptr_db, "CN=Forms,CN=%s,CN=Printers", printer->object_name);
 
717
        W_ERROR_HAVE_NO_MEMORY(base_dn);
 
718
 
 
719
        count = sptr_db_search(sptr_db, mem_ctx, base_dn, &msgs, NULL,
 
720
                               "(&(form-name=%s)(objectClass=form))",
 
721
                               r->in.form_name);
 
722
 
 
723
        if (count == 0) return WERR_FOOBAR;
 
724
        if (count > 1) return WERR_FOOBAR;
 
725
        if (count < 0) return WERR_GENERAL_FAILURE;
 
726
 
 
727
        info = talloc(mem_ctx, union spoolss_FormInfo);
 
728
        W_ERROR_HAVE_NO_MEMORY(info);
 
729
 
 
730
        switch (r->in.level) {
 
731
        case 1:
 
732
                info->info1.flags       = samdb_result_uint(msgs[0], "flags", SPOOLSS_FORM_BUILTIN);
 
733
 
 
734
                info->info1.form_name   = samdb_result_string(msgs[0], "form-name", NULL);
 
735
                W_ERROR_HAVE_NO_MEMORY(info->info1.form_name);
 
736
 
 
737
                info->info1.size.width  = samdb_result_uint(msgs[0], "size-width", 0);
 
738
                info->info1.size.height = samdb_result_uint(msgs[0], "size-height", 0);
 
739
 
 
740
                info->info1.area.left   = samdb_result_uint(msgs[0], "area-left", 0);
 
741
                info->info1.area.top    = samdb_result_uint(msgs[0], "area-top", 0);
 
742
                info->info1.area.right  = samdb_result_uint(msgs[0], "area-right", 0);
 
743
                info->info1.area.bottom = samdb_result_uint(msgs[0], "area-bottom", 0);
 
744
                break;
 
745
        default:
 
746
                return WERR_UNKNOWN_LEVEL;
 
747
        }
 
748
 
 
749
        r->out.info     = info;
 
750
        return WERR_OK;
 
751
}
 
752
 
 
753
static WERROR sptr_GetPrintProcessorDirectory(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx,
 
754
                                              struct spoolss_GetPrintProcessorDirectory *r)
 
755
{
 
756
        union spoolss_PrintProcessorDirectoryInfo *info;
 
757
        const char *prefix;
 
758
        const char *postfix;
 
759
 
 
760
        /*
 
761
         * NOTE: normally r->in.level is 1, but both w2k3 and nt4 sp6a
 
762
         *        are ignoring the r->in.level completely, so we do :-)
 
763
         */
 
764
 
 
765
        /*
 
766
         * TODO: check the server name is ours
 
767
         * - if it's a invalid UNC then return WERR_INVALID_NAME
 
768
         * - if it's the wrong host name return WERR_INVALID_PARAM
 
769
         * - if it's "" then we need to return a local WINDOWS path
 
770
         */
 
771
        if (!r->in.server || !r->in.server[0]) {
 
772
                prefix = "C:\\PRTPROCS";
 
773
        } else {
 
774
                prefix = talloc_asprintf(mem_ctx, "%s\\prnproc$", r->in.server);
 
775
                W_ERROR_HAVE_NO_MEMORY(prefix);
 
776
        }
 
777
 
 
778
        if (r->in.environment && strcmp(SPOOLSS_ARCHITECTURE_NT_X86, r->in.environment) == 0) {
 
779
                postfix = "W32X86";
 
780
        } else {
 
781
                return WERR_INVALID_ENVIRONMENT;
 
782
        }
 
783
 
 
784
        info = talloc(mem_ctx, union spoolss_PrintProcessorDirectoryInfo);
 
785
        W_ERROR_HAVE_NO_MEMORY(info);
 
786
 
 
787
        info->info1.directory_name      = talloc_asprintf(mem_ctx, "%s\\%s", prefix, postfix);
 
788
        W_ERROR_HAVE_NO_MEMORY(info->info1.directory_name);
 
789
 
 
790
        r->out.info = info;
 
791
        return WERR_OK;
 
792
}
 
793
 
 
794
 
 
795
/*
 
796
  initialialise the simble ldb backend, registering ourselves with the ntptr subsystem
 
797
 */
 
798
static const struct ntptr_ops ntptr_simple_ldb_ops = {
 
799
        .name                           = "simple_ldb",
 
800
        .init_context                   = sptr_init_context,
 
801
 
 
802
        /* PrintServer functions */
 
803
        .OpenPrintServer                = sptr_OpenPrintServer,
 
804
/*      .XcvDataPrintServer             = sptr_XcvDataPrintServer,
 
805
*/
 
806
        /* PrintServer PrinterData functions */
 
807
/*      .EnumPrintServerData            = sptr_EnumPrintServerData,
 
808
*/      .GetPrintServerData             = sptr_GetPrintServerData,
 
809
/*      .SetPrintServerData             = sptr_SetPrintServerData,
 
810
        .DeletePrintServerData          = sptr_DeletePrintServerData,
 
811
*/
 
812
        /* PrintServer Form functions */
 
813
        .EnumPrintServerForms           = sptr_EnumPrintServerForms,
 
814
        .AddPrintServerForm             = sptr_AddPrintServerForm,
 
815
        .SetPrintServerForm             = sptr_SetPrintServerForm,
 
816
        .DeletePrintServerForm          = sptr_DeletePrintServerForm,
 
817
 
 
818
        /* PrintServer Driver functions */
 
819
        .EnumPrinterDrivers             = sptr_EnumPrinterDrivers,
 
820
/*      .AddPrinterDriver               = sptr_AddPrinterDriver,
 
821
        .DeletePrinterDriver            = sptr_DeletePrinterDriver,
 
822
*/      .GetPrinterDriverDirectory      = sptr_GetPrinterDriverDirectory,
 
823
 
 
824
        /* Port functions */
 
825
        .EnumPorts                      = sptr_EnumPorts,
 
826
/*      .OpenPort                       = sptr_OpenPort,
 
827
        .XcvDataPort                    = sptr_XcvDataPort,
 
828
*/
 
829
        /* Monitor functions */
 
830
        .EnumMonitors                   = sptr_EnumMonitors,
 
831
/*      .OpenMonitor                    = sptr_OpenMonitor,
 
832
        .XcvDataMonitor                 = sptr_XcvDataMonitor,
 
833
*/
 
834
        /* PrintProcessor functions */
 
835
/*      .EnumPrintProcessors            = sptr_EnumPrintProcessors,
 
836
*/
 
837
        .GetPrintProcessorDirectory     = sptr_GetPrintProcessorDirectory,
 
838
 
 
839
        /* Printer functions */
 
840
        .EnumPrinters                   = sptr_EnumPrinters,
 
841
        .OpenPrinter                    = sptr_OpenPrinter,
 
842
/*      .AddPrinter                     = sptr_AddPrinter,
 
843
        .GetPrinter                     = sptr_GetPrinter,
 
844
        .SetPrinter                     = sptr_SetPrinter,
 
845
        .DeletePrinter                  = sptr_DeletePrinter,
 
846
        .XcvDataPrinter                 = sptr_XcvDataPrinter,
 
847
*/
 
848
        /* Printer Driver functions */
 
849
/*      .GetPrinterDriver               = sptr_GetPrinterDriver,
 
850
*/
 
851
        /* Printer PrinterData functions */
 
852
/*      .EnumPrinterData                = sptr_EnumPrinterData,
 
853
        .GetPrinterData                 = sptr_GetPrinterData,
 
854
        .SetPrinterData                 = sptr_SetPrinterData,
 
855
        .DeletePrinterData              = sptr_DeletePrinterData,
 
856
*/
 
857
        /* Printer Form functions */
 
858
/*      .EnumPrinterForms               = sptr_EnumPrinterForms,
 
859
        .AddPrinterForm                 = sptr_AddPrinterForm,
 
860
*/      .GetPrinterForm                 = sptr_GetPrinterForm,
 
861
/*      .SetPrinterForm                 = sptr_SetPrinterForm,
 
862
        .DeletePrinterForm              = sptr_DeletePrinterForm,
 
863
*/
 
864
        /* Printer Job functions */
 
865
/*      .EnumJobs                       = sptr_EnumJobs,
 
866
        .AddJob                         = sptr_AddJob,
 
867
        .ScheduleJob                    = sptr_ScheduleJob,
 
868
        .GetJob                         = sptr_GetJob,
 
869
        .SetJob                         = sptr_SetJob,
 
870
*/
 
871
        /* Printer Printing functions */
 
872
/*      .StartDocPrinter                = sptr_StartDocPrinter,
 
873
        .EndDocPrinter                  = sptr_EndDocPrinter,
 
874
        .StartPagePrinter               = sptr_StartPagePrinter,
 
875
        .EndPagePrinter                 = sptr_EndPagePrinter,
 
876
        .WritePrinter                   = sptr_WritePrinter,
 
877
        .ReadPrinter                    = sptr_ReadPrinter,
 
878
*/};
 
879
 
 
880
NTSTATUS ntptr_simple_ldb_init(void)
 
881
{
 
882
        NTSTATUS ret;
 
883
 
 
884
        ret = ntptr_register(&ntptr_simple_ldb_ops);
 
885
        if (!NT_STATUS_IS_OK(ret)) {
 
886
                DEBUG(0,("Failed to register NTPTR '%s' backend!\n",
 
887
                         ntptr_simple_ldb_ops.name));
 
888
        }
 
889
 
 
890
        return ret;
 
891
}