r6303: Setting up for 3.0.15pre1
[Samba.git] / source / libads / ldap_printer.c
blob61275e40d11de997f7c71c1c83b8ef09e9a2725e
1 /*
2 Unix SMB/CIFS implementation.
3 ads (active directory) printer utility library
4 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
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 2 of the License, or
9 (at your option) any later version.
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.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "includes.h"
23 #ifdef HAVE_ADS
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.
30 ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res,
31 const char *printer, const char *servername)
33 ADS_STATUS status;
34 char *srv_dn, **srv_cn, *s;
35 const char *attrs[] = {"*", "nTSecurityDescriptor", NULL};
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;
43 srv_dn = ldap_get_dn(ads->ld, *res);
44 srv_cn = ldap_explode_dn(srv_dn, 1);
45 ads_msgfree(ads, *res);
47 asprintf(&s, "(cn=%s-%s)", srv_cn[0], printer);
48 status = ads_search(ads, res, s, attrs);
50 ldap_memfree(srv_dn);
51 ldap_value_free(srv_cn);
52 free(s);
53 return status;
56 ADS_STATUS ads_find_printers(ADS_STRUCT *ads, void **res)
58 char *ldap_expr;
59 const char *attrs[] = { "objectClass", "printerName", "location", "driverName",
60 "serverName", "description", NULL };
62 /* For the moment only display all printers */
64 ldap_expr =
65 CONST_DISCARD(char *,
66 "(&(!(showInAdvancedViewOnly=TRUE))(uncName=*)"
67 "(objectCategory=printQueue))");
69 return ads_search(ads, res, ldap_expr, attrs);
73 modify a printer entry in the directory
75 ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn,
76 TALLOC_CTX *ctx, const ADS_MODLIST *mods)
78 return ads_gen_mod(ads, prt_dn, *mods);
82 add a printer to the directory
84 ADS_STATUS ads_add_printer_entry(ADS_STRUCT *ads, char *prt_dn,
85 TALLOC_CTX *ctx, ADS_MODLIST *mods)
87 ads_mod_str(ctx, mods, "objectClass", "printQueue");
88 return ads_gen_add(ads, prt_dn, *mods);
92 map a REG_SZ to an ldap mod
94 static BOOL map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods,
95 const REGISTRY_VALUE *value)
97 char *str_value = NULL;
98 ADS_STATUS status;
100 if (value->type != REG_SZ)
101 return False;
103 if (value->size && *((smb_ucs2_t *) value->data_p)) {
104 pull_ucs2_talloc(ctx, &str_value, (const smb_ucs2_t *) value->data_p);
105 status = ads_mod_str(ctx, mods, value->valuename, str_value);
106 return ADS_ERR_OK(status);
108 return True;
113 map a REG_DWORD to an ldap mod
115 static BOOL map_dword(TALLOC_CTX *ctx, ADS_MODLIST *mods,
116 const REGISTRY_VALUE *value)
118 char *str_value = NULL;
119 ADS_STATUS status;
121 if (value->type != REG_DWORD)
122 return False;
123 str_value = talloc_asprintf(ctx, "%d", *((uint32 *) value->data_p));
124 status = ads_mod_str(ctx, mods, value->valuename, str_value);
125 return ADS_ERR_OK(status);
129 map a boolean REG_BINARY to an ldap mod
131 static BOOL map_bool(TALLOC_CTX *ctx, ADS_MODLIST *mods,
132 const REGISTRY_VALUE *value)
134 char *str_value;
135 ADS_STATUS status;
137 if ((value->type != REG_BINARY) || (value->size != 1))
138 return False;
139 str_value = talloc_asprintf(ctx, "%s",
140 *(value->data_p) ? "TRUE" : "FALSE");
141 status = ads_mod_str(ctx, mods, value->valuename, str_value);
142 return ADS_ERR_OK(status);
146 map a REG_MULTI_SZ to an ldap mod
148 static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods,
149 const REGISTRY_VALUE *value)
151 char **str_values = NULL;
152 smb_ucs2_t *cur_str = (smb_ucs2_t *) value->data_p;
153 uint32 size = 0, num_vals = 0, i=0;
154 ADS_STATUS status;
156 if (value->type != REG_MULTI_SZ)
157 return False;
159 while(cur_str && *cur_str && (size < value->size)) {
160 size += 2 * (strlen_w(cur_str) + 1);
161 cur_str += strlen_w(cur_str) + 1;
162 num_vals++;
165 if (num_vals) {
166 str_values = TALLOC_ARRAY(ctx, char *, num_vals + 1);
167 memset(str_values, '\0',
168 (num_vals + 1) * sizeof(char *));
170 cur_str = (smb_ucs2_t *) value->data_p;
171 for (i=0; i < num_vals; i++)
172 cur_str += pull_ucs2_talloc(ctx, &str_values[i],
173 cur_str);
175 status = ads_mod_strlist(ctx, mods, value->valuename,
176 (const char **) str_values);
177 return ADS_ERR_OK(status);
179 return True;
182 struct valmap_to_ads {
183 const char *valname;
184 BOOL (*fn)(TALLOC_CTX *, ADS_MODLIST *, const REGISTRY_VALUE *);
188 map a REG_SZ to an ldap mod
190 static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods,
191 REGISTRY_VALUE *value)
193 const struct valmap_to_ads map[] = {
194 {SPOOL_REG_ASSETNUMBER, map_sz},
195 {SPOOL_REG_BYTESPERMINUTE, map_dword},
196 {SPOOL_REG_DEFAULTPRIORITY, map_dword},
197 {SPOOL_REG_DESCRIPTION, map_sz},
198 {SPOOL_REG_DRIVERNAME, map_sz},
199 {SPOOL_REG_DRIVERVERSION, map_dword},
200 {SPOOL_REG_FLAGS, map_dword},
201 {SPOOL_REG_LOCATION, map_sz},
202 {SPOOL_REG_OPERATINGSYSTEM, map_sz},
203 {SPOOL_REG_OPERATINGSYSTEMHOTFIX, map_sz},
204 {SPOOL_REG_OPERATINGSYSTEMSERVICEPACK, map_sz},
205 {SPOOL_REG_OPERATINGSYSTEMVERSION, map_sz},
206 {SPOOL_REG_PORTNAME, map_multi_sz},
207 {SPOOL_REG_PRINTATTRIBUTES, map_dword},
208 {SPOOL_REG_PRINTBINNAMES, map_multi_sz},
209 {SPOOL_REG_PRINTCOLLATE, map_bool},
210 {SPOOL_REG_PRINTCOLOR, map_bool},
211 {SPOOL_REG_PRINTDUPLEXSUPPORTED, map_bool},
212 {SPOOL_REG_PRINTENDTIME, map_dword},
213 {SPOOL_REG_PRINTFORMNAME, map_sz},
214 {SPOOL_REG_PRINTKEEPPRINTEDJOBS, map_bool},
215 {SPOOL_REG_PRINTLANGUAGE, map_multi_sz},
216 {SPOOL_REG_PRINTMACADDRESS, map_sz},
217 {SPOOL_REG_PRINTMAXCOPIES, map_sz},
218 {SPOOL_REG_PRINTMAXRESOLUTIONSUPPORTED, map_dword},
219 {SPOOL_REG_PRINTMAXXEXTENT, map_dword},
220 {SPOOL_REG_PRINTMAXYEXTENT, map_dword},
221 {SPOOL_REG_PRINTMEDIAREADY, map_multi_sz},
222 {SPOOL_REG_PRINTMEDIASUPPORTED, map_multi_sz},
223 {SPOOL_REG_PRINTMEMORY, map_dword},
224 {SPOOL_REG_PRINTMINXEXTENT, map_dword},
225 {SPOOL_REG_PRINTMINYEXTENT, map_dword},
226 {SPOOL_REG_PRINTNETWORKADDRESS, map_sz},
227 {SPOOL_REG_PRINTNOTIFY, map_sz},
228 {SPOOL_REG_PRINTNUMBERUP, map_dword},
229 {SPOOL_REG_PRINTORIENTATIONSSUPPORTED, map_multi_sz},
230 {SPOOL_REG_PRINTOWNER, map_sz},
231 {SPOOL_REG_PRINTPAGESPERMINUTE, map_dword},
232 {SPOOL_REG_PRINTRATE, map_dword},
233 {SPOOL_REG_PRINTRATEUNIT, map_sz},
234 {SPOOL_REG_PRINTSEPARATORFILE, map_sz},
235 {SPOOL_REG_PRINTSHARENAME, map_sz},
236 {SPOOL_REG_PRINTSPOOLING, map_sz},
237 {SPOOL_REG_PRINTSTAPLINGSUPPORTED, map_bool},
238 {SPOOL_REG_PRINTSTARTTIME, map_dword},
239 {SPOOL_REG_PRINTSTATUS, map_sz},
240 {SPOOL_REG_PRIORITY, map_dword},
241 {SPOOL_REG_SERVERNAME, map_sz},
242 {SPOOL_REG_SHORTSERVERNAME, map_sz},
243 {SPOOL_REG_UNCNAME, map_sz},
244 {SPOOL_REG_URL, map_sz},
245 {SPOOL_REG_VERSIONNUMBER, map_dword},
246 {NULL, NULL}
248 int i;
250 for (i=0; map[i].valname; i++) {
251 if (StrCaseCmp(map[i].valname, value->valuename) == 0) {
252 if (!map[i].fn(ctx, mods, value)) {
253 DEBUG(5, ("Add of value %s to modlist failed\n", value->valuename));
254 } else {
255 DEBUG(7, ("Mapped value %s\n", value->valuename));
263 WERROR get_remote_printer_publishing_data(struct cli_state *cli,
264 TALLOC_CTX *mem_ctx,
265 ADS_MODLIST *mods,
266 const char *printer)
268 WERROR result;
269 char *printername, *servername;
270 REGVAL_CTR dsdriver_ctr, dsspooler_ctr;
271 BOOL got_dsdriver = False, got_dsspooler = False;
272 uint32 needed, i;
273 POLICY_HND pol;
275 asprintf(&servername, "\\\\%s", cli->desthost);
276 asprintf(&printername, "%s\\%s", servername, printer);
277 if (!servername || !printername) {
278 DEBUG(3, ("Insufficient memory\n"));
279 return WERR_NOMEM;
282 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
283 "", MAXIMUM_ALLOWED_ACCESS,
284 servername, cli->user_name, &pol);
285 if (!W_ERROR_IS_OK(result)) {
286 DEBUG(3, ("Unable to open printer %s, error is %s.\n",
287 printername, dos_errstr(result)));
288 return result;
291 result = cli_spoolss_enumprinterdataex(cli, mem_ctx, 0, &needed,
292 &pol, SPOOL_DSDRIVER_KEY, NULL);
294 if (W_ERROR_V(result) == ERRmoredata)
295 result = cli_spoolss_enumprinterdataex(cli, mem_ctx, needed,
296 NULL, &pol,
297 SPOOL_DSDRIVER_KEY,
298 &dsdriver_ctr);
300 if (!W_ERROR_IS_OK(result)) {
301 DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
302 printername, dos_errstr(result)));
303 } else {
305 /* Have the data we need now, so start building */
306 got_dsdriver = True;
307 for (i=0; i < dsdriver_ctr.num_values; i++)
308 map_regval_to_ads(mem_ctx, mods,
309 dsdriver_ctr.values[i]);
312 result = cli_spoolss_enumprinterdataex(cli, mem_ctx, 0, &needed,
313 &pol, SPOOL_DSSPOOLER_KEY,
314 NULL);
316 if (W_ERROR_V(result) == ERRmoredata)
317 result = cli_spoolss_enumprinterdataex(cli, mem_ctx, needed,
318 NULL, &pol,
319 SPOOL_DSSPOOLER_KEY,
320 &dsspooler_ctr);
322 if (!W_ERROR_IS_OK(result)) {
323 DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
324 printername, dos_errstr(result)));
325 } else {
326 got_dsspooler = True;
327 for (i=0; i < dsspooler_ctr.num_values; i++)
328 map_regval_to_ads(mem_ctx, mods,
329 dsspooler_ctr.values[i]);
332 ads_mod_str(mem_ctx, mods, SPOOL_REG_PRINTERNAME, printer);
334 if (got_dsdriver) regval_ctr_destroy(&dsdriver_ctr);
335 if (got_dsspooler) regval_ctr_destroy(&dsspooler_ctr);
336 cli_spoolss_close_printer(cli, mem_ctx, &pol);
338 return result;
341 BOOL get_local_printer_publishing_data(TALLOC_CTX *mem_ctx,
342 ADS_MODLIST *mods,
343 NT_PRINTER_DATA *data)
345 uint32 key,val;
347 for (key=0; key < data->num_keys; key++) {
348 REGVAL_CTR ctr = data->keys[key].values;
349 for (val=0; val < ctr.num_values; val++)
350 map_regval_to_ads(mem_ctx, mods, ctr.values[val]);
352 return True;
355 #endif