Coverage Report

Created: 2025-07-23 07:04

/src/samba/source3/libsmb/cliprint.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
   Unix SMB/CIFS implementation.
3
   client print routines
4
   Copyright (C) Andrew Tridgell 1994-1998
5
6
   This program is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 3 of the License, or
9
   (at your option) any later version.
10
11
   This program is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
   GNU General Public License for more details.
15
16
   You should have received a copy of the GNU General Public License
17
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
*/
19
20
#include "includes.h"
21
#include "source3/include/client.h"
22
#include "source3/libsmb/proto.h"
23
#include "libsmb/clirap.h"
24
#include "../libcli/smb/smbXcli_base.h"
25
#include "lib/util/string_wrappers.h"
26
27
/*****************************************************************************
28
 Convert a character pointer in a cli_call_api() response to a form we can use.
29
 This function contains code to prevent core dumps if the server returns
30
 invalid data.
31
*****************************************************************************/
32
static const char *fix_char_ptr(unsigned int datap, unsigned int converter,
33
        char *rdata, int rdrcnt)
34
0
{
35
0
  unsigned int offset;
36
37
0
  if (datap == 0) {
38
    /* turn NULL pointers into zero length strings */
39
0
    return "";
40
0
  }
41
42
0
  offset = datap - converter;
43
44
0
  if (offset >= rdrcnt) {
45
0
    DEBUG(1,("bad char ptr: datap=%u, converter=%u rdrcnt=%d>\n",
46
0
       datap, converter, rdrcnt));
47
0
    return "<ERROR>";
48
0
  }
49
0
  return &rdata[offset];
50
0
}
51
52
/****************************************************************************
53
call fn() on each entry in a print queue
54
****************************************************************************/
55
56
NTSTATUS cli_print_queue(struct cli_state *cli,
57
       void (*fn)(struct print_job_info *))
58
0
{
59
0
  uint8_t *rparam = NULL;
60
0
  uint8_t *rdata = NULL;
61
0
  char *p = NULL;
62
0
  uint32_t rdrcnt, rprcnt;
63
0
  char param[1024];
64
0
  int converter;
65
0
  int result_code=0;
66
0
  int i = -1;
67
0
  NTSTATUS status;
68
69
0
  memset(param,'\0',sizeof(param));
70
71
0
  p = param;
72
0
  SSVAL(p,0,76);         /* API function number 76 (DosPrintJobEnum) */
73
0
  p += 2;
74
0
  strlcpy_base(p,"zWrLeh", param, sizeof(param));   /* parameter description? */
75
0
  p = skip_string(param,sizeof(param),p);
76
0
  strlcpy_base(p,"WWzWWDDzz", param, sizeof(param));  /* returned data format */
77
0
  p = skip_string(param,sizeof(param),p);
78
0
  strlcpy_base(p,cli->share, param, sizeof(param));    /* name of queue */
79
0
  p = skip_string(param,sizeof(param),p);
80
0
  SSVAL(p,0,2);   /* API function level 2, PRJINFO_2 data structure */
81
0
  SSVAL(p,2,1000); /* size of bytes of returned data buffer */
82
0
  p += 4;
83
0
  strlcpy_base(p,"", param,sizeof(param));   /* subformat */
84
0
  p = skip_string(param,sizeof(param),p);
85
86
0
  DEBUG(4,("doing cli_print_queue for %s\n", cli->share));
87
88
0
  status = cli_trans(
89
0
    talloc_tos(),
90
0
    cli,
91
0
    SMBtrans,    /* trans_cmd */
92
0
    "\\PIPE\\LANMAN",  /* name */
93
0
    0,       /* fid */
94
0
    0,       /* function */
95
0
    0,       /* flags */
96
0
    NULL,      /* setup */
97
0
    0,       /* num_setup */
98
0
    0,       /* max_setup */
99
0
    (uint8_t *)param,  /* param */
100
0
    PTR_DIFF(p,param), /* num_param */
101
0
    1024,      /* max_param */
102
0
    NULL,      /* data */
103
0
    0,       /* num_data */
104
0
    CLI_BUFFER_SIZE,   /* max_data */
105
0
    NULL,      /* recv_flags2 */
106
0
    NULL,      /* rsetup */
107
0
    0,       /* min_rsetup */
108
0
    NULL,      /* num_rsetup */
109
0
    &rparam,     /* rparam */
110
0
    8,       /* min_rparam */
111
0
    &rprcnt,     /* num_rparam */
112
0
    &rdata,      /* rdata */
113
0
    0,       /* min_rdata */
114
0
    &rdrcnt);    /* num_rdata */
115
0
  if (!NT_STATUS_IS_OK(status)) {
116
0
    return status;
117
0
  }
118
119
0
  result_code = SVAL(rparam,0);
120
0
  converter = SVAL(rparam,2);       /* conversion factor */
121
122
0
  if (result_code == 0) {
123
0
    struct print_job_info job;
124
125
0
    p = (char *)rdata;
126
127
0
    for (i = 0; i < SVAL(rparam,4); ++i) {
128
0
      job.id = SVAL(p,0);
129
0
      job.priority = SVAL(p,2);
130
0
      fstrcpy(job.user,
131
0
        fix_char_ptr(SVAL(p,4), converter,
132
0
               (char *)rdata, rdrcnt));
133
0
      job.t = make_unix_date3(
134
0
        p + 12, smb1cli_conn_server_time_zone(cli->conn));
135
0
      job.size = IVAL(p,16);
136
0
      fstrcpy(job.name,fix_char_ptr(SVAL(p,24),
137
0
                  converter,
138
0
                  (char *)rdata, rdrcnt));
139
0
      fn(&job);
140
0
      p += 28;
141
0
    }
142
0
  }
143
144
  /* If any parameters or data were returned, free the storage. */
145
0
  TALLOC_FREE(rparam);
146
0
  TALLOC_FREE(rdata);
147
148
0
  return NT_STATUS_OK;
149
0
}
150
151
/****************************************************************************
152
  cancel a print job
153
  ****************************************************************************/
