WHATSNEW: Update changes since 3.3.0pre2.
[Samba/bb.git] / source / libads / ldap_printer.c
blob9935e2311a5b9f6d65cb1dd1f2bf7debf62a4630
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"
22 #ifdef HAVE_ADS
25 find a printer given the name and the hostname
26 Note that results "res" may be allocated on return so that the
27 results can be used. It should be freed using ads_msgfree.
29 ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, LDAPMessage **res,
30 const char *printer,
31 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 if (ads_count_replies(ads, *res) != 1) {
44 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
46 srv_dn = ldap_get_dn(ads->ldap.ld, *res);
47 if (srv_dn == NULL) {
48 return ADS_ERROR(LDAP_NO_MEMORY);
50 srv_cn = ldap_explode_dn(srv_dn, 1);
51 if (srv_cn == NULL) {
52 ldap_memfree(srv_dn);
53 return ADS_ERROR(LDAP_INVALID_DN_SYNTAX);
55 ads_msgfree(ads, *res);
57 asprintf(&s, "(cn=%s-%s)", srv_cn[0], printer);
58 status = ads_search(ads, res, s, attrs);
60 ldap_memfree(srv_dn);
61 ldap_value_free(srv_cn);
62 free(s);
63 return status;
66 ADS_STATUS ads_find_printers(ADS_STRUCT *ads, LDAPMessage **res)
68 const char *ldap_expr;
69 const char *attrs[] = { "objectClass", "printerName", "location", "driverName",
70 "serverName", "description", NULL };
72 /* For the moment only display all printers */
74 ldap_expr = "(&(!(showInAdvancedViewOnly=TRUE))(uncName=*)"
75 "(objectCategory=printQueue))";
77 return ads_search(ads, res, ldap_expr, attrs);
81 modify a printer entry in the directory
83 ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn,
84 TALLOC_CTX *ctx, const ADS_MODLIST *mods)
86 return ads_gen_mod(ads, prt_dn, *mods);
90 add a printer to the directory
92 ADS_STATUS ads_add_printer_entry(ADS_STRUCT *ads, char *prt_dn,
93 TALLOC_CTX *ctx, ADS_MODLIST *mods)
95 ads_mod_str(ctx, mods, "objectClass", "printQueue");
96 return ads_gen_add(ads, prt_dn, *mods);
100 map a REG_SZ to an ldap mod
102 static bool map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods,
103 const REGISTRY_VALUE *value)
105 char *str_value = NULL;
106 size_t converted_size;
107 ADS_STATUS status;
109 if (value->type != REG_SZ)
110 return false;
112 if (value->size && *((smb_ucs2_t *) value->data_p)) {
113 if (!pull_ucs2_talloc(ctx, &str_value,
114 (const smb_ucs2_t *) value->data_p,
115 &converted_size))
117 return false;
119 status = ads_mod_str(ctx, mods, value->valuename, str_value);
120 return ADS_ERR_OK(status);
122 return true;
127 map a REG_DWORD to an ldap mod
129 static bool map_dword(TALLOC_CTX *ctx, ADS_MODLIST *mods,
130 const REGISTRY_VALUE *value)
132 char *str_value = NULL;
133 ADS_STATUS status;
135 if (value->type != REG_DWORD)
136 return False;
137 str_value = talloc_asprintf(ctx, "%d", *((uint32 *) value->data_p));
138 if (!str_value) {
139 return False;
141 status = ads_mod_str(ctx, mods, value->valuename, str_value);
142 return ADS_ERR_OK(status);
146 map a boolean REG_BINARY to an ldap mod
148 static bool map_bool(TALLOC_CTX *ctx, ADS_MODLIST *mods,
149 const REGISTRY_VALUE *value)
151 char *str_value;
152 ADS_STATUS status;
154 if ((value->type != REG_BINARY) || (value->size != 1))
155 return False;
156 str_value = talloc_asprintf(ctx, "%s",
157 *(value->data_p) ? "TRUE" : "FALSE");
158 if (!str_value) {
159 return False;
161 status = ads_mod_str(ctx, mods, value->valuename, str_value);
162 return ADS_ERR_OK(status);
166 map a REG_MULTI_SZ to an ldap mod
168 static bool map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods,
169 const REGISTRY_VALUE *value)
171 char **str_values = NULL;
172 size_t converted_size;
173 smb_ucs2_t *cur_str = (smb_ucs2_t *) value->data_p;
174 uint32 size = 0, num_vals = 0, i=0;
175 ADS_STATUS status;
177 if (value->type != REG_MULTI_SZ)
178 return False;
180 while(cur_str && *cur_str && (size < value->size)) {
181 size += 2 * (strlen_w(cur_str) + 1);
182 cur_str += strlen_w(cur_str) + 1;
183 num_vals++;
186 if (num_vals) {
187 str_values = TALLOC_ARRAY(ctx, char *, num_vals + 1);
188 if (!str_values) {
189 return False;
191 memset(str_values, '\0',
192 (num_vals + 1) * sizeof(char *));
194 cur_str = (smb_ucs2_t *) value->data_p;
195 for (i=0; i < num_vals; i++) {
196 cur_str += pull_ucs2_talloc(ctx, &str_values[i],
197 cur_str, &converted_size) ?
198 converted_size : (size_t)-1;
201 status = ads_mod_strlist(ctx, mods, value->valuename,
202 (const char **) str_values);
203 return ADS_ERR_OK(status);
205 return True;
208 struct valmap_to_ads {
209 const char *valname;
210 bool (*fn)(TALLOC_CTX *, ADS_MODLIST *, const REGISTRY_VALUE *);
214 map a REG_SZ to an ldap mod
216 static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods,
217 REGISTRY_VALUE *value)
219 const struct valmap_to_ads map[] = {
220 {SPOOL_REG_ASSETNUMBER, map_sz},
221 {SPOOL_REG_BYTESPERMINUTE, map_dword},
222 {SPOOL_REG_DEFAULTPRIORITY, map_dword},
223 {SPOOL_REG_DESCRIPTION, map_sz},
224 {SPOOL_REG_DRIVERNAME, map_sz},
225 {SPOOL_REG_DRIVERVERSION, map_dword},
226 {SPOOL_REG_FLAGS, map_dword},
227 {SPOOL_REG_LOCATION, map_sz},
228 {SPOOL_REG_OPERATINGSYSTEM, map_sz},
229 {SPOOL_REG_OPERATINGSYSTEMHOTFIX, map_sz},
230 {SPOOL_REG_OPERATINGSYSTEMSERVICEPACK, map_sz},
231 {SPOOL_REG_OPERATINGSYSTEMVERSION, map_sz},
232 {SPOOL_REG_PORTNAME, map_multi_sz},
233 {SPOOL_REG_PRINTATTRIBUTES, map_dword},
234 {SPOOL_REG_PRINTBINNAMES, map_multi_sz},
235 {SPOOL_REG_PRINTCOLLATE, map_bool},
236 {SPOOL_REG_PRINTCOLOR, map_bool},
237 {SPOOL_REG_PRINTDUPLEXSUPPORTED, map_bool},
238 {SPOOL_REG_PRINTENDTIME, map_dword},
239 {SPOOL_REG_PRINTFORMNAME, map_sz},
240 {SPOOL_REG_PRINTKEEPPRINTEDJOBS, map_bool},
241 {SPOOL_REG_PRINTLANGUAGE, map_multi_sz},
242 {SPOOL_REG_PRINTMACADDRESS, map_sz},
243 {SPOOL_REG_PRINTMAXCOPIES, map_sz},
244 {SPOOL_REG_PRINTMAXRESOLUTIONSUPPORTED, map_dword},
245 {SPOOL_REG_PRINTMAXXEXTENT, map_dword},
246 {SPOOL_REG_PRINTMAXYEXTENT, map_dword},
247 {SPOOL_REG_PRINTMEDIAREADY, map_multi_sz},
248 {SPOOL_REG_PRINTMEDIASUPPORTED, map_multi_sz},
249 {SPOOL_REG_PRINTMEMORY, map_dword},
250 {SPOOL_REG_PRINTMINXEXTENT, map_dword},
251 {SPOOL_REG_PRINTMINYEXTENT, map_dword},
252 {SPOOL_REG_PRINTNETWORKADDRESS, map_sz},
253 {SPOOL_REG_PRINTNOTIFY, map_sz},
254 {SPOOL_REG_PRINTNUMBERUP, map_dword},
255 {SPOOL_REG_PRINTORIENTATIONSSUPPORTED, map_multi_sz},
256 {SPOOL_REG_PRINTOWNER, map_sz},
257 {SPOOL_REG_PRINTPAGESPERMINUTE, map_dword},
258 {SPOOL_REG_PRINTRATE, map_dword},
259 {SPOOL_REG_PRINTRATEUNIT, map_sz},
260 {SPOOL_REG_PRINTSEPARATORFILE, map_sz},
261 {SPOOL_REG_PRINTSHARENAME, map_sz},
262 {SPOOL_REG_PRINTSPOOLING, map_sz},
263 {SPOOL_REG_PRINTSTAPLINGSUPPORTED, map_bool},
264 {SPOOL_REG_PRINTSTARTTIME, map_dword},
265 {SPOOL_REG_PRINTSTATUS, map_sz},
266 {SPOOL_REG_PRIORITY, map_dword},
267 {SPOOL_REG_SERVERNAME, map_sz},
268 {SPOOL_REG_SHORTSERVERNAME, map_sz},
269 {SPOOL_REG_UNCNAME, map_sz},
270 {SPOOL_REG_URL, map_sz},
271 {SPOOL_REG_VERSIONNUMBER, map_dword},
272 {NULL, NULL}
274 int i;
276 for (i=0; map[i].valname; i++) {
277 if (StrCaseCmp(map[i].valname, value->valuename) == 0) {
278 if (!map[i].fn(ctx, mods, value)) {
279 DEBUG(5, ("Add of value %s to modlist failed\n", value->valuename));
280 } else {
281 DEBUG(7, ("Mapped value %s\n", value->valuename));
289 WERROR get_remote_printer_publishing_data(struct rpc_pipe_client *cli,
290 TALLOC_CTX *mem_ctx,
291 ADS_MODLIST *mods,
292 const char *printer)
294 WERROR result;
295 char *printername, *servername;
296 REGVAL_CTR *dsdriver_ctr, *dsspooler_ctr;
297 uint32 i;
298 POLICY_HND pol;
300 if ((asprintf(&servername, "\\\\%s", cli->desthost) == -1)
301 || (asprintf(&printername, "%s\\%s", servername, printer) == -1)) {
302 DEBUG(3, ("Insufficient memory\n"));
303 return WERR_NOMEM;
306 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
307 "", MAXIMUM_ALLOWED_ACCESS,
308 servername, cli->auth->user_name,
309 &pol);
310 if (!W_ERROR_IS_OK(result)) {
311 DEBUG(3, ("Unable to open printer %s, error is %s.\n",
312 printername, dos_errstr(result)));
313 return result;
316 if ( !(dsdriver_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) )
317 return WERR_NOMEM;
319 result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSDRIVER_KEY, dsdriver_ctr);
321 if (!W_ERROR_IS_OK(result)) {
322 DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
323 printername, dos_errstr(result)));
324 } else {
325 uint32 num_values = regval_ctr_numvals( dsdriver_ctr );
327 /* Have the data we need now, so start building */
328 for (i=0; i < num_values; i++) {
329 map_regval_to_ads(mem_ctx, mods, dsdriver_ctr->values[i]);
333 if ( !(dsspooler_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) )
334 return WERR_NOMEM;
336 result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSSPOOLER_KEY, dsspooler_ctr);
338 if (!W_ERROR_IS_OK(result)) {
339 DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
340 printername, dos_errstr(result)));
341 } else {
342 uint32 num_values = regval_ctr_numvals( dsspooler_ctr );
344 for (i=0; i<num_values; i++) {
345 map_regval_to_ads(mem_ctx, mods, dsspooler_ctr->values[i]);
349 ads_mod_str(mem_ctx, mods, SPOOL_REG_PRINTERNAME, printer);
351 TALLOC_FREE( dsdriver_ctr );
352 TALLOC_FREE( dsspooler_ctr );
354 rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
356 return result;
359 bool get_local_printer_publishing_data(TALLOC_CTX *mem_ctx,
360 ADS_MODLIST *mods,
361 NT_PRINTER_DATA *data)
363 uint32 key,val;
365 for (key=0; key < data->num_keys; key++) {
366 REGVAL_CTR *ctr = data->keys[key].values;
367 for (val=0; val < ctr->num_values; val++)
368 map_regval_to_ads(mem_ctx, mods, ctr->values[val]);
370 return True;
373 #endif