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

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

Update 3.2 branch to 3.2.9

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