X-Git-Url: http://git.samba.org/samba.git/?p=sfrench%2Fsamba-autobuild%2F.git;a=blobdiff_plain;f=source3%2Frpc_server%2Fsrv_spoolss_nt.c;h=577f7f1ded0532303bb01a8ead3a69d1f9aa6ab8;hp=a6f3bfba1783cf9a26a2e7e64b4e4536b6281e14;hb=ddcab787c408824ff753b929abd2240bc088451d;hpb=93bfb6ca542e1e99ae7ae93fca94a0e33d99bca5 diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index a6f3bfba178..577f7f1ded0 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -72,6 +72,18 @@ struct xcv_api_table { WERROR(*fn) (NT_USER_TOKEN *token, RPC_BUFFER *in, RPC_BUFFER *out, uint32 *needed); }; +/******************************************************************** + * Canonicalize servername. + ********************************************************************/ + +static const char *canon_servername(const char *servername) +{ + const char *pservername = servername; + while (*pservername == '\\') { + pservername++; + } + return pservername; +} /* translate between internal status numbers and NT status numbers */ static int nt_printj_status(int v) @@ -153,16 +165,18 @@ static void srv_spoolss_replycloseprinter(int snum, POLICY_HND *handle) return; } - result = rpccli_spoolss_reply_close_printer(notify_cli_pipe, notify_cli_pipe->cli->mem_ctx, handle); + result = rpccli_spoolss_reply_close_printer(notify_cli_pipe, + talloc_tos(), + handle); if (!W_ERROR_IS_OK(result)) DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n", - dos_errstr(result))); + win_errstr(result))); /* if it's the last connection, deconnect the IPC$ share */ if (smb_connections==1) { - cli_shutdown( notify_cli_pipe->cli ); + cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) ); notify_cli_pipe = NULL; /* The above call shuts downn the pipe also. */ messaging_deregister(smbd_messaging_context(), @@ -284,10 +298,11 @@ static bool close_printer_handle(pipes_struct *p, POLICY_HND *hnd) /**************************************************************************** Delete a printer given a handle. ****************************************************************************/ -WERROR delete_printer_hook( NT_USER_TOKEN *token, const char *sharename ) + +WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename ) { char *cmd = lp_deleteprinter_cmd(); - pstring command; + char *command = NULL; int ret; SE_PRIV se_printop = SE_PRINT_OPERATOR; bool is_print_op = False; @@ -297,8 +312,12 @@ WERROR delete_printer_hook( NT_USER_TOKEN *token, const char *sharename ) if ( !*cmd ) return WERR_OK; - pstr_sprintf(command, "%s \"%s\"", cmd, sharename); - + command = talloc_asprintf(ctx, + "%s \"%s\"", + cmd, sharename); + if (!command) { + return WERR_NOMEM; + } if ( token ) is_print_op = user_has_privileges( token, &se_printop ); @@ -322,6 +341,8 @@ WERROR delete_printer_hook( NT_USER_TOKEN *token, const char *sharename ) DEBUGADD(10,("returned [%d]\n", ret)); + TALLOC_FREE(command); + if (ret != 0) return WERR_BADFID; /* What to return here? */ @@ -367,7 +388,7 @@ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd) return WERR_BADFID; } - return delete_printer_hook( p->pipe_user.nt_user_token, Printer->sharename ); + return delete_printer_hook(p->mem_ctx, p->pipe_user.nt_user_token, Printer->sharename ); } /**************************************************************************** @@ -446,13 +467,12 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename) aprinter = handlename; if ( *handlename == '\\' ) { - servername = handlename + 2; - if ( (aprinter = strchr_m( handlename+2, '\\' )) != NULL ) { + servername = canon_servername(handlename); + if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) { *aprinter = '\0'; aprinter++; } - } - else { + } else { servername = ""; } @@ -512,10 +532,16 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename) fstrcpy(sname, lp_servicename(snum)); printer = NULL; - result = get_a_printer( NULL, &printer, 2, sname ); + + /* This call doesn't fill in the location or comment from + * a CUPS server for efficiency with large numbers of printers. + * JRA. + */ + + result = get_a_printer_search( NULL, &printer, 2, sname ); if ( !W_ERROR_IS_OK(result) ) { DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n", - sname, dos_errstr(result))); + sname, win_errstr(result))); continue; } @@ -1258,7 +1284,7 @@ void do_drv_upgrade_printer(struct messaging_context *msg, result = mod_a_printer(printer, 2); if (!W_ERROR_IS_OK(result)) { DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n", - dos_errstr(result))); + win_errstr(result))); } } @@ -1521,6 +1547,13 @@ WERROR _spoolss_open_printer(pipes_struct *p, SPOOL_Q_OPEN_PRINTER *q_u, SPOOL_R memcpy(r_u, &r_u_ex, sizeof(*r_u)); + if (W_ERROR_EQUAL(r_u->status, WERR_INVALID_PARAM)) { + /* OpenPrinterEx returns this for a bad + * printer name. We must return WERR_INVALID_PRINTER_NAME + * instead. + */ + r_u->status = WERR_INVALID_PRINTER_NAME; + } return r_u->status; } @@ -1536,8 +1569,9 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, int snum; Printer_entry *Printer=NULL; - if ( !q_u->printername ) - return WERR_INVALID_PRINTER_NAME; + if (!q_u->printername) { + return WERR_INVALID_PARAM; + } /* some sanity check because you can open a printer or a print server */ /* aka: \\server\printer or \\server */ @@ -1546,15 +1580,16 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, DEBUGADD(3,("checking name: %s\n",name)); - if (!open_printer_hnd(p, handle, name, 0)) - return WERR_INVALID_PRINTER_NAME; + if (!open_printer_hnd(p, handle, name, 0)) { + return WERR_INVALID_PARAM; + } Printer=find_printer_index_by_hnd(p, handle); if ( !Printer ) { DEBUG(0,(" _spoolss_open_printer_ex: logic error. Can't find printer " "handle we created for printer %s\n", name )); close_printer_handle(p,handle); - return WERR_INVALID_PRINTER_NAME; + return WERR_INVALID_PARAM; } /* @@ -1625,7 +1660,8 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, !user_has_privileges(p->pipe_user.nt_user_token, &se_printop ) && !token_contains_name_in_list( - uidtoname(p->pipe_user.ut.uid), NULL, + uidtoname(p->pipe_user.ut.uid), + NULL, NULL, p->pipe_user.nt_user_token, lp_printer_admin(snum))) { close_printer_handle(p, handle); @@ -1679,9 +1715,9 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, return WERR_ACCESS_DENIED; } - if (!user_ok_token(uidtoname(p->pipe_user.ut.uid), + if (!user_ok_token(uidtoname(p->pipe_user.ut.uid), NULL, p->pipe_user.nt_user_token, snum) || - !print_access_check(&p->pipe_user, snum, + !print_access_check(p->server_info, snum, printer_default->access_required)) { DEBUG(3, ("access DENIED for printer open\n")); close_printer_handle(p, handle); @@ -1984,8 +2020,10 @@ WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER if ( (p->pipe_user.ut.uid != 0) && !user_has_privileges(p->pipe_user.nt_user_token, &se_printop ) - && !token_contains_name_in_list( uidtoname(p->pipe_user.ut.uid), - NULL, p->pipe_user.nt_user_token, lp_printer_admin(-1)) ) + && !token_contains_name_in_list( + uidtoname(p->pipe_user.ut.uid), NULL, + NULL, p->pipe_user.nt_user_token, + lp_printer_admin(-1)) ) { return WERR_ACCESS_DENIED; } @@ -2079,8 +2117,9 @@ WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIV if ( (p->pipe_user.ut.uid != 0) && !user_has_privileges(p->pipe_user.nt_user_token, &se_printop ) - && !token_contains_name_in_list( uidtoname(p->pipe_user.ut.uid), - NULL, p->pipe_user.nt_user_token, lp_printer_admin(-1)) ) + && !token_contains_name_in_list( + uidtoname(p->pipe_user.ut.uid), NULL, NULL, + p->pipe_user.nt_user_token, lp_printer_admin(-1)) ) { return WERR_ACCESS_DENIED; } @@ -2534,13 +2573,13 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe, struct cli_state *the_cli; struct sockaddr_storage rm_addr; - if ( is_zero_addr(client_ss) ) { + if ( is_zero_addr((struct sockaddr *)client_ss) ) { if ( !resolve_name( remote_machine, &rm_addr, 0x20) ) { DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine)); return False; } - if (ismyaddr(&rm_addr)) { + if (ismyaddr((struct sockaddr *)&rm_addr)) { DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine)); return False; } @@ -2578,17 +2617,14 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe, * Now start the NT Domain stuff :-). */ - if ( !(*pp_pipe = cli_rpc_pipe_open_noauth(the_cli, PI_SPOOLSS, &ret)) ) { + ret = cli_rpc_pipe_open_noauth(the_cli, &syntax_spoolss, pp_pipe); + if (!NT_STATUS_IS_OK(ret)) { DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n", remote_machine, nt_errstr(ret))); cli_shutdown(the_cli); return False; } - /* make sure to save the cli_state pointer. Keep its own talloc_ctx */ - - (*pp_pipe)->cli = the_cli; - return True; } @@ -2632,12 +2668,16 @@ static bool srv_spoolss_replyopenprinter(int snum, const char *printer, smb_connections++; - result = rpccli_spoolss_reply_open_printer(notify_cli_pipe, notify_cli_pipe->cli->mem_ctx, printer, localprinter, - type, handle); + result = rpccli_spoolss_reply_open_printer(notify_cli_pipe, + talloc_tos(), + printer, + localprinter, + type, + handle); if (!W_ERROR_IS_OK(result)) DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n", - dos_errstr(result))); + win_errstr(result))); return (W_ERROR_IS_OK(result)); } @@ -2693,9 +2733,8 @@ WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE !get_printer_snum(p, handle, &snum, NULL) ) return WERR_BADFID; - if (!interpret_string_addr(&client_ss, - p->conn->client_address, - AI_NUMERICHOST)) { + if (!interpret_string_addr(&client_ss, p->client_address, + AI_NUMERICHOST)) { return WERR_SERVER_UNAVAILABLE; } @@ -2719,20 +2758,17 @@ void spoolss_notify_server_name(int snum, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - pstring temp; + smb_ucs2_t *temp = NULL; uint32 len; - len = rpcstr_push(temp, printer->info_2->servername, sizeof(temp)-2, STR_TERMINATE); + len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->servername); + if (len == (uint32)-1) { + len = 0; + } data->notify_data.data.length = len; if (len) { - data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); - if (!data->notify_data.data.string) { - data->notify_data.data.length = 0; - return; - } - - memcpy(data->notify_data.data.string, temp, len); + data->notify_data.data.string = (uint16 *)temp; } else { data->notify_data.data.string = NULL; } @@ -2748,7 +2784,7 @@ void spoolss_notify_printer_name(int snum, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - pstring temp; + smb_ucs2_t *temp = NULL; uint32 len; /* the notify name should not contain the \\server\ part */ @@ -2760,16 +2796,14 @@ void spoolss_notify_printer_name(int snum, p++; } - len = rpcstr_push(temp, p, sizeof(temp)-2, STR_TERMINATE); + len = rpcstr_push_talloc(mem_ctx, &temp, p); + if (len == (uint32)-1) { + len = 0; + } data->notify_data.data.length = len; if (len) { - data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); - if (!data->notify_data.data.string) { - data->notify_data.data.length = 0; - return; - } - memcpy(data->notify_data.data.string, temp, len); + data->notify_data.data.string = (uint16 *)temp; } else { data->notify_data.data.string = NULL; } @@ -2785,19 +2819,17 @@ void spoolss_notify_share_name(int snum, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - pstring temp; + smb_ucs2_t *temp = NULL; uint32 len; - len = rpcstr_push(temp, lp_servicename(snum), sizeof(temp)-2, STR_TERMINATE); + len = rpcstr_push_talloc(mem_ctx, &temp, lp_servicename(snum)); + if (len == (uint32)-1) { + len = 0; + } data->notify_data.data.length = len; if (len) { - data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); - if (!data->notify_data.data.string) { - data->notify_data.data.length = 0; - return; - } - memcpy(data->notify_data.data.string, temp, len); + data->notify_data.data.string = (uint16 *)temp; } else { data->notify_data.data.string = NULL; } @@ -2814,23 +2846,19 @@ void spoolss_notify_port_name(int snum, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - pstring temp; + smb_ucs2_t *temp = NULL; uint32 len; /* even if it's strange, that's consistant in all the code */ - len = rpcstr_push(temp, printer->info_2->portname, sizeof(temp)-2, STR_TERMINATE); + len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->portname); + if (len == (uint32)-1) { + len = 0; + } data->notify_data.data.length = len; if (len) { - data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); - - if (!data->notify_data.data.string) { - data->notify_data.data.length = 0; - return; - } - - memcpy(data->notify_data.data.string, temp, len); + data->notify_data.data.string = (uint16 *)temp; } else { data->notify_data.data.string = NULL; } @@ -2847,21 +2875,17 @@ void spoolss_notify_driver_name(int snum, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - pstring temp; + smb_ucs2_t *temp = NULL; uint32 len; - len = rpcstr_push(temp, printer->info_2->drivername, sizeof(temp)-2, STR_TERMINATE); + len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->drivername); + if (len == (uint32)-1) { + len = 0; + } data->notify_data.data.length = len; if (len) { - data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); - - if (!data->notify_data.data.string) { - data->notify_data.data.length = 0; - return; - } - - memcpy(data->notify_data.data.string, temp, len); + data->notify_data.data.string = (uint16 *)temp; } else { data->notify_data.data.string = NULL; } @@ -2877,24 +2901,20 @@ void spoolss_notify_comment(int snum, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - pstring temp; + smb_ucs2_t *temp = NULL; uint32 len; if (*printer->info_2->comment == '\0') - len = rpcstr_push(temp, lp_comment(snum), sizeof(temp)-2, STR_TERMINATE); + len = rpcstr_push_talloc(mem_ctx, &temp, lp_comment(snum)); else - len = rpcstr_push(temp, printer->info_2->comment, sizeof(temp)-2, STR_TERMINATE); + len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->comment); + if (len == (uint32)-1) { + len = 0; + } data->notify_data.data.length = len; if (len) { - data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); - - if (!data->notify_data.data.string) { - data->notify_data.data.length = 0; - return; - } - - memcpy(data->notify_data.data.string, temp, len); + data->notify_data.data.string = (uint16 *)temp; } else { data->notify_data.data.string = NULL; } @@ -2911,21 +2931,17 @@ void spoolss_notify_location(int snum, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - pstring temp; + smb_ucs2_t *temp = NULL; uint32 len; - len = rpcstr_push(temp, printer->info_2->location,sizeof(temp)-2, STR_TERMINATE); + len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->location); + if (len == (uint32)-1) { + len = 0; + } data->notify_data.data.length = len; if (len) { - data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); - - if (!data->notify_data.data.string) { - data->notify_data.data.length = 0; - return; - } - - memcpy(data->notify_data.data.string, temp, len); + data->notify_data.data.string = (uint16 *)temp; } else { data->notify_data.data.string = NULL; } @@ -2957,21 +2973,17 @@ void spoolss_notify_sepfile(int snum, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - pstring temp; + smb_ucs2_t *temp = NULL; uint32 len; - len = rpcstr_push(temp, printer->info_2->sepfile, sizeof(temp)-2, STR_TERMINATE); + len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->sepfile); + if (len == (uint32)-1) { + len = 0; + } data->notify_data.data.length = len; if (len) { - data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); - - if (!data->notify_data.data.string) { - data->notify_data.data.length = 0; - return; - } - - memcpy(data->notify_data.data.string, temp, len); + data->notify_data.data.string = (uint16 *)temp; } else { data->notify_data.data.string = NULL; } @@ -2988,21 +3000,17 @@ void spoolss_notify_print_processor(int snum, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - pstring temp; + smb_ucs2_t *temp = NULL; uint32 len; - len = rpcstr_push(temp, printer->info_2->printprocessor, sizeof(temp)-2, STR_TERMINATE); + len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->printprocessor); + if (len == (uint32)-1) { + len = 0; + } data->notify_data.data.length = len; if (len) { - data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); - - if (!data->notify_data.data.string) { - data->notify_data.data.length = 0; - return; - } - - memcpy(data->notify_data.data.string, temp, len); + data->notify_data.data.string = (uint16 *)temp; } else { data->notify_data.data.string = NULL; } @@ -3019,21 +3027,17 @@ void spoolss_notify_parameters(int snum, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - pstring temp; + smb_ucs2_t *temp = NULL; uint32 len; - len = rpcstr_push(temp, printer->info_2->parameters, sizeof(temp)-2, STR_TERMINATE); + len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->parameters); + if (len == (uint32)-1) { + len = 0; + } data->notify_data.data.length = len; if (len) { - data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); - - if (!data->notify_data.data.string) { - data->notify_data.data.length = 0; - return; - } - - memcpy(data->notify_data.data.string, temp, len); + data->notify_data.data.string = (uint16 *)temp; } else { data->notify_data.data.string = NULL; } @@ -3050,21 +3054,17 @@ void spoolss_notify_datatype(int snum, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - pstring temp; + smb_ucs2_t *temp = NULL; uint32 len; - len = rpcstr_push(temp, printer->info_2->datatype, sizeof(pstring)-2, STR_TERMINATE); + len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->datatype); + if (len == (uint32)-1) { + len = 0; + } data->notify_data.data.length = len; if (len) { - data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); - - if (!data->notify_data.data.string) { - data->notify_data.data.length = 0; - return; - } - - memcpy(data->notify_data.data.string, temp, len); + data->notify_data.data.string = (uint16 *)temp; } else { data->notify_data.data.string = NULL; } @@ -3214,21 +3214,17 @@ static void spoolss_notify_username(int snum, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - pstring temp; + smb_ucs2_t *temp = NULL; uint32 len; - len = rpcstr_push(temp, queue->fs_user, sizeof(temp)-2, STR_TERMINATE); + len = rpcstr_push_talloc(mem_ctx, &temp, queue->fs_user); + if (len == (uint32)-1) { + len = 0; + } data->notify_data.data.length = len; if (len) { - data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); - - if (!data->notify_data.data.string) { - data->notify_data.data.length = 0; - return; - } - - memcpy(data->notify_data.data.string, temp, len); + data->notify_data.data.string = (uint16 *)temp; } else { data->notify_data.data.string = NULL; } @@ -3258,21 +3254,17 @@ static void spoolss_notify_job_name(int snum, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - pstring temp; + smb_ucs2_t *temp = NULL; uint32 len; - len = rpcstr_push(temp, queue->fs_file, sizeof(temp)-2, STR_TERMINATE); + len = rpcstr_push_talloc(mem_ctx, &temp, queue->fs_file); + if (len == (uint32)-1) { + len = 0; + } data->notify_data.data.length = len; if (len) { - data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); - - if (!data->notify_data.data.string) { - data->notify_data.data.length = 0; - return; - } - - memcpy(data->notify_data.data.string, temp, len); + data->notify_data.data.string = (uint16 *)temp; } else { data->notify_data.data.string = NULL; } @@ -3293,7 +3285,7 @@ static void spoolss_notify_job_status_string(int snum, */ const char *p = ""; - pstring temp; + smb_ucs2_t *temp = NULL; uint32 len; #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */ @@ -3315,18 +3307,14 @@ static void spoolss_notify_job_status_string(int snum, } #endif /* NO LONGER NEEDED. */ - len = rpcstr_push(temp, p, sizeof(temp) - 2, STR_TERMINATE); + len = rpcstr_push_talloc(mem_ctx, &temp, p); + if (len == (uint32)-1) { + len = 0; + } data->notify_data.data.length = len; if (len) { - data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); - - if (!data->notify_data.data.string) { - data->notify_data.data.length = 0; - return; - } - - memcpy(data->notify_data.data.string, temp, len); + data->notify_data.data.string = (uint16 *)temp; } else { data->notify_data.data.string = NULL; } @@ -3954,7 +3942,7 @@ done: static bool construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *printer, int snum) { - pstring chaine; + char *chaine = NULL; int count; NT_PRINTER_INFO_LEVEL *ntprinter = NULL; counter_printer_0 *session_counter; @@ -3962,10 +3950,19 @@ static bool construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *p struct tm *t; time_t setuptime; print_status_struct status; + TALLOC_CTX *ctx = talloc_tos(); if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum)))) return False; + init_unistr(&printer->printername, ntprinter->info_2->printername); + + chaine = talloc_asprintf(ctx, "\\\\%s", get_server_name(print_hnd)); + if (!chaine) { + free_a_printer(&ntprinter,2); + return false; + } + count = print_queue_length(snum, &status); /* check if we already have a counter for this printer */ @@ -3974,6 +3971,8 @@ static bool construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *p break; } + init_unistr(&printer->servername, chaine); + /* it's the first time, add it to the list */ if (session_counter==NULL) { if((session_counter=SMB_MALLOC_P(counter_printer_0)) == NULL) { @@ -3994,14 +3993,6 @@ static bool construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *p * and should be zeroed on samba startup */ global_counter=session_counter->counter; - - pstrcpy(chaine,ntprinter->info_2->printername); - - init_unistr(&printer->printername, chaine); - - slprintf(chaine,sizeof(chaine)-1,"\\\\%s", get_server_name(print_hnd)); - init_unistr(&printer->servername, chaine); - printer->cjobs = count; printer->total_jobs = 0; printer->total_bytes = 0; @@ -4059,30 +4050,35 @@ static bool construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *p ********************************************************************/ static bool construct_printer_info_1(Printer_entry *print_hnd, uint32 flags, PRINTER_INFO_1 *printer, int snum) { - pstring chaine; - pstring chaine2; + char *chaine = NULL; NT_PRINTER_INFO_LEVEL *ntprinter = NULL; + TALLOC_CTX *ctx = talloc_tos(); if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum)))) - return False; + return false; printer->flags=flags; if (*ntprinter->info_2->comment == '\0') { init_unistr(&printer->comment, lp_comment(snum)); - slprintf(chaine,sizeof(chaine)-1,"%s,%s,%s", ntprinter->info_2->printername, - ntprinter->info_2->drivername, lp_comment(snum)); + chaine = talloc_asprintf(ctx, + "%s,%s,%s", ntprinter->info_2->printername, + ntprinter->info_2->drivername, lp_comment(snum)); } else { init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */ - slprintf(chaine,sizeof(chaine)-1,"%s,%s,%s", ntprinter->info_2->printername, - ntprinter->info_2->drivername, ntprinter->info_2->comment); + chaine = talloc_asprintf(ctx, + "%s,%s,%s", ntprinter->info_2->printername, + ntprinter->info_2->drivername, ntprinter->info_2->comment); } - slprintf(chaine2,sizeof(chaine)-1,"%s", ntprinter->info_2->printername); + if (!chaine) { + free_a_printer(&ntprinter,2); + return false; + } init_unistr(&printer->description, chaine); - init_unistr(&printer->name, chaine2); + init_unistr(&printer->name, ntprinter->info_2->printername); free_a_printer(&ntprinter,2); @@ -4376,10 +4372,13 @@ static bool construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *p struct GUID guid; if (is_printer_published(print_hnd, snum, &guid)) { - asprintf(&guid_str, "{%s}", - smb_uuid_string(talloc_tos(), guid)); + if (asprintf(&guid_str, "{%s}", + GUID_string(talloc_tos(), &guid)) == -1) { + return false; + } strupper_m(guid_str); init_unistr(&printer->guid, guid_str); + SAFE_FREE(guid_str); printer->action = SPOOL_DS_PUBLISH; } else { init_unistr(&printer->guid, ""); @@ -4673,20 +4672,16 @@ static WERROR enumprinters_level1( uint32 flags, fstring name, * handle enumeration of printers at level 2 ********************************************************************/ -static WERROR enumprinters_level2( uint32 flags, fstring servername, +static WERROR enumprinters_level2( uint32 flags, const char *servername, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { - char *s = servername; - if (flags & PRINTER_ENUM_LOCAL) { return enum_all_printers_info_2(buffer, offered, needed, returned); } if (flags & PRINTER_ENUM_NAME) { - if ((servername[0] == '\\') && (servername[1] == '\\')) - s = servername + 2; - if (is_myname_or_ipaddr(s)) + if (is_myname_or_ipaddr(canon_servername(servername))) return enum_all_printers_info_2(buffer, offered, needed, returned); else return WERR_INVALID_NAME; @@ -4702,7 +4697,7 @@ static WERROR enumprinters_level2( uint32 flags, fstring servername, * handle enumeration of printers at level 5 ********************************************************************/ -static WERROR enumprinters_level5( uint32 flags, fstring servername, +static WERROR enumprinters_level5( uint32 flags, const char *servername, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { @@ -5042,8 +5037,10 @@ static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL) return WERR_NOMEM; - if (!construct_printer_info_7(print_hnd, printer, snum)) - return WERR_NOMEM; + if (!construct_printer_info_7(print_hnd, printer, snum)) { + result = WERR_NOMEM; + goto out; + } /* check the required size. */ *needed += spoolss_size_printer_info_7(printer); @@ -5122,7 +5119,7 @@ WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GET * fill a DRIVER_INFO_1 struct ********************************************************************/ -static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername, fstring architecture) +static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername, fstring architecture) { init_unistr( &info->name, driver.info_3->name); } @@ -5131,7 +5128,7 @@ static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_IN * construct_printer_driver_info_1 ********************************************************************/ -static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, fstring servername, fstring architecture, uint32 version) +static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, const char *servername, fstring architecture, uint32 version) { NT_PRINTER_INFO_LEVEL *printer = NULL; NT_PRINTER_DRIVER_INFO_LEVEL driver; @@ -5158,30 +5155,43 @@ static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, fst * fill a printer_info_2 struct ********************************************************************/ -static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername) +static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername) { - pstring temp; + TALLOC_CTX *ctx = talloc_tos(); + char *temp = NULL; + const char *cservername = canon_servername(servername); info->version=driver.info_3->cversion; init_unistr( &info->name, driver.info_3->name ); init_unistr( &info->architecture, driver.info_3->environment ); - - if (strlen(driver.info_3->driverpath)) { - slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath); + if (strlen(driver.info_3->driverpath)) { + temp = talloc_asprintf(ctx, + "\\\\%s%s", + cservername, + driver.info_3->driverpath); init_unistr( &info->driverpath, temp ); - } else - init_unistr( &info->driverpath, "" ); + } else { + init_unistr( &info->driverpath, "" ); + } + TALLOC_FREE(temp); if (strlen(driver.info_3->datafile)) { - slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile); + temp = talloc_asprintf(ctx, + "\\\\%s%s", + cservername, + driver.info_3->datafile); init_unistr( &info->datafile, temp ); } else init_unistr( &info->datafile, "" ); + TALLOC_FREE(temp); if (strlen(driver.info_3->configfile)) { - slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile); + temp = talloc_asprintf(ctx, + "\\\\%s%s", + cservername, + driver.info_3->configfile); init_unistr( &info->configfile, temp ); } else init_unistr( &info->configfile, "" ); @@ -5192,7 +5202,7 @@ static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_IN * fill a printer_info_2 struct ********************************************************************/ -static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fstring servername, fstring architecture, uint32 version) +static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, const char *servername, fstring architecture, uint32 version) { NT_PRINTER_INFO_LEVEL *printer = NULL; NT_PRINTER_DRIVER_INFO_LEVEL driver; @@ -5226,17 +5236,16 @@ static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const c int i=0; int j=0; const char *v; - pstring line; + char *line = NULL; + TALLOC_CTX *ctx = talloc_tos(); DEBUG(6,("init_unistr_array\n")); *uni_array=NULL; - while (True) - { - if ( !char_array ) + while (true) { + if ( !char_array ) { v = ""; - else - { + } else { v = char_array[i]; if (!v) v = ""; /* hack to handle null lists */ @@ -5244,12 +5253,21 @@ static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const c /* hack to allow this to be used in places other than when generating the list of dependent files */ - - if ( servername ) - slprintf( line, sizeof(line)-1, "\\\\%s%s", servername, v ); - else - pstrcpy( line, v ); + TALLOC_FREE(line); + if ( servername ) { + line = talloc_asprintf(ctx, + "\\\\%s%s", + canon_servername(servername), + v); + } else { + line = talloc_strdup(ctx, v); + } + + if (!line) { + SAFE_FREE(*uni_array); + return 0; + } DEBUGADD(6,("%d:%s:%lu\n", i, line, (unsigned long)strlen(line))); /* add one extra unit16 for the second terminating NULL */ @@ -5285,9 +5303,11 @@ static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const c * fill a printer_info_3 struct ********************************************************************/ -static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername) +static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername) { - pstring temp; + char *temp = NULL; + TALLOC_CTX *ctx = talloc_tos(); + const char *cservername = canon_servername(servername); ZERO_STRUCTP(info); @@ -5297,34 +5317,50 @@ static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_IN init_unistr( &info->architecture, driver.info_3->environment ); if (strlen(driver.info_3->driverpath)) { - slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath); + temp = talloc_asprintf(ctx, + "\\\\%s%s", + cservername, + driver.info_3->driverpath); init_unistr( &info->driverpath, temp ); } else init_unistr( &info->driverpath, "" ); + TALLOC_FREE(temp); if (strlen(driver.info_3->datafile)) { - slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile); + temp = talloc_asprintf(ctx, + "\\\\%s%s", + cservername, + driver.info_3->datafile); init_unistr( &info->datafile, temp ); } else init_unistr( &info->datafile, "" ); + TALLOC_FREE(temp); if (strlen(driver.info_3->configfile)) { - slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile); + temp = talloc_asprintf(ctx, + "\\\\%s%s", + cservername, + driver.info_3->configfile); init_unistr( &info->configfile, temp ); } else init_unistr( &info->configfile, "" ); + TALLOC_FREE(temp); if (strlen(driver.info_3->helpfile)) { - slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->helpfile); + temp = talloc_asprintf(ctx, + "\\\\%s%s", + cservername, + driver.info_3->helpfile); init_unistr( &info->helpfile, temp ); } else init_unistr( &info->helpfile, "" ); + TALLOC_FREE(temp); init_unistr( &info->monitorname, driver.info_3->monitorname ); init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype ); info->dependentfiles=NULL; - init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, servername); + init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, cservername); } /******************************************************************** @@ -5332,7 +5368,7 @@ static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_IN * fill a printer_info_3 struct ********************************************************************/ -static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, fstring servername, fstring architecture, uint32 version) +static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, const char *servername, fstring architecture, uint32 version) { NT_PRINTER_INFO_LEVEL *printer = NULL; NT_PRINTER_DRIVER_INFO_LEVEL driver; @@ -5340,12 +5376,12 @@ static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, fst ZERO_STRUCT(driver); status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) ); - DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status))); + DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status))); if (!W_ERROR_IS_OK(status)) return WERR_INVALID_PRINTER_NAME; status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version); - DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status))); + DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status))); #if 0 /* JERRY */ @@ -5365,7 +5401,7 @@ static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, fst /* Yes - try again with a WinNT driver. */ version = 2; status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version); - DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status))); + DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status))); } #endif @@ -5391,10 +5427,12 @@ static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, fst * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA. ********************************************************************/ -static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername) +static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername) { - pstring temp; + char *temp = NULL; fstring nullstr; + TALLOC_CTX *ctx = talloc_tos(); + const char *cservername = canon_servername(servername); ZERO_STRUCTP(info); memset(&nullstr, '\0', sizeof(fstring)); @@ -5405,29 +5443,45 @@ static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_IN init_unistr( &info->architecture, driver.info_3->environment ); if (strlen(driver.info_3->driverpath)) { - slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath); + temp = talloc_asprintf(ctx, + "\\\\%s%s", + cservername, + driver.info_3->driverpath); init_unistr( &info->driverpath, temp ); } else init_unistr( &info->driverpath, "" ); + TALLOC_FREE(temp); if (strlen(driver.info_3->datafile)) { - slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile); + temp = talloc_asprintf(ctx, + "\\\\%s%s", + cservername, + driver.info_3->datafile); init_unistr( &info->datafile, temp ); } else init_unistr( &info->datafile, "" ); + TALLOC_FREE(temp); if (strlen(driver.info_3->configfile)) { - slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile); + temp = talloc_asprintf(ctx, + "\\\\%s%s", + cservername, + driver.info_3->configfile); init_unistr( &info->configfile, temp ); } else init_unistr( &info->configfile, "" ); + TALLOC_FREE(temp); if (strlen(driver.info_3->helpfile)) { - slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->helpfile); + temp = talloc_asprintf(ctx, + "\\\\%s%s", + cservername, + driver.info_3->helpfile); init_unistr( &info->helpfile, temp ); } else init_unistr( &info->helpfile, "" ); + TALLOC_FREE(temp); init_unistr( &info->monitorname, driver.info_3->monitorname ); init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype ); @@ -5455,7 +5509,7 @@ static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_IN ********************************************************************/ static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum, - fstring servername, fstring architecture, uint32 version) + const char *servername, fstring architecture, uint32 version) { NT_PRINTER_INFO_LEVEL *printer = NULL; NT_PRINTER_DRIVER_INFO_LEVEL driver; @@ -5465,14 +5519,14 @@ static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum, status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) ); - DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status))); + DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status))); if (!W_ERROR_IS_OK(status)) return WERR_INVALID_PRINTER_NAME; status = get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version); - DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status))); + DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status))); if (!W_ERROR_IS_OK(status)) { @@ -5488,7 +5542,7 @@ static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum, /* Yes - try again with a WinNT driver. */ version = 2; status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version); - DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status))); + DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status))); if (!W_ERROR_IS_OK(status)) { free_a_printer(&printer,2); return WERR_UNKNOWN_PRINTER_DRIVER; @@ -5522,7 +5576,7 @@ static void free_printer_driver_info_6(DRIVER_INFO_6 *info) /**************************************************************************** ****************************************************************************/ -static WERROR getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getprinterdriver2_level1(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { DRIVER_INFO_1 *info=NULL; WERROR result; @@ -5560,7 +5614,7 @@ out: /**************************************************************************** ****************************************************************************/ -static WERROR getprinterdriver2_level2(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getprinterdriver2_level2(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { DRIVER_INFO_2 *info=NULL; WERROR result; @@ -5598,7 +5652,7 @@ out: /**************************************************************************** ****************************************************************************/ -static WERROR getprinterdriver2_level3(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getprinterdriver2_level3(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { DRIVER_INFO_3 info; WERROR result; @@ -5634,7 +5688,7 @@ out: /**************************************************************************** ****************************************************************************/ -static WERROR getprinterdriver2_level6(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getprinterdriver2_level6(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { DRIVER_INFO_6 info; WERROR result; @@ -5786,10 +5840,10 @@ WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, S POLICY_HND *handle = &q_u->handle; DOC_INFO *docinfo = &q_u->doc_info_container.docinfo; uint32 *jobid = &r_u->jobid; - + TALLOC_CTX *ctx = p->mem_ctx; DOC_INFO_1 *info_1 = &docinfo->doc_info_1; int snum; - pstring jobname; + char *jobname = NULL; fstring datatype; Printer_entry *Printer = find_printer_index_by_hnd(p, handle); @@ -5819,9 +5873,10 @@ WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, S return WERR_BADFID; } - unistr2_to_ascii(jobname, &info_1->docname, sizeof(jobname)); + jobname = unistr2_to_ascii_talloc(ctx, &info_1->docname); - Printer->jobid = print_job_start(&p->pipe_user, snum, jobname, Printer->nt_devmode); + Printer->jobid = print_job_start(p->server_info, snum, jobname, + Printer->nt_devmode); /* An error occured in print_job_start() so return an appropriate NT error code. */ @@ -5908,18 +5963,18 @@ static WERROR control_printer(POLICY_HND *handle, uint32 command, switch (command) { case PRINTER_CONTROL_PAUSE: - if (print_queue_pause(&p->pipe_user, snum, &errcode)) { + if (print_queue_pause(p->server_info, snum, &errcode)) { errcode = WERR_OK; } break; case PRINTER_CONTROL_RESUME: case PRINTER_CONTROL_UNPAUSE: - if (print_queue_resume(&p->pipe_user, snum, &errcode)) { + if (print_queue_resume(p->server_info, snum, &errcode)) { errcode = WERR_OK; } break; case PRINTER_CONTROL_PURGE: - if (print_queue_purge(&p->pipe_user, snum, &errcode)) { + if (print_queue_purge(p->server_info, snum, &errcode)) { errcode = WERR_OK; } break; @@ -5951,7 +6006,7 @@ WERROR _spoolss_abortprinter(pipes_struct *p, SPOOL_Q_ABORTPRINTER *q_u, SPOOL_R if (!get_printer_snum(p, handle, &snum, NULL)) return WERR_BADFID; - print_job_delete( &p->pipe_user, snum, Printer->jobid, &errcode ); + print_job_delete(p->server_info, snum, Printer->jobid, &errcode ); return errcode; } @@ -5999,7 +6054,11 @@ static WERROR update_printer_sec(POLICY_HND *handle, uint32 level, /* NT seems to like setting the security descriptor even though nothing may have actually changed. */ - nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr); + if ( !nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr)) { + DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n")); + result = WERR_BADFID; + goto done; + } if (DEBUGLEVEL >= 10) { SEC_ACL *the_acl; @@ -6010,11 +6069,8 @@ static WERROR update_printer_sec(POLICY_HND *handle, uint32 level, PRINTERNAME(snum), the_acl->num_aces)); for (i = 0; i < the_acl->num_aces; i++) { - fstring sid_str; - - sid_to_string(sid_str, &the_acl->aces[i].trustee); - - DEBUG(10, ("%s 0x%08x\n", sid_str, + DEBUG(10, ("%s 0x%08x\n", sid_string_dbg( + &the_acl->aces[i].trustee), the_acl->aces[i].access_mask)); } @@ -6025,11 +6081,8 @@ static WERROR update_printer_sec(POLICY_HND *handle, uint32 level, PRINTERNAME(snum), the_acl->num_aces)); for (i = 0; i < the_acl->num_aces; i++) { - fstring sid_str; - - sid_to_string(sid_str, &the_acl->aces[i].trustee); - - DEBUG(10, ("%s 0x%08x\n", sid_str, + DEBUG(10, ("%s 0x%08x\n", sid_string_dbg( + &the_acl->aces[i].trustee), the_acl->aces[i].access_mask)); } } else { @@ -6109,12 +6162,11 @@ static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum) /**************************************************************************** ****************************************************************************/ -WERROR add_port_hook(NT_USER_TOKEN *token, const char *portname, const char *uri ) +WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri ) { char *cmd = lp_addport_cmd(); - pstring command; + char *command = NULL; int ret; - int fd; SE_PRIV se_printop = SE_PRINT_OPERATOR; bool is_print_op = False; @@ -6122,7 +6174,11 @@ WERROR add_port_hook(NT_USER_TOKEN *token, const char *portname, const char *uri return WERR_ACCESS_DENIED; } - slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"", cmd, portname, uri ); + command = talloc_asprintf(ctx, + "%s \"%s\" \"%s\"", cmd, portname, uri ); + if (!command) { + return WERR_NOMEM; + } if ( token ) is_print_op = user_has_privileges( token, &se_printop ); @@ -6134,7 +6190,7 @@ WERROR add_port_hook(NT_USER_TOKEN *token, const char *portname, const char *uri if ( is_print_op ) become_root(); - ret = smbrun(command, &fd); + ret = smbrun(command, NULL); if ( is_print_op ) unbecome_root(); @@ -6143,9 +6199,9 @@ WERROR add_port_hook(NT_USER_TOKEN *token, const char *portname, const char *uri DEBUGADD(10,("returned [%d]\n", ret)); + TALLOC_FREE(command); + if ( ret != 0 ) { - if (fd != -1) - close(fd); return WERR_ACCESS_DENIED; } @@ -6155,26 +6211,37 @@ WERROR add_port_hook(NT_USER_TOKEN *token, const char *portname, const char *uri /**************************************************************************** ****************************************************************************/ -bool add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer) +bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer) { char *cmd = lp_addprinter_cmd(); char **qlines; - pstring command; + char *command = NULL; int numlines; int ret; int fd; - fstring remote_machine = "%m"; SE_PRIV se_printop = SE_PRINT_OPERATOR; bool is_print_op = False; + char *remote_machine = talloc_strdup(ctx, "%m"); - standard_sub_basic(current_user_info.smb_name, - current_user_info.domain, - remote_machine,sizeof(remote_machine)); + if (!remote_machine) { + return false; + } + remote_machine = talloc_sub_basic(ctx, + current_user_info.smb_name, + current_user_info.domain, + remote_machine); + if (!remote_machine) { + return false; + } - slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"", + command = talloc_asprintf(ctx, + "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"", cmd, printer->info_2->printername, printer->info_2->sharename, printer->info_2->portname, printer->info_2->drivername, printer->info_2->location, printer->info_2->comment, remote_machine); + if (!command) { + return false; + } if ( token ) is_print_op = user_has_privileges( token, &se_printop ); @@ -6199,6 +6266,9 @@ bool add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer) DEBUGADD(10,("returned [%d]\n", ret)); + TALLOC_FREE(command); + TALLOC_FREE(remote_machine); + if ( ret != 0 ) { if (fd != -1) close(fd); @@ -6210,7 +6280,7 @@ bool add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer) numlines = 0; /* Get lines and convert them back to dos-codepage */ - qlines = fd_lines_load(fd, &numlines, 0); + qlines = fd_lines_load(fd, &numlines, 0, NULL); DEBUGADD(10,("Lines returned = [%d]\n", numlines)); close(fd); @@ -6223,7 +6293,7 @@ bool add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer) DEBUGADD(6,("Line[0] = [%s]\n", qlines[0])); } - file_lines_free(qlines); + TALLOC_FREE(qlines); return True; } @@ -6318,7 +6388,7 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level, { /* add_printer_hook() will call reload_services() */ - if ( !add_printer_hook(p->pipe_user.nt_user_token, printer) ) { + if ( !add_printer_hook(p->mem_ctx, p->pipe_user.nt_user_token, printer) ) { result = WERR_ACCESS_DENIED; goto done; } @@ -6826,18 +6896,18 @@ WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u switch (command) { case JOB_CONTROL_CANCEL: case JOB_CONTROL_DELETE: - if (print_job_delete(&p->pipe_user, snum, jobid, &errcode)) { + if (print_job_delete(p->server_info, snum, jobid, &errcode)) { errcode = WERR_OK; } break; case JOB_CONTROL_PAUSE: - if (print_job_pause(&p->pipe_user, snum, jobid, &errcode)) { + if (print_job_pause(p->server_info, snum, jobid, &errcode)) { errcode = WERR_OK; } break; case JOB_CONTROL_RESTART: case JOB_CONTROL_RESUME: - if (print_job_resume(&p->pipe_user, snum, jobid, &errcode)) { + if (print_job_resume(p->server_info, snum, jobid, &errcode)) { errcode = WERR_OK; } break; @@ -6852,7 +6922,7 @@ WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u Enumerates all printer drivers at level 1. ****************************************************************************/ -static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enumprinterdrivers_level1(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { int i; int ndrivers; @@ -6936,7 +7006,7 @@ out: Enumerates all printer drivers at level 2. ****************************************************************************/ -static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enumprinterdrivers_level2(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { int i; int ndrivers; @@ -7021,7 +7091,7 @@ out: Enumerates all printer drivers at level 3. ****************************************************************************/ -static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static WERROR enumprinterdrivers_level3(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { int i; int ndrivers; @@ -7117,7 +7187,7 @@ WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS uint32 offered = q_u->offered; uint32 *needed = &r_u->needed; uint32 *returned = &r_u->returned; - + const char *cservername; fstring servername; fstring architecture; @@ -7138,16 +7208,18 @@ WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture)); unistr2_to_ascii(servername, &q_u->name, sizeof(servername)); - if ( !is_myname_or_ipaddr( servername ) ) + cservername = canon_servername(servername); + + if (!is_myname_or_ipaddr(cservername)) return WERR_UNKNOWN_PRINTER_DRIVER; switch (level) { case 1: - return enumprinterdrivers_level1(servername, architecture, buffer, offered, needed, returned); + return enumprinterdrivers_level1(cservername, architecture, buffer, offered, needed, returned); case 2: - return enumprinterdrivers_level2(servername, architecture, buffer, offered, needed, returned); + return enumprinterdrivers_level2(cservername, architecture, buffer, offered, needed, returned); case 3: - return enumprinterdrivers_level3(servername, architecture, buffer, offered, needed, returned); + return enumprinterdrivers_level3(cservername, architecture, buffer, offered, needed, returned); default: return WERR_UNKNOWN_LEVEL; } @@ -7395,11 +7467,11 @@ static void fill_port_2(PORT_INFO_2 *port, const char *name) wrapper around the enumer ports command ****************************************************************************/ -WERROR enumports_hook( int *count, char ***lines ) +WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines ) { char *cmd = lp_enumports_cmd(); - char **qlines; - pstring command; + char **qlines = NULL; + char *command = NULL; int numlines; int ret; int fd; @@ -7423,11 +7495,15 @@ WERROR enumports_hook( int *count, char ***lines ) else { /* we have a valid enumport command */ - slprintf(command, sizeof(command)-1, "%s \"%d\"", cmd, 1); + command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1); + if (!command) { + return WERR_NOMEM; + } DEBUG(10,("Running [%s]\n", command)); ret = smbrun(command, &fd); DEBUG(10,("Returned [%d]\n", ret)); + TALLOC_FREE(command); if (ret != 0) { if (fd != -1) { close(fd); @@ -7436,7 +7512,7 @@ WERROR enumports_hook( int *count, char ***lines ) } numlines = 0; - qlines = fd_lines_load(fd, &numlines, 0); + qlines = fd_lines_load(fd, &numlines, 0, NULL); DEBUGADD(10,("Lines returned = [%d]\n", numlines)); close(fd); } @@ -7459,17 +7535,17 @@ static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *need char **qlines = NULL; int numlines = 0; - result = enumports_hook( &numlines, &qlines ); + result = enumports_hook(talloc_tos(), &numlines, &qlines ); if (!W_ERROR_IS_OK(result)) { - file_lines_free(qlines); + TALLOC_FREE(qlines); return result; } if(numlines) { if((ports=SMB_MALLOC_ARRAY( PORT_INFO_1, numlines )) == NULL) { DEBUG(10,("Returning WERR_NOMEM [%s]\n", - dos_errstr(WERR_NOMEM))); - file_lines_free(qlines); + win_errstr(WERR_NOMEM))); + TALLOC_FREE(qlines); return WERR_NOMEM; } @@ -7478,7 +7554,7 @@ static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *need fill_port_1(&ports[i], qlines[i]); } } - file_lines_free(qlines); + TALLOC_FREE(qlines); *returned = numlines; @@ -7525,15 +7601,15 @@ static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *need char **qlines = NULL; int numlines = 0; - result = enumports_hook( &numlines, &qlines ); + result = enumports_hook(talloc_tos(), &numlines, &qlines ); if ( !W_ERROR_IS_OK(result)) { - file_lines_free(qlines); + TALLOC_FREE(qlines); return result; } if(numlines) { if((ports=SMB_MALLOC_ARRAY( PORT_INFO_2, numlines)) == NULL) { - file_lines_free(qlines); + TALLOC_FREE(qlines); return WERR_NOMEM; } @@ -7543,7 +7619,7 @@ static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *need } } - file_lines_free(qlines); + TALLOC_FREE(qlines); *returned = numlines; @@ -7652,7 +7728,7 @@ static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_ trying to add a printer like this --jerry */ if (*lp_addprinter_cmd() ) { - if ( !add_printer_hook(p->pipe_user.nt_user_token, printer) ) { + if ( !add_printer_hook(p->mem_ctx, p->pipe_user.nt_user_token, printer) ) { free_a_printer(&printer,2); return WERR_ACCESS_DENIED; } @@ -7793,6 +7869,17 @@ WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u, goto done; } + switch(level) { + case 3: + fstrcpy(driver_name, + driver.info_3->name ? driver.info_3->name : ""); + break; + case 6: + fstrcpy(driver_name, + driver.info_6->name ? driver.info_6->name : ""); + break; + } + /* * I think this is where he DrvUpgradePrinter() hook would be * be called in a driver's interface DLL on a Windows NT 4.0/2k @@ -7916,26 +8003,27 @@ static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name) static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) { - pstring path; - pstring long_archi; - fstring servername; - char *pservername; + char *path = NULL; + char *long_archi = NULL; + char *servername = NULL; + const char *pservername = NULL; const char *short_archi; DRIVER_DIRECTORY_1 *info=NULL; WERROR result = WERR_OK; + TALLOC_CTX *ctx = talloc_tos(); - unistr2_to_ascii(servername, name, sizeof(servername)); - unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)); - - /* check for beginning double '\'s and that the server - long enough */ - - pservername = servername; - if ( *pservername == '\\' && strlen(servername)>2 ) { - pservername += 2; + servername = unistr2_to_ascii_talloc(ctx, name); + if (!servername) { + return WERR_NOMEM; + } + long_archi = unistr2_to_ascii_talloc(ctx, uni_environment); + if (!long_archi) { + return WERR_NOMEM; } - if ( !is_myname_or_ipaddr( pservername ) ) + pservername = canon_servername(servername); + + if ( !is_myname_or_ipaddr(pservername)) return WERR_INVALID_PARAM; if (!(short_archi = get_short_archi(long_archi))) @@ -7944,7 +8032,12 @@ static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environmen if((info=SMB_MALLOC_P(DRIVER_DIRECTORY_1)) == NULL) return WERR_NOMEM; - slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", pservername, short_archi); + path = talloc_asprintf(ctx, + "\\\\%s\\print$\\%s", pservername, short_archi); + if (!path) { + result = WERR_NOMEM; + goto out; + } DEBUG(4,("printer driver directory: [%s]\n", path)); @@ -8313,7 +8406,8 @@ WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_ int snum=0; WERROR status = WERR_OK; Printer_entry *Printer=find_printer_index_by_hnd(p, handle); - pstring valuename; + char *valuename = NULL; + TALLOC_CTX *ctx = p->mem_ctx; DEBUG(5,("spoolss_deleteprinterdata\n")); @@ -8334,7 +8428,11 @@ WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_ if (!W_ERROR_IS_OK(status)) return status; - unistr2_to_ascii(valuename, value, sizeof(valuename)); + valuename = unistr2_to_ascii_talloc(ctx, value); + if (!valuename) { + free_a_printer(&printer, 2); + return WERR_NOMEM; + } status = delete_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename ); @@ -8342,6 +8440,7 @@ WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_ mod_a_printer( printer, 2 ); free_a_printer(&printer, 2); + TALLOC_FREE(valuename); return status; } @@ -8391,7 +8490,7 @@ WERROR _spoolss_addform( pipes_struct *p, SPOOL_Q_ADDFORM *q_u, SPOOL_R_ADDFORM /* can't add if builtin */ if (get_a_builtin_ntform(&form->name,&tmpForm)) { - status = WERR_ALREADY_EXISTS; + status = WERR_FILE_EXISTS; goto done; } @@ -9245,7 +9344,9 @@ WERROR _spoolss_deleteprinterdataex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATAEX int snum=0; WERROR status = WERR_OK; Printer_entry *Printer=find_printer_index_by_hnd(p, handle); - pstring valuename, keyname; + char *valuename = NULL; + char *keyname = NULL; + TALLOC_CTX *ctx = p->mem_ctx; DEBUG(5,("spoolss_deleteprinterdataex\n")); @@ -9262,13 +9363,16 @@ WERROR _spoolss_deleteprinterdataex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATAEX return WERR_ACCESS_DENIED; } + valuename = unistr2_to_ascii_talloc(ctx, value); + keyname = unistr2_to_ascii_talloc(ctx, key); + if (!valuename || !keyname) { + return WERR_NOMEM; + } + status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); if (!W_ERROR_IS_OK(status)) return status; - unistr2_to_ascii(valuename, value, sizeof(valuename)); - unistr2_to_ascii(keyname, key, sizeof(keyname)); - status = delete_printer_dataex( printer, keyname, valuename ); if ( W_ERROR_IS_OK(status) ) @@ -9545,13 +9649,16 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_ /* copy data into the reply */ - r_u->ctr.size = r_u->needed; + /* mz: Vista x64 returns 0x6f7 (The stub received bad data), if the + response buffer size is != the offered buffer size + + r_u->ctr.size = r_u->needed; + */ + r_u->ctr.size = in_size; r_u->ctr.size_of_array = r_u->returned; r_u->ctr.values = enum_values; - - done: if ( printer ) free_a_printer(&printer, 2); @@ -9562,7 +9669,7 @@ done: /**************************************************************************** ****************************************************************************/ -static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1 *info, char *name) +static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1 *info, const char *name) { init_unistr(&info->name, name); } @@ -9573,12 +9680,15 @@ static WERROR getprintprocessordirectory_level_1(UNISTR2 *name, uint32 offered, uint32 *needed) { - pstring path; - pstring long_archi; + char *long_archi = NULL; PRINTPROCESSOR_DIRECTORY_1 *info=NULL; WERROR result = WERR_OK; + TALLOC_CTX *ctx = talloc_tos(); - unistr2_to_ascii(long_archi, environment, sizeof(long_archi)); + long_archi = unistr2_to_ascii_talloc(ctx, environment); + if (!long_archi) { + return WERR_NOMEM; + } if (!get_short_archi(long_archi)) return WERR_INVALID_ENVIRONMENT; @@ -9586,9 +9696,7 @@ static WERROR getprintprocessordirectory_level_1(UNISTR2 *name, if((info=SMB_MALLOC_P(PRINTPROCESSOR_DIRECTORY_1)) == NULL) return WERR_NOMEM; - pstrcpy(path, "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86"); - - fill_printprocessordirectory_1(info, path); + fill_printprocessordirectory_1(info, "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86"); *needed += spoolss_size_printprocessordirectory_info_1(info); @@ -9673,7 +9781,8 @@ static WERROR xcvtcp_addport( NT_USER_TOKEN *token, RPC_BUFFER *in, RPC_BUFFER *out, uint32 *needed ) { NT_PORT_DATA_1 port1; - pstring device_uri; + TALLOC_CTX *ctx = talloc_tos(); + char *device_uri = NULL; ZERO_STRUCT( port1 ); @@ -9687,18 +9796,24 @@ static WERROR xcvtcp_addport( NT_USER_TOKEN *token, RPC_BUFFER *in, switch ( port1.protocol ) { case PORT_PROTOCOL_DIRECT: - pstr_sprintf( device_uri, "socket://%s:%d/", port1.hostaddr, port1.port ); + device_uri = talloc_asprintf(ctx, + "socket://%s:%d/", port1.hostaddr, port1.port ); break; case PORT_PROTOCOL_LPR: - pstr_sprintf( device_uri, "lpr://%s/%s", port1.hostaddr, port1.queue ); + device_uri = talloc_asprintf(ctx, + "lpr://%s/%s", port1.hostaddr, port1.queue ); break; default: return WERR_UNKNOWN_PORT; } - return add_port_hook( token, port1.name, device_uri ); + if (!device_uri) { + return WERR_NOMEM; + } + + return add_port_hook(ctx, token, port1.name, device_uri ); } /*******************************************************************