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
, &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
);
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
;
105 if (value
->type
!= REG_DWORD
)
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
)
121 if ((value
->type
!= REG_BINARY
) || (value
->size
!= 1))
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;
140 if (value
->type
!= REG_MULTI_SZ
)
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;
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
],
160 status
= ads_mod_strlist(ctx
, mods
, value
->valuename
,
161 (const char **) str_values
);
162 return ADS_ERR_OK(status
);
167 struct valmap_to_ads
{
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
},
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
));
240 DEBUG(7, ("Mapped value %s\n", value
->valuename
));
248 WERROR
get_remote_printer_publishing_data(struct cli_state
*cli
,
254 char *printername
, *servername
;
255 REGVAL_CTR dsdriver_ctr
, dsspooler_ctr
;
256 BOOL got_dsdriver
= False
, got_dsspooler
= False
;
260 asprintf(&servername
, "\\\\%s", cli
->desthost
);
261 asprintf(&printername
, "%s\\%s", servername
, printer
);
262 if (!servername
|| !printername
) {
263 DEBUG(3, ("Insufficient memory\n"));
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
)));
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
,
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
)));
290 /* Have the data we need now, so start building */
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
,
301 if (W_ERROR_V(result
) == ERRmoredata
)
302 result
= cli_spoolss_enumprinterdataex(cli
, mem_ctx
, needed
,
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
)));
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
);
326 BOOL
get_local_printer_publishing_data(TALLOC_CTX
*mem_ctx
,
328 NT_PRINTER_DATA
*data
)
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
]);