s3: Re-run make samba3-idl.
[Samba/gebeck_regimport.git] / source3 / libads / ldap_printer.c
blobd5290b23a9cf954975f34b461c5b2004debe16d1
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 3 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, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
21 #include "../librpc/gen_ndr/cli_spoolss.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, LDAPMessage **res,
31 const char *printer,
32 const char *servername)
34 ADS_STATUS status;
35 char *srv_dn, **srv_cn, *s = NULL;
36 const char *attrs[] = {"*", "nTSecurityDescriptor", NULL};
38 status = ads_find_machine_acct(ads, res, servername);
39 if (!ADS_ERR_OK(status)) {
40 DEBUG(1, ("ads_find_printer_on_server: cannot find host %s in ads\n",
41 servername));
42 return status;
44 if (ads_count_replies(ads, *res) != 1) {
45 if (res) {
46 ads_msgfree(ads, *res);
47 *res = NULL;
49 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
51 srv_dn = ldap_get_dn(ads->ldap.ld, *res);
52 if (srv_dn == NULL) {
53 if (res) {
54 ads_msgfree(ads, *res);
55 *res = NULL;
57 return ADS_ERROR(LDAP_NO_MEMORY);
59 srv_cn = ldap_explode_dn(srv_dn, 1);
60 if (srv_cn == NULL) {
61 ldap_memfree(srv_dn);
62 if (res) {
63 ads_msgfree(ads, *res);
64 *res = NULL;
66 return ADS_ERROR(LDAP_INVALID_DN_SYNTAX);
68 if (res) {
69 ads_msgfree(ads, *res);
70 *res = NULL;
73 if (asprintf(&s, "(cn=%s-%s)", srv_cn[0], printer) == -1) {
74 ldap_memfree(srv_dn);
75 return ADS_ERROR(LDAP_NO_MEMORY);
77 status = ads_search(ads, res, s, attrs);
79 ldap_memfree(srv_dn);
80 ldap_value_free(srv_cn);
81 SAFE_FREE(s);
82 return status;
85 ADS_STATUS ads_find_printers(ADS_STRUCT *ads, LDAPMessage **res)
87 const char *ldap_expr;
88 const char *attrs[] = { "objectClass", "printerName", "location", "driverName",
89 "serverName", "description", NULL };
91 /* For the moment only display all printers */
93 ldap_expr = "(&(!(showInAdvancedViewOnly=TRUE))(uncName=*)"
94 "(objectCategory=printQueue))";
96 return ads_search(ads, res, ldap_expr, attrs);
100 modify a printer entry in the directory
102 ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn,
103 TALLOC_CTX *ctx, const ADS_MODLIST *mods)
105 return ads_gen_mod(ads, prt_dn, *mods);
109 add a printer to the directory
111 ADS_STATUS ads_add_printer_entry(ADS_STRUCT *ads, char *prt_dn,
112 TALLOC_CTX *ctx, ADS_MODLIST *mods)
114 ads_mod_str(ctx, mods, "objectClass", "printQueue");
115 return ads_gen_add(ads, prt_dn, *mods);
119 map a REG_SZ to an ldap mod
121 static bool map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods,
122 const struct regval_blob *value)
124 char *str_value = NULL;
125 size_t converted_size;
126 ADS_STATUS status;
128 if (value->type != REG_SZ)
129 return false;
131 if (value->size && *((smb_ucs2_t *) value->data_p)) {
132 if (!pull_ucs2_talloc(ctx, &str_value,
133 (const smb_ucs2_t *) value->data_p,
134 &converted_size))
136 return false;
138 status = ads_mod_str(ctx, mods, value->valuename, str_value);
139 return ADS_ERR_OK(status);
141 return true;
146 map a REG_DWORD to an ldap mod
148 static bool map_dword(TALLOC_CTX *ctx, ADS_MODLIST *mods,
149 const struct regval_blob *value)
151 char *str_value = NULL;
152 ADS_STATUS status;
154 if (value->type != REG_DWORD)
155 return False;
156 str_value = talloc_asprintf(ctx, "%d", *((uint32 *) value->data_p));
157 if (!str_value) {
158 return False;
160 status = ads_mod_str(ctx, mods, value->valuename, str_value);
161 return ADS_ERR_OK(status);
165 map a boolean REG_BINARY to an ldap mod
167 static bool map_bool(TALLOC_CTX *ctx, ADS_MODLIST *mods,
168 const struct regval_blob *value)
170 char *str_value;
171 ADS_STATUS status;
173 if ((value->type != REG_BINARY) || (value->size != 1))
174 return False;
175 str_value = talloc_asprintf(ctx, "%s",
176 *(value->data_p) ? "TRUE" : "FALSE");
177 if (!str_value) {
178 return False;
180 status = ads_mod_str(ctx, mods, value->valuename, str_value);
181 return ADS_ERR_OK(status);
185 map a REG_MULTI_SZ to an ldap mod
187 static bool map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods,
188 const struct regval_blob *value)
190 char **str_values = NULL;
191 size_t converted_size;
192 smb_ucs2_t *cur_str = (smb_ucs2_t *) value->data_p;
193 uint32 size = 0, num_vals = 0, i=0;
194 ADS_STATUS status;
196 if (value->type != REG_MULTI_SZ)
197 return False;
199 while(cur_str && *cur_str && (size < value->size)) {
200 size += 2 * (strlen_w(cur_str) + 1);
201 cur_str += strlen_w(cur_str) + 1;
202 num_vals++;
205 if (num_vals) {
206 str_values = TALLOC_ARRAY(ctx, char *, num_vals + 1);
207 if (!str_values) {
208 return False;
210 memset(str_values, '\0',
211 (num_vals + 1) * sizeof(char *));
213 cur_str = (smb_ucs2_t *) value->data_p;
214 for (i=0; i < num_vals; i++) {
215 cur_str += pull_ucs2_talloc(ctx, &str_values[i],
216 cur_str, &converted_size) ?
217 converted_size : (size_t)-1;
220 status = ads_mod_strlist(ctx, mods, value->valuename,
221 (const char **) str_values);
222 return ADS_ERR_OK(status);
224 return True;
227 struct valmap_to_ads {
228 const char *valname;
229 bool (*fn)(TALLOC_CTX *, ADS_MODLIST *, const struct regval_blob *);
233 map a REG_SZ to an ldap mod
235 static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods,
236 struct regval_blob *value)
238 const struct valmap_to_ads map[] = {
239 {SPOOL_REG_ASSETNUMBER, map_sz},
240 {SPOOL_REG_BYTESPERMINUTE, map_dword},
241 {SPOOL_REG_DEFAULTPRIORITY, map_dword},
242 {SPOOL_REG_DESCRIPTION, map_sz},
243 {SPOOL_REG_DRIVERNAME, map_sz},
244 {SPOOL_REG_DRIVERVERSION, map_dword},
245 {SPOOL_REG_FLAGS, map_dword},
246 {SPOOL_REG_LOCATION, map_sz},
247 {SPOOL_REG_OPERATINGSYSTEM, map_sz},
248 {SPOOL_REG_OPERATINGSYSTEMHOTFIX, map_sz},
249 {SPOOL_REG_OPERATINGSYSTEMSERVICEPACK, map_sz},
250 {SPOOL_REG_OPERATINGSYSTEMVERSION, map_sz},
251 {SPOOL_REG_PORTNAME, map_multi_sz},
252 {SPOOL_REG_PRINTATTRIBUTES, map_dword},
253 {SPOOL_REG_PRINTBINNAMES, map_multi_sz},
254 {SPOOL_REG_PRINTCOLLATE, map_bool},
255 {SPOOL_REG_PRINTCOLOR, map_bool},
256 {SPOOL_REG_PRINTDUPLEXSUPPORTED, map_bool},
257 {SPOOL_REG_PRINTENDTIME, map_dword},
258 {SPOOL_REG_PRINTFORMNAME, map_sz},
259 {SPOOL_REG_PRINTKEEPPRINTEDJOBS, map_bool},
260 {SPOOL_REG_PRINTLANGUAGE, map_multi_sz},
261 {SPOOL_REG_PRINTMACADDRESS, map_sz},
262 {SPOOL_REG_PRINTMAXCOPIES, map_sz},
263 {SPOOL_REG_PRINTMAXRESOLUTIONSUPPORTED, map_dword},
264 {SPOOL_REG_PRINTMAXXEXTENT, map_dword},
265 {SPOOL_REG_PRINTMAXYEXTENT, map_dword},
266 {SPOOL_REG_PRINTMEDIAREADY, map_multi_sz},
267 {SPOOL_REG_PRINTMEDIASUPPORTED, map_multi_sz},
268 {SPOOL_REG_PRINTMEMORY, map_dword},
269 {SPOOL_REG_PRINTMINXEXTENT, map_dword},
270 {SPOOL_REG_PRINTMINYEXTENT, map_dword},
271 {SPOOL_REG_PRINTNETWORKADDRESS, map_sz},
272 {SPOOL_REG_PRINTNOTIFY, map_sz},
273 {SPOOL_REG_PRINTNUMBERUP, map_dword},
274 {SPOOL_REG_PRINTORIENTATIONSSUPPORTED, map_multi_sz},
275 {SPOOL_REG_PRINTOWNER, map_sz},
276 {SPOOL_REG_PRINTPAGESPERMINUTE, map_dword},
277 {SPOOL_REG_PRINTRATE, map_dword},
278 {SPOOL_REG_PRINTRATEUNIT, map_sz},
279 {SPOOL_REG_PRINTSEPARATORFILE, map_sz},
280 {SPOOL_REG_PRINTSHARENAME, map_sz},
281 {SPOOL_REG_PRINTSPOOLING, map_sz},
282 {SPOOL_REG_PRINTSTAPLINGSUPPORTED, map_bool},
283 {SPOOL_REG_PRINTSTARTTIME, map_dword},
284 {SPOOL_REG_PRINTSTATUS, map_sz},
285 {SPOOL_REG_PRIORITY, map_dword},
286 {SPOOL_REG_SERVERNAME, map_sz},
287 {SPOOL_REG_SHORTSERVERNAME, map_sz},
288 {SPOOL_REG_UNCNAME, map_sz},
289 {SPOOL_REG_URL, map_sz},
290 {SPOOL_REG_VERSIONNUMBER, map_dword},
291 {NULL, NULL}
293 int i;
295 for (i=0; map[i].valname; i++) {
296 if (StrCaseCmp(map[i].valname, value->valuename) == 0) {
297 if (!map[i].fn(ctx, mods, value)) {
298 DEBUG(5, ("Add of value %s to modlist failed\n", value->valuename));
299 } else {
300 DEBUG(7, ("Mapped value %s\n", value->valuename));
308 WERROR get_remote_printer_publishing_data(struct rpc_pipe_client *cli,
309 TALLOC_CTX *mem_ctx,
310 ADS_MODLIST *mods,
311 const char *printer)
313 WERROR result;
314 char *printername;
315 struct spoolss_PrinterEnumValues *info;
316 uint32_t count;
317 uint32 i;
318 struct policy_handle pol;
320 if ((asprintf(&printername, "%s\\%s", cli->srv_name_slash, printer) == -1)) {
321 DEBUG(3, ("Insufficient memory\n"));
322 return WERR_NOMEM;
325 result = rpccli_spoolss_openprinter_ex(cli, mem_ctx,
326 printername,
327 SEC_FLAG_MAXIMUM_ALLOWED,
328 &pol);
329 if (!W_ERROR_IS_OK(result)) {
330 DEBUG(3, ("Unable to open printer %s, error is %s.\n",
331 printername, win_errstr(result)));
332 SAFE_FREE(printername);
333 return result;
336 result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol,
337 SPOOL_DSDRIVER_KEY,
339 &count,
340 &info);
342 if (!W_ERROR_IS_OK(result)) {
343 DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
344 printername, win_errstr(result)));
345 } else {
346 /* Have the data we need now, so start building */
347 for (i=0; i < count; i++) {
348 struct regval_blob v;
350 fstrcpy(v.valuename, info[i].value_name);
351 v.type = info[i].type;
352 v.data_p = info[i].data->data;
353 v.size = info[i].data->length;
355 map_regval_to_ads(mem_ctx, mods, &v);
359 result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol,
360 SPOOL_DSSPOOLER_KEY,
362 &count,
363 &info);
364 if (!W_ERROR_IS_OK(result)) {
365 DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
366 printername, win_errstr(result)));
367 } else {
368 for (i=0; i < count; i++) {
369 struct regval_blob v;
371 fstrcpy(v.valuename, info[i].value_name);
372 v.type = info[i].type;
373 v.data_p = info[i].data->data;
374 v.size = info[i].data->length;
376 map_regval_to_ads(mem_ctx, mods, &v);
380 ads_mod_str(mem_ctx, mods, SPOOL_REG_PRINTERNAME, printer);
382 rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL);
383 SAFE_FREE(printername);
385 return result;
388 bool get_local_printer_publishing_data(TALLOC_CTX *mem_ctx,
389 ADS_MODLIST *mods,
390 NT_PRINTER_DATA *data)
392 uint32 key,val;
394 for (key=0; key < data->num_keys; key++) {
395 struct regval_ctr *ctr = data->keys[key].values;
396 for (val=0; val < ctr->num_values; val++)
397 map_regval_to_ads(mem_ctx, mods, ctr->values[val]);
399 return True;
402 #endif