?? net_rpc_printer.c
字號:
/* adddriver dst */ if (!net_spoolss_addprinterdriver(pipe_hnd_dst, mem_ctx, level, &drv_ctr_src)) { nt_status = NT_STATUS_UNSUCCESSFUL; goto done; } DEBUGADD(1,("Sucessfully added driver [%s] for printer [%s]\n", drivername, printername)); } if (strlen(drivername) == 0) { DEBUGADD(1,("Did not get driver for printer %s\n", printername)); goto done; } /* setdriver dst */ init_unistr(&info_ctr_dst.printers_2->drivername, drivername); if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_ctr_dst)) { nt_status = NT_STATUS_UNSUCCESSFUL; goto done; } DEBUGADD(1,("Sucessfully set driver %s for printer %s\n", drivername, printername)); /* close dst */ if (got_hnd_dst) { rpccli_spoolss_close_printer(pipe_hnd_dst, mem_ctx, &hnd_dst); got_hnd_dst = False; } /* close src */ if (got_hnd_src) { rpccli_spoolss_close_printer(pipe_hnd, mem_ctx, &hnd_src); got_hnd_src = False; } } nt_status = NT_STATUS_OK;done: if (got_hnd_src) rpccli_spoolss_close_printer(pipe_hnd, mem_ctx, &hnd_src); if (got_hnd_dst) rpccli_spoolss_close_printer(pipe_hnd_dst, mem_ctx, &hnd_dst); if (cli_dst) { cli_shutdown(cli_dst); } if (got_src_driver_share) cli_shutdown(cli_share_src); if (got_dst_driver_share) cli_shutdown(cli_share_dst); return nt_status;}/** * Migrate printer-queues from a src to the dst server * (requires a working "addprinter command" to be installed for the local smbd) * * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passed through. * * @param domain_sid The domain sid aquired from the remote server * @param cli A cli_state connected to the server. * @param mem_ctx Talloc context, destoyed on compleation of the function. * @param argc Standard main() style argc * @param argv Standard main() style argv. Initial components are already * stripped * * @return Normal NTSTATUS return. **/NTSTATUS rpc_printer_migrate_printers_internals(const DOM_SID *domain_sid, const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, int argc, const char **argv){ WERROR result; NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; uint32 i = 0, num_printers; uint32 level = 2; PRINTER_INFO_CTR ctr_src, ctr_dst, ctr_enum; struct cli_state *cli_dst = NULL; POLICY_HND hnd_dst, hnd_src; pstring printername, sharename; BOOL got_hnd_src = False; BOOL got_hnd_dst = False; struct rpc_pipe_client *pipe_hnd_dst = NULL; DEBUG(3,("copying printers\n")); /* connect destination PI_SPOOLSS */ nt_status = connect_dst_pipe(&cli_dst, &pipe_hnd_dst, PI_SPOOLSS); if (!NT_STATUS_IS_OK(nt_status)) return nt_status; /* enum printers */ if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &ctr_enum)) { nt_status = NT_STATUS_UNSUCCESSFUL; goto done; } if (!num_printers) { printf ("no printers found on server.\n"); nt_status = NT_STATUS_OK; goto done; } /* do something for all printers */ for (i = 0; i < num_printers; i++) { /* do some initialization */ rpcstr_pull(printername, ctr_enum.printers_2[i].printername.buffer, sizeof(printername), -1, STR_TERMINATE); rpcstr_pull(sharename, ctr_enum.printers_2[i].sharename.buffer, sizeof(sharename), -1, STR_TERMINATE); /* we can reset NT_STATUS here because we do not get any real NT_STATUS-codes anymore from now on */ nt_status = NT_STATUS_UNSUCCESSFUL; d_printf("migrating printer queue for: [%s] / [%s]\n", printername, sharename); /* open dst printer handle */ if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename, PRINTER_ALL_ACCESS, cli->user_name, &hnd_dst)) { DEBUG(1,("could not open printer: %s\n", sharename)); } else { got_hnd_dst = True; } /* check for existing dst printer */ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &ctr_dst)) { printf ("could not get printer, creating printer.\n"); } else { DEBUG(1,("printer already exists: %s\n", sharename)); /* close printer handles here */ if (got_hnd_src) { rpccli_spoolss_close_printer(pipe_hnd, mem_ctx, &hnd_src); got_hnd_src = False; } if (got_hnd_dst) { rpccli_spoolss_close_printer(pipe_hnd_dst, mem_ctx, &hnd_dst); got_hnd_dst = False; } continue; } /* now get again src printer ctr via getprinter, we first need a handle for that */ /* open src printer handle */ if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, sharename, MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src)) goto done; got_hnd_src = True; /* getprinter on the src server */ if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, level, &ctr_src)) goto done; /* copy each src printer to a dst printer 1:1, maybe some values have to be changed though */ d_printf("creating printer: %s\n", printername); result = rpccli_spoolss_addprinterex (pipe_hnd_dst, mem_ctx, level, &ctr_src); if (W_ERROR_IS_OK(result)) d_printf ("printer [%s] successfully added.\n", printername); else if (W_ERROR_V(result) == W_ERROR_V(WERR_PRINTER_ALREADY_EXISTS)) d_fprintf (stderr, "printer [%s] already exists.\n", printername); else { d_fprintf (stderr, "could not create printer [%s]\n", printername); goto done; } /* close printer handles here */ if (got_hnd_src) { rpccli_spoolss_close_printer(pipe_hnd, mem_ctx, &hnd_src); got_hnd_src = False; } if (got_hnd_dst) { rpccli_spoolss_close_printer(pipe_hnd_dst, mem_ctx, &hnd_dst); got_hnd_dst = False; } } nt_status = NT_STATUS_OK;done: if (got_hnd_src) rpccli_spoolss_close_printer(pipe_hnd, mem_ctx, &hnd_src); if (got_hnd_dst) rpccli_spoolss_close_printer(pipe_hnd_dst, mem_ctx, &hnd_dst); if (cli_dst) { cli_shutdown(cli_dst); } return nt_status;}/** * Migrate Printer-Settings from a src server to the dst server * (for this to work, printers and drivers already have to be migrated earlier) * * All parameters are provided by the run_rpc_command function, except for * argc, argv which are passed through. * * @param domain_sid The domain sid aquired from the remote server * @param cli A cli_state connected to the server. * @param mem_ctx Talloc context, destoyed on compleation of the function. * @param argc Standard main() style argc * @param argv Standard main() style argv. Initial components are already * stripped * * @return Normal NTSTATUS return. **/NTSTATUS rpc_printer_migrate_settings_internals(const DOM_SID *domain_sid, const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, int argc, const char **argv){ /* FIXME: Here the nightmare begins */ WERROR result; NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; uint32 i = 0, p = 0, j = 0; uint32 num_printers, val_needed, data_needed; uint32 level = 2; pstring printername = "", sharename = ""; BOOL got_hnd_src = False; BOOL got_hnd_dst = False; struct rpc_pipe_client *pipe_hnd_dst = NULL; POLICY_HND hnd_src, hnd_dst; PRINTER_INFO_CTR ctr_enum, ctr_dst, ctr_dst_publish; REGVAL_CTR *reg_ctr; struct cli_state *cli_dst = NULL; char *devicename = NULL, *unc_name = NULL, *url = NULL; fstring longname; uint16 *keylist = NULL, *curkey; ZERO_STRUCT(ctr_enum); DEBUG(3,("copying printer settings\n")); /* connect destination PI_SPOOLSS */ nt_status = connect_dst_pipe(&cli_dst, &pipe_hnd_dst, PI_SPOOLSS); if (!NT_STATUS_IS_OK(nt_status)) return nt_status; /* enum src printers */ if (!get_printer_info(pipe_hnd, mem_ctx, level, argc, argv, &num_printers, &ctr_enum)) { nt_status = NT_STATUS_UNSUCCESSFUL; goto done; } if (!num_printers) { printf ("no printers found on server.\n"); nt_status = NT_STATUS_OK; goto done; } /* needed for dns-strings in regkeys */ get_mydnsfullname(longname); /* do something for all printers */ for (i = 0; i < num_printers; i++) { /* do some initialization */ rpcstr_pull(printername, ctr_enum.printers_2[i].printername.buffer, sizeof(printername), -1, STR_TERMINATE); rpcstr_pull(sharename, ctr_enum.printers_2[i].sharename.buffer, sizeof(sharename), -1, STR_TERMINATE); /* we can reset NT_STATUS here because we do not get any real NT_STATUS-codes anymore from now on */ nt_status = NT_STATUS_UNSUCCESSFUL; d_printf("migrating printer settings for: [%s] / [%s]\n", printername, sharename); /* open src printer handle */ if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, sharename, MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src)) goto done; got_hnd_src = True; /* open dst printer handle */ if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename, PRINTER_ALL_ACCESS, cli_dst->user_name, &hnd_dst)) goto done; got_hnd_dst = True; /* check for existing dst printer */ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &ctr_dst)) goto done; /* STEP 1: COPY DEVICE-MODE and other PRINTER_INFO_2-attributes */ ctr_dst.printers_2 = &ctr_enum.printers_2[i]; /* why is the port always disconnected when the printer is correctly installed (incl. driver ???) */ init_unistr( &ctr_dst.printers_2->portname, SAMBA_PRINTER_PORT_NAME); /* check if printer is published */ if (ctr_enum.printers_2[i].attributes & PRINTER_ATTRIBUTE_PUBLISHED) { /* check for existing dst printer */ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &ctr_dst_publish)) goto done; ctr_dst_publish.printers_7->action = SPOOL_DS_PUBLISH; /* ignore False from setprinter due to WERR_IO_PENDING */ net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &ctr_dst_publish); DEBUG(3,("republished printer\n")); } if (ctr_enum.printers_2[i].devmode != NULL) { /* copy devmode (info level 2) */ ctr_dst.printers_2->devmode = TALLOC_MEMDUP(mem_ctx, ctr_enum.printers_2[i].devmode, sizeof(DEVICEMODE)); /* do not copy security descriptor (we have another * command for that) */ ctr_dst.printers_2->secdesc = NULL;#if 0 if (asprintf(&devicename, "\\\\%s\\%s", longname, printername) < 0) { nt_status = NT_STATUS_NO_MEMORY; goto done; } init_unistr(&ctr_dst.printers_2->devmode->devicename, devicename); #endif if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &ctr_dst)) goto done; DEBUGADD(1,("\tSetPrinter of DEVICEMODE succeeded\n")); } /* STEP 2: COPY REGISTRY VALUES */ /* please keep in mind that samba parse_spools gives horribly crippled results when used to rpccli_spoolss_enumprinterdataex a win2k3-server. (Bugzilla #1851) FIXME: IIRC I've seen it too on a win2k-server */ /* enumerate data on src handle */ result = rpccli_spoolss_enumprinterdata(pipe_hnd, mem_ctx, &hnd_src, p, 0, 0, &val_needed, &data_needed, NULL); /* loop for all printerdata of "PrinterDriverData" */ while (W_ERROR_IS_OK(result)) { REGISTRY_VALUE value; result = rpccli_spoolss_enumprinterdata( pipe_hnd, mem_ctx, &hnd_src, p++, val_needed, /* loop for all reg_keys */ if (W_ERROR_IS_OK(result)) { /* display_value */ if (opt_verbose) display_reg_value(SPOOL_PRINTERDATA_KEY, value); /* set_value */ if (!net_spoolss_setprinterdata(pipe_hnd_dst, mem_ctx, &hnd_dst, &value)) goto done; DEBUGADD(1,("\tSetPrinterData of [%s] succeeded\n", value.valuename)); } } /* STEP 3: COPY SUBKEY VALUES */ /* here we need to enum all printer_keys and then work on the result with enum_printer_key_ex. nt4 does not respond to enumprinterkey, win2k does, so continue in case of an error */ if (!net_spoolss_enumprinterkey(pipe_hnd, mem_ctx, &hnd_src, "", &keylist)) { printf("got no key-data\n"); continue; } /* work on a list of printer keys each key has to be enumerated to get all required information. information is then set via setprinterdataex-calls */ if (keylist == NULL) continue; curkey = keylist; while (*curkey != 0) { pstring subkey; rpcstr_pull(subkey, curkey, sizeof(subkey), -1, STR_TERMINATE); curkey += strlen(subkey) + 1; if ( !(reg_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) ) return NT_STATUS_NO_MEMORY; /* enumerate all src subkeys */ if (!net_spoolss_enumprinterdataex(pipe_hnd, mem_ctx, 0, &hnd_src, subkey, reg_ctr)) goto done; for (j=0; j < reg_ctr->num_values; j++) { REGISTRY_VALUE value; UNISTR2 data; /* although samba replies with sane data in most cases we should try to avoid writing wrong registry data */ if (strequal(reg_ctr->values[j]->valuename, SPOOL_REG_PORTNAME) || strequal(reg_ctr->values[j]->valuename, SPOOL_REG_UNCNAME) || strequal(reg_ctr->values[j]->valuename, SPOOL_REG_URL) || strequal(reg_ctr->values[j]->valuename, SPOOL_REG_SHORTSERVERNAME) || strequal(reg_ctr->values[j]->valuename, SPOOL_REG_SERVERNAME)) { if (strequal(reg_ctr->values[j]->valuename, SPOOL_REG_PORTNAME)) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -