source: vendor/3.5.0/source3/libads/ldap_printer.c

Last change on this file was 414, checked in by Herwig Bauernfeind, 15 years ago

Samba 3.5.0: Initial import

File size: 10.8 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 ads (active directory) printer utility library
4 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#include "includes.h"
21#include "../librpc/gen_ndr/cli_spoolss.h"
22
23#ifdef HAVE_ADS
24
25/*
26 find a printer given the name and the hostname
27 Note that results "res" may be allocated on return so that the
28 results can be used. It should be freed using ads_msgfree.
29*/
30 ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, LDAPMessage **res,
31 const char *printer,
32 const char *servername)
33{
34 ADS_STATUS status;
35 char *srv_dn, **srv_cn, *s = NULL;
36 const char *attrs[] = {"*", "nTSecurityDescriptor", NULL};
37
38 status = ads_find_machine_acct(ads, res, servername);
39 if (!ADS_ERR_OK(status)) {
40 DEBUG(1, ("ads_find_printer_on_server: cannot find host %s in ads\n",
41 servername));
42 return status;
43 }
44 if (ads_count_replies(ads, *res) != 1) {
45 if (res) {
46 ads_msgfree(ads, *res);
47 *res = NULL;
48 }
49 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
50 }
51 srv_dn = ldap_get_dn(ads->ldap.ld, *res);
52 if (srv_dn == NULL) {
53 if (res) {
54 ads_msgfree(ads, *res);
55 *res = NULL;
56 }
57 return ADS_ERROR(LDAP_NO_MEMORY);
58 }
59 srv_cn = ldap_explode_dn(srv_dn, 1);
60 if (srv_cn == NULL) {
61 ldap_memfree(srv_dn);
62 if (res) {
63 ads_msgfree(ads, *res);
64 *res = NULL;
65 }
66 return ADS_ERROR(LDAP_INVALID_DN_SYNTAX);
67 }
68 if (res) {
69 ads_msgfree(ads, *res);
70 *res = NULL;
71 }
72
73 if (asprintf(&s, "(cn=%s-%s)", srv_cn[0], printer) == -1) {
74 ldap_memfree(srv_dn);
75 return ADS_ERROR(LDAP_NO_MEMORY);
76 }
77 status = ads_search(ads, res, s, attrs);
78
79 ldap_memfree(srv_dn);
80 ldap_value_free(srv_cn);
81 SAFE_FREE(s);
82 return status;
83}
84
85 ADS_STATUS ads_find_printers(ADS_STRUCT *ads, LDAPMessage **res)
86{
87 const char *ldap_expr;
88 const char *attrs[] = { "objectClass", "printerName", "location", "driverName",
89 "serverName", "description", NULL };
90
91 /* For the moment only display all printers */
92
93 ldap_expr = "(&(!(showInAdvancedViewOnly=TRUE))(uncName=*)"
94 "(objectCategory=printQueue))";
95
96 return ads_search(ads, res, ldap_expr, attrs);
97}
98
99/*
100 modify a printer entry in the directory
101*/
102ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn,
103 TALLOC_CTX *ctx, const ADS_MODLIST *mods)
104{
105 return ads_gen_mod(ads, prt_dn, *mods);
106}
107
108/*
109 add a printer to the directory
110*/
111ADS_STATUS ads_add_printer_entry(ADS_STRUCT *ads, char *prt_dn,
112 TALLOC_CTX *ctx, ADS_MODLIST *mods)
113{
114 ads_mod_str(ctx, mods, "objectClass", "printQueue");
115 return ads_gen_add(ads, prt_dn, *mods);
116}
117
118/*
119 map a REG_SZ to an ldap mod
120*/
121static bool map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods,
122 const struct regval_blob *value)
123{
124 char *str_value = NULL;
125 size_t converted_size;
126 ADS_STATUS status;
127
128 if (value->type != REG_SZ)
129 return false;
130
131 if (value->size && *((smb_ucs2_t *) value->data_p)) {
132 if (!pull_ucs2_talloc(ctx, &str_value,
133 (const smb_ucs2_t *) value->data_p,
134 &converted_size))
135 {
136 return false;
137 }
138 status = ads_mod_str(ctx, mods, value->valuename, str_value);
139 return ADS_ERR_OK(status);
140 }
141 return true;
142
143}
144
145/*
146 map a REG_DWORD to an ldap mod
147*/
148static bool map_dword(TALLOC_CTX *ctx, ADS_MODLIST *mods,
149 const struct regval_blob *value)
150{
151 char *str_value = NULL;
152 ADS_STATUS status;
153
154 if (value->type != REG_DWORD)
155 return False;
156 str_value = talloc_asprintf(ctx, "%d", *((uint32 *) value->data_p));
157 if (!str_value) {
158 return False;
159 }
160 status = ads_mod_str(ctx, mods, value->valuename, str_value);
161 return ADS_ERR_OK(status);
162}
163
164/*
165 map a boolean REG_BINARY to an ldap mod
166*/
167static bool map_bool(TALLOC_CTX *ctx, ADS_MODLIST *mods,
168 const struct regval_blob *value)
169{
170 char *str_value;
171 ADS_STATUS status;
172
173 if ((value->type != REG_BINARY) || (value->size != 1))
174 return False;
175 str_value = talloc_asprintf(ctx, "%s",
176 *(value->data_p) ? "TRUE" : "FALSE");
177 if (!str_value) {
178 return False;
179 }
180 status = ads_mod_str(ctx, mods, value->valuename, str_value);
181 return ADS_ERR_OK(status);
182}
183
184/*
185 map a REG_MULTI_SZ to an ldap mod
186*/
187static bool map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods,
188 const struct regval_blob *value)
189{
190 char **str_values = NULL;
191 size_t converted_size;
192 smb_ucs2_t *cur_str = (smb_ucs2_t *) value->data_p;
193 uint32 size = 0, num_vals = 0, i=0;
194 ADS_STATUS status;
195
196 if (value->type != REG_MULTI_SZ)
197 return False;
198
199 while(cur_str && *cur_str && (size < value->size)) {
200 size += 2 * (strlen_w(cur_str) + 1);
201 cur_str += strlen_w(cur_str) + 1;
202 num_vals++;
203 };
204
205 if (num_vals) {
206 str_values = TALLOC_ARRAY(ctx, char *, num_vals + 1);
207 if (!str_values) {
208 return False;
209 }
210 memset(str_values, '\0',
211 (num_vals + 1) * sizeof(char *));
212
213 cur_str = (smb_ucs2_t *) value->data_p;
214 for (i=0; i < num_vals; i++) {
215 cur_str += pull_ucs2_talloc(ctx, &str_values[i],
216 cur_str, &converted_size) ?
217 converted_size : (size_t)-1;
218 }
219
220 status = ads_mod_strlist(ctx, mods, value->valuename,
221 (const char **) str_values);
222 return ADS_ERR_OK(status);
223 }
224 return True;
225}
226
227struct valmap_to_ads {
228 const char *valname;
229 bool (*fn)(TALLOC_CTX *, ADS_MODLIST *, const struct regval_blob *);
230};
231
232/*
233 map a REG_SZ to an ldap mod
234*/
235static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods,
236 struct regval_blob *value)
237{
238 const struct valmap_to_ads map[] = {
239 {SPOOL_REG_ASSETNUMBER, map_sz},
240 {SPOOL_REG_BYTESPERMINUTE, map_dword},
241 {SPOOL_REG_DEFAULTPRIORITY, map_dword},
242 {SPOOL_REG_DESCRIPTION, map_sz},
243 {SPOOL_REG_DRIVERNAME, map_sz},
244 {SPOOL_REG_DRIVERVERSION, map_dword},
245 {SPOOL_REG_FLAGS, map_dword},
246 {SPOOL_REG_LOCATION, map_sz},
247 {SPOOL_REG_OPERATINGSYSTEM, map_sz},
248 {SPOOL_REG_OPERATINGSYSTEMHOTFIX, map_sz},
249 {SPOOL_REG_OPERATINGSYSTEMSERVICEPACK, map_sz},
250 {SPOOL_REG_OPERATINGSYSTEMVERSION, map_sz},
251 {SPOOL_REG_PORTNAME, map_multi_sz},
252 {SPOOL_REG_PRINTATTRIBUTES, map_dword},
253 {SPOOL_REG_PRINTBINNAMES, map_multi_sz},
254 {SPOOL_REG_PRINTCOLLATE, map_bool},
255 {SPOOL_REG_PRINTCOLOR, map_bool},
256 {SPOOL_REG_PRINTDUPLEXSUPPORTED, map_bool},
257 {SPOOL_REG_PRINTENDTIME, map_dword},
258 {SPOOL_REG_PRINTFORMNAME, map_sz},
259 {SPOOL_REG_PRINTKEEPPRINTEDJOBS, map_bool},
260 {SPOOL_REG_PRINTLANGUAGE, map_multi_sz},
261 {SPOOL_REG_PRINTMACADDRESS, map_sz},
262 {SPOOL_REG_PRINTMAXCOPIES, map_sz},
263 {SPOOL_REG_PRINTMAXRESOLUTIONSUPPORTED, map_dword},
264 {SPOOL_REG_PRINTMAXXEXTENT, map_dword},
265 {SPOOL_REG_PRINTMAXYEXTENT, map_dword},
266 {SPOOL_REG_PRINTMEDIAREADY, map_multi_sz},
267 {SPOOL_REG_PRINTMEDIASUPPORTED, map_multi_sz},
268 {SPOOL_REG_PRINTMEMORY, map_dword},
269 {SPOOL_REG_PRINTMINXEXTENT, map_dword},
270 {SPOOL_REG_PRINTMINYEXTENT, map_dword},
271 {SPOOL_REG_PRINTNETWORKADDRESS, map_sz},
272 {SPOOL_REG_PRINTNOTIFY, map_sz},
273 {SPOOL_REG_PRINTNUMBERUP, map_dword},
274 {SPOOL_REG_PRINTORIENTATIONSSUPPORTED, map_multi_sz},
275 {SPOOL_REG_PRINTOWNER, map_sz},
276 {SPOOL_REG_PRINTPAGESPERMINUTE, map_dword},
277 {SPOOL_REG_PRINTRATE, map_dword},
278 {SPOOL_REG_PRINTRATEUNIT, map_sz},
279 {SPOOL_REG_PRINTSEPARATORFILE, map_sz},
280 {SPOOL_REG_PRINTSHARENAME, map_sz},
281 {SPOOL_REG_PRINTSPOOLING, map_sz},
282 {SPOOL_REG_PRINTSTAPLINGSUPPORTED, map_bool},
283 {SPOOL_REG_PRINTSTARTTIME, map_dword},
284 {SPOOL_REG_PRINTSTATUS, map_sz},
285 {SPOOL_REG_PRIORITY, map_dword},
286 {SPOOL_REG_SERVERNAME, map_sz},
287 {SPOOL_REG_SHORTSERVERNAME, map_sz},
288 {SPOOL_REG_UNCNAME, map_sz},
289 {SPOOL_REG_URL, map_sz},
290 {SPOOL_REG_VERSIONNUMBER, map_dword},
291 {NULL, NULL}
292 };
293 int i;
294
295 for (i=0; map[i].valname; i++) {
296 if (StrCaseCmp(map[i].valname, value->valuename) == 0) {
297 if (!map[i].fn(ctx, mods, value)) {
298 DEBUG(5, ("Add of value %s to modlist failed\n", value->valuename));
299 } else {
300 DEBUG(7, ("Mapped value %s\n", value->valuename));
301 }
302
303 }
304 }
305}
306
307
308WERROR get_remote_printer_publishing_data(struct rpc_pipe_client *cli,
309 TALLOC_CTX *mem_ctx,
310 ADS_MODLIST *mods,
311 const char *printer)
312{
313 WERROR result;
314 char *printername;
315 struct spoolss_PrinterEnumValues *info;
316 uint32_t count;
317 uint32 i;
318 struct policy_handle pol;
319
320 if ((asprintf(&printername, "%s\\%s", cli->srv_name_slash, printer) == -1)) {
321 DEBUG(3, ("Insufficient memory\n"));
322 return WERR_NOMEM;
323 }
324
325 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
326 printername,
327 SEC_FLAG_MAXIMUM_ALLOWED,
328 &pol);
329 if (!W_ERROR_IS_OK(result)) {
330 DEBUG(3, ("Unable to open printer %s, error is %s.\n",
331 printername, win_errstr(result)));
332 SAFE_FREE(printername);
333 return result;
334 }
335
336 result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol,
337 SPOOL_DSDRIVER_KEY,
338 0,
339 &count,
340 &info);
341
342 if (!W_ERROR_IS_OK(result)) {
343 DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
344 printername, win_errstr(result)));
345 } else {
346 /* Have the data we need now, so start building */
347 for (i=0; i < count; i++) {
348 struct regval_blob v;
349 DATA_BLOB blob;
350
351 result = push_spoolss_PrinterData(mem_ctx, &blob,
352 info[i].type,
353 info[i].data);
354 if (W_ERROR_IS_OK(result)) {
355 fstrcpy(v.valuename, info[i].value_name);
356 v.type = info[i].type;
357 v.data_p = blob.data;
358 v.size = blob.length;
359
360 map_regval_to_ads(mem_ctx, mods, &v);
361 }
362 }
363 }
364
365 result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol,
366 SPOOL_DSSPOOLER_KEY,
367 0,
368 &count,
369 &info);
370 if (!W_ERROR_IS_OK(result)) {
371 DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
372 printername, win_errstr(result)));
373 } else {
374 for (i=0; i < count; i++) {
375 struct regval_blob v;
376 DATA_BLOB blob = data_blob_null;
377
378 result = push_spoolss_PrinterData(mem_ctx, &blob,
379 info[i].type,
380 info[i].data);
381 if (W_ERROR_IS_OK(result)) {
382 fstrcpy(v.valuename, info[i].value_name);
383 v.type = info[i].type;
384 v.data_p = blob.data;
385 v.size = blob.length;
386
387 map_regval_to_ads(mem_ctx, mods, &v);
388 }
389 }
390 }
391
392 ads_mod_str(mem_ctx, mods, SPOOL_REG_PRINTERNAME, printer);
393
394 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
395 SAFE_FREE(printername);
396
397 return result;
398}
399
400bool get_local_printer_publishing_data(TALLOC_CTX *mem_ctx,
401 ADS_MODLIST *mods,
402 NT_PRINTER_DATA *data)
403{
404 uint32 key,val;
405
406 for (key=0; key < data->num_keys; key++) {
407 struct regval_ctr *ctr = data->keys[key].values;
408 for (val=0; val < ctr->num_values; val++)
409 map_regval_to_ads(mem_ctx, mods, ctr->values[val]);
410 }
411 return True;
412}
413
414#endif
Note: See TracBrowser for help on using the repository browser.