00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "includes.h"
00024
00025 extern struct current_user current_user;
00026
00027 static TDB_CONTEXT *tdb_forms;
00028 static TDB_CONTEXT *tdb_drivers;
00029 static TDB_CONTEXT *tdb_printers;
00030
00031 #define FORMS_PREFIX "FORMS/"
00032 #define DRIVERS_PREFIX "DRIVERS/"
00033 #define DRIVER_INIT_PREFIX "DRIVER_INIT/"
00034 #define PRINTERS_PREFIX "PRINTERS/"
00035 #define SECDESC_PREFIX "SECDESC/"
00036 #define GLOBAL_C_SETPRINTER "GLOBALS/c_setprinter"
00037
00038 #define NTDRIVERS_DATABASE_VERSION_1 1
00039 #define NTDRIVERS_DATABASE_VERSION_2 2
00040 #define NTDRIVERS_DATABASE_VERSION_3 3
00041 #define NTDRIVERS_DATABASE_VERSION_4 4
00042 #define NTDRIVERS_DATABASE_VERSION_5 5
00043
00044
00045
00046 GENERIC_MAPPING printer_generic_mapping = {
00047 PRINTER_READ,
00048 PRINTER_WRITE,
00049 PRINTER_EXECUTE,
00050 PRINTER_ALL_ACCESS
00051 };
00052
00053 STANDARD_MAPPING printer_std_mapping = {
00054 PRINTER_READ,
00055 PRINTER_WRITE,
00056 PRINTER_EXECUTE,
00057 PRINTER_ALL_ACCESS
00058 };
00059
00060
00061
00062 GENERIC_MAPPING printserver_generic_mapping = {
00063 SERVER_READ,
00064 SERVER_WRITE,
00065 SERVER_EXECUTE,
00066 SERVER_ALL_ACCESS
00067 };
00068
00069 STANDARD_MAPPING printserver_std_mapping = {
00070 SERVER_READ,
00071 SERVER_WRITE,
00072 SERVER_EXECUTE,
00073 SERVER_ALL_ACCESS
00074 };
00075
00076
00077
00078 GENERIC_MAPPING job_generic_mapping = {
00079 JOB_READ,
00080 JOB_WRITE,
00081 JOB_EXECUTE,
00082 JOB_ALL_ACCESS
00083 };
00084
00085
00086
00087
00088
00089 static const nt_forms_struct default_forms[] = {
00090 {"Letter",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
00091 {"Letter Small",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
00092 {"Tabloid",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
00093 {"Ledger",0x1,0x696b8,0x44368,0x0,0x0,0x696b8,0x44368},
00094 {"Legal",0x1,0x34b5c,0x56d10,0x0,0x0,0x34b5c,0x56d10},
00095 {"Statement",0x1,0x221b4,0x34b5c,0x0,0x0,0x221b4,0x34b5c},
00096 {"Executive",0x1,0x2cf56,0x411cc,0x0,0x0,0x2cf56,0x411cc},
00097 {"A3",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
00098 {"A4",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
00099 {"A4 Small",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
00100 {"A5",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
00101 {"B4 (JIS)",0x1,0x3ebe8,0x58de0,0x0,0x0,0x3ebe8,0x58de0},
00102 {"B5 (JIS)",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
00103 {"Folio",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
00104 {"Quarto",0x1,0x347d8,0x43238,0x0,0x0,0x347d8,0x43238},
00105 {"10x14",0x1,0x3e030,0x56d10,0x0,0x0,0x3e030,0x56d10},
00106 {"11x17",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
00107 {"Note",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
00108 {"Envelope #9",0x1,0x18079,0x37091,0x0,0x0,0x18079,0x37091},
00109 {"Envelope #10",0x1,0x19947,0x3ae94,0x0,0x0,0x19947,0x3ae94},
00110 {"Envelope #11",0x1,0x1be7c,0x40565,0x0,0x0,0x1be7c,0x40565},
00111 {"Envelope #12",0x1,0x1d74a,0x44368,0x0,0x0,0x1d74a,0x44368},
00112 {"Envelope #14",0x1,0x1f018,0x47504,0x0,0x0,0x1f018,0x47504},
00113 {"C size sheet",0x1,0x696b8,0x886d0,0x0,0x0,0x696b8,0x886d0},
00114 {"D size sheet",0x1,0x886d0,0xd2d70,0x0,0x0,0x886d0,0xd2d70},
00115 {"E size sheet",0x1,0xd2d70,0x110da0,0x0,0x0,0xd2d70,0x110da0},
00116 {"Envelope DL",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
00117 {"Envelope C5",0x1,0x278d0,0x37e88,0x0,0x0,0x278d0,0x37e88},
00118 {"Envelope C3",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
00119 {"Envelope C4",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
00120 {"Envelope C6",0x1,0x1bd50,0x278d0,0x0,0x0,0x1bd50,0x278d0},
00121 {"Envelope C65",0x1,0x1bd50,0x37e88,0x0,0x0,0x1bd50,0x37e88},
00122 {"Envelope B4",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
00123 {"Envelope B5",0x1,0x2af80,0x3d090,0x0,0x0,0x2af80,0x3d090},
00124 {"Envelope B6",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
00125 {"Envelope",0x1,0x1adb0,0x38270,0x0,0x0,0x1adb0,0x38270},
00126 {"Envelope Monarch",0x1,0x18079,0x2e824,0x0,0x0,0x18079,0x2e824},
00127 {"6 3/4 Envelope",0x1,0x167ab,0x284ec,0x0,0x0,0x167ab,0x284ec},
00128 {"US Std Fanfold",0x1,0x5c3e1,0x44368,0x0,0x0,0x5c3e1,0x44368},
00129 {"German Std Fanfold",0x1,0x34b5c,0x4a6a0,0x0,0x0,0x34b5c,0x4a6a0},
00130 {"German Legal Fanfold",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
00131 {"B4 (ISO)",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
00132 {"Japanese Postcard",0x1,0x186a0,0x24220,0x0,0x0,0x186a0,0x24220},
00133 {"9x11",0x1,0x37cf8,0x44368,0x0,0x0,0x37cf8,0x44368},
00134 {"10x11",0x1,0x3e030,0x44368,0x0,0x0,0x3e030,0x44368},
00135 {"15x11",0x1,0x5d048,0x44368,0x0,0x0,0x5d048,0x44368},
00136 {"Envelope Invite",0x1,0x35b60,0x35b60,0x0,0x0,0x35b60,0x35b60},
00137 {"Reserved48",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
00138 {"Reserved49",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
00139 {"Letter Extra",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
00140 {"Legal Extra",0x1,0x3ae94,0x5d048,0x0,0x0,0x3ae94,0x5d048},
00141 {"Tabloid Extra",0x1,0x4a6a0,0x6f9f0,0x0,0x0,0x4a6a0,0x6f9f0},
00142 {"A4 Extra",0x1,0x397c2,0x4eb16,0x0,0x0,0x397c2,0x4eb16},
00143 {"Letter Transverse",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
00144 {"A4 Transverse",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
00145 {"Letter Extra Transverse",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
00146 {"Super A",0x1,0x376b8,0x56ea0,0x0,0x0,0x376b8,0x56ea0},
00147 {"Super B",0x1,0x4a768,0x76e58,0x0,0x0,0x4a768,0x76e58},
00148 {"Letter Plus",0x1,0x34b5c,0x4eb16,0x0,0x0,0x34b5c,0x4eb16},
00149 {"A4 Plus",0x1,0x33450,0x50910,0x0,0x0,0x33450,0x50910},
00150 {"A5 Transverse",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
00151 {"B5 (JIS) Transverse",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
00152 {"A3 Extra",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
00153 {"A5 Extra",0x1,0x2a7b0,0x395f8,0x0,0x0,0x2a7b0,0x395f8},
00154 {"B5 (ISO) Extra",0x1,0x31128,0x43620,0x0,0x0,0x31128,0x43620},
00155 {"A2",0x1,0x668a0,0x91050,0x0,0x0,0x668a0,0x91050},
00156 {"A3 Transverse",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
00157 {"A3 Extra Transverse",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
00158 {"Japanese Double Postcard",0x1,0x30d40,0x24220,0x0,0x0,0x30d40,0x24220},
00159 {"A6",0x1,0x19a28,0x24220,0x0,0x0,0x19a28,0x24220},
00160 {"Japanese Envelope Kaku #2",0x1,0x3a980,0x510e0,0x0,0x0,0x3a980,0x510e0},
00161 {"Japanese Envelope Kaku #3",0x1,0x34bc0,0x43a08,0x0,0x0,0x34bc0,0x43a08},
00162 {"Japanese Envelope Chou #3",0x1,0x1d4c0,0x395f8,0x0,0x0,0x1d4c0,0x395f8},
00163 {"Japanese Envelope Chou #4",0x1,0x15f90,0x320c8,0x0,0x0,0x15f90,0x320c8},
00164 {"Letter Rotated",0x1,0x44368,0x34b5c,0x0,0x0,0x44368,0x34b5c},
00165 {"A3 Rotated",0x1,0x668a0,0x48828,0x0,0x0,0x668a0,0x48828},
00166 {"A4 Rotated",0x1,0x48828,0x33450,0x0,0x0,0x48828,0x33450},
00167 {"A5 Rotated",0x1,0x33450,0x24220,0x0,0x0,0x33450,0x24220},
00168 {"B4 (JIS) Rotated",0x1,0x58de0,0x3ebe8,0x0,0x0,0x58de0,0x3ebe8},
00169 {"B5 (JIS) Rotated",0x1,0x3ebe8,0x2c6f0,0x0,0x0,0x3ebe8,0x2c6f0},
00170 {"Japanese Postcard Rotated",0x1,0x24220,0x186a0,0x0,0x0,0x24220,0x186a0},
00171 {"Double Japan Postcard Rotated",0x1,0x24220,0x30d40,0x0,0x0,0x24220,0x30d40},
00172 {"A6 Rotated",0x1,0x24220,0x19a28,0x0,0x0,0x24220,0x19a28},
00173 {"Japan Envelope Kaku #2 Rotated",0x1,0x510e0,0x3a980,0x0,0x0,0x510e0,0x3a980},
00174 {"Japan Envelope Kaku #3 Rotated",0x1,0x43a08,0x34bc0,0x0,0x0,0x43a08, 0x34bc0},
00175 {"Japan Envelope Chou #3 Rotated",0x1,0x395f8,0x1d4c0,0x0,0x0,0x395f8,0x1d4c0},
00176 {"Japan Envelope Chou #4 Rotated",0x1,0x320c8,0x15f90,0x0,0x0,0x320c8,0x15f90},
00177 {"B6 (JIS)",0x1,0x1f400,0x2c6f0,0x0,0x0,0x1f400,0x2c6f0},
00178 {"B6 (JIS) Rotated",0x1,0x2c6f0,0x1f400,0x0,0x0,0x2c6f0,0x1f400},
00179 {"12x11",0x1,0x4a724,0x443e1,0x0,0x0,0x4a724,0x443e1},
00180 {"Japan Envelope You #4",0x1,0x19a28,0x395f8,0x0,0x0,0x19a28,0x395f8},
00181 {"Japan Envelope You #4 Rotated",0x1,0x395f8,0x19a28,0x0,0x0,0x395f8,0x19a28},
00182 {"PRC 16K",0x1,0x2de60,0x3f7a0,0x0,0x0,0x2de60,0x3f7a0},
00183 {"PRC 32K",0x1,0x1fbd0,0x2cec0,0x0,0x0,0x1fbd0,0x2cec0},
00184 {"PRC 32K(Big)",0x1,0x222e0,0x318f8,0x0,0x0,0x222e0,0x318f8},
00185 {"PRC Envelope #1",0x1,0x18e70,0x28488,0x0,0x0,0x18e70,0x28488},
00186 {"PRC Envelope #2",0x1,0x18e70,0x2af80,0x0,0x0,0x18e70,0x2af80},
00187 {"PRC Envelope #3",0x1,0x1e848,0x2af80,0x0,0x0,0x1e848,0x2af80},
00188 {"PRC Envelope #4",0x1,0x1adb0,0x32c80,0x0,0x0,0x1adb0,0x32c80},
00189 {"PRC Envelope #5",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
00190 {"PRC Envelope #6",0x1,0x1d4c0,0x38270,0x0,0x0,0x1d4c0,0x38270},
00191 {"PRC Envelope #7",0x1,0x27100,0x38270,0x0,0x0,0x27100,0x38270},
00192 {"PRC Envelope #8",0x1,0x1d4c0,0x4b708,0x0,0x0,0x1d4c0,0x4b708},
00193 {"PRC Envelope #9",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
00194 {"PRC Envelope #10",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
00195 {"PRC 16K Rotated",0x1,0x3f7a0,0x2de60,0x0,0x0,0x3f7a0,0x2de60},
00196 {"PRC 32K Rotated",0x1,0x2cec0,0x1fbd0,0x0,0x0,0x2cec0,0x1fbd0},
00197 {"PRC 32K(Big) Rotated",0x1,0x318f8,0x222e0,0x0,0x0,0x318f8,0x222e0},
00198 {"PRC Envelope #1 Rotated",0x1,0x28488,0x18e70,0x0,0x0,0x28488,0x18e70},
00199 {"PRC Envelope #2 Rotated",0x1,0x2af80,0x18e70,0x0,0x0,0x2af80,0x18e70},
00200 {"PRC Envelope #3 Rotated",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
00201 {"PRC Envelope #4 Rotated",0x1,0x32c80,0x1adb0,0x0,0x0,0x32c80,0x1adb0},
00202 {"PRC Envelope #5 Rotated",0x1,0x35b60,0x1adb0,0x0,0x0,0x35b60,0x1adb0},
00203 {"PRC Envelope #6 Rotated",0x1,0x38270,0x1d4c0,0x0,0x0,0x38270,0x1d4c0},
00204 {"PRC Envelope #7 Rotated",0x1,0x38270,0x27100,0x0,0x0,0x38270,0x27100},
00205 {"PRC Envelope #8 Rotated",0x1,0x4b708,0x1d4c0,0x0,0x0,0x4b708,0x1d4c0},
00206 {"PRC Envelope #9 Rotated",0x1,0x4f1a0,0x37e88,0x0,0x0,0x4f1a0,0x37e88},
00207 {"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
00208 };
00209
00210 struct table_node {
00211 const char *long_archi;
00212 const char *short_archi;
00213 int version;
00214 };
00215
00216 #define SPL_ARCH_WIN40 "WIN40"
00217 #define SPL_ARCH_W32X86 "W32X86"
00218 #define SPL_ARCH_W32MIPS "W32MIPS"
00219 #define SPL_ARCH_W32ALPHA "W32ALPHA"
00220 #define SPL_ARCH_W32PPC "W32PPC"
00221 #define SPL_ARCH_IA64 "IA64"
00222 #define SPL_ARCH_X64 "x64"
00223
00224 static const struct table_node archi_table[]= {
00225
00226 {"Windows 4.0", SPL_ARCH_WIN40, 0 },
00227 {"Windows NT x86", SPL_ARCH_W32X86, 2 },
00228 {"Windows NT R4000", SPL_ARCH_W32MIPS, 2 },
00229 {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA, 2 },
00230 {"Windows NT PowerPC", SPL_ARCH_W32PPC, 2 },
00231 {"Windows IA64", SPL_ARCH_IA64, 3 },
00232 {"Windows x64", SPL_ARCH_X64, 3 },
00233 {NULL, "", -1 }
00234 };
00235
00236
00237
00238
00239
00240
00241 static TDB_DATA make_printer_tdbkey( const char *sharename )
00242 {
00243 fstring share;
00244 static pstring keystr;
00245 TDB_DATA key;
00246
00247 fstrcpy( share, sharename );
00248 strlower_m( share );
00249
00250 pstr_sprintf( keystr, "%s%s", PRINTERS_PREFIX, share );
00251
00252 key.dptr = keystr;
00253 key.dsize = strlen(keystr)+1;
00254
00255 return key;
00256 }
00257
00258
00259
00260
00261
00262 static char *make_printers_secdesc_tdbkey( const char* sharename )
00263 {
00264 fstring share;
00265 static pstring keystr;
00266
00267 fstrcpy( share, sharename );
00268 strlower_m( share );
00269
00270 pstr_sprintf( keystr, "%s%s", SECDESC_PREFIX, share );
00271
00272 return keystr;
00273 }
00274
00275
00276
00277
00278 static BOOL upgrade_to_version_3(void)
00279 {
00280 TDB_DATA kbuf, newkey, dbuf;
00281
00282 DEBUG(0,("upgrade_to_version_3: upgrading print tdb's to version 3\n"));
00283
00284 for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr;
00285 newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
00286
00287 dbuf = tdb_fetch(tdb_drivers, kbuf);
00288
00289 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
00290 DEBUG(0,("upgrade_to_version_3:moving form\n"));
00291 if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) {
00292 SAFE_FREE(dbuf.dptr);
00293 DEBUG(0,("upgrade_to_version_3: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));
00294 return False;
00295 }
00296 if (tdb_delete(tdb_drivers, kbuf) != 0) {
00297 SAFE_FREE(dbuf.dptr);
00298 DEBUG(0,("upgrade_to_version_3: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));
00299 return False;
00300 }
00301 }
00302
00303 if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
00304 DEBUG(0,("upgrade_to_version_3:moving printer\n"));
00305 if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
00306 SAFE_FREE(dbuf.dptr);
00307 DEBUG(0,("upgrade_to_version_3: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));
00308 return False;
00309 }
00310 if (tdb_delete(tdb_drivers, kbuf) != 0) {
00311 SAFE_FREE(dbuf.dptr);
00312 DEBUG(0,("upgrade_to_version_3: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));
00313 return False;
00314 }
00315 }
00316
00317 if (strncmp(kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
00318 DEBUG(0,("upgrade_to_version_3:moving secdesc\n"));
00319 if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
00320 SAFE_FREE(dbuf.dptr);
00321 DEBUG(0,("upgrade_to_version_3: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));
00322 return False;
00323 }
00324 if (tdb_delete(tdb_drivers, kbuf) != 0) {
00325 SAFE_FREE(dbuf.dptr);
00326 DEBUG(0,("upgrade_to_version_3: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));
00327 return False;
00328 }
00329 }
00330
00331 SAFE_FREE(dbuf.dptr);
00332 }
00333
00334 return True;
00335 }
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
00346 TDB_DATA data, void *state )
00347 {
00348 prs_struct ps;
00349 SEC_DESC_BUF *sd_orig = NULL;
00350 SEC_DESC_BUF *sd_new, *sd_store;
00351 SEC_DESC *sec, *new_sec;
00352 TALLOC_CTX *ctx = state;
00353 int result, i;
00354 uint32 sd_size;
00355 size_t size_new_sec;
00356 DOM_SID sid;
00357
00358 if (!data.dptr || data.dsize == 0) {
00359 return 0;
00360 }
00361
00362 if ( strncmp( key.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX) ) != 0 ) {
00363 return 0;
00364 }
00365
00366
00367
00368 ZERO_STRUCT( ps );
00369
00370 prs_init( &ps, 0, ctx, UNMARSHALL );
00371 prs_give_memory( &ps, data.dptr, data.dsize, False );
00372
00373 if ( !sec_io_desc_buf( "sec_desc_upg_fn", &sd_orig, &ps, 1 ) ) {
00374
00375 DEBUG(0,("sec_desc_upg_fn: Failed to parse original sec_desc for %si. Deleting....\n", key.dptr ));
00376 tdb_delete( tdb_printers, key );
00377 prs_mem_free( &ps );
00378 return 0;
00379 }
00380
00381 if (!sd_orig) {
00382 prs_mem_free( &ps );
00383 return 0;
00384 }
00385 sec = sd_orig->sec;
00386
00387
00388
00389 if ( !sec->dacl ) {
00390 prs_mem_free( &ps );
00391 return 0;
00392 }
00393
00394
00395
00396 for ( i=0; i<sec->dacl->num_aces; i++ ) {
00397 switch ( sec->dacl->aces[i].access_mask ) {
00398 case (GENERIC_READ_ACCESS | GENERIC_WRITE_ACCESS | GENERIC_EXECUTE_ACCESS):
00399 sec->dacl->aces[i].access_mask = PRINTER_ACE_PRINT;
00400 break;
00401
00402 case GENERIC_ALL_ACCESS:
00403 sec->dacl->aces[i].access_mask = PRINTER_ACE_FULL_CONTROL;
00404 break;
00405
00406 case READ_CONTROL_ACCESS:
00407 sec->dacl->aces[i].access_mask = PRINTER_ACE_MANAGE_DOCUMENTS;
00408
00409 default:
00410 break;
00411 }
00412 }
00413
00414
00415
00416 string_to_sid(&sid, "S-1-5-32-544" );
00417 new_sec = make_sec_desc( ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
00418 &sid, &sid,
00419 NULL, NULL, &size_new_sec );
00420 if (!new_sec) {
00421 prs_mem_free( &ps );
00422 return 0;
00423 }
00424 sd_new = make_sec_desc_buf( ctx, size_new_sec, new_sec );
00425 if (!sd_new) {
00426 prs_mem_free( &ps );
00427 return 0;
00428 }
00429
00430 if ( !(sd_store = sec_desc_merge( ctx, sd_new, sd_orig )) ) {
00431 DEBUG(0,("sec_desc_upg_fn: Failed to update sec_desc for %s\n", key.dptr ));
00432 prs_mem_free( &ps );
00433 return 0;
00434 }
00435
00436 prs_mem_free( &ps );
00437
00438
00439
00440 sd_size = sec_desc_size(sd_store->sec) + sizeof(SEC_DESC_BUF);
00441 prs_init(&ps, sd_size, ctx, MARSHALL);
00442
00443 if ( !sec_io_desc_buf( "sec_desc_upg_fn", &sd_store, &ps, 1 ) ) {
00444 DEBUG(0,("sec_desc_upg_fn: Failed to parse new sec_desc for %s\n", key.dptr ));
00445 prs_mem_free( &ps );
00446 return 0;
00447 }
00448
00449 data.dptr = prs_data_p( &ps );
00450 data.dsize = sd_size;
00451
00452 result = tdb_store( tdb_printers, key, data, TDB_REPLACE );
00453
00454 prs_mem_free( &ps );
00455
00456
00457
00458 return (result == -1);
00459 }
00460
00461
00462
00463
00464 static BOOL upgrade_to_version_4(void)
00465 {
00466 TALLOC_CTX *ctx;
00467 int result;
00468
00469 DEBUG(0,("upgrade_to_version_4: upgrading printer security descriptors\n"));
00470
00471 if ( !(ctx = talloc_init( "upgrade_to_version_4" )) )
00472 return False;
00473
00474 result = tdb_traverse( tdb_printers, sec_desc_upg_fn, ctx );
00475
00476 talloc_destroy( ctx );
00477
00478 return ( result != -1 );
00479 }
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 static int normalize_printers_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
00490 TDB_DATA data, void *state )
00491 {
00492 TDB_DATA new_key;
00493
00494 if (!data.dptr || data.dsize == 0)
00495 return 0;
00496
00497
00498
00499 if ( strncmp( key.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX) ) == 0 ) {
00500 new_key = make_printer_tdbkey( key.dptr+strlen(PRINTERS_PREFIX) );
00501 }
00502 else if ( strncmp( key.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX) ) == 0 ) {
00503 new_key.dptr = make_printers_secdesc_tdbkey( key.dptr+strlen(SECDESC_PREFIX) );
00504 new_key.dsize = strlen( new_key.dptr ) + 1;
00505 }
00506 else {
00507
00508 return 0;
00509 }
00510
00511
00512
00513 if ( tdb_delete( the_tdb, key ) != 0 ) {
00514 DEBUG(0,("normalize_printers_fn: tdb_delete for [%s] failed!\n",
00515 key.dptr));
00516 return 1;
00517 }
00518
00519 if ( tdb_store( the_tdb, new_key, data, TDB_REPLACE) != 0 ) {
00520 DEBUG(0,("normalize_printers_fn: failed to store new record for [%s]!\n",
00521 key.dptr));
00522 return 1;
00523 }
00524
00525 return 0;
00526 }
00527
00528
00529
00530
00531 static BOOL upgrade_to_version_5(void)
00532 {
00533 TALLOC_CTX *ctx;
00534 int result;
00535
00536 DEBUG(0,("upgrade_to_version_5: normalizing printer keys\n"));
00537
00538 if ( !(ctx = talloc_init( "upgrade_to_version_5" )) )
00539 return False;
00540
00541 result = tdb_traverse( tdb_printers, normalize_printers_fn, NULL );
00542
00543 talloc_destroy( ctx );
00544
00545 return ( result != -1 );
00546 }
00547
00548
00549
00550
00551
00552 BOOL nt_printing_init(void)
00553 {
00554 const char *vstring = "INFO/version";
00555 WERROR win_rc;
00556 int32 vers_id;
00557
00558 if ( tdb_drivers && tdb_printers && tdb_forms )
00559 return True;
00560
00561 if (tdb_drivers)
00562 tdb_close(tdb_drivers);
00563 tdb_drivers = tdb_open_log(lock_path("ntdrivers.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
00564 if (!tdb_drivers) {
00565 DEBUG(0,("nt_printing_init: Failed to open nt drivers database %s (%s)\n",
00566 lock_path("ntdrivers.tdb"), strerror(errno) ));
00567 return False;
00568 }
00569
00570 if (tdb_printers)
00571 tdb_close(tdb_printers);
00572 tdb_printers = tdb_open_log(lock_path("ntprinters.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
00573 if (!tdb_printers) {
00574 DEBUG(0,("nt_printing_init: Failed to open nt printers database %s (%s)\n",
00575 lock_path("ntprinters.tdb"), strerror(errno) ));
00576 return False;
00577 }
00578
00579 if (tdb_forms)
00580 tdb_close(tdb_forms);
00581 tdb_forms = tdb_open_log(lock_path("ntforms.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
00582 if (!tdb_forms) {
00583 DEBUG(0,("nt_printing_init: Failed to open nt forms database %s (%s)\n",
00584 lock_path("ntforms.tdb"), strerror(errno) ));
00585 return False;
00586 }
00587
00588
00589
00590 vers_id = tdb_fetch_int32(tdb_drivers, vstring);
00591 if (vers_id == -1) {
00592 DEBUG(10, ("Fresh database\n"));
00593 tdb_store_int32( tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_5 );
00594 vers_id = NTDRIVERS_DATABASE_VERSION_5;
00595 }
00596
00597 if ( vers_id != NTDRIVERS_DATABASE_VERSION_5 ) {
00598
00599 if ((vers_id == NTDRIVERS_DATABASE_VERSION_1) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_1)) {
00600 if (!upgrade_to_version_3())
00601 return False;
00602 tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_3);
00603 vers_id = NTDRIVERS_DATABASE_VERSION_3;
00604 }
00605
00606 if ((vers_id == NTDRIVERS_DATABASE_VERSION_2) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_2)) {
00607
00608
00609 tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_3);
00610 vers_id = NTDRIVERS_DATABASE_VERSION_3;
00611 }
00612
00613 if (vers_id == NTDRIVERS_DATABASE_VERSION_3 ) {
00614 if ( !upgrade_to_version_4() )
00615 return False;
00616 tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_4);
00617 vers_id = NTDRIVERS_DATABASE_VERSION_4;
00618 }
00619
00620 if (vers_id == NTDRIVERS_DATABASE_VERSION_4 ) {
00621 if ( !upgrade_to_version_5() )
00622 return False;
00623 tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_5);
00624 vers_id = NTDRIVERS_DATABASE_VERSION_5;
00625 }
00626
00627
00628 if ( vers_id != NTDRIVERS_DATABASE_VERSION_5 ) {
00629 DEBUG(0,("nt_printing_init: Unknown printer database version [%d]\n", vers_id));
00630 return False;
00631 }
00632 }
00633
00634 update_c_setprinter(True);
00635
00636
00637
00638
00639
00640
00641 message_register(MSG_PRINTER_DRVUPGRADE, do_drv_upgrade_printer, NULL);
00642
00643
00644
00645
00646
00647
00648 message_register(MSG_PRINTERDATA_INIT_RESET, reset_all_printerdata,
00649 NULL);
00650
00651
00652
00653
00654
00655
00656 if ( lp_security() == SEC_ADS ) {
00657 win_rc = check_published_printers();
00658 if (!W_ERROR_IS_OK(win_rc))
00659 DEBUG(0, ("nt_printing_init: error checking published printers: %s\n", dos_errstr(win_rc)));
00660 }
00661
00662 return True;
00663 }
00664
00665
00666
00667
00668
00669 static void driver_unix_convert(char *name,connection_struct *conn,
00670 char *saved_last_component, SMB_STRUCT_STAT *pst)
00671 {
00672 unix_format(name);
00673 unix_clean_name(name);
00674 trim_string(name,"/","/");
00675 unix_convert(conn, name, False, saved_last_component, pst);
00676 }
00677
00678
00679
00680
00681
00682 static int traverse_counting_printers(TDB_CONTEXT *t, TDB_DATA key,
00683 TDB_DATA data, void *context)
00684 {
00685 int *printer_count = (int*)context;
00686
00687 if (memcmp(PRINTERS_PREFIX, key.dptr, sizeof(PRINTERS_PREFIX)-1) == 0) {
00688 (*printer_count)++;
00689 DEBUG(10,("traverse_counting_printers: printer = [%s] printer_count = %d\n", key.dptr, *printer_count));
00690 }
00691
00692 return 0;
00693 }
00694
00695
00696
00697
00698
00699
00700
00701
00702 uint32 update_c_setprinter(BOOL initialize)
00703 {
00704 int32 c_setprinter;
00705 int32 printer_count = 0;
00706
00707 tdb_lock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
00708
00709
00710 tdb_traverse(tdb_printers, traverse_counting_printers, (void *)&printer_count);
00711
00712
00713
00714
00715 if (!initialize)
00716 c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER) + printer_count;
00717 else
00718 c_setprinter = printer_count;
00719
00720 DEBUG(10,("update_c_setprinter: c_setprinter = %u\n", (unsigned int)c_setprinter));
00721 tdb_store_int32(tdb_printers, GLOBAL_C_SETPRINTER, c_setprinter);
00722
00723 tdb_unlock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
00724
00725 return (uint32)c_setprinter;
00726 }
00727
00728
00729
00730
00731
00732 uint32 get_c_setprinter(void)
00733 {
00734 int32 c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER);
00735
00736 if (c_setprinter == (int32)-1)
00737 c_setprinter = update_c_setprinter(True);
00738
00739 DEBUG(10,("get_c_setprinter: c_setprinter = %d\n", c_setprinter));
00740
00741 return (uint32)c_setprinter;
00742 }
00743
00744
00745
00746
00747
00748 int get_builtin_ntforms(nt_forms_struct **list)
00749 {
00750 *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
00751 if (!*list) {
00752 return 0;
00753 }
00754 return sizeof(default_forms) / sizeof(default_forms[0]);
00755 }
00756
00757
00758
00759
00760
00761 BOOL get_a_builtin_ntform(UNISTR2 *uni_formname,nt_forms_struct *form)
00762 {
00763 int i,count;
00764 fstring form_name;
00765 unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
00766 DEBUGADD(6,("Looking for builtin form %s \n", form_name));
00767 count = sizeof(default_forms) / sizeof(default_forms[0]);
00768 for (i=0;i<count;i++) {
00769 if (strequal(form_name,default_forms[i].name)) {
00770 DEBUGADD(6,("Found builtin form %s \n", form_name));
00771 memcpy(form,&default_forms[i],sizeof(*form));
00772 break;
00773 }
00774 }
00775
00776 return (i !=count);
00777 }
00778
00779
00780
00781
00782
00783 int get_ntforms(nt_forms_struct **list)
00784 {
00785 TDB_DATA kbuf, newkey, dbuf;
00786 nt_forms_struct form;
00787 int ret;
00788 int i;
00789 int n = 0;
00790
00791 *list = NULL;
00792
00793 for (kbuf = tdb_firstkey(tdb_forms);
00794 kbuf.dptr;
00795 newkey = tdb_nextkey(tdb_forms, kbuf), safe_free(kbuf.dptr), kbuf=newkey)
00796 {
00797 if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0)
00798 continue;
00799
00800 dbuf = tdb_fetch(tdb_forms, kbuf);
00801 if (!dbuf.dptr)
00802 continue;
00803
00804 fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
00805 ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",
00806 &i, &form.flag, &form.width, &form.length, &form.left,
00807 &form.top, &form.right, &form.bottom);
00808 SAFE_FREE(dbuf.dptr);
00809 if (ret != dbuf.dsize)
00810 continue;
00811
00812 *list = SMB_REALLOC_ARRAY(*list, nt_forms_struct, n+1);
00813 if (!*list) {
00814 DEBUG(0,("get_ntforms: Realloc fail.\n"));
00815 return 0;
00816 }
00817 (*list)[n] = form;
00818 n++;
00819 }
00820
00821
00822 return n;
00823 }
00824
00825
00826
00827
00828 int write_ntforms(nt_forms_struct **list, int number)
00829 {
00830 pstring buf, key;
00831 int len;
00832 TDB_DATA kbuf,dbuf;
00833 int i;
00834
00835 for (i=0;i<number;i++) {
00836
00837 len = tdb_pack(buf, sizeof(buf), "dddddddd",
00838 i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
00839 (*list)[i].left, (*list)[i].top, (*list)[i].right,
00840 (*list)[i].bottom);
00841 if (len > sizeof(buf)) break;
00842 slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[i].name);
00843 kbuf.dsize = strlen(key)+1;
00844 kbuf.dptr = key;
00845 dbuf.dsize = len;
00846 dbuf.dptr = buf;
00847 if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) break;
00848 }
00849
00850 return i;
00851 }
00852
00853
00854
00855
00856 BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
00857 {
00858 int n=0;
00859 BOOL update;
00860 fstring form_name;
00861
00862
00863
00864
00865
00866
00867
00868 update=False;
00869
00870 unistr2_to_ascii(form_name, &form->name, sizeof(form_name)-1);
00871 for (n=0; n<*count; n++) {
00872 if ( strequal((*list)[n].name, form_name) ) {
00873 update=True;
00874 break;
00875 }
00876 }
00877
00878 if (update==False) {
00879 if((*list=SMB_REALLOC_ARRAY(*list, nt_forms_struct, n+1)) == NULL) {
00880 DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));
00881 return False;
00882 }
00883 unistr2_to_ascii((*list)[n].name, &form->name, sizeof((*list)[n].name)-1);
00884 (*count)++;
00885 }
00886
00887 (*list)[n].flag=form->flags;
00888 (*list)[n].width=form->size_x;
00889 (*list)[n].length=form->size_y;
00890 (*list)[n].left=form->left;
00891 (*list)[n].top=form->top;
00892 (*list)[n].right=form->right;
00893 (*list)[n].bottom=form->bottom;
00894
00895 DEBUG(6,("add_a_form: Successfully %s form [%s]\n",
00896 update ? "updated" : "added", form_name));
00897
00898 return True;
00899 }
00900
00901
00902
00903
00904
00905 BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR *ret)
00906 {
00907 pstring key;
00908 TDB_DATA kbuf;
00909 int n=0;
00910 fstring form_name;
00911
00912 *ret = WERR_OK;
00913
00914 unistr2_to_ascii(form_name, del_name, sizeof(form_name)-1);
00915
00916 for (n=0; n<*count; n++) {
00917 if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
00918 DEBUG(103, ("delete_a_form, [%s] in list\n", form_name));
00919 break;
00920 }
00921 }
00922
00923 if (n == *count) {
00924 DEBUG(10,("delete_a_form, [%s] not found\n", form_name));
00925 *ret = WERR_INVALID_PARAM;
00926 return False;
00927 }
00928
00929 slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[n].name);
00930 kbuf.dsize = strlen(key)+1;
00931 kbuf.dptr = key;
00932 if (tdb_delete(tdb_forms, kbuf) != 0) {
00933 *ret = WERR_NOMEM;
00934 return False;
00935 }
00936
00937 return True;
00938 }
00939
00940
00941
00942
00943
00944 void update_a_form(nt_forms_struct **list, const FORM *form, int count)
00945 {
00946 int n=0;
00947 fstring form_name;
00948 unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
00949
00950 DEBUG(106, ("[%s]\n", form_name));
00951 for (n=0; n<count; n++) {
00952 DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
00953 if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
00954 break;
00955 }
00956
00957 if (n==count) return;
00958
00959 (*list)[n].flag=form->flags;
00960 (*list)[n].width=form->size_x;
00961 (*list)[n].length=form->size_y;
00962 (*list)[n].left=form->left;
00963 (*list)[n].top=form->top;
00964 (*list)[n].right=form->right;
00965 (*list)[n].bottom=form->bottom;
00966 }
00967
00968
00969
00970
00971
00972 int get_ntdrivers(fstring **list, const char *architecture, uint32 version)
00973 {
00974 int total=0;
00975 const char *short_archi;
00976 pstring key;
00977 TDB_DATA kbuf, newkey;
00978
00979 short_archi = get_short_archi(architecture);
00980 if (!short_archi) {
00981 return 0;
00982 }
00983
00984 slprintf(key, sizeof(key)-1, "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
00985
00986 for (kbuf = tdb_firstkey(tdb_drivers);
00987 kbuf.dptr;
00988 newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
00989
00990 if (strncmp(kbuf.dptr, key, strlen(key)) != 0)
00991 continue;
00992
00993 if((*list = SMB_REALLOC_ARRAY(*list, fstring, total+1)) == NULL) {
00994 DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));
00995 return -1;
00996 }
00997
00998 fstrcpy((*list)[total], kbuf.dptr+strlen(key));
00999 total++;
01000 }
01001
01002 return(total);
01003 }
01004
01005
01006
01007
01008
01009
01010 const char *get_short_archi(const char *long_archi)
01011 {
01012 int i=-1;
01013
01014 DEBUG(107,("Getting architecture dependant directory\n"));
01015 do {
01016 i++;
01017 } while ( (archi_table[i].long_archi!=NULL ) &&
01018 StrCaseCmp(long_archi, archi_table[i].long_archi) );
01019
01020 if (archi_table[i].long_archi==NULL) {
01021 DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
01022 return NULL;
01023 }
01024
01025
01026
01027 DEBUGADD(108,("index: [%d]\n", i));
01028 DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));
01029 DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));
01030
01031 return archi_table[i].short_archi;
01032 }
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042 static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 *minor)
01043 {
01044 int i;
01045 char *buf = NULL;
01046 ssize_t byte_count;
01047
01048 if ((buf=(char *)SMB_MALLOC(DOS_HEADER_SIZE)) == NULL) {
01049 DEBUG(0,("get_file_version: PE file [%s] DOS Header malloc failed bytes = %d\n",
01050 fname, DOS_HEADER_SIZE));
01051 goto error_exit;
01052 }
01053
01054 if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
01055 DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %lu\n",
01056 fname, (unsigned long)byte_count));
01057 goto no_version_info;
01058 }
01059
01060
01061 if (SVAL(buf,DOS_HEADER_MAGIC_OFFSET) != DOS_HEADER_MAGIC) {
01062 DEBUG(6,("get_file_version: File [%s] bad DOS magic = 0x%x\n",
01063 fname, SVAL(buf,DOS_HEADER_MAGIC_OFFSET)));
01064 goto no_version_info;
01065 }
01066
01067
01068 if (SMB_VFS_LSEEK(fsp, fsp->fh->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
01069 DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
01070 fname, errno));
01071
01072 goto no_version_info;
01073 }
01074
01075
01076 if ((byte_count = vfs_read_data(fsp, buf, NE_HEADER_SIZE)) < NE_HEADER_SIZE) {
01077 DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %lu\n",
01078 fname, (unsigned long)byte_count));
01079
01080 goto no_version_info;
01081 }
01082
01083
01084 if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
01085 unsigned int num_sections;
01086 unsigned int section_table_bytes;
01087
01088
01089 if (SMB_VFS_LSEEK(fsp, fsp->fh->fd,
01090 SVAL(buf,PE_HEADER_OPTIONAL_HEADER_SIZE)-(NE_HEADER_SIZE-PE_HEADER_SIZE),
01091 SEEK_CUR) == (SMB_OFF_T)-1) {
01092 DEBUG(3,("get_file_version: File [%s] Windows optional header too short, errno = %d\n",
01093 fname, errno));
01094 goto error_exit;
01095 }
01096
01097
01098 num_sections = SVAL(buf,PE_HEADER_NUMBER_OF_SECTIONS);
01099 section_table_bytes = num_sections * PE_HEADER_SECT_HEADER_SIZE;
01100 if (section_table_bytes == 0)
01101 goto error_exit;
01102
01103 SAFE_FREE(buf);
01104 if ((buf=(char *)SMB_MALLOC(section_table_bytes)) == NULL) {
01105 DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
01106 fname, section_table_bytes));
01107 goto error_exit;
01108 }
01109
01110 if ((byte_count = vfs_read_data(fsp, buf, section_table_bytes)) < section_table_bytes) {
01111 DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %lu\n",
01112 fname, (unsigned long)byte_count));
01113 goto error_exit;
01114 }
01115
01116
01117 for (i = 0; i < num_sections; i++) {
01118 int sec_offset = i * PE_HEADER_SECT_HEADER_SIZE;
01119
01120 if (strcmp(".rsrc", &buf[sec_offset+PE_HEADER_SECT_NAME_OFFSET]) == 0) {
01121 unsigned int section_pos = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET);
01122 unsigned int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET);
01123
01124 if (section_bytes == 0)
01125 goto error_exit;
01126
01127 SAFE_FREE(buf);
01128 if ((buf=(char *)SMB_MALLOC(section_bytes)) == NULL) {
01129 DEBUG(0,("get_file_version: PE file [%s] version malloc failed bytes = %d\n",
01130 fname, section_bytes));
01131 goto error_exit;
01132 }
01133
01134
01135 if (SMB_VFS_LSEEK(fsp, fsp->fh->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
01136 DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
01137 fname, errno));
01138 goto error_exit;
01139 }
01140
01141 if ((byte_count = vfs_read_data(fsp, buf, section_bytes)) < section_bytes) {
01142 DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %lu\n",
01143 fname, (unsigned long)byte_count));
01144 goto error_exit;
01145 }
01146
01147 if (section_bytes < VS_VERSION_INFO_UNICODE_SIZE)
01148 goto error_exit;
01149
01150 for (i=0; i<section_bytes-VS_VERSION_INFO_UNICODE_SIZE; i++) {
01151
01152 if (buf[i] == 'V' && buf[i+1] == '\0' && buf[i+2] == 'S') {
01153
01154 int pos = (i + sizeof(VS_SIGNATURE)*2 + 3) & 0xfffffffc;
01155
01156 if (IVAL(buf,pos) == VS_MAGIC_VALUE) {
01157 *major = IVAL(buf,pos+VS_MAJOR_OFFSET);
01158 *minor = IVAL(buf,pos+VS_MINOR_OFFSET);
01159
01160 DEBUG(6,("get_file_version: PE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
01161 fname, *major, *minor,
01162 (*major>>16)&0xffff, *major&0xffff,
01163 (*minor>>16)&0xffff, *minor&0xffff));
01164 SAFE_FREE(buf);
01165 return 1;
01166 }
01167 }
01168 }
01169 }
01170 }
01171
01172
01173 DEBUG(10,("get_file_version: PE file [%s] has no version info\n", fname));
01174 SAFE_FREE(buf);
01175 return 0;
01176
01177 } else if (SVAL(buf,NE_HEADER_SIGNATURE_OFFSET) == NE_HEADER_SIGNATURE) {
01178 if (CVAL(buf,NE_HEADER_TARGET_OS_OFFSET) != NE_HEADER_TARGOS_WIN ) {
01179 DEBUG(3,("get_file_version: NE file [%s] wrong target OS = 0x%x\n",
01180 fname, CVAL(buf,NE_HEADER_TARGET_OS_OFFSET)));
01181
01182
01183 goto error_exit;
01184 }
01185
01186
01187 SAFE_FREE(buf);
01188 if ((buf=(char *)SMB_MALLOC(VS_NE_BUF_SIZE)) == NULL) {
01189 DEBUG(0,("get_file_version: NE file [%s] malloc failed bytes = %d\n",
01190 fname, PE_HEADER_SIZE));
01191 goto error_exit;
01192 }
01193
01194
01195
01196
01197 while((byte_count = vfs_read_data(fsp, buf, VS_NE_BUF_SIZE)) > 0) {
01198
01199 if (byte_count-VS_VERSION_INFO_SIZE <= 0) break;
01200
01201 for(i=0; i<byte_count; i++) {
01202
01203 if (buf[i] != 'V') continue;
01204
01205
01206
01207 if (i>byte_count-VS_VERSION_INFO_SIZE) {
01208 int bc;
01209
01210 memcpy(buf, &buf[i], byte_count-i);
01211 if ((bc = vfs_read_data(fsp, &buf[byte_count-i], VS_NE_BUF_SIZE-
01212 (byte_count-i))) < 0) {
01213
01214 DEBUG(0,("get_file_version: NE file [%s] Read error, errno=%d\n",
01215 fname, errno));
01216 goto error_exit;
01217 }
01218
01219 byte_count = bc + (byte_count - i);
01220 if (byte_count<VS_VERSION_INFO_SIZE) break;
01221
01222 i = 0;
01223 }
01224
01225
01226
01227
01228
01229 if (strcmp(&buf[i], VS_SIGNATURE) == 0) {
01230
01231 int skip = -(SMB_VFS_LSEEK(fsp, fsp->fh->fd, 0, SEEK_CUR) - (byte_count - i) +
01232 sizeof(VS_SIGNATURE)) & 3;
01233 if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue;
01234
01235 *major = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MAJOR_OFFSET);
01236 *minor = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MINOR_OFFSET);
01237 DEBUG(6,("get_file_version: NE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
01238 fname, *major, *minor,
01239 (*major>>16)&0xffff, *major&0xffff,
01240 (*minor>>16)&0xffff, *minor&0xffff));
01241 SAFE_FREE(buf);
01242 return 1;
01243 }
01244 }
01245 }
01246
01247
01248 DEBUG(0,("get_file_version: NE file [%s] Version info not found\n", fname));
01249 SAFE_FREE(buf);
01250 return 0;
01251
01252 } else
01253
01254 DEBUG(3,("get_file_version: File [%s] unknown file format, signature = 0x%x\n",
01255 fname, IVAL(buf,PE_HEADER_SIGNATURE_OFFSET)));
01256
01257 no_version_info:
01258 SAFE_FREE(buf);
01259 return 0;
01260
01261 error_exit:
01262 SAFE_FREE(buf);
01263 return -1;
01264 }
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276 static int file_version_is_newer(connection_struct *conn, fstring new_file, fstring old_file)
01277 {
01278 BOOL use_version = True;
01279 pstring filepath;
01280
01281 uint32 new_major;
01282 uint32 new_minor;
01283 time_t new_create_time;
01284
01285 uint32 old_major;
01286 uint32 old_minor;
01287 time_t old_create_time;
01288
01289 files_struct *fsp = NULL;
01290 SMB_STRUCT_STAT st;
01291 SMB_STRUCT_STAT stat_buf;
01292
01293 NTSTATUS status;
01294
01295 SET_STAT_INVALID(st);
01296 SET_STAT_INVALID(stat_buf);
01297 new_create_time = (time_t)0;
01298 old_create_time = (time_t)0;
01299
01300
01301 pstrcpy(filepath, old_file);
01302
01303 driver_unix_convert(filepath,conn,NULL,&stat_buf);
01304
01305 status = open_file_ntcreate(conn, filepath, &stat_buf,
01306 FILE_GENERIC_READ,
01307 FILE_SHARE_READ|FILE_SHARE_WRITE,
01308 FILE_OPEN,
01309 0,
01310 FILE_ATTRIBUTE_NORMAL,
01311 INTERNAL_OPEN_ONLY,
01312 NULL, &fsp);
01313
01314 if (!NT_STATUS_IS_OK(status)) {
01315
01316 DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n",
01317 filepath, errno));
01318 return True;
01319
01320 } else {
01321 int ret = get_file_version(fsp, old_file, &old_major, &old_minor);
01322 if (ret == -1) {
01323 goto error_exit;
01324 }
01325
01326 if (!ret) {
01327 DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
01328 old_file));
01329 use_version = False;
01330 if (SMB_VFS_FSTAT(fsp, fsp->fh->fd, &st) == -1) goto error_exit;
01331 old_create_time = st.st_mtime;
01332 DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time));
01333 }
01334 }
01335 close_file(fsp, NORMAL_CLOSE);
01336
01337
01338 pstrcpy(filepath, new_file);
01339 driver_unix_convert(filepath,conn,NULL,&stat_buf);
01340
01341 status = open_file_ntcreate(conn, filepath, &stat_buf,
01342 FILE_GENERIC_READ,
01343 FILE_SHARE_READ|FILE_SHARE_WRITE,
01344 FILE_OPEN,
01345 0,
01346 FILE_ATTRIBUTE_NORMAL,
01347 INTERNAL_OPEN_ONLY,
01348 NULL, &fsp);
01349
01350 if (!NT_STATUS_IS_OK(status)) {
01351
01352 DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n",
01353 filepath, errno));
01354 goto error_exit;
01355
01356 } else {
01357 int ret = get_file_version(fsp, new_file, &new_major, &new_minor);
01358 if (ret == -1) {
01359 goto error_exit;
01360 }
01361
01362 if (!ret) {
01363 DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
01364 new_file));
01365 use_version = False;
01366 if (SMB_VFS_FSTAT(fsp, fsp->fh->fd, &st) == -1) goto error_exit;
01367 new_create_time = st.st_mtime;
01368 DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time));
01369 }
01370 }
01371 close_file(fsp, NORMAL_CLOSE);
01372
01373 if (use_version && (new_major != old_major || new_minor != old_minor)) {
01374
01375 if (new_major > old_major ||
01376 (new_major == old_major && new_minor > old_minor)) {
01377
01378 DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
01379 return True;
01380 }
01381 else {
01382 DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
01383 return False;
01384 }
01385
01386 } else {
01387
01388 if (new_create_time > old_create_time) {
01389 DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
01390 return True;
01391 }
01392 else {
01393 DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
01394 return False;
01395 }
01396 }
01397
01398 error_exit:
01399 if(fsp)
01400 close_file(fsp, NORMAL_CLOSE);
01401 return -1;
01402 }
01403
01404
01405
01406
01407 static uint32 get_correct_cversion(const char *architecture, fstring driverpath_in,
01408 struct current_user *user, WERROR *perr)
01409 {
01410 int cversion;
01411 NTSTATUS nt_status;
01412 pstring driverpath;
01413 DATA_BLOB null_pw;
01414 fstring res_type;
01415 files_struct *fsp = NULL;
01416 SMB_STRUCT_STAT st;
01417 connection_struct *conn;
01418 NTSTATUS status;
01419
01420 SET_STAT_INVALID(st);
01421
01422 *perr = WERR_INVALID_PARAM;
01423
01424
01425 if (strcmp(architecture, SPL_ARCH_WIN40) == 0) {
01426 DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
01427 *perr = WERR_OK;
01428 return 0;
01429 }
01430
01431
01432 if (strcmp(architecture, SPL_ARCH_X64) == 0) {
01433 DEBUG(10,("get_correct_cversion: Driver is x64, cversion = 3\n"));
01434 *perr = WERR_OK;
01435 return 3;
01436 }
01437
01438
01439
01440
01441
01442
01443
01444 null_pw = data_blob(NULL, 0);
01445 fstrcpy(res_type, "A:");
01446 become_root();
01447 conn = make_connection_with_chdir("print$", null_pw, res_type, user->vuid, &nt_status);
01448 unbecome_root();
01449
01450 if (conn == NULL) {
01451 DEBUG(0,("get_correct_cversion: Unable to connect\n"));
01452 *perr = ntstatus_to_werror(nt_status);
01453 return -1;
01454 }
01455
01456
01457 if (!become_user(conn, user->vuid)) {
01458 DEBUG(0,("get_correct_cversion: Can't become user!\n"));
01459 *perr = WERR_ACCESS_DENIED;
01460 return -1;
01461 }
01462
01463
01464
01465 slprintf(driverpath, sizeof(driverpath)-1, "%s/%s", architecture, driverpath_in);
01466
01467 driver_unix_convert(driverpath,conn,NULL,&st);
01468
01469 if ( !vfs_file_exist( conn, driverpath, &st ) ) {
01470 *perr = WERR_BADFILE;
01471 goto error_exit;
01472 }
01473
01474 status = open_file_ntcreate(conn, driverpath, &st,
01475 FILE_GENERIC_READ,
01476 FILE_SHARE_READ|FILE_SHARE_WRITE,
01477 FILE_OPEN,
01478 0,
01479 FILE_ATTRIBUTE_NORMAL,
01480 INTERNAL_OPEN_ONLY,
01481 NULL, &fsp);
01482
01483 if (!NT_STATUS_IS_OK(status)) {
01484 DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
01485 driverpath, errno));
01486 *perr = WERR_ACCESS_DENIED;
01487 goto error_exit;
01488 } else {
01489 uint32 major;
01490 uint32 minor;
01491 int ret = get_file_version(fsp, driverpath, &major, &minor);
01492 if (ret == -1) goto error_exit;
01493
01494 if (!ret) {
01495 DEBUG(6,("get_correct_cversion: Version info not found [%s]\n", driverpath));
01496 goto error_exit;
01497 }
01498
01499
01500
01501
01502
01503
01504
01505
01506 cversion = major & 0x0000ffff;
01507 switch (cversion) {
01508 case 2:
01509 case 3:
01510 break;
01511
01512 default:
01513 DEBUG(6,("get_correct_cversion: cversion invalid [%s] cversion = %d\n",
01514 driverpath, cversion));
01515 goto error_exit;
01516 }
01517
01518 DEBUG(10,("get_correct_cversion: Version info found [%s] major = 0x%x minor = 0x%x\n",
01519 driverpath, major, minor));
01520 }
01521
01522 DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
01523 driverpath, cversion));
01524
01525 close_file(fsp, NORMAL_CLOSE);
01526 close_cnum(conn, user->vuid);
01527 unbecome_user();
01528 *perr = WERR_OK;
01529 return cversion;
01530
01531
01532 error_exit:
01533
01534 if(fsp)
01535 close_file(fsp, NORMAL_CLOSE);
01536
01537 close_cnum(conn, user->vuid);
01538 unbecome_user();
01539 return -1;
01540 }
01541
01542
01543
01544 static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver,
01545 struct current_user *user)
01546 {
01547 const char *architecture;
01548 fstring new_name;
01549 char *p;
01550 int i;
01551 WERROR err;
01552
01553
01554
01555
01556
01557
01558 if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
01559 fstrcpy(new_name, p+1);
01560 fstrcpy(driver->driverpath, new_name);
01561 }
01562
01563 if ((p = strrchr(driver->datafile,'\\')) != NULL) {
01564 fstrcpy(new_name, p+1);
01565 fstrcpy(driver->datafile, new_name);
01566 }
01567
01568 if ((p = strrchr(driver->configfile,'\\')) != NULL) {
01569 fstrcpy(new_name, p+1);
01570 fstrcpy(driver->configfile, new_name);
01571 }
01572
01573 if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
01574 fstrcpy(new_name, p+1);
01575 fstrcpy(driver->helpfile, new_name);
01576 }
01577
01578 if (driver->dependentfiles) {
01579 for (i=0; *driver->dependentfiles[i]; i++) {
01580 if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
01581 fstrcpy(new_name, p+1);
01582 fstrcpy(driver->dependentfiles[i], new_name);
01583 }
01584 }
01585 }
01586
01587 architecture = get_short_archi(driver->environment);
01588 if (!architecture) {
01589 return WERR_UNKNOWN_PRINTER_DRIVER;
01590 }
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603 if ((driver->cversion = get_correct_cversion( architecture, driver->driverpath, user, &err)) == -1)
01604 return err;
01605
01606 return WERR_OK;
01607 }
01608
01609
01610
01611 static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver, struct current_user *user)
01612 {
01613 const char *architecture;
01614 fstring new_name;
01615 char *p;
01616 int i;
01617 WERROR err;
01618
01619
01620
01621
01622
01623
01624 if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
01625 fstrcpy(new_name, p+1);
01626 fstrcpy(driver->driverpath, new_name);
01627 }
01628
01629 if ((p = strrchr(driver->datafile,'\\')) != NULL) {
01630 fstrcpy(new_name, p+1);
01631 fstrcpy(driver->datafile, new_name);
01632 }
01633
01634 if ((p = strrchr(driver->configfile,'\\')) != NULL) {
01635 fstrcpy(new_name, p+1);
01636 fstrcpy(driver->configfile, new_name);
01637 }
01638
01639 if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
01640 fstrcpy(new_name, p+1);
01641 fstrcpy(driver->helpfile, new_name);
01642 }
01643
01644 if (driver->dependentfiles) {
01645 for (i=0; *driver->dependentfiles[i]; i++) {
01646 if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
01647 fstrcpy(new_name, p+1);
01648 fstrcpy(driver->dependentfiles[i], new_name);
01649 }
01650 }
01651 }
01652
01653 architecture = get_short_archi(driver->environment);
01654 if (!architecture) {
01655 return WERR_UNKNOWN_PRINTER_DRIVER;
01656 }
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670 if ((driver->version = get_correct_cversion(architecture, driver->driverpath, user, &err)) == -1)
01671 return err;
01672
01673 return WERR_OK;
01674 }
01675
01676
01677
01678 WERROR clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
01679 uint32 level, struct current_user *user)
01680 {
01681 switch (level) {
01682 case 3:
01683 {
01684 NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
01685 driver=driver_abstract.info_3;
01686 return clean_up_driver_struct_level_3(driver, user);
01687 }
01688 case 6:
01689 {
01690 NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
01691 driver=driver_abstract.info_6;
01692 return clean_up_driver_struct_level_6(driver, user);
01693 }
01694 default:
01695 return WERR_INVALID_PARAM;
01696 }
01697 }
01698
01699
01700
01701
01702
01703 static void convert_level_6_to_level3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dst, NT_PRINTER_DRIVER_INFO_LEVEL_6 *src)
01704 {
01705 dst->cversion = src->version;
01706
01707 fstrcpy( dst->name, src->name);
01708 fstrcpy( dst->environment, src->environment);
01709 fstrcpy( dst->driverpath, src->driverpath);
01710 fstrcpy( dst->datafile, src->datafile);
01711 fstrcpy( dst->configfile, src->configfile);
01712 fstrcpy( dst->helpfile, src->helpfile);
01713 fstrcpy( dst->monitorname, src->monitorname);
01714 fstrcpy( dst->defaultdatatype, src->defaultdatatype);
01715 dst->dependentfiles = src->dependentfiles;
01716 }
01717
01718 #if 0
01719
01720 static char* ffmt(unsigned char *c){
01721 int i;
01722 static char ffmt_str[17];
01723
01724 for (i=0; i<16; i++) {
01725 if ((c[i] < ' ') || (c[i] > '~'))
01726 ffmt_str[i]='.';
01727 else
01728 ffmt_str[i]=c[i];
01729 }
01730 ffmt_str[16]='\0';
01731 return ffmt_str;
01732 }
01733
01734 #endif
01735
01736
01737
01738 WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level,
01739 struct current_user *user, WERROR *perr)
01740 {
01741 NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
01742 NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
01743 const char *architecture;
01744 pstring new_dir;
01745 pstring old_name;
01746 pstring new_name;
01747 DATA_BLOB null_pw;
01748 connection_struct *conn;
01749 NTSTATUS nt_status;
01750 pstring inbuf;
01751 pstring outbuf;
01752 fstring res_type;
01753 SMB_STRUCT_STAT st;
01754 int ver = 0;
01755 int i;
01756
01757 memset(inbuf, '\0', sizeof(inbuf));
01758 memset(outbuf, '\0', sizeof(outbuf));
01759 *perr = WERR_OK;
01760
01761 if (level==3)
01762 driver=driver_abstract.info_3;
01763 else if (level==6) {
01764 convert_level_6_to_level3(&converted_driver, driver_abstract.info_6);
01765 driver = &converted_driver;
01766 } else {
01767 DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level ));
01768 return WERR_UNKNOWN_LEVEL;
01769 }
01770
01771 architecture = get_short_archi(driver->environment);
01772 if (!architecture) {
01773 return WERR_UNKNOWN_PRINTER_DRIVER;
01774 }
01775
01776
01777
01778
01779
01780
01781 null_pw = data_blob(NULL, 0);
01782 fstrcpy(res_type, "A:");
01783 become_root();
01784 conn = make_connection_with_chdir("print$", null_pw, res_type, user->vuid, &nt_status);
01785 unbecome_root();
01786
01787 if (conn == NULL) {
01788 DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
01789 *perr = ntstatus_to_werror(nt_status);
01790 return WERR_NO_SUCH_SHARE;
01791 }
01792
01793
01794
01795
01796
01797 if (!become_user(conn, conn->vuid)) {
01798 DEBUG(0,("move_driver_to_download_area: Can't become user!\n"));
01799 return WERR_ACCESS_DENIED;
01800 }
01801
01802
01803
01804
01805
01806 DEBUG(5,("Creating first directory\n"));
01807 slprintf(new_dir, sizeof(new_dir)-1, "%s/%d", architecture, driver->cversion);
01808 driver_unix_convert(new_dir, conn, NULL, &st);
01809 create_directory(conn, new_dir);
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828 DEBUG(5,("Moving files now !\n"));
01829
01830 if (driver->driverpath && strlen(driver->driverpath)) {
01831 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->driverpath);
01832 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->driverpath);
01833 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
01834 driver_unix_convert(new_name, conn, NULL, &st);
01835 if ( !NT_STATUS_IS_OK(copy_file(conn, new_name, old_name, OPENX_FILE_EXISTS_TRUNCATE|
01836 OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
01837 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
01838 new_name, old_name));
01839 *perr = WERR_ACCESS_DENIED;
01840 ver = -1;
01841 }
01842 }
01843 }
01844
01845 if (driver->datafile && strlen(driver->datafile)) {
01846 if (!strequal(driver->datafile, driver->driverpath)) {
01847 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->datafile);
01848 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->datafile);
01849 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
01850 driver_unix_convert(new_name, conn, NULL, &st);
01851 if ( !NT_STATUS_IS_OK(copy_file(conn, new_name, old_name, OPENX_FILE_EXISTS_TRUNCATE|
01852 OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
01853 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
01854 new_name, old_name));
01855 *perr = WERR_ACCESS_DENIED;
01856 ver = -1;
01857 }
01858 }
01859 }
01860 }
01861
01862 if (driver->configfile && strlen(driver->configfile)) {
01863 if (!strequal(driver->configfile, driver->driverpath) &&
01864 !strequal(driver->configfile, driver->datafile)) {
01865 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->configfile);
01866 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->configfile);
01867 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
01868 driver_unix_convert(new_name, conn, NULL, &st);
01869 if ( !NT_STATUS_IS_OK(copy_file(conn, new_name, old_name, OPENX_FILE_EXISTS_TRUNCATE|
01870 OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
01871 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
01872 new_name, old_name));
01873 *perr = WERR_ACCESS_DENIED;
01874 ver = -1;
01875 }
01876 }
01877 }
01878 }
01879
01880 if (driver->helpfile && strlen(driver->helpfile)) {
01881 if (!strequal(driver->helpfile, driver->driverpath) &&
01882 !strequal(driver->helpfile, driver->datafile) &&
01883 !strequal(driver->helpfile, driver->configfile)) {
01884 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->helpfile);
01885 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->helpfile);
01886 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
01887 driver_unix_convert(new_name, conn, NULL, &st);
01888 if ( !NT_STATUS_IS_OK(copy_file(conn, new_name, old_name, OPENX_FILE_EXISTS_TRUNCATE|
01889 OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
01890 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
01891 new_name, old_name));
01892 *perr = WERR_ACCESS_DENIED;
01893 ver = -1;
01894 }
01895 }
01896 }
01897 }
01898
01899 if (driver->dependentfiles) {
01900 for (i=0; *driver->dependentfiles[i]; i++) {
01901 if (!strequal(driver->dependentfiles[i], driver->driverpath) &&
01902 !strequal(driver->dependentfiles[i], driver->datafile) &&
01903 !strequal(driver->dependentfiles[i], driver->configfile) &&
01904 !strequal(driver->dependentfiles[i], driver->helpfile)) {
01905 int j;
01906 for (j=0; j < i; j++) {
01907 if (strequal(driver->dependentfiles[i], driver->dependentfiles[j])) {
01908 goto NextDriver;
01909 }
01910 }
01911
01912 slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->dependentfiles[i]);
01913 slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->dependentfiles[i]);
01914 if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
01915 driver_unix_convert(new_name, conn, NULL, &st);
01916 if ( !NT_STATUS_IS_OK(copy_file(conn, new_name, old_name,
01917 OPENX_FILE_EXISTS_TRUNCATE|
01918 OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
01919 DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
01920 new_name, old_name));
01921 *perr = WERR_ACCESS_DENIED;
01922 ver = -1;
01923 }
01924 }
01925 }
01926 NextDriver: ;
01927 }
01928 }
01929
01930 close_cnum(conn, user->vuid);
01931 unbecome_user();
01932
01933 return ver != -1 ? WERR_OK : WERR_UNKNOWN_PRINTER_DRIVER;
01934 }
01935
01936
01937
01938 static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
01939 {
01940 int len, buflen;
01941 const char *architecture;
01942 pstring directory;
01943 fstring temp_name;
01944 pstring key;
01945 char *buf;
01946 int i, ret;
01947 TDB_DATA kbuf, dbuf;
01948
01949 architecture = get_short_archi(driver->environment);
01950 if (!architecture) {
01951 return (uint32)-1;
01952 }
01953
01954
01955
01956
01957
01958
01959 slprintf(directory, sizeof(directory)-1, "\\print$\\%s\\%d\\", architecture, driver->cversion);
01960
01961
01962
01963
01964
01965
01966
01967 if (strlen(driver->driverpath)) {
01968 fstrcpy(temp_name, driver->driverpath);
01969 slprintf(driver->driverpath, sizeof(driver->driverpath)-1, "%s%s", directory, temp_name);
01970 }
01971
01972 if (strlen(driver->datafile)) {
01973 fstrcpy(temp_name, driver->datafile);
01974 slprintf(driver->datafile, sizeof(driver->datafile)-1, "%s%s", directory, temp_name);
01975 }
01976
01977 if (strlen(driver->configfile)) {
01978 fstrcpy(temp_name, driver->configfile);
01979 slprintf(driver->configfile, sizeof(driver->configfile)-1, "%s%s", directory, temp_name);
01980 }
01981
01982 if (strlen(driver->helpfile)) {
01983 fstrcpy(temp_name, driver->helpfile);
01984 slprintf(driver->helpfile, sizeof(driver->helpfile)-1, "%s%s", directory, temp_name);
01985 }
01986
01987 if (driver->dependentfiles) {
01988 for (i=0; *driver->dependentfiles[i]; i++) {
01989 fstrcpy(temp_name, driver->dependentfiles[i]);
01990 slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i])-1, "%s%s", directory, temp_name);
01991 }
01992 }
01993
01994 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
01995
01996 DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key ));
01997
01998 buf = NULL;
01999 len = buflen = 0;
02000
02001 again:
02002 len = 0;
02003 len += tdb_pack(buf+len, buflen-len, "dffffffff",
02004 driver->cversion,
02005 driver->name,
02006 driver->environment,
02007 driver->driverpath,
02008 driver->datafile,
02009 driver->configfile,
02010 driver->helpfile,
02011 driver->monitorname,
02012 driver->defaultdatatype);
02013
02014 if (driver->dependentfiles) {
02015 for (i=0; *driver->dependentfiles[i]; i++) {
02016 len += tdb_pack(buf+len, buflen-len, "f",
02017 driver->dependentfiles[i]);
02018 }
02019 }
02020
02021 if (len != buflen) {
02022 buf = (char *)SMB_REALLOC(buf, len);
02023 if (!buf) {
02024 DEBUG(0,("add_a_printer_driver_3: failed to enlarge buffer\n!"));
02025 ret = -1;
02026 goto done;
02027 }
02028 buflen = len;
02029 goto again;
02030 }
02031
02032
02033 kbuf.dptr = key;
02034 kbuf.dsize = strlen(key)+1;
02035 dbuf.dptr = buf;
02036 dbuf.dsize = len;
02037
02038 ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
02039
02040 done:
02041 if (ret)
02042 DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key ));
02043
02044 SAFE_FREE(buf);
02045 return ret;
02046 }
02047
02048
02049
02050 static uint32 add_a_printer_driver_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
02051 {
02052 NT_PRINTER_DRIVER_INFO_LEVEL_3 info3;
02053
02054 ZERO_STRUCT(info3);
02055 info3.cversion = driver->version;
02056 fstrcpy(info3.name,driver->name);
02057 fstrcpy(info3.environment,driver->environment);
02058 fstrcpy(info3.driverpath,driver->driverpath);
02059 fstrcpy(info3.datafile,driver->datafile);
02060 fstrcpy(info3.configfile,driver->configfile);
02061 fstrcpy(info3.helpfile,driver->helpfile);
02062 fstrcpy(info3.monitorname,driver->monitorname);
02063 fstrcpy(info3.defaultdatatype,driver->defaultdatatype);
02064 info3.dependentfiles = driver->dependentfiles;
02065
02066 return add_a_printer_driver_3(&info3);
02067 }
02068
02069
02070
02071
02072 static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, const char *driver, const char *arch)
02073 {
02074 NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
02075
02076 ZERO_STRUCT(info);
02077
02078 fstrcpy(info.name, driver);
02079 fstrcpy(info.defaultdatatype, "RAW");
02080
02081 fstrcpy(info.driverpath, "");
02082 fstrcpy(info.datafile, "");
02083 fstrcpy(info.configfile, "");
02084 fstrcpy(info.helpfile, "");
02085
02086 if ((info.dependentfiles= SMB_MALLOC_ARRAY(fstring, 2)) == NULL)
02087 return WERR_NOMEM;
02088
02089 memset(info.dependentfiles, '\0', 2*sizeof(fstring));
02090 fstrcpy(info.dependentfiles[0], "");
02091
02092 *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&info, sizeof(info));
02093 if (!*info_ptr) {
02094 SAFE_FREE(info.dependentfiles);
02095 return WERR_NOMEM;
02096 }
02097
02098 return WERR_OK;
02099 }
02100
02101
02102
02103 static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring drivername, const char *arch, uint32 version)
02104 {
02105 NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
02106 TDB_DATA kbuf, dbuf;
02107 const char *architecture;
02108 int len = 0;
02109 int i;
02110 pstring key;
02111
02112 ZERO_STRUCT(driver);
02113
02114 architecture = get_short_archi(arch);
02115 if ( !architecture ) {
02116 return WERR_UNKNOWN_PRINTER_DRIVER;
02117 }
02118
02119
02120
02121 if ( strcmp( architecture, SPL_ARCH_WIN40 ) == 0 )
02122 version = 0;
02123
02124 DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, drivername));
02125
02126 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, drivername);
02127
02128 kbuf.dptr = key;
02129 kbuf.dsize = strlen(key)+1;
02130
02131 dbuf = tdb_fetch(tdb_drivers, kbuf);
02132 if (!dbuf.dptr)
02133 return WERR_UNKNOWN_PRINTER_DRIVER;
02134
02135 len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
02136 &driver.cversion,
02137 driver.name,
02138 driver.environment,
02139 driver.driverpath,
02140 driver.datafile,
02141 driver.configfile,
02142 driver.helpfile,
02143 driver.monitorname,
02144 driver.defaultdatatype);
02145
02146 i=0;
02147 while (len < dbuf.dsize) {
02148 driver.dependentfiles = SMB_REALLOC_ARRAY(driver.dependentfiles, fstring, i+2);
02149 if ( !driver.dependentfiles ) {
02150 DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n"));
02151 break;
02152 }
02153
02154 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
02155 &driver.dependentfiles[i]);
02156 i++;
02157 }
02158
02159 if ( driver.dependentfiles )
02160 fstrcpy( driver.dependentfiles[i], "" );
02161
02162 SAFE_FREE(dbuf.dptr);
02163
02164 if (len != dbuf.dsize) {
02165 SAFE_FREE(driver.dependentfiles);
02166
02167 return get_a_printer_driver_3_default(info_ptr, drivername, arch);
02168 }
02169
02170 *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
02171 if (!*info_ptr) {
02172 SAFE_FREE(driver.dependentfiles);
02173 return WERR_NOMEM;
02174 }
02175
02176 return WERR_OK;
02177 }
02178
02179
02180
02181
02182
02183 static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
02184 {
02185 uint32 result;
02186 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
02187 int i;
02188
02189 DEBUG(20,("Dumping printer driver at level [%d]\n", level));
02190
02191 switch (level)
02192 {
02193 case 3:
02194 {
02195 if (driver.info_3 == NULL)
02196 result=5;
02197 else {
02198 info3=driver.info_3;
02199
02200 DEBUGADD(20,("version:[%d]\n", info3->cversion));
02201 DEBUGADD(20,("name:[%s]\n", info3->name));
02202 DEBUGADD(20,("environment:[%s]\n", info3->environment));
02203 DEBUGADD(20,("driverpath:[%s]\n", info3->driverpath));
02204 DEBUGADD(20,("datafile:[%s]\n", info3->datafile));
02205 DEBUGADD(20,("configfile:[%s]\n", info3->configfile));
02206 DEBUGADD(20,("helpfile:[%s]\n", info3->helpfile));
02207 DEBUGADD(20,("monitorname:[%s]\n", info3->monitorname));
02208 DEBUGADD(20,("defaultdatatype:[%s]\n", info3->defaultdatatype));
02209
02210 for (i=0; info3->dependentfiles &&
02211 *info3->dependentfiles[i]; i++) {
02212 DEBUGADD(20,("dependentfile:[%s]\n",
02213 info3->dependentfiles[i]));
02214 }
02215 result=0;
02216 }
02217 break;
02218 }
02219 default:
02220 DEBUGADD(20,("dump_a_printer_driver: Level %u not implemented\n", (unsigned int)level));
02221 result=1;
02222 break;
02223 }
02224
02225 return result;
02226 }
02227
02228
02229
02230 int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
02231 {
02232 int len = 0;
02233
02234 len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
02235
02236 if (!nt_devmode)
02237 return len;
02238
02239 len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
02240 nt_devmode->devicename,
02241 nt_devmode->formname,
02242
02243 nt_devmode->specversion,
02244 nt_devmode->driverversion,
02245 nt_devmode->size,
02246 nt_devmode->driverextra,
02247 nt_devmode->orientation,
02248 nt_devmode->papersize,
02249 nt_devmode->paperlength,
02250 nt_devmode->paperwidth,
02251 nt_devmode->scale,
02252 nt_devmode->copies,
02253 nt_devmode->defaultsource,
02254 nt_devmode->printquality,
02255 nt_devmode->color,
02256 nt_devmode->duplex,
02257 nt_devmode->yresolution,
02258 nt_devmode->ttoption,
02259 nt_devmode->collate,
02260 nt_devmode->logpixels,
02261
02262 nt_devmode->fields,
02263 nt_devmode->bitsperpel,
02264 nt_devmode->pelswidth,
02265 nt_devmode->pelsheight,
02266 nt_devmode->displayflags,
02267 nt_devmode->displayfrequency,
02268 nt_devmode->icmmethod,
02269 nt_devmode->icmintent,
02270 nt_devmode->mediatype,
02271 nt_devmode->dithertype,
02272 nt_devmode->reserved1,
02273 nt_devmode->reserved2,
02274 nt_devmode->panningwidth,
02275 nt_devmode->panningheight,
02276 nt_devmode->nt_dev_private);
02277
02278
02279 if (nt_devmode->nt_dev_private) {
02280 len += tdb_pack(buf+len, buflen-len, "B",
02281 nt_devmode->driverextra,
02282 nt_devmode->nt_dev_private);
02283 }
02284
02285 DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
02286
02287 return len;
02288 }
02289
02290
02291
02292
02293
02294 static int pack_values(NT_PRINTER_DATA *data, char *buf, int buflen)
02295 {
02296 int len = 0;
02297 int i, j;
02298 REGISTRY_VALUE *val;
02299 REGVAL_CTR *val_ctr;
02300 pstring path;
02301 int num_values;
02302
02303 if ( !data )
02304 return 0;
02305
02306
02307
02308 for ( i=0; i<data->num_keys; i++ ) {
02309 val_ctr = data->keys[i].values;
02310 num_values = regval_ctr_numvals( val_ctr );
02311
02312
02313
02314 len += tdb_pack(buf+len, buflen-len, "pPdB",
02315 &data->keys[i].name,
02316 data->keys[i].name,
02317 REG_NONE,
02318 0,
02319 NULL);
02320
02321
02322
02323 for ( j=0; j<num_values; j++ ) {
02324
02325
02326 val = regval_ctr_specific_value( val_ctr, j );
02327 pstrcpy( path, data->keys[i].name );
02328 pstrcat( path, "\\" );
02329 pstrcat( path, regval_name(val) );
02330
02331 len += tdb_pack(buf+len, buflen-len, "pPdB",
02332 val,
02333 path,
02334 regval_type(val),
02335 regval_size(val),
02336 regval_data_p(val) );
02337
02338 DEBUG(8,("specific: [%s], len: %d\n", regval_name(val), regval_size(val)));
02339 }
02340
02341 }
02342
02343
02344
02345 len += tdb_pack(buf+len, buflen-len, "p", NULL);
02346
02347 return len;
02348 }
02349
02350
02351
02352
02353
02354
02355
02356 uint32 del_a_printer(const char *sharename)
02357 {
02358 TDB_DATA kbuf;
02359 pstring printdb_path;
02360
02361 kbuf = make_printer_tdbkey( sharename );
02362 tdb_delete(tdb_printers, kbuf);
02363
02364 kbuf.dptr = make_printers_secdesc_tdbkey( sharename );
02365 kbuf.dsize = strlen(kbuf.dptr) + 1;
02366 tdb_delete(tdb_printers, kbuf);
02367
02368 close_all_print_db();
02369
02370 if (geteuid() == 0) {
02371 pstrcpy(printdb_path, lock_path("printing/"));
02372 pstrcat(printdb_path, sharename);
02373 pstrcat(printdb_path, ".tdb");
02374
02375 unlink(printdb_path);
02376 }
02377
02378 return 0;
02379 }
02380
02381
02382
02383 static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
02384 {
02385 char *buf;
02386 int buflen, len;
02387 WERROR ret;
02388 TDB_DATA kbuf, dbuf;
02389
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401
02402 if ( info->servername[0] != '\0' ) {
02403 trim_string(info->printername, info->servername, NULL);
02404 trim_char(info->printername, '\\', '\0');
02405 info->servername[0]='\0';
02406 }
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418 buf = NULL;
02419 buflen = 0;
02420
02421 again:
02422 len = 0;
02423 len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
02424 info->attributes,
02425 info->priority,
02426 info->default_priority,
02427 info->starttime,
02428 info->untiltime,
02429 info->status,
02430 info->cjobs,
02431 info->averageppm,
02432 info->changeid,
02433 info->c_setprinter,
02434 info->setuptime,
02435 info->servername,
02436 info->printername,
02437 info->sharename,
02438 info->portname,
02439 info->drivername,
02440 info->comment,
02441 info->location,
02442 info->sepfile,
02443 info->printprocessor,
02444 info->datatype,
02445 info->parameters);
02446
02447 len += pack_devicemode(info->devmode, buf+len, buflen-len);
02448
02449 len += pack_values( info->data, buf+len, buflen-len );
02450
02451 if (buflen != len) {
02452 buf = (char *)SMB_REALLOC(buf, len);
02453 if (!buf) {
02454 DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n"));
02455 ret = WERR_NOMEM;
02456 goto done;
02457 }
02458 buflen = len;
02459 goto again;
02460 }
02461
02462
02463 kbuf = make_printer_tdbkey( info->sharename );
02464
02465 dbuf.dptr = buf;
02466 dbuf.dsize = len;
02467
02468 ret = (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) == 0? WERR_OK : WERR_NOMEM);
02469
02470 done:
02471 if (!W_ERROR_IS_OK(ret))
02472 DEBUG(8, ("error updating printer to tdb on disk\n"));
02473
02474 SAFE_FREE(buf);
02475
02476 DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
02477 info->sharename, info->drivername, info->portname, len));
02478
02479 return ret;
02480 }
02481
02482
02483
02484
02485
02486
02487 NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
02488 {
02489
02490 char adevice[MAXDEVICENAME];
02491 NT_DEVICEMODE *nt_devmode = SMB_MALLOC_P(NT_DEVICEMODE);
02492
02493 if (nt_devmode == NULL) {
02494 DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
02495 return NULL;
02496 }
02497
02498 ZERO_STRUCTP(nt_devmode);
02499
02500 slprintf(adevice, sizeof(adevice), "%s", default_devicename);
02501 fstrcpy(nt_devmode->devicename, adevice);
02502
02503 fstrcpy(nt_devmode->formname, "Letter");
02504
02505 nt_devmode->specversion = 0x0401;
02506 nt_devmode->driverversion = 0x0400;
02507 nt_devmode->size = 0x00DC;
02508 nt_devmode->driverextra = 0x0000;
02509 nt_devmode->fields = FORMNAME | TTOPTION | PRINTQUALITY |
02510 DEFAULTSOURCE | COPIES | SCALE |
02511 PAPERSIZE | ORIENTATION;
02512 nt_devmode->orientation = 1;
02513 nt_devmode->papersize = PAPER_LETTER;
02514 nt_devmode->paperlength = 0;
02515 nt_devmode->paperwidth = 0;
02516 nt_devmode->scale = 0x64;
02517 nt_devmode->copies = 1;
02518 nt_devmode->defaultsource = BIN_FORMSOURCE;
02519 nt_devmode->printquality = RES_HIGH;
02520 nt_devmode->color = COLOR_MONOCHROME;
02521 nt_devmode->duplex = DUP_SIMPLEX;
02522 nt_devmode->yresolution = 0;
02523 nt_devmode->ttoption = TT_SUBDEV;
02524 nt_devmode->collate = COLLATE_FALSE;
02525 nt_devmode->icmmethod = 0;
02526 nt_devmode->icmintent = 0;
02527 nt_devmode->mediatype = 0;
02528 nt_devmode->dithertype = 0;
02529
02530
02531 nt_devmode->logpixels = 0;
02532 nt_devmode->bitsperpel = 0;
02533 nt_devmode->pelswidth = 0;
02534 nt_devmode->pelsheight = 0;
02535 nt_devmode->displayflags = 0;
02536 nt_devmode->displayfrequency = 0;
02537 nt_devmode->reserved1 = 0;
02538 nt_devmode->reserved2 = 0;
02539 nt_devmode->panningwidth = 0;
02540 nt_devmode->panningheight = 0;
02541
02542 nt_devmode->nt_dev_private = NULL;
02543 return nt_devmode;
02544 }
02545
02546
02547
02548
02549
02550 NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
02551 {
02552 NT_DEVICEMODE *new_nt_devicemode = NULL;
02553
02554 if ( !nt_devicemode )
02555 return NULL;
02556
02557 if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
02558 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
02559 return NULL;
02560 }
02561
02562 new_nt_devicemode->nt_dev_private = NULL;
02563 if (nt_devicemode->nt_dev_private != NULL) {
02564 if ((new_nt_devicemode->nt_dev_private = (uint8 *)memdup(nt_devicemode->nt_dev_private, nt_devicemode->driverextra)) == NULL) {
02565 SAFE_FREE(new_nt_devicemode);
02566 DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
02567 return NULL;
02568 }
02569 }
02570
02571 return new_nt_devicemode;
02572 }
02573
02574
02575
02576
02577
02578 void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
02579 {
02580 NT_DEVICEMODE *nt_devmode = *devmode_ptr;
02581
02582 if(nt_devmode == NULL)
02583 return;
02584
02585 DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
02586
02587 SAFE_FREE(nt_devmode->nt_dev_private);
02588 SAFE_FREE(*devmode_ptr);
02589 }
02590
02591
02592
02593
02594
02595 static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
02596 {
02597 NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
02598
02599 if ( !info )
02600 return;
02601
02602 free_nt_devicemode(&info->devmode);
02603
02604 TALLOC_FREE( *info_ptr );
02605 }
02606
02607
02608
02609
02610 int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
02611 {
02612 int len = 0;
02613 int extra_len = 0;
02614 NT_DEVICEMODE devmode;
02615
02616 ZERO_STRUCT(devmode);
02617
02618 len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
02619
02620 if (!*nt_devmode) return len;
02621
02622 len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
02623 devmode.devicename,
02624 devmode.formname,
02625
02626 &devmode.specversion,
02627 &devmode.driverversion,
02628 &devmode.size,
02629 &devmode.driverextra,
02630 &devmode.orientation,
02631 &devmode.papersize,
02632 &devmode.paperlength,
02633 &devmode.paperwidth,
02634 &devmode.scale,
02635 &devmode.copies,
02636 &devmode.defaultsource,
02637 &devmode.printquality,
02638 &devmode.color,
02639 &devmode.duplex,
02640 &devmode.yresolution,
02641 &devmode.ttoption,
02642 &devmode.collate,
02643 &devmode.logpixels,
02644
02645 &devmode.fields,
02646 &devmode.bitsperpel,
02647 &devmode.pelswidth,
02648 &devmode.pelsheight,
02649 &devmode.displayflags,
02650 &devmode.displayfrequency,
02651 &devmode.icmmethod,
02652 &devmode.icmintent,
02653 &devmode.mediatype,
02654 &devmode.dithertype,
02655 &devmode.reserved1,
02656 &devmode.reserved2,
02657 &devmode.panningwidth,
02658 &devmode.panningheight,
02659 &devmode.nt_dev_private);
02660
02661 if (devmode.nt_dev_private) {
02662
02663
02664
02665 len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.nt_dev_private);
02666 devmode.driverextra=(uint16)extra_len;
02667
02668
02669 if (devmode.driverextra == 0) {
02670 devmode.nt_dev_private = NULL;
02671 }
02672 }
02673
02674 *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
02675 if (!*nt_devmode) {
02676 SAFE_FREE(devmode.nt_dev_private);
02677 return -1;
02678 }
02679
02680 DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
02681 if (devmode.nt_dev_private)
02682 DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
02683
02684 return len;
02685 }
02686
02687
02688
02689
02690
02691 int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
02692 {
02693 NT_PRINTER_KEY *d;
02694 int key_index;
02695
02696 if ( !name || !data )
02697 return -1;
02698
02699
02700
02701 if ( !(d = TALLOC_REALLOC_ARRAY( data, data->keys, NT_PRINTER_KEY, data->num_keys+1)) ) {
02702 DEBUG(0,("add_new_printer_key: Realloc() failed!\n"));
02703 return -1;
02704 }
02705
02706 data->keys = d;
02707
02708 key_index = data->num_keys;
02709
02710
02711
02712 data->keys[key_index].name = talloc_strdup( data, name );
02713
02714 if ( !(data->keys[key_index].values = TALLOC_ZERO_P( data, REGVAL_CTR )) )
02715 return -1;
02716
02717 data->num_keys++;
02718
02719 DEBUG(10,("add_new_printer_key: Inserted new data key [%s]\n", name ));
02720
02721 return key_index;
02722 }
02723
02724
02725
02726
02727
02728 int delete_printer_key( NT_PRINTER_DATA *data, const char *name )
02729 {
02730 int i;
02731
02732 for ( i=0; i<data->num_keys; i++ ) {
02733 if ( strequal( data->keys[i].name, name ) ) {
02734
02735
02736
02737 TALLOC_FREE( data->keys[i].name );
02738 TALLOC_FREE( data->keys[i].values );
02739
02740
02741
02742 data->num_keys--;
02743 if ( data->num_keys && (i < data->num_keys) )
02744 memmove( &data->keys[i], &data->keys[i+1], sizeof(NT_PRINTER_KEY)*(data->num_keys-i) );
02745
02746 break;
02747 }
02748 }
02749
02750
02751 return data->num_keys;
02752 }
02753
02754
02755
02756
02757
02758 int lookup_printerkey( NT_PRINTER_DATA *data, const char *name )
02759 {
02760 int key_index = -1;
02761 int i;
02762
02763 if ( !data || !name )
02764 return -1;
02765
02766 DEBUG(12,("lookup_printerkey: Looking for [%s]\n", name));
02767
02768
02769
02770 for ( i=0; i<data->num_keys; i++ ) {
02771 if ( strequal(data->keys[i].name, name) ) {
02772 DEBUG(12,("lookup_printerkey: Found [%s]!\n", name));
02773 key_index = i;
02774 break;
02775
02776 }
02777 }
02778
02779 return key_index;
02780 }
02781
02782
02783
02784
02785 int get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subkeys )
02786 {
02787 int i, j;
02788 int key_len;
02789 int num_subkeys = 0;
02790 char *p;
02791 fstring *subkeys_ptr = NULL;
02792 fstring subkeyname;
02793
02794 *subkeys = NULL;
02795
02796 if ( !data )
02797 return 0;
02798
02799 if ( !key )
02800 return -1;
02801
02802
02803
02804 if ( strlen(key) == 0 ) {
02805 for ( i=0; i<data->num_keys; i++ ) {
02806
02807
02808
02809 if ( !(subkeys_ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) {
02810 DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n",
02811 num_subkeys+1));
02812 return -1;
02813 }
02814
02815 fstrcpy( subkeys_ptr[num_subkeys], data->keys[i].name );
02816 num_subkeys++;
02817 }
02818
02819 goto done;
02820 }
02821
02822
02823
02824
02825 for ( i=0; i<data->num_keys; i++ ) {
02826 if ( StrnCaseCmp(data->keys[i].name, key, strlen(key)) == 0 ) {
02827
02828
02829 key_len = strlen( key );
02830 if ( strlen(data->keys[i].name) == key_len )
02831 break;
02832
02833
02834
02835 p = data->keys[i].name + key_len;
02836 if ( *p == '\\' )
02837 p++;
02838 fstrcpy( subkeyname, p );
02839 if ( (p = strchr( subkeyname, '\\' )) )
02840 *p = '\0';
02841
02842
02843
02844 for ( j=0; j<num_subkeys; j++ ) {
02845 if ( strequal( subkeys_ptr[j], subkeyname ) )
02846 break;
02847 }
02848
02849 if ( j != num_subkeys )
02850 continue;
02851
02852
02853
02854 if ( !(subkeys_ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) {
02855 DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n",
02856 num_subkeys+1));
02857 return 0;
02858 }
02859
02860 fstrcpy( subkeys_ptr[num_subkeys], subkeyname );
02861 num_subkeys++;
02862 }
02863
02864 }
02865
02866
02867
02868 if ( i == data->num_keys ) {
02869 SAFE_FREE(subkeys_ptr);
02870 return -1;
02871 }
02872
02873 done:
02874
02875
02876 if (num_subkeys)
02877 fstrcpy(subkeys_ptr[num_subkeys], "" );
02878
02879 *subkeys = subkeys_ptr;
02880
02881 return num_subkeys;
02882 }
02883
02884 #ifdef HAVE_ADS
02885 static void map_sz_into_ctr(REGVAL_CTR *ctr, const char *val_name,
02886 const char *sz)
02887 {
02888 smb_ucs2_t conv_str[1024];
02889 size_t str_size;
02890
02891 regval_ctr_delvalue(ctr, val_name);
02892 str_size = push_ucs2(NULL, conv_str, sz, sizeof(conv_str),
02893 STR_TERMINATE | STR_NOALIGN);
02894 regval_ctr_addvalue(ctr, val_name, REG_SZ,
02895 (char *) conv_str, str_size);
02896 }
02897
02898 static void map_dword_into_ctr(REGVAL_CTR *ctr, const char *val_name,
02899 uint32 dword)
02900 {
02901 regval_ctr_delvalue(ctr, val_name);
02902 regval_ctr_addvalue(ctr, val_name, REG_DWORD,
02903 (char *) &dword, sizeof(dword));
02904 }
02905
02906 static void map_bool_into_ctr(REGVAL_CTR *ctr, const char *val_name,
02907 BOOL b)
02908 {
02909 uint8 bin_bool = (b ? 1 : 0);
02910 regval_ctr_delvalue(ctr, val_name);
02911 regval_ctr_addvalue(ctr, val_name, REG_BINARY,
02912 (char *) &bin_bool, sizeof(bin_bool));
02913 }
02914
02915 static void map_single_multi_sz_into_ctr(REGVAL_CTR *ctr, const char *val_name,
02916 const char *multi_sz)
02917 {
02918 smb_ucs2_t *conv_strs = NULL;
02919 size_t str_size;
02920
02921
02922
02923 str_size = strlen(multi_sz) + 2;
02924 conv_strs = SMB_CALLOC_ARRAY(smb_ucs2_t, str_size);
02925 if (!conv_strs) {
02926 return;
02927 }
02928
02929
02930 str_size *= sizeof(smb_ucs2_t);
02931 push_ucs2(NULL, conv_strs, multi_sz, str_size,
02932 STR_TERMINATE | STR_NOALIGN);
02933
02934 regval_ctr_delvalue(ctr, val_name);
02935 regval_ctr_addvalue(ctr, val_name, REG_MULTI_SZ,
02936 (char *) conv_strs, str_size);
02937 safe_free(conv_strs);
02938
02939 }
02940
02941
02942
02943
02944
02945
02946
02947
02948 static BOOL map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2)
02949 {
02950 REGVAL_CTR *ctr = NULL;
02951 fstring longname;
02952 fstring dnssuffix;
02953 char *allocated_string = NULL;
02954 const char *ascii_str;
02955 int i;
02956
02957 if ((i = lookup_printerkey(info2->data, SPOOL_DSSPOOLER_KEY)) < 0)
02958 i = add_new_printer_key(info2->data, SPOOL_DSSPOOLER_KEY);
02959 ctr = info2->data->keys[i].values;
02960
02961 map_sz_into_ctr(ctr, SPOOL_REG_PRINTERNAME, info2->sharename);
02962 map_sz_into_ctr(ctr, SPOOL_REG_SHORTSERVERNAME, global_myname());
02963
02964
02965
02966
02967
02968 if ( get_mydnsdomname( dnssuffix ) )
02969 fstr_sprintf( longname, "%s.%s", global_myname(), dnssuffix );
02970 else
02971 fstrcpy( longname, global_myname() );
02972
02973 map_sz_into_ctr(ctr, SPOOL_REG_SERVERNAME, longname);
02974
02975 asprintf(&allocated_string, "\\\\%s\\%s", longname, info2->sharename);
02976 map_sz_into_ctr(ctr, SPOOL_REG_UNCNAME, allocated_string);
02977 SAFE_FREE(allocated_string);
02978
02979 map_dword_into_ctr(ctr, SPOOL_REG_VERSIONNUMBER, 4);
02980 map_sz_into_ctr(ctr, SPOOL_REG_DRIVERNAME, info2->drivername);
02981 map_sz_into_ctr(ctr, SPOOL_REG_LOCATION, info2->location);
02982 map_sz_into_ctr(ctr, SPOOL_REG_DESCRIPTION, info2->comment);
02983 map_single_multi_sz_into_ctr(ctr, SPOOL_REG_PORTNAME, info2->portname);
02984 map_sz_into_ctr(ctr, SPOOL_REG_PRINTSEPARATORFILE, info2->sepfile);
02985 map_dword_into_ctr(ctr, SPOOL_REG_PRINTSTARTTIME, info2->starttime);
02986 map_dword_into_ctr(ctr, SPOOL_REG_PRINTENDTIME, info2->untiltime);
02987 map_dword_into_ctr(ctr, SPOOL_REG_PRIORITY, info2->priority);
02988
02989 map_bool_into_ctr(ctr, SPOOL_REG_PRINTKEEPPRINTEDJOBS,
02990 (info2->attributes &
02991 PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
02992
02993 switch (info2->attributes & 0x3) {
02994 case 0:
02995 ascii_str = SPOOL_REGVAL_PRINTWHILESPOOLING;
02996 break;
02997 case 1:
02998 ascii_str = SPOOL_REGVAL_PRINTAFTERSPOOLED;
02999 break;
03000 case 2:
03001 ascii_str = SPOOL_REGVAL_PRINTDIRECT;
03002 break;
03003 default:
03004 ascii_str = "unknown";
03005 }
03006 map_sz_into_ctr(ctr, SPOOL_REG_PRINTSPOOLING, ascii_str);
03007
03008 return True;
03009 }
03010
03011
03012
03013
03014 static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2,
03015 struct GUID guid)
03016 {
03017 int i;
03018 REGVAL_CTR *ctr=NULL;
03019 UNISTR2 unistr_guid;
03020
03021
03022 if ((i = lookup_printerkey(info2->data, SPOOL_DSSPOOLER_KEY)) < 0)
03023 i = add_new_printer_key(info2->data, SPOOL_DSSPOOLER_KEY);
03024 ctr = info2->data->keys[i].values;
03025
03026 regval_ctr_delvalue(ctr, "objectGUID");
03027
03028
03029
03030
03031 ZERO_STRUCT( unistr_guid );
03032 init_unistr2( &unistr_guid, smb_uuid_string_static(guid),
03033 UNI_STR_TERMINATE );
03034
03035 regval_ctr_addvalue(ctr, "objectGUID", REG_SZ,
03036 (char *)unistr_guid.buffer,
03037 unistr_guid.uni_max_len*2);
03038
03039 }
03040
03041 static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
03042 NT_PRINTER_INFO_LEVEL *printer)
03043 {
03044 ADS_STATUS ads_rc;
03045 LDAPMessage *res;
03046 char *prt_dn = NULL, *srv_dn, *srv_cn_0, *srv_cn_escaped, *sharename_escaped;
03047 char *srv_dn_utf8, **srv_cn_utf8;
03048 TALLOC_CTX *ctx;
03049 ADS_MODLIST mods;
03050 const char *attrs[] = {"objectGUID", NULL};
03051 struct GUID guid;
03052 WERROR win_rc = WERR_OK;
03053
03054 DEBUG(5, ("publishing printer %s\n", printer->info_2->printername));
03055
03056
03057 ads_find_machine_acct(ads, &res, global_myname());
03058
03059
03060
03061
03062 srv_dn_utf8 = ldap_get_dn((LDAP *)ads->ld, (LDAPMessage *)res);
03063 if (!srv_dn_utf8) {
03064 ads_destroy(&ads);
03065 return WERR_SERVER_UNAVAILABLE;
03066 }
03067 ads_msgfree(ads, res);
03068 srv_cn_utf8 = ldap_explode_dn(srv_dn_utf8, 1);
03069 if (!srv_cn_utf8) {
03070 ldap_memfree(srv_dn_utf8);
03071 ads_destroy(&ads);
03072 return WERR_SERVER_UNAVAILABLE;
03073 }
03074
03075 if (pull_utf8_allocate(&srv_dn, srv_dn_utf8) == (size_t)-1) {
03076 ldap_memfree(srv_dn_utf8);
03077 ldap_memfree(srv_cn_utf8);
03078 ads_destroy(&ads);
03079 return WERR_SERVER_UNAVAILABLE;
03080 }
03081 if (pull_utf8_allocate(&srv_cn_0, srv_cn_utf8[0]) == (size_t)-1) {
03082 ldap_memfree(srv_dn_utf8);
03083 ldap_memfree(srv_cn_utf8);
03084 ads_destroy(&ads);
03085 SAFE_FREE(srv_dn);
03086 return WERR_SERVER_UNAVAILABLE;
03087 }
03088
03089 ldap_memfree(srv_dn_utf8);
03090 ldap_memfree(srv_cn_utf8);
03091
03092 srv_cn_escaped = escape_rdn_val_string_alloc(srv_cn_0);
03093 if (!srv_cn_escaped) {
03094 SAFE_FREE(srv_cn_0);
03095 ldap_memfree(srv_dn_utf8);
03096 ads_destroy(&ads);
03097 return WERR_SERVER_UNAVAILABLE;
03098 }
03099 sharename_escaped = escape_rdn_val_string_alloc(printer->info_2->sharename);
03100 if (!sharename_escaped) {
03101 SAFE_FREE(srv_cn_escaped);
03102 SAFE_FREE(srv_cn_0);
03103 ldap_memfree(srv_dn_utf8);
03104 ads_destroy(&ads);
03105 return WERR_SERVER_UNAVAILABLE;
03106 }
03107
03108
03109 asprintf(&prt_dn, "cn=%s-%s,%s", srv_cn_escaped, sharename_escaped, srv_dn);
03110
03111 SAFE_FREE(srv_dn);
03112 SAFE_FREE(srv_cn_0);
03113 SAFE_FREE(srv_cn_escaped);
03114 SAFE_FREE(sharename_escaped);
03115
03116
03117 ctx = talloc_init("nt_printer_publish_ads");
03118 if (ctx == NULL) {
03119 SAFE_FREE(prt_dn);
03120 return WERR_NOMEM;
03121 }
03122
03123 mods = ads_init_mods(ctx);
03124
03125 if (mods == NULL) {
03126 SAFE_FREE(prt_dn);
03127 talloc_destroy(ctx);
03128 return WERR_NOMEM;
03129 }
03130
03131 get_local_printer_publishing_data(ctx, &mods, printer->info_2->data);
03132 ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME,
03133 printer->info_2->sharename);
03134
03135
03136 ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx, &mods);
03137 if (ads_rc.err.rc == LDAP_NO_SUCH_OBJECT)
03138 ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods);
03139
03140 if (!ADS_ERR_OK(ads_rc))
03141 DEBUG(3, ("error publishing %s: %s\n", printer->info_2->sharename, ads_errstr(ads_rc)));
03142
03143 talloc_destroy(ctx);
03144
03145
03146 if (ADS_ERR_OK(ads_search_dn(ads, &res, prt_dn, attrs))) {
03147 ZERO_STRUCT(guid);
03148 ads_pull_guid(ads, res, &guid);
03149 ads_msgfree(ads, res);
03150 store_printer_guid(printer->info_2, guid);
03151 win_rc = mod_a_printer(printer, 2);
03152 }
03153
03154 SAFE_FREE(prt_dn);
03155 return win_rc;
03156 }
03157
03158 static WERROR nt_printer_unpublish_ads(ADS_STRUCT *ads,
03159 NT_PRINTER_INFO_LEVEL *printer)
03160 {
03161 ADS_STATUS ads_rc;
03162 LDAPMessage *res;
03163 char *prt_dn = NULL;
03164
03165 DEBUG(5, ("unpublishing printer %s\n", printer->info_2->printername));
03166
03167
03168 ads_rc = ads_find_printer_on_server(ads, &res,
03169 printer->info_2->sharename, global_myname());
03170
03171 if (ADS_ERR_OK(ads_rc) && ads_count_replies(ads, res)) {
03172 prt_dn = ads_get_dn(ads, res);
03173 if (!prt_dn) {
03174 ads_msgfree(ads, res);
03175 return WERR_NOMEM;
03176 }
03177 ads_rc = ads_del_dn(ads, prt_dn);
03178 ads_memfree(ads, prt_dn);
03179 }
03180
03181 ads_msgfree(ads, res);
03182 return WERR_OK;
03183 }
03184
03185
03186
03187
03188
03189
03190
03191
03192 WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
03193 {
03194 ADS_STATUS ads_rc;
03195 ADS_STRUCT *ads = NULL;
03196 NT_PRINTER_INFO_LEVEL *printer = NULL;
03197 WERROR win_rc;
03198
03199 win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum));
03200 if (!W_ERROR_IS_OK(win_rc))
03201 goto done;
03202
03203 switch (action) {
03204 case SPOOL_DS_PUBLISH:
03205 case SPOOL_DS_UPDATE:
03206
03207 if (!(map_nt_printer_info2_to_dsspooler(printer->info_2))) {
03208 win_rc = WERR_NOMEM;
03209 goto done;
03210 }
03211
03212 printer->info_2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED;
03213 break;
03214 case SPOOL_DS_UNPUBLISH:
03215 printer->info_2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED;
03216 break;
03217 default:
03218 win_rc = WERR_NOT_SUPPORTED;
03219 goto done;
03220 }
03221
03222 win_rc = mod_a_printer(printer, 2);
03223 if (!W_ERROR_IS_OK(win_rc)) {
03224 DEBUG(3, ("err %d saving data\n", W_ERROR_V(win_rc)));
03225 goto done;
03226 }
03227
03228 ads = ads_init(lp_realm(), lp_workgroup(), NULL);
03229 if (!ads) {
03230 DEBUG(3, ("ads_init() failed\n"));
03231 win_rc = WERR_SERVER_UNAVAILABLE;
03232 goto done;
03233 }
03234 setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
03235 SAFE_FREE(ads->auth.password);
03236 ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
03237 NULL, NULL);
03238
03239
03240 ads_rc = ads_connect(ads);
03241 if (!ADS_ERR_OK(ads_rc)) {
03242 DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
03243 win_rc = WERR_ACCESS_DENIED;
03244 goto done;
03245 }
03246
03247 switch (action) {
03248 case SPOOL_DS_PUBLISH:
03249 case SPOOL_DS_UPDATE:
03250 win_rc = nt_printer_publish_ads(ads, printer);
03251 break;
03252 case SPOOL_DS_UNPUBLISH:
03253 win_rc = nt_printer_unpublish_ads(ads, printer);
03254 break;
03255 }
03256
03257 done:
03258 free_a_printer(&printer, 2);
03259 ads_destroy(&ads);
03260 return win_rc;
03261 }
03262
03263 WERROR check_published_printers(void)
03264 {
03265 ADS_STATUS ads_rc;
03266 ADS_STRUCT *ads = NULL;
03267 int snum;
03268 int n_services = lp_numservices();
03269 NT_PRINTER_INFO_LEVEL *printer = NULL;
03270
03271 ads = ads_init(lp_realm(), lp_workgroup(), NULL);
03272 if (!ads) {
03273 DEBUG(3, ("ads_init() failed\n"));
03274 return WERR_SERVER_UNAVAILABLE;
03275 }
03276 setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
03277 SAFE_FREE(ads->auth.password);
03278 ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
03279 NULL, NULL);
03280
03281
03282 ads_rc = ads_connect(ads);
03283 if (!ADS_ERR_OK(ads_rc)) {
03284 DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
03285 ads_destroy(&ads);
03286 ads_kdestroy("MEMORY:prtpub_cache");
03287 return WERR_ACCESS_DENIED;
03288 }
03289
03290 for (snum = 0; snum < n_services; snum++) {
03291 if (!(lp_snum_ok(snum) && lp_print_ok(snum)))
03292 continue;
03293
03294 if (W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2,
03295 lp_servicename(snum))) &&
03296 (printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED))
03297 nt_printer_publish_ads(ads, printer);
03298
03299 free_a_printer(&printer, 2);
03300 }
03301
03302 ads_destroy(&ads);
03303 ads_kdestroy("MEMORY:prtpub_cache");
03304 return WERR_OK;
03305 }
03306
03307 BOOL is_printer_published(Printer_entry *print_hnd, int snum,
03308 struct GUID *guid)
03309 {
03310 NT_PRINTER_INFO_LEVEL *printer = NULL;
03311 REGVAL_CTR *ctr;
03312 REGISTRY_VALUE *guid_val;
03313 WERROR win_rc;
03314 int i;
03315 BOOL ret = False;
03316
03317 win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum));
03318
03319 if (!W_ERROR_IS_OK(win_rc) ||
03320 !(printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED) ||
03321 ((i = lookup_printerkey(printer->info_2->data, SPOOL_DSSPOOLER_KEY)) < 0) ||
03322 !(ctr = printer->info_2->data->keys[i].values) ||
03323 !(guid_val = regval_ctr_getvalue(ctr, "objectGUID")))
03324 {
03325 free_a_printer(&printer, 2);
03326 return False;
03327 }
03328
03329
03330
03331 if ( guid ) {
03332 fstring guid_str;
03333
03334
03335
03336
03337 switch ( regval_type(guid_val) ){
03338 case REG_SZ:
03339 rpcstr_pull( guid_str, regval_data_p(guid_val),
03340 sizeof(guid_str)-1, -1, STR_TERMINATE );
03341 ret = smb_string_to_uuid( guid_str, guid );
03342 break;
03343 case REG_BINARY:
03344 if ( regval_size(guid_val) != sizeof(struct GUID) ) {
03345 ret = False;
03346 break;
03347 }
03348 memcpy(guid, regval_data_p(guid_val), sizeof(struct GUID));
03349 break;
03350 default:
03351 DEBUG(0,("is_printer_published: GUID value stored as "
03352 "invaluid type (%d)\n", regval_type(guid_val) ));
03353 break;
03354 }
03355 }
03356
03357 free_a_printer(&printer, 2);
03358 return ret;
03359 }
03360 #else
03361 WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
03362 {
03363 return WERR_OK;
03364 }
03365
03366 WERROR check_published_printers(void)
03367 {
03368 return WERR_OK;
03369 }
03370
03371 BOOL is_printer_published(Printer_entry *print_hnd, int snum,
03372 struct GUID *guid)
03373 {
03374 return False;
03375 }
03376 #endif
03377
03378
03379
03380
03381 WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key )
03382 {
03383 NT_PRINTER_DATA *data;
03384 int i;
03385 int removed_keys = 0;
03386 int empty_slot;
03387
03388 data = p2->data;
03389 empty_slot = data->num_keys;
03390
03391 if ( !key )
03392 return WERR_INVALID_PARAM;
03393
03394
03395
03396 if ( !strlen(key) ) {
03397
03398 TALLOC_FREE( data );
03399
03400 p2->data = NULL;
03401
03402 DEBUG(8,("delete_all_printer_data: Removed all Printer Data from printer [%s]\n",
03403 p2->printername ));
03404
03405 return WERR_OK;
03406 }
03407
03408
03409
03410 for ( i=0; i<data->num_keys; i++ ) {
03411 if ( StrnCaseCmp( data->keys[i].name, key, strlen(key)) == 0 ) {
03412 DEBUG(8,("delete_all_printer_data: Removed all Printer Data from key [%s]\n",
03413 data->keys[i].name));
03414
03415 TALLOC_FREE( data->keys[i].name );
03416 TALLOC_FREE( data->keys[i].values );
03417
03418
03419
03420 ZERO_STRUCTP( &data->keys[i] );
03421 }
03422 }
03423
03424
03425
03426 for ( i=0; i<data->num_keys; i++ ) {
03427 if ( !data->keys[i].name ) {
03428 empty_slot = i;
03429 removed_keys++;
03430 break;
03431 }
03432 }
03433
03434 if ( i == data->num_keys )
03435
03436 return WERR_INVALID_PARAM;
03437
03438
03439
03440 for ( i=empty_slot+1; i<data->num_keys; i++ ) {
03441 if ( data->keys[i].name ) {
03442 memcpy( &data->keys[empty_slot], &data->keys[i], sizeof(NT_PRINTER_KEY) );
03443 ZERO_STRUCTP( &data->keys[i] );
03444 empty_slot++;
03445 removed_keys++;
03446 }
03447 }
03448
03449
03450
03451 data->num_keys -= removed_keys;
03452
03453
03454
03455 if ( !data->num_keys ) {
03456 DEBUG(8,("delete_all_printer_data: No keys left for printer [%s]\n", p2->printername ));
03457
03458 SAFE_FREE( data->keys );
03459 ZERO_STRUCTP( data );
03460 }
03461
03462 return WERR_OK;
03463 }
03464
03465
03466
03467
03468 WERROR delete_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
03469 {
03470 WERROR result = WERR_OK;
03471 int key_index;
03472
03473
03474
03475 if ( !key || !*key|| !value || !*value )
03476 return WERR_INVALID_NAME;
03477
03478
03479
03480 key_index = lookup_printerkey( p2->data, key );
03481 if ( key_index == -1 )
03482 return WERR_OK;
03483
03484
03485
03486 if ( !regval_ctr_getvalue( p2->data->keys[key_index].values, value ) )
03487 return WERR_BADFILE;
03488
03489 regval_ctr_delvalue( p2->data->keys[key_index].values, value );
03490
03491 DEBUG(8,("delete_printer_data: Removed key => [%s], value => [%s]\n",
03492 key, value ));
03493
03494 return result;
03495 }
03496
03497
03498
03499
03500 WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value,
03501 uint32 type, uint8 *data, int real_len )
03502 {
03503 WERROR result = WERR_OK;
03504 int key_index;
03505
03506
03507
03508 if ( !key || !*key|| !value || !*value )
03509 return WERR_INVALID_NAME;
03510
03511
03512
03513 key_index = lookup_printerkey( p2->data, key );
03514 if ( key_index == -1 )
03515 key_index = add_new_printer_key( p2->data, key );
03516
03517 if ( key_index == -1 )
03518 return WERR_NOMEM;
03519
03520 regval_ctr_addvalue( p2->data->keys[key_index].values, value,
03521 type, (const char *)data, real_len );
03522
03523 DEBUG(8,("add_printer_data: Added key => [%s], value => [%s], type=> [%d], size => [%d]\n",
03524 key, value, type, real_len ));
03525
03526 return result;
03527 }
03528
03529
03530
03531
03532 REGISTRY_VALUE* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
03533 {
03534 int key_index;
03535
03536 if ( (key_index = lookup_printerkey( p2->data, key )) == -1 )
03537 return NULL;
03538
03539 DEBUG(8,("get_printer_data: Attempting to lookup key => [%s], value => [%s]\n",
03540 key, value ));
03541
03542 return regval_ctr_getvalue( p2->data->keys[key_index].values, value );
03543 }
03544
03545
03546
03547
03548
03549 static int unpack_values(NT_PRINTER_DATA *printer_data, char *buf, int buflen)
03550 {
03551 int len = 0;
03552 uint32 type;
03553 pstring string, valuename, keyname;
03554 char *str;
03555 int size;
03556 uint8 *data_p;
03557 REGISTRY_VALUE *regval_p;
03558 int key_index;
03559
03560
03561
03562 add_new_printer_key( printer_data, SPOOL_PRINTERDATA_KEY );
03563
03564
03565
03566 while ( True ) {
03567
03568
03569
03570 regval_p = NULL;
03571 len += tdb_unpack(buf+len, buflen-len, "p", ®val_p);
03572 if ( !regval_p )
03573 break;
03574
03575
03576
03577 len += tdb_unpack(buf+len, buflen-len, "fdB",
03578 string,
03579 &type,
03580 &size,
03581 &data_p);
03582
03583
03584
03585
03586 if ( type == REG_NONE ) {
03587 if ( (key_index=lookup_printerkey( printer_data, string)) == -1 )
03588 add_new_printer_key( printer_data, string );
03589 continue;
03590 }
03591
03592
03593
03594
03595
03596
03597
03598
03599
03600 str = strchr_m( string, '\\');
03601
03602
03603
03604 if ( !str ) {
03605 pstrcpy( keyname, SPOOL_PRINTERDATA_KEY );
03606 pstrcpy( valuename, string );
03607 }
03608 else {
03609 *str = '\0';
03610 pstrcpy( keyname, string );
03611 pstrcpy( valuename, str+1 );
03612 }
03613
03614
03615
03616 if ( (key_index=lookup_printerkey( printer_data, keyname )) == -1 )
03617 key_index = add_new_printer_key( printer_data, keyname );
03618
03619 if ( key_index == -1 ) {
03620 DEBUG(0,("unpack_values: Failed to allocate a new key [%s]!\n",
03621 keyname));
03622 break;
03623 }
03624
03625 DEBUG(8,("specific: [%s:%s], len: %d\n", keyname, valuename, size));
03626
03627
03628
03629
03630 if ( type == REG_BINARY &&
03631 strequal( keyname, SPOOL_DSSPOOLER_KEY ) &&
03632 strequal( valuename, "objectGUID" ) )
03633 {
03634 struct GUID guid;
03635 UNISTR2 unistr_guid;
03636
03637 ZERO_STRUCT( unistr_guid );
03638
03639
03640
03641 memcpy( &guid, data_p, sizeof(struct GUID) );
03642
03643 init_unistr2( &unistr_guid, smb_uuid_string_static(guid),
03644 UNI_STR_TERMINATE );
03645
03646 regval_ctr_addvalue( printer_data->keys[key_index].values,
03647 valuename, REG_SZ,
03648 (const char *)unistr_guid.buffer,
03649 unistr_guid.uni_str_len*2 );
03650
03651 } else {
03652
03653
03654 regval_ctr_addvalue( printer_data->keys[key_index].values,
03655 valuename, type, (const char *)data_p,
03656 size );
03657 }
03658
03659
03660 SAFE_FREE(data_p);
03661
03662 }
03663
03664 return len;
03665 }
03666
03667
03668
03669
03670 static void map_to_os2_driver(fstring drivername)
03671 {
03672 static BOOL initialised=False;
03673 static fstring last_from,last_to;
03674 char *mapfile = lp_os2_driver_map();
03675 char **lines = NULL;
03676 int numlines = 0;
03677 int i;
03678
03679 if (!strlen(drivername))
03680 return;
03681
03682 if (!*mapfile)
03683 return;
03684
03685 if (!initialised) {
03686 *last_from = *last_to = 0;
03687 initialised = True;
03688 }
03689
03690 if (strequal(drivername,last_from)) {
03691 DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,last_to));
03692 fstrcpy(drivername,last_to);
03693 return;
03694 }
03695
03696 lines = file_lines_load(mapfile, &numlines,0);
03697 if (numlines == 0 || lines == NULL) {
03698 DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile));
03699 SAFE_FREE(lines);
03700 return;
03701 }
03702
03703 DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
03704
03705 for( i = 0; i < numlines; i++) {
03706 char *nt_name = lines[i];
03707 char *os2_name = strchr(nt_name,'=');
03708
03709 if (!os2_name)
03710 continue;
03711
03712 *os2_name++ = 0;
03713
03714 while (isspace(*nt_name))
03715 nt_name++;
03716
03717 if (!*nt_name || strchr("#;",*nt_name))
03718 continue;
03719
03720 {
03721 int l = strlen(nt_name);
03722 while (l && isspace(nt_name[l-1])) {
03723 nt_name[l-1] = 0;
03724 l--;
03725 }
03726 }
03727
03728 while (isspace(*os2_name))
03729 os2_name++;
03730
03731 {
03732 int l = strlen(os2_name);
03733 while (l && isspace(os2_name[l-1])) {
03734 os2_name[l-1] = 0;
03735 l--;
03736 }
03737 }
03738
03739 if (strequal(nt_name,drivername)) {
03740 DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name));
03741 fstrcpy(last_from,drivername);
03742 fstrcpy(last_to,os2_name);
03743 fstrcpy(drivername,os2_name);
03744 file_lines_free(lines);
03745 return;
03746 }
03747 }
03748
03749 file_lines_free(lines);
03750 }
03751
03752
03753
03754
03755
03756 static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 *info,
03757 const char *servername,
03758 const char* sharename,
03759 BOOL get_loc_com)
03760 {
03761 int snum = lp_servicenumber(sharename);
03762
03763 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", servername);
03764 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
03765 servername, sharename);
03766 fstrcpy(info->sharename, sharename);
03767 fstrcpy(info->portname, SAMBA_PRINTER_PORT_NAME);
03768
03769
03770
03771
03772
03773 #if 0
03774 if (!*info->drivername)
03775 fstrcpy(info->drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER");
03776 #endif
03777
03778
03779 DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info->drivername));
03780
03781 pstrcpy(info->comment, "");
03782 fstrcpy(info->printprocessor, "winprint");
03783 fstrcpy(info->datatype, "RAW");
03784
03785 #ifdef HAVE_CUPS
03786 if (get_loc_com && (enum printing_types)lp_printing(snum) == PRINT_CUPS ) {
03787
03788
03789 if ( !strlen(info->location) || !strlen(info->comment) )
03790 cups_pull_comment_location( info );
03791 }
03792 #endif
03793
03794 info->attributes = PRINTER_ATTRIBUTE_SAMBA;
03795
03796 info->starttime = 0;
03797 info->untiltime = 0;
03798 info->priority = 1;
03799 info->default_priority = 1;
03800 info->setuptime = (uint32)time(NULL);
03801
03802
03803
03804
03805
03806
03807
03808
03809
03810
03811
03812 if (lp_default_devmode(snum)) {
03813 if ((info->devmode = construct_nt_devicemode(info->printername)) == NULL) {
03814 goto fail;
03815 }
03816 } else {
03817 info->devmode = NULL;
03818 }
03819
03820 if (!nt_printing_getsec(info, sharename, &info->secdesc_buf)) {
03821 goto fail;
03822 }
03823
03824 return WERR_OK;
03825
03826 fail:
03827 if (info->devmode)
03828 free_nt_devicemode(&info->devmode);
03829
03830 return WERR_ACCESS_DENIED;
03831 }
03832
03833
03834
03835
03836 static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info,
03837 const char *servername,
03838 const char *sharename,
03839 BOOL get_loc_com)
03840 {
03841 int len = 0;
03842 int snum = lp_servicenumber(sharename);
03843 TDB_DATA kbuf, dbuf;
03844 fstring printername;
03845 char adevice[MAXDEVICENAME];
03846
03847 kbuf = make_printer_tdbkey( sharename );
03848
03849 dbuf = tdb_fetch(tdb_printers, kbuf);
03850 if (!dbuf.dptr) {
03851 return get_a_printer_2_default(info, servername,
03852 sharename, get_loc_com);
03853 }
03854
03855 len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
03856 &info->attributes,
03857 &info->priority,
03858 &info->default_priority,
03859 &info->starttime,
03860 &info->untiltime,
03861 &info->status,
03862 &info->cjobs,
03863 &info->averageppm,
03864 &info->changeid,
03865 &info->c_setprinter,
03866 &info->setuptime,
03867 info->servername,
03868 info->printername,
03869 info->sharename,
03870 info->portname,
03871 info->drivername,
03872 info->comment,
03873 info->location,
03874 info->sepfile,
03875 info->printprocessor,
03876 info->datatype,
03877 info->parameters);
03878
03879
03880 info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
03881 info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
03882
03883
03884 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", servername);
03885
03886 if ( lp_force_printername(snum) ) {
03887 slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, sharename );
03888 } else {
03889 slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, info->printername);
03890 }
03891
03892 fstrcpy(info->printername, printername);
03893
03894 #ifdef HAVE_CUPS
03895 if (get_loc_com && (enum printing_types)lp_printing(snum) == PRINT_CUPS ) {
03896
03897
03898 if ( !strlen(info->location) || !strlen(info->comment) )
03899 cups_pull_comment_location( info );
03900 }
03901 #endif
03902
03903 len += unpack_devicemode(&info->devmode,dbuf.dptr+len, dbuf.dsize-len);
03904
03905
03906
03907
03908
03909
03910
03911
03912
03913 if (lp_default_devmode(snum) && !info->devmode) {
03914 DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
03915 printername));
03916 info->devmode = construct_nt_devicemode(printername);
03917 }
03918
03919 slprintf( adevice, sizeof(adevice), "%s", info->printername );
03920 if (info->devmode) {
03921 fstrcpy(info->devmode->devicename, adevice);
03922 }
03923
03924 if ( !(info->data = TALLOC_ZERO_P( info, NT_PRINTER_DATA )) ) {
03925 DEBUG(0,("unpack_values: talloc() failed!\n"));
03926 SAFE_FREE(dbuf.dptr);
03927 return WERR_NOMEM;
03928 }
03929 len += unpack_values( info->data, dbuf.dptr+len, dbuf.dsize-len );
03930
03931
03932
03933
03934 if (!nt_printing_getsec(info, sharename, &info->secdesc_buf)) {
03935 SAFE_FREE(dbuf.dptr);
03936 return WERR_NOMEM;
03937 }
03938
03939
03940
03941 if (get_remote_arch() == RA_OS2) {
03942 map_to_os2_driver(info->drivername);
03943 }
03944
03945 SAFE_FREE(dbuf.dptr);
03946
03947 DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
03948 sharename, info->printername, info->drivername));
03949
03950 return WERR_OK;
03951 }
03952
03953
03954
03955
03956 static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
03957 {
03958 uint32 result;
03959 NT_PRINTER_INFO_LEVEL_2 *info2;
03960
03961 DEBUG(106,("Dumping printer at level [%d]\n", level));
03962
03963 switch (level) {
03964 case 2:
03965 {
03966 if (printer->info_2 == NULL)
03967 result=5;
03968 else
03969 {
03970 info2=printer->info_2;
03971
03972 DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
03973 DEBUGADD(106,("priority:[%d]\n", info2->priority));
03974 DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
03975 DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
03976 DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
03977 DEBUGADD(106,("status:[%d]\n", info2->status));
03978 DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
03979 DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
03980 DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
03981 DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
03982 DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
03983
03984 DEBUGADD(106,("servername:[%s]\n", info2->servername));
03985 DEBUGADD(106,("printername:[%s]\n", info2->printername));
03986 DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
03987 DEBUGADD(106,("portname:[%s]\n", info2->portname));
03988 DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
03989 DEBUGADD(106,("comment:[%s]\n", info2->comment));
03990 DEBUGADD(106,("location:[%s]\n", info2->location));
03991 DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
03992 DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
03993 DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
03994 DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
03995 result=0;
03996 }
03997 break;
03998 }
03999 default:
04000 DEBUGADD(106,("dump_a_printer: Level %u not implemented\n", (unsigned int)level ));
04001 result=1;
04002 break;
04003 }
04004
04005 return result;
04006 }
04007
04008
04009
04010
04011
04012
04013
04014
04015
04016 static uint32 rev_changeid(void)
04017 {
04018 struct timeval tv;
04019
04020 get_process_uptime(&tv);
04021
04022 #if 1
04023
04024 return tv.tv_sec * 1000 + tv.tv_usec / 1000;
04025 #else
04026
04027
04028
04029
04030
04031 return tv.tv_sec * 10 + tv.tv_usec / 100000;
04032 #endif
04033 }
04034
04035
04036
04037
04038
04039
04040
04041
04042
04043
04044
04045
04046 WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
04047 {
04048 WERROR result;
04049
04050 dump_a_printer(printer, level);
04051
04052 switch (level) {
04053 case 2:
04054 {
04055
04056
04057
04058
04059
04060
04061
04062
04063
04064
04065 printer->info_2->changeid = rev_changeid();
04066
04067
04068
04069
04070
04071
04072
04073
04074
04075
04076
04077
04078
04079
04080
04081
04082
04083
04084
04085
04086 result=update_a_printer_2(printer->info_2);
04087
04088 break;
04089 }
04090 default:
04091 result=WERR_UNKNOWN_LEVEL;
04092 break;
04093 }
04094
04095 return result;
04096 }
04097
04098
04099
04100
04101
04102 static BOOL set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr )
04103 {
04104 int len = 0;
04105 pstring key;
04106 TDB_DATA kbuf, dbuf;
04107 NT_PRINTER_INFO_LEVEL_2 info;
04108
04109
04110 ZERO_STRUCT(info);
04111
04112
04113
04114
04115
04116
04117
04118 if ( info_ptr->data )
04119 delete_all_printer_data( info_ptr, "" );
04120
04121 slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info_ptr->drivername);
04122
04123 kbuf.dptr = key;
04124 kbuf.dsize = strlen(key)+1;
04125
04126 dbuf = tdb_fetch(tdb_drivers, kbuf);
04127 if (!dbuf.dptr) {
04128
04129
04130
04131
04132 free_nt_devicemode(&info_ptr->devmode);
04133 return False;
04134 }
04135
04136
04137
04138
04139
04140 len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
04141
04142
04143
04144
04145
04146
04147 if ( info.devmode ) {
04148 ZERO_STRUCT(info.devmode->devicename);
04149 fstrcpy(info.devmode->devicename, info_ptr->printername);
04150 }
04151
04152
04153
04154
04155
04156
04157
04158
04159
04160
04161
04162
04163
04164
04165
04166 free_nt_devicemode(&info_ptr->devmode);
04167 info_ptr->devmode = info.devmode;
04168
04169 DEBUG(10,("set_driver_init_2: Set printer [%s] init %s DEVMODE for driver [%s]\n",
04170 info_ptr->printername, info_ptr->devmode?"VALID":"NULL", info_ptr->drivername));
04171
04172
04173
04174 if ( !(info_ptr->data = TALLOC_ZERO_P( info_ptr, NT_PRINTER_DATA )) ) {
04175 DEBUG(0,("set_driver_init_2: talloc() failed!\n"));
04176 return False;
04177 }
04178
04179 len += unpack_values( info_ptr->data, dbuf.dptr+len, dbuf.dsize-len );
04180
04181
04182 SAFE_FREE(dbuf.dptr);
04183
04184 return True;
04185 }
04186
04187
04188
04189
04190
04191
04192
04193
04194 BOOL set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
04195 {
04196 BOOL result = False;
04197
04198 switch (level) {
04199 case 2:
04200 result = set_driver_init_2(printer->info_2);
04201 break;
04202
04203 default:
04204 DEBUG(0,("set_driver_init: Programmer's error! Unknown driver_init level [%d]\n",
04205 level));
04206 break;
04207 }
04208
04209 return result;
04210 }
04211
04212
04213
04214
04215
04216 BOOL del_driver_init(char *drivername)
04217 {
04218 pstring key;
04219 TDB_DATA kbuf;
04220
04221 if (!drivername || !*drivername) {
04222 DEBUG(3,("del_driver_init: No drivername specified!\n"));
04223 return False;
04224 }
04225
04226 slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, drivername);
04227
04228 kbuf.dptr = key;
04229 kbuf.dsize = strlen(key)+1;
04230
04231 DEBUG(6,("del_driver_init: Removing driver init data for [%s]\n", drivername));
04232
04233 return (tdb_delete(tdb_drivers, kbuf) == 0);
04234 }
04235
04236
04237
04238
04239
04240
04241
04242
04243
04244 static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
04245 {
04246 pstring key;
04247 char *buf;
04248 int buflen, len, ret;
04249 TDB_DATA kbuf, dbuf;
04250
04251 buf = NULL;
04252 buflen = 0;
04253
04254 again:
04255 len = 0;
04256 len += pack_devicemode(info->devmode, buf+len, buflen-len);
04257
04258 len += pack_values( info->data, buf+len, buflen-len );
04259
04260 if (buflen < len) {
04261 buf = (char *)SMB_REALLOC(buf, len);
04262 if (!buf) {
04263 DEBUG(0, ("update_driver_init_2: failed to enlarge buffer!\n"));
04264 ret = -1;
04265 goto done;
04266 }
04267 buflen = len;
04268 goto again;
04269 }
04270
04271 slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info->drivername);
04272
04273 kbuf.dptr = key;
04274 kbuf.dsize = strlen(key)+1;
04275 dbuf.dptr = buf;
04276 dbuf.dsize = len;
04277
04278 ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
04279
04280 done:
04281 if (ret == -1)
04282 DEBUG(8, ("update_driver_init_2: error updating printer init to tdb on disk\n"));
04283
04284 SAFE_FREE(buf);
04285
04286 DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & values for driver [%s]\n",
04287 info->sharename, info->drivername));
04288
04289 return ret;
04290 }
04291
04292
04293
04294
04295
04296 static uint32 update_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
04297 {
04298 uint32 result;
04299
04300 dump_a_printer(printer, level);
04301
04302 switch (level) {
04303 case 2:
04304 result = update_driver_init_2(printer->info_2);
04305 break;
04306 default:
04307 result = 1;
04308 break;
04309 }
04310
04311 return result;
04312 }
04313
04314
04315
04316
04317
04318
04319
04320 static BOOL convert_driver_init( TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode, uint8 *data, uint32 data_len )
04321 {
04322 BOOL result = False;
04323 prs_struct ps;
04324 DEVICEMODE devmode;
04325
04326 ZERO_STRUCT(devmode);
04327
04328 prs_init(&ps, 0, ctx, UNMARSHALL);
04329 ps.data_p = (char *)data;
04330 ps.buffer_size = data_len;
04331
04332 if (spoolss_io_devmode("phantom DEVMODE", &ps, 0, &devmode))
04333 result = convert_devicemode("", &devmode, &nt_devmode);
04334 else
04335 DEBUG(10,("convert_driver_init: error parsing DEVMODE\n"));
04336
04337 return result;
04338 }
04339
04340
04341
04342
04343
04344
04345
04346
04347
04348
04349
04350
04351
04352
04353
04354
04355
04356
04357
04358
04359
04360
04361
04362 static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, uint8 *data, uint32 data_len )
04363 {
04364 WERROR status = WERR_OK;
04365 TALLOC_CTX *ctx = NULL;
04366 NT_DEVICEMODE *nt_devmode = NULL;
04367 NT_DEVICEMODE *tmp_devmode = printer->info_2->devmode;
04368
04369
04370
04371
04372 DEBUG(8,("save_driver_init_2: Enter...\n"));
04373
04374 if ( !printer->info_2->devmode && data_len ) {
04375
04376
04377
04378
04379
04380 if ((ctx = talloc_init("save_driver_init_2")) == NULL)
04381 return WERR_NOMEM;
04382
04383 if ((nt_devmode = SMB_MALLOC_P(NT_DEVICEMODE)) == NULL) {
04384 status = WERR_NOMEM;
04385 goto done;
04386 }
04387
04388 ZERO_STRUCTP(nt_devmode);
04389
04390
04391
04392
04393
04394 if ( !convert_driver_init( ctx, nt_devmode, data, data_len )) {
04395 DEBUG(10,("save_driver_init_2: error converting DEVMODE\n"));
04396 status = WERR_INVALID_PARAM;
04397 goto done;
04398 }
04399
04400 printer->info_2->devmode = nt_devmode;
04401 }
04402
04403
04404
04405
04406
04407
04408
04409 if ( update_driver_init(printer, 2) != 0 ) {
04410 DEBUG(10,("save_driver_init_2: error updating DEVMODE\n"));
04411 status = WERR_NOMEM;
04412 goto done;
04413 }
04414
04415
04416
04417
04418
04419
04420 status = mod_a_printer(printer, 2);
04421 if (!W_ERROR_IS_OK(status)) {
04422 DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n",
04423 printer->info_2->printername));
04424 }
04425
04426 done:
04427 talloc_destroy(ctx);
04428 free_nt_devicemode( &nt_devmode );
04429
04430 printer->info_2->devmode = tmp_devmode;
04431
04432 return status;
04433 }
04434
04435
04436
04437
04438
04439 WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, uint8 *data, uint32 data_len)
04440 {
04441 WERROR status = WERR_OK;
04442
04443 switch (level) {
04444 case 2:
04445 status = save_driver_init_2( printer, data, data_len );
04446 break;
04447 default:
04448 status = WERR_UNKNOWN_LEVEL;
04449 break;
04450 }
04451
04452 return status;
04453 }
04454
04455
04456
04457
04458
04459
04460
04461
04462
04463
04464
04465
04466
04467
04468
04469 static WERROR get_a_printer_internal( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level,
04470 const char *sharename, BOOL get_loc_com)
04471 {
04472 WERROR result;
04473 fstring servername;
04474
04475 DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
04476
04477 if ( !(*pp_printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
04478 DEBUG(0,("get_a_printer: talloc() fail.\n"));
04479 return WERR_NOMEM;
04480 }
04481
04482 switch (level) {
04483 case 2:
04484 if ( !((*pp_printer)->info_2 = TALLOC_ZERO_P(*pp_printer, NT_PRINTER_INFO_LEVEL_2)) ) {
04485 DEBUG(0,("get_a_printer: talloc() fail.\n"));
04486 TALLOC_FREE( *pp_printer );
04487 return WERR_NOMEM;
04488 }
04489
04490 if ( print_hnd )
04491 fstrcpy( servername, print_hnd->servername );
04492 else {
04493 fstrcpy( servername, "%L" );
04494 standard_sub_basic( "", "", servername,
04495 sizeof(servername)-1 );
04496 }
04497
04498 result = get_a_printer_2( (*pp_printer)->info_2,
04499 servername,
04500 sharename,
04501 get_loc_com);
04502
04503
04504
04505
04506 if ( !W_ERROR_IS_OK(result) ) {
04507 TALLOC_FREE( *pp_printer );
04508 DEBUG(10,("get_a_printer: [%s] level %u returning %s\n",
04509 sharename, (unsigned int)level, dos_errstr(result)));
04510 return result;
04511 }
04512
04513 dump_a_printer( *pp_printer, level);
04514
04515 break;
04516
04517 default:
04518 TALLOC_FREE( *pp_printer );
04519 return WERR_UNKNOWN_LEVEL;
04520 }
04521
04522 return WERR_OK;
04523 }
04524
04525 WERROR get_a_printer( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level,
04526 const char *sharename)
04527 {
04528 return get_a_printer_internal(print_hnd, pp_printer, level,
04529 sharename, True);
04530 }
04531
04532 WERROR get_a_printer_search( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level,
04533 const char *sharename)
04534 {
04535 return get_a_printer_internal(print_hnd, pp_printer, level,
04536 sharename, False);
04537 }
04538
04539
04540
04541
04542
04543 uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
04544 {
04545 NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
04546
04547 if ( !printer )
04548 return 0;
04549
04550 switch (level) {
04551 case 2:
04552 if ( printer->info_2 )
04553 free_nt_printer_info_level_2(&printer->info_2);
04554 break;
04555
04556 default:
04557 DEBUG(0,("free_a_printer: unknown level! [%d]\n", level ));
04558 return 1;
04559 }
04560
04561 TALLOC_FREE(*pp_printer);
04562
04563 return 0;
04564 }
04565
04566
04567
04568 uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
04569 {
04570 uint32 result;
04571 DEBUG(104,("adding a printer at level [%d]\n", level));
04572 dump_a_printer_driver(driver, level);
04573
04574 switch (level) {
04575 case 3:
04576 result=add_a_printer_driver_3(driver.info_3);
04577 break;
04578
04579 case 6:
04580 result=add_a_printer_driver_6(driver.info_6);
04581 break;
04582
04583 default:
04584 result=1;
04585 break;
04586 }
04587
04588 return result;
04589 }
04590
04591
04592
04593 WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
04594 fstring drivername, const char *architecture, uint32 version)
04595 {
04596 WERROR result;
04597
04598 switch (level) {
04599 case 3:
04600
04601
04602 if ( version == DRIVER_ANY_VERSION ) {
04603
04604 result = get_a_printer_driver_3(&driver->info_3, drivername,
04605 architecture, 3);
04606
04607 if ( !W_ERROR_IS_OK(result) ) {
04608 result = get_a_printer_driver_3( &driver->info_3,
04609 drivername, architecture, 2 );
04610 }
04611 } else {
04612 result = get_a_printer_driver_3(&driver->info_3, drivername,
04613 architecture, version);
04614 }
04615 break;
04616
04617 default:
04618 result=W_ERROR(1);
04619 break;
04620 }
04621
04622 if (W_ERROR_IS_OK(result))
04623 dump_a_printer_driver(*driver, level);
04624
04625 return result;
04626 }
04627
04628
04629
04630 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
04631 {
04632 uint32 result;
04633
04634 switch (level) {
04635 case 3:
04636 {
04637 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
04638 if (driver.info_3 != NULL)
04639 {
04640 info3=driver.info_3;
04641 SAFE_FREE(info3->dependentfiles);
04642 ZERO_STRUCTP(info3);
04643 SAFE_FREE(info3);
04644 result=0;
04645 } else {
04646 result=4;
04647 }
04648 break;
04649 }
04650 case 6:
04651 {
04652 NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
04653 if (driver.info_6 != NULL) {
04654 info6=driver.info_6;
04655 SAFE_FREE(info6->dependentfiles);
04656 SAFE_FREE(info6->previousnames);
04657 ZERO_STRUCTP(info6);
04658 SAFE_FREE(info6);
04659 result=0;
04660 } else {
04661 result=4;
04662 }
04663 break;
04664 }
04665 default:
04666 result=1;
04667 break;
04668 }
04669 return result;
04670 }
04671
04672
04673
04674
04675
04676
04677
04678 BOOL printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3 )
04679 {
04680 int snum;
04681 int n_services = lp_numservices();
04682 NT_PRINTER_INFO_LEVEL *printer = NULL;
04683 BOOL in_use = False;
04684
04685 if ( !info_3 )
04686 return False;
04687
04688 DEBUG(10,("printer_driver_in_use: Beginning search through ntprinters.tdb...\n"));
04689
04690
04691
04692 for (snum=0; snum<n_services && !in_use; snum++) {
04693 if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
04694 continue;
04695
04696 if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_servicename(snum))) )
04697 continue;
04698
04699 if ( strequal(info_3->name, printer->info_2->drivername) )
04700 in_use = True;
04701
04702 free_a_printer( &printer, 2 );
04703 }
04704
04705 DEBUG(10,("printer_driver_in_use: Completed search through ntprinters.tdb...\n"));
04706
04707 if ( in_use ) {
04708 NT_PRINTER_DRIVER_INFO_LEVEL d;
04709 WERROR werr;
04710
04711 DEBUG(5,("printer_driver_in_use: driver \"%s\" is currently in use\n", info_3->name));
04712
04713
04714
04715
04716 if ( !strequal( "Windows NT x86", info_3->environment ) ) {
04717 werr = get_a_printer_driver( &d, 3, info_3->name, "Windows NT x86", DRIVER_ANY_VERSION );
04718 }
04719 else {
04720 switch ( info_3->cversion ) {
04721 case 2:
04722 werr = get_a_printer_driver( &d, 3, info_3->name, "Windows NT x86", 3 );
04723 break;
04724 case 3:
04725 werr = get_a_printer_driver( &d, 3, info_3->name, "Windows NT x86", 2 );
04726 break;
04727 default:
04728 DEBUG(0,("printer_driver_in_use: ERROR! unknown driver version (%d)\n",
04729 info_3->cversion));
04730 werr = WERR_UNKNOWN_PRINTER_DRIVER;
04731 break;
04732 }
04733 }
04734
04735
04736
04737 if ( W_ERROR_IS_OK(werr) ) {
04738
04739 in_use = False;
04740 free_a_printer_driver( d, 3 );
04741 }
04742 }
04743
04744
04745
04746 return in_use;
04747 }
04748
04749
04750
04751
04752
04753
04754 static BOOL drv_file_in_use( char* file, NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
04755 {
04756 int i = 0;
04757
04758 if ( !info )
04759 return False;
04760
04761
04762 if (!file || !file[0]) {
04763 return false;
04764 }
04765
04766 if ( strequal(file, info->driverpath) )
04767 return True;
04768
04769 if ( strequal(file, info->datafile) )
04770 return True;
04771
04772 if ( strequal(file, info->configfile) )
04773 return True;
04774
04775 if ( strequal(file, info->helpfile) )
04776 return True;
04777
04778
04779
04780 if ( !info->dependentfiles )
04781 return False;
04782
04783 while ( *info->dependentfiles[i] ) {
04784 if ( strequal(file, info->dependentfiles[i]) )
04785 return True;
04786 i++;
04787 }
04788
04789 return False;
04790
04791 }
04792
04793
04794
04795
04796
04797
04798 static void trim_dependent_file( fstring files[], int idx )
04799 {
04800
04801
04802
04803 while( *files[idx+1] ) {
04804 fstrcpy( files[idx], files[idx+1] );
04805 idx++;
04806 }
04807
04808 *files[idx] = '\0';
04809
04810 return;
04811 }
04812
04813
04814
04815
04816
04817 static BOOL trim_overlap_drv_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *src,
04818 NT_PRINTER_DRIVER_INFO_LEVEL_3 *drv )
04819 {
04820 BOOL in_use = False;
04821 int i = 0;
04822
04823 if ( !src || !drv )
04824 return False;
04825
04826
04827
04828 if ( drv_file_in_use(src->driverpath, drv) ) {
04829 in_use = True;
04830 DEBUG(10,("Removing driverfile [%s] from list\n", src->driverpath));
04831 fstrcpy( src->driverpath, "" );
04832 }
04833
04834 if ( drv_file_in_use(src->datafile, drv) ) {
04835 in_use = True;
04836 DEBUG(10,("Removing datafile [%s] from list\n", src->datafile));
04837 fstrcpy( src->datafile, "" );
04838 }
04839
04840 if ( drv_file_in_use(src->configfile, drv) ) {
04841 in_use = True;
04842 DEBUG(10,("Removing configfile [%s] from list\n", src->configfile));
04843 fstrcpy( src->configfile, "" );
04844 }
04845
04846 if ( drv_file_in_use(src->helpfile, drv) ) {
04847 in_use = True;
04848 DEBUG(10,("Removing helpfile [%s] from list\n", src->helpfile));
04849 fstrcpy( src->helpfile, "" );
04850 }
04851
04852
04853
04854 if ( !src->dependentfiles )
04855 return in_use;
04856
04857 while ( *src->dependentfiles[i] ) {
04858 if ( drv_file_in_use(src->dependentfiles[i], drv) ) {
04859 in_use = True;
04860 DEBUG(10,("Removing [%s] from dependent file list\n", src->dependentfiles[i]));
04861 trim_dependent_file( src->dependentfiles, i );
04862 } else
04863 i++;
04864 }
04865
04866 return in_use;
04867 }
04868
04869
04870
04871
04872
04873
04874
04875
04876
04877
04878
04879
04880
04881
04882
04883
04884
04885
04886 BOOL printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
04887 {
04888 int i;
04889 int ndrivers;
04890 uint32 version;
04891 fstring *list = NULL;
04892 NT_PRINTER_DRIVER_INFO_LEVEL driver;
04893 BOOL in_use = False;
04894
04895 if ( !info )
04896 return False;
04897
04898 version = info->cversion;
04899
04900
04901
04902 DEBUG(5,("printer_driver_files_in_use: Beginning search through ntdrivers.tdb...\n"));
04903
04904
04905
04906 list = NULL;
04907 ndrivers = get_ntdrivers(&list, info->environment, version);
04908
04909 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n",
04910 ndrivers, info->environment, version));
04911
04912
04913
04914 for (i=0; i<ndrivers; i++) {
04915 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
04916
04917 ZERO_STRUCT(driver);
04918
04919 if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, list[i], info->environment, version)) ) {
04920 SAFE_FREE(list);
04921 return True;
04922 }
04923
04924
04925
04926
04927 if ( !strequal(info->name, driver.info_3->name) ) {
04928 if ( trim_overlap_drv_files(info, driver.info_3) ) {
04929
04930
04931
04932 in_use = True;
04933 }
04934 }
04935
04936 free_a_printer_driver(driver, 3);
04937 }
04938
04939 SAFE_FREE(list);
04940
04941 DEBUG(5,("printer_driver_files_in_use: Completed search through ntdrivers.tdb...\n"));
04942
04943 driver.info_3 = info;
04944
04945 if ( DEBUGLEVEL >= 20 )
04946 dump_a_printer_driver( driver, 3 );
04947
04948 return in_use;
04949 }
04950
04951
04952
04953
04954
04955
04956
04957 static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct current_user *user )
04958 {
04959 int i = 0;
04960 char *s;
04961 pstring file;
04962 connection_struct *conn;
04963 DATA_BLOB null_pw;
04964 NTSTATUS nt_status;
04965 fstring res_type;
04966 SMB_STRUCT_STAT st;
04967
04968 if ( !info_3 )
04969 return False;
04970
04971 DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n", info_3->name, info_3->cversion));
04972
04973
04974
04975
04976
04977
04978
04979 null_pw = data_blob( NULL, 0 );
04980 fstrcpy(res_type, "A:");
04981 become_root();
04982 conn = make_connection_with_chdir( "print$", null_pw, res_type, user->vuid, &nt_status );
04983 unbecome_root();
04984
04985 if ( !conn ) {
04986 DEBUG(0,("delete_driver_files: Unable to connect\n"));
04987 return False;
04988 }
04989
04990 if ( !CAN_WRITE(conn) ) {
04991 DEBUG(3,("delete_driver_files: Cannot delete print driver when [print$] is read-only\n"));
04992 return False;
04993 }
04994
04995
04996
04997 if ( !become_user(conn, conn->vuid) ) {
04998 DEBUG(0,("delete_driver_files: Can't become user!\n"));
04999 return False;
05000 }
05001
05002
05003
05004
05005 if ( *info_3->driverpath ) {
05006 if ( (s = strchr( &info_3->driverpath[1], '\\' )) != NULL ) {
05007 pstrcpy( file, s );
05008 driver_unix_convert(file, conn, NULL, &st);
05009 DEBUG(10,("deleting driverfile [%s]\n", s));
05010 unlink_internals(conn, 0, file, False, False);
05011 }
05012 }
05013
05014 if ( *info_3->configfile ) {
05015 if ( (s = strchr( &info_3->configfile[1], '\\' )) != NULL ) {
05016 pstrcpy( file, s );
05017 driver_unix_convert(file, conn, NULL, &st);
05018 DEBUG(10,("deleting configfile [%s]\n", s));
05019 unlink_internals(conn, 0, file, False, False);
05020 }
05021 }
05022
05023 if ( *info_3->datafile ) {
05024 if ( (s = strchr( &info_3->datafile[1], '\\' )) != NULL ) {
05025 pstrcpy( file, s );
05026 driver_unix_convert(file, conn, NULL, &st);
05027 DEBUG(10,("deleting datafile [%s]\n", s));
05028 unlink_internals(conn, 0, file, False, False);
05029 }
05030 }
05031
05032 if ( *info_3->helpfile ) {
05033 if ( (s = strchr( &info_3->helpfile[1], '\\' )) != NULL ) {
05034 pstrcpy( file, s );
05035 driver_unix_convert(file, conn, NULL, &st);
05036 DEBUG(10,("deleting helpfile [%s]\n", s));
05037 unlink_internals(conn, 0, file, False, False);
05038 }
05039 }
05040
05041
05042
05043 if ( info_3->dependentfiles ) {
05044 while ( info_3->dependentfiles[i][0] ) {
05045 char *p;
05046
05047
05048
05049 if ( (p = strchr( info_3->dependentfiles[i]+1, '\\' )) != NULL ) {
05050 pstrcpy( file, p );
05051 driver_unix_convert(file, conn, NULL, &st);
05052 DEBUG(10,("deleting dependent file [%s]\n", file));
05053 unlink_internals(conn, 0, file, False, False);
05054 }
05055
05056 i++;
05057 }
05058 }
05059
05060 unbecome_user();
05061
05062 return True;
05063 }
05064
05065
05066
05067
05068
05069
05070 WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct current_user *user,
05071 uint32 version, BOOL delete_files )
05072 {
05073 pstring key;
05074 const char *arch;
05075 TDB_DATA kbuf, dbuf;
05076 NT_PRINTER_DRIVER_INFO_LEVEL ctr;
05077
05078
05079
05080 arch = get_short_archi(info_3->environment);
05081 if (!arch) {
05082 return WERR_UNKNOWN_PRINTER_DRIVER;
05083 }
05084 slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX,
05085 arch, version, info_3->name);
05086
05087 DEBUG(5,("delete_printer_driver: key = [%s] delete_files = %s\n",
05088 key, delete_files ? "TRUE" : "FALSE" ));
05089
05090 ctr.info_3 = info_3;
05091 dump_a_printer_driver( ctr, 3 );
05092
05093 kbuf.dptr=key;
05094 kbuf.dsize=strlen(key)+1;
05095
05096
05097
05098 dbuf = tdb_fetch( tdb_drivers, kbuf );
05099 if ( !dbuf.dptr ) {
05100 DEBUG(8,("delete_printer_driver: Driver unknown [%s]\n", key));
05101 return WERR_UNKNOWN_PRINTER_DRIVER;
05102 }
05103
05104 SAFE_FREE( dbuf.dptr );
05105
05106
05107
05108 if (tdb_delete(tdb_drivers, kbuf) == -1) {
05109 DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key));
05110 return WERR_ACCESS_DENIED;
05111 }
05112
05113
05114
05115
05116
05117
05118
05119 if ( delete_files )
05120 delete_driver_files( info_3, user );
05121
05122
05123 DEBUG(5,("delete_printer_driver: driver delete successful [%s]\n", key));
05124
05125 return WERR_OK;
05126 }
05127
05128
05129
05130
05131
05132 WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr)
05133 {
05134 SEC_DESC_BUF *new_secdesc_ctr = NULL;
05135 SEC_DESC_BUF *old_secdesc_ctr = NULL;
05136 prs_struct ps;
05137 TALLOC_CTX *mem_ctx = NULL;
05138 char *key;
05139 WERROR status;
05140
05141 mem_ctx = talloc_init("nt_printing_setsec");
05142 if (mem_ctx == NULL)
05143 return WERR_NOMEM;
05144
05145
05146
05147
05148
05149
05150 if (!secdesc_ctr->sec->owner_sid || !secdesc_ctr->sec->group_sid) {
05151 DOM_SID *owner_sid, *group_sid;
05152 SEC_ACL *dacl, *sacl;
05153 SEC_DESC *psd = NULL;
05154 size_t size;
05155
05156 if (!nt_printing_getsec(mem_ctx, sharename, &old_secdesc_ctr)) {
05157 status = WERR_NOMEM;
05158 goto out;
05159 }
05160
05161
05162
05163 owner_sid = secdesc_ctr->sec->owner_sid ?
05164 secdesc_ctr->sec->owner_sid :
05165 old_secdesc_ctr->sec->owner_sid;
05166
05167 group_sid = secdesc_ctr->sec->group_sid ?
05168 secdesc_ctr->sec->group_sid :
05169 old_secdesc_ctr->sec->group_sid;
05170
05171 dacl = secdesc_ctr->sec->dacl ?
05172 secdesc_ctr->sec->dacl :
05173 old_secdesc_ctr->sec->dacl;
05174
05175 sacl = secdesc_ctr->sec->sacl ?
05176 secdesc_ctr->sec->sacl :
05177 old_secdesc_ctr->sec->sacl;
05178
05179
05180
05181 psd = make_sec_desc(mem_ctx, secdesc_ctr->sec->revision, secdesc_ctr->sec->type,
05182 owner_sid, group_sid,
05183 sacl,
05184 dacl,
05185 &size);
05186
05187 if (!psd) {
05188 status = WERR_NOMEM;
05189 goto out;
05190 }
05191
05192 new_secdesc_ctr = make_sec_desc_buf(mem_ctx, size, psd);
05193 }
05194
05195 if (!new_secdesc_ctr) {
05196 new_secdesc_ctr = secdesc_ctr;
05197 }
05198
05199
05200
05201 prs_init(&ps, (uint32)sec_desc_size(new_secdesc_ctr->sec) +
05202 sizeof(SEC_DESC_BUF), mem_ctx, MARSHALL);
05203
05204 if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr,
05205 &ps, 1)) {
05206 status = WERR_BADFUNC;
05207 goto out;
05208 }
05209
05210 key = make_printers_secdesc_tdbkey( sharename );
05211
05212 if (tdb_prs_store(tdb_printers, key, &ps)==0) {
05213 status = WERR_OK;
05214 } else {
05215 DEBUG(1,("Failed to store secdesc for %s\n", sharename));
05216 status = WERR_BADFUNC;
05217 }
05218
05219
05220
05221 out:
05222
05223 prs_mem_free(&ps);
05224 if (mem_ctx)
05225 talloc_destroy(mem_ctx);
05226 return status;
05227 }
05228
05229
05230
05231
05232
05233 static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
05234 {
05235 SEC_ACE ace[5];
05236 int i = 0;
05237 SEC_ACCESS sa;
05238 SEC_ACL *psa = NULL;
05239 SEC_DESC_BUF *sdb = NULL;
05240 SEC_DESC *psd = NULL;
05241 DOM_SID adm_sid;
05242 size_t sd_size;
05243
05244
05245
05246 init_sec_access(&sa, PRINTER_ACE_PRINT);
05247 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
05248 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
05249
05250
05251
05252 if ( IS_DC ) {
05253 DOM_SID domadmins_sid;
05254
05255 sid_copy(&domadmins_sid, get_global_sam_sid());
05256 sid_append_rid(&domadmins_sid, DOMAIN_GROUP_RID_ADMINS);
05257
05258 init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
05259 init_sec_ace(&ace[i++], &domadmins_sid,
05260 SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
05261 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
05262 init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
05263 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
05264 }
05265 else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {
05266 sid_append_rid(&adm_sid, DOMAIN_USER_RID_ADMIN);
05267
05268 init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
05269 init_sec_ace(&ace[i++], &adm_sid,
05270 SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
05271 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
05272 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
05273 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
05274 }
05275
05276
05277
05278 init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
05279 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
05280 SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
05281 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
05282 init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
05283 SEC_ACE_TYPE_ACCESS_ALLOWED,
05284 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
05285
05286
05287
05288
05289
05290
05291
05292
05293 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
05294 psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
05295 &global_sid_Builtin_Administrators,
05296 &global_sid_Builtin_Administrators,
05297 NULL, psa, &sd_size);
05298 }
05299
05300 if (!psd) {
05301 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
05302 return NULL;
05303 }
05304
05305 sdb = make_sec_desc_buf(ctx, sd_size, psd);
05306
05307 DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
05308 (unsigned int)sd_size));
05309
05310 return sdb;
05311 }
05312
05313
05314
05315
05316
05317 BOOL nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **secdesc_ctr)
05318 {
05319 prs_struct ps;
05320 char *key;
05321 char *temp;
05322
05323 if (strlen(sharename) > 2 && (temp = strchr(sharename + 2, '\\'))) {
05324 sharename = temp + 1;
05325 }
05326
05327 ZERO_STRUCT(ps);
05328
05329
05330
05331 key = make_printers_secdesc_tdbkey( sharename );
05332
05333 if (tdb_prs_fetch(tdb_printers, key, &ps, ctx)!=0 ||
05334 !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
05335
05336 prs_mem_free(&ps);
05337
05338 DEBUG(4,("using default secdesc for %s\n", sharename));
05339
05340 if (!(*secdesc_ctr = construct_default_printer_sdb(ctx))) {
05341 return False;
05342 }
05343
05344
05345
05346 prs_init(&ps, (uint32)sec_desc_size((*secdesc_ctr)->sec) +
05347 sizeof(SEC_DESC_BUF), ctx, MARSHALL);
05348
05349 if (sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
05350 tdb_prs_store(tdb_printers, key, &ps);
05351 }
05352
05353 prs_mem_free(&ps);
05354
05355 return True;
05356 }
05357
05358 prs_mem_free(&ps);
05359
05360
05361
05362
05363
05364 if (sid_equal((*secdesc_ctr)->sec->owner_sid, &global_sid_World)) {
05365 DOM_SID owner_sid;
05366
05367
05368
05369 if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {
05370 SEC_DESC_BUF *new_secdesc_ctr = NULL;
05371 SEC_DESC *psd = NULL;
05372 size_t size;
05373
05374
05375
05376 sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
05377
05378 psd = make_sec_desc(ctx, (*secdesc_ctr)->sec->revision, (*secdesc_ctr)->sec->type,
05379 &owner_sid,
05380 (*secdesc_ctr)->sec->group_sid,
05381 (*secdesc_ctr)->sec->sacl,
05382 (*secdesc_ctr)->sec->dacl,
05383 &size);
05384
05385 if (!psd) {
05386 return False;
05387 }
05388
05389 new_secdesc_ctr = make_sec_desc_buf(ctx, size, psd);
05390 if (!new_secdesc_ctr) {
05391 return False;
05392 }
05393
05394
05395
05396 *secdesc_ctr = new_secdesc_ctr;
05397
05398
05399
05400 nt_printing_setsec(sharename, *secdesc_ctr);
05401 }
05402 }
05403
05404 if (DEBUGLEVEL >= 10) {
05405 SEC_ACL *the_acl = (*secdesc_ctr)->sec->dacl;
05406 int i;
05407
05408 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
05409 sharename, the_acl->num_aces));
05410
05411 for (i = 0; i < the_acl->num_aces; i++) {
05412 fstring sid_str;
05413
05414 sid_to_string(sid_str, &the_acl->aces[i].trustee);
05415
05416 DEBUG(10, ("%s %d %d 0x%08x\n", sid_str,
05417 the_acl->aces[i].type, the_acl->aces[i].flags,
05418 the_acl->aces[i].access_mask));
05419 }
05420 }
05421
05422 return True;
05423 }
05424
05425
05426
05427
05428
05429
05430
05431
05432
05433
05434
05435
05436
05437
05438
05439
05440
05441
05442
05443
05444
05445
05446
05447
05448
05449
05450
05451
05452
05453
05454
05455
05456
05457
05458
05459
05460
05461
05462
05463
05464
05465 void map_printer_permissions(SEC_DESC *sd)
05466 {
05467 int i;
05468
05469 for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
05470 se_map_generic(&sd->dacl->aces[i].access_mask,
05471 &printer_generic_mapping);
05472 }
05473 }
05474
05475 void map_job_permissions(SEC_DESC *sd)
05476 {
05477 int i;
05478
05479 for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
05480 se_map_generic(&sd->dacl->aces[i].access_mask,
05481 &job_generic_mapping);
05482 }
05483 }
05484
05485
05486
05487
05488
05489
05490
05491
05492
05493
05494
05495
05496
05497
05498
05499
05500
05501
05502
05503
05504
05505
05506
05507
05508
05509 BOOL print_access_check(struct current_user *user, int snum, int access_type)
05510 {
05511 SEC_DESC_BUF *secdesc = NULL;
05512 uint32 access_granted;
05513 NTSTATUS status;
05514 BOOL result;
05515 const char *pname;
05516 TALLOC_CTX *mem_ctx = NULL;
05517 SE_PRIV se_printop = SE_PRINT_OPERATOR;
05518
05519
05520
05521 if (!user)
05522 user = ¤t_user;
05523
05524
05525
05526 if ( user->ut.uid == 0 || user_has_privileges(user->nt_user_token, &se_printop ) ) {
05527 return True;
05528 }
05529
05530
05531
05532 pname = PRINTERNAME(snum);
05533
05534 if (!pname || !*pname) {
05535 errno = EACCES;
05536 return False;
05537 }
05538
05539
05540
05541 if(!(mem_ctx = talloc_init("print_access_check"))) {
05542 errno = ENOMEM;
05543 return False;
05544 }
05545
05546 if (!nt_printing_getsec(mem_ctx, pname, &secdesc)) {
05547 talloc_destroy(mem_ctx);
05548 errno = ENOMEM;
05549 return False;
05550 }
05551
05552 if (access_type == JOB_ACCESS_ADMINISTER) {
05553 SEC_DESC_BUF *parent_secdesc = secdesc;
05554
05555
05556
05557
05558
05559 secdesc = se_create_child_secdesc(mem_ctx, parent_secdesc->sec, False);
05560
05561 if (!secdesc) {
05562 talloc_destroy(mem_ctx);
05563 errno = ENOMEM;
05564 return False;
05565 }
05566
05567 map_job_permissions(secdesc->sec);
05568 } else {
05569 map_printer_permissions(secdesc->sec);
05570 }
05571
05572
05573 result = se_access_check(secdesc->sec, user->nt_user_token, access_type,
05574 &access_granted, &status);
05575
05576 DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
05577
05578
05579
05580 if ((access_granted == 0) &&
05581 (token_contains_name_in_list(uidtoname(user->ut.uid), NULL,
05582 user->nt_user_token,
05583 lp_printer_admin(snum)))) {
05584 talloc_destroy(mem_ctx);
05585 return True;
05586 }
05587
05588 talloc_destroy(mem_ctx);
05589
05590 if (!result) {
05591 errno = EACCES;
05592 }
05593
05594 return result;
05595 }
05596
05597
05598
05599
05600
05601 BOOL print_time_access_check(const char *servicename)
05602 {
05603 NT_PRINTER_INFO_LEVEL *printer = NULL;
05604 BOOL ok = False;
05605 time_t now = time(NULL);
05606 struct tm *t;
05607 uint32 mins;
05608
05609 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
05610 return False;
05611
05612 if (printer->info_2->starttime == 0 && printer->info_2->untiltime == 0)
05613 ok = True;
05614
05615 t = gmtime(&now);
05616 mins = (uint32)t->tm_hour*60 + (uint32)t->tm_min;
05617
05618 if (mins >= printer->info_2->starttime && mins <= printer->info_2->untiltime)
05619 ok = True;
05620
05621 free_a_printer(&printer, 2);
05622
05623 if (!ok)
05624 errno = EACCES;
05625
05626 return ok;
05627 }
05628
05629
05630
05631
05632
05633 char* get_server_name( Printer_entry *printer )
05634 {
05635 return printer->servername;
05636 }
05637
05638