2 Unix SMB/CIFS implementation.
3 ads (active directory) printer utility library
4 Copyright (C) Jim McDonough 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, *exp;
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_add_printer: 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(&exp, "(cn=%s-%s)", srv_cn[0], printer);
48 status = ads_search(ads, res, exp, attrs);
51 ldap_value_free(srv_cn);
57 modify a printer entry in the directory
59 ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn,
60 TALLOC_CTX *ctx, const ADS_MODLIST *mods)
62 return ads_gen_mod(ads, prt_dn, *mods);
66 add a printer to the directory
68 ADS_STATUS ads_add_printer_entry(ADS_STRUCT *ads, char *prt_dn,
69 TALLOC_CTX *ctx, ADS_MODLIST *mods)
71 ads_mod_str(ctx, mods, "objectClass", "printQueue");
72 return ads_gen_add(ads, prt_dn, *mods);
76 map a REG_SZ to an ldap mod
78 static BOOL map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods,
79 const REGISTRY_VALUE *value)
81 char *str_value = NULL;
84 if (value->type != REG_SZ)
87 if (value->size && *((smb_ucs2_t *) value->data_p)) {
88 pull_ucs2_talloc(ctx, (void **) &str_value,
89 (const smb_ucs2_t *) value->data_p);
90 status = ads_mod_str(ctx, mods, value->valuename, str_value);
91 return ADS_ERR_OK(status);
98 map a REG_DWORD to an ldap mod
100 static BOOL map_dword(TALLOC_CTX *ctx, ADS_MODLIST *mods,
101 const REGISTRY_VALUE *value)
103 char *str_value = NULL;
106 if (value->type != REG_DWORD)
108 str_value = talloc_asprintf(ctx, "%d", *((uint32 *) value->data_p));
109 status = ads_mod_str(ctx, mods, value->valuename, str_value);
110 return ADS_ERR_OK(status);
114 map a boolean REG_BINARY to an ldap mod
116 static BOOL map_bool(TALLOC_CTX *ctx, ADS_MODLIST *mods,
117 const REGISTRY_VALUE *value)
122 if ((value->type != REG_BINARY) || (value->size != 1))
124 str_value = talloc_asprintf(ctx, "%s",
125 *(value->data_p) ? "TRUE" : "FALSE");
126 status = ads_mod_str(ctx, mods, value->valuename, str_value);
127 return ADS_ERR_OK(status);
131 map a REG_MULTI_SZ to an ldap mod
133 static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods,
134 const REGISTRY_VALUE *value)
136 char **str_values = NULL;
137 smb_ucs2_t *cur_str = (smb_ucs2_t *) value->data_p;
138 uint32 size = 0, num_vals = 0, i=0;
141 if (value->type != REG_MULTI_SZ)
144 while(cur_str && *cur_str && (size < value->size)) {
145 size += 2 * (strlen_w(cur_str) + 1);
146 cur_str += strlen_w(cur_str) + 1;
151 str_values = talloc(ctx,
152 (num_vals + 1) * sizeof(smb_ucs2_t *));
153 memset(str_values, '\0',
154 (num_vals + 1) * sizeof(smb_ucs2_t *));
156 cur_str = (smb_ucs2_t *) value->data_p;
157 for (i=0; i < num_vals; i++)
158 cur_str += pull_ucs2_talloc(ctx,
159 (void **) &str_values[i],
162 status = ads_mod_strlist(ctx, mods, value->valuename,
163 (const char **) str_values);
164 return ADS_ERR_OK(status);
169 struct valmap_to_ads {
171 BOOL (*fn)(TALLOC_CTX *, ADS_MODLIST *, const REGISTRY_VALUE *);
175 map a REG_SZ to an ldap mod
177 static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods,
178 REGISTRY_VALUE *value)
180 struct valmap_to_ads map[] = {
181 {SPOOL_REG_ASSETNUMBER, map_sz},
182 {SPOOL_REG_BYTESPERMINUTE, map_dword},
183 {SPOOL_REG_DEFAULTPRIORITY, map_dword},
184 {SPOOL_REG_DRIVERNAME, map_sz},
185 {SPOOL_REG_DRIVERVERSION, map_dword},
186 {SPOOL_REG_FLAGS, map_dword},
187 {SPOOL_REG_LOCATION, map_sz},
188 {SPOOL_REG_OPERATINGSYSTEM, map_sz},
189 {SPOOL_REG_OPERATINGSYSTEMHOTFIX, map_sz},
190 {SPOOL_REG_OPERATINGSYSTEMSERVICEPACK, map_sz},
191 {SPOOL_REG_OPERATINGSYSTEMVERSION, map_sz},
192 {SPOOL_REG_PORTNAME, map_multi_sz},
193 {SPOOL_REG_PRINTATTRIBUTES, map_dword},
194 {SPOOL_REG_PRINTBINNAMES, map_multi_sz},
195 {SPOOL_REG_PRINTCOLLATE, map_bool},
196 {SPOOL_REG_PRINTCOLOR, map_bool},
197 {SPOOL_REG_PRINTDUPLEXSUPPORTED, map_bool},
198 {SPOOL_REG_PRINTENDTIME, map_dword},
199 {SPOOL_REG_PRINTFORMNAME, map_sz},
200 {SPOOL_REG_PRINTKEEPPRINTEDJOBS, map_bool},
201 {SPOOL_REG_PRINTLANGUAGE, map_multi_sz},
202 {SPOOL_REG_PRINTMACADDRESS, map_sz},
203 {SPOOL_REG_PRINTMAXCOPIES, map_sz},
204 {SPOOL_REG_PRINTMAXRESOLUTIONSUPPORTED, map_dword},
205 {SPOOL_REG_PRINTMAXXEXTENT, map_dword},
206 {SPOOL_REG_PRINTMAXYEXTENT, map_dword},
207 {SPOOL_REG_PRINTMEDIAREADY, map_multi_sz},
208 {SPOOL_REG_PRINTMEDIASUPPORTED, map_multi_sz},
209 {SPOOL_REG_PRINTMEMORY, map_dword},
210 {SPOOL_REG_PRINTMINXEXTENT, map_dword},
211 {SPOOL_REG_PRINTMINYEXTENT, map_dword},
212 {SPOOL_REG_PRINTNETWORKADDRESS, map_sz},
213 {SPOOL_REG_PRINTNOTIFY, map_sz},
214 {SPOOL_REG_PRINTNUMBERUP, map_dword},
215 {SPOOL_REG_PRINTORIENTATIONSSUPPORTED, map_multi_sz},
216 {SPOOL_REG_PRINTOWNER, map_sz},
217 {SPOOL_REG_PRINTPAGESPERMINUTE, map_dword},
218 {SPOOL_REG_PRINTRATE, map_dword},
219 {SPOOL_REG_PRINTRATEUNIT, map_sz},
220 {SPOOL_REG_PRINTSEPARATORFILE, map_sz},
221 {SPOOL_REG_PRINTSHARENAME, map_sz},
222 {SPOOL_REG_PRINTSPOOLING, map_sz},
223 {SPOOL_REG_PRINTSTAPLINGSUPPORTED, map_bool},
224 {SPOOL_REG_PRINTSTARTTIME, map_dword},
225 {SPOOL_REG_PRINTSTATUS, map_sz},
226 {SPOOL_REG_PRIORITY, map_dword},
227 {SPOOL_REG_SERVERNAME, map_sz},
228 {SPOOL_REG_SHORTSERVERNAME, map_sz},
229 {SPOOL_REG_UNCNAME, map_sz},
230 {SPOOL_REG_URL, map_sz},
231 {SPOOL_REG_VERSIONNUMBER, map_dword},
236 for (i=0; map[i].valname; i++) {
237 if (StrCaseCmp(map[i].valname, value->valuename) == 0) {
238 if (!map[i].fn(ctx, mods, value)) {
239 DEBUG(5, ("Add of value %s to modlist failed\n", value->valuename));
241 DEBUG(7, ("Mapped value %s\n", value->valuename));
249 WERROR get_remote_printer_publishing_data(struct cli_state *cli,
255 char *printername, *servername;
256 REGVAL_CTR dsdriver_ctr, dsspooler_ctr;
257 BOOL got_dsdriver = False, got_dsspooler = False;
261 asprintf(&servername, "\\\\%s", cli->desthost);
262 asprintf(&printername, "%s\\%s", servername, printer);
263 if (!servername || !printername) {
264 DEBUG(3, ("Insufficient memory\n"));
268 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
269 "", MAXIMUM_ALLOWED_ACCESS,
270 servername, cli->user_name, &pol);
271 if (!W_ERROR_IS_OK(result)) {
272 DEBUG(3, ("Unable to open printer %s, error is %s.\n",
273 printername, dos_errstr(result)));
277 result = cli_spoolss_enumprinterdataex(cli, mem_ctx, 0, &needed,
278 &pol, SPOOL_DSDRIVER_KEY, NULL);
280 if (W_ERROR_V(result) == ERRmoredata)
281 result = cli_spoolss_enumprinterdataex(cli, mem_ctx, needed,
286 if (!W_ERROR_IS_OK(result)) {
287 DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
288 printername, dos_errstr(result)));
291 /* Have the data we need now, so start building */
293 for (i=0; i < dsdriver_ctr.num_values; i++)
294 map_regval_to_ads(mem_ctx, mods,
295 dsdriver_ctr.values[i]);
298 result = cli_spoolss_enumprinterdataex(cli, mem_ctx, 0, &needed,
299 &pol, SPOOL_DSSPOOLER_KEY,
302 if (W_ERROR_V(result) == ERRmoredata)
303 result = cli_spoolss_enumprinterdataex(cli, mem_ctx, needed,
308 if (!W_ERROR_IS_OK(result)) {
309 DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
310 printername, dos_errstr(result)));
312 got_dsspooler = True;
313 for (i=0; i < dsspooler_ctr.num_values; i++)
314 map_regval_to_ads(mem_ctx, mods,
315 dsspooler_ctr.values[i]);
318 ads_mod_str(mem_ctx, mods, SPOOL_REG_PRINTERNAME, printer);
320 if (got_dsdriver) regval_ctr_destroy(&dsdriver_ctr);
321 if (got_dsspooler) regval_ctr_destroy(&dsspooler_ctr);
322 cli_spoolss_close_printer(cli, mem_ctx, &pol);
327 BOOL get_local_printer_publishing_data(TALLOC_CTX *mem_ctx,
329 NT_PRINTER_DATA *data)
333 for (key=0; key < data->num_keys; key++) {
334 REGVAL_CTR ctr = data->keys[key].values;
335 for (val=0; val < ctr.num_values; val++)
336 map_regval_to_ads(mem_ctx, mods, ctr.values[val]);