libads/ldap_printer.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    ads (active directory) printer utility library
00004    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
00005    
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015    
00016    You should have received a copy of the GNU General Public License
00017    along with this program; if not, write to the Free Software
00018    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019 */
00020 
00021 #include "includes.h"
00022 
00023 #ifdef HAVE_ADS
00024 
00025 /*
00026   find a printer given the name and the hostname
00027     Note that results "res" may be allocated on return so that the
00028     results can be used.  It should be freed using ads_msgfree.
00029 */
00030  ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, LDAPMessage **res,
00031                                        const char *printer,
00032                                        const char *servername)
00033 {
00034         ADS_STATUS status;
00035         char *srv_dn, **srv_cn, *s;
00036         const char *attrs[] = {"*", "nTSecurityDescriptor", NULL};
00037 
00038         status = ads_find_machine_acct(ads, res, servername);
00039         if (!ADS_ERR_OK(status)) {
00040                 DEBUG(1, ("ads_find_printer_on_server: cannot find host %s in ads\n",
00041                           servername));
00042                 return status;
00043         }
00044         if (ads_count_replies(ads, *res) != 1) {
00045                 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
00046         }
00047         srv_dn = ldap_get_dn(ads->ld, *res);
00048         if (srv_dn == NULL) {
00049                 return ADS_ERROR(LDAP_NO_MEMORY);
00050         }
00051         srv_cn = ldap_explode_dn(srv_dn, 1);
00052         if (srv_cn == NULL) {
00053                 ldap_memfree(srv_dn);
00054                 return ADS_ERROR(LDAP_INVALID_DN_SYNTAX);
00055         }
00056         ads_msgfree(ads, *res);
00057 
00058         asprintf(&s, "(cn=%s-%s)", srv_cn[0], printer);
00059         status = ads_search(ads, res, s, attrs);
00060 
00061         ldap_memfree(srv_dn);
00062         ldap_value_free(srv_cn);
00063         free(s);
00064         return status;  
00065 }
00066 
00067  ADS_STATUS ads_find_printers(ADS_STRUCT *ads, LDAPMessage **res)
00068 {
00069         const char *ldap_expr;
00070         const char *attrs[] = { "objectClass", "printerName", "location", "driverName",
00071                                 "serverName", "description", NULL };
00072 
00073         /* For the moment only display all printers */
00074 
00075         ldap_expr = "(&(!(showInAdvancedViewOnly=TRUE))(uncName=*)"
00076                 "(objectCategory=printQueue))";
00077 
00078         return ads_search(ads, res, ldap_expr, attrs);
00079 }
00080 
00081 /*
00082   modify a printer entry in the directory
00083 */
00084 ADS_STATUS ads_mod_printer_entry(ADS_STRUCT *ads, char *prt_dn,
00085                                  TALLOC_CTX *ctx, const ADS_MODLIST *mods)
00086 {
00087         return ads_gen_mod(ads, prt_dn, *mods);
00088 }
00089 
00090 /*
00091   add a printer to the directory
00092 */
00093 ADS_STATUS ads_add_printer_entry(ADS_STRUCT *ads, char *prt_dn,
00094                                         TALLOC_CTX *ctx, ADS_MODLIST *mods)
00095 {
00096         ads_mod_str(ctx, mods, "objectClass", "printQueue");
00097         return ads_gen_add(ads, prt_dn, *mods);
00098 }
00099 
00100 /*
00101   map a REG_SZ to an ldap mod
00102 */
00103 static BOOL map_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods, 
00104                             const REGISTRY_VALUE *value)
00105 {
00106         char *str_value = NULL;
00107         ADS_STATUS status;
00108 
00109         if (value->type != REG_SZ)
00110                 return False;
00111 
00112         if (value->size && *((smb_ucs2_t *) value->data_p)) {
00113                 pull_ucs2_talloc(ctx, &str_value, (const smb_ucs2_t *) value->data_p);
00114                 status = ads_mod_str(ctx, mods, value->valuename, str_value);
00115                 return ADS_ERR_OK(status);
00116         }
00117         return True;
00118                 
00119 }
00120 
00121 /*
00122   map a REG_DWORD to an ldap mod
00123 */
00124 static BOOL map_dword(TALLOC_CTX *ctx, ADS_MODLIST *mods, 
00125                       const REGISTRY_VALUE *value)
00126 {
00127         char *str_value = NULL;
00128         ADS_STATUS status;
00129 
00130         if (value->type != REG_DWORD)
00131                 return False;
00132         str_value = talloc_asprintf(ctx, "%d", *((uint32 *) value->data_p));
00133         if (!str_value) {
00134                 return False;
00135         }
00136         status = ads_mod_str(ctx, mods, value->valuename, str_value);
00137         return ADS_ERR_OK(status);
00138 }
00139 
00140 /*
00141   map a boolean REG_BINARY to an ldap mod
00142 */
00143 static BOOL map_bool(TALLOC_CTX *ctx, ADS_MODLIST *mods,
00144                      const REGISTRY_VALUE *value)
00145 {
00146         char *str_value;
00147         ADS_STATUS status;
00148 
00149         if ((value->type != REG_BINARY) || (value->size != 1))
00150                 return False;
00151         str_value =  talloc_asprintf(ctx, "%s", 
00152                                      *(value->data_p) ? "TRUE" : "FALSE");
00153         if (!str_value) {
00154                 return False;
00155         }
00156         status = ads_mod_str(ctx, mods, value->valuename, str_value);
00157         return ADS_ERR_OK(status);
00158 }
00159 
00160 /*
00161   map a REG_MULTI_SZ to an ldap mod
00162 */
00163 static BOOL map_multi_sz(TALLOC_CTX *ctx, ADS_MODLIST *mods,
00164                          const REGISTRY_VALUE *value)
00165 {
00166         char **str_values = NULL;
00167         smb_ucs2_t *cur_str = (smb_ucs2_t *) value->data_p;
00168         uint32 size = 0, num_vals = 0, i=0;
00169         ADS_STATUS status;
00170 
00171         if (value->type != REG_MULTI_SZ)
00172                 return False;
00173 
00174         while(cur_str && *cur_str && (size < value->size)) {            
00175                 size += 2 * (strlen_w(cur_str) + 1);
00176                 cur_str += strlen_w(cur_str) + 1;
00177                 num_vals++;
00178         };
00179 
00180         if (num_vals) {
00181                 str_values = TALLOC_ARRAY(ctx, char *, num_vals + 1);
00182                 if (!str_values) {
00183                         return False;
00184                 }
00185                 memset(str_values, '\0', 
00186                        (num_vals + 1) * sizeof(char *));
00187 
00188                 cur_str = (smb_ucs2_t *) value->data_p;
00189                 for (i=0; i < num_vals; i++)
00190                         cur_str += pull_ucs2_talloc(ctx, &str_values[i],
00191                                                     cur_str);
00192 
00193                 status = ads_mod_strlist(ctx, mods, value->valuename, 
00194                                          (const char **) str_values);
00195                 return ADS_ERR_OK(status);
00196         } 
00197         return True;
00198 }
00199 
00200 struct valmap_to_ads {
00201         const char *valname;
00202         BOOL (*fn)(TALLOC_CTX *, ADS_MODLIST *, const REGISTRY_VALUE *);
00203 };
00204 
00205 /*
00206   map a REG_SZ to an ldap mod
00207 */
00208 static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods, 
00209                               REGISTRY_VALUE *value)
00210 {
00211         const struct valmap_to_ads map[] = {
00212                 {SPOOL_REG_ASSETNUMBER, map_sz},
00213                 {SPOOL_REG_BYTESPERMINUTE, map_dword},
00214                 {SPOOL_REG_DEFAULTPRIORITY, map_dword},
00215                 {SPOOL_REG_DESCRIPTION, map_sz},
00216                 {SPOOL_REG_DRIVERNAME, map_sz},
00217                 {SPOOL_REG_DRIVERVERSION, map_dword},
00218                 {SPOOL_REG_FLAGS, map_dword},
00219                 {SPOOL_REG_LOCATION, map_sz},
00220                 {SPOOL_REG_OPERATINGSYSTEM, map_sz},
00221                 {SPOOL_REG_OPERATINGSYSTEMHOTFIX, map_sz},
00222                 {SPOOL_REG_OPERATINGSYSTEMSERVICEPACK, map_sz},
00223                 {SPOOL_REG_OPERATINGSYSTEMVERSION, map_sz},
00224                 {SPOOL_REG_PORTNAME, map_multi_sz},
00225                 {SPOOL_REG_PRINTATTRIBUTES, map_dword},
00226                 {SPOOL_REG_PRINTBINNAMES, map_multi_sz},
00227                 {SPOOL_REG_PRINTCOLLATE, map_bool},
00228                 {SPOOL_REG_PRINTCOLOR, map_bool},
00229                 {SPOOL_REG_PRINTDUPLEXSUPPORTED, map_bool},
00230                 {SPOOL_REG_PRINTENDTIME, map_dword},
00231                 {SPOOL_REG_PRINTFORMNAME, map_sz},
00232                 {SPOOL_REG_PRINTKEEPPRINTEDJOBS, map_bool},
00233                 {SPOOL_REG_PRINTLANGUAGE, map_multi_sz},
00234                 {SPOOL_REG_PRINTMACADDRESS, map_sz},
00235                 {SPOOL_REG_PRINTMAXCOPIES, map_sz},
00236                 {SPOOL_REG_PRINTMAXRESOLUTIONSUPPORTED, map_dword},
00237                 {SPOOL_REG_PRINTMAXXEXTENT, map_dword},
00238                 {SPOOL_REG_PRINTMAXYEXTENT, map_dword},
00239                 {SPOOL_REG_PRINTMEDIAREADY, map_multi_sz},
00240                 {SPOOL_REG_PRINTMEDIASUPPORTED, map_multi_sz},
00241                 {SPOOL_REG_PRINTMEMORY, map_dword},
00242                 {SPOOL_REG_PRINTMINXEXTENT, map_dword},
00243                 {SPOOL_REG_PRINTMINYEXTENT, map_dword},
00244                 {SPOOL_REG_PRINTNETWORKADDRESS, map_sz},
00245                 {SPOOL_REG_PRINTNOTIFY, map_sz},
00246                 {SPOOL_REG_PRINTNUMBERUP, map_dword},
00247                 {SPOOL_REG_PRINTORIENTATIONSSUPPORTED, map_multi_sz},
00248                 {SPOOL_REG_PRINTOWNER, map_sz},
00249                 {SPOOL_REG_PRINTPAGESPERMINUTE, map_dword},
00250                 {SPOOL_REG_PRINTRATE, map_dword},
00251                 {SPOOL_REG_PRINTRATEUNIT, map_sz},
00252                 {SPOOL_REG_PRINTSEPARATORFILE, map_sz},
00253                 {SPOOL_REG_PRINTSHARENAME, map_sz},
00254                 {SPOOL_REG_PRINTSPOOLING, map_sz},
00255                 {SPOOL_REG_PRINTSTAPLINGSUPPORTED, map_bool},
00256                 {SPOOL_REG_PRINTSTARTTIME, map_dword},
00257                 {SPOOL_REG_PRINTSTATUS, map_sz},
00258                 {SPOOL_REG_PRIORITY, map_dword},
00259                 {SPOOL_REG_SERVERNAME, map_sz},
00260                 {SPOOL_REG_SHORTSERVERNAME, map_sz},
00261                 {SPOOL_REG_UNCNAME, map_sz},
00262                 {SPOOL_REG_URL, map_sz},
00263                 {SPOOL_REG_VERSIONNUMBER, map_dword},
00264                 {NULL, NULL}
00265         };
00266         int i;
00267 
00268         for (i=0; map[i].valname; i++) {
00269                 if (StrCaseCmp(map[i].valname, value->valuename) == 0) {
00270                         if (!map[i].fn(ctx, mods, value)) {
00271                                 DEBUG(5, ("Add of value %s to modlist failed\n", value->valuename));
00272                         } else {
00273                                 DEBUG(7, ("Mapped value %s\n", value->valuename));
00274                         }
00275                         
00276                 }
00277         }
00278 }
00279 
00280 
00281 WERROR get_remote_printer_publishing_data(struct rpc_pipe_client *cli, 
00282                                           TALLOC_CTX *mem_ctx,
00283                                           ADS_MODLIST *mods,
00284                                           const char *printer)
00285 {
00286         WERROR result;
00287         char *printername, *servername;
00288         REGVAL_CTR *dsdriver_ctr, *dsspooler_ctr;
00289         uint32 i;
00290         POLICY_HND pol;
00291 
00292         asprintf(&servername, "\\\\%s", cli->cli->desthost);
00293         asprintf(&printername, "%s\\%s", servername, printer);
00294         if (!servername || !printername) {
00295                 DEBUG(3, ("Insufficient memory\n"));
00296                 return WERR_NOMEM;
00297         }
00298         
00299         result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername, 
00300                                              "", MAXIMUM_ALLOWED_ACCESS, 
00301                                              servername, cli->cli->user_name, &pol);
00302         if (!W_ERROR_IS_OK(result)) {
00303                 DEBUG(3, ("Unable to open printer %s, error is %s.\n",
00304                           printername, dos_errstr(result)));
00305                 return result;
00306         }
00307         
00308         if ( !(dsdriver_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) ) 
00309                 return WERR_NOMEM;
00310 
00311         result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSDRIVER_KEY, dsdriver_ctr);
00312 
00313         if (!W_ERROR_IS_OK(result)) {
00314                 DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
00315                           printername, dos_errstr(result)));
00316         } else {
00317                 uint32 num_values = regval_ctr_numvals( dsdriver_ctr );
00318 
00319                 /* Have the data we need now, so start building */
00320                 for (i=0; i < num_values; i++) {
00321                         map_regval_to_ads(mem_ctx, mods, dsdriver_ctr->values[i]);
00322                 }
00323         }
00324         
00325         if ( !(dsspooler_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) )
00326                 return WERR_NOMEM;
00327 
00328         result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSSPOOLER_KEY, dsspooler_ctr);
00329 
00330         if (!W_ERROR_IS_OK(result)) {
00331                 DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
00332                           printername, dos_errstr(result)));
00333         } else {
00334                 uint32 num_values = regval_ctr_numvals( dsspooler_ctr );
00335 
00336                 for (i=0; i<num_values; i++) {
00337                         map_regval_to_ads(mem_ctx, mods, dsspooler_ctr->values[i]);
00338                 }
00339         }
00340         
00341         ads_mod_str(mem_ctx, mods, SPOOL_REG_PRINTERNAME, printer);
00342 
00343         TALLOC_FREE( dsdriver_ctr );
00344         TALLOC_FREE( dsspooler_ctr );
00345 
00346         rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
00347 
00348         return result;
00349 }
00350 
00351 BOOL get_local_printer_publishing_data(TALLOC_CTX *mem_ctx,
00352                                        ADS_MODLIST *mods,
00353                                        NT_PRINTER_DATA *data)
00354 {
00355         uint32 key,val;
00356 
00357         for (key=0; key < data->num_keys; key++) {
00358                 REGVAL_CTR *ctr = data->keys[key].values;
00359                 for (val=0; val < ctr->num_values; val++)
00360                         map_regval_to_ads(mem_ctx, mods, ctr->values[val]);
00361         }
00362         return True;
00363 }
00364 
00365 #endif

Sambaに対してSat Aug 29 21:23:01 2009に生成されました。  doxygen 1.4.7