preparing for release of 3.0alpha23
[Samba.git] / source / libads / ldap_printer.c
blobf5cd4f2885d2cdd547069b8b1e61f90554e784bd
1 /*
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.
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, *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",
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(&exp, "(cn=%s-%s)", srv_cn[0], printer);
48 status = ads_search(ads, res, exp, attrs);
50 ldap_memfree(srv_dn);
51 ldap_value_free(srv_cn);
52 free(exp);
53 return status;
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;
82 ADS_STATUS status;
84 if (value->type != REG_SZ)
85 return False;
87 if (value->size && *((smb_ucs2_t *) value->data_p)) {
88 pull_ucs2_talloc(ctx, &str_value, (const smb_ucs2_t *) value->data_p);
89 status = ads_mod_str(ctx, mods, value->valuename, str_value);
90 return ADS_ERR_OK(status);
92 return True;
97 map a REG_DWORD to an ldap mod
99 static BOOL map_dword(TALLOC_CTX *ctx, ADS_MODLIST *mods,
100 const REGISTRY_VALUE *value)
102 char *str_value = NULL;
103 ADS_STATUS status;
105 if (value->type != REG_DWORD)
106 return False;
107 str_value = talloc_asprintf(ctx, "%d", *((uint32 *) value->data_p));
108 status = ads_mod_str(ctx, mods, value->valuename, str_value);
109 return ADS_ERR_OK(status);
113 map a boolean REG_BINARY to an ldap mod
115 static BOOL map_bool(TALLOC_CTX *ctx, ADS_MODLIST *mods,
116 const REGISTRY_VALUE *value)
118 char *str_value;
119 ADS_STATUS status;
121 if ((value->type != REG_BINARY) || (value->size != 1))
122 return False;
123 str_value = talloc_asprintf(ctx, "%s",
124 *(value->data_p) ? "TRUE" : "FALSE");
125 status = ads_mod_str(ctx, mods, value->valuename, str_value);
126 return ADS_ERR_OK(status);
130 map a REG_MULTI_SZ to an ldap mod
132 static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods,
133 const REGISTRY_VALUE *value)
135 char **str_values = NULL;
136 smb_ucs2_t *cur_str = (smb_ucs2_t *) value->data_p;
137 uint32 size = 0, num_vals = 0, i=0;
138 ADS_STATUS status;
140 if (value->type != REG_MULTI_SZ)
141 return False;
143 while(cur_str && *cur_str && (size < value->size)) {
144 size += 2 * (strlen_w(cur_str) + 1);
145 cur_str += strlen_w(cur_str) + 1;
146 num_vals++;
149 if (num_vals) {
150 str_values = talloc(ctx,
151 (num_vals + 1) * sizeof(smb_ucs2_t *));
152 memset(str_values, '\0',
153 (num_vals + 1) * sizeof(smb_ucs2_t *));
155 cur_str = (smb_ucs2_t *) value->data_p;
156 for (i=0; i < num_vals; i++)
157 cur_str += pull_ucs2_talloc(ctx, &str_values[i],
158 cur_str);
160 status = ads_mod_strlist(ctx, mods, value->valuename,
161 (const char **) str_values);
162 return ADS_ERR_OK(status);
164 return True;
167 struct valmap_to_ads {
168 const char *valname;
169 BOOL (*fn)(TALLOC_CTX *, ADS_MODLIST *, const REGISTRY_VALUE *);
173 map a REG_SZ to an ldap mod
175 static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods,
176 REGISTRY_VALUE *value)
178 const struct valmap_to_ads map[] = {
179 {SPOOL_REG_ASSETNUMBER, map_sz},
180 {SPOOL_REG_BYTESPERMINUTE, map_dword},
181 {SPOOL_REG_DEFAULTPRIORITY, map_dword},
182 {SPOOL_REG_DESCRIPTION, map_sz},
183 {SPOOL_REG_DRIVERNAME, map_sz},
184 {SPOOL_REG_DRIVERVERSION, map_dword},
185 {SPOOL_REG_FLAGS, map_dword},
186 {SPOOL_REG_LOCATION, map_sz},
187 {SPOOL_REG_OPERATINGSYSTEM, map_sz},
188 {SPOOL_REG_OPERATINGSYSTEMHOTFIX, map_sz},
189 {SPOOL_REG_OPERATINGSYSTEMSERVICEPACK, map_sz},
190 {SPOOL_REG_OPERATINGSYSTEMVERSION, map_sz},
191 {SPOOL_REG_PORTNAME, map_multi_sz},
192 {SPOOL_REG_PRINTATTRIBUTES, map_dword},
193 {SPOOL_REG_PRINTBINNAMES, map_multi_sz},
194 {SPOOL_REG_PRINTCOLLATE, map_bool},
195 {SPOOL_REG_PRINTCOLOR, map_bool},
196 {SPOOL_REG_PRINTDUPLEXSUPPORTED, map_bool},
197 {SPOOL_REG_PRINTENDTIME, map_dword},
198 {SPOOL_REG_PRINTFORMNAME, map_sz},
199 {SPOOL_REG_PRINTKEEPPRINTEDJOBS, map_bool},
200 {SPOOL_REG_PRINTLANGUAGE, map_multi_sz},
201 {SPOOL_REG_PRINTMACADDRESS, map_sz},
202 {SPOOL_REG_PRINTMAXCOPIES, map_sz},
203 {SPOOL_REG_PRINTMAXRESOLUTIONSUPPORTED, map_dword},
204 {SPOOL_REG_PRINTMAXXEXTENT, map_dword},
205 {SPOOL_REG_PRINTMAXYEXTENT, map_dword},
206 {SPOOL_REG_PRINTMEDIAREADY, map_multi_sz},
207 {SPOOL_REG_PRINTMEDIASUPPORTED, map_multi_sz},
208 {SPOOL_REG_PRINTMEMORY, map_dword},
209 {SPOOL_REG_PRINTMINXEXTENT, map_dword},
210 {SPOOL_REG_PRINTMINYEXTENT, map_dword},
211 {SPOOL_REG_PRINTNETWORKADDRESS, map_sz},
212 {SPOOL_REG_PRINTNOTIFY, map_sz},
213 {SPOOL_REG_PRINTNUMBERUP, map_dword},
214 {SPOOL_REG_PRINTORIENTATIONSSUPPORTED, map_multi_sz},
215 {SPOOL_REG_PRINTOWNER, map_sz},
216 {SPOOL_REG_PRINTPAGESPERMINUTE, map_dword},
217 {SPOOL_REG_PRINTRATE, map_dword},
218 {SPOOL_REG_PRINTRATEUNIT, map_sz},
219 {SPOOL_REG_PRINTSEPARATORFILE, map_sz},
220 {SPOOL_REG_PRINTSHARENAME, map_sz},
221 {SPOOL_REG_PRINTSPOOLING, map_sz},
222 {SPOOL_REG_PRINTSTAPLINGSUPPORTED, map_bool},
223 {SPOOL_REG_PRINTSTARTTIME, map_dword},
224 {SPOOL_REG_PRINTSTATUS, map_sz},
225 {SPOOL_REG_PRIORITY, map_dword},
226 {SPOOL_REG_SERVERNAME, map_sz},
227 {SPOOL_REG_SHORTSERVERNAME, map_sz},
228 {SPOOL_REG_UNCNAME, map_sz},
229 {SPOOL_REG_URL, map_sz},
230 {SPOOL_REG_VERSIONNUMBER, map_dword},
231 {NULL, NULL}
233 int i;
235 for (i=0; map[i].valname; i++) {
236 if (StrCaseCmp(map[i].valname, value->valuename) == 0) {
237 if (!map[i].fn(ctx, mods, value)) {
238 DEBUG(5, ("Add of value %s to modlist failed\n", value->valuename));
239 } else {
240 DEBUG(7, ("Mapped value %s\n", value->valuename));
248 WERROR get_remote_printer_publishing_data(struct cli_state *cli,
249 TALLOC_CTX *mem_ctx,
250 ADS_MODLIST *mods,
251 const char *printer)
253 WERROR result;
254 char *printername, *servername;
255 REGVAL_CTR dsdriver_ctr, dsspooler_ctr;
256 BOOL got_dsdriver = False, got_dsspooler = False;
257 uint32 needed, i;
258 POLICY_HND pol;
260 asprintf(&servername, "\\\\%s", cli->desthost);
261 asprintf(&printername, "%s\\%s", servername, printer);
262 if (!servername || !printername) {
263 DEBUG(3, ("Insufficient memory\n"));
264 return WERR_NOMEM;
267 result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
268 "", MAXIMUM_ALLOWED_ACCESS,
269 servername, cli->user_name, &pol);
270 if (!W_ERROR_IS_OK(result)) {
271 DEBUG(3, ("Unable to open printer %s, error is %s.\n",
272 printername, dos_errstr(result)));
273 return result;
276 result = cli_spoolss_enumprinterdataex(cli, mem_ctx, 0, &needed,
277 &pol, SPOOL_DSDRIVER_KEY, NULL);
279 if (W_ERROR_V(result) == ERRmoredata)
280 result = cli_spoolss_enumprinterdataex(cli, mem_ctx, needed,
281 NULL, &pol,
282 SPOOL_DSDRIVER_KEY,
283 &dsdriver_ctr);
285 if (!W_ERROR_IS_OK(result)) {
286 DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
287 printername, dos_errstr(result)));
288 } else {
290 /* Have the data we need now, so start building */
291 got_dsdriver = True;
292 for (i=0; i < dsdriver_ctr.num_values; i++)
293 map_regval_to_ads(mem_ctx, mods,
294 dsdriver_ctr.values[i]);
297 result = cli_spoolss_enumprinterdataex(cli, mem_ctx, 0, &needed,
298 &pol, SPOOL_DSSPOOLER_KEY,
299 NULL);
301 if (W_ERROR_V(result) == ERRmoredata)
302 result = cli_spoolss_enumprinterdataex(cli, mem_ctx, needed,
303 NULL, &pol,
304 SPOOL_DSSPOOLER_KEY,
305 &dsspooler_ctr);
307 if (!W_ERROR_IS_OK(result)) {
308 DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
309 printername, dos_errstr(result)));
310 } else {
311 got_dsspooler = True;
312 for (i=0; i < dsspooler_ctr.num_values; i++)
313 map_regval_to_ads(mem_ctx, mods,
314 dsspooler_ctr.values[i]);
317 ads_mod_str(mem_ctx, mods, SPOOL_REG_PRINTERNAME, printer);
319 if (got_dsdriver) regval_ctr_destroy(&dsdriver_ctr);
320 if (got_dsspooler) regval_ctr_destroy(&dsspooler_ctr);
321 cli_spoolss_close_printer(cli, mem_ctx, &pol);
323 return result;
326 BOOL get_local_printer_publishing_data(TALLOC_CTX *mem_ctx,
327 ADS_MODLIST *mods,
328 NT_PRINTER_DATA *data)
330 uint32 key,val;
332 for (key=0; key < data->num_keys; key++) {
333 REGVAL_CTR ctr = data->keys[key].values;
334 for (val=0; val < ctr.num_values; val++)
335 map_regval_to_ads(mem_ctx, mods, ctr.values[val]);
337 return True;
340 #endif