154
155
NTSTATUS cli_printjob_del(struct cli_state *cli, int job)
156
0
{
157
0
  uint8_t *rparam = NULL;
158
0
  uint8_t *rdata = NULL;
159
0
  char *p = NULL;
160
0
  uint32_t rdrcnt, rprcnt;
161
0
  int result_code;
162
0
  char param[1024];
163
0
  NTSTATUS status = NT_STATUS_OK;
164
165
0
  memset(param,'\0',sizeof(param));
166
167
0
  p = param;
168
0
  SSVAL(p,0,81);   /* DosPrintJobDel() */
169
0
  p += 2;
170
0
  strlcpy_base(p,"W", param,sizeof(param));
171
0
  p = skip_string(param,sizeof(param),p);
172
0
  strlcpy_base(p,"", param,sizeof(param));
173
0
  p = skip_string(param,sizeof(param),p);
174
0
  SSVAL(p,0,job);
175
0
  p += 2;
176
177
0
  status = cli_trans(talloc_tos(),
178
0
         cli,
179
0
         SMBtrans,        /* trans_cmd */
180
0
         "\\PIPE\\LANMAN",   /* name */
181
0
         0,          /* fid */
182
0
         0,          /* function */
183
0
         0,          /* flags */
184
0
         NULL,         /* setup */
185
0
         0,          /* num_setup */
186
0
         0,          /* max_setup */
187
0
         (uint8_t *)param,   /* param */
188
0
         PTR_DIFF(p, param), /* num_param */
189
0
         1024,         /* max_param */
190
0
         NULL,         /* data */
191
0
         0,          /* num_data */
192
0
         CLI_BUFFER_SIZE,    /* max_data */
193
0
         NULL,         /* recv_flags2 */
194
0
         NULL,         /* rsetup */
195
0
         0,          /* min_rsetup */
196
0
         NULL,         /* num_rsetup */
197
0
         &rparam,        /* rparam */
198
0
         8,          /* min_rparam */
199
0
         &rprcnt,        /* num_rparam */
200
0
         &rdata,         /* rdata */
201
0
         0,          /* min_rdata */
202
0
         &rdrcnt);         /* num_rdata */
203
0
  if (!NT_STATUS_IS_OK(status)) {
204
0
    return status;
205
0
  }
206
207
0
  result_code = SVAL(rparam, 0);
208
209
0
  TALLOC_FREE(rparam);
210
0
  TALLOC_FREE(rdata);
211
212
0
  if (result_code == ERRnosuchprintjob) {
213
0
    status = NT_STATUS_INVALID_PARAMETER;
214
0
  }
215
216
0
  return status;
217
0
}