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.
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)
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",
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);
51 ldap_value_free(srv_cn);
56 ADS_STATUS ads_find_printers(ADS_STRUCT *ads, void **res)
59 const char *attrs[] = { "objectClass", "printerName", "location", "driverName",
60 "serverName", "description", NULL };
62 /* For the moment only display all printers */
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;
100 if (value->type != REG_SZ)
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);
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;
121 if (value->type != REG_DWORD)
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)
137 if ((value->type != REG_BINARY) || (value->size != 1))
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;
156 if (value->type != REG_MULTI_SZ)
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;
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],
175 status = ads_mod_strlist(ctx, mods, value->valuename,
176 (const char **) str_values);
177 return ADS_ERR_OK(status);
182 struct valmap_to_ads {
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},
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));
255 DEBUG(7, ("Mapped value %s\n", value->valuename));
263 WERROR get_remote_printer_publishing_data(struct cli_state *cli,
269 char *printername, *servername;
270 REGVAL_CTR dsdriver_ctr, dsspooler_ctr;
271 BOOL got_dsdriver = False, got_dsspooler = False;
275 asprintf(&servername, "\\\\%s", cli->desthost);
276 asprintf(&printername, "%s\\%s", servername, printer);
277 if (!servername || !printername) {
278 DEBUG(3, ("Insufficient memory\n"));
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)));
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,
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)));
305 /* Have the data we need now, so start building */
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,
316 if (W_ERROR_V(result) == ERRmoredata)
317 result = cli_spoolss_enumprinterdataex(cli, mem_ctx, needed,
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)));
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);
341 BOOL get_local_printer_publishing_data(TALLOC_CTX *mem_ctx,
343 NT_PRINTER_DATA *data)
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]);