00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "includes.h"
00030
00031 extern userdom_struct current_user_info;
00032
00033 #undef DBGC_CLASS
00034 #define DBGC_CLASS DBGC_RPC_SRV
00035
00036 #ifndef MAX_OPEN_PRINTER_EXS
00037 #define MAX_OPEN_PRINTER_EXS 50
00038 #endif
00039
00040 #define MAGIC_DISPLAY_FREQUENCY 0xfade2bad
00041 #define PHANTOM_DEVMODE_KEY "_p_f_a_n_t_0_m_"
00042
00043 struct table_node {
00044 const char *long_archi;
00045 const char *short_archi;
00046 int version;
00047 };
00048
00049 static Printer_entry *printers_list;
00050
00051 typedef struct _counter_printer_0 {
00052 struct _counter_printer_0 *next;
00053 struct _counter_printer_0 *prev;
00054
00055 int snum;
00056 uint32 counter;
00057 } counter_printer_0;
00058
00059 static counter_printer_0 *counter_list;
00060
00061 static struct rpc_pipe_client *notify_cli_pipe;
00062 static uint32 smb_connections=0;
00063
00064
00065
00066
00067 extern STANDARD_MAPPING printer_std_mapping, printserver_std_mapping;
00068
00069
00070
00071 struct xcv_api_table {
00072 const char *name;
00073 WERROR(*fn) (NT_USER_TOKEN *token, RPC_BUFFER *in, RPC_BUFFER *out, uint32 *needed);
00074 };
00075
00076
00077
00078
00079
00080 static const char *canon_servername(const char *servername)
00081 {
00082 const char *pservername = servername;
00083 while (*pservername == '\\') {
00084 pservername++;
00085 }
00086 return pservername;
00087 }
00088
00089
00090 static int nt_printj_status(int v)
00091 {
00092 switch (v) {
00093 case LPQ_QUEUED:
00094 return 0;
00095 case LPQ_PAUSED:
00096 return JOB_STATUS_PAUSED;
00097 case LPQ_SPOOLING:
00098 return JOB_STATUS_SPOOLING;
00099 case LPQ_PRINTING:
00100 return JOB_STATUS_PRINTING;
00101 case LPQ_ERROR:
00102 return JOB_STATUS_ERROR;
00103 case LPQ_DELETING:
00104 return JOB_STATUS_DELETING;
00105 case LPQ_OFFLINE:
00106 return JOB_STATUS_OFFLINE;
00107 case LPQ_PAPEROUT:
00108 return JOB_STATUS_PAPEROUT;
00109 case LPQ_PRINTED:
00110 return JOB_STATUS_PRINTED;
00111 case LPQ_DELETED:
00112 return JOB_STATUS_DELETED;
00113 case LPQ_BLOCKED:
00114 return JOB_STATUS_BLOCKED;
00115 case LPQ_USER_INTERVENTION:
00116 return JOB_STATUS_USER_INTERVENTION;
00117 }
00118 return 0;
00119 }
00120
00121 static int nt_printq_status(int v)
00122 {
00123 switch (v) {
00124 case LPQ_PAUSED:
00125 return PRINTER_STATUS_PAUSED;
00126 case LPQ_QUEUED:
00127 case LPQ_SPOOLING:
00128 case LPQ_PRINTING:
00129 return 0;
00130 }
00131 return 0;
00132 }
00133
00134
00135
00136
00137
00138 static void free_spool_notify_option(SPOOL_NOTIFY_OPTION **pp)
00139 {
00140 if (*pp == NULL)
00141 return;
00142
00143 SAFE_FREE((*pp)->ctr.type);
00144 SAFE_FREE(*pp);
00145 }
00146
00147
00148
00149
00150
00151 static void srv_spoolss_replycloseprinter(int snum, POLICY_HND *handle)
00152 {
00153 WERROR result;
00154
00155
00156
00157
00158
00159
00160 if (!print_notify_deregister_pid(snum))
00161 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
00162
00163
00164 if (smb_connections==0) {
00165 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
00166 return;
00167 }
00168
00169 result = rpccli_spoolss_reply_close_printer(notify_cli_pipe, notify_cli_pipe->cli->mem_ctx, handle);
00170
00171 if (!W_ERROR_IS_OK(result))
00172 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
00173 dos_errstr(result)));
00174
00175
00176 if (smb_connections==1) {
00177
00178 cli_shutdown( notify_cli_pipe->cli );
00179 notify_cli_pipe = NULL;
00180
00181 message_deregister(MSG_PRINTER_NOTIFY2);
00182
00183
00184
00185
00186 register_message_flags( False, FLAG_MSG_PRINT_NOTIFY );
00187 }
00188
00189 smb_connections--;
00190 }
00191
00192
00193
00194
00195
00196 static void free_printer_entry(void *ptr)
00197 {
00198 Printer_entry *Printer = (Printer_entry *)ptr;
00199
00200 if (Printer->notify.client_connected==True) {
00201 int snum = -1;
00202
00203 if ( Printer->printer_type == SPLHND_SERVER) {
00204 snum = -1;
00205 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
00206 } else if (Printer->printer_type == SPLHND_PRINTER) {
00207 snum = print_queue_snum(Printer->sharename);
00208 if (snum != -1)
00209 srv_spoolss_replycloseprinter(snum,
00210 &Printer->notify.client_hnd);
00211 }
00212 }
00213
00214 Printer->notify.flags=0;
00215 Printer->notify.options=0;
00216 Printer->notify.localmachine[0]='\0';
00217 Printer->notify.printerlocal=0;
00218 free_spool_notify_option(&Printer->notify.option);
00219 Printer->notify.option=NULL;
00220 Printer->notify.client_connected=False;
00221
00222 free_nt_devicemode( &Printer->nt_devmode );
00223 free_a_printer( &Printer->printer_info, 2 );
00224
00225 talloc_destroy( Printer->ctx );
00226
00227
00228 DLIST_REMOVE(printers_list, Printer);
00229
00230 SAFE_FREE(Printer);
00231 }
00232
00233
00234
00235
00236
00237 static SPOOL_NOTIFY_OPTION *dup_spool_notify_option(SPOOL_NOTIFY_OPTION *sp)
00238 {
00239 SPOOL_NOTIFY_OPTION *new_sp = NULL;
00240
00241 if (!sp)
00242 return NULL;
00243
00244 new_sp = SMB_MALLOC_P(SPOOL_NOTIFY_OPTION);
00245 if (!new_sp)
00246 return NULL;
00247
00248 *new_sp = *sp;
00249
00250 if (sp->ctr.count) {
00251 new_sp->ctr.type = (SPOOL_NOTIFY_OPTION_TYPE *)memdup(sp->ctr.type, sizeof(SPOOL_NOTIFY_OPTION_TYPE) * sp->ctr.count);
00252
00253 if (!new_sp->ctr.type) {
00254 SAFE_FREE(new_sp);
00255 return NULL;
00256 }
00257 }
00258
00259 return new_sp;
00260 }
00261
00262
00263
00264
00265
00266 static Printer_entry *find_printer_index_by_hnd(pipes_struct *p, POLICY_HND *hnd)
00267 {
00268 Printer_entry *find_printer = NULL;
00269
00270 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
00271 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
00272 return NULL;
00273 }
00274
00275 return find_printer;
00276 }
00277
00278
00279
00280
00281
00282 static BOOL close_printer_handle(pipes_struct *p, POLICY_HND *hnd)
00283 {
00284 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
00285
00286 if (!Printer) {
00287 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
00288 return False;
00289 }
00290
00291 close_policy_hnd(p, hnd);
00292
00293 return True;
00294 }
00295
00296
00297
00298
00299 WERROR delete_printer_hook( NT_USER_TOKEN *token, const char *sharename )
00300 {
00301 char *cmd = lp_deleteprinter_cmd();
00302 pstring command;
00303 int ret;
00304 SE_PRIV se_printop = SE_PRINT_OPERATOR;
00305 BOOL is_print_op = False;
00306
00307
00308
00309 if ( !*cmd )
00310 return WERR_OK;
00311
00312 pstr_sprintf(command, "%s \"%s\"", cmd, sharename);
00313
00314 if ( token )
00315 is_print_op = user_has_privileges( token, &se_printop );
00316
00317 DEBUG(10,("Running [%s]\n", command));
00318
00319
00320
00321 if ( is_print_op )
00322 become_root();
00323
00324 if ( (ret = smbrun(command, NULL)) == 0 ) {
00325
00326 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
00327 }
00328
00329 if ( is_print_op )
00330 unbecome_root();
00331
00332
00333
00334 DEBUGADD(10,("returned [%d]\n", ret));
00335
00336 if (ret != 0)
00337 return WERR_BADFID;
00338
00339
00340 reload_services( False );
00341
00342 if ( lp_servicenumber( sharename ) < 0 )
00343 return WERR_ACCESS_DENIED;
00344
00345 return WERR_OK;
00346 }
00347
00348
00349
00350
00351
00352 static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
00353 {
00354 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
00355
00356 if (!Printer) {
00357 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
00358 return WERR_BADFID;
00359 }
00360
00361
00362
00363
00364
00365
00366
00367
00368 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
00369 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
00370 return WERR_ACCESS_DENIED;
00371 }
00372
00373
00374
00375
00376 if (del_a_printer( Printer->sharename ) != 0) {
00377 DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
00378 return WERR_BADFID;
00379 }
00380
00381 return delete_printer_hook( p->pipe_user.nt_user_token, Printer->sharename );
00382 }
00383
00384
00385
00386
00387
00388 static BOOL get_printer_snum(pipes_struct *p, POLICY_HND *hnd, int *number)
00389 {
00390 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
00391
00392 if (!Printer) {
00393 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
00394 return False;
00395 }
00396
00397 switch (Printer->printer_type) {
00398 case SPLHND_PRINTER:
00399 DEBUG(4,("short name:%s\n", Printer->sharename));
00400 *number = print_queue_snum(Printer->sharename);
00401 return (*number != -1);
00402 case SPLHND_SERVER:
00403 return False;
00404 default:
00405 return False;
00406 }
00407 }
00408
00409
00410
00411
00412
00413
00414 static BOOL set_printer_hnd_printertype(Printer_entry *Printer, char *handlename)
00415 {
00416 DEBUG(3,("Setting printer type=%s\n", handlename));
00417
00418 if ( strlen(handlename) < 3 ) {
00419 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
00420 return False;
00421 }
00422
00423
00424 if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
00425 DEBUGADD(4,("Printer is a print server\n"));
00426 Printer->printer_type = SPLHND_SERVER;
00427 }
00428
00429 else {
00430 DEBUGADD(4,("Printer is a printer\n"));
00431 Printer->printer_type = SPLHND_PRINTER;
00432 }
00433
00434 return True;
00435 }
00436
00437
00438
00439
00440
00441
00442
00443
00444 static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
00445 {
00446 int snum;
00447 int n_services=lp_numservices();
00448 char *aprinter, *printername;
00449 const char *servername;
00450 fstring sname;
00451 BOOL found=False;
00452 NT_PRINTER_INFO_LEVEL *printer = NULL;
00453 WERROR result;
00454
00455 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename, (unsigned long)strlen(handlename)));
00456
00457 aprinter = handlename;
00458 if ( *handlename == '\\' ) {
00459 servername = canon_servername(handlename);
00460 if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
00461 *aprinter = '\0';
00462 aprinter++;
00463 }
00464 } else {
00465 servername = "";
00466 }
00467
00468
00469
00470 if ( !is_myname_or_ipaddr( servername ) )
00471 return False;
00472
00473 fstrcpy( Printer->servername, servername );
00474
00475 if ( Printer->printer_type == SPLHND_SERVER )
00476 return True;
00477
00478 if ( Printer->printer_type != SPLHND_PRINTER )
00479 return False;
00480
00481 DEBUGADD(5, ("searching for [%s]\n", aprinter ));
00482
00483
00484
00485 if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
00486 Printer->printer_type = SPLHND_PORTMON_TCP;
00487 fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
00488 found = True;
00489 }
00490 else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
00491 Printer->printer_type = SPLHND_PORTMON_LOCAL;
00492 fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
00493 found = True;
00494 }
00495
00496
00497
00498
00499
00500
00501
00502 for (snum=0; !found && snum<n_services; snum++) {
00503
00504
00505
00506 if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) )
00507 continue;
00508
00509 fstrcpy(sname, lp_servicename(snum));
00510 if ( strequal( aprinter, sname ) ) {
00511 found = True;
00512 break;
00513 }
00514
00515
00516
00517
00518 if ( lp_force_printername(snum) )
00519 continue;
00520
00521 fstrcpy(sname, lp_servicename(snum));
00522
00523 printer = NULL;
00524
00525
00526
00527
00528
00529 result = get_a_printer_search( NULL, &printer, 2, sname );
00530 if ( !W_ERROR_IS_OK(result) ) {
00531 DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
00532 sname, dos_errstr(result)));
00533 continue;
00534 }
00535
00536
00537 if ( !(printername = strchr_m(&printer->info_2->printername[2], '\\')) ) {
00538 DEBUG(0,("set_printer_hnd_name: info2->printername in wrong format! [%s]\n",
00539 printer->info_2->printername));
00540 free_a_printer( &printer, 2);
00541 continue;
00542 }
00543
00544 printername++;
00545
00546 if ( strequal(printername, aprinter) ) {
00547 free_a_printer( &printer, 2);
00548 found = True;
00549 break;
00550 }
00551
00552 DEBUGADD(10, ("printername: %s\n", printername));
00553
00554 free_a_printer( &printer, 2);
00555 }
00556
00557 free_a_printer( &printer, 2);
00558
00559 if ( !found ) {
00560 DEBUGADD(4,("Printer not found\n"));
00561 return False;
00562 }
00563
00564 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
00565
00566 fstrcpy(Printer->sharename, sname);
00567
00568 return True;
00569 }
00570
00571
00572
00573
00574
00575 static BOOL open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint32 access_granted)
00576 {
00577 Printer_entry *new_printer;
00578
00579 DEBUG(10,("open_printer_hnd: name [%s]\n", name));
00580
00581 if((new_printer=SMB_MALLOC_P(Printer_entry)) == NULL)
00582 return False;
00583
00584 ZERO_STRUCTP(new_printer);
00585
00586 if (!create_policy_hnd(p, hnd, free_printer_entry, new_printer)) {
00587 SAFE_FREE(new_printer);
00588 return False;
00589 }
00590
00591
00592 DLIST_ADD(printers_list, new_printer);
00593
00594 new_printer->notify.option=NULL;
00595
00596 if ( !(new_printer->ctx = talloc_init("Printer Entry [%p]", hnd)) ) {
00597 DEBUG(0,("open_printer_hnd: talloc_init() failed!\n"));
00598 close_printer_handle(p, hnd);
00599 return False;
00600 }
00601
00602 if (!set_printer_hnd_printertype(new_printer, name)) {
00603 close_printer_handle(p, hnd);
00604 return False;
00605 }
00606
00607 if (!set_printer_hnd_name(new_printer, name)) {
00608 close_printer_handle(p, hnd);
00609 return False;
00610 }
00611
00612 new_printer->access_granted = access_granted;
00613
00614 DEBUG(5, ("%d printer handles active\n", (int)p->pipe_handles->count ));
00615
00616 return True;
00617 }
00618
00619
00620
00621
00622
00623
00624 static BOOL is_monitoring_event_flags(uint32 flags, uint16 notify_type,
00625 uint16 notify_field)
00626 {
00627 return True;
00628 }
00629
00630 static BOOL is_monitoring_event(Printer_entry *p, uint16 notify_type,
00631 uint16 notify_field)
00632 {
00633 SPOOL_NOTIFY_OPTION *option = p->notify.option;
00634 uint32 i, j;
00635
00636
00637
00638
00639
00640
00641
00642
00643 if (!option) {
00644 return False;
00645 }
00646
00647 if (p->notify.flags)
00648 return is_monitoring_event_flags(
00649 p->notify.flags, notify_type, notify_field);
00650
00651 for (i = 0; i < option->count; i++) {
00652
00653
00654
00655 if (option->ctr.type[i].type != notify_type)
00656 continue;
00657
00658
00659
00660 for (j = 0; j < option->ctr.type[i].count; j++) {
00661 if (option->ctr.type[i].fields[j] == notify_field) {
00662 return True;
00663 }
00664 }
00665 }
00666
00667 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
00668 p->servername, p->sharename, notify_type, notify_field));
00669
00670 return False;
00671 }
00672
00673
00674
00675 static void notify_one_value(struct spoolss_notify_msg *msg,
00676 SPOOL_NOTIFY_INFO_DATA *data,
00677 TALLOC_CTX *mem_ctx)
00678 {
00679 data->notify_data.value[0] = msg->notify.value[0];
00680 data->notify_data.value[1] = 0;
00681 }
00682
00683 static void notify_string(struct spoolss_notify_msg *msg,
00684 SPOOL_NOTIFY_INFO_DATA *data,
00685 TALLOC_CTX *mem_ctx)
00686 {
00687 UNISTR2 unistr;
00688
00689
00690
00691 init_unistr2(&unistr, msg->notify.data, UNI_STR_TERMINATE);
00692
00693 data->notify_data.data.length = msg->len * 2;
00694 data->notify_data.data.string = TALLOC_ARRAY(mem_ctx, uint16, msg->len);
00695
00696 if (!data->notify_data.data.string) {
00697 data->notify_data.data.length = 0;
00698 return;
00699 }
00700
00701 memcpy(data->notify_data.data.string, unistr.buffer, msg->len * 2);
00702 }
00703
00704 static void notify_system_time(struct spoolss_notify_msg *msg,
00705 SPOOL_NOTIFY_INFO_DATA *data,
00706 TALLOC_CTX *mem_ctx)
00707 {
00708 SYSTEMTIME systime;
00709 prs_struct ps;
00710
00711 if (msg->len != sizeof(time_t)) {
00712 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
00713 msg->len));
00714 return;
00715 }
00716
00717 if (!prs_init(&ps, RPC_MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL)) {
00718 DEBUG(5, ("notify_system_time: prs_init() failed\n"));
00719 return;
00720 }
00721
00722 if (!make_systemtime(&systime, gmtime((time_t *)msg->notify.data))) {
00723 DEBUG(5, ("notify_system_time: unable to make systemtime\n"));
00724 prs_mem_free(&ps);
00725 return;
00726 }
00727
00728 if (!spoolss_io_system_time("", &ps, 0, &systime)) {
00729 prs_mem_free(&ps);
00730 return;
00731 }
00732
00733 data->notify_data.data.length = prs_offset(&ps);
00734 if (prs_offset(&ps)) {
00735 data->notify_data.data.string = (uint16 *)
00736 TALLOC(mem_ctx, prs_offset(&ps));
00737 if (!data->notify_data.data.string) {
00738 prs_mem_free(&ps);
00739 return;
00740 }
00741 prs_copy_all_data_out((char *)data->notify_data.data.string, &ps);
00742 } else {
00743 data->notify_data.data.string = NULL;
00744 }
00745
00746 prs_mem_free(&ps);
00747 }
00748
00749 struct notify2_message_table {
00750 const char *name;
00751 void (*fn)(struct spoolss_notify_msg *msg,
00752 SPOOL_NOTIFY_INFO_DATA *data, TALLOC_CTX *mem_ctx);
00753 };
00754
00755 static struct notify2_message_table printer_notify_table[] = {
00756 { "PRINTER_NOTIFY_SERVER_NAME", notify_string },
00757 { "PRINTER_NOTIFY_PRINTER_NAME", notify_string },
00758 { "PRINTER_NOTIFY_SHARE_NAME", notify_string },
00759 { "PRINTER_NOTIFY_PORT_NAME", notify_string },
00760 { "PRINTER_NOTIFY_DRIVER_NAME", notify_string },
00761 { "PRINTER_NOTIFY_COMMENT", notify_string },
00762 { "PRINTER_NOTIFY_LOCATION", notify_string },
00763 { "PRINTER_NOTIFY_DEVMODE", NULL },
00764 { "PRINTER_NOTIFY_SEPFILE", notify_string },
00765 { "PRINTER_NOTIFY_PRINT_PROCESSOR", notify_string },
00766 { "PRINTER_NOTIFY_PARAMETERS", NULL },
00767 { "PRINTER_NOTIFY_DATATYPE", notify_string },
00768 { "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NULL },
00769 { "PRINTER_NOTIFY_ATTRIBUTES", notify_one_value },
00770 { "PRINTER_NOTIFY_PRIORITY", notify_one_value },
00771 { "PRINTER_NOTIFY_DEFAULT_PRIORITY", NULL },
00772 { "PRINTER_NOTIFY_START_TIME", NULL },
00773 { "PRINTER_NOTIFY_UNTIL_TIME", NULL },
00774 { "PRINTER_NOTIFY_STATUS", notify_one_value },
00775 };
00776
00777 static struct notify2_message_table job_notify_table[] = {
00778 { "JOB_NOTIFY_PRINTER_NAME", NULL },
00779 { "JOB_NOTIFY_MACHINE_NAME", NULL },
00780 { "JOB_NOTIFY_PORT_NAME", NULL },
00781 { "JOB_NOTIFY_USER_NAME", notify_string },
00782 { "JOB_NOTIFY_NOTIFY_NAME", NULL },
00783 { "JOB_NOTIFY_DATATYPE", NULL },
00784 { "JOB_NOTIFY_PRINT_PROCESSOR", NULL },
00785 { "JOB_NOTIFY_PARAMETERS", NULL },
00786 { "JOB_NOTIFY_DRIVER_NAME", NULL },
00787 { "JOB_NOTIFY_DEVMODE", NULL },
00788 { "JOB_NOTIFY_STATUS", notify_one_value },
00789 { "JOB_NOTIFY_STATUS_STRING", NULL },
00790 { "JOB_NOTIFY_SECURITY_DESCRIPTOR", NULL },
00791 { "JOB_NOTIFY_DOCUMENT", notify_string },
00792 { "JOB_NOTIFY_PRIORITY", NULL },
00793 { "JOB_NOTIFY_POSITION", NULL },
00794 { "JOB_NOTIFY_SUBMITTED", notify_system_time },
00795 { "JOB_NOTIFY_START_TIME", NULL },
00796 { "JOB_NOTIFY_UNTIL_TIME", NULL },
00797 { "JOB_NOTIFY_TIME", NULL },
00798 { "JOB_NOTIFY_TOTAL_PAGES", notify_one_value },
00799 { "JOB_NOTIFY_PAGES_PRINTED", NULL },
00800 { "JOB_NOTIFY_TOTAL_BYTES", notify_one_value },
00801 { "JOB_NOTIFY_BYTES_PRINTED", NULL },
00802 };
00803
00804
00805
00806
00807
00808
00809 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
00810 {
00811 if ( !ctr )
00812 return;
00813
00814 ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
00815
00816 return;
00817 }
00818
00819
00820
00821
00822
00823 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
00824 {
00825 if ( !ctr )
00826 return;
00827
00828 if ( ctr->ctx )
00829 talloc_destroy(ctr->ctx);
00830
00831 ZERO_STRUCTP(ctr);
00832
00833 return;
00834 }
00835
00836
00837
00838
00839 static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
00840 {
00841 if ( !ctr )
00842 return NULL;
00843
00844 return ctr->ctx;
00845 }
00846
00847
00848
00849
00850 static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
00851 {
00852 if ( !ctr || !ctr->msg_groups )
00853 return NULL;
00854
00855 if ( idx >= ctr->num_groups )
00856 return NULL;
00857
00858 return &ctr->msg_groups[idx];
00859
00860 }
00861
00862
00863
00864
00865
00866 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
00867 {
00868 if ( !ctr )
00869 return 0;
00870
00871 return ctr->num_groups;
00872 }
00873
00874
00875
00876
00877
00878 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
00879 {
00880 SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL;
00881 SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL;
00882 SPOOLSS_NOTIFY_MSG *msg_list = NULL;
00883 int i, new_slot;
00884
00885 if ( !ctr || !msg )
00886 return 0;
00887
00888
00889
00890 for ( i=0; i<ctr->num_groups; i++ ) {
00891 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
00892 break;
00893 }
00894
00895
00896
00897 if ( i == ctr->num_groups ) {
00898 ctr->num_groups++;
00899
00900 if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
00901 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
00902 return 0;
00903 }
00904 ctr->msg_groups = groups;
00905
00906
00907
00908 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
00909 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
00910 }
00911
00912
00913
00914 msg_grp = &ctr->msg_groups[i];
00915
00916 msg_grp->num_msgs++;
00917
00918 if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
00919 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
00920 return 0;
00921 }
00922 msg_grp->msgs = msg_list;
00923
00924 new_slot = msg_grp->num_msgs-1;
00925 memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
00926
00927
00928
00929 if ( msg->len != 0 )
00930 msg_grp->msgs[new_slot].notify.data = (char *)
00931 TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
00932
00933 return ctr->num_groups;
00934 }
00935
00936
00937
00938
00939
00940
00941 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
00942 {
00943 Printer_entry *p;
00944 TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
00945 SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
00946 SPOOLSS_NOTIFY_MSG *messages;
00947 int sending_msg_count;
00948
00949 if ( !msg_group ) {
00950 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
00951 return;
00952 }
00953
00954 messages = msg_group->msgs;
00955
00956 if ( !messages ) {
00957 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
00958 return;
00959 }
00960
00961 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
00962
00963
00964
00965 for (p = printers_list; p; p = p->next) {
00966 SPOOL_NOTIFY_INFO_DATA *data;
00967 uint32 data_len = 0;
00968 uint32 id;
00969 int i;
00970
00971
00972
00973 if ( !p->notify.client_connected )
00974 continue;
00975
00976 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
00977
00978
00979
00980
00981 if ( ( p->printer_type == SPLHND_PRINTER ) &&
00982 ( !strequal(msg_group->printername, p->sharename) ) )
00983 continue;
00984
00985 DEBUG(10,("Our printer\n"));
00986
00987
00988
00989 data = TALLOC_ARRAY( mem_ctx, SPOOL_NOTIFY_INFO_DATA, msg_group->num_msgs);
00990 if (!data) {
00991 return;
00992 }
00993
00994 ZERO_STRUCTP(data);
00995
00996
00997
00998 sending_msg_count = 0;
00999
01000 for ( i=0; i<msg_group->num_msgs; i++ ) {
01001 SPOOLSS_NOTIFY_MSG *msg = &messages[i];
01002
01003
01004
01005 if (!is_monitoring_event(p, msg->type, msg->field))
01006 continue;
01007
01008 sending_msg_count++;
01009
01010
01011 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
01012 msg->type, msg->field, p->sharename));
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027 if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
01028 id = 0;
01029 else
01030 id = msg->id;
01031
01032
01033
01034
01035 if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
01036 id = sysjob_to_jobid(msg->id);
01037
01038 if (id == -1) {
01039 DEBUG(3, ("no such unix jobid %d\n", msg->id));
01040 goto done;
01041 }
01042 }
01043
01044 construct_info_data( &data[data_len], msg->type, msg->field, id );
01045
01046 switch(msg->type) {
01047 case PRINTER_NOTIFY_TYPE:
01048 if ( printer_notify_table[msg->field].fn )
01049 printer_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx);
01050 break;
01051
01052 case JOB_NOTIFY_TYPE:
01053 if ( job_notify_table[msg->field].fn )
01054 job_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx);
01055 break;
01056
01057 default:
01058 DEBUG(5, ("Unknown notification type %d\n", msg->type));
01059 goto done;
01060 }
01061
01062 data_len++;
01063 }
01064
01065 if ( sending_msg_count ) {
01066 rpccli_spoolss_rrpcn( notify_cli_pipe, mem_ctx, &p->notify.client_hnd,
01067 data_len, data, p->notify.change, 0 );
01068 }
01069 }
01070
01071 done:
01072 DEBUG(8,("send_notify2_changes: Exit...\n"));
01073 return;
01074 }
01075
01076
01077
01078
01079 static BOOL notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
01080 {
01081
01082 uint32 tv_sec, tv_usec;
01083 size_t offset = 0;
01084
01085
01086
01087 offset += tdb_unpack((char *)buf + offset, len - offset, "f",
01088 msg->printer);
01089
01090 offset += tdb_unpack((char *)buf + offset, len - offset, "ddddddd",
01091 &tv_sec, &tv_usec,
01092 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
01093
01094 if (msg->len == 0)
01095 tdb_unpack((char *)buf + offset, len - offset, "dd",
01096 &msg->notify.value[0], &msg->notify.value[1]);
01097 else
01098 tdb_unpack((char *)buf + offset, len - offset, "B",
01099 &msg->len, &msg->notify.data);
01100
01101 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
01102 msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
01103
01104 tv->tv_sec = tv_sec;
01105 tv->tv_usec = tv_usec;
01106
01107 if (msg->len == 0)
01108 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
01109 msg->notify.value[1]));
01110 else
01111 dump_data(3, msg->notify.data, msg->len);
01112
01113 return True;
01114 }
01115
01116
01117
01118
01119
01120 static void receive_notify2_message_list(int msg_type, struct process_id src,
01121 void *msg, size_t len,
01122 void *private_data)
01123 {
01124 size_t msg_count, i;
01125 char *buf = (char *)msg;
01126 char *msg_ptr;
01127 size_t msg_len;
01128 SPOOLSS_NOTIFY_MSG notify;
01129 SPOOLSS_NOTIFY_MSG_CTR messages;
01130 int num_groups;
01131
01132 if (len < 4) {
01133 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
01134 return;
01135 }
01136
01137 msg_count = IVAL(buf, 0);
01138 msg_ptr = buf + 4;
01139
01140 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
01141
01142 if (msg_count == 0) {
01143 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
01144 return;
01145 }
01146
01147
01148
01149 ZERO_STRUCT( messages );
01150 notify_msg_ctr_init( &messages );
01151
01152
01153
01154
01155
01156
01157
01158
01159 for ( i=0; i<msg_count; i++ ) {
01160 struct timeval msg_tv;
01161
01162 if (msg_ptr + 4 - buf > len) {
01163 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
01164 return;
01165 }
01166
01167 msg_len = IVAL(msg_ptr,0);
01168 msg_ptr += 4;
01169
01170 if (msg_ptr + msg_len - buf > len) {
01171 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
01172 return;
01173 }
01174
01175
01176
01177 ZERO_STRUCT( notify );
01178 notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len );
01179 msg_ptr += msg_len;
01180
01181
01182
01183 notify_msg_ctr_addmsg( &messages, ¬ify );
01184
01185
01186
01187 if ( notify.len != 0 )
01188 SAFE_FREE( notify.notify.data );
01189 }
01190
01191
01192
01193 num_groups = notify_msg_ctr_numgroups( &messages );
01194 for ( i=0; i<num_groups; i++ )
01195 send_notify2_changes( &messages, i );
01196
01197
01198
01199
01200 DEBUG(10,("receive_notify2_message_list: processed %u messages\n", (uint32)msg_count ));
01201
01202 notify_msg_ctr_destroy( &messages );
01203
01204 return;
01205 }
01206
01207
01208
01209
01210
01211
01212
01213 static BOOL srv_spoolss_drv_upgrade_printer(char* drivername)
01214 {
01215 int len = strlen(drivername);
01216
01217 if (!len)
01218 return False;
01219
01220 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
01221 drivername));
01222
01223 message_send_pid(pid_to_procid(sys_getpid()),
01224 MSG_PRINTER_DRVUPGRADE, drivername, len+1, False);
01225
01226 return True;
01227 }
01228
01229
01230
01231
01232
01233
01234 void do_drv_upgrade_printer(int msg_type, struct process_id src,
01235 void *buf, size_t len, void *private_data)
01236 {
01237 fstring drivername;
01238 int snum;
01239 int n_services = lp_numservices();
01240
01241 len = MIN(len,sizeof(drivername)-1);
01242 strncpy(drivername, (const char *)buf, len);
01243
01244 DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername ));
01245
01246
01247
01248 for (snum=0; snum<n_services; snum++)
01249 {
01250 if (lp_snum_ok(snum) && lp_print_ok(snum) )
01251 {
01252 WERROR result;
01253 NT_PRINTER_INFO_LEVEL *printer = NULL;
01254
01255 result = get_a_printer(NULL, &printer, 2, lp_const_servicename(snum));
01256 if (!W_ERROR_IS_OK(result))
01257 continue;
01258
01259 if (printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername))
01260 {
01261 DEBUG(6,("Updating printer [%s]\n", printer->info_2->printername));
01262
01263
01264
01265 result = mod_a_printer(printer, 2);
01266 if (!W_ERROR_IS_OK(result)) {
01267 DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
01268 dos_errstr(result)));
01269 }
01270 }
01271
01272 free_a_printer(&printer, 2);
01273 }
01274 }
01275
01276
01277 }
01278
01279
01280
01281
01282
01283
01284 void update_monitored_printq_cache( void )
01285 {
01286 Printer_entry *printer = printers_list;
01287 int snum;
01288
01289
01290
01291 while ( printer )
01292 {
01293 if ( (printer->printer_type == SPLHND_PRINTER)
01294 && printer->notify.client_connected )
01295 {
01296 snum = print_queue_snum(printer->sharename);
01297 print_queue_status( snum, NULL, NULL );
01298 }
01299
01300 printer = printer->next;
01301 }
01302
01303 return;
01304 }
01305
01306
01307
01308
01309
01310
01311 static BOOL srv_spoolss_reset_printerdata(char* drivername)
01312 {
01313 int len = strlen(drivername);
01314
01315 if (!len)
01316 return False;
01317
01318 DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
01319 drivername));
01320
01321 message_send_pid(pid_to_procid(sys_getpid()),
01322 MSG_PRINTERDATA_INIT_RESET, drivername, len+1, False);
01323
01324 return True;
01325 }
01326
01327
01328
01329
01330
01331
01332 void reset_all_printerdata(int msg_type, struct process_id src,
01333 void *buf, size_t len, void *private_data)
01334 {
01335 fstring drivername;
01336 int snum;
01337 int n_services = lp_numservices();
01338
01339 len = MIN( len, sizeof(drivername)-1 );
01340 strncpy( drivername, (const char *)buf, len );
01341
01342 DEBUG(10,("reset_all_printerdata: Got message for new driver [%s]\n", drivername ));
01343
01344
01345
01346 for ( snum=0; snum<n_services; snum++ )
01347 {
01348 if ( lp_snum_ok(snum) && lp_print_ok(snum) )
01349 {
01350 WERROR result;
01351 NT_PRINTER_INFO_LEVEL *printer = NULL;
01352
01353 result = get_a_printer( NULL, &printer, 2, lp_const_servicename(snum) );
01354 if ( !W_ERROR_IS_OK(result) )
01355 continue;
01356
01357
01358
01359
01360
01361
01362 if ( printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername) )
01363 {
01364 DEBUG(6,("reset_all_printerdata: Updating printer [%s]\n", printer->info_2->printername));
01365
01366 if ( !set_driver_init(printer, 2) ) {
01367 DEBUG(5,("reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]!\n",
01368 printer->info_2->printername, printer->info_2->drivername));
01369 }
01370
01371 result = mod_a_printer( printer, 2 );
01372 if ( !W_ERROR_IS_OK(result) ) {
01373 DEBUG(3,("reset_all_printerdata: mod_a_printer() failed! (%s)\n",
01374 get_dos_error_msg(result)));
01375 }
01376 }
01377
01378 free_a_printer( &printer, 2 );
01379 }
01380 }
01381
01382
01383
01384 return;
01385 }
01386
01387
01388
01389
01390
01391 static DEVICEMODE* dup_devicemode(TALLOC_CTX *ctx, DEVICEMODE *devmode)
01392 {
01393 DEVICEMODE *d;
01394 int len;
01395
01396 if (!devmode)
01397 return NULL;
01398
01399 DEBUG (8,("dup_devmode\n"));
01400
01401
01402
01403 d = (DEVICEMODE *)TALLOC_MEMDUP(ctx, devmode, sizeof(DEVICEMODE));
01404 if (!d)
01405 return NULL;
01406
01407
01408
01409 len = unistrlen(devmode->devicename.buffer);
01410 if (len != -1) {
01411 d->devicename.buffer = TALLOC_ARRAY(ctx, uint16, len);
01412 if (!d->devicename.buffer) {
01413 return NULL;
01414 }
01415 if (unistrcpy(d->devicename.buffer, devmode->devicename.buffer) != len)
01416 return NULL;
01417 }
01418
01419
01420 len = unistrlen(devmode->formname.buffer);
01421 if (len != -1) {
01422 d->formname.buffer = TALLOC_ARRAY(ctx, uint16, len);
01423 if (!d->formname.buffer) {
01424 return NULL;
01425 }
01426 if (unistrcpy(d->formname.buffer, devmode->formname.buffer) != len)
01427 return NULL;
01428 }
01429
01430 if (devmode->driverextra) {
01431 d->dev_private = (uint8 *)TALLOC_MEMDUP(ctx, devmode->dev_private,
01432 devmode->driverextra);
01433 if (!d->dev_private) {
01434 return NULL;
01435 }
01436 } else {
01437 d->dev_private = NULL;
01438 }
01439 return d;
01440 }
01441
01442 static void copy_devmode_ctr(TALLOC_CTX *ctx, DEVMODE_CTR *new_ctr, DEVMODE_CTR *ctr)
01443 {
01444 if (!new_ctr || !ctr)
01445 return;
01446
01447 DEBUG(8,("copy_devmode_ctr\n"));
01448
01449 new_ctr->size = ctr->size;
01450 new_ctr->devmode_ptr = ctr->devmode_ptr;
01451
01452 if(ctr->devmode_ptr)
01453 new_ctr->devmode = dup_devicemode(ctx, ctr->devmode);
01454 }
01455
01456 static void copy_printer_default(TALLOC_CTX *ctx, PRINTER_DEFAULT *new_def, PRINTER_DEFAULT *def)
01457 {
01458 if (!new_def || !def)
01459 return;
01460
01461 DEBUG(8,("copy_printer_defaults\n"));
01462
01463 new_def->datatype_ptr = def->datatype_ptr;
01464
01465 if (def->datatype_ptr)
01466 copy_unistr2(&new_def->datatype, &def->datatype);
01467
01468 copy_devmode_ctr(ctx, &new_def->devmode_cont, &def->devmode_cont);
01469
01470 new_def->access_required = def->access_required;
01471 }
01472
01473
01474
01475
01476
01477
01478 static WERROR convert_to_openprinterex(TALLOC_CTX *ctx, SPOOL_Q_OPEN_PRINTER_EX *q_u_ex, SPOOL_Q_OPEN_PRINTER *q_u)
01479 {
01480 if (!q_u_ex || !q_u)
01481 return WERR_OK;
01482
01483 DEBUG(8,("convert_to_openprinterex\n"));
01484
01485 if ( q_u->printername ) {
01486 q_u_ex->printername = TALLOC_ZERO_P( ctx, UNISTR2 );
01487 if (q_u_ex->printername == NULL)
01488 return WERR_NOMEM;
01489 copy_unistr2(q_u_ex->printername, q_u->printername);
01490 }
01491
01492 copy_printer_default(ctx, &q_u_ex->printer_default, &q_u->printer_default);
01493
01494 return WERR_OK;
01495 }
01496
01497
01498
01499
01500
01501
01502
01503 WERROR _spoolss_open_printer(pipes_struct *p, SPOOL_Q_OPEN_PRINTER *q_u, SPOOL_R_OPEN_PRINTER *r_u)
01504 {
01505 SPOOL_Q_OPEN_PRINTER_EX q_u_ex;
01506 SPOOL_R_OPEN_PRINTER_EX r_u_ex;
01507
01508 if (!q_u || !r_u)
01509 return WERR_NOMEM;
01510
01511 ZERO_STRUCT(q_u_ex);
01512 ZERO_STRUCT(r_u_ex);
01513
01514
01515
01516 r_u_ex.status = convert_to_openprinterex(p->mem_ctx, &q_u_ex, q_u);
01517 if (!W_ERROR_IS_OK(r_u_ex.status))
01518 return r_u_ex.status;
01519
01520 r_u_ex.status = _spoolss_open_printer_ex(p, &q_u_ex, &r_u_ex);
01521
01522
01523
01524 memcpy(r_u, &r_u_ex, sizeof(*r_u));
01525
01526 return r_u->status;
01527 }
01528
01529
01530
01531
01532 WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, SPOOL_R_OPEN_PRINTER_EX *r_u)
01533 {
01534 PRINTER_DEFAULT *printer_default = &q_u->printer_default;
01535 POLICY_HND *handle = &r_u->handle;
01536
01537 fstring name;
01538 int snum;
01539 struct current_user user;
01540 Printer_entry *Printer=NULL;
01541
01542 if ( !q_u->printername )
01543 return WERR_INVALID_PRINTER_NAME;
01544
01545
01546
01547
01548 unistr2_to_ascii(name, q_u->printername, sizeof(name)-1);
01549
01550 DEBUGADD(3,("checking name: %s\n",name));
01551
01552 if (!open_printer_hnd(p, handle, name, 0))
01553 return WERR_INVALID_PRINTER_NAME;
01554
01555 Printer=find_printer_index_by_hnd(p, handle);
01556 if ( !Printer ) {
01557 DEBUG(0,(" _spoolss_open_printer_ex: logic error. Can't find printer "
01558 "handle we created for printer %s\n", name ));
01559 close_printer_handle(p,handle);
01560 return WERR_INVALID_PRINTER_NAME;
01561 }
01562
01563 get_current_user(&user, p);
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589 switch (Printer->printer_type )
01590 {
01591 case SPLHND_SERVER:
01592 case SPLHND_PORTMON_TCP:
01593 case SPLHND_PORTMON_LOCAL:
01594
01595
01596 snum = -1;
01597
01598
01599
01600 se_map_standard(&printer_default->access_required,
01601 &printserver_std_mapping);
01602
01603
01604
01605
01606 printer_default->access_required &= SPECIFIC_RIGHTS_MASK;
01607
01608 if (printer_default->access_required &
01609 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
01610 DEBUG(3, ("access DENIED for non-printserver bits\n"));
01611 close_printer_handle(p, handle);
01612 return WERR_ACCESS_DENIED;
01613 }
01614
01615
01616
01617 if ( printer_default->access_required & SERVER_ACCESS_ADMINISTER )
01618 {
01619 SE_PRIV se_printop = SE_PRINT_OPERATOR;
01620
01621 if (!lp_ms_add_printer_wizard()) {
01622 close_printer_handle(p, handle);
01623 return WERR_ACCESS_DENIED;
01624 }
01625
01626
01627
01628
01629 if ((user.ut.uid != 0) &&
01630 !user_has_privileges(user.nt_user_token,
01631 &se_printop ) &&
01632 !token_contains_name_in_list(
01633 uidtoname(user.ut.uid), NULL,
01634 user.nt_user_token,
01635 lp_printer_admin(snum))) {
01636 close_printer_handle(p, handle);
01637 return WERR_ACCESS_DENIED;
01638 }
01639
01640 printer_default->access_required = SERVER_ACCESS_ADMINISTER;
01641 }
01642 else
01643 {
01644 printer_default->access_required = SERVER_ACCESS_ENUMERATE;
01645 }
01646
01647 DEBUG(4,("Setting print server access = %s\n", (printer_default->access_required == SERVER_ACCESS_ADMINISTER)
01648 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
01649
01650
01651 break;
01652
01653 case SPLHND_PRINTER:
01654
01655
01656
01657 if (!get_printer_snum(p, handle, &snum)) {
01658 close_printer_handle(p, handle);
01659 return WERR_BADFID;
01660 }
01661
01662 se_map_standard(&printer_default->access_required, &printer_std_mapping);
01663
01664
01665 if (printer_default->access_required == 0x0)
01666 printer_default->access_required = PRINTER_ACCESS_USE;
01667
01668
01669
01670
01671
01672
01673
01674 if (lp_use_client_driver(snum)
01675 && (printer_default->access_required & PRINTER_ACCESS_ADMINISTER))
01676 {
01677 printer_default->access_required = PRINTER_ACCESS_USE;
01678 }
01679
01680
01681
01682 if ( !check_access(smbd_server_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
01683 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
01684 return WERR_ACCESS_DENIED;
01685 }
01686
01687 if (!user_ok_token(uidtoname(user.ut.uid), user.nt_user_token,
01688 snum) ||
01689 !print_access_check(&user, snum,
01690 printer_default->access_required)) {
01691 DEBUG(3, ("access DENIED for printer open\n"));
01692 close_printer_handle(p, handle);
01693 return WERR_ACCESS_DENIED;
01694 }
01695
01696 if ((printer_default->access_required & SPECIFIC_RIGHTS_MASK)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
01697 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
01698 close_printer_handle(p, handle);
01699 return WERR_ACCESS_DENIED;
01700 }
01701
01702 if (printer_default->access_required & PRINTER_ACCESS_ADMINISTER)
01703 printer_default->access_required = PRINTER_ACCESS_ADMINISTER;
01704 else
01705 printer_default->access_required = PRINTER_ACCESS_USE;
01706
01707 DEBUG(4,("Setting printer access = %s\n", (printer_default->access_required == PRINTER_ACCESS_ADMINISTER)
01708 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
01709
01710 break;
01711
01712 default:
01713
01714 return WERR_BADFID;
01715 }
01716
01717 Printer->access_granted = printer_default->access_required;
01718
01719
01720
01721
01722
01723
01724 if ( (Printer->printer_type != SPLHND_SERVER)
01725 && q_u->printer_default.devmode_cont.devmode_ptr )
01726 {
01727 convert_devicemode( Printer->sharename, q_u->printer_default.devmode_cont.devmode,
01728 &Printer->nt_devmode );
01729 }
01730
01731 #if 0
01732
01733
01734
01735 if ( (printer_default->access_required == PRINTER_ACCESS_ADMINISTER)
01736 && (RA_WIN2K == get_remote_arch()) )
01737 {
01738 DEBUG(10,("_spoolss_open_printer_ex: Enabling LAN/WAN hack for Win2k clients.\n"));
01739 sys_usleep( 500000 );
01740 }
01741 #endif
01742
01743 return WERR_OK;
01744 }
01745
01746
01747
01748
01749 static BOOL convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL *uni,
01750 NT_PRINTER_INFO_LEVEL *printer, uint32 level)
01751 {
01752 BOOL ret;
01753
01754 switch (level) {
01755 case 2:
01756
01757
01758
01759
01760 if ( !printer->info_2 ) {
01761 printer->info_2 = TALLOC_ZERO_P( printer, NT_PRINTER_INFO_LEVEL_2 );
01762 if ( !printer->info_2 ) {
01763 DEBUG(0,("convert_printer_info: talloc() failed!\n"));
01764 return False;
01765 }
01766 }
01767
01768 ret = uni_2_asc_printer_info_2(uni->info_2, printer->info_2);
01769 printer->info_2->setuptime = time(NULL);
01770
01771 return ret;
01772 }
01773
01774 return False;
01775 }
01776
01777 static BOOL convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *uni,
01778 NT_PRINTER_DRIVER_INFO_LEVEL *printer, uint32 level)
01779 {
01780 BOOL result = True;
01781
01782 switch (level) {
01783 case 3:
01784 printer->info_3=NULL;
01785 if (!uni_2_asc_printer_driver_3(uni->info_3, &printer->info_3))
01786 result = False;
01787 break;
01788 case 6:
01789 printer->info_6=NULL;
01790 if (!uni_2_asc_printer_driver_6(uni->info_6, &printer->info_6))
01791 result = False;
01792 break;
01793 default:
01794 break;
01795 }
01796
01797 return result;
01798 }
01799
01800 BOOL convert_devicemode(const char *printername, const DEVICEMODE *devmode,
01801 NT_DEVICEMODE **pp_nt_devmode)
01802 {
01803 NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
01804
01805
01806
01807
01808
01809
01810 if (nt_devmode == NULL) {
01811 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
01812 if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
01813 return False;
01814 }
01815
01816 rpcstr_pull(nt_devmode->devicename,devmode->devicename.buffer, 31, -1, 0);
01817 rpcstr_pull(nt_devmode->formname,devmode->formname.buffer, 31, -1, 0);
01818
01819 nt_devmode->specversion=devmode->specversion;
01820 nt_devmode->driverversion=devmode->driverversion;
01821 nt_devmode->size=devmode->size;
01822 nt_devmode->fields=devmode->fields;
01823 nt_devmode->orientation=devmode->orientation;
01824 nt_devmode->papersize=devmode->papersize;
01825 nt_devmode->paperlength=devmode->paperlength;
01826 nt_devmode->paperwidth=devmode->paperwidth;
01827 nt_devmode->scale=devmode->scale;
01828 nt_devmode->copies=devmode->copies;
01829 nt_devmode->defaultsource=devmode->defaultsource;
01830 nt_devmode->printquality=devmode->printquality;
01831 nt_devmode->color=devmode->color;
01832 nt_devmode->duplex=devmode->duplex;
01833 nt_devmode->yresolution=devmode->yresolution;
01834 nt_devmode->ttoption=devmode->ttoption;
01835 nt_devmode->collate=devmode->collate;
01836
01837 nt_devmode->logpixels=devmode->logpixels;
01838 nt_devmode->bitsperpel=devmode->bitsperpel;
01839 nt_devmode->pelswidth=devmode->pelswidth;
01840 nt_devmode->pelsheight=devmode->pelsheight;
01841 nt_devmode->displayflags=devmode->displayflags;
01842 nt_devmode->displayfrequency=devmode->displayfrequency;
01843 nt_devmode->icmmethod=devmode->icmmethod;
01844 nt_devmode->icmintent=devmode->icmintent;
01845 nt_devmode->mediatype=devmode->mediatype;
01846 nt_devmode->dithertype=devmode->dithertype;
01847 nt_devmode->reserved1=devmode->reserved1;
01848 nt_devmode->reserved2=devmode->reserved2;
01849 nt_devmode->panningwidth=devmode->panningwidth;
01850 nt_devmode->panningheight=devmode->panningheight;
01851
01852
01853
01854
01855
01856
01857 if ((devmode->driverextra != 0) && (devmode->dev_private != NULL)) {
01858 SAFE_FREE(nt_devmode->nt_dev_private);
01859 nt_devmode->driverextra=devmode->driverextra;
01860 if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL)
01861 return False;
01862 memcpy(nt_devmode->nt_dev_private, devmode->dev_private, nt_devmode->driverextra);
01863 }
01864
01865 *pp_nt_devmode = nt_devmode;
01866
01867 return True;
01868 }
01869
01870
01871
01872
01873
01874 static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handle)
01875 {
01876 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
01877 int snum;
01878
01879 if (!Printer) {
01880 DEBUG(2,("_spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
01881 return WERR_BADFID;
01882 }
01883
01884 if (!get_printer_snum(p, handle, &snum))
01885 return WERR_BADFID;
01886
01887 Printer->document_started=False;
01888 print_job_end(snum, Printer->jobid,NORMAL_CLOSE);
01889
01890
01891 return WERR_OK;
01892 }
01893
01894
01895
01896
01897
01898 WERROR _spoolss_closeprinter(pipes_struct *p, SPOOL_Q_CLOSEPRINTER *q_u, SPOOL_R_CLOSEPRINTER *r_u)
01899 {
01900 POLICY_HND *handle = &q_u->handle;
01901
01902 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
01903
01904 if (Printer && Printer->document_started)
01905 _spoolss_enddocprinter_internal(p, handle);
01906
01907 if (!close_printer_handle(p, handle))
01908 return WERR_BADFID;
01909
01910
01911
01912
01913
01914
01915 memset(&r_u->handle, '\0', sizeof(r_u->handle));
01916
01917 return WERR_OK;
01918 }
01919
01920
01921
01922
01923
01924
01925 WERROR _spoolss_deleteprinter(pipes_struct *p, SPOOL_Q_DELETEPRINTER *q_u, SPOOL_R_DELETEPRINTER *r_u)
01926 {
01927 POLICY_HND *handle = &q_u->handle;
01928 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
01929 WERROR result;
01930
01931 if (Printer && Printer->document_started)
01932 _spoolss_enddocprinter_internal(p, handle);
01933
01934 memcpy(&r_u->handle, &q_u->handle, sizeof(r_u->handle));
01935
01936 result = delete_printer_handle(p, handle);
01937
01938 update_c_setprinter(False);
01939
01940 return result;
01941 }
01942
01943
01944
01945
01946
01947
01948 static int get_version_id (char * arch)
01949 {
01950 int i;
01951 struct table_node archi_table[]= {
01952
01953 {"Windows 4.0", "WIN40", 0 },
01954 {"Windows NT x86", "W32X86", 2 },
01955 {"Windows NT R4000", "W32MIPS", 2 },
01956 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
01957 {"Windows NT PowerPC", "W32PPC", 2 },
01958 {"Windows IA64", "IA64", 3 },
01959 {"Windows x64", "x64", 3 },
01960 {NULL, "", -1 }
01961 };
01962
01963 for (i=0; archi_table[i].long_archi != NULL; i++)
01964 {
01965 if (strcmp(arch, archi_table[i].long_archi) == 0)
01966 return (archi_table[i].version);
01967 }
01968
01969 return -1;
01970 }
01971
01972
01973
01974
01975
01976 WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER *q_u, SPOOL_R_DELETEPRINTERDRIVER *r_u)
01977 {
01978 fstring driver;
01979 fstring arch;
01980 NT_PRINTER_DRIVER_INFO_LEVEL info;
01981 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k;
01982 int version;
01983 struct current_user user;
01984 WERROR status;
01985 WERROR status_win2k = WERR_ACCESS_DENIED;
01986 SE_PRIV se_printop = SE_PRINT_OPERATOR;
01987
01988 get_current_user(&user, p);
01989
01990
01991
01992
01993 if ( (user.ut.uid != 0)
01994 && !user_has_privileges(user.nt_user_token, &se_printop )
01995 && !token_contains_name_in_list( uidtoname(user.ut.uid),
01996 NULL, user.nt_user_token, lp_printer_admin(-1)) )
01997 {
01998 return WERR_ACCESS_DENIED;
01999 }
02000
02001 unistr2_to_ascii(driver, &q_u->driver, sizeof(driver)-1 );
02002 unistr2_to_ascii(arch, &q_u->arch, sizeof(arch)-1 );
02003
02004
02005
02006 if ((version=get_version_id(arch)) == -1)
02007 return WERR_INVALID_ENVIRONMENT;
02008
02009 ZERO_STRUCT(info);
02010 ZERO_STRUCT(info_win2k);
02011
02012 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version)))
02013 {
02014
02015
02016 if ( version == 2 ) {
02017 version = 3;
02018 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
02019 status = WERR_UNKNOWN_PRINTER_DRIVER;
02020 goto done;
02021 }
02022 }
02023
02024 else {
02025 status = WERR_UNKNOWN_PRINTER_DRIVER;
02026 goto done;
02027 }
02028
02029 }
02030
02031 if (printer_driver_in_use(info.info_3)) {
02032 status = WERR_PRINTER_DRIVER_IN_USE;
02033 goto done;
02034 }
02035
02036 if ( version == 2 )
02037 {
02038 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
02039 {
02040
02041
02042
02043 status_win2k = delete_printer_driver(info_win2k.info_3, &user, 3, False );
02044 free_a_printer_driver( info_win2k, 3 );
02045
02046
02047 if ( !W_ERROR_IS_OK(status_win2k) )
02048 {
02049 status = status_win2k;
02050 goto done;
02051 }
02052 }
02053 }
02054
02055 status = delete_printer_driver(info.info_3, &user, version, False);
02056
02057
02058
02059 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
02060 status = WERR_OK;
02061
02062 done:
02063 free_a_printer_driver( info, 3 );
02064
02065 return status;
02066 }
02067
02068
02069
02070
02071
02072 WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVEREX *q_u, SPOOL_R_DELETEPRINTERDRIVEREX *r_u)
02073 {
02074 fstring driver;
02075 fstring arch;
02076 NT_PRINTER_DRIVER_INFO_LEVEL info;
02077 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k;
02078 int version;
02079 uint32 flags = q_u->delete_flags;
02080 BOOL delete_files;
02081 struct current_user user;
02082 WERROR status;
02083 WERROR status_win2k = WERR_ACCESS_DENIED;
02084 SE_PRIV se_printop = SE_PRINT_OPERATOR;
02085
02086 get_current_user(&user, p);
02087
02088
02089
02090
02091 if ( (user.ut.uid != 0)
02092 && !user_has_privileges(user.nt_user_token, &se_printop )
02093 && !token_contains_name_in_list( uidtoname(user.ut.uid),
02094 NULL, user.nt_user_token, lp_printer_admin(-1)) )
02095 {
02096 return WERR_ACCESS_DENIED;
02097 }
02098
02099 unistr2_to_ascii(driver, &q_u->driver, sizeof(driver)-1 );
02100 unistr2_to_ascii(arch, &q_u->arch, sizeof(arch)-1 );
02101
02102
02103 if ((version=get_version_id(arch)) == -1) {
02104
02105 return WERR_INVALID_ENVIRONMENT;
02106 }
02107
02108 if ( flags & DPD_DELETE_SPECIFIC_VERSION )
02109 version = q_u->version;
02110
02111 ZERO_STRUCT(info);
02112 ZERO_STRUCT(info_win2k);
02113
02114 status = get_a_printer_driver(&info, 3, driver, arch, version);
02115
02116 if ( !W_ERROR_IS_OK(status) )
02117 {
02118
02119
02120
02121
02122
02123
02124 if ( (flags&DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
02125 goto done;
02126
02127
02128
02129 version = 3;
02130 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
02131 status = WERR_UNKNOWN_PRINTER_DRIVER;
02132 goto done;
02133 }
02134 }
02135
02136 if ( printer_driver_in_use(info.info_3) ) {
02137 status = WERR_PRINTER_DRIVER_IN_USE;
02138 goto done;
02139 }
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153 delete_files = flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
02154
02155
02156
02157 if ( delete_files && printer_driver_files_in_use(info.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
02158
02159 status = WERR_ACCESS_DENIED;
02160 goto done;
02161 }
02162
02163
02164
02165
02166 if ( (version == 2) && ((flags&DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
02167 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
02168 {
02169
02170 if ( delete_files && printer_driver_files_in_use(info_win2k.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
02171
02172 free_a_printer_driver( info_win2k, 3 );
02173 status = WERR_ACCESS_DENIED;
02174 goto done;
02175 }
02176
02177
02178
02179
02180 status_win2k = delete_printer_driver(info_win2k.info_3, &user, 3, delete_files);
02181 free_a_printer_driver( info_win2k, 3 );
02182
02183
02184
02185 if ( !W_ERROR_IS_OK(status_win2k) )
02186 goto done;
02187 }
02188 }
02189
02190 status = delete_printer_driver(info.info_3, &user, version, delete_files);
02191
02192 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
02193 status = WERR_OK;
02194 done:
02195 free_a_printer_driver( info, 3 );
02196
02197 return status;
02198 }
02199
02200
02201
02202
02203
02204
02205 static WERROR get_printer_dataex( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL *printer,
02206 const char *key, const char *value, uint32 *type, uint8 **data,
02207 uint32 *needed, uint32 in_size )
02208 {
02209 REGISTRY_VALUE *val;
02210 uint32 size;
02211 int data_len;
02212
02213 if ( !(val = get_printer_data( printer->info_2, key, value)) )
02214 return WERR_BADFILE;
02215
02216 *type = regval_type( val );
02217
02218 DEBUG(5,("get_printer_dataex: allocating %d\n", in_size));
02219
02220 size = regval_size( val );
02221
02222
02223
02224 if ( in_size ) {
02225 data_len = (size > in_size) ? in_size : size*sizeof(uint8);
02226
02227
02228 if ( data_len ) {
02229 if ( (*data = (uint8 *)TALLOC_MEMDUP(ctx, regval_data_p(val), data_len)) == NULL )
02230 return WERR_NOMEM;
02231 }
02232 else {
02233 if ( (*data = (uint8 *)TALLOC_ZERO(ctx, in_size)) == NULL )
02234 return WERR_NOMEM;
02235 }
02236 }
02237 else
02238 *data = NULL;
02239
02240 *needed = size;
02241
02242 DEBUG(5,("get_printer_dataex: copy done\n"));
02243
02244 return WERR_OK;
02245 }
02246
02247
02248
02249
02250
02251 static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value )
02252 {
02253 return delete_printer_data( printer->info_2, key, value );
02254 }
02255
02256
02257
02258
02259
02260 WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value,
02261 uint32 type, uint8 *data, int real_len )
02262 {
02263
02264
02265 return add_printer_data( printer->info_2, key, value, type, data, real_len );
02266 }
02267
02268
02269
02270
02271
02272 static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
02273 {
02274 int i;
02275
02276 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
02277
02278 if (!StrCaseCmp(value, "W3SvcInstalled")) {
02279 *type = REG_DWORD;
02280 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
02281 return WERR_NOMEM;
02282 SIVAL(*data, 0, 0x00);
02283 *needed = 0x4;
02284 return WERR_OK;
02285 }
02286
02287 if (!StrCaseCmp(value, "BeepEnabled")) {
02288 *type = REG_DWORD;
02289 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
02290 return WERR_NOMEM;
02291 SIVAL(*data, 0, 0x00);
02292 *needed = 0x4;
02293 return WERR_OK;
02294 }
02295
02296 if (!StrCaseCmp(value, "EventLog")) {
02297 *type = REG_DWORD;
02298 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
02299 return WERR_NOMEM;
02300
02301 SIVAL(*data, 0, 0x0);
02302 *needed = 0x4;
02303 return WERR_OK;
02304 }
02305
02306 if (!StrCaseCmp(value, "NetPopup")) {
02307 *type = REG_DWORD;
02308 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
02309 return WERR_NOMEM;
02310 SIVAL(*data, 0, 0x00);
02311 *needed = 0x4;
02312 return WERR_OK;
02313 }
02314
02315 if (!StrCaseCmp(value, "MajorVersion")) {
02316 *type = REG_DWORD;
02317 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
02318 return WERR_NOMEM;
02319
02320
02321
02322
02323
02324
02325 if ( RA_WINNT == get_remote_arch() )
02326 SIVAL(*data, 0, 2);
02327 else
02328 SIVAL(*data, 0, 3);
02329
02330 *needed = 0x4;
02331 return WERR_OK;
02332 }
02333
02334 if (!StrCaseCmp(value, "MinorVersion")) {
02335 *type = REG_DWORD;
02336 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
02337 return WERR_NOMEM;
02338 SIVAL(*data, 0, 0);
02339 *needed = 0x4;
02340 return WERR_OK;
02341 }
02342
02343
02344
02345
02346
02347
02348
02349
02350 if (!StrCaseCmp(value, "OSVersion")) {
02351 *type = REG_BINARY;
02352 *needed = 0x114;
02353
02354 if ( !(*data = TALLOC_ZERO_ARRAY(ctx, uint8, (*needed > in_size) ? *needed:in_size )) )
02355 return WERR_NOMEM;
02356
02357 SIVAL(*data, 0, *needed);
02358 SIVAL(*data, 4, 5);
02359 SIVAL(*data, 8, 0);
02360 SIVAL(*data, 12, 2195);
02361
02362
02363
02364 return WERR_OK;
02365 }
02366
02367
02368 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
02369 const char *string="C:\\PRINTERS";
02370 *type = REG_SZ;
02371 *needed = 2*(strlen(string)+1);
02372 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
02373 return WERR_NOMEM;
02374 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
02375
02376
02377 for (i=0; i<strlen(string); i++) {
02378 (*data)[2*i]=string[i];
02379 (*data)[2*i+1]='\0';
02380 }
02381 return WERR_OK;
02382 }
02383
02384 if (!StrCaseCmp(value, "Architecture")) {
02385 const char *string="Windows NT x86";
02386 *type = REG_SZ;
02387 *needed = 2*(strlen(string)+1);
02388 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
02389 return WERR_NOMEM;
02390 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
02391 for (i=0; i<strlen(string); i++) {
02392 (*data)[2*i]=string[i];
02393 (*data)[2*i+1]='\0';
02394 }
02395 return WERR_OK;
02396 }
02397
02398 if (!StrCaseCmp(value, "DsPresent")) {
02399 *type = REG_DWORD;
02400 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
02401 return WERR_NOMEM;
02402
02403
02404
02405
02406 if ( lp_security() == SEC_ADS )
02407 SIVAL(*data, 0, 0x01);
02408 else
02409 SIVAL(*data, 0, 0x00);
02410
02411 *needed = 0x4;
02412 return WERR_OK;
02413 }
02414
02415 if (!StrCaseCmp(value, "DNSMachineName")) {
02416 pstring hostname;
02417
02418 if (!get_mydnsfullname(hostname))
02419 return WERR_BADFILE;
02420 *type = REG_SZ;
02421 *needed = 2*(strlen(hostname)+1);
02422 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
02423 return WERR_NOMEM;
02424 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
02425 for (i=0; i<strlen(hostname); i++) {
02426 (*data)[2*i]=hostname[i];
02427 (*data)[2*i+1]='\0';
02428 }
02429 return WERR_OK;
02430 }
02431
02432
02433 return WERR_BADFILE;
02434 }
02435
02436
02437
02438
02439
02440 WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u)
02441 {
02442 POLICY_HND *handle = &q_u->handle;
02443 UNISTR2 *valuename = &q_u->valuename;
02444 uint32 in_size = q_u->size;
02445 uint32 *type = &r_u->type;
02446 uint32 *out_size = &r_u->size;
02447 uint8 **data = &r_u->data;
02448 uint32 *needed = &r_u->needed;
02449 WERROR status;
02450 fstring value;
02451 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
02452 NT_PRINTER_INFO_LEVEL *printer = NULL;
02453 int snum = 0;
02454
02455
02456
02457
02458
02459
02460
02461
02462 *out_size = in_size;
02463
02464
02465
02466 *needed = 0;
02467 *type = 0;
02468
02469 DEBUG(4,("_spoolss_getprinterdata\n"));
02470
02471 if ( !Printer ) {
02472 DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
02473 status = WERR_BADFID;
02474 goto done;
02475 }
02476
02477 unistr2_to_ascii(value, valuename, sizeof(value)-1);
02478
02479 if ( Printer->printer_type == SPLHND_SERVER )
02480 status = getprinterdata_printer_server( p->mem_ctx, value, type, data, needed, *out_size );
02481 else
02482 {
02483 if ( !get_printer_snum(p,handle, &snum) ) {
02484 status = WERR_BADFID;
02485 goto done;
02486 }
02487
02488 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
02489 if ( !W_ERROR_IS_OK(status) )
02490 goto done;
02491
02492
02493
02494 if ( strequal(value, "ChangeId") ) {
02495 *type = REG_DWORD;
02496 *needed = sizeof(uint32);
02497 if ( (*data = (uint8*)TALLOC(p->mem_ctx, sizeof(uint32))) == NULL) {
02498 status = WERR_NOMEM;
02499 goto done;
02500 }
02501 SIVAL( *data, 0, printer->info_2->changeid );
02502 status = WERR_OK;
02503 }
02504 else
02505 status = get_printer_dataex( p->mem_ctx, printer, SPOOL_PRINTERDATA_KEY, value, type, data, needed, *out_size );
02506 }
02507
02508 if (*needed > *out_size)
02509 status = WERR_MORE_DATA;
02510
02511 done:
02512 if ( !W_ERROR_IS_OK(status) )
02513 {
02514 DEBUG(5, ("error %d: allocating %d\n", W_ERROR_V(status),*out_size));
02515
02516
02517
02518 if ( *out_size ) {
02519 if((*data=(uint8 *)TALLOC_ZERO_ARRAY(p->mem_ctx, uint8, *out_size)) == NULL) {
02520 if ( printer )
02521 free_a_printer( &printer, 2 );
02522 return WERR_NOMEM;
02523 }
02524 } else {
02525 *data = NULL;
02526 }
02527 }
02528
02529
02530
02531 if ( printer )
02532 free_a_printer( &printer, 2 );
02533
02534 return status;
02535 }
02536
02537
02538
02539
02540
02541 static BOOL spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
02542 struct in_addr *client_ip, const char *remote_machine)
02543 {
02544 NTSTATUS ret;
02545 struct cli_state *the_cli;
02546 struct in_addr rm_addr;
02547
02548 if ( is_zero_ip(*client_ip) ) {
02549 if ( !resolve_name( remote_machine, &rm_addr, 0x20) ) {
02550 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
02551 return False;
02552 }
02553
02554 if ( ismyip( rm_addr )) {
02555 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine));
02556 return False;
02557 }
02558 } else {
02559 rm_addr.s_addr = client_ip->s_addr;
02560 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
02561 inet_ntoa(*client_ip) ));
02562 }
02563
02564
02565
02566 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
02567 &rm_addr, 0, "IPC$", "IPC",
02568 "",
02569 "",
02570 "",
02571 0, lp_client_signing(), NULL );
02572
02573 if ( !NT_STATUS_IS_OK( ret ) ) {
02574 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
02575 remote_machine ));
02576 return False;
02577 }
02578
02579 if ( the_cli->protocol != PROTOCOL_NT1 ) {
02580 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
02581 cli_shutdown(the_cli);
02582 return False;
02583 }
02584
02585
02586
02587
02588
02589
02590 if ( !(*pp_pipe = cli_rpc_pipe_open_noauth(the_cli, PI_SPOOLSS, &ret)) ) {
02591 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
02592 remote_machine, nt_errstr(ret)));
02593 cli_shutdown(the_cli);
02594 return False;
02595 }
02596
02597
02598
02599 (*pp_pipe)->cli = the_cli;
02600
02601 return True;
02602 }
02603
02604
02605
02606
02607
02608 static BOOL srv_spoolss_replyopenprinter(int snum, const char *printer,
02609 uint32 localprinter, uint32 type,
02610 POLICY_HND *handle, struct in_addr *client_ip)
02611 {
02612 WERROR result;
02613
02614
02615
02616
02617
02618 if (smb_connections==0) {
02619 fstring unix_printer;
02620
02621 fstrcpy(unix_printer, printer+2);
02622
02623 if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ip, unix_printer ))
02624 return False;
02625
02626 message_register(MSG_PRINTER_NOTIFY2,
02627 receive_notify2_message_list, NULL);
02628
02629
02630 register_message_flags( True, FLAG_MSG_PRINT_NOTIFY );
02631 }
02632
02633
02634
02635
02636
02637
02638 if (!print_notify_register_pid(snum))
02639 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
02640
02641 smb_connections++;
02642
02643 result = rpccli_spoolss_reply_open_printer(notify_cli_pipe, notify_cli_pipe->cli->mem_ctx, printer, localprinter,
02644 type, handle);
02645
02646 if (!W_ERROR_IS_OK(result))
02647 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
02648 dos_errstr(result)));
02649
02650 return (W_ERROR_IS_OK(result));
02651 }
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662
02663
02664 WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u)
02665 {
02666 POLICY_HND *handle = &q_u->handle;
02667 uint32 flags = q_u->flags;
02668 uint32 options = q_u->options;
02669 UNISTR2 *localmachine = &q_u->localmachine;
02670 uint32 printerlocal = q_u->printerlocal;
02671 int snum = -1;
02672 SPOOL_NOTIFY_OPTION *option = q_u->option;
02673 struct in_addr client_ip;
02674
02675
02676
02677 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
02678
02679 if (!Printer) {
02680 DEBUG(2,("_spoolss_rffpcnex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
02681 return WERR_BADFID;
02682 }
02683
02684 Printer->notify.flags=flags;
02685 Printer->notify.options=options;
02686 Printer->notify.printerlocal=printerlocal;
02687
02688 if (Printer->notify.option)
02689 free_spool_notify_option(&Printer->notify.option);
02690
02691 Printer->notify.option=dup_spool_notify_option(option);
02692
02693 unistr2_to_ascii(Printer->notify.localmachine, localmachine,
02694 sizeof(Printer->notify.localmachine)-1);
02695
02696
02697
02698 if ( Printer->printer_type == SPLHND_SERVER)
02699 snum = -1;
02700 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
02701 !get_printer_snum(p, handle, &snum) )
02702 return WERR_BADFID;
02703
02704 client_ip.s_addr = inet_addr(p->conn->client_address);
02705
02706 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
02707 Printer->notify.printerlocal, 1,
02708 &Printer->notify.client_hnd, &client_ip))
02709 return WERR_SERVER_UNAVAILABLE;
02710
02711 Printer->notify.client_connected=True;
02712
02713 return WERR_OK;
02714 }
02715
02716
02717
02718
02719
02720 void spoolss_notify_server_name(int snum,
02721 SPOOL_NOTIFY_INFO_DATA *data,
02722 print_queue_struct *queue,
02723 NT_PRINTER_INFO_LEVEL *printer,
02724 TALLOC_CTX *mem_ctx)
02725 {
02726 pstring temp;
02727 uint32 len;
02728
02729 len = rpcstr_push(temp, printer->info_2->servername, sizeof(temp)-2, STR_TERMINATE);
02730
02731 data->notify_data.data.length = len;
02732 if (len) {
02733 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
02734 if (!data->notify_data.data.string) {
02735 data->notify_data.data.length = 0;
02736 return;
02737 }
02738
02739 memcpy(data->notify_data.data.string, temp, len);
02740 } else {
02741 data->notify_data.data.string = NULL;
02742 }
02743 }
02744
02745
02746
02747
02748
02749 void spoolss_notify_printer_name(int snum,
02750 SPOOL_NOTIFY_INFO_DATA *data,
02751 print_queue_struct *queue,
02752 NT_PRINTER_INFO_LEVEL *printer,
02753 TALLOC_CTX *mem_ctx)
02754 {
02755 pstring temp;
02756 uint32 len;
02757
02758
02759 char *p = strrchr(printer->info_2->printername, '\\');
02760
02761 if (!p) {
02762 p = printer->info_2->printername;
02763 } else {
02764 p++;
02765 }
02766
02767 len = rpcstr_push(temp, p, sizeof(temp)-2, STR_TERMINATE);
02768
02769 data->notify_data.data.length = len;
02770 if (len) {
02771 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
02772 if (!data->notify_data.data.string) {
02773 data->notify_data.data.length = 0;
02774 return;
02775 }
02776 memcpy(data->notify_data.data.string, temp, len);
02777 } else {
02778 data->notify_data.data.string = NULL;
02779 }
02780 }
02781
02782
02783
02784
02785
02786 void spoolss_notify_share_name(int snum,
02787 SPOOL_NOTIFY_INFO_DATA *data,
02788 print_queue_struct *queue,
02789 NT_PRINTER_INFO_LEVEL *printer,
02790 TALLOC_CTX *mem_ctx)
02791 {
02792 pstring temp;
02793 uint32 len;
02794
02795 len = rpcstr_push(temp, lp_servicename(snum), sizeof(temp)-2, STR_TERMINATE);
02796
02797 data->notify_data.data.length = len;
02798 if (len) {
02799 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
02800 if (!data->notify_data.data.string) {
02801 data->notify_data.data.length = 0;
02802 return;
02803 }
02804 memcpy(data->notify_data.data.string, temp, len);
02805 } else {
02806 data->notify_data.data.string = NULL;
02807 }
02808
02809 }
02810
02811
02812
02813
02814
02815 void spoolss_notify_port_name(int snum,
02816 SPOOL_NOTIFY_INFO_DATA *data,
02817 print_queue_struct *queue,
02818 NT_PRINTER_INFO_LEVEL *printer,
02819 TALLOC_CTX *mem_ctx)
02820 {
02821 pstring temp;
02822 uint32 len;
02823
02824
02825
02826 len = rpcstr_push(temp, printer->info_2->portname, sizeof(temp)-2, STR_TERMINATE);
02827
02828 data->notify_data.data.length = len;
02829 if (len) {
02830 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
02831
02832 if (!data->notify_data.data.string) {
02833 data->notify_data.data.length = 0;
02834 return;
02835 }
02836
02837 memcpy(data->notify_data.data.string, temp, len);
02838 } else {
02839 data->notify_data.data.string = NULL;
02840 }
02841 }
02842
02843
02844
02845
02846
02847
02848 void spoolss_notify_driver_name(int snum,
02849 SPOOL_NOTIFY_INFO_DATA *data,
02850 print_queue_struct *queue,
02851 NT_PRINTER_INFO_LEVEL *printer,
02852 TALLOC_CTX *mem_ctx)
02853 {
02854 pstring temp;
02855 uint32 len;
02856
02857 len = rpcstr_push(temp, printer->info_2->drivername, sizeof(temp)-2, STR_TERMINATE);
02858
02859 data->notify_data.data.length = len;
02860 if (len) {
02861 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
02862
02863 if (!data->notify_data.data.string) {
02864 data->notify_data.data.length = 0;
02865 return;
02866 }
02867
02868 memcpy(data->notify_data.data.string, temp, len);
02869 } else {
02870 data->notify_data.data.string = NULL;
02871 }
02872 }
02873
02874
02875
02876
02877
02878 void spoolss_notify_comment(int snum,
02879 SPOOL_NOTIFY_INFO_DATA *data,
02880 print_queue_struct *queue,
02881 NT_PRINTER_INFO_LEVEL *printer,
02882 TALLOC_CTX *mem_ctx)
02883 {
02884 pstring temp;
02885 uint32 len;
02886
02887 if (*printer->info_2->comment == '\0')
02888 len = rpcstr_push(temp, lp_comment(snum), sizeof(temp)-2, STR_TERMINATE);
02889 else
02890 len = rpcstr_push(temp, printer->info_2->comment, sizeof(temp)-2, STR_TERMINATE);
02891
02892 data->notify_data.data.length = len;
02893 if (len) {
02894 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
02895
02896 if (!data->notify_data.data.string) {
02897 data->notify_data.data.length = 0;
02898 return;
02899 }
02900
02901 memcpy(data->notify_data.data.string, temp, len);
02902 } else {
02903 data->notify_data.data.string = NULL;
02904 }
02905 }
02906
02907
02908
02909
02910
02911
02912 void spoolss_notify_location(int snum,
02913 SPOOL_NOTIFY_INFO_DATA *data,
02914 print_queue_struct *queue,
02915 NT_PRINTER_INFO_LEVEL *printer,
02916 TALLOC_CTX *mem_ctx)
02917 {
02918 pstring temp;
02919 uint32 len;
02920
02921 len = rpcstr_push(temp, printer->info_2->location,sizeof(temp)-2, STR_TERMINATE);
02922
02923 data->notify_data.data.length = len;
02924 if (len) {
02925 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
02926
02927 if (!data->notify_data.data.string) {
02928 data->notify_data.data.length = 0;
02929 return;
02930 }
02931
02932 memcpy(data->notify_data.data.string, temp, len);
02933 } else {
02934 data->notify_data.data.string = NULL;
02935 }
02936 }
02937
02938
02939
02940
02941
02942
02943 static void spoolss_notify_devmode(int snum,
02944 SPOOL_NOTIFY_INFO_DATA *data,
02945 print_queue_struct *queue,
02946 NT_PRINTER_INFO_LEVEL *printer,
02947 TALLOC_CTX *mem_ctx)
02948 {
02949
02950 data->notify_data.data.length = 0;
02951 data->notify_data.data.string = NULL;
02952 }
02953
02954
02955
02956
02957
02958 void spoolss_notify_sepfile(int snum,
02959 SPOOL_NOTIFY_INFO_DATA *data,
02960 print_queue_struct *queue,
02961 NT_PRINTER_INFO_LEVEL *printer,
02962 TALLOC_CTX *mem_ctx)
02963 {
02964 pstring temp;
02965 uint32 len;
02966
02967 len = rpcstr_push(temp, printer->info_2->sepfile, sizeof(temp)-2, STR_TERMINATE);
02968
02969 data->notify_data.data.length = len;
02970 if (len) {
02971 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
02972
02973 if (!data->notify_data.data.string) {
02974 data->notify_data.data.length = 0;
02975 return;
02976 }
02977
02978 memcpy(data->notify_data.data.string, temp, len);
02979 } else {
02980 data->notify_data.data.string = NULL;
02981 }
02982 }
02983
02984
02985
02986
02987
02988
02989 void spoolss_notify_print_processor(int snum,
02990 SPOOL_NOTIFY_INFO_DATA *data,
02991 print_queue_struct *queue,
02992 NT_PRINTER_INFO_LEVEL *printer,
02993 TALLOC_CTX *mem_ctx)
02994 {
02995 pstring temp;
02996 uint32 len;
02997
02998 len = rpcstr_push(temp, printer->info_2->printprocessor, sizeof(temp)-2, STR_TERMINATE);
02999
03000 data->notify_data.data.length = len;
03001 if (len) {
03002 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
03003
03004 if (!data->notify_data.data.string) {
03005 data->notify_data.data.length = 0;
03006 return;
03007 }
03008
03009 memcpy(data->notify_data.data.string, temp, len);
03010 } else {
03011 data->notify_data.data.string = NULL;
03012 }
03013 }
03014
03015
03016
03017
03018
03019
03020 void spoolss_notify_parameters(int snum,
03021 SPOOL_NOTIFY_INFO_DATA *data,
03022 print_queue_struct *queue,
03023 NT_PRINTER_INFO_LEVEL *printer,
03024 TALLOC_CTX *mem_ctx)
03025 {
03026 pstring temp;
03027 uint32 len;
03028
03029 len = rpcstr_push(temp, printer->info_2->parameters, sizeof(temp)-2, STR_TERMINATE);
03030
03031 data->notify_data.data.length = len;
03032 if (len) {
03033 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
03034
03035 if (!data->notify_data.data.string) {
03036 data->notify_data.data.length = 0;
03037 return;
03038 }
03039
03040 memcpy(data->notify_data.data.string, temp, len);
03041 } else {
03042 data->notify_data.data.string = NULL;
03043 }
03044 }
03045
03046
03047
03048
03049
03050
03051 void spoolss_notify_datatype(int snum,
03052 SPOOL_NOTIFY_INFO_DATA *data,
03053 print_queue_struct *queue,
03054 NT_PRINTER_INFO_LEVEL *printer,
03055 TALLOC_CTX *mem_ctx)
03056 {
03057 pstring temp;
03058 uint32 len;
03059
03060 len = rpcstr_push(temp, printer->info_2->datatype, sizeof(pstring)-2, STR_TERMINATE);
03061
03062 data->notify_data.data.length = len;
03063 if (len) {
03064 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
03065
03066 if (!data->notify_data.data.string) {
03067 data->notify_data.data.length = 0;
03068 return;
03069 }
03070
03071 memcpy(data->notify_data.data.string, temp, len);
03072 } else {
03073 data->notify_data.data.string = NULL;
03074 }
03075 }
03076
03077
03078
03079
03080
03081
03082
03083 static void spoolss_notify_security_desc(int snum,
03084 SPOOL_NOTIFY_INFO_DATA *data,
03085 print_queue_struct *queue,
03086 NT_PRINTER_INFO_LEVEL *printer,
03087 TALLOC_CTX *mem_ctx)
03088 {
03089 data->notify_data.sd.size = printer->info_2->secdesc_buf->len;
03090 data->notify_data.sd.desc = dup_sec_desc( mem_ctx, printer->info_2->secdesc_buf->sec ) ;
03091 }
03092
03093
03094
03095
03096
03097
03098 void spoolss_notify_attributes(int snum,
03099 SPOOL_NOTIFY_INFO_DATA *data,
03100 print_queue_struct *queue,
03101 NT_PRINTER_INFO_LEVEL *printer,
03102 TALLOC_CTX *mem_ctx)
03103 {
03104 data->notify_data.value[0] = printer->info_2->attributes;
03105 data->notify_data.value[1] = 0;
03106 }
03107
03108
03109
03110
03111
03112 static void spoolss_notify_priority(int snum,
03113 SPOOL_NOTIFY_INFO_DATA *data,
03114 print_queue_struct *queue,
03115 NT_PRINTER_INFO_LEVEL *printer,
03116 TALLOC_CTX *mem_ctx)
03117 {
03118 data->notify_data.value[0] = printer->info_2->priority;
03119 data->notify_data.value[1] = 0;
03120 }
03121
03122
03123
03124
03125
03126 static void spoolss_notify_default_priority(int snum,
03127 SPOOL_NOTIFY_INFO_DATA *data,
03128 print_queue_struct *queue,
03129 NT_PRINTER_INFO_LEVEL *printer,
03130 TALLOC_CTX *mem_ctx)
03131 {
03132 data->notify_data.value[0] = printer->info_2->default_priority;
03133 data->notify_data.value[1] = 0;
03134 }
03135
03136
03137
03138
03139
03140 static void spoolss_notify_start_time(int snum,
03141 SPOOL_NOTIFY_INFO_DATA *data,
03142 print_queue_struct *queue,
03143 NT_PRINTER_INFO_LEVEL *printer,
03144 TALLOC_CTX *mem_ctx)
03145 {
03146 data->notify_data.value[0] = printer->info_2->starttime;
03147 data->notify_data.value[1] = 0;
03148 }
03149
03150
03151
03152
03153
03154 static void spoolss_notify_until_time(int snum,
03155 SPOOL_NOTIFY_INFO_DATA *data,
03156 print_queue_struct *queue,
03157 NT_PRINTER_INFO_LEVEL *printer,
03158 TALLOC_CTX *mem_ctx)
03159 {
03160 data->notify_data.value[0] = printer->info_2->untiltime;
03161 data->notify_data.value[1] = 0;
03162 }
03163
03164
03165
03166
03167
03168 static void spoolss_notify_status(int snum,
03169 SPOOL_NOTIFY_INFO_DATA *data,
03170 print_queue_struct *queue,
03171 NT_PRINTER_INFO_LEVEL *printer,
03172 TALLOC_CTX *mem_ctx)
03173 {
03174 print_status_struct status;
03175
03176 print_queue_length(snum, &status);
03177 data->notify_data.value[0]=(uint32) status.status;
03178 data->notify_data.value[1] = 0;
03179 }
03180
03181
03182
03183
03184
03185 void spoolss_notify_cjobs(int snum,
03186 SPOOL_NOTIFY_INFO_DATA *data,
03187 print_queue_struct *queue,
03188 NT_PRINTER_INFO_LEVEL *printer,
03189 TALLOC_CTX *mem_ctx)
03190 {
03191 data->notify_data.value[0] = print_queue_length(snum, NULL);
03192 data->notify_data.value[1] = 0;
03193 }
03194
03195
03196
03197
03198
03199 static void spoolss_notify_average_ppm(int snum,
03200 SPOOL_NOTIFY_INFO_DATA *data,
03201 print_queue_struct *queue,
03202 NT_PRINTER_INFO_LEVEL *printer,
03203 TALLOC_CTX *mem_ctx)
03204 {
03205
03206
03207 data->notify_data.value[0] = printer->info_2->averageppm;
03208 data->notify_data.value[1] = 0;
03209 }
03210
03211
03212
03213
03214
03215 static void spoolss_notify_username(int snum,
03216 SPOOL_NOTIFY_INFO_DATA *data,
03217 print_queue_struct *queue,
03218 NT_PRINTER_INFO_LEVEL *printer,
03219 TALLOC_CTX *mem_ctx)
03220 {
03221 pstring temp;
03222 uint32 len;
03223
03224 len = rpcstr_push(temp, queue->fs_user, sizeof(temp)-2, STR_TERMINATE);
03225
03226 data->notify_data.data.length = len;
03227 if (len) {
03228 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
03229
03230 if (!data->notify_data.data.string) {
03231 data->notify_data.data.length = 0;
03232 return;
03233 }
03234
03235 memcpy(data->notify_data.data.string, temp, len);
03236 } else {
03237 data->notify_data.data.string = NULL;
03238 }
03239 }
03240
03241
03242
03243
03244
03245 static void spoolss_notify_job_status(int snum,
03246 SPOOL_NOTIFY_INFO_DATA *data,
03247 print_queue_struct *queue,
03248 NT_PRINTER_INFO_LEVEL *printer,
03249 TALLOC_CTX *mem_ctx)
03250 {
03251 data->notify_data.value[0]=nt_printj_status(queue->status);
03252 data->notify_data.value[1] = 0;
03253 }
03254
03255
03256
03257
03258
03259 static void spoolss_notify_job_name(int snum,
03260 SPOOL_NOTIFY_INFO_DATA *data,
03261 print_queue_struct *queue,
03262 NT_PRINTER_INFO_LEVEL *printer,
03263 TALLOC_CTX *mem_ctx)
03264 {
03265 pstring temp;
03266 uint32 len;
03267
03268 len = rpcstr_push(temp, queue->fs_file, sizeof(temp)-2, STR_TERMINATE);
03269
03270 data->notify_data.data.length = len;
03271 if (len) {
03272 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
03273
03274 if (!data->notify_data.data.string) {
03275 data->notify_data.data.length = 0;
03276 return;
03277 }
03278
03279 memcpy(data->notify_data.data.string, temp, len);
03280 } else {
03281 data->notify_data.data.string = NULL;
03282 }
03283 }
03284
03285
03286
03287
03288
03289 static void spoolss_notify_job_status_string(int snum,
03290 SPOOL_NOTIFY_INFO_DATA *data,
03291 print_queue_struct *queue,
03292 NT_PRINTER_INFO_LEVEL *printer,
03293 TALLOC_CTX *mem_ctx)
03294 {
03295
03296
03297
03298
03299 const char *p = "";
03300 pstring temp;
03301 uint32 len;
03302
03303 #if 0
03304 p = "unknown";
03305
03306 switch (queue->status) {
03307 case LPQ_QUEUED:
03308 p = "Queued";
03309 break;
03310 case LPQ_PAUSED:
03311 p = "";
03312 break;
03313 case LPQ_SPOOLING:
03314 p = "Spooling";
03315 break;
03316 case LPQ_PRINTING:
03317 p = "Printing";
03318 break;
03319 }
03320 #endif
03321
03322 len = rpcstr_push(temp, p, sizeof(temp) - 2, STR_TERMINATE);
03323
03324 data->notify_data.data.length = len;
03325 if (len) {
03326 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
03327
03328 if (!data->notify_data.data.string) {
03329 data->notify_data.data.length = 0;
03330 return;
03331 }
03332
03333 memcpy(data->notify_data.data.string, temp, len);
03334 } else {
03335 data->notify_data.data.string = NULL;
03336 }
03337 }
03338
03339
03340
03341
03342
03343 static void spoolss_notify_job_time(int snum,
03344 SPOOL_NOTIFY_INFO_DATA *data,
03345 print_queue_struct *queue,
03346 NT_PRINTER_INFO_LEVEL *printer,
03347 TALLOC_CTX *mem_ctx)
03348 {
03349 data->notify_data.value[0]=0x0;
03350 data->notify_data.value[1]=0;
03351 }
03352
03353
03354
03355
03356
03357 static void spoolss_notify_job_size(int snum,
03358 SPOOL_NOTIFY_INFO_DATA *data,
03359 print_queue_struct *queue,
03360 NT_PRINTER_INFO_LEVEL *printer,
03361 TALLOC_CTX *mem_ctx)
03362 {
03363 data->notify_data.value[0]=queue->size;
03364 data->notify_data.value[1]=0;
03365 }
03366
03367
03368
03369
03370 static void spoolss_notify_total_pages(int snum,
03371 SPOOL_NOTIFY_INFO_DATA *data,
03372 print_queue_struct *queue,
03373 NT_PRINTER_INFO_LEVEL *printer,
03374 TALLOC_CTX *mem_ctx)
03375 {
03376 data->notify_data.value[0]=queue->page_count;
03377 data->notify_data.value[1]=0;
03378 }
03379
03380
03381
03382
03383 static void spoolss_notify_pages_printed(int snum,
03384 SPOOL_NOTIFY_INFO_DATA *data,
03385 print_queue_struct *queue,
03386 NT_PRINTER_INFO_LEVEL *printer,
03387 TALLOC_CTX *mem_ctx)
03388 {
03389 data->notify_data.value[0]=0;
03390 data->notify_data.value[1]=0;
03391 }
03392
03393
03394
03395
03396
03397 static void spoolss_notify_job_position(int snum,
03398 SPOOL_NOTIFY_INFO_DATA *data,
03399 print_queue_struct *queue,
03400 NT_PRINTER_INFO_LEVEL *printer,
03401 TALLOC_CTX *mem_ctx)
03402 {
03403 data->notify_data.value[0]=queue->job;
03404 data->notify_data.value[1]=0;
03405 }
03406
03407
03408
03409
03410
03411 static void spoolss_notify_submitted_time(int snum,
03412 SPOOL_NOTIFY_INFO_DATA *data,
03413 print_queue_struct *queue,
03414 NT_PRINTER_INFO_LEVEL *printer,
03415 TALLOC_CTX *mem_ctx)
03416 {
03417 struct tm *t;
03418 uint32 len;
03419 SYSTEMTIME st;
03420 char *p;
03421
03422 t=gmtime(&queue->time);
03423
03424 len = sizeof(SYSTEMTIME);
03425
03426 data->notify_data.data.length = len;
03427 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
03428
03429 if (!data->notify_data.data.string) {
03430 data->notify_data.data.length = 0;
03431 return;
03432 }
03433
03434 make_systemtime(&st, t);
03435
03436
03437
03438
03439
03440
03441 p = (char *)data->notify_data.data.string;
03442 SSVAL(p, 0, st.year);
03443 SSVAL(p, 2, st.month);
03444 SSVAL(p, 4, st.dayofweek);
03445 SSVAL(p, 6, st.day);
03446 SSVAL(p, 8, st.hour);
03447 SSVAL(p, 10, st.minute);
03448 SSVAL(p, 12, st.second);
03449 SSVAL(p, 14, st.milliseconds);
03450 }
03451
03452 struct s_notify_info_data_table
03453 {
03454 uint16 type;
03455 uint16 field;
03456 const char *name;
03457 uint32 size;
03458 void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data,
03459 print_queue_struct *queue,
03460 NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx);
03461 };
03462
03463
03464
03465
03466
03467 static const struct s_notify_info_data_table notify_info_data_table[] =
03468 {
03469 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_STRING, spoolss_notify_server_name },
03470 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name },
03471 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_STRING, spoolss_notify_share_name },
03472 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name },
03473 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name },
03474 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", NOTIFY_STRING, spoolss_notify_comment },
03475 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", NOTIFY_STRING, spoolss_notify_location },
03476 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode },
03477 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", NOTIFY_STRING, spoolss_notify_sepfile },
03478 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor },
03479 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters },
03480 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype },
03481 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_SECDESC, spoolss_notify_security_desc },
03482 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_ONE_VALUE, spoolss_notify_attributes },
03483 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority },
03484 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_default_priority },
03485 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time },
03486 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time },
03487 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_status },
03488 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_POINTER, NULL },
03489 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", NOTIFY_ONE_VALUE, spoolss_notify_cjobs },
03490 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_ONE_VALUE, spoolss_notify_average_ppm },
03491 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_POINTER, NULL },
03492 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_POINTER, NULL },
03493 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_POINTER, NULL },
03494 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_POINTER, NULL },
03495 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name },
03496 { JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_STRING, spoolss_notify_server_name },
03497 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name },
03498 { JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", NOTIFY_STRING, spoolss_notify_username },
03499 { JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_STRING, spoolss_notify_username },
03500 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype },
03501 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor },
03502 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters },
03503 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name },
03504 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode },
03505 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_job_status },
03506 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", NOTIFY_STRING, spoolss_notify_job_status_string },
03507 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_POINTER, NULL },
03508 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", NOTIFY_STRING, spoolss_notify_job_name },
03509 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority },
03510 { JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", NOTIFY_ONE_VALUE, spoolss_notify_job_position },
03511 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", NOTIFY_POINTER, spoolss_notify_submitted_time },
03512 { JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time },
03513 { JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time },
03514 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", NOTIFY_ONE_VALUE, spoolss_notify_job_time },
03515 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_ONE_VALUE, spoolss_notify_total_pages },
03516 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_ONE_VALUE, spoolss_notify_pages_printed },
03517 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_ONE_VALUE, spoolss_notify_job_size },
03518 { PRINT_TABLE_END, 0x0, NULL, 0x0, NULL },
03519 };
03520
03521
03522
03523
03524
03525 static uint32 size_of_notify_info_data(uint16 type, uint16 field)
03526 {
03527 int i=0;
03528
03529 for (i = 0; i < (sizeof(notify_info_data_table)/sizeof(struct s_notify_info_data_table)); i++) {
03530 if ( (notify_info_data_table[i].type == type)
03531 && (notify_info_data_table[i].field == field) ) {
03532 switch(notify_info_data_table[i].size) {
03533 case NOTIFY_ONE_VALUE:
03534 case NOTIFY_TWO_VALUE:
03535 return 1;
03536 case NOTIFY_STRING:
03537 return 2;
03538
03539
03540
03541
03542
03543 case NOTIFY_POINTER:
03544 return 4;
03545
03546 case NOTIFY_SECDESC:
03547 return 5;
03548 }
03549 }
03550 }
03551
03552 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
03553
03554 return 0;
03555 }
03556
03557
03558
03559
03560
03561 static uint32 type_of_notify_info_data(uint16 type, uint16 field)
03562 {
03563 uint32 i=0;
03564
03565 for (i = 0; i < (sizeof(notify_info_data_table)/sizeof(struct s_notify_info_data_table)); i++) {
03566 if (notify_info_data_table[i].type == type &&
03567 notify_info_data_table[i].field == field)
03568 return notify_info_data_table[i].size;
03569 }
03570
03571 return 0;
03572 }
03573
03574
03575
03576
03577 static BOOL search_notify(uint16 type, uint16 field, int *value)
03578 {
03579 int i;
03580
03581 for (i = 0; notify_info_data_table[i].type != PRINT_TABLE_END; i++) {
03582 if (notify_info_data_table[i].type == type &&
03583 notify_info_data_table[i].field == field &&
03584 notify_info_data_table[i].fn != NULL) {
03585 *value = i;
03586 return True;
03587 }
03588 }
03589
03590 return False;
03591 }
03592
03593
03594
03595
03596 void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id)
03597 {
03598 info_data->type = type;
03599 info_data->field = field;
03600 info_data->reserved = 0;
03601
03602 info_data->size = size_of_notify_info_data(type, field);
03603 info_data->enc_type = type_of_notify_info_data(type, field);
03604
03605 info_data->id = id;
03606 }
03607
03608
03609
03610
03611
03612
03613
03614 static BOOL construct_notify_printer_info(Printer_entry *print_hnd, SPOOL_NOTIFY_INFO *info, int
03615 snum, SPOOL_NOTIFY_OPTION_TYPE
03616 *option_type, uint32 id,
03617 TALLOC_CTX *mem_ctx)
03618 {
03619 int field_num,j;
03620 uint16 type;
03621 uint16 field;
03622
03623 SPOOL_NOTIFY_INFO_DATA *current_data;
03624 NT_PRINTER_INFO_LEVEL *printer = NULL;
03625 print_queue_struct *queue=NULL;
03626
03627 type=option_type->type;
03628
03629 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
03630 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
03631 option_type->count, lp_servicename(snum)));
03632
03633 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum))))
03634 return False;
03635
03636 for(field_num=0; field_num<option_type->count; field_num++) {
03637 field = option_type->fields[field_num];
03638
03639 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
03640
03641 if (!search_notify(type, field, &j) )
03642 continue;
03643
03644 if((info->data=SMB_REALLOC_ARRAY(info->data, SPOOL_NOTIFY_INFO_DATA, info->count+1)) == NULL) {
03645 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
03646 free_a_printer(&printer, 2);
03647 return False;
03648 }
03649
03650 current_data = &info->data[info->count];
03651
03652 construct_info_data(current_data, type, field, id);
03653
03654 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
03655 notify_info_data_table[j].name, snum, printer->info_2->printername ));
03656
03657 notify_info_data_table[j].fn(snum, current_data, queue,
03658 printer, mem_ctx);
03659
03660 info->count++;
03661 }
03662
03663 free_a_printer(&printer, 2);
03664 return True;
03665 }
03666
03667
03668
03669
03670
03671
03672
03673 static BOOL construct_notify_jobs_info(print_queue_struct *queue,
03674 SPOOL_NOTIFY_INFO *info,
03675 NT_PRINTER_INFO_LEVEL *printer,
03676 int snum, SPOOL_NOTIFY_OPTION_TYPE
03677 *option_type, uint32 id,
03678 TALLOC_CTX *mem_ctx)
03679 {
03680 int field_num,j;
03681 uint16 type;
03682 uint16 field;
03683
03684 SPOOL_NOTIFY_INFO_DATA *current_data;
03685
03686 DEBUG(4,("construct_notify_jobs_info\n"));
03687
03688 type = option_type->type;
03689
03690 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
03691 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
03692 option_type->count));
03693
03694 for(field_num=0; field_num<option_type->count; field_num++) {
03695 field = option_type->fields[field_num];
03696
03697 if (!search_notify(type, field, &j) )
03698 continue;
03699
03700 if((info->data=SMB_REALLOC_ARRAY(info->data, SPOOL_NOTIFY_INFO_DATA, info->count+1)) == NULL) {
03701 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
03702 return False;
03703 }
03704
03705 current_data=&(info->data[info->count]);
03706
03707 construct_info_data(current_data, type, field, id);
03708 notify_info_data_table[j].fn(snum, current_data, queue,
03709 printer, mem_ctx);
03710 info->count++;
03711 }
03712
03713 return True;
03714 }
03715
03716
03717
03718
03719
03720
03721
03722
03723
03724
03725
03726
03727
03728
03729
03730
03731
03732
03733
03734
03735
03736
03737
03738
03739
03740
03741
03742
03743
03744
03745
03746 static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
03747 SPOOL_NOTIFY_INFO *info,
03748 TALLOC_CTX *mem_ctx)
03749 {
03750 int snum;
03751 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
03752 int n_services=lp_numservices();
03753 int i;
03754 SPOOL_NOTIFY_OPTION *option;
03755 SPOOL_NOTIFY_OPTION_TYPE *option_type;
03756
03757 DEBUG(4,("printserver_notify_info\n"));
03758
03759 if (!Printer)
03760 return WERR_BADFID;
03761
03762 option=Printer->notify.option;
03763 info->version=2;
03764 info->data=NULL;
03765 info->count=0;
03766
03767
03768
03769
03770 if ( !option )
03771 return WERR_BADFID;
03772
03773 for (i=0; i<option->count; i++) {
03774 option_type=&(option->ctr.type[i]);
03775
03776 if (option_type->type!=PRINTER_NOTIFY_TYPE)
03777 continue;
03778
03779 for (snum=0; snum<n_services; snum++)
03780 {
03781 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
03782 construct_notify_printer_info ( Printer, info, snum, option_type, snum, mem_ctx );
03783 }
03784 }
03785
03786 #if 0
03787
03788
03789
03790
03791 DEBUG(1,("dumping the NOTIFY_INFO\n"));
03792 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
03793 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
03794
03795 for (i=0; i<info->count; i++) {
03796 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
03797 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
03798 info->data[i].id, info->data[i].size, info->data[i].enc_type));
03799 }
03800 #endif
03801
03802 return WERR_OK;
03803 }
03804
03805
03806
03807
03808
03809
03810
03811 static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info,
03812 TALLOC_CTX *mem_ctx)
03813 {
03814 int snum;
03815 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
03816 int i;
03817 uint32 id;
03818 SPOOL_NOTIFY_OPTION *option;
03819 SPOOL_NOTIFY_OPTION_TYPE *option_type;
03820 int count,j;
03821 print_queue_struct *queue=NULL;
03822 print_status_struct status;
03823
03824 DEBUG(4,("printer_notify_info\n"));
03825
03826 if (!Printer)
03827 return WERR_BADFID;
03828
03829 option=Printer->notify.option;
03830 id = 0x0;
03831 info->version=2;
03832 info->data=NULL;
03833 info->count=0;
03834
03835
03836
03837
03838 if ( !option )
03839 return WERR_BADFID;
03840
03841 get_printer_snum(p, hnd, &snum);
03842
03843 for (i=0; i<option->count; i++) {
03844 option_type=&option->ctr.type[i];
03845
03846 switch ( option_type->type ) {
03847 case PRINTER_NOTIFY_TYPE:
03848 if(construct_notify_printer_info(Printer, info, snum,
03849 option_type, id,
03850 mem_ctx))
03851 id--;
03852 break;
03853
03854 case JOB_NOTIFY_TYPE: {
03855 NT_PRINTER_INFO_LEVEL *printer = NULL;
03856
03857 count = print_queue_status(snum, &queue, &status);
03858
03859 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))))
03860 goto done;
03861
03862 for (j=0; j<count; j++) {
03863 construct_notify_jobs_info(&queue[j], info,
03864 printer, snum,
03865 option_type,
03866 queue[j].job,
03867 mem_ctx);
03868 }
03869
03870 free_a_printer(&printer, 2);
03871
03872 done:
03873 SAFE_FREE(queue);
03874 break;
03875 }
03876 }
03877 }
03878
03879
03880
03881
03882
03883
03884
03885
03886
03887
03888
03889
03890
03891
03892
03893 return WERR_OK;
03894 }
03895
03896
03897
03898
03899
03900 WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u)
03901 {
03902 POLICY_HND *handle = &q_u->handle;
03903 SPOOL_NOTIFY_INFO *info = &r_u->info;
03904
03905 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
03906 WERROR result = WERR_BADFID;
03907
03908
03909 r_u->info_ptr=0x1;
03910
03911 if (!Printer) {
03912 DEBUG(2,("_spoolss_rfnpcnex: Invalid handle (%s:%u:%u).\n",
03913 OUR_HANDLE(handle)));
03914 goto done;
03915 }
03916
03917 DEBUG(4,("Printer type %x\n",Printer->printer_type));
03918
03919
03920
03921
03922
03923
03924
03925
03926
03927
03928
03929 Printer->notify.fnpcn = True;
03930
03931 if (Printer->notify.client_connected) {
03932 DEBUG(10,("_spoolss_rfnpcnex: Saving change value in request [%x]\n", q_u->change));
03933 Printer->notify.change = q_u->change;
03934 }
03935
03936
03937
03938 switch (Printer->printer_type) {
03939 case SPLHND_SERVER:
03940 result = printserver_notify_info(p, handle, info, p->mem_ctx);
03941 break;
03942
03943 case SPLHND_PRINTER:
03944 result = printer_notify_info(p, handle, info, p->mem_ctx);
03945 break;
03946 }
03947
03948 Printer->notify.fnpcn = False;
03949
03950 done:
03951 return result;
03952 }
03953
03954
03955
03956
03957
03958
03959 static BOOL construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *printer, int snum)
03960 {
03961 pstring chaine;
03962 int count;
03963 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
03964 counter_printer_0 *session_counter;
03965 uint32 global_counter;
03966 struct tm *t;
03967 time_t setuptime;
03968 print_status_struct status;
03969
03970 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
03971 return False;
03972
03973 count = print_queue_length(snum, &status);
03974
03975
03976 for(session_counter = counter_list; session_counter; session_counter = session_counter->next) {
03977 if (session_counter->snum == snum)
03978 break;
03979 }
03980
03981
03982 if (session_counter==NULL) {
03983 if((session_counter=SMB_MALLOC_P(counter_printer_0)) == NULL) {
03984 free_a_printer(&ntprinter, 2);
03985 return False;
03986 }
03987 ZERO_STRUCTP(session_counter);
03988 session_counter->snum=snum;
03989 session_counter->counter=0;
03990 DLIST_ADD(counter_list, session_counter);
03991 }
03992
03993
03994 session_counter->counter++;
03995
03996
03997
03998
03999
04000 global_counter=session_counter->counter;
04001
04002 pstrcpy(chaine,ntprinter->info_2->printername);
04003
04004 init_unistr(&printer->printername, chaine);
04005
04006 slprintf(chaine,sizeof(chaine)-1,"\\\\%s", get_server_name(print_hnd));
04007 init_unistr(&printer->servername, chaine);
04008
04009 printer->cjobs = count;
04010 printer->total_jobs = 0;
04011 printer->total_bytes = 0;
04012
04013 setuptime = (time_t)ntprinter->info_2->setuptime;
04014 t=gmtime(&setuptime);
04015
04016 printer->year = t->tm_year+1900;
04017 printer->month = t->tm_mon+1;
04018 printer->dayofweek = t->tm_wday;
04019 printer->day = t->tm_mday;
04020 printer->hour = t->tm_hour;
04021 printer->minute = t->tm_min;
04022 printer->second = t->tm_sec;
04023 printer->milliseconds = 0;
04024
04025 printer->global_counter = global_counter;
04026 printer->total_pages = 0;
04027
04028
04029 printer->major_version = 0x0005;
04030 printer->build_version = 0x0893;
04031
04032 printer->unknown7 = 0x1;
04033 printer->unknown8 = 0x0;
04034 printer->unknown9 = 0x0;
04035 printer->session_counter = session_counter->counter;
04036 printer->unknown11 = 0x0;
04037 printer->printer_errors = 0x0;
04038 printer->unknown13 = 0x0;
04039 printer->unknown14 = 0x1;
04040 printer->unknown15 = 0x024a;
04041 printer->unknown16 = 0x0;
04042 printer->change_id = ntprinter->info_2->changeid;
04043 printer->unknown18 = 0x0;
04044 printer->status = nt_printq_status(status.status);
04045 printer->unknown20 = 0x0;
04046 printer->c_setprinter = get_c_setprinter();
04047 printer->unknown22 = 0x0;
04048 printer->unknown23 = 0x6;
04049 printer->unknown24 = 0;
04050 printer->unknown25 = 0;
04051 printer->unknown26 = 0;
04052 printer->unknown27 = 0;
04053 printer->unknown28 = 0;
04054 printer->unknown29 = 0;
04055
04056 free_a_printer(&ntprinter,2);
04057 return (True);
04058 }
04059
04060
04061
04062
04063
04064 static BOOL construct_printer_info_1(Printer_entry *print_hnd, uint32 flags, PRINTER_INFO_1 *printer, int snum)
04065 {
04066 pstring chaine;
04067 pstring chaine2;
04068 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
04069
04070 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
04071 return False;
04072
04073 printer->flags=flags;
04074
04075 if (*ntprinter->info_2->comment == '\0') {
04076 init_unistr(&printer->comment, lp_comment(snum));
04077 slprintf(chaine,sizeof(chaine)-1,"%s,%s,%s", ntprinter->info_2->printername,
04078 ntprinter->info_2->drivername, lp_comment(snum));
04079 }
04080 else {
04081 init_unistr(&printer->comment, ntprinter->info_2->comment);
04082 slprintf(chaine,sizeof(chaine)-1,"%s,%s,%s", ntprinter->info_2->printername,
04083 ntprinter->info_2->drivername, ntprinter->info_2->comment);
04084 }
04085
04086 slprintf(chaine2,sizeof(chaine)-1,"%s", ntprinter->info_2->printername);
04087
04088 init_unistr(&printer->description, chaine);
04089 init_unistr(&printer->name, chaine2);
04090
04091 free_a_printer(&ntprinter,2);
04092
04093 return True;
04094 }
04095
04096
04097
04098
04099
04100 static void free_dev_mode(DEVICEMODE *dev)
04101 {
04102 if (dev == NULL)
04103 return;
04104
04105 SAFE_FREE(dev->dev_private);
04106 SAFE_FREE(dev);
04107 }
04108
04109
04110
04111
04112
04113
04114
04115 static BOOL convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode )
04116 {
04117 if ( !devmode || !ntdevmode )
04118 return False;
04119
04120 init_unistr(&devmode->devicename, ntdevmode->devicename);
04121
04122 init_unistr(&devmode->formname, ntdevmode->formname);
04123
04124 devmode->specversion = ntdevmode->specversion;
04125 devmode->driverversion = ntdevmode->driverversion;
04126 devmode->size = ntdevmode->size;
04127 devmode->driverextra = ntdevmode->driverextra;
04128 devmode->fields = ntdevmode->fields;
04129
04130 devmode->orientation = ntdevmode->orientation;
04131 devmode->papersize = ntdevmode->papersize;
04132 devmode->paperlength = ntdevmode->paperlength;
04133 devmode->paperwidth = ntdevmode->paperwidth;
04134 devmode->scale = ntdevmode->scale;
04135 devmode->copies = ntdevmode->copies;
04136 devmode->defaultsource = ntdevmode->defaultsource;
04137 devmode->printquality = ntdevmode->printquality;
04138 devmode->color = ntdevmode->color;
04139 devmode->duplex = ntdevmode->duplex;
04140 devmode->yresolution = ntdevmode->yresolution;
04141 devmode->ttoption = ntdevmode->ttoption;
04142 devmode->collate = ntdevmode->collate;
04143 devmode->icmmethod = ntdevmode->icmmethod;
04144 devmode->icmintent = ntdevmode->icmintent;
04145 devmode->mediatype = ntdevmode->mediatype;
04146 devmode->dithertype = ntdevmode->dithertype;
04147
04148 if (ntdevmode->nt_dev_private != NULL) {
04149 if ((devmode->dev_private=(uint8 *)memdup(ntdevmode->nt_dev_private, ntdevmode->driverextra)) == NULL)
04150 return False;
04151 }
04152
04153 return True;
04154 }
04155
04156
04157
04158
04159
04160 DEVICEMODE *construct_dev_mode(const char *servicename)
04161 {
04162 NT_PRINTER_INFO_LEVEL *printer = NULL;
04163 DEVICEMODE *devmode = NULL;
04164
04165 DEBUG(7,("construct_dev_mode\n"));
04166
04167 DEBUGADD(8,("getting printer characteristics\n"));
04168
04169 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
04170 return NULL;
04171
04172 if ( !printer->info_2->devmode ) {
04173 DEBUG(5, ("BONG! There was no device mode!\n"));
04174 goto done;
04175 }
04176
04177 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) == NULL) {
04178 DEBUG(2,("construct_dev_mode: malloc fail.\n"));
04179 goto done;
04180 }
04181
04182 ZERO_STRUCTP(devmode);
04183
04184 DEBUGADD(8,("loading DEVICEMODE\n"));
04185
04186 if ( !convert_nt_devicemode( devmode, printer->info_2->devmode ) ) {
04187 free_dev_mode( devmode );
04188 devmode = NULL;
04189 }
04190
04191 done:
04192 free_a_printer(&printer,2);
04193
04194 return devmode;
04195 }
04196
04197
04198
04199
04200
04201
04202 static BOOL construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *printer, int snum)
04203 {
04204 int count;
04205 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
04206
04207 print_status_struct status;
04208
04209 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
04210 return False;
04211
04212 count = print_queue_length(snum, &status);
04213
04214 init_unistr(&printer->servername, ntprinter->info_2->servername);
04215 init_unistr(&printer->printername, ntprinter->info_2->printername);
04216 init_unistr(&printer->sharename, lp_servicename(snum));
04217 init_unistr(&printer->portname, ntprinter->info_2->portname);
04218 init_unistr(&printer->drivername, ntprinter->info_2->drivername);
04219
04220 if (*ntprinter->info_2->comment == '\0')
04221 init_unistr(&printer->comment, lp_comment(snum));
04222 else
04223 init_unistr(&printer->comment, ntprinter->info_2->comment);
04224
04225 init_unistr(&printer->location, ntprinter->info_2->location);
04226 init_unistr(&printer->sepfile, ntprinter->info_2->sepfile);
04227 init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);
04228 init_unistr(&printer->datatype, ntprinter->info_2->datatype);
04229 init_unistr(&printer->parameters, ntprinter->info_2->parameters);
04230
04231 printer->attributes = ntprinter->info_2->attributes;
04232
04233 printer->priority = ntprinter->info_2->priority;
04234 printer->defaultpriority = ntprinter->info_2->default_priority;
04235 printer->starttime = ntprinter->info_2->starttime;
04236 printer->untiltime = ntprinter->info_2->untiltime;
04237 printer->status = nt_printq_status(status.status);
04238 printer->cjobs = count;
04239 printer->averageppm = ntprinter->info_2->averageppm;
04240
04241 if ( !(printer->devmode = construct_dev_mode(
04242 lp_const_servicename(snum))) )
04243 DEBUG(8, ("Returning NULL Devicemode!\n"));
04244
04245 printer->secdesc = NULL;
04246
04247 if ( ntprinter->info_2->secdesc_buf
04248 && ntprinter->info_2->secdesc_buf->len != 0 )
04249 {
04250
04251
04252
04253 printer->secdesc = dup_sec_desc( get_talloc_ctx(),
04254 ntprinter->info_2->secdesc_buf->sec );
04255 }
04256
04257 free_a_printer(&ntprinter, 2);
04258
04259 return True;
04260 }
04261
04262
04263
04264
04265
04266
04267 static BOOL construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **pp_printer, int snum)
04268 {
04269 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
04270 PRINTER_INFO_3 *printer = NULL;
04271
04272 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
04273 return False;
04274
04275 *pp_printer = NULL;
04276 if ((printer = SMB_MALLOC_P(PRINTER_INFO_3)) == NULL) {
04277 DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
04278 free_a_printer(&ntprinter, 2);
04279 return False;
04280 }
04281
04282 ZERO_STRUCTP(printer);
04283
04284
04285
04286 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
04287
04288
04289
04290 printer->secdesc = dup_sec_desc( get_talloc_ctx(),
04291 ntprinter->info_2->secdesc_buf->sec );
04292 }
04293
04294 free_a_printer(&ntprinter, 2);
04295
04296 *pp_printer = printer;
04297 return True;
04298 }
04299
04300
04301
04302
04303
04304
04305 static BOOL construct_printer_info_4(Printer_entry *print_hnd, PRINTER_INFO_4 *printer, int snum)
04306 {
04307 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
04308
04309 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
04310 return False;
04311
04312 init_unistr(&printer->printername, ntprinter->info_2->printername);
04313 init_unistr(&printer->servername, ntprinter->info_2->servername);
04314 printer->attributes = ntprinter->info_2->attributes;
04315
04316 free_a_printer(&ntprinter, 2);
04317 return True;
04318 }
04319
04320
04321
04322
04323
04324
04325 static BOOL construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *printer, int snum)
04326 {
04327 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
04328
04329 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
04330 return False;
04331
04332 init_unistr(&printer->printername, ntprinter->info_2->printername);
04333 init_unistr(&printer->portname, ntprinter->info_2->portname);
04334 printer->attributes = ntprinter->info_2->attributes;
04335
04336
04337
04338 printer->device_not_selected_timeout = 0x0;
04339 printer->transmission_retry_timeout = 0x0;
04340
04341 free_a_printer(&ntprinter, 2);
04342
04343 return True;
04344 }
04345
04346
04347
04348
04349
04350
04351 static BOOL construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum)
04352 {
04353 char *guid_str = NULL;
04354 struct GUID guid;
04355
04356 if (is_printer_published(print_hnd, snum, &guid)) {
04357 asprintf(&guid_str, "{%s}", smb_uuid_string_static(guid));
04358 strupper_m(guid_str);
04359 init_unistr(&printer->guid, guid_str);
04360 printer->action = SPOOL_DS_PUBLISH;
04361 } else {
04362 init_unistr(&printer->guid, "");
04363 printer->action = SPOOL_DS_UNPUBLISH;
04364 }
04365
04366 return True;
04367 }
04368
04369
04370
04371
04372
04373 static WERROR enum_all_printers_info_1(uint32 flags, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
04374 {
04375 int snum;
04376 int i;
04377 int n_services=lp_numservices();
04378 PRINTER_INFO_1 *printers=NULL;
04379 PRINTER_INFO_1 current_prt;
04380 WERROR result = WERR_OK;
04381
04382 DEBUG(4,("enum_all_printers_info_1\n"));
04383
04384 for (snum=0; snum<n_services; snum++) {
04385 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
04386 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
04387
04388 if (construct_printer_info_1(NULL, flags, ¤t_prt, snum)) {
04389 if((printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_1, *returned +1)) == NULL) {
04390 DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
04391 *returned=0;
04392 return WERR_NOMEM;
04393 }
04394 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
04395
04396 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_1));
04397 (*returned)++;
04398 }
04399 }
04400 }
04401
04402
04403 for (i=0; i<*returned; i++)
04404 (*needed) += spoolss_size_printer_info_1(&printers[i]);
04405
04406 if (*needed > offered) {
04407 result = WERR_INSUFFICIENT_BUFFER;
04408 goto out;
04409 }
04410
04411 if (!rpcbuf_alloc_size(buffer, *needed)) {
04412 result = WERR_NOMEM;
04413 goto out;
04414 }
04415
04416
04417 for (i=0; i<*returned; i++)
04418 smb_io_printer_info_1("", buffer, &printers[i], 0);
04419
04420 out:
04421
04422
04423 SAFE_FREE(printers);
04424
04425 if ( !W_ERROR_IS_OK(result) )
04426 *returned = 0;
04427
04428 return result;
04429 }
04430
04431
04432
04433
04434
04435 static WERROR enum_all_printers_info_1_local(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
04436 {
04437 DEBUG(4,("enum_all_printers_info_1_local\n"));
04438
04439 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
04440 }
04441
04442
04443
04444
04445
04446 static WERROR enum_all_printers_info_1_name(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
04447 {
04448 char *s = name;
04449
04450 DEBUG(4,("enum_all_printers_info_1_name\n"));
04451
04452 if ((name[0] == '\\') && (name[1] == '\\'))
04453 s = name + 2;
04454
04455 if (is_myname_or_ipaddr(s)) {
04456 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
04457 }
04458 else
04459 return WERR_INVALID_NAME;
04460 }
04461
04462 #if 0
04463
04464
04465
04466
04467 static WERROR enum_all_printers_info_1_remote(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
04468 {
04469 PRINTER_INFO_1 *printer;
04470 fstring printername;
04471 fstring desc;
04472 fstring comment;
04473 DEBUG(4,("enum_all_printers_info_1_remote\n"));
04474 WERROR result = WERR_OK;
04475
04476
04477
04478
04479
04480
04481
04482
04483
04484 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
04485 return WERR_NOMEM;
04486
04487 *returned=1;
04488
04489 slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", name);
04490 slprintf(desc, sizeof(desc)-1,"%s", name);
04491 slprintf(comment, sizeof(comment)-1, "Logged on Domain");
04492
04493 init_unistr(&printer->description, desc);
04494 init_unistr(&printer->name, printername);
04495 init_unistr(&printer->comment, comment);
04496 printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER;
04497
04498
04499 *needed += spoolss_size_printer_info_1(printer);
04500
04501 if (*needed > offered) {
04502 result = WERR_INSUFFICIENT_BUFFER;
04503 goto out;
04504 }
04505
04506 if (!rpcbuf_alloc_size(buffer, *needed)) {
04507 result = WERR_NOMEM;
04508 goto out;
04509 }
04510
04511
04512 smb_io_printer_info_1("", buffer, printer, 0);
04513
04514 out:
04515
04516 SAFE_FREE(printer);
04517
04518 if ( !W_ERROR_IS_OK(result) )
04519 *returned = 0;
04520
04521 return result;
04522 }
04523
04524 #endif
04525
04526
04527
04528
04529
04530 static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
04531 {
04532 char *s = name;
04533
04534 DEBUG(4,("enum_all_printers_info_1_network\n"));
04535
04536
04537
04538
04539
04540
04541
04542
04543
04544 if (name[0] == '\\' && name[1] == '\\')
04545 s = name + 2;
04546
04547 if (is_myname_or_ipaddr(s))
04548 return WERR_CAN_NOT_COMPLETE;
04549
04550 return enum_all_printers_info_1(PRINTER_ENUM_UNKNOWN_8, buffer, offered, needed, returned);
04551 }
04552
04553
04554
04555
04556
04557
04558
04559 static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
04560 {
04561 int snum;
04562 int i;
04563 int n_services=lp_numservices();
04564 PRINTER_INFO_2 *printers=NULL;
04565 PRINTER_INFO_2 current_prt;
04566 WERROR result = WERR_OK;
04567
04568 *returned = 0;
04569
04570 for (snum=0; snum<n_services; snum++) {
04571 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
04572 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
04573
04574 if (construct_printer_info_2(NULL, ¤t_prt, snum)) {
04575 if ( !(printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) ) {
04576 DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
04577 *returned = 0;
04578 return WERR_NOMEM;
04579 }
04580
04581 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned + 1));
04582
04583 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2));
04584
04585 (*returned)++;
04586 }
04587 }
04588 }
04589
04590
04591 for (i=0; i<*returned; i++)
04592 (*needed) += spoolss_size_printer_info_2(&printers[i]);
04593
04594 if (*needed > offered) {
04595 result = WERR_INSUFFICIENT_BUFFER;
04596 goto out;
04597 }
04598
04599 if (!rpcbuf_alloc_size(buffer, *needed)) {
04600 result = WERR_NOMEM;
04601 goto out;
04602 }
04603
04604
04605 for (i=0; i<*returned; i++)
04606 smb_io_printer_info_2("", buffer, &(printers[i]), 0);
04607
04608 out:
04609
04610
04611 for (i=0; i<*returned; i++)
04612 free_devmode(printers[i].devmode);
04613
04614 SAFE_FREE(printers);
04615
04616 if ( !W_ERROR_IS_OK(result) )
04617 *returned = 0;
04618
04619 return result;
04620 }
04621
04622
04623
04624
04625
04626 static WERROR enumprinters_level1( uint32 flags, fstring name,
04627 RPC_BUFFER *buffer, uint32 offered,
04628 uint32 *needed, uint32 *returned)
04629 {
04630
04631
04632 if (flags & PRINTER_ENUM_LOCAL)
04633 return enum_all_printers_info_1_local(buffer, offered, needed, returned);
04634
04635 if (flags & PRINTER_ENUM_NAME)
04636 return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
04637
04638 #if 0
04639 if (flags & PRINTER_ENUM_REMOTE)
04640 return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
04641 #endif
04642
04643 if (flags & PRINTER_ENUM_NETWORK)
04644 return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
04645
04646 return WERR_OK;
04647 }
04648
04649
04650
04651
04652
04653 static WERROR enumprinters_level2( uint32 flags, const char *servername,
04654 RPC_BUFFER *buffer, uint32 offered,
04655 uint32 *needed, uint32 *returned)
04656 {
04657 if (flags & PRINTER_ENUM_LOCAL) {
04658 return enum_all_printers_info_2(buffer, offered, needed, returned);
04659 }
04660
04661 if (flags & PRINTER_ENUM_NAME) {
04662 if (is_myname_or_ipaddr(canon_servername(servername)))
04663 return enum_all_printers_info_2(buffer, offered, needed, returned);
04664 else
04665 return WERR_INVALID_NAME;
04666 }
04667
04668 if (flags & PRINTER_ENUM_REMOTE)
04669 return WERR_UNKNOWN_LEVEL;
04670
04671 return WERR_OK;
04672 }
04673
04674
04675
04676
04677
04678 static WERROR enumprinters_level5( uint32 flags, const char *servername,
04679 RPC_BUFFER *buffer, uint32 offered,
04680 uint32 *needed, uint32 *returned)
04681 {
04682
04683 return WERR_OK;
04684 }
04685
04686
04687
04688
04689
04690
04691
04692 WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u)
04693 {
04694 uint32 flags = q_u->flags;
04695 UNISTR2 *servername = &q_u->servername;
04696 uint32 level = q_u->level;
04697 RPC_BUFFER *buffer = NULL;
04698 uint32 offered = q_u->offered;
04699 uint32 *needed = &r_u->needed;
04700 uint32 *returned = &r_u->returned;
04701
04702 fstring name;
04703
04704
04705
04706 if (!q_u->buffer && (offered!=0)) {
04707 return WERR_INVALID_PARAM;
04708 }
04709
04710 rpcbuf_move(q_u->buffer, &r_u->buffer);
04711 buffer = r_u->buffer;
04712
04713 DEBUG(4,("_spoolss_enumprinters\n"));
04714
04715 *needed=0;
04716 *returned=0;
04717
04718
04719
04720
04721
04722
04723
04724
04725
04726
04727
04728
04729
04730
04731 unistr2_to_ascii(name, servername, sizeof(name)-1);
04732 strupper_m(name);
04733
04734 switch (level) {
04735 case 1:
04736 return enumprinters_level1(flags, name, buffer, offered, needed, returned);
04737 case 2:
04738 return enumprinters_level2(flags, name, buffer, offered, needed, returned);
04739 case 5:
04740 return enumprinters_level5(flags, name, buffer, offered, needed, returned);
04741 case 3:
04742 case 4:
04743 break;
04744 }
04745 return WERR_UNKNOWN_LEVEL;
04746 }
04747
04748
04749
04750
04751 static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
04752 {
04753 PRINTER_INFO_0 *printer=NULL;
04754 WERROR result = WERR_OK;
04755
04756 if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL)
04757 return WERR_NOMEM;
04758
04759 construct_printer_info_0(print_hnd, printer, snum);
04760
04761
04762 *needed += spoolss_size_printer_info_0(printer);
04763
04764 if (*needed > offered) {
04765 result = WERR_INSUFFICIENT_BUFFER;
04766 goto out;
04767 }
04768
04769 if (!rpcbuf_alloc_size(buffer, *needed)) {
04770 result = WERR_NOMEM;
04771 goto out;
04772 }
04773
04774
04775 smb_io_printer_info_0("", buffer, printer, 0);
04776
04777 out:
04778
04779
04780 SAFE_FREE(printer);
04781
04782 return result;
04783 }
04784
04785
04786
04787
04788 static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
04789 {
04790 PRINTER_INFO_1 *printer=NULL;
04791 WERROR result = WERR_OK;
04792
04793 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
04794 return WERR_NOMEM;
04795
04796 construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, snum);
04797
04798
04799 *needed += spoolss_size_printer_info_1(printer);
04800
04801 if (*needed > offered) {
04802 result = WERR_INSUFFICIENT_BUFFER;
04803 goto out;
04804 }
04805
04806 if (!rpcbuf_alloc_size(buffer, *needed)) {
04807 result = WERR_NOMEM;
04808 goto out;
04809 }
04810
04811
04812 smb_io_printer_info_1("", buffer, printer, 0);
04813
04814 out:
04815
04816 SAFE_FREE(printer);
04817
04818 return result;
04819 }
04820
04821
04822
04823
04824 static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
04825 {
04826 PRINTER_INFO_2 *printer=NULL;
04827 WERROR result = WERR_OK;
04828
04829 if((printer=SMB_MALLOC_P(PRINTER_INFO_2))==NULL)
04830 return WERR_NOMEM;
04831
04832 construct_printer_info_2(print_hnd, printer, snum);
04833
04834
04835 *needed += spoolss_size_printer_info_2(printer);
04836
04837 if (*needed > offered) {
04838 result = WERR_INSUFFICIENT_BUFFER;
04839 goto out;
04840 }
04841
04842 if (!rpcbuf_alloc_size(buffer, *needed)) {
04843 result = WERR_NOMEM;
04844 goto out;
04845 }
04846
04847
04848 if (!smb_io_printer_info_2("", buffer, printer, 0))
04849 result = WERR_NOMEM;
04850
04851 out:
04852
04853 free_printer_info_2(printer);
04854
04855 return result;
04856 }
04857
04858
04859
04860
04861 static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
04862 {
04863 PRINTER_INFO_3 *printer=NULL;
04864 WERROR result = WERR_OK;
04865
04866 if (!construct_printer_info_3(print_hnd, &printer, snum))
04867 return WERR_NOMEM;
04868
04869
04870 *needed += spoolss_size_printer_info_3(printer);
04871
04872 if (*needed > offered) {
04873 result = WERR_INSUFFICIENT_BUFFER;
04874 goto out;
04875 }
04876
04877 if (!rpcbuf_alloc_size(buffer, *needed)) {
04878 result = WERR_NOMEM;
04879 goto out;
04880 }
04881
04882
04883 smb_io_printer_info_3("", buffer, printer, 0);
04884
04885 out:
04886
04887 free_printer_info_3(printer);
04888
04889 return result;
04890 }
04891
04892
04893
04894
04895 static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
04896 {
04897 PRINTER_INFO_4 *printer=NULL;
04898 WERROR result = WERR_OK;
04899
04900 if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL)
04901 return WERR_NOMEM;
04902
04903 if (!construct_printer_info_4(print_hnd, printer, snum)) {
04904 SAFE_FREE(printer);
04905 return WERR_NOMEM;
04906 }
04907
04908
04909 *needed += spoolss_size_printer_info_4(printer);
04910
04911 if (*needed > offered) {
04912 result = WERR_INSUFFICIENT_BUFFER;
04913 goto out;
04914 }
04915
04916 if (!rpcbuf_alloc_size(buffer, *needed)) {
04917 result = WERR_NOMEM;
04918 goto out;
04919 }
04920
04921
04922 smb_io_printer_info_4("", buffer, printer, 0);
04923
04924 out:
04925
04926 free_printer_info_4(printer);
04927
04928 return result;
04929 }
04930
04931
04932
04933
04934 static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
04935 {
04936 PRINTER_INFO_5 *printer=NULL;
04937 WERROR result = WERR_OK;
04938
04939 if((printer=SMB_MALLOC_P(PRINTER_INFO_5))==NULL)
04940 return WERR_NOMEM;
04941
04942 if (!construct_printer_info_5(print_hnd, printer, snum)) {
04943 free_printer_info_5(printer);
04944 return WERR_NOMEM;
04945 }
04946
04947
04948 *needed += spoolss_size_printer_info_5(printer);
04949
04950 if (*needed > offered) {
04951 result = WERR_INSUFFICIENT_BUFFER;
04952 goto out;
04953 }
04954
04955 if (!rpcbuf_alloc_size(buffer, *needed)) {
04956 result = WERR_NOMEM;
04957 goto out;
04958 }
04959
04960
04961 smb_io_printer_info_5("", buffer, printer, 0);
04962
04963 out:
04964
04965 free_printer_info_5(printer);
04966
04967 return result;
04968 }
04969
04970 static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
04971 {
04972 PRINTER_INFO_7 *printer=NULL;
04973 WERROR result = WERR_OK;
04974
04975 if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL)
04976 return WERR_NOMEM;
04977
04978 if (!construct_printer_info_7(print_hnd, printer, snum))
04979 return WERR_NOMEM;
04980
04981
04982 *needed += spoolss_size_printer_info_7(printer);
04983
04984 if (*needed > offered) {
04985 result = WERR_INSUFFICIENT_BUFFER;
04986 goto out;
04987 }
04988
04989 if (!rpcbuf_alloc_size(buffer, *needed)) {
04990 result = WERR_NOMEM;
04991 goto out;
04992
04993 }
04994
04995
04996 smb_io_printer_info_7("", buffer, printer, 0);
04997
04998 out:
04999
05000 free_printer_info_7(printer);
05001
05002 return result;
05003 }
05004
05005
05006
05007
05008 WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u)
05009 {
05010 POLICY_HND *handle = &q_u->handle;
05011 uint32 level = q_u->level;
05012 RPC_BUFFER *buffer = NULL;
05013 uint32 offered = q_u->offered;
05014 uint32 *needed = &r_u->needed;
05015 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
05016
05017 int snum;
05018
05019
05020
05021 if (!q_u->buffer && (offered!=0)) {
05022 return WERR_INVALID_PARAM;
05023 }
05024
05025 rpcbuf_move(q_u->buffer, &r_u->buffer);
05026 buffer = r_u->buffer;
05027
05028 *needed=0;
05029
05030 if (!get_printer_snum(p, handle, &snum))
05031 return WERR_BADFID;
05032
05033 switch (level) {
05034 case 0:
05035 return getprinter_level_0(Printer, snum, buffer, offered, needed);
05036 case 1:
05037 return getprinter_level_1(Printer, snum, buffer, offered, needed);
05038 case 2:
05039 return getprinter_level_2(Printer, snum, buffer, offered, needed);
05040 case 3:
05041 return getprinter_level_3(Printer, snum, buffer, offered, needed);
05042 case 4:
05043 return getprinter_level_4(Printer, snum, buffer, offered, needed);
05044 case 5:
05045 return getprinter_level_5(Printer, snum, buffer, offered, needed);
05046 case 7:
05047 return getprinter_level_7(Printer, snum, buffer, offered, needed);
05048 }
05049 return WERR_UNKNOWN_LEVEL;
05050 }
05051
05052
05053
05054
05055
05056 static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername, fstring architecture)
05057 {
05058 init_unistr( &info->name, driver.info_3->name);
05059 }
05060
05061
05062
05063
05064
05065 static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, const char *servername, fstring architecture, uint32 version)
05066 {
05067 NT_PRINTER_INFO_LEVEL *printer = NULL;
05068 NT_PRINTER_DRIVER_INFO_LEVEL driver;
05069
05070 ZERO_STRUCT(driver);
05071
05072 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
05073 return WERR_INVALID_PRINTER_NAME;
05074
05075 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
05076 free_a_printer(&printer, 2);
05077 return WERR_UNKNOWN_PRINTER_DRIVER;
05078 }
05079
05080 fill_printer_driver_info_1(info, driver, servername, architecture);
05081
05082 free_a_printer(&printer,2);
05083
05084 return WERR_OK;
05085 }
05086
05087
05088
05089
05090
05091
05092 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
05093 {
05094 pstring temp;
05095 const char *cservername = canon_servername(servername);
05096
05097 info->version=driver.info_3->cversion;
05098
05099 init_unistr( &info->name, driver.info_3->name );
05100 init_unistr( &info->architecture, driver.info_3->environment );
05101
05102
05103 if (strlen(driver.info_3->driverpath)) {
05104 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", cservername, driver.info_3->driverpath);
05105 init_unistr( &info->driverpath, temp );
05106 } else
05107 init_unistr( &info->driverpath, "" );
05108
05109 if (strlen(driver.info_3->datafile)) {
05110 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", cservername, driver.info_3->datafile);
05111 init_unistr( &info->datafile, temp );
05112 } else
05113 init_unistr( &info->datafile, "" );
05114
05115 if (strlen(driver.info_3->configfile)) {
05116 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", cservername, driver.info_3->configfile);
05117 init_unistr( &info->configfile, temp );
05118 } else
05119 init_unistr( &info->configfile, "" );
05120 }
05121
05122
05123
05124
05125
05126
05127 static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, const char *servername, fstring architecture, uint32 version)
05128 {
05129 NT_PRINTER_INFO_LEVEL *printer = NULL;
05130 NT_PRINTER_DRIVER_INFO_LEVEL driver;
05131
05132 ZERO_STRUCT(printer);
05133 ZERO_STRUCT(driver);
05134
05135 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
05136 return WERR_INVALID_PRINTER_NAME;
05137
05138 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
05139 free_a_printer(&printer, 2);
05140 return WERR_UNKNOWN_PRINTER_DRIVER;
05141 }
05142
05143 fill_printer_driver_info_2(info, driver, servername);
05144
05145 free_a_printer(&printer,2);
05146
05147 return WERR_OK;
05148 }
05149
05150
05151
05152
05153
05154
05155
05156 static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const char *servername)
05157 {
05158 int i=0;
05159 int j=0;
05160 const char *v;
05161 pstring line;
05162
05163 DEBUG(6,("init_unistr_array\n"));
05164 *uni_array=NULL;
05165
05166 while (True)
05167 {
05168 if ( !char_array )
05169 v = "";
05170 else
05171 {
05172 v = char_array[i];
05173 if (!v)
05174 v = "";
05175 }
05176
05177
05178
05179
05180 if ( servername )
05181 slprintf( line, sizeof(line)-1, "\\\\%s%s", canon_servername(servername), v );
05182 else
05183 pstrcpy( line, v );
05184
05185 DEBUGADD(6,("%d:%s:%lu\n", i, line, (unsigned long)strlen(line)));
05186
05187
05188
05189 if ( (*uni_array=SMB_REALLOC_ARRAY(*uni_array, uint16, j+1+strlen(line)+2)) == NULL ) {
05190 DEBUG(2,("init_unistr_array: Realloc error\n" ));
05191 return 0;
05192 }
05193
05194 if ( !strlen(v) )
05195 break;
05196
05197 j += (rpcstr_push((*uni_array+j), line, sizeof(uint16)*strlen(line)+2, STR_TERMINATE) / sizeof(uint16));
05198 i++;
05199 }
05200
05201 if (*uni_array) {
05202
05203 if (!j)
05204 (*uni_array)[j++]=0x0000;
05205 (*uni_array)[j]=0x0000;
05206 }
05207
05208 DEBUGADD(6,("last one:done\n"));
05209
05210
05211
05212 return j+1;
05213 }
05214
05215
05216
05217
05218
05219
05220 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
05221 {
05222 pstring temp;
05223 const char *cservername = canon_servername(servername);
05224
05225 ZERO_STRUCTP(info);
05226
05227 info->version=driver.info_3->cversion;
05228
05229 init_unistr( &info->name, driver.info_3->name );
05230 init_unistr( &info->architecture, driver.info_3->environment );
05231
05232 if (strlen(driver.info_3->driverpath)) {
05233 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", cservername, driver.info_3->driverpath);
05234 init_unistr( &info->driverpath, temp );
05235 } else
05236 init_unistr( &info->driverpath, "" );
05237
05238 if (strlen(driver.info_3->datafile)) {
05239 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", cservername, driver.info_3->datafile);
05240 init_unistr( &info->datafile, temp );
05241 } else
05242 init_unistr( &info->datafile, "" );
05243
05244 if (strlen(driver.info_3->configfile)) {
05245 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", cservername, driver.info_3->configfile);
05246 init_unistr( &info->configfile, temp );
05247 } else
05248 init_unistr( &info->configfile, "" );
05249
05250 if (strlen(driver.info_3->helpfile)) {
05251 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", cservername, driver.info_3->helpfile);
05252 init_unistr( &info->helpfile, temp );
05253 } else
05254 init_unistr( &info->helpfile, "" );
05255
05256 init_unistr( &info->monitorname, driver.info_3->monitorname );
05257 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
05258
05259 info->dependentfiles=NULL;
05260 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, cservername);
05261 }
05262
05263
05264
05265
05266
05267
05268 static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, const char *servername, fstring architecture, uint32 version)
05269 {
05270 NT_PRINTER_INFO_LEVEL *printer = NULL;
05271 NT_PRINTER_DRIVER_INFO_LEVEL driver;
05272 WERROR status;
05273 ZERO_STRUCT(driver);
05274
05275 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
05276 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status)));
05277 if (!W_ERROR_IS_OK(status))
05278 return WERR_INVALID_PRINTER_NAME;
05279
05280 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
05281 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status)));
05282
05283 #if 0
05284
05285
05286
05287
05288
05289
05290
05291
05292
05293 if (!W_ERROR_IS_OK(status)) {
05294
05295
05296
05297 if (version == 3) {
05298
05299 version = 2;
05300 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
05301 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status)));
05302 }
05303 #endif
05304
05305 if (!W_ERROR_IS_OK(status)) {
05306 free_a_printer(&printer,2);
05307 return WERR_UNKNOWN_PRINTER_DRIVER;
05308 }
05309
05310 #if 0
05311 }
05312 #endif
05313
05314
05315 fill_printer_driver_info_3(info, driver, servername);
05316
05317 free_a_printer(&printer,2);
05318
05319 return WERR_OK;
05320 }
05321
05322
05323
05324
05325
05326
05327 static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
05328 {
05329 pstring temp;
05330 fstring nullstr;
05331 const char *cservername = canon_servername(servername);
05332
05333 ZERO_STRUCTP(info);
05334 memset(&nullstr, '\0', sizeof(fstring));
05335
05336 info->version=driver.info_3->cversion;
05337
05338 init_unistr( &info->name, driver.info_3->name );
05339 init_unistr( &info->architecture, driver.info_3->environment );
05340
05341 if (strlen(driver.info_3->driverpath)) {
05342 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", cservername, driver.info_3->driverpath);
05343 init_unistr( &info->driverpath, temp );
05344 } else
05345 init_unistr( &info->driverpath, "" );
05346
05347 if (strlen(driver.info_3->datafile)) {
05348 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", cservername, driver.info_3->datafile);
05349 init_unistr( &info->datafile, temp );
05350 } else
05351 init_unistr( &info->datafile, "" );
05352
05353 if (strlen(driver.info_3->configfile)) {
05354 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", cservername, driver.info_3->configfile);
05355 init_unistr( &info->configfile, temp );
05356 } else
05357 init_unistr( &info->configfile, "" );
05358
05359 if (strlen(driver.info_3->helpfile)) {
05360 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", cservername, driver.info_3->helpfile);
05361 init_unistr( &info->helpfile, temp );
05362 } else
05363 init_unistr( &info->helpfile, "" );
05364
05365 init_unistr( &info->monitorname, driver.info_3->monitorname );
05366 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
05367
05368 info->dependentfiles = NULL;
05369 init_unistr_array( &info->dependentfiles, driver.info_3->dependentfiles, servername );
05370
05371 info->previousdrivernames=NULL;
05372 init_unistr_array(&info->previousdrivernames, &nullstr, servername);
05373
05374 info->driver_date=0;
05375
05376 info->padding=0;
05377 info->driver_version_low=0;
05378 info->driver_version_high=0;
05379
05380 init_unistr( &info->mfgname, "");
05381 init_unistr( &info->oem_url, "");
05382 init_unistr( &info->hardware_id, "");
05383 init_unistr( &info->provider, "");
05384 }
05385
05386
05387
05388
05389
05390
05391 static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum,
05392 const char *servername, fstring architecture, uint32 version)
05393 {
05394 NT_PRINTER_INFO_LEVEL *printer = NULL;
05395 NT_PRINTER_DRIVER_INFO_LEVEL driver;
05396 WERROR status;
05397
05398 ZERO_STRUCT(driver);
05399
05400 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
05401
05402 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status)));
05403
05404 if (!W_ERROR_IS_OK(status))
05405 return WERR_INVALID_PRINTER_NAME;
05406
05407 status = get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
05408
05409 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status)));
05410
05411 if (!W_ERROR_IS_OK(status))
05412 {
05413
05414
05415
05416
05417 if (version < 3) {
05418 free_a_printer(&printer,2);
05419 return WERR_UNKNOWN_PRINTER_DRIVER;
05420 }
05421
05422
05423 version = 2;
05424 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
05425 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status)));
05426 if (!W_ERROR_IS_OK(status)) {
05427 free_a_printer(&printer,2);
05428 return WERR_UNKNOWN_PRINTER_DRIVER;
05429 }
05430 }
05431
05432 fill_printer_driver_info_6(info, driver, servername);
05433
05434 free_a_printer(&printer,2);
05435 free_a_printer_driver(driver, 3);
05436
05437 return WERR_OK;
05438 }
05439
05440
05441
05442
05443 static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
05444 {
05445 SAFE_FREE(info->dependentfiles);
05446 }
05447
05448
05449
05450
05451 static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
05452 {
05453 SAFE_FREE(info->dependentfiles);
05454 }
05455
05456
05457
05458
05459 static WERROR getprinterdriver2_level1(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
05460 {
05461 DRIVER_INFO_1 *info=NULL;
05462 WERROR result;
05463
05464 if((info=SMB_MALLOC_P(DRIVER_INFO_1)) == NULL)
05465 return WERR_NOMEM;
05466
05467 result = construct_printer_driver_info_1(info, snum, servername, architecture, version);
05468 if (!W_ERROR_IS_OK(result))
05469 goto out;
05470
05471
05472 *needed += spoolss_size_printer_driver_info_1(info);
05473
05474 if (*needed > offered) {
05475 result = WERR_INSUFFICIENT_BUFFER;
05476 goto out;
05477 }
05478
05479 if (!rpcbuf_alloc_size(buffer, *needed)) {
05480 result = WERR_NOMEM;
05481 goto out;
05482 }
05483
05484
05485 smb_io_printer_driver_info_1("", buffer, info, 0);
05486
05487 out:
05488
05489 SAFE_FREE(info);
05490
05491 return result;
05492 }
05493
05494
05495
05496
05497 static WERROR getprinterdriver2_level2(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
05498 {
05499 DRIVER_INFO_2 *info=NULL;
05500 WERROR result;
05501
05502 if((info=SMB_MALLOC_P(DRIVER_INFO_2)) == NULL)
05503 return WERR_NOMEM;
05504
05505 result = construct_printer_driver_info_2(info, snum, servername, architecture, version);
05506 if (!W_ERROR_IS_OK(result))
05507 goto out;
05508
05509
05510 *needed += spoolss_size_printer_driver_info_2(info);
05511
05512 if (*needed > offered) {
05513 result = WERR_INSUFFICIENT_BUFFER;
05514 goto out;
05515 }
05516
05517 if (!rpcbuf_alloc_size(buffer, *needed)) {
05518 result = WERR_NOMEM;
05519 goto out;
05520 }
05521
05522
05523 smb_io_printer_driver_info_2("", buffer, info, 0);
05524
05525 out:
05526
05527 SAFE_FREE(info);
05528
05529 return result;
05530 }
05531
05532
05533
05534
05535 static WERROR getprinterdriver2_level3(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
05536 {
05537 DRIVER_INFO_3 info;
05538 WERROR result;
05539
05540 ZERO_STRUCT(info);
05541
05542 result = construct_printer_driver_info_3(&info, snum, servername, architecture, version);
05543 if (!W_ERROR_IS_OK(result))
05544 goto out;
05545
05546
05547 *needed += spoolss_size_printer_driver_info_3(&info);
05548
05549 if (*needed > offered) {
05550 result = WERR_INSUFFICIENT_BUFFER;
05551 goto out;
05552 }
05553
05554 if (!rpcbuf_alloc_size(buffer, *needed)) {
05555 result = WERR_NOMEM;
05556 goto out;
05557 }
05558
05559
05560 smb_io_printer_driver_info_3("", buffer, &info, 0);
05561
05562 out:
05563 free_printer_driver_info_3(&info);
05564
05565 return result;
05566 }
05567
05568
05569
05570
05571 static WERROR getprinterdriver2_level6(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
05572 {
05573 DRIVER_INFO_6 info;
05574 WERROR result;
05575
05576 ZERO_STRUCT(info);
05577
05578 result = construct_printer_driver_info_6(&info, snum, servername, architecture, version);
05579 if (!W_ERROR_IS_OK(result))
05580 goto out;
05581
05582
05583 *needed += spoolss_size_printer_driver_info_6(&info);
05584
05585 if (*needed > offered) {
05586 result = WERR_INSUFFICIENT_BUFFER;
05587 goto out;
05588 }
05589
05590 if (!rpcbuf_alloc_size(buffer, *needed)) {
05591 result = WERR_NOMEM;
05592 goto out;
05593 }
05594
05595
05596 smb_io_printer_driver_info_6("", buffer, &info, 0);
05597
05598 out:
05599 free_printer_driver_info_6(&info);
05600
05601 return result;
05602 }
05603
05604
05605
05606
05607 WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u)
05608 {
05609 POLICY_HND *handle = &q_u->handle;
05610 UNISTR2 *uni_arch = &q_u->architecture;
05611 uint32 level = q_u->level;
05612 uint32 clientmajorversion = q_u->clientmajorversion;
05613 RPC_BUFFER *buffer = NULL;
05614 uint32 offered = q_u->offered;
05615 uint32 *needed = &r_u->needed;
05616 uint32 *servermajorversion = &r_u->servermajorversion;
05617 uint32 *serverminorversion = &r_u->serverminorversion;
05618 Printer_entry *printer;
05619
05620 fstring servername;
05621 fstring architecture;
05622 int snum;
05623
05624
05625
05626 if (!q_u->buffer && (offered!=0)) {
05627 return WERR_INVALID_PARAM;
05628 }
05629
05630 rpcbuf_move(q_u->buffer, &r_u->buffer);
05631 buffer = r_u->buffer;
05632
05633 DEBUG(4,("_spoolss_getprinterdriver2\n"));
05634
05635 if ( !(printer = find_printer_index_by_hnd( p, handle )) ) {
05636 DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n"));
05637 return WERR_INVALID_PRINTER_NAME;
05638 }
05639
05640 *needed = 0;
05641 *servermajorversion = 0;
05642 *serverminorversion = 0;
05643
05644 fstrcpy(servername, get_server_name( printer ));
05645 unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)-1);
05646
05647 if (!get_printer_snum(p, handle, &snum))
05648 return WERR_BADFID;
05649
05650 switch (level) {
05651 case 1:
05652 return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
05653 case 2:
05654 return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
05655 case 3:
05656 return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
05657 case 6:
05658 return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
05659 #if 0
05660 case 101:
05661
05662
05663 break;
05664 #endif
05665 }
05666
05667 return WERR_UNKNOWN_LEVEL;
05668 }
05669
05670
05671
05672
05673 WERROR _spoolss_startpageprinter(pipes_struct *p, SPOOL_Q_STARTPAGEPRINTER *q_u, SPOOL_R_STARTPAGEPRINTER *r_u)
05674 {
05675 POLICY_HND *handle = &q_u->handle;
05676
05677 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
05678
05679 if (!Printer) {
05680 DEBUG(3,("Error in startpageprinter printer handle\n"));
05681 return WERR_BADFID;
05682 }
05683
05684 Printer->page_started=True;
05685 return WERR_OK;
05686 }
05687
05688
05689
05690
05691 WERROR _spoolss_endpageprinter(pipes_struct *p, SPOOL_Q_ENDPAGEPRINTER *q_u, SPOOL_R_ENDPAGEPRINTER *r_u)
05692 {
05693 POLICY_HND *handle = &q_u->handle;
05694 int snum;
05695
05696 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
05697
05698 if (!Printer) {
05699 DEBUG(2,("_spoolss_endpageprinter: Invalid handle (%s:%u:%u).\n",OUR_HANDLE(handle)));
05700 return WERR_BADFID;
05701 }
05702
05703 if (!get_printer_snum(p, handle, &snum))
05704 return WERR_BADFID;
05705
05706 Printer->page_started=False;
05707 print_job_endpage(snum, Printer->jobid);
05708
05709 return WERR_OK;
05710 }
05711
05712
05713
05714
05715
05716
05717
05718 WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, SPOOL_R_STARTDOCPRINTER *r_u)
05719 {
05720 POLICY_HND *handle = &q_u->handle;
05721 DOC_INFO *docinfo = &q_u->doc_info_container.docinfo;
05722 uint32 *jobid = &r_u->jobid;
05723
05724 DOC_INFO_1 *info_1 = &docinfo->doc_info_1;
05725 int snum;
05726 pstring jobname;
05727 fstring datatype;
05728 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
05729 struct current_user user;
05730
05731 if (!Printer) {
05732 DEBUG(2,("_spoolss_startdocprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
05733 return WERR_BADFID;
05734 }
05735
05736 get_current_user(&user, p);
05737
05738
05739
05740
05741
05742
05743
05744
05745
05746 if (info_1->p_datatype != 0) {
05747 unistr2_to_ascii(datatype, &info_1->datatype, sizeof(datatype));
05748 if (strcmp(datatype, "RAW") != 0) {
05749 (*jobid)=0;
05750 return WERR_INVALID_DATATYPE;
05751 }
05752 }
05753
05754
05755 if (!get_printer_snum(p, handle, &snum)) {
05756 return WERR_BADFID;
05757 }
05758
05759 unistr2_to_ascii(jobname, &info_1->docname, sizeof(jobname));
05760
05761 Printer->jobid = print_job_start(&user, snum, jobname, Printer->nt_devmode);
05762
05763
05764
05765
05766 if (Printer->jobid == -1) {
05767 return map_werror_from_unix(errno);
05768 }
05769
05770 Printer->document_started=True;
05771 (*jobid) = Printer->jobid;
05772
05773 return WERR_OK;
05774 }
05775
05776
05777
05778
05779
05780
05781
05782 WERROR _spoolss_enddocprinter(pipes_struct *p, SPOOL_Q_ENDDOCPRINTER *q_u, SPOOL_R_ENDDOCPRINTER *r_u)
05783 {
05784 POLICY_HND *handle = &q_u->handle;
05785
05786 return _spoolss_enddocprinter_internal(p, handle);
05787 }
05788
05789
05790
05791
05792 WERROR _spoolss_writeprinter(pipes_struct *p, SPOOL_Q_WRITEPRINTER *q_u, SPOOL_R_WRITEPRINTER *r_u)
05793 {
05794 POLICY_HND *handle = &q_u->handle;
05795 uint32 buffer_size = q_u->buffer_size;
05796 uint8 *buffer = q_u->buffer;
05797 uint32 *buffer_written = &q_u->buffer_size2;
05798 int snum;
05799 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
05800
05801 if (!Printer) {
05802 DEBUG(2,("_spoolss_writeprinter: Invalid handle (%s:%u:%u)\n",OUR_HANDLE(handle)));
05803 r_u->buffer_written = q_u->buffer_size2;
05804 return WERR_BADFID;
05805 }
05806
05807 if (!get_printer_snum(p, handle, &snum))
05808 return WERR_BADFID;
05809
05810 (*buffer_written) = (uint32)print_job_write(snum, Printer->jobid, (const char *)buffer,
05811 (SMB_OFF_T)-1, (size_t)buffer_size);
05812 if (*buffer_written == (uint32)-1) {
05813 r_u->buffer_written = 0;
05814 if (errno == ENOSPC)
05815 return WERR_NO_SPOOL_SPACE;
05816 else
05817 return WERR_ACCESS_DENIED;
05818 }
05819
05820 r_u->buffer_written = q_u->buffer_size2;
05821
05822 return WERR_OK;
05823 }
05824
05825
05826
05827
05828
05829
05830
05831 static WERROR control_printer(POLICY_HND *handle, uint32 command,
05832 pipes_struct *p)
05833 {
05834 struct current_user user;
05835 int snum;
05836 WERROR errcode = WERR_BADFUNC;
05837 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
05838
05839 get_current_user(&user, p);
05840
05841 if (!Printer) {
05842 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
05843 return WERR_BADFID;
05844 }
05845
05846 if (!get_printer_snum(p, handle, &snum))
05847 return WERR_BADFID;
05848
05849 switch (command) {
05850 case PRINTER_CONTROL_PAUSE:
05851 if (print_queue_pause(&user, snum, &errcode)) {
05852 errcode = WERR_OK;
05853 }
05854 break;
05855 case PRINTER_CONTROL_RESUME:
05856 case PRINTER_CONTROL_UNPAUSE:
05857 if (print_queue_resume(&user, snum, &errcode)) {
05858 errcode = WERR_OK;
05859 }
05860 break;
05861 case PRINTER_CONTROL_PURGE:
05862 if (print_queue_purge(&user, snum, &errcode)) {
05863 errcode = WERR_OK;
05864 }
05865 break;
05866 default:
05867 return WERR_UNKNOWN_LEVEL;
05868 }
05869
05870 return errcode;
05871 }
05872
05873
05874
05875
05876
05877
05878
05879 WERROR _spoolss_abortprinter(pipes_struct *p, SPOOL_Q_ABORTPRINTER *q_u, SPOOL_R_ABORTPRINTER *r_u)
05880 {
05881 POLICY_HND *handle = &q_u->handle;
05882 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
05883 int snum;
05884 struct current_user user;
05885 WERROR errcode = WERR_OK;
05886
05887 if (!Printer) {
05888 DEBUG(2,("_spoolss_abortprinter: Invalid handle (%s:%u:%u)\n",OUR_HANDLE(handle)));
05889 return WERR_BADFID;
05890 }
05891
05892 if (!get_printer_snum(p, handle, &snum))
05893 return WERR_BADFID;
05894
05895 get_current_user( &user, p );
05896
05897 print_job_delete( &user, snum, Printer->jobid, &errcode );
05898
05899 return errcode;
05900 }
05901
05902
05903
05904
05905
05906
05907 static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
05908 const SPOOL_PRINTER_INFO_LEVEL *info,
05909 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
05910 {
05911 SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
05912 WERROR result;
05913 int snum;
05914
05915 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
05916
05917 if (!Printer || !get_printer_snum(p, handle, &snum)) {
05918 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
05919 OUR_HANDLE(handle)));
05920
05921 result = WERR_BADFID;
05922 goto done;
05923 }
05924
05925 if (!secdesc_ctr) {
05926 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
05927 result = WERR_INVALID_PARAM;
05928 goto done;
05929 }
05930
05931
05932
05933
05934
05935
05936 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
05937 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
05938 result = WERR_ACCESS_DENIED;
05939 goto done;
05940 }
05941
05942
05943
05944
05945 nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr);
05946
05947 if (DEBUGLEVEL >= 10) {
05948 SEC_ACL *the_acl;
05949 int i;
05950
05951 the_acl = old_secdesc_ctr->sec->dacl;
05952 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
05953 PRINTERNAME(snum), the_acl->num_aces));
05954
05955 for (i = 0; i < the_acl->num_aces; i++) {
05956 fstring sid_str;
05957
05958 sid_to_string(sid_str, &the_acl->aces[i].trustee);
05959
05960 DEBUG(10, ("%s 0x%08x\n", sid_str,
05961 the_acl->aces[i].access_mask));
05962 }
05963
05964 the_acl = secdesc_ctr->sec->dacl;
05965
05966 if (the_acl) {
05967 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
05968 PRINTERNAME(snum), the_acl->num_aces));
05969
05970 for (i = 0; i < the_acl->num_aces; i++) {
05971 fstring sid_str;
05972
05973 sid_to_string(sid_str, &the_acl->aces[i].trustee);
05974
05975 DEBUG(10, ("%s 0x%08x\n", sid_str,
05976 the_acl->aces[i].access_mask));
05977 }
05978 } else {
05979 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
05980 }
05981 }
05982
05983 new_secdesc_ctr = sec_desc_merge(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
05984 if (!new_secdesc_ctr) {
05985 result = WERR_NOMEM;
05986 goto done;
05987 }
05988
05989 if (sec_desc_equal(new_secdesc_ctr->sec, old_secdesc_ctr->sec)) {
05990 result = WERR_OK;
05991 goto done;
05992 }
05993
05994 result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr);
05995
05996 done:
05997
05998 return result;
05999 }
06000
06001
06002
06003
06004
06005
06006
06007
06008
06009
06010 static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
06011 {
06012 fstring printername;
06013 const char *p;
06014
06015 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
06016 "portname=%s drivername=%s comment=%s location=%s\n",
06017 info->servername, info->printername, info->sharename,
06018 info->portname, info->drivername, info->comment, info->location));
06019
06020
06021 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname());
06022 fstrcpy(info->sharename, lp_servicename(snum));
06023
06024
06025
06026 if ( lp_force_printername(snum) ) {
06027 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
06028 global_myname(), info->sharename );
06029 } else {
06030
06031
06032
06033 fstrcpy( printername, info->printername );
06034 p = printername;
06035 if ( printername[0] == '\\' && printername[1] == '\\' ) {
06036 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
06037 p++;
06038 }
06039
06040 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
06041 global_myname(), p );
06042 }
06043
06044 info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
06045 info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
06046
06047
06048
06049 return True;
06050 }
06051
06052
06053
06054
06055 WERROR add_port_hook(NT_USER_TOKEN *token, const char *portname, const char *uri )
06056 {
06057 char *cmd = lp_addport_cmd();
06058 pstring command;
06059 int ret;
06060 int fd;
06061 SE_PRIV se_printop = SE_PRINT_OPERATOR;
06062 BOOL is_print_op = False;
06063
06064 if ( !*cmd ) {
06065 return WERR_ACCESS_DENIED;
06066 }
06067
06068 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"", cmd, portname, uri );
06069
06070 if ( token )
06071 is_print_op = user_has_privileges( token, &se_printop );
06072
06073 DEBUG(10,("Running [%s]\n", command));
06074
06075
06076
06077 if ( is_print_op )
06078 become_root();
06079
06080 ret = smbrun(command, &fd);
06081
06082 if ( is_print_op )
06083 unbecome_root();
06084
06085
06086
06087 DEBUGADD(10,("returned [%d]\n", ret));
06088
06089 if ( ret != 0 ) {
06090 if (fd != -1)
06091 close(fd);
06092 return WERR_ACCESS_DENIED;
06093 }
06094
06095 return WERR_OK;
06096 }
06097
06098
06099
06100
06101 BOOL add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
06102 {
06103 char *cmd = lp_addprinter_cmd();
06104 char **qlines;
06105 pstring command;
06106 int numlines;
06107 int ret;
06108 int fd;
06109 fstring remote_machine = "%m";
06110 SE_PRIV se_printop = SE_PRINT_OPERATOR;
06111 BOOL is_print_op = False;
06112
06113 standard_sub_basic(current_user_info.smb_name,
06114 current_user_info.domain,
06115 remote_machine,sizeof(remote_machine));
06116
06117 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
06118 cmd, printer->info_2->printername, printer->info_2->sharename,
06119 printer->info_2->portname, printer->info_2->drivername,
06120 printer->info_2->location, printer->info_2->comment, remote_machine);
06121
06122 if ( token )
06123 is_print_op = user_has_privileges( token, &se_printop );
06124
06125 DEBUG(10,("Running [%s]\n", command));
06126
06127
06128
06129 if ( is_print_op )
06130 become_root();
06131
06132 if ( (ret = smbrun(command, &fd)) == 0 ) {
06133
06134 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
06135 }
06136
06137 if ( is_print_op )
06138 unbecome_root();
06139
06140
06141
06142 DEBUGADD(10,("returned [%d]\n", ret));
06143
06144 if ( ret != 0 ) {
06145 if (fd != -1)
06146 close(fd);
06147 return False;
06148 }
06149
06150
06151 reload_services( False );
06152
06153 numlines = 0;
06154
06155 qlines = fd_lines_load(fd, &numlines, 0);
06156 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
06157 close(fd);
06158
06159
06160
06161
06162 if (numlines) {
06163
06164 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
06165 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
06166 }
06167
06168 file_lines_free(qlines);
06169 return True;
06170 }
06171
06172
06173
06174
06175
06176
06177
06178 static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
06179 const SPOOL_PRINTER_INFO_LEVEL *info,
06180 DEVICEMODE *devmode)
06181 {
06182 int snum;
06183 NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
06184 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
06185 WERROR result;
06186 UNISTR2 buffer;
06187 fstring asc_buffer;
06188
06189 DEBUG(8,("update_printer\n"));
06190
06191 result = WERR_OK;
06192
06193 if (!Printer) {
06194 result = WERR_BADFID;
06195 goto done;
06196 }
06197
06198 if (!get_printer_snum(p, handle, &snum)) {
06199 result = WERR_BADFID;
06200 goto done;
06201 }
06202
06203 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))) ||
06204 (!W_ERROR_IS_OK(get_a_printer(Printer, &old_printer, 2, lp_const_servicename(snum))))) {
06205 result = WERR_BADFID;
06206 goto done;
06207 }
06208
06209 DEBUGADD(8,("Converting info_2 struct\n"));
06210
06211
06212
06213
06214
06215
06216
06217 if (!convert_printer_info(info, printer, level)) {
06218 result = WERR_NOMEM;
06219 goto done;
06220 }
06221
06222 if (devmode) {
06223
06224
06225
06226 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
06227 if (!convert_devicemode(printer->info_2->printername, devmode,
06228 &printer->info_2->devmode)) {
06229 result = WERR_NOMEM;
06230 goto done;
06231 }
06232 }
06233
06234
06235
06236 if (!check_printer_ok(printer->info_2, snum)) {
06237 result = WERR_INVALID_PARAM;
06238 goto done;
06239 }
06240
06241
06242
06243
06244
06245
06246 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
06247 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
06248 result = WERR_ACCESS_DENIED;
06249 goto done;
06250 }
06251
06252
06253
06254
06255 if ( *lp_addprinter_cmd()
06256 && (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)
06257 || !strequal(printer->info_2->comment, old_printer->info_2->comment)
06258 || !strequal(printer->info_2->portname, old_printer->info_2->portname)
06259 || !strequal(printer->info_2->location, old_printer->info_2->location)) )
06260 {
06261
06262
06263 if ( !add_printer_hook(p->pipe_user.nt_user_token, printer) ) {
06264 result = WERR_ACCESS_DENIED;
06265 goto done;
06266 }
06267 }
06268
06269
06270
06271
06272
06273
06274 if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername))
06275 {
06276 if (!set_driver_init(printer, 2))
06277 {
06278 DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
06279 printer->info_2->drivername));
06280 }
06281
06282 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
06283 printer->info_2->drivername));
06284
06285 notify_printer_driver(snum, printer->info_2->drivername);
06286 }
06287
06288
06289
06290
06291
06292
06293
06294 if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) {
06295 init_unistr2( &buffer, printer->info_2->comment, UNI_STR_TERMINATE);
06296 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "description",
06297 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
06298
06299 notify_printer_comment(snum, printer->info_2->comment);
06300 }
06301
06302 if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
06303 init_unistr2( &buffer, printer->info_2->sharename, UNI_STR_TERMINATE);
06304 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName",
06305 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
06306
06307 notify_printer_sharename(snum, printer->info_2->sharename);
06308 }
06309
06310 if (!strequal(printer->info_2->printername, old_printer->info_2->printername)) {
06311 char *pname;
06312
06313 if ( (pname = strchr_m( printer->info_2->printername+2, '\\' )) != NULL )
06314 pname++;
06315 else
06316 pname = printer->info_2->printername;
06317
06318
06319 init_unistr2( &buffer, pname, UNI_STR_TERMINATE);
06320 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
06321 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
06322
06323 notify_printer_printername( snum, pname );
06324 }
06325
06326 if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
06327 init_unistr2( &buffer, printer->info_2->portname, UNI_STR_TERMINATE);
06328 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName",
06329 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
06330
06331 notify_printer_port(snum, printer->info_2->portname);
06332 }
06333
06334 if (!strequal(printer->info_2->location, old_printer->info_2->location)) {
06335 init_unistr2( &buffer, printer->info_2->location, UNI_STR_TERMINATE);
06336 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "location",
06337 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
06338
06339 notify_printer_location(snum, printer->info_2->location);
06340 }
06341
06342
06343
06344
06345 init_unistr2( &buffer, global_myname(), UNI_STR_TERMINATE);
06346 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "serverName",
06347 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
06348 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shortServerName",
06349 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
06350
06351 slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s",
06352 global_myname(), printer->info_2->sharename );
06353 init_unistr2( &buffer, asc_buffer, UNI_STR_TERMINATE);
06354 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName",
06355 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
06356
06357
06358 result = mod_a_printer(printer, 2);
06359
06360 done:
06361 free_a_printer(&printer, 2);
06362 free_a_printer(&old_printer, 2);
06363
06364
06365 return result;
06366 }
06367
06368
06369
06370 static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle,
06371 const SPOOL_PRINTER_INFO_LEVEL *info)
06372 {
06373 #ifdef HAVE_ADS
06374 SPOOL_PRINTER_INFO_LEVEL_7 *info7 = info->info_7;
06375 int snum;
06376 Printer_entry *Printer;
06377
06378 if ( lp_security() != SEC_ADS ) {
06379 return WERR_UNKNOWN_LEVEL;
06380 }
06381
06382 Printer = find_printer_index_by_hnd(p, handle);
06383
06384 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
06385
06386 if (!Printer)
06387 return WERR_BADFID;
06388
06389 if (!get_printer_snum(p, handle, &snum))
06390 return WERR_BADFID;
06391
06392 nt_printer_publish(Printer, snum, info7->action);
06393
06394 return WERR_OK;
06395 #else
06396 return WERR_UNKNOWN_LEVEL;
06397 #endif
06398 }
06399
06400
06401
06402 WERROR _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SETPRINTER *r_u)
06403 {
06404 POLICY_HND *handle = &q_u->handle;
06405 uint32 level = q_u->level;
06406 SPOOL_PRINTER_INFO_LEVEL *info = &q_u->info;
06407 DEVMODE_CTR devmode_ctr = q_u->devmode_ctr;
06408 SEC_DESC_BUF *secdesc_ctr = q_u->secdesc_ctr;
06409 uint32 command = q_u->command;
06410 WERROR result;
06411
06412 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
06413
06414 if (!Printer) {
06415 DEBUG(2,("_spoolss_setprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
06416 return WERR_BADFID;
06417 }
06418
06419
06420 switch (level) {
06421 case 0:
06422 return control_printer(handle, command, p);
06423 case 2:
06424 result = update_printer(p, handle, level, info, devmode_ctr.devmode);
06425 if (!W_ERROR_IS_OK(result))
06426 return result;
06427 if (secdesc_ctr)
06428 result = update_printer_sec(handle, level, info, p, secdesc_ctr);
06429 return result;
06430 case 3:
06431 return update_printer_sec(handle, level, info, p,
06432 secdesc_ctr);
06433 case 7:
06434 return publish_or_unpublish_printer(p, handle, info);
06435 default:
06436 return WERR_UNKNOWN_LEVEL;
06437 }
06438 }
06439
06440
06441
06442
06443 WERROR _spoolss_fcpn(pipes_struct *p, SPOOL_Q_FCPN *q_u, SPOOL_R_FCPN *r_u)
06444 {
06445 POLICY_HND *handle = &q_u->handle;
06446 Printer_entry *Printer= find_printer_index_by_hnd(p, handle);
06447
06448 if (!Printer) {
06449 DEBUG(2,("_spoolss_fcpn: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
06450 return WERR_BADFID;
06451 }
06452
06453 if (Printer->notify.client_connected==True) {
06454 int snum = -1;
06455
06456 if ( Printer->printer_type == SPLHND_SERVER)
06457 snum = -1;
06458 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
06459 !get_printer_snum(p, handle, &snum) )
06460 return WERR_BADFID;
06461
06462 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
06463 }
06464
06465 Printer->notify.flags=0;
06466 Printer->notify.options=0;
06467 Printer->notify.localmachine[0]='\0';
06468 Printer->notify.printerlocal=0;
06469 if (Printer->notify.option)
06470 free_spool_notify_option(&Printer->notify.option);
06471 Printer->notify.client_connected=False;
06472
06473 return WERR_OK;
06474 }
06475
06476
06477
06478
06479 WERROR _spoolss_addjob(pipes_struct *p, SPOOL_Q_ADDJOB *q_u, SPOOL_R_ADDJOB *r_u)
06480 {
06481
06482
06483 if (!q_u->buffer && (q_u->offered!=0)) {
06484 return WERR_INVALID_PARAM;
06485 }
06486
06487 rpcbuf_move(q_u->buffer, &r_u->buffer);
06488
06489 r_u->needed = 0;
06490 return WERR_INVALID_PARAM;
06491
06492
06493
06494 }
06495
06496
06497
06498
06499 static void fill_job_info_1(JOB_INFO_1 *job_info, const print_queue_struct *queue,
06500 int position, int snum,
06501 const NT_PRINTER_INFO_LEVEL *ntprinter)
06502 {
06503 struct tm *t;
06504
06505 t=gmtime(&queue->time);
06506
06507 job_info->jobid=queue->job;
06508 init_unistr(&job_info->printername, lp_servicename(snum));
06509 init_unistr(&job_info->machinename, ntprinter->info_2->servername);
06510 init_unistr(&job_info->username, queue->fs_user);
06511 init_unistr(&job_info->document, queue->fs_file);
06512 init_unistr(&job_info->datatype, "RAW");
06513 init_unistr(&job_info->text_status, "");
06514 job_info->status=nt_printj_status(queue->status);
06515 job_info->priority=queue->priority;
06516 job_info->position=position;
06517 job_info->totalpages=queue->page_count;
06518 job_info->pagesprinted=0;
06519
06520 make_systemtime(&job_info->submitted, t);
06521 }
06522
06523
06524
06525
06526 static BOOL fill_job_info_2(JOB_INFO_2 *job_info, const print_queue_struct *queue,
06527 int position, int snum,
06528 const NT_PRINTER_INFO_LEVEL *ntprinter,
06529 DEVICEMODE *devmode)
06530 {
06531 struct tm *t;
06532
06533 t=gmtime(&queue->time);
06534
06535 job_info->jobid=queue->job;
06536
06537 init_unistr(&job_info->printername, ntprinter->info_2->printername);
06538
06539 init_unistr(&job_info->machinename, ntprinter->info_2->servername);
06540 init_unistr(&job_info->username, queue->fs_user);
06541 init_unistr(&job_info->document, queue->fs_file);
06542 init_unistr(&job_info->notifyname, queue->fs_user);
06543 init_unistr(&job_info->datatype, "RAW");
06544 init_unistr(&job_info->printprocessor, "winprint");
06545 init_unistr(&job_info->parameters, "");
06546 init_unistr(&job_info->drivername, ntprinter->info_2->drivername);
06547 init_unistr(&job_info->text_status, "");
06548
06549
06550
06551 job_info->status=nt_printj_status(queue->status);
06552 job_info->priority=queue->priority;
06553 job_info->position=position;
06554 job_info->starttime=0;
06555 job_info->untiltime=0;
06556 job_info->totalpages=queue->page_count;
06557 job_info->size=queue->size;
06558 make_systemtime(&(job_info->submitted), t);
06559 job_info->timeelapsed=0;
06560 job_info->pagesprinted=0;
06561
06562 job_info->devmode = devmode;
06563
06564 return (True);
06565 }
06566
06567
06568
06569
06570
06571 static WERROR enumjobs_level1(const print_queue_struct *queue, int snum,
06572 const NT_PRINTER_INFO_LEVEL *ntprinter,
06573 RPC_BUFFER *buffer, uint32 offered,
06574 uint32 *needed, uint32 *returned)
06575 {
06576 JOB_INFO_1 *info;
06577 int i;
06578 WERROR result = WERR_OK;
06579
06580 info=SMB_MALLOC_ARRAY(JOB_INFO_1,*returned);
06581 if (info==NULL) {
06582 *returned=0;
06583 return WERR_NOMEM;
06584 }
06585
06586 for (i=0; i<*returned; i++)
06587 fill_job_info_1( &info[i], &queue[i], i, snum, ntprinter );
06588
06589
06590 for (i=0; i<*returned; i++)
06591 (*needed) += spoolss_size_job_info_1(&info[i]);
06592
06593 if (*needed > offered) {
06594 result = WERR_INSUFFICIENT_BUFFER;
06595 goto out;
06596 }
06597
06598 if (!rpcbuf_alloc_size(buffer, *needed)) {
06599 result = WERR_NOMEM;
06600 goto out;
06601 }
06602
06603
06604 for (i=0; i<*returned; i++)
06605 smb_io_job_info_1("", buffer, &info[i], 0);
06606
06607 out:
06608
06609 SAFE_FREE(info);
06610
06611 if ( !W_ERROR_IS_OK(result) )
06612 *returned = 0;
06613
06614 return result;
06615 }
06616
06617
06618
06619
06620
06621 static WERROR enumjobs_level2(const print_queue_struct *queue, int snum,
06622 const NT_PRINTER_INFO_LEVEL *ntprinter,
06623 RPC_BUFFER *buffer, uint32 offered,
06624 uint32 *needed, uint32 *returned)
06625 {
06626 JOB_INFO_2 *info = NULL;
06627 int i;
06628 WERROR result = WERR_OK;
06629 DEVICEMODE *devmode = NULL;
06630
06631 if ( !(info = SMB_MALLOC_ARRAY(JOB_INFO_2,*returned)) ) {
06632 *returned=0;
06633 return WERR_NOMEM;
06634 }
06635
06636
06637
06638 devmode = construct_dev_mode(lp_const_servicename(snum));
06639
06640 for (i=0; i<*returned; i++)
06641 fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode);
06642
06643
06644 for (i=0; i<*returned; i++)
06645 (*needed) += spoolss_size_job_info_2(&info[i]);
06646
06647 if (*needed > offered) {
06648 result = WERR_INSUFFICIENT_BUFFER;
06649 goto out;
06650 }
06651
06652 if (!rpcbuf_alloc_size(buffer, *needed)) {
06653 result = WERR_NOMEM;
06654 goto out;
06655 }
06656
06657
06658 for (i=0; i<*returned; i++)
06659 smb_io_job_info_2("", buffer, &info[i], 0);
06660
06661 out:
06662 free_devmode(devmode);
06663 SAFE_FREE(info);
06664
06665 if ( !W_ERROR_IS_OK(result) )
06666 *returned = 0;
06667
06668 return result;
06669
06670 }
06671
06672
06673
06674
06675
06676 WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u)
06677 {
06678 POLICY_HND *handle = &q_u->handle;
06679 uint32 level = q_u->level;
06680 RPC_BUFFER *buffer = NULL;
06681 uint32 offered = q_u->offered;
06682 uint32 *needed = &r_u->needed;
06683 uint32 *returned = &r_u->returned;
06684 WERROR wret;
06685 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
06686 int snum;
06687 print_status_struct prt_status;
06688 print_queue_struct *queue=NULL;
06689
06690
06691
06692 if (!q_u->buffer && (offered!=0)) {
06693 return WERR_INVALID_PARAM;
06694 }
06695
06696 rpcbuf_move(q_u->buffer, &r_u->buffer);
06697 buffer = r_u->buffer;
06698
06699 DEBUG(4,("_spoolss_enumjobs\n"));
06700
06701 *needed=0;
06702 *returned=0;
06703
06704
06705
06706 if (!get_printer_snum(p, handle, &snum))
06707 return WERR_BADFID;
06708
06709 wret = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
06710 if ( !W_ERROR_IS_OK(wret) )
06711 return wret;
06712
06713 *returned = print_queue_status(snum, &queue, &prt_status);
06714 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
06715
06716 if (*returned == 0) {
06717 SAFE_FREE(queue);
06718 free_a_printer(&ntprinter, 2);
06719 return WERR_OK;
06720 }
06721
06722 switch (level) {
06723 case 1:
06724 wret = enumjobs_level1(queue, snum, ntprinter, buffer, offered, needed, returned);
06725 break;
06726 case 2:
06727 wret = enumjobs_level2(queue, snum, ntprinter, buffer, offered, needed, returned);
06728 break;
06729 default:
06730 *returned=0;
06731 wret = WERR_UNKNOWN_LEVEL;
06732 break;
06733 }
06734
06735 SAFE_FREE(queue);
06736 free_a_printer( &ntprinter, 2 );
06737 return wret;
06738 }
06739
06740
06741
06742
06743 WERROR _spoolss_schedulejob( pipes_struct *p, SPOOL_Q_SCHEDULEJOB *q_u, SPOOL_R_SCHEDULEJOB *r_u)
06744 {
06745 return WERR_OK;
06746 }
06747
06748
06749
06750
06751 WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u)
06752 {
06753 POLICY_HND *handle = &q_u->handle;
06754 uint32 jobid = q_u->jobid;
06755 uint32 command = q_u->command;
06756
06757 struct current_user user;
06758 int snum;
06759 WERROR errcode = WERR_BADFUNC;
06760
06761 if (!get_printer_snum(p, handle, &snum)) {
06762 return WERR_BADFID;
06763 }
06764
06765 if (!print_job_exists(lp_const_servicename(snum), jobid)) {
06766 return WERR_INVALID_PRINTER_NAME;
06767 }
06768
06769 get_current_user(&user, p);
06770
06771 switch (command) {
06772 case JOB_CONTROL_CANCEL:
06773 case JOB_CONTROL_DELETE:
06774 if (print_job_delete(&user, snum, jobid, &errcode)) {
06775 errcode = WERR_OK;
06776 }
06777 break;
06778 case JOB_CONTROL_PAUSE:
06779 if (print_job_pause(&user, snum, jobid, &errcode)) {
06780 errcode = WERR_OK;
06781 }
06782 break;
06783 case JOB_CONTROL_RESTART:
06784 case JOB_CONTROL_RESUME:
06785 if (print_job_resume(&user, snum, jobid, &errcode)) {
06786 errcode = WERR_OK;
06787 }
06788 break;
06789 default:
06790 return WERR_UNKNOWN_LEVEL;
06791 }
06792
06793 return errcode;
06794 }
06795
06796
06797
06798
06799
06800 static WERROR enumprinterdrivers_level1(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
06801 {
06802 int i;
06803 int ndrivers;
06804 uint32 version;
06805 fstring *list = NULL;
06806 NT_PRINTER_DRIVER_INFO_LEVEL driver;
06807 DRIVER_INFO_1 *driver_info_1=NULL;
06808 WERROR result = WERR_OK;
06809
06810 *returned=0;
06811
06812 for (version=0; version<DRIVER_MAX_VERSION; version++) {
06813 list=NULL;
06814 ndrivers=get_ntdrivers(&list, architecture, version);
06815 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
06816
06817 if(ndrivers == -1) {
06818 SAFE_FREE(driver_info_1);
06819 return WERR_NOMEM;
06820 }
06821
06822 if(ndrivers != 0) {
06823 if((driver_info_1=SMB_REALLOC_ARRAY(driver_info_1, DRIVER_INFO_1, *returned+ndrivers )) == NULL) {
06824 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
06825 SAFE_FREE(list);
06826 return WERR_NOMEM;
06827 }
06828 }
06829
06830 for (i=0; i<ndrivers; i++) {
06831 WERROR status;
06832 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
06833 ZERO_STRUCT(driver);
06834 status = get_a_printer_driver(&driver, 3, list[i],
06835 architecture, version);
06836 if (!W_ERROR_IS_OK(status)) {
06837 SAFE_FREE(list);
06838 SAFE_FREE(driver_info_1);
06839 return status;
06840 }
06841 fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture );
06842 free_a_printer_driver(driver, 3);
06843 }
06844
06845 *returned+=ndrivers;
06846 SAFE_FREE(list);
06847 }
06848
06849
06850 for (i=0; i<*returned; i++) {
06851 DEBUGADD(6,("adding driver [%d]'s size\n",i));
06852 *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]);
06853 }
06854
06855 if (*needed > offered) {
06856 result = WERR_INSUFFICIENT_BUFFER;
06857 goto out;
06858 }
06859
06860 if (!rpcbuf_alloc_size(buffer, *needed)) {
06861 result = WERR_NOMEM;
06862 goto out;
06863 }
06864
06865
06866 for (i=0; i<*returned; i++) {
06867 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
06868 smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
06869 }
06870
06871 out:
06872 SAFE_FREE(driver_info_1);
06873
06874 if ( !W_ERROR_IS_OK(result) )
06875 *returned = 0;
06876
06877 return result;
06878 }
06879
06880
06881
06882
06883
06884 static WERROR enumprinterdrivers_level2(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
06885 {
06886 int i;
06887 int ndrivers;
06888 uint32 version;
06889 fstring *list = NULL;
06890 NT_PRINTER_DRIVER_INFO_LEVEL driver;
06891 DRIVER_INFO_2 *driver_info_2=NULL;
06892 WERROR result = WERR_OK;
06893
06894 *returned=0;
06895
06896 for (version=0; version<DRIVER_MAX_VERSION; version++) {
06897 list=NULL;
06898 ndrivers=get_ntdrivers(&list, architecture, version);
06899 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
06900
06901 if(ndrivers == -1) {
06902 SAFE_FREE(driver_info_2);
06903 return WERR_NOMEM;
06904 }
06905
06906 if(ndrivers != 0) {
06907 if((driver_info_2=SMB_REALLOC_ARRAY(driver_info_2, DRIVER_INFO_2, *returned+ndrivers )) == NULL) {
06908 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
06909 SAFE_FREE(list);
06910 return WERR_NOMEM;
06911 }
06912 }
06913
06914 for (i=0; i<ndrivers; i++) {
06915 WERROR status;
06916
06917 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
06918 ZERO_STRUCT(driver);
06919 status = get_a_printer_driver(&driver, 3, list[i],
06920 architecture, version);
06921 if (!W_ERROR_IS_OK(status)) {
06922 SAFE_FREE(list);
06923 SAFE_FREE(driver_info_2);
06924 return status;
06925 }
06926 fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername);
06927 free_a_printer_driver(driver, 3);
06928 }
06929
06930 *returned+=ndrivers;
06931 SAFE_FREE(list);
06932 }
06933
06934
06935 for (i=0; i<*returned; i++) {
06936 DEBUGADD(6,("adding driver [%d]'s size\n",i));
06937 *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
06938 }
06939
06940 if (*needed > offered) {
06941 result = WERR_INSUFFICIENT_BUFFER;
06942 goto out;
06943 }
06944
06945 if (!rpcbuf_alloc_size(buffer, *needed)) {
06946 result = WERR_NOMEM;
06947 goto out;
06948 }
06949
06950
06951 for (i=0; i<*returned; i++) {
06952 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
06953 smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
06954 }
06955
06956 out:
06957 SAFE_FREE(driver_info_2);
06958
06959 if ( !W_ERROR_IS_OK(result) )
06960 *returned = 0;
06961
06962 return result;
06963 }
06964
06965
06966
06967
06968
06969 static WERROR enumprinterdrivers_level3(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
06970 {
06971 int i;
06972 int ndrivers;
06973 uint32 version;
06974 fstring *list = NULL;
06975 DRIVER_INFO_3 *driver_info_3=NULL;
06976 NT_PRINTER_DRIVER_INFO_LEVEL driver;
06977 WERROR result = WERR_OK;
06978
06979 *returned=0;
06980
06981 for (version=0; version<DRIVER_MAX_VERSION; version++) {
06982 list=NULL;
06983 ndrivers=get_ntdrivers(&list, architecture, version);
06984 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
06985
06986 if(ndrivers == -1) {
06987 SAFE_FREE(driver_info_3);
06988 return WERR_NOMEM;
06989 }
06990
06991 if(ndrivers != 0) {
06992 if((driver_info_3=SMB_REALLOC_ARRAY(driver_info_3, DRIVER_INFO_3, *returned+ndrivers )) == NULL) {
06993 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
06994 SAFE_FREE(list);
06995 return WERR_NOMEM;
06996 }
06997 }
06998
06999 for (i=0; i<ndrivers; i++) {
07000 WERROR status;
07001
07002 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
07003 ZERO_STRUCT(driver);
07004 status = get_a_printer_driver(&driver, 3, list[i],
07005 architecture, version);
07006 if (!W_ERROR_IS_OK(status)) {
07007 SAFE_FREE(list);
07008 SAFE_FREE(driver_info_3);
07009 return status;
07010 }
07011 fill_printer_driver_info_3(&driver_info_3[*returned+i], driver, servername);
07012 free_a_printer_driver(driver, 3);
07013 }
07014
07015 *returned+=ndrivers;
07016 SAFE_FREE(list);
07017 }
07018
07019
07020 for (i=0; i<*returned; i++) {
07021 DEBUGADD(6,("adding driver [%d]'s size\n",i));
07022 *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
07023 }
07024
07025 if (*needed > offered) {
07026 result = WERR_INSUFFICIENT_BUFFER;
07027 goto out;
07028 }
07029
07030 if (!rpcbuf_alloc_size(buffer, *needed)) {
07031 result = WERR_NOMEM;
07032 goto out;
07033 }
07034
07035
07036 for (i=0; i<*returned; i++) {
07037 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
07038 smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
07039 }
07040
07041 out:
07042 for (i=0; i<*returned; i++) {
07043 SAFE_FREE(driver_info_3[i].dependentfiles);
07044 }
07045
07046 SAFE_FREE(driver_info_3);
07047
07048 if ( !W_ERROR_IS_OK(result) )
07049 *returned = 0;
07050
07051 return result;
07052 }
07053
07054
07055
07056
07057
07058 WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
07059 {
07060 uint32 level = q_u->level;
07061 RPC_BUFFER *buffer = NULL;
07062 uint32 offered = q_u->offered;
07063 uint32 *needed = &r_u->needed;
07064 uint32 *returned = &r_u->returned;
07065 const char *cservername;
07066 fstring servername;
07067 fstring architecture;
07068
07069
07070
07071 if (!q_u->buffer && (offered!=0)) {
07072 return WERR_INVALID_PARAM;
07073 }
07074
07075 rpcbuf_move(q_u->buffer, &r_u->buffer);
07076 buffer = r_u->buffer;
07077
07078 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
07079
07080 *needed = 0;
07081 *returned = 0;
07082
07083 unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture)-1);
07084 unistr2_to_ascii(servername, &q_u->name, sizeof(servername)-1);
07085
07086 cservername = canon_servername(servername);
07087
07088 if (!is_myname_or_ipaddr(cservername))
07089 return WERR_UNKNOWN_PRINTER_DRIVER;
07090
07091 switch (level) {
07092 case 1:
07093 return enumprinterdrivers_level1(cservername, architecture, buffer, offered, needed, returned);
07094 case 2:
07095 return enumprinterdrivers_level2(cservername, architecture, buffer, offered, needed, returned);
07096 case 3:
07097 return enumprinterdrivers_level3(cservername, architecture, buffer, offered, needed, returned);
07098 default:
07099 return WERR_UNKNOWN_LEVEL;
07100 }
07101 }
07102
07103
07104
07105
07106 static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
07107 {
07108 form->flag=list->flag;
07109 init_unistr(&form->name, list->name);
07110 form->width=list->width;
07111 form->length=list->length;
07112 form->left=list->left;
07113 form->top=list->top;
07114 form->right=list->right;
07115 form->bottom=list->bottom;
07116 }
07117
07118
07119
07120
07121 WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u)
07122 {
07123 uint32 level = q_u->level;
07124 RPC_BUFFER *buffer = NULL;
07125 uint32 offered = q_u->offered;
07126 uint32 *needed = &r_u->needed;
07127 uint32 *numofforms = &r_u->numofforms;
07128 uint32 numbuiltinforms;
07129
07130 nt_forms_struct *list=NULL;
07131 nt_forms_struct *builtinlist=NULL;
07132 FORM_1 *forms_1;
07133 int buffer_size=0;
07134 int i;
07135
07136
07137
07138 if (!q_u->buffer && (offered!=0) ) {
07139 return WERR_INVALID_PARAM;
07140 }
07141
07142 rpcbuf_move(q_u->buffer, &r_u->buffer);
07143 buffer = r_u->buffer;
07144
07145 DEBUG(4,("_spoolss_enumforms\n"));
07146 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
07147 DEBUGADD(5,("Info level [%d]\n", level));
07148
07149 numbuiltinforms = get_builtin_ntforms(&builtinlist);
07150 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms));
07151 *numofforms = get_ntforms(&list);
07152 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms));
07153 *numofforms += numbuiltinforms;
07154
07155 if (*numofforms == 0) {
07156 SAFE_FREE(builtinlist);
07157 SAFE_FREE(list);
07158 return WERR_NO_MORE_ITEMS;
07159 }
07160
07161 switch (level) {
07162 case 1:
07163 if ((forms_1=SMB_MALLOC_ARRAY(FORM_1, *numofforms)) == NULL) {
07164 SAFE_FREE(builtinlist);
07165 SAFE_FREE(list);
07166 *numofforms=0;
07167 return WERR_NOMEM;
07168 }
07169
07170
07171 for (i=0; i<numbuiltinforms; i++) {
07172 DEBUGADD(6,("Filling form number [%d]\n",i));
07173 fill_form_1(&forms_1[i], &builtinlist[i]);
07174 }
07175
07176 SAFE_FREE(builtinlist);
07177
07178 for (; i<*numofforms; i++) {
07179 DEBUGADD(6,("Filling form number [%d]\n",i));
07180 fill_form_1(&forms_1[i], &list[i-numbuiltinforms]);
07181 }
07182
07183 SAFE_FREE(list);
07184
07185
07186 for (i=0; i<numbuiltinforms; i++) {
07187 DEBUGADD(6,("adding form [%d]'s size\n",i));
07188 buffer_size += spoolss_size_form_1(&forms_1[i]);
07189 }
07190 for (; i<*numofforms; i++) {
07191 DEBUGADD(6,("adding form [%d]'s size\n",i));
07192 buffer_size += spoolss_size_form_1(&forms_1[i]);
07193 }
07194
07195 *needed=buffer_size;
07196
07197 if (*needed > offered) {
07198 SAFE_FREE(forms_1);
07199 *numofforms=0;
07200 return WERR_INSUFFICIENT_BUFFER;
07201 }
07202
07203 if (!rpcbuf_alloc_size(buffer, buffer_size)){
07204 SAFE_FREE(forms_1);
07205 *numofforms=0;
07206 return WERR_NOMEM;
07207 }
07208
07209
07210 for (i=0; i<numbuiltinforms; i++) {
07211 DEBUGADD(6,("adding form [%d] to buffer\n",i));
07212 smb_io_form_1("", buffer, &forms_1[i], 0);
07213 }
07214 for (; i<*numofforms; i++) {
07215 DEBUGADD(6,("adding form [%d] to buffer\n",i));
07216 smb_io_form_1("", buffer, &forms_1[i], 0);
07217 }
07218
07219 SAFE_FREE(forms_1);
07220
07221 return WERR_OK;
07222
07223 default:
07224 SAFE_FREE(list);
07225 SAFE_FREE(builtinlist);
07226 return WERR_UNKNOWN_LEVEL;
07227 }
07228 }
07229
07230
07231
07232
07233 WERROR _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *r_u)
07234 {
07235 uint32 level = q_u->level;
07236 UNISTR2 *uni_formname = &q_u->formname;
07237 RPC_BUFFER *buffer = NULL;
07238 uint32 offered = q_u->offered;
07239 uint32 *needed = &r_u->needed;
07240
07241 nt_forms_struct *list=NULL;
07242 nt_forms_struct builtin_form;
07243 BOOL foundBuiltin;
07244 FORM_1 form_1;
07245 fstring form_name;
07246 int buffer_size=0;
07247 int numofforms=0, i=0;
07248
07249
07250
07251 if (!q_u->buffer && (offered!=0)) {
07252 return WERR_INVALID_PARAM;
07253 }
07254
07255 rpcbuf_move(q_u->buffer, &r_u->buffer);
07256 buffer = r_u->buffer;
07257
07258 unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
07259
07260 DEBUG(4,("_spoolss_getform\n"));
07261 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
07262 DEBUGADD(5,("Info level [%d]\n", level));
07263
07264 foundBuiltin = get_a_builtin_ntform(uni_formname,&builtin_form);
07265 if (!foundBuiltin) {
07266 numofforms = get_ntforms(&list);
07267 DEBUGADD(5,("Number of forms [%d]\n", numofforms));
07268
07269 if (numofforms == 0)
07270 return WERR_BADFID;
07271 }
07272
07273 switch (level) {
07274 case 1:
07275 if (foundBuiltin) {
07276 fill_form_1(&form_1, &builtin_form);
07277 } else {
07278
07279
07280 for (i=0; i<numofforms; i++) {
07281
07282 DEBUG(4,("_spoolss_getform: checking form %s (want %s)\n", list[i].name, form_name));
07283
07284 if (strequal(form_name, list[i].name)) {
07285 DEBUGADD(6,("Found form %s number [%d]\n", form_name, i));
07286 fill_form_1(&form_1, &list[i]);
07287 break;
07288 }
07289 }
07290
07291 SAFE_FREE(list);
07292 if (i == numofforms) {
07293 return WERR_BADFID;
07294 }
07295 }
07296
07297
07298 *needed=spoolss_size_form_1(&form_1);
07299
07300 if (*needed > offered)
07301 return WERR_INSUFFICIENT_BUFFER;
07302
07303 if (!rpcbuf_alloc_size(buffer, buffer_size))
07304 return WERR_NOMEM;
07305
07306
07307 DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name, i));
07308 smb_io_form_1("", buffer, &form_1, 0);
07309
07310 return WERR_OK;
07311
07312 default:
07313 SAFE_FREE(list);
07314 return WERR_UNKNOWN_LEVEL;
07315 }
07316 }
07317
07318
07319
07320
07321 static void fill_port_1(PORT_INFO_1 *port, const char *name)
07322 {
07323 init_unistr(&port->port_name, name);
07324 }
07325
07326
07327
07328
07329
07330
07331 static void fill_port_2(PORT_INFO_2 *port, const char *name)
07332 {
07333 init_unistr(&port->port_name, name);
07334 init_unistr(&port->monitor_name, "Local Monitor");
07335 init_unistr(&port->description, SPL_LOCAL_PORT );
07336 port->port_type=PORT_TYPE_WRITE;
07337 port->reserved=0x0;
07338 }
07339
07340
07341
07342
07343
07344
07345 WERROR enumports_hook( int *count, char ***lines )
07346 {
07347 char *cmd = lp_enumports_cmd();
07348 char **qlines;
07349 pstring command;
07350 int numlines;
07351 int ret;
07352 int fd;
07353
07354 *count = 0;
07355 *lines = NULL;
07356
07357
07358
07359 if ( !*cmd ) {
07360 qlines = SMB_MALLOC_ARRAY( char*, 2 );
07361 qlines[0] = SMB_STRDUP( SAMBA_PRINTER_PORT_NAME );
07362 qlines[1] = NULL;
07363 numlines = 1;
07364 }
07365 else {
07366
07367
07368 slprintf(command, sizeof(command)-1, "%s \"%d\"", cmd, 1);
07369
07370 DEBUG(10,("Running [%s]\n", command));
07371 ret = smbrun(command, &fd);
07372 DEBUG(10,("Returned [%d]\n", ret));
07373 if (ret != 0) {
07374 if (fd != -1) {
07375 close(fd);
07376 }
07377 return WERR_ACCESS_DENIED;
07378 }
07379
07380 numlines = 0;
07381 qlines = fd_lines_load(fd, &numlines, 0);
07382 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
07383 close(fd);
07384 }
07385
07386 *count = numlines;
07387 *lines = qlines;
07388
07389 return WERR_OK;
07390 }
07391
07392
07393
07394
07395
07396 static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
07397 {
07398 PORT_INFO_1 *ports=NULL;
07399 int i=0;
07400 WERROR result = WERR_OK;
07401 char **qlines = NULL;
07402 int numlines = 0;
07403
07404 result = enumports_hook( &numlines, &qlines );
07405 if (!W_ERROR_IS_OK(result)) {
07406 file_lines_free(qlines);
07407 return result;
07408 }
07409
07410 if(numlines) {
07411 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_1, numlines )) == NULL) {
07412 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
07413 dos_errstr(WERR_NOMEM)));
07414 file_lines_free(qlines);
07415 return WERR_NOMEM;
07416 }
07417
07418 for (i=0; i<numlines; i++) {
07419 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
07420 fill_port_1(&ports[i], qlines[i]);
07421 }
07422 }
07423 file_lines_free(qlines);
07424
07425 *returned = numlines;
07426
07427
07428 for (i=0; i<*returned; i++) {
07429 DEBUGADD(6,("adding port [%d]'s size\n", i));
07430 *needed += spoolss_size_port_info_1(&ports[i]);
07431 }
07432
07433 if (*needed > offered) {
07434 result = WERR_INSUFFICIENT_BUFFER;
07435 goto out;
07436 }
07437
07438 if (!rpcbuf_alloc_size(buffer, *needed)) {
07439 result = WERR_NOMEM;
07440 goto out;
07441 }
07442
07443
07444 for (i=0; i<*returned; i++) {
07445 DEBUGADD(6,("adding port [%d] to buffer\n", i));
07446 smb_io_port_1("", buffer, &ports[i], 0);
07447 }
07448
07449 out:
07450 SAFE_FREE(ports);
07451
07452 if ( !W_ERROR_IS_OK(result) )
07453 *returned = 0;
07454
07455 return result;
07456 }
07457
07458
07459
07460
07461
07462 static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
07463 {
07464 PORT_INFO_2 *ports=NULL;
07465 int i=0;
07466 WERROR result = WERR_OK;
07467 char **qlines = NULL;
07468 int numlines = 0;
07469
07470 result = enumports_hook( &numlines, &qlines );
07471 if ( !W_ERROR_IS_OK(result)) {
07472 file_lines_free(qlines);
07473 return result;
07474 }
07475
07476 if(numlines) {
07477 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_2, numlines)) == NULL) {
07478 file_lines_free(qlines);
07479 return WERR_NOMEM;
07480 }
07481
07482 for (i=0; i<numlines; i++) {
07483 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
07484 fill_port_2(&(ports[i]), qlines[i]);
07485 }
07486 }
07487
07488 file_lines_free(qlines);
07489
07490 *returned = numlines;
07491
07492
07493 for (i=0; i<*returned; i++) {
07494 DEBUGADD(6,("adding port [%d]'s size\n", i));
07495 *needed += spoolss_size_port_info_2(&ports[i]);
07496 }
07497
07498 if (*needed > offered) {
07499 result = WERR_INSUFFICIENT_BUFFER;
07500 goto out;
07501 }
07502
07503 if (!rpcbuf_alloc_size(buffer, *needed)) {
07504 result = WERR_NOMEM;
07505 goto out;
07506 }
07507
07508
07509 for (i=0; i<*returned; i++) {
07510 DEBUGADD(6,("adding port [%d] to buffer\n", i));
07511 smb_io_port_2("", buffer, &ports[i], 0);
07512 }
07513
07514 out:
07515 SAFE_FREE(ports);
07516
07517 if ( !W_ERROR_IS_OK(result) )
07518 *returned = 0;
07519
07520 return result;
07521 }
07522
07523
07524
07525
07526
07527 WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
07528 {
07529 uint32 level = q_u->level;
07530 RPC_BUFFER *buffer = NULL;
07531 uint32 offered = q_u->offered;
07532 uint32 *needed = &r_u->needed;
07533 uint32 *returned = &r_u->returned;
07534
07535
07536
07537 if (!q_u->buffer && (offered!=0)) {
07538 return WERR_INVALID_PARAM;
07539 }
07540
07541 rpcbuf_move(q_u->buffer, &r_u->buffer);
07542 buffer = r_u->buffer;
07543
07544 DEBUG(4,("_spoolss_enumports\n"));
07545
07546 *returned=0;
07547 *needed=0;
07548
07549 switch (level) {
07550 case 1:
07551 return enumports_level_1(buffer, offered, needed, returned);
07552 case 2:
07553 return enumports_level_2(buffer, offered, needed, returned);
07554 default:
07555 return WERR_UNKNOWN_LEVEL;
07556 }
07557 }
07558
07559
07560
07561
07562 static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_srv_name,
07563 const SPOOL_PRINTER_INFO_LEVEL *info,
07564 DEVICEMODE *devmode, SEC_DESC_BUF *sec_desc_buf,
07565 uint32 user_switch, const SPOOL_USER_CTR *user,
07566 POLICY_HND *handle)
07567 {
07568 NT_PRINTER_INFO_LEVEL *printer = NULL;
07569 fstring name;
07570 int snum;
07571 WERROR err = WERR_OK;
07572
07573 if ( !(printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
07574 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
07575 return WERR_NOMEM;
07576 }
07577
07578
07579 if (!convert_printer_info(info, printer, 2)) {
07580 free_a_printer(&printer, 2);
07581 return WERR_NOMEM;
07582 }
07583
07584
07585
07586 if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
07587 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
07588 printer->info_2->sharename));
07589 free_a_printer(&printer, 2);
07590 return WERR_PRINTER_ALREADY_EXISTS;
07591 }
07592
07593
07594
07595
07596 if (*lp_addprinter_cmd() ) {
07597 if ( !add_printer_hook(p->pipe_user.nt_user_token, printer) ) {
07598 free_a_printer(&printer,2);
07599 return WERR_ACCESS_DENIED;
07600 }
07601 } else {
07602 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
07603 "smb.conf parameter \"addprinter command\" is defined. This"
07604 "parameter must exist for this call to succeed\n",
07605 printer->info_2->sharename ));
07606 }
07607
07608
07609
07610
07611 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname(),
07612 printer->info_2->sharename);
07613
07614
07615 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
07616 free_a_printer(&printer,2);
07617 return WERR_ACCESS_DENIED;
07618 }
07619
07620
07621 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
07622 free_a_printer(&printer,2);
07623 return WERR_ACCESS_DENIED;
07624 }
07625
07626
07627
07628
07629
07630 if (!check_printer_ok(printer->info_2, snum)) {
07631 free_a_printer(&printer,2);
07632 return WERR_INVALID_PARAM;
07633 }
07634
07635
07636
07637
07638
07639
07640
07641 if (!devmode)
07642 {
07643 set_driver_init(printer, 2);
07644 }
07645 else
07646 {
07647
07648
07649 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
07650
07651 if (!convert_devicemode(printer->info_2->printername, devmode,
07652 &printer->info_2->devmode))
07653 return WERR_NOMEM;
07654 }
07655
07656
07657 err = mod_a_printer(printer, 2);
07658 if (!W_ERROR_IS_OK(err)) {
07659 free_a_printer(&printer,2);
07660 return err;
07661 }
07662
07663 if (!open_printer_hnd(p, handle, name, PRINTER_ACCESS_ADMINISTER)) {
07664
07665 del_a_printer(printer->info_2->sharename);
07666 free_a_printer(&printer,2);
07667 return WERR_ACCESS_DENIED;
07668 }
07669
07670 update_c_setprinter(False);
07671 free_a_printer(&printer,2);
07672
07673 return WERR_OK;
07674 }
07675
07676
07677
07678
07679 WERROR _spoolss_addprinterex( pipes_struct *p, SPOOL_Q_ADDPRINTEREX *q_u, SPOOL_R_ADDPRINTEREX *r_u)
07680 {
07681 UNISTR2 *uni_srv_name = q_u->server_name;
07682 uint32 level = q_u->level;
07683 SPOOL_PRINTER_INFO_LEVEL *info = &q_u->info;
07684 DEVICEMODE *devmode = q_u->devmode_ctr.devmode;
07685 SEC_DESC_BUF *sdb = q_u->secdesc_ctr;
07686 uint32 user_switch = q_u->user_switch;
07687 SPOOL_USER_CTR *user = &q_u->user_ctr;
07688 POLICY_HND *handle = &r_u->handle;
07689
07690 switch (level) {
07691 case 1:
07692
07693
07694 return WERR_UNKNOWN_LEVEL;
07695 case 2:
07696 return spoolss_addprinterex_level_2(p, uni_srv_name, info,
07697 devmode, sdb,
07698 user_switch, user, handle);
07699 default:
07700 return WERR_UNKNOWN_LEVEL;
07701 }
07702 }
07703
07704
07705
07706
07707 WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u, SPOOL_R_ADDPRINTERDRIVER *r_u)
07708 {
07709 uint32 level = q_u->level;
07710 SPOOL_PRINTER_DRIVER_INFO_LEVEL *info = &q_u->info;
07711 WERROR err = WERR_OK;
07712 NT_PRINTER_DRIVER_INFO_LEVEL driver;
07713 struct current_user user;
07714 fstring driver_name;
07715 uint32 version;
07716
07717 ZERO_STRUCT(driver);
07718
07719 get_current_user(&user, p);
07720
07721 if (!convert_printer_driver_info(info, &driver, level)) {
07722 err = WERR_NOMEM;
07723 goto done;
07724 }
07725
07726 DEBUG(5,("Cleaning driver's information\n"));
07727 err = clean_up_driver_struct(driver, level, &user);
07728 if (!W_ERROR_IS_OK(err))
07729 goto done;
07730
07731 DEBUG(5,("Moving driver to final destination\n"));
07732 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(driver, level, &user, &err)) ) {
07733 goto done;
07734 }
07735
07736 if (add_a_printer_driver(driver, level)!=0) {
07737 err = WERR_ACCESS_DENIED;
07738 goto done;
07739 }
07740
07741
07742
07743
07744
07745
07746
07747
07748 if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
07749 DEBUG(0,("_spoolss_addprinterdriver: Failed to send message about upgrading driver [%s]!\n",
07750 driver_name));
07751 }
07752
07753
07754
07755
07756
07757
07758
07759
07760
07761
07762
07763 if (level == 3)
07764 version = driver.info_3->cversion;
07765 else if (level == 6)
07766 version = driver.info_6->version;
07767 else
07768 version = -1;
07769 switch (version) {
07770
07771
07772
07773 case 0:
07774 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for 9x driver [%s]\n",
07775 driver_name));
07776 break;
07777
07778
07779
07780
07781
07782 case 2:
07783 {
07784 NT_PRINTER_DRIVER_INFO_LEVEL driver1;
07785
07786 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1, 3, driver_name, "Windows NT x86", 3))) {
07787
07788
07789
07790 if (!del_driver_init(driver_name))
07791 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) Nt failed!\n", driver_name));
07792 } else {
07793
07794
07795
07796 free_a_printer_driver(driver1,3);
07797 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for Nt driver [%s]\n",
07798 driver_name));
07799 }
07800 }
07801 break;
07802
07803
07804
07805
07806 case 3:
07807 if (!del_driver_init(driver_name))
07808 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) 2k/Xp failed!\n", driver_name));
07809 break;
07810
07811 default:
07812 DEBUG(0,("_spoolss_addprinterdriver: invalid level=%d\n", level));
07813 break;
07814 }
07815
07816
07817 done:
07818 free_a_printer_driver(driver, level);
07819 return err;
07820 }
07821
07822
07823
07824
07825
07826 WERROR _spoolss_addprinterdriverex(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVEREX *q_u, SPOOL_R_ADDPRINTERDRIVEREX *r_u)
07827 {
07828 SPOOL_Q_ADDPRINTERDRIVER q_u_local;
07829 SPOOL_R_ADDPRINTERDRIVER r_u_local;
07830
07831
07832
07833
07834
07835
07836 if ( q_u->copy_flags != APD_COPY_NEW_FILES )
07837 return WERR_ACCESS_DENIED;
07838
07839 ZERO_STRUCT(q_u_local);
07840 ZERO_STRUCT(r_u_local);
07841
07842
07843 q_u_local.server_name_ptr = q_u->server_name_ptr;
07844 copy_unistr2(&q_u_local.server_name, &q_u->server_name);
07845 q_u_local.level = q_u->level;
07846 memcpy( &q_u_local.info, &q_u->info, sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL) );
07847
07848 return _spoolss_addprinterdriver( p, &q_u_local, &r_u_local );
07849 }
07850
07851
07852
07853
07854 static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name)
07855 {
07856 init_unistr(&info->name, name);
07857 }
07858
07859
07860
07861
07862 static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
07863 {
07864 pstring path;
07865 pstring long_archi;
07866 fstring servername;
07867 const char *pservername;
07868 const char *short_archi;
07869 DRIVER_DIRECTORY_1 *info=NULL;
07870 WERROR result = WERR_OK;
07871
07872 unistr2_to_ascii(servername, name, sizeof(servername)-1);
07873 unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
07874
07875 pservername = canon_servername(servername);
07876
07877 if ( !is_myname_or_ipaddr( pservername ) )
07878 return WERR_INVALID_PARAM;
07879
07880 if (!(short_archi = get_short_archi(long_archi)))
07881 return WERR_INVALID_ENVIRONMENT;
07882
07883 if((info=SMB_MALLOC_P(DRIVER_DIRECTORY_1)) == NULL)
07884 return WERR_NOMEM;
07885
07886 slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", pservername, short_archi);
07887
07888 DEBUG(4,("printer driver directory: [%s]\n", path));
07889
07890 fill_driverdir_1(info, path);
07891
07892 *needed += spoolss_size_driverdir_info_1(info);
07893
07894 if (*needed > offered) {
07895 result = WERR_INSUFFICIENT_BUFFER;
07896 goto out;
07897 }
07898
07899 if (!rpcbuf_alloc_size(buffer, *needed)) {
07900 result = WERR_NOMEM;
07901 goto out;
07902 }
07903
07904 smb_io_driverdir_1("", buffer, info, 0);
07905
07906 out:
07907 SAFE_FREE(info);
07908
07909 return result;
07910 }
07911
07912
07913
07914
07915 WERROR _spoolss_getprinterdriverdirectory(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, SPOOL_R_GETPRINTERDRIVERDIR *r_u)
07916 {
07917 UNISTR2 *name = &q_u->name;
07918 UNISTR2 *uni_environment = &q_u->environment;
07919 uint32 level = q_u->level;
07920 RPC_BUFFER *buffer = NULL;
07921 uint32 offered = q_u->offered;
07922 uint32 *needed = &r_u->needed;
07923
07924
07925
07926 if (!q_u->buffer && (offered!=0)) {
07927 return WERR_INVALID_PARAM;
07928 }
07929
07930 rpcbuf_move(q_u->buffer, &r_u->buffer);
07931 buffer = r_u->buffer;
07932
07933 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
07934
07935 *needed=0;
07936
07937 switch(level) {
07938 case 1:
07939 return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed);
07940 default:
07941 return WERR_UNKNOWN_LEVEL;
07942 }
07943 }
07944
07945
07946
07947
07948 WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u)
07949 {
07950 POLICY_HND *handle = &q_u->handle;
07951 uint32 idx = q_u->index;
07952 uint32 in_value_len = q_u->valuesize;
07953 uint32 in_data_len = q_u->datasize;
07954 uint32 *out_max_value_len = &r_u->valuesize;
07955 uint16 **out_value = &r_u->value;
07956 uint32 *out_value_len = &r_u->realvaluesize;
07957 uint32 *out_type = &r_u->type;
07958 uint32 *out_max_data_len = &r_u->datasize;
07959 uint8 **data_out = &r_u->data;
07960 uint32 *out_data_len = &r_u->realdatasize;
07961
07962 NT_PRINTER_INFO_LEVEL *printer = NULL;
07963
07964 uint32 biggest_valuesize;
07965 uint32 biggest_datasize;
07966 uint32 data_len;
07967 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
07968 int snum;
07969 WERROR result;
07970 REGISTRY_VALUE *val = NULL;
07971 NT_PRINTER_DATA *p_data;
07972 int i, key_index, num_values;
07973 int name_length;
07974
07975 *out_type = 0;
07976
07977 *out_max_data_len = 0;
07978 *data_out = NULL;
07979 *out_data_len = 0;
07980
07981 DEBUG(5,("spoolss_enumprinterdata\n"));
07982
07983 if (!Printer) {
07984 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
07985 return WERR_BADFID;
07986 }
07987
07988 if (!get_printer_snum(p,handle, &snum))
07989 return WERR_BADFID;
07990
07991 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
07992 if (!W_ERROR_IS_OK(result))
07993 return result;
07994
07995 p_data = printer->info_2->data;
07996 key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
07997
07998 result = WERR_OK;
07999
08000
08001
08002
08003
08004
08005
08006 if ( !in_value_len && !in_data_len && (key_index != -1) )
08007 {
08008 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
08009
08010 biggest_valuesize = 0;
08011 biggest_datasize = 0;
08012
08013 num_values = regval_ctr_numvals( p_data->keys[key_index].values );
08014
08015 for ( i=0; i<num_values; i++ )
08016 {
08017 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
08018
08019 name_length = strlen(val->valuename);
08020 if ( strlen(val->valuename) > biggest_valuesize )
08021 biggest_valuesize = name_length;
08022
08023 if ( val->size > biggest_datasize )
08024 biggest_datasize = val->size;
08025
08026 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
08027 biggest_datasize));
08028 }
08029
08030
08031
08032
08033 *out_value_len = 2 * (1+biggest_valuesize);
08034 *out_data_len = biggest_datasize;
08035
08036 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
08037
08038 goto done;
08039 }
08040
08041
08042
08043
08044
08045
08046 if ( key_index != -1 )
08047 val = regval_ctr_specific_value( p_data->keys[key_index].values, idx );
08048
08049 if ( !val )
08050 {
08051
08052
08053
08054
08055 *out_max_value_len=(in_value_len/sizeof(uint16));
08056
08057 if (in_value_len) {
08058 if((*out_value=(uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
08059 {
08060 result = WERR_NOMEM;
08061 goto done;
08062 }
08063 *out_value_len = (uint32)rpcstr_push((char *)*out_value, "", in_value_len, 0);
08064 } else {
08065 *out_value=NULL;
08066 *out_value_len = 0;
08067 }
08068
08069
08070
08071 *out_max_data_len = in_data_len;
08072 *out_data_len = in_data_len;
08073
08074
08075
08076 if ( in_data_len && ((*data_out=(uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) )
08077 {
08078 result = WERR_NOMEM;
08079 goto done;
08080 }
08081
08082 result = WERR_NO_MORE_ITEMS;
08083 }
08084 else
08085 {
08086
08087
08088
08089
08090
08091
08092
08093
08094
08095
08096 *out_max_value_len=(in_value_len/sizeof(uint16));
08097 if (in_value_len) {
08098 if ( (*out_value = (uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL )
08099 {
08100 result = WERR_NOMEM;
08101 goto done;
08102 }
08103
08104 *out_value_len = (uint32)rpcstr_push((char *)*out_value, regval_name(val), (size_t)in_value_len, 0);
08105 } else {
08106 *out_value = NULL;
08107 *out_value_len = 0;
08108 }
08109
08110
08111
08112 *out_type = regval_type( val );
08113
08114
08115
08116 *out_max_data_len = in_data_len;
08117 if ( in_data_len && (*data_out = (uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
08118 {
08119 result = WERR_NOMEM;
08120 goto done;
08121 }
08122 data_len = regval_size(val);
08123 if ( *data_out && data_len )
08124 memcpy( *data_out, regval_data_p(val), data_len );
08125 *out_data_len = data_len;
08126 }
08127
08128 done:
08129 free_a_printer(&printer, 2);
08130 return result;
08131 }
08132
08133
08134
08135
08136 WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u)
08137 {
08138 POLICY_HND *handle = &q_u->handle;
08139 UNISTR2 *value = &q_u->value;
08140 uint32 type = q_u->type;
08141 uint8 *data = q_u->data;
08142 uint32 real_len = q_u->real_len;
08143
08144 NT_PRINTER_INFO_LEVEL *printer = NULL;
08145 int snum=0;
08146 WERROR status = WERR_OK;
08147 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
08148 fstring valuename;
08149
08150 DEBUG(5,("spoolss_setprinterdata\n"));
08151
08152 if (!Printer) {
08153 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
08154 return WERR_BADFID;
08155 }
08156
08157 if ( Printer->printer_type == SPLHND_SERVER ) {
08158 DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
08159 return WERR_INVALID_PARAM;
08160 }
08161
08162 if (!get_printer_snum(p,handle, &snum))
08163 return WERR_BADFID;
08164
08165
08166
08167
08168
08169
08170
08171
08172
08173 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
08174 {
08175 DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
08176 status = WERR_ACCESS_DENIED;
08177 goto done;
08178 }
08179
08180 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
08181 if (!W_ERROR_IS_OK(status))
08182 return status;
08183
08184 unistr2_to_ascii( valuename, value, sizeof(valuename)-1 );
08185
08186
08187
08188
08189
08190
08191 if ( (type == REG_BINARY) && strequal( valuename, PHANTOM_DEVMODE_KEY))
08192 {
08193
08194 status = save_driver_init( printer, 2, data, real_len );
08195
08196 srv_spoolss_reset_printerdata( printer->info_2->drivername );
08197 }
08198 else
08199 {
08200 status = set_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename,
08201 type, data, real_len );
08202 if ( W_ERROR_IS_OK(status) )
08203 status = mod_a_printer(printer, 2);
08204 }
08205
08206 done:
08207 free_a_printer(&printer, 2);
08208
08209 return status;
08210 }
08211
08212
08213
08214
08215 WERROR _spoolss_resetprinter(pipes_struct *p, SPOOL_Q_RESETPRINTER *q_u, SPOOL_R_RESETPRINTER *r_u)
08216 {
08217 POLICY_HND *handle = &q_u->handle;
08218 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
08219 int snum;
08220
08221 DEBUG(5,("_spoolss_resetprinter\n"));
08222
08223
08224
08225
08226
08227
08228
08229 if (!Printer) {
08230 DEBUG(2,("_spoolss_resetprinter: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
08231 return WERR_BADFID;
08232 }
08233
08234 if (!get_printer_snum(p,handle, &snum))
08235 return WERR_BADFID;
08236
08237
08238
08239 return WERR_OK;
08240 }
08241
08242
08243
08244
08245
08246 WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_u, SPOOL_R_DELETEPRINTERDATA *r_u)
08247 {
08248 POLICY_HND *handle = &q_u->handle;
08249 UNISTR2 *value = &q_u->valuename;
08250
08251 NT_PRINTER_INFO_LEVEL *printer = NULL;
08252 int snum=0;
08253 WERROR status = WERR_OK;
08254 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
08255 pstring valuename;
08256
08257 DEBUG(5,("spoolss_deleteprinterdata\n"));
08258
08259 if (!Printer) {
08260 DEBUG(2,("_spoolss_deleteprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
08261 return WERR_BADFID;
08262 }
08263
08264 if (!get_printer_snum(p, handle, &snum))
08265 return WERR_BADFID;
08266
08267 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
08268 DEBUG(3, ("_spoolss_deleteprinterdata: printer properties change denied by handle\n"));
08269 return WERR_ACCESS_DENIED;
08270 }
08271
08272 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
08273 if (!W_ERROR_IS_OK(status))
08274 return status;
08275
08276 unistr2_to_ascii( valuename, value, sizeof(valuename)-1 );
08277
08278 status = delete_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename );
08279
08280 if ( W_ERROR_IS_OK(status) )
08281 mod_a_printer( printer, 2 );
08282
08283 free_a_printer(&printer, 2);
08284
08285 return status;
08286 }
08287
08288
08289
08290
08291 WERROR _spoolss_addform( pipes_struct *p, SPOOL_Q_ADDFORM *q_u, SPOOL_R_ADDFORM *r_u)
08292 {
08293 POLICY_HND *handle = &q_u->handle;
08294 FORM *form = &q_u->form;
08295 nt_forms_struct tmpForm;
08296 int snum;
08297 WERROR status = WERR_OK;
08298 NT_PRINTER_INFO_LEVEL *printer = NULL;
08299
08300 int count=0;
08301 nt_forms_struct *list=NULL;
08302 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
08303
08304 DEBUG(5,("spoolss_addform\n"));
08305
08306 if (!Printer) {
08307 DEBUG(2,("_spoolss_addform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
08308 return WERR_BADFID;
08309 }
08310
08311
08312
08313
08314 if ( Printer->printer_type == SPLHND_PRINTER )
08315 {
08316 if (!get_printer_snum(p,handle, &snum))
08317 return WERR_BADFID;
08318
08319 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
08320 if (!W_ERROR_IS_OK(status))
08321 goto done;
08322 }
08323
08324 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
08325 DEBUG(2,("_spoolss_addform: denied by handle permissions.\n"));
08326 status = WERR_ACCESS_DENIED;
08327 goto done;
08328 }
08329
08330
08331
08332 if (get_a_builtin_ntform(&form->name,&tmpForm)) {
08333 status = WERR_ALREADY_EXISTS;
08334 goto done;
08335 }
08336
08337 count = get_ntforms(&list);
08338
08339 if(!add_a_form(&list, form, &count)) {
08340 status = WERR_NOMEM;
08341 goto done;
08342 }
08343
08344 write_ntforms(&list, count);
08345
08346
08347
08348
08349
08350 if ( Printer->printer_type == SPLHND_PRINTER )
08351 status = mod_a_printer(printer, 2);
08352
08353 done:
08354 if ( printer )
08355 free_a_printer(&printer, 2);
08356 SAFE_FREE(list);
08357
08358 return status;
08359 }
08360
08361
08362
08363
08364 WERROR _spoolss_deleteform( pipes_struct *p, SPOOL_Q_DELETEFORM *q_u, SPOOL_R_DELETEFORM *r_u)
08365 {
08366 POLICY_HND *handle = &q_u->handle;
08367 UNISTR2 *form_name = &q_u->name;
08368 nt_forms_struct tmpForm;
08369 int count=0;
08370 nt_forms_struct *list=NULL;
08371 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
08372 int snum;
08373 WERROR status = WERR_OK;
08374 NT_PRINTER_INFO_LEVEL *printer = NULL;
08375
08376 DEBUG(5,("spoolss_deleteform\n"));
08377
08378 if (!Printer) {
08379 DEBUG(2,("_spoolss_deleteform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
08380 return WERR_BADFID;
08381 }
08382
08383
08384
08385 if ( Printer->printer_type == SPLHND_PRINTER )
08386 {
08387 if (!get_printer_snum(p,handle, &snum))
08388 return WERR_BADFID;
08389
08390 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
08391 if (!W_ERROR_IS_OK(status))
08392 goto done;
08393 }
08394
08395 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
08396 DEBUG(2,("_spoolss_deleteform: denied by handle permissions.\n"));
08397 status = WERR_ACCESS_DENIED;
08398 goto done;
08399 }
08400
08401
08402
08403 if (get_a_builtin_ntform(form_name,&tmpForm)) {
08404 status = WERR_INVALID_PARAM;
08405 goto done;
08406 }
08407
08408 count = get_ntforms(&list);
08409
08410 if ( !delete_a_form(&list, form_name, &count, &status ))
08411 goto done;
08412
08413
08414
08415
08416
08417 if ( Printer->printer_type == SPLHND_PRINTER )
08418 status = mod_a_printer(printer, 2);
08419
08420 done:
08421 if ( printer )
08422 free_a_printer(&printer, 2);
08423 SAFE_FREE(list);
08424
08425 return status;
08426 }
08427
08428
08429
08430
08431 WERROR _spoolss_setform(pipes_struct *p, SPOOL_Q_SETFORM *q_u, SPOOL_R_SETFORM *r_u)
08432 {
08433 POLICY_HND *handle = &q_u->handle;
08434 FORM *form = &q_u->form;
08435 nt_forms_struct tmpForm;
08436 int snum;
08437 WERROR status = WERR_OK;
08438 NT_PRINTER_INFO_LEVEL *printer = NULL;
08439
08440 int count=0;
08441 nt_forms_struct *list=NULL;
08442 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
08443
08444 DEBUG(5,("spoolss_setform\n"));
08445
08446 if (!Printer) {
08447 DEBUG(2,("_spoolss_setform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
08448 return WERR_BADFID;
08449 }
08450
08451
08452
08453 if ( Printer->printer_type == SPLHND_PRINTER )
08454 {
08455 if (!get_printer_snum(p,handle, &snum))
08456 return WERR_BADFID;
08457
08458 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
08459 if (!W_ERROR_IS_OK(status))
08460 goto done;
08461 }
08462
08463 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
08464 DEBUG(2,("_spoolss_setform: denied by handle permissions\n"));
08465 status = WERR_ACCESS_DENIED;
08466 goto done;
08467 }
08468
08469
08470 if (get_a_builtin_ntform(&form->name,&tmpForm)) {
08471 status = WERR_INVALID_PARAM;
08472 goto done;
08473 }
08474
08475 count = get_ntforms(&list);
08476 update_a_form(&list, form, count);
08477 write_ntforms(&list, count);
08478
08479
08480
08481
08482
08483 if ( Printer->printer_type == SPLHND_PRINTER )
08484 status = mod_a_printer(printer, 2);
08485
08486
08487 done:
08488 if ( printer )
08489 free_a_printer(&printer, 2);
08490 SAFE_FREE(list);
08491
08492 return status;
08493 }
08494
08495
08496
08497
08498
08499 static WERROR enumprintprocessors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
08500 {
08501 PRINTPROCESSOR_1 *info_1=NULL;
08502 WERROR result = WERR_OK;
08503
08504 if((info_1 = SMB_MALLOC_P(PRINTPROCESSOR_1)) == NULL)
08505 return WERR_NOMEM;
08506
08507 (*returned) = 0x1;
08508
08509 init_unistr(&info_1->name, "winprint");
08510
08511 *needed += spoolss_size_printprocessor_info_1(info_1);
08512
08513 if (*needed > offered) {
08514 result = WERR_INSUFFICIENT_BUFFER;
08515 goto out;
08516 }
08517
08518 if (!rpcbuf_alloc_size(buffer, *needed)) {
08519 result = WERR_NOMEM;
08520 goto out;
08521 }
08522
08523 smb_io_printprocessor_info_1("", buffer, info_1, 0);
08524
08525 out:
08526 SAFE_FREE(info_1);
08527
08528 if ( !W_ERROR_IS_OK(result) )
08529 *returned = 0;
08530
08531 return result;
08532 }
08533
08534
08535
08536
08537 WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
08538 {
08539 uint32 level = q_u->level;
08540 RPC_BUFFER *buffer = NULL;
08541 uint32 offered = q_u->offered;
08542 uint32 *needed = &r_u->needed;
08543 uint32 *returned = &r_u->returned;
08544
08545
08546
08547 if (!q_u->buffer && (offered!=0)) {
08548 return WERR_INVALID_PARAM;
08549 }
08550
08551 rpcbuf_move(q_u->buffer, &r_u->buffer);
08552 buffer = r_u->buffer;
08553
08554 DEBUG(5,("spoolss_enumprintprocessors\n"));
08555
08556
08557
08558
08559
08560
08561
08562
08563 *returned=0;
08564 *needed=0;
08565
08566 switch (level) {
08567 case 1:
08568 return enumprintprocessors_level_1(buffer, offered, needed, returned);
08569 default:
08570 return WERR_UNKNOWN_LEVEL;
08571 }
08572 }
08573
08574
08575
08576
08577
08578 static WERROR enumprintprocdatatypes_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
08579 {
08580 PRINTPROCDATATYPE_1 *info_1=NULL;
08581 WERROR result = WERR_OK;
08582
08583 if((info_1 = SMB_MALLOC_P(PRINTPROCDATATYPE_1)) == NULL)
08584 return WERR_NOMEM;
08585
08586 (*returned) = 0x1;
08587
08588 init_unistr(&info_1->name, "RAW");
08589
08590 *needed += spoolss_size_printprocdatatype_info_1(info_1);
08591
08592 if (*needed > offered) {
08593 result = WERR_INSUFFICIENT_BUFFER;
08594 goto out;
08595 }
08596
08597 if (!rpcbuf_alloc_size(buffer, *needed)) {
08598 result = WERR_NOMEM;
08599 goto out;
08600 }
08601
08602 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
08603
08604 out:
08605 SAFE_FREE(info_1);
08606
08607 if ( !W_ERROR_IS_OK(result) )
08608 *returned = 0;
08609
08610 return result;
08611 }
08612
08613
08614
08615
08616 WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
08617 {
08618 uint32 level = q_u->level;
08619 RPC_BUFFER *buffer = NULL;
08620 uint32 offered = q_u->offered;
08621 uint32 *needed = &r_u->needed;
08622 uint32 *returned = &r_u->returned;
08623
08624
08625
08626 if (!q_u->buffer && (offered!=0)) {
08627 return WERR_INVALID_PARAM;
08628 }
08629
08630 rpcbuf_move(q_u->buffer, &r_u->buffer);
08631 buffer = r_u->buffer;
08632
08633 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
08634
08635 *returned=0;
08636 *needed=0;
08637
08638 switch (level) {
08639 case 1:
08640 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
08641 default:
08642 return WERR_UNKNOWN_LEVEL;
08643 }
08644 }
08645
08646
08647
08648
08649
08650 static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
08651 {
08652 PRINTMONITOR_1 *info_1;
08653 WERROR result = WERR_OK;
08654 int i;
08655
08656 if((info_1 = SMB_MALLOC_ARRAY(PRINTMONITOR_1, 2)) == NULL)
08657 return WERR_NOMEM;
08658
08659 *returned = 2;
08660
08661 init_unistr(&(info_1[0].name), SPL_LOCAL_PORT );
08662 init_unistr(&(info_1[1].name), SPL_TCPIP_PORT );
08663
08664 for ( i=0; i<*returned; i++ ) {
08665 *needed += spoolss_size_printmonitor_info_1(&info_1[i]);
08666 }
08667
08668 if (*needed > offered) {
08669 result = WERR_INSUFFICIENT_BUFFER;
08670 goto out;
08671 }
08672
08673 if (!rpcbuf_alloc_size(buffer, *needed)) {
08674 result = WERR_NOMEM;
08675 goto out;
08676 }
08677
08678 for ( i=0; i<*returned; i++ ) {
08679 smb_io_printmonitor_info_1("", buffer, &info_1[i], 0);
08680 }
08681
08682 out:
08683 SAFE_FREE(info_1);
08684
08685 if ( !W_ERROR_IS_OK(result) )
08686 *returned = 0;
08687
08688 return result;
08689 }
08690
08691
08692
08693
08694
08695 static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
08696 {
08697 PRINTMONITOR_2 *info_2;
08698 WERROR result = WERR_OK;
08699 int i;
08700
08701 if((info_2 = SMB_MALLOC_ARRAY(PRINTMONITOR_2, 2)) == NULL)
08702 return WERR_NOMEM;
08703
08704 *returned = 2;
08705
08706 init_unistr( &(info_2[0].name), SPL_LOCAL_PORT );
08707 init_unistr( &(info_2[0].environment), "Windows NT X86" );
08708 init_unistr( &(info_2[0].dll_name), "localmon.dll" );
08709
08710 init_unistr( &(info_2[1].name), SPL_TCPIP_PORT );
08711 init_unistr( &(info_2[1].environment), "Windows NT X86" );
08712 init_unistr( &(info_2[1].dll_name), "tcpmon.dll" );
08713
08714 for ( i=0; i<*returned; i++ ) {
08715 *needed += spoolss_size_printmonitor_info_2(&info_2[i]);
08716 }
08717
08718 if (*needed > offered) {
08719 result = WERR_INSUFFICIENT_BUFFER;
08720 goto out;
08721 }
08722
08723 if (!rpcbuf_alloc_size(buffer, *needed)) {
08724 result = WERR_NOMEM;
08725 goto out;
08726 }
08727
08728 for ( i=0; i<*returned; i++ ) {
08729 smb_io_printmonitor_info_2("", buffer, &info_2[i], 0);
08730 }
08731
08732 out:
08733 SAFE_FREE(info_2);
08734
08735 if ( !W_ERROR_IS_OK(result) )
08736 *returned = 0;
08737
08738 return result;
08739 }
08740
08741
08742
08743
08744 WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
08745 {
08746 uint32 level = q_u->level;
08747 RPC_BUFFER *buffer = NULL;
08748 uint32 offered = q_u->offered;
08749 uint32 *needed = &r_u->needed;
08750 uint32 *returned = &r_u->returned;
08751
08752
08753
08754 if (!q_u->buffer && (offered!=0)) {
08755 return WERR_INVALID_PARAM;
08756 }
08757
08758 rpcbuf_move(q_u->buffer, &r_u->buffer);
08759 buffer = r_u->buffer;
08760
08761 DEBUG(5,("spoolss_enumprintmonitors\n"));
08762
08763
08764
08765
08766
08767
08768
08769
08770 *returned=0;
08771 *needed=0;
08772
08773 switch (level) {
08774 case 1:
08775 return enumprintmonitors_level_1(buffer, offered, needed, returned);
08776 case 2:
08777 return enumprintmonitors_level_2(buffer, offered, needed, returned);
08778 default:
08779 return WERR_UNKNOWN_LEVEL;
08780 }
08781 }
08782
08783
08784
08785
08786 static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum,
08787 NT_PRINTER_INFO_LEVEL *ntprinter,
08788 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
08789 uint32 *needed)
08790 {
08791 int i=0;
08792 BOOL found=False;
08793 JOB_INFO_1 *info_1=NULL;
08794 WERROR result = WERR_OK;
08795
08796 info_1=SMB_MALLOC_P(JOB_INFO_1);
08797
08798 if (info_1 == NULL) {
08799 return WERR_NOMEM;
08800 }
08801
08802 for (i=0; i<count && found==False; i++) {
08803 if ((*queue)[i].job==(int)jobid)
08804 found=True;
08805 }
08806
08807 if (found==False) {
08808 SAFE_FREE(info_1);
08809
08810 return WERR_INVALID_PARAM;
08811 }
08812
08813 fill_job_info_1( info_1, &((*queue)[i-1]), i, snum, ntprinter );
08814
08815 *needed += spoolss_size_job_info_1(info_1);
08816
08817 if (*needed > offered) {
08818 result = WERR_INSUFFICIENT_BUFFER;
08819 goto out;
08820 }
08821
08822 if (!rpcbuf_alloc_size(buffer, *needed)) {
08823 result = WERR_NOMEM;
08824 goto out;
08825 }
08826
08827 smb_io_job_info_1("", buffer, info_1, 0);
08828
08829 out:
08830 SAFE_FREE(info_1);
08831
08832 return result;
08833 }
08834
08835
08836
08837
08838 static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
08839 NT_PRINTER_INFO_LEVEL *ntprinter,
08840 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
08841 uint32 *needed)
08842 {
08843 int i = 0;
08844 BOOL found = False;
08845 JOB_INFO_2 *info_2;
08846 WERROR result;
08847 DEVICEMODE *devmode = NULL;
08848 NT_DEVICEMODE *nt_devmode = NULL;
08849
08850 if ( !(info_2=SMB_MALLOC_P(JOB_INFO_2)) )
08851 return WERR_NOMEM;
08852
08853 ZERO_STRUCTP(info_2);
08854
08855 for ( i=0; i<count && found==False; i++ )
08856 {
08857 if ((*queue)[i].job == (int)jobid)
08858 found = True;
08859 }
08860
08861 if ( !found ) {
08862
08863
08864 result = WERR_INVALID_PARAM;
08865 goto done;
08866 }
08867
08868
08869
08870
08871
08872
08873
08874 if ( !(nt_devmode=print_job_devmode( lp_const_servicename(snum), jobid )) )
08875 devmode = construct_dev_mode(lp_const_servicename(snum));
08876 else {
08877 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) != NULL) {
08878 ZERO_STRUCTP( devmode );
08879 convert_nt_devicemode( devmode, nt_devmode );
08880 }
08881 }
08882
08883 fill_job_info_2(info_2, &((*queue)[i-1]), i, snum, ntprinter, devmode);
08884
08885 *needed += spoolss_size_job_info_2(info_2);
08886
08887 if (*needed > offered) {
08888 result = WERR_INSUFFICIENT_BUFFER;
08889 goto done;
08890 }
08891
08892 if (!rpcbuf_alloc_size(buffer, *needed)) {
08893 result = WERR_NOMEM;
08894 goto done;
08895 }
08896
08897 smb_io_job_info_2("", buffer, info_2, 0);
08898
08899 result = WERR_OK;
08900
08901 done:
08902
08903
08904 free_job_info_2(info_2);
08905 SAFE_FREE(info_2);
08906
08907 return result;
08908 }
08909
08910
08911
08912
08913 WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u)
08914 {
08915 POLICY_HND *handle = &q_u->handle;
08916 uint32 jobid = q_u->jobid;
08917 uint32 level = q_u->level;
08918 RPC_BUFFER *buffer = NULL;
08919 uint32 offered = q_u->offered;
08920 uint32 *needed = &r_u->needed;
08921 WERROR wstatus = WERR_OK;
08922 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
08923 int snum;
08924 int count;
08925 print_queue_struct *queue = NULL;
08926 print_status_struct prt_status;
08927
08928
08929
08930 if (!q_u->buffer && (offered!=0)) {
08931 return WERR_INVALID_PARAM;
08932 }
08933
08934 rpcbuf_move(q_u->buffer, &r_u->buffer);
08935 buffer = r_u->buffer;
08936
08937 DEBUG(5,("spoolss_getjob\n"));
08938
08939 *needed = 0;
08940
08941 if (!get_printer_snum(p, handle, &snum))
08942 return WERR_BADFID;
08943
08944 wstatus = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
08945 if ( !W_ERROR_IS_OK(wstatus) )
08946 return wstatus;
08947
08948 count = print_queue_status(snum, &queue, &prt_status);
08949
08950 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
08951 count, prt_status.status, prt_status.message));
08952
08953 switch ( level ) {
08954 case 1:
08955 wstatus = getjob_level_1(&queue, count, snum, ntprinter, jobid,
08956 buffer, offered, needed);
08957 break;
08958 case 2:
08959 wstatus = getjob_level_2(&queue, count, snum, ntprinter, jobid,
08960 buffer, offered, needed);
08961 break;
08962 default:
08963 wstatus = WERR_UNKNOWN_LEVEL;
08964 break;
08965 }
08966
08967 SAFE_FREE(queue);
08968 free_a_printer( &ntprinter, 2 );
08969
08970 return wstatus;
08971 }
08972
08973
08974
08975
08976
08977
08978
08979
08980 WERROR _spoolss_getprinterdataex(pipes_struct *p, SPOOL_Q_GETPRINTERDATAEX *q_u, SPOOL_R_GETPRINTERDATAEX *r_u)
08981 {
08982 POLICY_HND *handle = &q_u->handle;
08983 uint32 in_size = q_u->size;
08984 uint32 *type = &r_u->type;
08985 uint32 *out_size = &r_u->size;
08986 uint8 **data = &r_u->data;
08987 uint32 *needed = &r_u->needed;
08988 fstring keyname, valuename;
08989
08990 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
08991
08992 NT_PRINTER_INFO_LEVEL *printer = NULL;
08993 int snum = 0;
08994 WERROR status = WERR_OK;
08995
08996 DEBUG(4,("_spoolss_getprinterdataex\n"));
08997
08998 unistr2_to_ascii(keyname, &q_u->keyname, sizeof(keyname) - 1);
08999 unistr2_to_ascii(valuename, &q_u->valuename, sizeof(valuename) - 1);
09000
09001 DEBUG(10, ("_spoolss_getprinterdataex: key => [%s], value => [%s]\n",
09002 keyname, valuename));
09003
09004
09005
09006 *needed = 0;
09007 *type = 0;
09008 *out_size = in_size;
09009
09010 if (!Printer) {
09011 DEBUG(2,("_spoolss_getprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
09012 status = WERR_BADFID;
09013 goto done;
09014 }
09015
09016
09017
09018 if (Printer->printer_type == SPLHND_SERVER) {
09019 DEBUG(10,("_spoolss_getprinterdataex: Not implemented for server handles yet\n"));
09020 status = WERR_INVALID_PARAM;
09021 goto done;
09022 }
09023
09024 if ( !get_printer_snum(p,handle, &snum) )
09025 return WERR_BADFID;
09026
09027 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
09028 if ( !W_ERROR_IS_OK(status) )
09029 goto done;
09030
09031
09032 if ( !strlen(keyname) ) {
09033 status = WERR_INVALID_PARAM;
09034 goto done;
09035 }
09036
09037 if ( lookup_printerkey( printer->info_2->data, keyname ) == -1 ) {
09038 DEBUG(4,("_spoolss_getprinterdataex: Invalid keyname [%s]\n", keyname ));
09039 free_a_printer( &printer, 2 );
09040 status = WERR_BADFILE;
09041 goto done;
09042 }
09043
09044
09045
09046 status = get_printer_dataex( p->mem_ctx, printer, keyname, valuename, type, data, needed, in_size );
09047
09048 if (*needed > *out_size)
09049 status = WERR_MORE_DATA;
09050
09051 done:
09052 if ( !W_ERROR_IS_OK(status) )
09053 {
09054 DEBUG(5, ("error: allocating %d\n", *out_size));
09055
09056
09057
09058 if ( *out_size )
09059 {
09060 if( (*data=(uint8 *)TALLOC_ZERO(p->mem_ctx, *out_size*sizeof(uint8))) == NULL ) {
09061 status = WERR_NOMEM;
09062 goto done;
09063 }
09064 } else {
09065 *data = NULL;
09066 }
09067 }
09068
09069 if ( printer )
09070 free_a_printer( &printer, 2 );
09071
09072 return status;
09073 }
09074
09075
09076
09077
09078
09079 WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u, SPOOL_R_SETPRINTERDATAEX *r_u)
09080 {
09081 POLICY_HND *handle = &q_u->handle;
09082 uint32 type = q_u->type;
09083 uint8 *data = q_u->data;
09084 uint32 real_len = q_u->real_len;
09085
09086 NT_PRINTER_INFO_LEVEL *printer = NULL;
09087 int snum = 0;
09088 WERROR status = WERR_OK;
09089 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
09090 fstring valuename;
09091 fstring keyname;
09092 char *oid_string;
09093
09094 DEBUG(4,("_spoolss_setprinterdataex\n"));
09095
09096
09097
09098
09099 if (!Printer) {
09100 DEBUG(2,("_spoolss_setprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
09101 return WERR_BADFID;
09102 }
09103
09104 if ( Printer->printer_type == SPLHND_SERVER ) {
09105 DEBUG(10,("_spoolss_setprinterdataex: Not implemented for server handles yet\n"));
09106 return WERR_INVALID_PARAM;
09107 }
09108
09109 if ( !get_printer_snum(p,handle, &snum) )
09110 return WERR_BADFID;
09111
09112
09113
09114
09115
09116
09117
09118
09119
09120 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
09121 {
09122 DEBUG(3, ("_spoolss_setprinterdataex: change denied by handle access permissions\n"));
09123 return WERR_ACCESS_DENIED;
09124 }
09125
09126 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
09127 if (!W_ERROR_IS_OK(status))
09128 return status;
09129
09130 unistr2_to_ascii( valuename, &q_u->value, sizeof(valuename) - 1);
09131 unistr2_to_ascii( keyname, &q_u->key, sizeof(keyname) - 1);
09132
09133
09134
09135 if ( (oid_string = strchr( valuename, ',' )) != NULL )
09136 {
09137 *oid_string = '\0';
09138 oid_string++;
09139 }
09140
09141
09142
09143 status = set_printer_dataex( printer, keyname, valuename, type, data, real_len );
09144
09145 if ( W_ERROR_IS_OK(status) )
09146 {
09147
09148 if ( oid_string ) {
09149 fstrcat( keyname, "\\" );
09150 fstrcat( keyname, SPOOL_OID_KEY );
09151
09152
09153
09154
09155
09156
09157
09158
09159 set_printer_dataex( printer, keyname, valuename,
09160 REG_SZ, (void*)oid_string, strlen(oid_string)+1 );
09161 }
09162
09163 status = mod_a_printer(printer, 2);
09164 }
09165
09166 free_a_printer(&printer, 2);
09167
09168 return status;
09169 }
09170
09171
09172
09173
09174
09175
09176 WERROR _spoolss_deleteprinterdataex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATAEX *q_u, SPOOL_R_DELETEPRINTERDATAEX *r_u)
09177 {
09178 POLICY_HND *handle = &q_u->handle;
09179 UNISTR2 *value = &q_u->valuename;
09180 UNISTR2 *key = &q_u->keyname;
09181
09182 NT_PRINTER_INFO_LEVEL *printer = NULL;
09183 int snum=0;
09184 WERROR status = WERR_OK;
09185 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
09186 pstring valuename, keyname;
09187
09188 DEBUG(5,("spoolss_deleteprinterdataex\n"));
09189
09190 if (!Printer) {
09191 DEBUG(2,("_spoolss_deleteprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
09192 return WERR_BADFID;
09193 }
09194
09195 if (!get_printer_snum(p, handle, &snum))
09196 return WERR_BADFID;
09197
09198 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
09199 DEBUG(3, ("_spoolss_deleteprinterdataex: printer properties change denied by handle\n"));
09200 return WERR_ACCESS_DENIED;
09201 }
09202
09203 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
09204 if (!W_ERROR_IS_OK(status))
09205 return status;
09206
09207 unistr2_to_ascii( valuename, value, sizeof(valuename)-1 );
09208 unistr2_to_ascii( keyname, key, sizeof(keyname)-1 );
09209
09210 status = delete_printer_dataex( printer, keyname, valuename );
09211
09212 if ( W_ERROR_IS_OK(status) )
09213 mod_a_printer( printer, 2 );
09214
09215 free_a_printer(&printer, 2);
09216
09217 return status;
09218 }
09219
09220
09221
09222
09223
09224
09225 WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u)
09226 {
09227 fstring key;
09228 fstring *keynames = NULL;
09229 uint16 *enumkeys = NULL;
09230 int num_keys;
09231 int printerkey_len;
09232 POLICY_HND *handle = &q_u->handle;
09233 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
09234 NT_PRINTER_DATA *data;
09235 NT_PRINTER_INFO_LEVEL *printer = NULL;
09236 int snum = 0;
09237 WERROR status = WERR_BADFILE;
09238
09239
09240 DEBUG(4,("_spoolss_enumprinterkey\n"));
09241
09242 if (!Printer) {
09243 DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
09244 return WERR_BADFID;
09245 }
09246
09247 if ( !get_printer_snum(p,handle, &snum) )
09248 return WERR_BADFID;
09249
09250 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
09251 if (!W_ERROR_IS_OK(status))
09252 return status;
09253
09254
09255
09256 unistr2_to_ascii( key, &q_u->key, sizeof(key)-1 );
09257 data = printer->info_2->data;
09258
09259 num_keys = get_printer_subkeys( data, key, &keynames );
09260
09261 if ( num_keys == -1 ) {
09262 status = WERR_BADFILE;
09263 goto done;
09264 }
09265
09266 printerkey_len = init_unistr_array( &enumkeys, keynames, NULL );
09267
09268 r_u->needed = printerkey_len*2;
09269
09270 if ( q_u->size < r_u->needed ) {
09271 status = WERR_MORE_DATA;
09272 goto done;
09273 }
09274
09275 if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys)) {
09276 status = WERR_NOMEM;
09277 goto done;
09278 }
09279
09280 status = WERR_OK;
09281
09282 if ( q_u->size < r_u->needed )
09283 status = WERR_MORE_DATA;
09284
09285 done:
09286 free_a_printer( &printer, 2 );
09287 SAFE_FREE( keynames );
09288
09289 return status;
09290 }
09291
09292
09293
09294
09295
09296 WERROR _spoolss_deleteprinterkey(pipes_struct *p, SPOOL_Q_DELETEPRINTERKEY *q_u, SPOOL_R_DELETEPRINTERKEY *r_u)
09297 {
09298 POLICY_HND *handle = &q_u->handle;
09299 Printer_entry *Printer = find_printer_index_by_hnd(p, &q_u->handle);
09300 fstring key;
09301 NT_PRINTER_INFO_LEVEL *printer = NULL;
09302 int snum=0;
09303 WERROR status;
09304
09305 DEBUG(5,("spoolss_deleteprinterkey\n"));
09306
09307 if (!Printer) {
09308 DEBUG(2,("_spoolss_deleteprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
09309 return WERR_BADFID;
09310 }
09311
09312
09313
09314 if ( !q_u->keyname.buffer )
09315 return WERR_INVALID_PARAM;
09316
09317 if (!get_printer_snum(p, handle, &snum))
09318 return WERR_BADFID;
09319
09320 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
09321 DEBUG(3, ("_spoolss_deleteprinterkey: printer properties change denied by handle\n"));
09322 return WERR_ACCESS_DENIED;
09323 }
09324
09325 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
09326 if (!W_ERROR_IS_OK(status))
09327 return status;
09328
09329
09330
09331 unistr2_to_ascii(key, &q_u->keyname, sizeof(key) - 1);
09332
09333 status = delete_all_printer_data( printer->info_2, key );
09334
09335 if ( W_ERROR_IS_OK(status) )
09336 status = mod_a_printer(printer, 2);
09337
09338 free_a_printer( &printer, 2 );
09339
09340 return status;
09341 }
09342
09343
09344
09345
09346
09347
09348 WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u)
09349 {
09350 POLICY_HND *handle = &q_u->handle;
09351 uint32 in_size = q_u->size;
09352 uint32 num_entries,
09353 needed;
09354 NT_PRINTER_INFO_LEVEL *printer = NULL;
09355 PRINTER_ENUM_VALUES *enum_values = NULL;
09356 NT_PRINTER_DATA *p_data;
09357 fstring key;
09358 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
09359 int snum;
09360 WERROR result;
09361 int key_index;
09362 int i;
09363 REGISTRY_VALUE *val;
09364 char *value_name;
09365 uint32 data_len;
09366
09367
09368 DEBUG(4,("_spoolss_enumprinterdataex\n"));
09369
09370 if (!Printer) {
09371 DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle)));
09372 return WERR_BADFID;
09373 }
09374
09375
09376
09377
09378
09379
09380
09381
09382 unistr2_to_ascii(key, &q_u->key, sizeof(key) - 1);
09383 if ( !strlen(key) ) {
09384 result = WERR_INVALID_PARAM;
09385 goto done;
09386 }
09387
09388
09389
09390 if (!get_printer_snum(p,handle, &snum))
09391 return WERR_BADFID;
09392
09393 ZERO_STRUCT(printer);
09394 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
09395 if (!W_ERROR_IS_OK(result))
09396 return result;
09397
09398
09399
09400 p_data = printer->info_2->data;
09401
09402 unistr2_to_ascii(key, &q_u->key, sizeof(key) - 1);
09403 if ( (key_index = lookup_printerkey( p_data, key)) == -1 )
09404 {
09405 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key));
09406 result = WERR_INVALID_PARAM;
09407 goto done;
09408 }
09409
09410 result = WERR_OK;
09411 needed = 0;
09412
09413
09414
09415 num_entries = regval_ctr_numvals( p_data->keys[key_index].values );
09416 if ( num_entries )
09417 {
09418 if ( (enum_values=TALLOC_ARRAY(p->mem_ctx, PRINTER_ENUM_VALUES, num_entries)) == NULL )
09419 {
09420 DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
09421 (unsigned long)num_entries*sizeof(PRINTER_ENUM_VALUES)));
09422 result = WERR_NOMEM;
09423 goto done;
09424 }
09425
09426 memset( enum_values, 0x0, num_entries*sizeof(PRINTER_ENUM_VALUES) );
09427 }
09428
09429
09430
09431
09432
09433
09434 for ( i=0; i<num_entries; i++ )
09435 {
09436
09437
09438 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
09439 DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val) ));
09440
09441
09442
09443 value_name = regval_name( val );
09444 init_unistr( &enum_values[i].valuename, value_name );
09445 enum_values[i].value_len = (strlen(value_name)+1) * 2;
09446 enum_values[i].type = regval_type( val );
09447
09448 data_len = regval_size( val );
09449 if ( data_len ) {
09450 if ( !(enum_values[i].data = TALLOC_MEMDUP(p->mem_ctx, regval_data_p(val), data_len)) )
09451 {
09452 DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n",
09453 data_len ));
09454 result = WERR_NOMEM;
09455 goto done;
09456 }
09457 }
09458 enum_values[i].data_len = data_len;
09459
09460
09461
09462 needed += spoolss_size_printer_enum_values(&enum_values[i]);
09463 }
09464
09465
09466
09467
09468
09469
09470
09471
09472 if (needed % 4) {
09473 needed += 4-(needed % 4);
09474 }
09475
09476 r_u->needed = needed;
09477 r_u->returned = num_entries;
09478
09479 if (needed > in_size) {
09480 result = WERR_MORE_DATA;
09481 goto done;
09482 }
09483
09484
09485
09486
09487
09488
09489
09490
09491 r_u->ctr.size = in_size;
09492
09493 r_u->ctr.size_of_array = r_u->returned;
09494 r_u->ctr.values = enum_values;
09495
09496
09497
09498 done:
09499 if ( printer )
09500 free_a_printer(&printer, 2);
09501
09502 return result;
09503 }
09504
09505
09506
09507
09508 static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1 *info, char *name)
09509 {
09510 init_unistr(&info->name, name);
09511 }
09512
09513 static WERROR getprintprocessordirectory_level_1(UNISTR2 *name,
09514 UNISTR2 *environment,
09515 RPC_BUFFER *buffer,
09516 uint32 offered,
09517 uint32 *needed)
09518 {
09519 pstring path;
09520 pstring long_archi;
09521 PRINTPROCESSOR_DIRECTORY_1 *info=NULL;
09522 WERROR result = WERR_OK;
09523
09524 unistr2_to_ascii(long_archi, environment, sizeof(long_archi)-1);
09525
09526 if (!get_short_archi(long_archi))
09527 return WERR_INVALID_ENVIRONMENT;
09528
09529 if((info=SMB_MALLOC_P(PRINTPROCESSOR_DIRECTORY_1)) == NULL)
09530 return WERR_NOMEM;
09531
09532 pstrcpy(path, "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86");
09533
09534 fill_printprocessordirectory_1(info, path);
09535
09536 *needed += spoolss_size_printprocessordirectory_info_1(info);
09537
09538 if (*needed > offered) {
09539 result = WERR_INSUFFICIENT_BUFFER;
09540 goto out;
09541 }
09542
09543 if (!rpcbuf_alloc_size(buffer, *needed)) {
09544 result = WERR_INSUFFICIENT_BUFFER;
09545 goto out;
09546 }
09547
09548 smb_io_printprocessordirectory_1("", buffer, info, 0);
09549
09550 out:
09551 SAFE_FREE(info);
09552
09553 return result;
09554 }
09555
09556 WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u)
09557 {
09558 uint32 level = q_u->level;
09559 RPC_BUFFER *buffer = NULL;
09560 uint32 offered = q_u->offered;
09561 uint32 *needed = &r_u->needed;
09562 WERROR result;
09563
09564
09565
09566 if (!q_u->buffer && (offered!=0)) {
09567 return WERR_INVALID_PARAM;
09568 }
09569
09570 rpcbuf_move(q_u->buffer, &r_u->buffer);
09571 buffer = r_u->buffer;
09572
09573 DEBUG(5,("_spoolss_getprintprocessordirectory\n"));
09574
09575 *needed=0;
09576
09577 switch(level) {
09578 case 1:
09579 result = getprintprocessordirectory_level_1
09580 (&q_u->name, &q_u->environment, buffer, offered, needed);
09581 break;
09582 default:
09583 result = WERR_UNKNOWN_LEVEL;
09584 }
09585
09586 return result;
09587 }
09588
09589
09590
09591
09592
09593 static WERROR xcvtcp_monitorui( NT_USER_TOKEN *token, RPC_BUFFER *in,
09594 RPC_BUFFER *out, uint32 *needed )
09595 {
09596 const char *dllname = "tcpmonui.dll";
09597
09598 *needed = (strlen(dllname)+1) * 2;
09599
09600 if ( rpcbuf_get_size(out) < *needed ) {
09601 return WERR_INSUFFICIENT_BUFFER;
09602 }
09603
09604 if ( !make_monitorui_buf( out, dllname ) ) {
09605 return WERR_NOMEM;
09606 }
09607
09608 return WERR_OK;
09609 }
09610
09611
09612
09613
09614
09615 static WERROR xcvtcp_addport( NT_USER_TOKEN *token, RPC_BUFFER *in,
09616 RPC_BUFFER *out, uint32 *needed )
09617 {
09618 NT_PORT_DATA_1 port1;
09619 pstring device_uri;
09620
09621 ZERO_STRUCT( port1 );
09622
09623
09624
09625 if ( !convert_port_data_1( &port1, in ) ) {
09626 return WERR_NOMEM;
09627 }
09628
09629
09630
09631 switch ( port1.protocol ) {
09632 case PORT_PROTOCOL_DIRECT:
09633 pstr_sprintf( device_uri, "socket://%s:%d/", port1.hostaddr, port1.port );
09634 break;
09635
09636 case PORT_PROTOCOL_LPR:
09637 pstr_sprintf( device_uri, "lpr://%s/%s", port1.hostaddr, port1.queue );
09638 break;
09639
09640 default:
09641 return WERR_UNKNOWN_PORT;
09642 }
09643
09644 return add_port_hook( token, port1.name, device_uri );
09645 }
09646
09647
09648
09649
09650 struct xcv_api_table xcvtcp_cmds[] = {
09651 { "MonitorUI", xcvtcp_monitorui },
09652 { "AddPort", xcvtcp_addport},
09653 { NULL, NULL }
09654 };
09655
09656 static WERROR process_xcvtcp_command( NT_USER_TOKEN *token, const char *command,
09657 RPC_BUFFER *inbuf, RPC_BUFFER *outbuf,
09658 uint32 *needed )
09659 {
09660 int i;
09661
09662 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
09663
09664 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
09665 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
09666 return xcvtcp_cmds[i].fn( token, inbuf, outbuf, needed );
09667 }
09668
09669 return WERR_BADFUNC;
09670 }
09671
09672
09673
09674 #if 0
09675
09676 static WERROR xcvlocal_monitorui( NT_USER_TOKEN *token, RPC_BUFFER *in,
09677 RPC_BUFFER *out, uint32 *needed )
09678 {
09679 const char *dllname = "localui.dll";
09680
09681 *needed = (strlen(dllname)+1) * 2;
09682
09683 if ( rpcbuf_get_size(out) < *needed ) {
09684 return WERR_INSUFFICIENT_BUFFER;
09685 }
09686
09687 if ( !make_monitorui_buf( out, dllname )) {
09688 return WERR_NOMEM;
09689 }
09690
09691 return WERR_OK;
09692 }
09693
09694
09695
09696
09697 struct xcv_api_table xcvlocal_cmds[] = {
09698 { "MonitorUI", xcvlocal_monitorui },
09699 { NULL, NULL }
09700 };
09701 #else
09702 struct xcv_api_table xcvlocal_cmds[] = {
09703 { NULL, NULL }
09704 };
09705 #endif
09706
09707
09708
09709
09710
09711
09712 static WERROR process_xcvlocal_command( NT_USER_TOKEN *token, const char *command,
09713 RPC_BUFFER *inbuf, RPC_BUFFER *outbuf,
09714 uint32 *needed )
09715 {
09716 int i;
09717
09718 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
09719
09720 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
09721 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
09722 return xcvlocal_cmds[i].fn( token, inbuf, outbuf , needed );
09723 }
09724 return WERR_BADFUNC;
09725 }
09726
09727
09728
09729
09730 WERROR _spoolss_xcvdataport(pipes_struct *p, SPOOL_Q_XCVDATAPORT *q_u, SPOOL_R_XCVDATAPORT *r_u)
09731 {
09732 Printer_entry *Printer = find_printer_index_by_hnd(p, &q_u->handle);
09733 fstring command;
09734
09735 if (!Printer) {
09736 DEBUG(2,("_spoolss_xcvdataport: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(&q_u->handle)));
09737 return WERR_BADFID;
09738 }
09739
09740
09741
09742 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
09743 DEBUG(2,("_spoolss_xcvdataport: Call only valid for Port Monitors\n"));
09744 return WERR_BADFID;
09745 }
09746
09747
09748
09749 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
09750 DEBUG(2,("_spoolss_xcvdataport: denied by handle permissions.\n"));
09751 return WERR_ACCESS_DENIED;
09752 }
09753
09754
09755
09756
09757 rpcstr_pull(command, q_u->dataname.buffer, sizeof(command),
09758 q_u->dataname.uni_str_len*2, 0);
09759
09760
09761
09762 rpcbuf_init( &r_u->outdata, q_u->offered, p->mem_ctx );
09763
09764 switch ( Printer->printer_type ) {
09765 case SPLHND_PORTMON_TCP:
09766 return process_xcvtcp_command( p->pipe_user.nt_user_token, command,
09767 &q_u->indata, &r_u->outdata, &r_u->needed );
09768 case SPLHND_PORTMON_LOCAL:
09769 return process_xcvlocal_command( p->pipe_user.nt_user_token, command,
09770 &q_u->indata, &r_u->outdata, &r_u->needed );
09771 }
09772
09773 return WERR_INVALID_PRINT_MONITOR;
09774 }
09775
09776