Small update to clitar.c to omit warnings about servers not
[samba.git] / source3 / rpc_server / srv_srvsvc.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 #include "nterr.h"
28
29 extern int DEBUGLEVEL;
30 extern pstring global_myname;
31
32 /*******************************************************************
33  fill in a share info level 1 structure.
34
35  this function breaks the rule that i'd like to be in place, namely
36  it doesn't receive its data as arguments: it has to call lp_xxxx()
37  functions itself.  yuck.
38
39  see ipc.c:fill_share_info()
40
41  ********************************************************************/
42 static void make_srv_share_1_info(SH_INFO_1    *sh1,
43                                   SH_INFO_1_STR *str1, int snum)
44 {
45         int len_net_name;
46         pstring net_name;
47         pstring remark;
48         uint32 type;
49
50         pstrcpy(net_name, lp_servicename(snum));
51         pstrcpy(remark  , lp_comment    (snum));
52         len_net_name = strlen(net_name);
53
54         /* work out the share type */
55         type = STYPE_DISKTREE;
56                 
57         if (lp_print_ok(snum))             type = STYPE_PRINTQ;
58         if (strequal("IPC$", net_name))    type = STYPE_IPC;
59         if (net_name[len_net_name] == '$') type |= STYPE_HIDDEN;
60
61         make_srv_share_info1    (sh1 , net_name, type, remark);
62         make_srv_share_info1_str(str1, net_name,       remark);
63 }
64
65 /*******************************************************************
66  fill in a share info level 1 structure.
67
68  this function breaks the rule that i'd like to be in place, namely
69  it doesn't receive its data as arguments: it has to call lp_xxxx()
70  functions itself.  yuck.
71
72  ********************************************************************/
73 static void make_srv_share_info_1(SRV_SHARE_INFO_1 *sh1, uint32 *snum, uint32 *svcs)
74 {
75         uint32 num_entries = 0;
76         (*svcs) = lp_numservices();
77
78         if (sh1 == NULL)
79         {
80                 (*snum) = 0;
81                 return;
82         }
83
84         DEBUG(5,("make_srv_share_1_sh1\n"));
85
86         for (; (*snum) < (*svcs) && num_entries < MAX_SHARE_ENTRIES; (*snum)++)
87         {
88                 if (lp_browseable((*snum)) && lp_snum_ok((*snum)))
89                 {
90                         make_srv_share_1_info(&(sh1->info_1    [num_entries]),
91                                                   &(sh1->info_1_str[num_entries]), (*snum));
92
93                         /* move on to creating next share */
94                         num_entries++;
95                 }
96         }
97
98         sh1->num_entries_read  = num_entries;
99         sh1->ptr_share_info    = num_entries > 0 ? 1 : 0;
100         sh1->num_entries_read2 = num_entries;
101         
102         if ((*snum) >= (*svcs))
103         {
104                 (*snum) = 0;
105         }
106 }
107
108 /*******************************************************************
109  fill in a share info level 2 structure.
110
111  this function breaks the rule that i'd like to be in place, namely
112  it doesn't receive its data as arguments: it has to call lp_xxxx()
113  functions itself.  yuck.
114
115  see ipc.c:fill_share_info()
116
117  ********************************************************************/
118 static void make_srv_share_2_info(SH_INFO_2     *sh2,
119                                   SH_INFO_2_STR *str2, int snum)
120 {
121         int len_net_name;
122         pstring net_name;
123         pstring remark;
124         pstring path;
125         pstring passwd;
126         uint32 type;
127
128         pstrcpy(net_name, lp_servicename(snum));
129         pstrcpy(remark  , lp_comment    (snum));
130         pstrcpy(path    , lp_pathname   (snum));
131         pstrcpy(passwd  , "");
132         len_net_name = strlen(net_name);
133
134         /* work out the share type */
135         type = STYPE_DISKTREE;
136                 
137         if (lp_print_ok(snum))             type = STYPE_PRINTQ;
138         if (strequal("IPC$", net_name))    type = STYPE_IPC;
139         if (net_name[len_net_name] == '$') type |= STYPE_HIDDEN;
140
141         make_srv_share_info2    (sh2 , net_name, type, remark, 0, 0xffffffff, 1, path, passwd);
142         make_srv_share_info2_str(str2, net_name,       remark,                   path, passwd);
143 }
144
145 /*******************************************************************
146  fill in a share info level 2 structure.
147
148  this function breaks the rule that i'd like to be in place, namely
149  it doesn't receive its data as arguments: it has to call lp_xxxx()
150  functions itself.  yuck.
151
152  ********************************************************************/
153 static void make_srv_share_info_2(SRV_SHARE_INFO_2 *sh2, uint32 *snum, uint32 *svcs)
154 {
155         uint32 num_entries = 0;
156         (*svcs) = lp_numservices();
157
158         if (sh2 == NULL)
159         {
160                 (*snum) = 0;
161                 return;
162         }
163
164         DEBUG(5,("make_srv_share_2_sh1\n"));
165
166         for (; (*snum) < (*svcs) && num_entries < MAX_SHARE_ENTRIES; (*snum)++)
167         {
168                 if (lp_browseable((*snum)) && lp_snum_ok((*snum)))
169                 {
170                         make_srv_share_2_info(&(sh2->info_2    [num_entries]),
171                                                   &(sh2->info_2_str[num_entries]), (*snum));
172
173                         /* move on to creating next share */
174                         num_entries++;
175                 }
176         }
177
178         sh2->num_entries_read  = num_entries;
179         sh2->ptr_share_info    = num_entries > 0 ? 1 : 0;
180         sh2->num_entries_read2 = num_entries;
181         
182         if ((*snum) >= (*svcs))
183         {
184                 (*snum) = 0;
185         }
186 }
187
188 /*******************************************************************
189  makes a SRV_R_NET_SHARE_ENUM structure.
190 ********************************************************************/
191 static uint32 make_srv_share_info_ctr(SRV_SHARE_INFO_CTR *ctr,
192                                 int switch_value, uint32 *resume_hnd, uint32 *total_entries)  
193 {
194         uint32 status = 0x0;
195         DEBUG(5,("make_srv_share_info_ctr: %d\n", __LINE__));
196
197         ctr->switch_value = switch_value;
198
199         switch (switch_value)
200         {
201                 case 1:
202                 {
203                         make_srv_share_info_1(&(ctr->share.info1), resume_hnd, total_entries);
204                         ctr->ptr_share_ctr = 1;
205                         break;
206                 }
207                 case 2:
208                 {
209                         make_srv_share_info_2(&(ctr->share.info2), resume_hnd, total_entries);
210                         ctr->ptr_share_ctr = 2;
211                         break;
212                 }
213                 default:
214                 {
215                         DEBUG(5,("make_srv_share_info_ctr: unsupported switch value %d\n",
216                                   switch_value));
217                         (*resume_hnd = 0);
218                         (*total_entries) = 0;
219                         ctr->ptr_share_ctr = 0;
220                         status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
221                         break;
222                 }
223         }
224
225         return status;
226 }
227
228 /*******************************************************************
229  makes a SRV_R_NET_SHARE_ENUM structure.
230 ********************************************************************/
231 static void make_srv_r_net_share_enum(SRV_R_NET_SHARE_ENUM *r_n,
232                                 uint32 resume_hnd, int share_level, int switch_value)  
233 {
234         DEBUG(5,("make_srv_r_net_share_enum: %d\n", __LINE__));
235
236         r_n->share_level  = share_level;
237         if (share_level == 0)
238         {
239                 r_n->status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
240         }
241         else
242         {
243                 r_n->status = make_srv_share_info_ctr(r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
244         }
245         if (r_n->status != 0x0)
246         {
247                 resume_hnd = 0;
248         }
249         make_enum_hnd(&(r_n->enum_hnd), resume_hnd);
250 }
251
252 /*******************************************************************
253 net share enum
254 ********************************************************************/
255 static void srv_reply_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n,
256                                 prs_struct *rdata)
257 {
258         SRV_R_NET_SHARE_ENUM r_n;
259         SRV_SHARE_INFO_CTR ctr;
260
261         r_n.ctr = &ctr;
262
263         DEBUG(5,("srv_net_share_enum: %d\n", __LINE__));
264
265         /* set up the */
266         make_srv_r_net_share_enum(&r_n,
267                                 get_enum_hnd(&q_n->enum_hnd),
268                                 q_n->share_level,
269                                 q_n->ctr->switch_value);
270
271         /* store the response in the SMB stream */
272         srv_io_r_net_share_enum("", &r_n, rdata, 0);
273
274         DEBUG(5,("srv_net_share_enum: %d\n", __LINE__));
275 }
276
277 /*******************************************************************
278  fill in a sess info level 1 structure.
279
280  this function breaks the rule that i'd like to be in place, namely
281  it doesn't receive its data as arguments: it has to call lp_xxxx()
282  functions itself.  yuck.
283
284  ********************************************************************/
285 static void make_srv_sess_0_info(SESS_INFO_0    *se0, SESS_INFO_0_STR *str0,
286                                 char *name)
287 {
288         make_srv_sess_info0    (se0 , name);
289         make_srv_sess_info0_str(str0, name);
290 }
291
292 /*******************************************************************
293  fill in a sess info level 0 structure.
294
295  this function breaks the rule that i'd like to be in place, namely
296  it doesn't receive its data as arguments: it has to call lp_xxxx()
297  functions itself.  yuck.
298
299  ********************************************************************/
300 static void make_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
301 {
302         uint32 num_entries = 0;
303         (*stot) = 1;
304
305         if (ss0 == NULL)
306         {
307                 (*snum) = 0;
308                 return;
309         }
310
311         DEBUG(5,("make_srv_sess_0_ss0\n"));
312
313         if (snum)
314         {
315                 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++)
316                 {
317                         make_srv_sess_0_info(&(ss0->info_0    [num_entries]),
318                                                                  &(ss0->info_0_str[num_entries]), "MACHINE");
319
320                         /* move on to creating next session */
321                         /* move on to creating next sess */
322                         num_entries++;
323                 }
324
325                 ss0->num_entries_read  = num_entries;
326                 ss0->ptr_sess_info     = num_entries > 0 ? 1 : 0;
327                 ss0->num_entries_read2 = num_entries;
328                 
329                 if ((*snum) >= (*stot))
330                 {
331                         (*snum) = 0;
332                 }
333         }
334         else
335         {
336                 ss0->num_entries_read = 0;
337                 ss0->ptr_sess_info = 0;
338                 ss0->num_entries_read2 = 0;
339         }
340 }
341
342 /*******************************************************************
343  fill in a sess info level 1 structure.
344
345  this function breaks the rule that i'd like to be in place, namely
346  it doesn't receive its data as arguments: it has to call lp_xxxx()
347  functions itself.  yuck.
348
349  ********************************************************************/
350 static void make_srv_sess_1_info(SESS_INFO_1    *se1, SESS_INFO_1_STR *str1,
351                                 char *name, char *user,
352                                 uint32 num_opens,
353                                 uint32 open_time, uint32 idle_time,
354                                 uint32 usr_flgs)
355 {
356         make_srv_sess_info1    (se1 , name, user, num_opens, open_time, idle_time, usr_flgs);
357         make_srv_sess_info1_str(str1, name, user);
358 }
359
360 /*******************************************************************
361  fill in a sess info level 1 structure.
362
363  this function breaks the rule that i'd like to be in place, namely
364  it doesn't receive its data as arguments: it has to call lp_xxxx()
365  functions itself.  yuck.
366
367  ********************************************************************/
368 static void make_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
369 {
370         uint32 num_entries = 0;
371         (*stot) = 1;
372
373         if (ss1 == NULL)
374         {
375                 (*snum) = 0;
376                 return;
377         }
378
379         DEBUG(5,("make_srv_sess_1_ss1\n"));
380
381         if (snum)
382         {
383                 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++)
384                 {
385                         make_srv_sess_1_info(&(ss1->info_1    [num_entries]),
386                                                                  &(ss1->info_1_str[num_entries]),
387                                              "MACHINE", "dummy_user", 1, 10, 5, 0);
388
389                         /* move on to creating next session */
390                         /* move on to creating next sess */
391                         num_entries++;
392                 }
393
394                 ss1->num_entries_read  = num_entries;
395                 ss1->ptr_sess_info     = num_entries > 0 ? 1 : 0;
396                 ss1->num_entries_read2 = num_entries;
397                 
398                 if ((*snum) >= (*stot))
399                 {
400                         (*snum) = 0;
401                 }
402         }
403         else
404         {
405                 ss1->num_entries_read = 0;
406                 ss1->ptr_sess_info = 0;
407                 ss1->num_entries_read2 = 0;
408                 
409                 (*stot) = 0;
410         }
411 }
412
413 /*******************************************************************
414  makes a SRV_R_NET_SESS_ENUM structure.
415 ********************************************************************/
416 static uint32 make_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
417                                 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
418 {
419         uint32 status = 0x0;
420         DEBUG(5,("make_srv_sess_info_ctr: %d\n", __LINE__));
421
422         ctr->switch_value = switch_value;
423
424         switch (switch_value)
425         {
426                 case 0:
427                 {
428                         make_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
429                         ctr->ptr_sess_ctr = 1;
430                         break;
431                 }
432                 case 1:
433                 {
434                         make_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
435                         ctr->ptr_sess_ctr = 1;
436                         break;
437                 }
438                 default:
439                 {
440                         DEBUG(5,("make_srv_sess_info_ctr: unsupported switch value %d\n",
441                                   switch_value));
442                         (*resume_hnd) = 0;
443                         (*total_entries) = 0;
444                         ctr->ptr_sess_ctr = 0;
445                         status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
446                         break;
447                 }
448         }
449
450         return status;
451 }
452
453 /*******************************************************************
454  makes a SRV_R_NET_SESS_ENUM structure.
455 ********************************************************************/
456 static void make_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
457                                 uint32 resume_hnd, int sess_level, int switch_value)  
458 {
459         DEBUG(5,("make_srv_r_net_sess_enum: %d\n", __LINE__));
460
461         r_n->sess_level  = sess_level;
462         if (sess_level == -1)
463         {
464                 r_n->status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
465         }
466         else
467         {
468                 r_n->status = make_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
469         }
470         if (r_n->status != 0x0)
471         {
472                 resume_hnd = 0;
473         }
474         make_enum_hnd(&(r_n->enum_hnd), resume_hnd);
475 }
476
477 /*******************************************************************
478 net sess enum
479 ********************************************************************/
480 static void srv_reply_net_sess_enum(SRV_Q_NET_SESS_ENUM *q_n,
481                                 prs_struct *rdata)
482 {
483         SRV_R_NET_SESS_ENUM r_n;
484         SRV_SESS_INFO_CTR ctr;
485
486         r_n.ctr = &ctr;
487
488         DEBUG(5,("srv_net_sess_enum: %d\n", __LINE__));
489
490         /* set up the */
491         make_srv_r_net_sess_enum(&r_n,
492                                 get_enum_hnd(&q_n->enum_hnd),
493                                 q_n->sess_level,
494                                 q_n->ctr->switch_value);
495
496         /* store the response in the SMB stream */
497         srv_io_r_net_sess_enum("", &r_n, rdata, 0);
498
499         DEBUG(5,("srv_net_sess_enum: %d\n", __LINE__));
500 }
501
502 /*******************************************************************
503  fill in a conn info level 0 structure.
504
505  this function breaks the rule that i'd like to be in place, namely
506  it doesn't receive its data as arguments: it has to call lp_xxxx()
507  functions itself.  yuck.
508
509  ********************************************************************/
510 static void make_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
511 {
512         uint32 num_entries = 0;
513         (*stot) = 1;
514
515         if (ss0 == NULL)
516         {
517                 (*snum) = 0;
518                 return;
519         }
520
521         DEBUG(5,("make_srv_conn_0_ss0\n"));
522
523         if (snum)
524         {
525                 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++)
526                 {
527                         make_srv_conn_info0(&(ss0->info_0    [num_entries]), (*stot));
528
529                         /* move on to creating next connection */
530                         /* move on to creating next conn */
531                         num_entries++;
532                 }
533
534                 ss0->num_entries_read  = num_entries;
535                 ss0->ptr_conn_info     = num_entries > 0 ? 1 : 0;
536                 ss0->num_entries_read2 = num_entries;
537                 
538                 
539
540                 if ((*snum) >= (*stot))
541                 {
542                         (*snum) = 0;
543                 }
544         }
545         else
546         {
547                 ss0->num_entries_read = 0;
548                 ss0->ptr_conn_info = 0;
549                 ss0->num_entries_read2 = 0;
550
551                 (*stot) = 0;
552         }
553 }
554
555 /*******************************************************************
556  fill in a conn info level 1 structure.
557
558  this function breaks the rule that i'd like to be in place, namely
559  it doesn't receive its data as arguments: it has to call lp_xxxx()
560  functions itself.  yuck.
561
562  ********************************************************************/
563 static void make_srv_conn_1_info(CONN_INFO_1    *se1, CONN_INFO_1_STR *str1,
564                                 uint32 id, uint32 type,
565                                 uint32 num_opens, uint32 num_users, uint32 open_time,
566                                 char *usr_name, char *net_name)
567 {
568         make_srv_conn_info1    (se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
569         make_srv_conn_info1_str(str1, usr_name, net_name);
570 }
571
572 /*******************************************************************
573  fill in a conn info level 1 structure.
574
575  this function breaks the rule that i'd like to be in place, namely
576  it doesn't receive its data as arguments: it has to call lp_xxxx()
577  functions itself.  yuck.
578
579  ********************************************************************/
580 static void make_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
581 {
582         uint32 num_entries = 0;
583         (*stot) = 1;
584
585         if (ss1 == NULL)
586         {
587                 (*snum) = 0;
588                 return;
589         }
590
591         DEBUG(5,("make_srv_conn_1_ss1\n"));
592
593         if (snum)
594         {
595                 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++)
596                 {
597                         make_srv_conn_1_info(&(ss1->info_1    [num_entries]),
598                                                                  &(ss1->info_1_str[num_entries]),
599                                              (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
600
601                         /* move on to creating next connection */
602                         /* move on to creating next conn */
603                         num_entries++;
604                 }
605
606                 ss1->num_entries_read  = num_entries;
607                 ss1->ptr_conn_info     = num_entries > 0 ? 1 : 0;
608                 ss1->num_entries_read2 = num_entries;
609                 
610
611                 if ((*snum) >= (*stot))
612                 {
613                         (*snum) = 0;
614                 }
615         }
616         else
617         {
618                 ss1->num_entries_read = 0;
619                 ss1->ptr_conn_info = 0;
620                 ss1->num_entries_read2 = 0;
621                 
622                 (*stot) = 0;
623         }
624 }
625
626 /*******************************************************************
627  makes a SRV_R_NET_CONN_ENUM structure.
628 ********************************************************************/
629 static uint32 make_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
630                                 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
631 {
632         uint32 status = 0x0;
633         DEBUG(5,("make_srv_conn_info_ctr: %d\n", __LINE__));
634
635         ctr->switch_value = switch_value;
636
637         switch (switch_value)
638         {
639                 case 0:
640                 {
641                         make_srv_conn_info_0(&(ctr->conn.info0), resume_hnd, total_entries);
642                         ctr->ptr_conn_ctr = 1;
643                         break;
644                 }
645                 case 1:
646                 {
647                         make_srv_conn_info_1(&(ctr->conn.info1), resume_hnd, total_entries);
648                         ctr->ptr_conn_ctr = 1;
649                         break;
650                 }
651                 default:
652                 {
653                         DEBUG(5,("make_srv_conn_info_ctr: unsupported switch value %d\n",
654                                   switch_value));
655                         (*resume_hnd = 0);
656                         (*total_entries) = 0;
657                         ctr->ptr_conn_ctr = 0;
658                         status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
659                         break;
660                 }
661         }
662
663         return status;
664 }
665
666 /*******************************************************************
667  makes a SRV_R_NET_CONN_ENUM structure.
668 ********************************************************************/
669 static void make_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
670                                 uint32 resume_hnd, int conn_level, int switch_value)  
671 {
672         DEBUG(5,("make_srv_r_net_conn_enum: %d\n", __LINE__));
673
674         r_n->conn_level  = conn_level;
675         if (conn_level == -1)
676         {
677                 r_n->status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
678         }
679         else
680         {
681                 r_n->status = make_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
682         }
683         if (r_n->status != 0x0)
684         {
685                 resume_hnd = 0;
686         }
687         make_enum_hnd(&(r_n->enum_hnd), resume_hnd);
688 }
689
690 /*******************************************************************
691 net conn enum
692 ********************************************************************/
693 static void srv_reply_net_conn_enum(SRV_Q_NET_CONN_ENUM *q_n,
694                                 prs_struct *rdata)
695 {
696         SRV_R_NET_CONN_ENUM r_n;
697         SRV_CONN_INFO_CTR ctr;
698
699         r_n.ctr = &ctr;
700
701         DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
702
703         /* set up the */
704         make_srv_r_net_conn_enum(&r_n,
705                                 get_enum_hnd(&q_n->enum_hnd),
706                                 q_n->conn_level,
707                                 q_n->ctr->switch_value);
708
709         /* store the response in the SMB stream */
710         srv_io_r_net_conn_enum("", &r_n, rdata, 0);
711
712         DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
713 }
714
715 /*******************************************************************
716  fill in a file info level 3 structure.
717  ********************************************************************/
718 static void make_srv_file_3_info(FILE_INFO_3     *fl3, FILE_INFO_3_STR *str3,
719                                 uint32 fnum, uint32 perms, uint32 num_locks,
720                                 char *path_name, char *user_name)
721 {
722         make_srv_file_info3    (fl3 , fnum, perms, num_locks, path_name, user_name);
723         make_srv_file_info3_str(str3, path_name, user_name);
724 }
725
726 /*******************************************************************
727  fill in a file info level 3 structure.
728
729  this function breaks the rule that i'd like to be in place, namely
730  it doesn't receive its data as arguments: it has to call lp_xxxx()
731  functions itself.  yuck.
732
733  ********************************************************************/
734 static void make_srv_file_info_3(SRV_FILE_INFO_3 *fl3, uint32 *fnum, uint32 *ftot)
735 {
736         uint32 num_entries = 0;
737         (*ftot) = 1;
738
739         if (fl3 == NULL)
740         {
741                 (*fnum) = 0;
742                 return;
743         }
744
745         DEBUG(5,("make_srv_file_3_fl3\n"));
746
747         for (; (*fnum) < (*ftot) && num_entries < MAX_FILE_ENTRIES; (*fnum)++)
748         {
749                 make_srv_file_3_info(&(fl3->info_3    [num_entries]),
750                                          &(fl3->info_3_str[num_entries]),
751                                      (*fnum), 0x35, 0, "\\PIPE\\samr", "dummy user");
752
753                 /* move on to creating next file */
754                 num_entries++;
755         }
756
757         fl3->num_entries_read  = num_entries;
758         fl3->ptr_file_info     = num_entries > 0 ? 1 : 0;
759         fl3->num_entries_read2 = num_entries;
760         
761         if ((*fnum) >= (*ftot))
762         {
763                 (*fnum) = 0;
764         }
765 }
766
767 /*******************************************************************
768  makes a SRV_R_NET_FILE_ENUM structure.
769 ********************************************************************/
770 static uint32 make_srv_file_info_ctr(SRV_FILE_INFO_CTR *ctr,
771                                 int switch_value, uint32 *resume_hnd, uint32 *total_entries)  
772 {
773         uint32 status = 0x0;
774         DEBUG(5,("make_srv_file_info_ctr: %d\n", __LINE__));
775
776         ctr->switch_value = switch_value;
777
778         switch (switch_value)
779         {
780                 case 3:
781                 {
782                         make_srv_file_info_3(&(ctr->file.info3), resume_hnd, total_entries);
783                         ctr->ptr_file_ctr = 1;
784                         break;
785                 }
786                 default:
787                 {
788                         DEBUG(5,("make_srv_file_info_ctr: unsupported switch value %d\n",
789                                   switch_value));
790                         (*resume_hnd = 0);
791                         (*total_entries) = 0;
792                         ctr->ptr_file_ctr = 0;
793                         status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
794                         break;
795                 }
796         }
797
798         return status;
799 }
800
801 /*******************************************************************
802  makes a SRV_R_NET_FILE_ENUM structure.
803 ********************************************************************/
804 static void make_srv_r_net_file_enum(SRV_R_NET_FILE_ENUM *r_n,
805                                 uint32 resume_hnd, int file_level, int switch_value)  
806 {
807         DEBUG(5,("make_srv_r_net_file_enum: %d\n", __LINE__));
808
809         r_n->file_level  = file_level;
810         if (file_level == 0)
811         {
812                 r_n->status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
813         }
814         else
815         {
816                 r_n->status = make_srv_file_info_ctr(r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
817         }
818         if (r_n->status != 0x0)
819         {
820                 resume_hnd = 0;
821         }
822         make_enum_hnd(&(r_n->enum_hnd), resume_hnd);
823 }
824
825 /*******************************************************************
826 net file enum
827 ********************************************************************/
828 static void srv_reply_net_file_enum(SRV_Q_NET_FILE_ENUM *q_n,
829                                 prs_struct *rdata)
830 {
831         SRV_R_NET_FILE_ENUM r_n;
832         SRV_FILE_INFO_CTR ctr;
833
834         r_n.ctr = &ctr;
835
836         DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
837
838         /* set up the */
839         make_srv_r_net_file_enum(&r_n,
840                                 get_enum_hnd(&q_n->enum_hnd),
841                                 q_n->file_level,
842                                 q_n->ctr->switch_value);
843
844         /* store the response in the SMB stream */
845         srv_io_r_net_file_enum("", &r_n, rdata, 0);
846
847         DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
848 }
849
850 /*******************************************************************
851 net server get info
852 ********************************************************************/
853 static void srv_reply_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *q_n,
854                                 prs_struct *rdata)
855 {
856         SRV_R_NET_SRV_GET_INFO r_n;
857         uint32 status = 0x0;
858         SRV_INFO_CTR ctr;
859
860
861         DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
862
863         switch (q_n->switch_value)
864         {
865                 case 102:
866                 {
867                         make_srv_info_102(&ctr.srv.sv102,
868                                           500, global_myname, lp_serverstring(),
869                                           5, 4, /* major/minor version - NT 5.4 :-) */
870                                           0x4100b, /* browsing stuff SV_TYPE_XXXX */
871                                           0xffffffff, /* users */
872                                           0xf, /* disc */
873                                           0, /* hidden */
874                                           240, /* announce */
875                                           3000, /* announce delta */
876                                           100000, /* licenses */
877                                           "c:\\"); /* user path */
878                         break;
879                 }
880                 case 101:
881                 {
882                         make_srv_info_101(&ctr.srv.sv101,
883                                           500, global_myname,
884                                           5, 4, /* major/minor version - NT 5.4 :-) */
885                                           0x4100b, /* browsing stuff SV_TYPE_XXXX */
886                                           lp_serverstring());
887                         break;
888                 }
889                 default:
890                 {
891                         status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
892                         break;
893                 }
894         }
895
896         /* set up the net server get info structure */
897         make_srv_r_net_srv_get_info(&r_n, q_n->switch_value, &ctr, status);
898
899         /* store the response in the SMB stream */
900         srv_io_r_net_srv_get_info("", &r_n, rdata, 0);
901
902         DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
903 }
904
905 /*******************************************************************
906 ********************************************************************/
907 static void api_srv_net_srv_get_info( int uid, prs_struct *data,
908                                     prs_struct *rdata )
909 {
910         SRV_Q_NET_SRV_GET_INFO q_n;
911
912         /* grab the net server get info */
913         srv_io_q_net_srv_get_info("", &q_n, data, 0);
914
915         /* construct reply.  always indicate success */
916         srv_reply_net_srv_get_info(&q_n, rdata);
917 }
918
919
920 /*******************************************************************
921 ********************************************************************/
922 static void api_srv_net_file_enum( int uid, prs_struct *data,
923                                     prs_struct *rdata )
924 {
925         SRV_Q_NET_FILE_ENUM q_n;
926         SRV_FILE_INFO_CTR ctr;
927
928         q_n.ctr = &ctr;
929
930         /* grab the net file enum */
931         srv_io_q_net_file_enum("", &q_n, data, 0);
932
933         /* construct reply.  always indicate success */
934         srv_reply_net_file_enum(&q_n, rdata);
935 }
936
937
938 /*******************************************************************
939 ********************************************************************/
940 static void api_srv_net_conn_enum( int uid, prs_struct *data,
941                                     prs_struct *rdata )
942 {
943         SRV_Q_NET_CONN_ENUM q_n;
944         SRV_CONN_INFO_CTR ctr;
945
946         q_n.ctr = &ctr;
947
948         /* grab the net server get enum */
949         srv_io_q_net_conn_enum("", &q_n, data, 0);
950
951         /* construct reply.  always indicate success */
952         srv_reply_net_conn_enum(&q_n, rdata);
953 }
954
955
956 /*******************************************************************
957 ********************************************************************/
958 static void api_srv_net_sess_enum( int uid, prs_struct *data,
959                                     prs_struct *rdata )
960 {
961         SRV_Q_NET_SESS_ENUM q_n;
962         SRV_SESS_INFO_CTR ctr;
963
964         q_n.ctr = &ctr;
965
966         /* grab the net server get enum */
967         srv_io_q_net_sess_enum("", &q_n, data, 0);
968
969         /* construct reply.  always indicate success */
970         srv_reply_net_sess_enum(&q_n, rdata);
971 }
972
973
974 /*******************************************************************
975 ********************************************************************/
976 static void api_srv_net_share_enum( int uid, prs_struct *data,
977                                     prs_struct *rdata )
978 {
979         SRV_Q_NET_SHARE_ENUM q_n;
980         SRV_SHARE_INFO_CTR ctr;
981
982         q_n.ctr = &ctr;
983
984         /* grab the net server get enum */
985         srv_io_q_net_share_enum("", &q_n, data, 0);
986
987         /* construct reply.  always indicate success */
988         srv_reply_net_share_enum(&q_n, rdata);
989 }
990
991 /*******************************************************************
992 time of day
993 ********************************************************************/
994 static void srv_reply_net_remote_tod(SRV_Q_NET_REMOTE_TOD *q_n,
995                                 prs_struct *rdata)
996 {
997         SRV_R_NET_REMOTE_TOD r_n;
998         TIME_OF_DAY_INFO tod;
999         struct tm *t;
1000         time_t unixdate = time(NULL);
1001
1002         r_n.tod = &tod;
1003         r_n.ptr_srv_tod = 0x1;
1004         r_n.status = 0x0;
1005
1006         DEBUG(5,("srv_reply_net_remote_tod: %d\n", __LINE__));
1007
1008         t = gmtime(&unixdate);
1009
1010         /* set up the */
1011         make_time_of_day_info(&tod,
1012                               unixdate,
1013                               0,
1014                               t->tm_hour,
1015                               t->tm_min,
1016                               t->tm_sec,
1017                               0,
1018                               TimeDiff(unixdate)/60,
1019                               10000,
1020                               t->tm_mday,
1021                               t->tm_mon + 1,
1022                               1900+t->tm_year,
1023                               t->tm_wday);
1024         
1025         /* store the response in the SMB stream */
1026         srv_io_r_net_remote_tod("", &r_n, rdata, 0);
1027         
1028         DEBUG(5,("srv_reply_net_remote_tod: %d\n", __LINE__));
1029 }
1030 /*******************************************************************
1031 ********************************************************************/
1032 static void api_srv_net_remote_tod( int uid, prs_struct *data,
1033                                     prs_struct *rdata )
1034 {
1035         SRV_Q_NET_REMOTE_TOD q_n;
1036
1037         /* grab the net server get enum */
1038         srv_io_q_net_remote_tod("", &q_n, data, 0);
1039
1040         /* construct reply.  always indicate success */
1041         srv_reply_net_remote_tod(&q_n, rdata);
1042 }
1043
1044
1045 /*******************************************************************
1046 \PIPE\srvsvc commands
1047 ********************************************************************/
1048 struct api_struct api_srv_cmds[] =
1049 {
1050         { "SRV_NETCONNENUM"     , SRV_NETCONNENUM     , api_srv_net_conn_enum    },
1051         { "SRV_NETSESSENUM"     , SRV_NETSESSENUM     , api_srv_net_sess_enum    },
1052         { "SRV_NETSHAREENUM"    , SRV_NETSHAREENUM    , api_srv_net_share_enum   },
1053         { "SRV_NETFILEENUM"     , SRV_NETFILEENUM     , api_srv_net_file_enum    },
1054         { "SRV_NET_SRV_GET_INFO", SRV_NET_SRV_GET_INFO, api_srv_net_srv_get_info },
1055         { "SRV_NET_REMOTE_TOD"  , SRV_NET_REMOTE_TOD  , api_srv_net_remote_tod   },
1056         { NULL                  , 0                   , NULL                     }
1057 };
1058
1059 /*******************************************************************
1060 receives a srvsvc pipe and responds.
1061 ********************************************************************/
1062 BOOL api_srvsvc_rpc(pipes_struct *p, prs_struct *data)
1063 {
1064         return api_rpcTNP(p, "api_srvsvc_rpc", api_srv_cmds, data);
1065 }
1066