source: branches/samba-3.3.x/source/libads/ldap_printer.c

Last change on this file was 221, checked in by Herwig Bauernfeind, 16 years ago

Update Samba 3.3 to 3.3.1

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