added jeremy's new c++-like code for parsing of security descriptors.
[samba.git] / source3 / rpc_parse / parse_svc.c
1
2 /* 
3  *  Unix SMB/Netbios implementation.
4  *  Version 1.9.
5  *  RPC Pipe client / server routines
6  *  Copyright (C) Andrew Tridgell              1992-1997,
7  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
8  *  Copyright (C) Paul Ashton                       1997.
9  *  
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *  
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *  
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24
25
26 #include "includes.h"
27
28 extern int DEBUGLEVEL;
29
30 /*******************************************************************
31  make_svc_q_open_sc_man
32  ********************************************************************/
33 void make_svc_q_open_sc_man(SVC_Q_OPEN_SC_MAN *q_u,
34                                 char *server, char *database,
35                                 uint32 des_access)  
36 {
37         DEBUG(5,("make_svc_q_open_sc_man\n"));
38
39         make_buf_unistr2(&(q_u->uni_srv_name), &(q_u->ptr_srv_name), server);
40         make_buf_unistr2(&(q_u->uni_db_name ), &(q_u->ptr_db_name), database);
41         q_u->des_access = des_access;
42
43 }
44
45 /*******************************************************************
46 reads or writes a SVC_Q_OPEN_SC_MAN structure.
47 ********************************************************************/
48 void svc_io_q_open_sc_man(char *desc, SVC_Q_OPEN_SC_MAN *q_u, prs_struct *ps, int depth)
49 {
50         if (q_u == NULL) return;
51
52         prs_debug(ps, depth, desc, "svc_io_q_open_sc_man");
53         depth++;
54
55         prs_align(ps);
56
57         prs_uint32("ptr_srv_name", ps, depth, &(q_u->ptr_srv_name));
58         smb_io_unistr2("", &(q_u->uni_srv_name), q_u->ptr_srv_name, ps, depth); 
59         prs_align(ps);
60
61         prs_uint32("ptr_db_name", ps, depth, &(q_u->ptr_db_name));
62         smb_io_unistr2("", &(q_u->uni_db_name), q_u->ptr_db_name, ps, depth); 
63         prs_align(ps);
64
65         prs_uint32("des_access", ps, depth, &(q_u->des_access));
66         prs_align(ps);
67 }
68
69 /*******************************************************************
70  make_svc_r_open_sc_man
71  ********************************************************************/
72 void make_svc_r_open_sc_man(SVC_R_OPEN_SC_MAN *r_u, POLICY_HND *hnd,
73                                 uint32 status)  
74 {
75         DEBUG(5,("make_svc_r_unknown_0: %d\n", __LINE__));
76
77         memcpy(&(r_u->pol), hnd, sizeof(r_u->pol));
78         r_u->status = status;
79 }
80
81 /*******************************************************************
82 reads or writes a structure.
83 ********************************************************************/
84 void svc_io_r_open_sc_man(char *desc,  SVC_R_OPEN_SC_MAN *r_u, prs_struct *ps, int depth)
85 {
86         if (r_u == NULL) return;
87
88         prs_debug(ps, depth, desc, "svc_io_r_open_sc_man");
89         depth++;
90
91         prs_align(ps);
92
93         smb_io_pol_hnd("", &(r_u->pol), ps, depth);
94
95         prs_uint32("status      ", ps, depth, &(r_u->status));
96 }
97
98 /*******************************************************************
99  make_svc_q_open_service
100  ********************************************************************/
101 void make_svc_q_open_service(SVC_Q_OPEN_SERVICE *q_u,
102                                 POLICY_HND *hnd,
103                                 char *server,
104                                 uint32 des_access)  
105 {
106         DEBUG(5,("make_svc_q_open_service\n"));
107
108         memcpy(&(q_u->scman_pol), hnd, sizeof(q_u->scman_pol));
109         make_unistr2(&(q_u->uni_svc_name), server, strlen(server)+1);
110         q_u->des_access = des_access;
111
112 }
113
114 /*******************************************************************
115 reads or writes a SVC_Q_OPEN_SERVICE structure.
116 ********************************************************************/
117 void svc_io_q_open_service(char *desc, SVC_Q_OPEN_SERVICE *q_u, prs_struct *ps, int depth)
118 {
119         if (q_u == NULL) return;
120
121         prs_debug(ps, depth, desc, "svc_io_q_open_service");
122         depth++;
123
124         prs_align(ps);
125
126         smb_io_pol_hnd("", &(q_u->scman_pol), ps, depth);
127         prs_align(ps);
128
129         smb_io_unistr2("", &(q_u->uni_svc_name), 1, ps, depth); 
130         prs_align(ps);
131
132         prs_uint32("des_access", ps, depth, &(q_u->des_access));
133         prs_align(ps);
134 }
135
136 /*******************************************************************
137  make_svc_r_open_service
138  ********************************************************************/
139 void make_svc_r_open_service(SVC_R_OPEN_SERVICE *r_u, POLICY_HND *hnd,
140                                 uint32 status)  
141 {
142         DEBUG(5,("make_svc_r_unknown_0: %d\n", __LINE__));
143
144         memcpy(&(r_u->pol), hnd, sizeof(r_u->pol));
145         r_u->status = status;
146 }
147
148 /*******************************************************************
149 reads or writes a structure.
150 ********************************************************************/
151 void svc_io_r_open_service(char *desc,  SVC_R_OPEN_SERVICE *r_u, prs_struct *ps, int depth)
152 {
153         if (r_u == NULL) return;
154
155         prs_debug(ps, depth, desc, "svc_io_r_open_service");
156         depth++;
157
158         prs_align(ps);
159
160         smb_io_pol_hnd("", &(r_u->pol), ps, depth);
161
162         prs_uint32("status      ", ps, depth, &(r_u->status));
163 }
164
165 /*******************************************************************
166  make_svc_query_svc_cfg
167  ********************************************************************/
168 void make_svc_query_svc_cfg(QUERY_SERVICE_CONFIG *q_u,
169                                 uint32 service_type, uint32 start_type,
170                                 uint32 error_control,
171                                 char* bin_path_name, char* load_order_grp, 
172                                 uint32 tag_id,
173                                 char* dependencies, char* service_start_name,
174                                 char* disp_name)
175 {
176         DEBUG(5,("make_svc_query_svc_cfg\n"));
177
178         q_u->service_type = service_type;
179         q_u->start_type = start_type;
180         q_u->error_control = error_control;
181         make_buf_unistr2(&(q_u->uni_bin_path_name     ), &(q_u->ptr_bin_path_name     ), bin_path_name     );
182         make_buf_unistr2(&(q_u->uni_load_order_grp    ), &(q_u->ptr_load_order_grp    ), load_order_grp    );
183         q_u->tag_id = tag_id;
184         make_buf_unistr2(&(q_u->uni_dependencies      ), &(q_u->ptr_dependencies      ), dependencies      );
185         make_buf_unistr2(&(q_u->uni_service_start_name), &(q_u->ptr_service_start_name), service_start_name);
186         make_buf_unistr2(&(q_u->uni_display_name      ), &(q_u->ptr_display_name      ), disp_name         );
187 }
188
189 /*******************************************************************
190 reads or writes a QUERY_SERVICE_CONFIG structure.
191 ********************************************************************/
192 void svc_io_query_svc_cfg(char *desc, QUERY_SERVICE_CONFIG *q_u, prs_struct *ps, int depth)
193 {
194         if (q_u == NULL) return;
195
196         prs_debug(ps, depth, desc, "svc_io_query_svc_cfg");
197         depth++;
198
199         prs_align(ps);
200
201         prs_uint32("service_type          ", ps, depth, &(q_u->service_type          ));
202         prs_uint32("start_type            ", ps, depth, &(q_u->start_type            ));
203         prs_uint32("error_control         ", ps, depth, &(q_u->error_control         ));
204         prs_uint32("ptr_bin_path_name     ", ps, depth, &(q_u->ptr_bin_path_name     ));
205         prs_uint32("ptr_load_order_grp    ", ps, depth, &(q_u->ptr_load_order_grp    ));
206         prs_uint32("tag_id                ", ps, depth, &(q_u->tag_id                ));
207         prs_uint32("ptr_dependencies      ", ps, depth, &(q_u->ptr_dependencies      ));
208         prs_uint32("ptr_service_start_name", ps, depth, &(q_u->ptr_service_start_name));
209         prs_uint32("ptr_display_name      ", ps, depth, &(q_u->ptr_display_name      ));
210
211         smb_io_unistr2("uni_bin_path_name     ", &(q_u->uni_bin_path_name     ), q_u->ptr_bin_path_name     , ps, depth); 
212         prs_align(ps);
213         smb_io_unistr2("uni_load_order_grp    ", &(q_u->uni_load_order_grp    ), q_u->ptr_load_order_grp    , ps, depth); 
214         prs_align(ps);
215         smb_io_unistr2("uni_dependencies      ", &(q_u->uni_dependencies      ), q_u->ptr_dependencies      , ps, depth); 
216         prs_align(ps);
217         smb_io_unistr2("uni_service_start_name", &(q_u->uni_service_start_name), q_u->ptr_service_start_name, ps, depth); 
218         prs_align(ps);
219         smb_io_unistr2("uni_display_name      ", &(q_u->uni_display_name      ), q_u->ptr_display_name      , ps, depth); 
220         prs_align(ps);
221 }
222
223 /*******************************************************************
224 makes an SVC_Q_ENUM_SVCS_STATUS structure.
225 ********************************************************************/
226 void make_svc_q_enum_svcs_status(SVC_Q_ENUM_SVCS_STATUS *q_c, POLICY_HND *hnd,
227                                 uint32 service_type, uint32 service_state,
228                                 uint32 buf_size, uint32 resume_hnd )
229 {
230         if (q_c == NULL || hnd == NULL) return;
231
232         DEBUG(5,("make_svc_q_enum_svcs_status\n"));
233
234         memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
235         q_c->service_type = service_type;
236         q_c->service_state = service_state;
237         q_c->buf_size = buf_size;
238         make_enum_hnd(&q_c->resume_hnd, resume_hnd);
239 }
240
241 /*******************************************************************
242 reads or writes a structure.
243 ********************************************************************/
244 void svc_io_q_enum_svcs_status(char *desc,  SVC_Q_ENUM_SVCS_STATUS *q_u, prs_struct *ps, int depth)
245 {
246         if (q_u == NULL) return;
247
248         prs_debug(ps, depth, desc, "svc_io_q_enum_svcs_status");
249         depth++;
250
251         prs_align(ps);
252
253         smb_io_pol_hnd("", &(q_u->pol), ps, depth); 
254         prs_align(ps);
255
256         prs_uint32("service_type ", ps, depth, &(q_u->service_type ));
257         prs_uint32("service_state", ps, depth, &(q_u->service_state));
258         prs_uint32("buf_size     ", ps, depth, &(q_u->buf_size     ));
259         smb_io_enum_hnd("resume_hnd", &(q_u->resume_hnd), ps, depth); 
260 }
261
262 /*******************************************************************
263 makes an SVC_R_ENUM_SVCS_STATUS structure.
264 ********************************************************************/
265 void make_svc_r_enum_svcs_status(SVC_R_ENUM_SVCS_STATUS *r_c, 
266                                 ENUM_SRVC_STATUS *svcs, uint32 more_buf_size,
267                                 uint32 num_svcs, uint32 resume_hnd,
268                                 uint32 dos_status)
269 {
270         if (r_c == NULL) return;
271
272         DEBUG(5,("make_svc_r_enum_svcs_status\n"));
273
274         r_c->svcs          = svcs;
275         r_c->more_buf_size = more_buf_size;
276         r_c->num_svcs      = num_svcs;
277         make_enum_hnd(&r_c->resume_hnd, resume_hnd);
278         r_c->dos_status = dos_status;
279 }
280
281 /*******************************************************************
282 reads or writes a SVC_R_ENUM_SVCS_STATUS structure.
283
284 this is another wierd structure.  WHY oh WHY can the microsoft teams
285 not COMMUNICATE and get some CONSISTENCY TO THEIR DATA STRUCTURES!
286 ARGH!
287
288 ********************************************************************/
289 void svc_io_r_enum_svcs_status(char *desc, SVC_R_ENUM_SVCS_STATUS *svc, prs_struct *ps, int depth)
290 {
291         int i;
292         if (svc == NULL) return;
293
294         prs_debug(ps, depth, desc, "svc_io_r_enum_svcs_status");
295         depth++;
296
297         prs_align(ps);
298         
299         /*
300          * format is actually as laid out in SVC_R_ENUM_SVCS_STATUS.
301          * the reason for all the jumping about, which is horrible
302          * and can be avoided, is due to the use of offsets instead
303          * of pointers.
304          *
305          * if i ever find out that these offsets are in fact non-zero
306          * tokens just like pointer-tokens, i am going to go MAD.
307          */
308
309         if (ps->io)
310         {
311                 /* reading */
312
313                 uint32 buf_offset;
314                 uint32 new_offset;
315
316                 prs_uint32("buf_size", ps, depth, &(svc->buf_size));
317
318                 buf_offset = ps->offset;
319                 ps->offset = buf_offset + svc->buf_size;
320
321                 prs_uint32("more_buf_size", ps, depth, &(svc->more_buf_size));
322                 prs_uint32("num_svcs", ps, depth, &(svc->num_svcs));
323                 smb_io_enum_hnd("resume_hnd", &(svc->resume_hnd), ps, depth); 
324                 prs_uint32("dos_status", ps, depth, &(svc->dos_status));
325
326                 new_offset = ps->offset;
327                 ps->offset = buf_offset;
328
329                 svc->svcs = Realloc(NULL, svc->num_svcs * sizeof(ENUM_SRVC_STATUS));
330
331                 if (svc->svcs == NULL)
332                 {
333                         DEBUG(0,("svc_io_r_enum_svcs_status: Realloc failed\n"));
334                         ps->offset = 0x7fffffff;
335                         return;
336                 }
337
338                 bzero(svc->svcs, svc->num_svcs * sizeof(ENUM_SRVC_STATUS));
339
340                 for (i = 0; i < svc->num_svcs; i++)
341                 {
342                         fstring name;
343                         uint32 old_offset;
344                         uint32 srvc_offset;
345                         uint32 disp_offset;
346
347                         prs_uint32("srvc_offset", ps, depth, &srvc_offset);
348                         prs_uint32("disp_offset", ps, depth, &disp_offset);
349                         svc_io_svc_status("status", &svc->svcs[i].status, ps, depth); 
350
351                         old_offset = ps->offset;
352
353                         ps->offset = buf_offset + srvc_offset;
354                         slprintf(name, sizeof(name)-1, "srvc[%02d]", i);
355                         smb_io_unistr(name, &svc->svcs[i].uni_srvc_name, ps, depth);
356
357                         ps->offset = buf_offset + disp_offset;
358                         slprintf(name, sizeof(name)-1, "disp[%02d]", i);
359                         smb_io_unistr(name, &svc->svcs[i].uni_disp_name, ps, depth);
360
361                         ps->offset = old_offset;
362                 }
363
364                 ps->offset = new_offset;
365         }
366         else
367         {
368                 /* writing */
369
370                 uint32 buf_offset;
371                 uint32 old_buf_offset;
372                 uint32 srvc_offset = 9 * sizeof(uint32) * svc->num_svcs;
373
374                 prs_uint32_pre("buf_size", ps, depth, &svc->buf_size, &buf_offset);
375                 old_buf_offset = ps->offset;
376
377                 srvc_offset += old_buf_offset;
378
379                 if (svc->svcs == NULL)
380                 {
381                         return;
382                 }
383
384                 for (i = 0; i < svc->num_svcs; i++)
385                 {
386                         fstring name;
387                         uint32 old_offset;
388
389                         /*
390                          * store unicode string offset and unicode string
391                          */
392
393                         srvc_offset -= old_buf_offset;
394                         prs_uint32("srvc_offset", ps, depth, &srvc_offset);
395                         srvc_offset += old_buf_offset;
396
397                         slprintf(name, sizeof(name)-1, "srvc[%02d]", i);
398
399                         old_offset = ps->offset;
400                         ps->offset = srvc_offset;
401                         smb_io_unistr(name, &svc->svcs[i].uni_srvc_name, ps, depth);
402                         srvc_offset = ps->offset;
403                         ps->offset = old_offset;
404
405                         /*
406                          * store unicode string offset and unicode string
407                          */
408
409                         srvc_offset -= old_buf_offset;
410                         prs_uint32("disp_offset", ps, depth, &srvc_offset);
411                         srvc_offset += old_buf_offset;
412
413                         slprintf(name, sizeof(name)-1, "disp[%02d]", i);
414
415                         old_offset = ps->offset;
416                         ps->offset = srvc_offset;
417                         smb_io_unistr(name, &svc->svcs[i].uni_disp_name, ps, depth);
418                         srvc_offset = ps->offset;
419                         ps->offset = old_offset;
420
421                         /*
422                          * store status info
423                          */
424
425                         svc_io_svc_status("status", &svc->svcs[i].status, ps, depth); 
426                 }
427
428                 prs_uint32_post("buf_size", ps, depth, &svc->buf_size, buf_offset, srvc_offset - buf_offset - sizeof(uint32));
429
430                 ps->offset = srvc_offset;
431
432                 prs_uint32("more_buf_size", ps, depth, &(svc->more_buf_size));
433                 prs_uint32("num_svcs", ps, depth, &(svc->num_svcs));
434                 smb_io_enum_hnd("resume_hnd", &(svc->resume_hnd), ps, depth); 
435                 prs_uint32("dos_status", ps, depth, &(svc->dos_status));
436         }
437 }
438
439 /*******************************************************************
440 reads or writes a structure.
441 ********************************************************************/
442 void svc_io_svc_status(char *desc,  SVC_STATUS *svc, prs_struct *ps, int depth)
443 {
444         if (svc == NULL) return;
445
446         prs_debug(ps, depth, desc, "svc_io_svc_status");
447         depth++;
448
449         prs_align(ps);
450
451         prs_uint32("svc_type", ps, depth, &(svc->svc_type));
452         prs_uint32("current_state", ps, depth, &(svc->current_state));
453         prs_uint32("controls_accepted", ps, depth, &(svc->controls_accepted));
454         prs_uint32("win32_exit_code", ps, depth, &(svc->win32_exit_code));
455         prs_uint32("svc_specific_exit_code", ps, depth, &(svc->svc_specific_exit_code));
456         prs_uint32("check_point", ps, depth, &(svc->check_point));
457         prs_uint32("wait_hint", ps, depth, &(svc->wait_hint));
458 }
459
460 /*******************************************************************
461 makes an SVC_Q_QUERY_SVC_CONFIG structure.
462 ********************************************************************/
463 void make_svc_q_query_svc_config(SVC_Q_QUERY_SVC_CONFIG *q_c, POLICY_HND *hnd,
464                                 uint32 buf_size)
465 {
466         if (q_c == NULL || hnd == NULL) return;
467
468         DEBUG(5,("make_svc_q_query_svc_config\n"));
469
470         memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
471         q_c->buf_size = buf_size;
472 }
473
474 /*******************************************************************
475 reads or writes a structure.
476 ********************************************************************/
477 void svc_io_q_query_svc_config(char *desc,  SVC_Q_QUERY_SVC_CONFIG *q_u, prs_struct *ps, int depth)
478 {
479         if (q_u == NULL) return;
480
481         prs_debug(ps, depth, desc, "svc_io_q_query_svc_config");
482         depth++;
483
484         prs_align(ps);
485
486         smb_io_pol_hnd("", &(q_u->pol), ps, depth); 
487         prs_align(ps);
488         prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
489 }
490
491 /*******************************************************************
492 makes an SVC_R_QUERY_SVC_CONFIG structure.
493 ********************************************************************/
494 void make_svc_r_query_svc_config(SVC_R_QUERY_SVC_CONFIG *r_c, 
495                                 QUERY_SERVICE_CONFIG *cfg,
496                                 uint32 buf_size)
497 {
498         if (r_c == NULL) return;
499
500         DEBUG(5,("make_svc_r_query_svc_config\n"));
501
502         r_c->cfg      = cfg;
503         r_c->buf_size = buf_size;
504 }
505
506 /*******************************************************************
507 reads or writes a structure.
508 ********************************************************************/
509 void svc_io_r_query_svc_config(char *desc,  SVC_R_QUERY_SVC_CONFIG *r_u, prs_struct *ps, int depth)
510 {
511         if (r_u == NULL) return;
512
513         prs_debug(ps, depth, desc, "svc_io_r_query_svc_config");
514         depth++;
515
516         prs_align(ps);
517
518         svc_io_query_svc_cfg("cfg", r_u->cfg, ps, depth); 
519         prs_uint32("buf_size", ps, depth, &(r_u->buf_size));
520         prs_uint32("status  ", ps, depth, &(r_u->status  ));
521 }
522
523 /*******************************************************************
524 makes an SVC_Q_CLOSE structure.
525 ********************************************************************/
526 void make_svc_q_close(SVC_Q_CLOSE *q_c, POLICY_HND *hnd)
527 {
528         if (q_c == NULL || hnd == NULL) return;
529
530         DEBUG(5,("make_svc_q_close\n"));
531
532         memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
533 }
534
535 /*******************************************************************
536 reads or writes a structure.
537 ********************************************************************/
538 void svc_io_q_close(char *desc,  SVC_Q_CLOSE *q_u, prs_struct *ps, int depth)
539 {
540         if (q_u == NULL) return;
541
542         prs_debug(ps, depth, desc, "svc_io_q_close");
543         depth++;
544
545         prs_align(ps);
546
547         smb_io_pol_hnd("", &(q_u->pol), ps, depth); 
548         prs_align(ps);
549 }
550
551 /*******************************************************************
552 reads or writes a structure.
553 ********************************************************************/
554 void svc_io_r_close(char *desc,  SVC_R_CLOSE *r_u, prs_struct *ps, int depth)
555 {
556         if (r_u == NULL) return;
557
558         prs_debug(ps, depth, desc, "svc_io_r_close");
559         depth++;
560
561         prs_align(ps);
562
563         smb_io_pol_hnd("", &(r_u->pol), ps, depth); 
564         prs_align(ps);
565
566         prs_uint32("status", ps, depth, &(r_u->status));
567 }
568