r20136: Fix #4290. Properly compute time to password expiration in message from
[Samba/bb.git] / source3 / libads / ldap_printer.c
blobf5168b05af0cf45abe98b6d024416e1175f07102
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 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, LDAPMessage **res,
31 const char *printer,
32 const char *servername)
34 ADS_STATUS status;
35 char *srv_dn, **srv_cn, *s;
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 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
47 srv_dn = ldap_get_dn(ads->ld, *res);
48 if (srv_dn == NULL) {
49 return ADS_ERROR(LDAP_NO_MEMORY);
51 srv_cn = ldap_explode_dn(srv_dn, 1);
52 if (srv_cn == NULL) {
53 ldap_memfree(srv_dn);
54 return ADS_ERROR(LDAP_INVALID_DN_SYNTAX);
56 ads_msgfree(ads, *res);
58 asprintf(&s, "(cn=%s-%s)", srv_cn[0], printer);
59 status = ads_search(ads, res, s, attrs);
61 ldap_memfree(srv_dn);
62 ldap_value_free(srv_cn);
63 free(s);
64 return status;
67 ADS_STATUS ads_find_printers(ADS_STRUCT *ads, LDAPMessage **res)
69 const char *ldap_expr;
70 const char *attrs[] = { "objectClass", "printerName", "location", "driverName",
71 "serverName", "description", NULL };
73 /* For the moment only display all printers */
75 ldap_expr = "(&(!(showInAdvancedViewOnly=TRUE))(uncName=*)"
76 "(objectCategory=printQueue))";
78 return ads_search(ads, res, ldap_expr, attrs);
82 modify a printer entry in the directory
84 ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn,
85 TALLOC_CTX *ctx, const ADS_MODLIST *mods)
87 return ads_gen_mod(ads, prt_dn, *mods);
91 add a printer to the directory
93 ADS_STATUS ads_add_printer_entry(ADS_STRUCT *ads, char *prt_dn,
94 TALLOC_CTX *ctx, ADS_MODLIST *mods)
96 ads_mod_str(ctx, mods, "objectClass", "printQueue");
97 return ads_gen_add(ads, prt_dn, *mods);
101 map a REG_SZ to an ldap mod
103 static BOOL map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods,
104 const REGISTRY_VALUE *value)
106 char *str_value = NULL;
107 ADS_STATUS status;
109 if (value->type != REG_SZ)
110 return False;
112 if (value->size && *((smb_ucs2_t *) value->data_p)) {
113 pull_ucs2_talloc(ctx, &str_value, (const smb_ucs2_t *) value->data_p);
114 status = ads_mod_str(ctx, mods, value->valuename, str_value);
115 return ADS_ERR_OK(status);
117 return True;
122 map a REG_DWORD to an ldap mod
124 static BOOL map_dword(TALLOC_CTX *ctx, ADS_MODLIST *mods,
125 const REGISTRY_VALUE *value)
127 char *str_value = NULL;
128 ADS_STATUS status;
130 if (value->type != REG_DWORD)
131 return False;
132 str_value = talloc_asprintf(ctx, "%d", *((uint32 *) value->data_p));
133 if (!str_value) {
134 return False;
136 status = ads_mod_str(ctx, mods, value->valuename, str_value);
137 return ADS_ERR_OK(status);
141 map a boolean REG_BINARY to an ldap mod
143 static BOOL map_bool(TALLOC_CTX *ctx, ADS_MODLIST *mods,
144 const REGISTRY_VALUE *value)
146 char *str_value;
147 ADS_STATUS status;
149 if ((value->type != REG_BINARY) || (value->size != 1))
150 return False;
151 str_value = talloc_asprintf(ctx, "%s",
152 *(value->data_p) ? "TRUE" : "FALSE");
153 if (!str_value) {
154 return False;
156 status = ads_mod_str(ctx, mods, value->valuename, str_value);
157 return ADS_ERR_OK(status);
161 map a REG_MULTI_SZ to an ldap mod
163 static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods,
164 const REGISTRY_VALUE *value)
166 char **str_values = NULL;
167 smb_ucs2_t *cur_str = (smb_ucs2_t *) value->data_p;
168 uint32 size = 0, num_vals = 0, i=0;
169 ADS_STATUS status;
171 if (value->type != REG_MULTI_SZ)
172 return False;
174 while(cur_str && *cur_str && (size < value->size)) {
175 size += 2 * (strlen_w(cur_str) + 1);
176 cur_str += strlen_w(cur_str) + 1;
177 num_vals++;
180 if (num_vals) {
181 str_values = TALLOC_ARRAY(ctx, char *, num_vals + 1);
182 if (!str_values) {
183 return False;
185 memset(str_values, '\0',
186 (num_vals + 1) * sizeof(char *));
188 cur_str = (smb_ucs2_t *) value->data_p;
189 for (i=0; i < num_vals; i++)
190 cur_str += pull_ucs2_talloc(ctx, &str_values[i],
191 cur_str);
193 status = ads_mod_strlist(ctx, mods, value->valuename,
194 (const char **) str_values);
195 return ADS_ERR_OK(status);
197 return True;
200 struct valmap_to_ads {
201 const char *valname;
202 BOOL (*fn)(TALLOC_CTX *, ADS_MODLIST *, const REGISTRY_VALUE *);
206 map a REG_SZ to an ldap mod
208 static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods,
209 REGISTRY_VALUE *value)
211 const struct valmap_to_ads map[] = {
212 {SPOOL_REG_ASSETNUMBER, map_sz},
213 {SPOOL_REG_BYTESPERMINUTE, map_dword},
214 {SPOOL_REG_DEFAULTPRIORITY, map_dword},
215 {SPOOL_REG_DESCRIPTION, map_sz},
216 {SPOOL_REG_DRIVERNAME, map_sz},
217 {SPOOL_REG_DRIVERVERSION, map_dword},
218 {SPOOL_REG_FLAGS, map_dword},
219 {SPOOL_REG_LOCATION, map_sz},
220 {SPOOL_REG_OPERATINGSYSTEM, map_sz},
221 {SPOOL_REG_OPERATINGSYSTEMHOTFIX, map_sz},
222 {SPOOL_REG_OPERATINGSYSTEMSERVICEPACK, map_sz},
223 {SPOOL_REG_OPERATINGSYSTEMVERSION, map_sz},
224 {SPOOL_REG_PORTNAME, map_multi_sz},
225 {SPOOL_REG_PRINTATTRIBUTES, map_dword},
226 {SPOOL_REG_PRINTBINNAMES, map_multi_sz},
227 {SPOOL_REG_PRINTCOLLATE, map_bool},
228 {SPOOL_REG_PRINTCOLOR, map_bool},
229 {SPOOL_REG_PRINTDUPLEXSUPPORTED, map_bool},
230 {SPOOL_REG_PRINTENDTIME, map_dword},
231 {SPOOL_REG_PRINTFORMNAME, map_sz},
232 {SPOOL_REG_PRINTKEEPPRINTEDJOBS, map_bool},
233 {SPOOL_REG_PRINTLANGUAGE, map_multi_sz},
234 {SPOOL_REG_PRINTMACADDRESS, map_sz},
235 {SPOOL_REG_PRINTMAXCOPIES, map_sz},
236 {SPOOL_REG_PRINTMAXRESOLUTIONSUPPORTED, map_dword},
237 {SPOOL_REG_PRINTMAXXEXTENT, map_dword},
238 {SPOOL_REG_PRINTMAXYEXTENT, map_dword},
239 {SPOOL_REG_PRINTMEDIAREADY, map_multi_sz},
240 {SPOOL_REG_PRINTMEDIASUPPORTED, map_multi_sz},
241 {SPOOL_REG_PRINTMEMORY, map_dword},
242 {SPOOL_REG_PRINTMINXEXTENT, map_dword},
243 {SPOOL_REG_PRINTMINYEXTENT, map_dword},
244 {SPOOL_REG_PRINTNETWORKADDRESS, map_sz},
245 {SPOOL_REG_PRINTNOTIFY, map_sz},
246 {SPOOL_REG_PRINTNUMBERUP, map_dword},
247 {SPOOL_REG_PRINTORIENTATIONSSUPPORTED, map_multi_sz},
248 {SPOOL_REG_PRINTOWNER, map_sz},
249 {SPOOL_REG_PRINTPAGESPERMINUTE, map_dword},
250 {SPOOL_REG_PRINTRATE, map_dword},
251 {SPOOL_REG_PRINTRATEUNIT, map_sz},
252 {SPOOL_REG_PRINTSEPARATORFILE, map_sz},
253 {SPOOL_REG_PRINTSHARENAME, map_sz},
254 {SPOOL_REG_PRINTSPOOLING, map_sz},
255 {SPOOL_REG_PRINTSTAPLINGSUPPORTED, map_bool},
256 {SPOOL_REG_PRINTSTARTTIME, map_dword},
257 {SPOOL_REG_PRINTSTATUS, map_sz},
258 {SPOOL_REG_PRIORITY, map_dword},
259 {SPOOL_REG_SERVERNAME, map_sz},
260 {SPOOL_REG_SHORTSERVERNAME, map_sz},
261 {SPOOL_REG_UNCNAME, map_sz},
262 {SPOOL_REG_URL, map_sz},
263 {SPOOL_REG_VERSIONNUMBER, map_dword},
264 {NULL, NULL}
266 int i;
268 for (i=0; map[i].valname; i++) {
269 if (StrCaseCmp(map[i].valname, value->valuename) == 0) {
270 if (!map[i].fn(ctx, mods, value)) {
271 DEBUG(5, ("Add of value %s to modlist failed\n", value->valuename));
272 } else {
273 DEBUG(7, ("Mapped value %s\n", value->valuename));
281 WERROR get_remote_printer_publishing_data(struct rpc_pipe_client *cli,
282 TALLOC_CTX *mem_ctx,
283 ADS_MODLIST *mods,
284 const char *printer)
286 WERROR result;
287 char *printername, *servername;
288 REGVAL_CTR *dsdriver_ctr, *dsspooler_ctr;
289 uint32 i;
290 POLICY_HND pol;
292 asprintf(&servername, "\\\\%s", cli->cli->desthost);
293 asprintf(&printername, "%s\\%s", servername, printer);
294 if (!servername || !printername) {
295 DEBUG(3, ("Insufficient memory\n"));
296 return WERR_NOMEM;
299 result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
300 "", MAXIMUM_ALLOWED_ACCESS,
301 servername, cli->cli->user_name, &pol);
302 if (!W_ERROR_IS_OK(result)) {
303 DEBUG(3, ("Unable to open printer %s, error is %s.\n",
304 printername, dos_errstr(result)));
305 return result;
308 if ( !(dsdriver_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) )
309 return WERR_NOMEM;
311 result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSDRIVER_KEY, dsdriver_ctr);
313 if (!W_ERROR_IS_OK(result)) {
314 DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
315 printername, dos_errstr(result)));
316 } else {
317 uint32 num_values = regval_ctr_numvals( dsdriver_ctr );
319 /* Have the data we need now, so start building */
320 for (i=0; i < num_values; i++) {
321 map_regval_to_ads(mem_ctx, mods, dsdriver_ctr->values[i]);
325 if ( !(dsspooler_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) )
326 return WERR_NOMEM;
328 result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSSPOOLER_KEY, dsspooler_ctr);
330 if (!W_ERROR_IS_OK(result)) {
331 DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
332 printername, dos_errstr(result)));
333 } else {
334 uint32 num_values = regval_ctr_numvals( dsspooler_ctr );
336 for (i=0; i<num_values; i++) {
337 map_regval_to_ads(mem_ctx, mods, dsspooler_ctr->values[i]);
341 ads_mod_str(mem_ctx, mods, SPOOL_REG_PRINTERNAME, printer);
343 TALLOC_FREE( dsdriver_ctr );
344 TALLOC_FREE( dsspooler_ctr );
346 rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
348 return result;
351 BOOL get_local_printer_publishing_data(TALLOC_CTX *mem_ctx,
352 ADS_MODLIST *mods,
353 NT_PRINTER_DATA *data)
355 uint32 key,val;
357 for (key=0; key < data->num_keys; key++) {
358 REGVAL_CTR *ctr = data->keys[key].values;
359 for (val=0; val < ctr->num_values; val++)
360 map_regval_to_ads(mem_ctx, mods, ctr->values[val]);
362 return True;
365 #endif