bb2083e28af3a58b3e81f8fa99b76dbbcb3ccfba
[kai/samba.git] / source / rpc_server / srv_srvsvc.c
1 /* 
2  *  Unix SMB/Netbios implementation.
3  *  Version 1.9.
4  *  RPC Pipe client / server routines
5  *  Copyright (C) Andrew Tridgell              1992-1997,
6  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
7  *  Copyright (C) Paul Ashton                       1997.
8  *  
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *  
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *  
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24 #include "includes.h"
25
26 extern int DEBUGLEVEL;
27 extern pstring global_myname;
28
29 /*******************************************************************
30  Fill in a share info level 1 structure.
31  ********************************************************************/
32
33 static void init_srv_share_info_1(SRV_SHARE_INFO_1 *sh1, int snum)
34 {
35         int len_net_name;
36         pstring net_name;
37         pstring remark;
38         uint32 type;
39
40         pstrcpy(net_name, lp_servicename(snum));
41         pstrcpy(remark, lp_comment(snum));
42         pstring_sub(remark,"%S",lp_servicename(snum));
43         len_net_name = strlen(net_name);
44
45         /* work out the share type */
46         type = STYPE_DISKTREE;
47                 
48         if (lp_print_ok(snum))
49                 type = STYPE_PRINTQ;
50         if (strequal("IPC$", net_name))
51                 type = STYPE_IPC;
52         if (net_name[len_net_name] == '$')
53                 type |= STYPE_HIDDEN;
54
55         init_srv_share_info1(&sh1->info_1, net_name, type, remark);
56         init_srv_share_info1_str(&sh1->info_1_str, net_name, remark);
57 }
58
59 /*******************************************************************
60  Fill in a share info level 2 structure.
61  ********************************************************************/
62
63 static void init_srv_share_info_2(SRV_SHARE_INFO_2 *sh2, int snum)
64 {
65         int len_net_name;
66         pstring net_name;
67         pstring remark;
68         pstring path;
69         pstring passwd;
70         uint32 type;
71
72         pstrcpy(net_name, lp_servicename(snum));
73         pstrcpy(remark, lp_comment(snum));
74         pstring_sub(remark,"%S",lp_servicename(snum));
75         pstrcpy(path, lp_pathname(snum));
76         pstrcpy(passwd, "");
77         len_net_name = strlen(net_name);
78
79         /* work out the share type */
80         type = STYPE_DISKTREE;
81                 
82         if (lp_print_ok(snum))
83                 type = STYPE_PRINTQ;
84         if (strequal("IPC$", net_name))
85                 type = STYPE_IPC;
86         if (net_name[len_net_name] == '$')
87                 type |= STYPE_HIDDEN;
88
89         init_srv_share_info2(&sh2->info_2, net_name, type, remark, 0, 0xffffffff, 1, path, passwd);
90         init_srv_share_info2_str(&sh2->info_2_str, net_name, remark, path, passwd);
91 }
92
93 /***************************************************************************
94  Fill in a share info level 1005 structure.
95  ***************************************************************************/
96 static void init_srv_share_info_1005(SRV_SHARE_INFO_1005* sh1005, int snum)
97 {
98         sh1005->dfs_root_flag = 0;
99
100 #ifdef MS_DFS
101         if(lp_host_msdfs() && *lp_dfsmap(snum) && lp_dfsmap_loaded(snum))
102                 sh1005->dfs_root_flag = 3;
103 #endif
104
105 }
106
107 /*******************************************************************
108  Fill in a share info structure.
109  ********************************************************************/
110
111 static BOOL init_srv_share_info_ctr(SRV_SHARE_INFO_CTR *ctr,
112                uint32 info_level, uint32 *resume_hnd, uint32 *total_entries)
113 {
114         int num_entries = 0;
115         int num_services = lp_numservices();
116         int snum;
117
118         DEBUG(5,("init_srv_share_info_ctr\n"));
119
120         ZERO_STRUCTPN(ctr);
121
122         ctr->info_level = ctr->switch_value = info_level;
123         *resume_hnd = 0;
124
125         /* Count the number of entries. */
126         for (snum = 0; snum < num_services; snum++) {
127                 if (lp_browseable(snum) && lp_snum_ok(snum))
128                         num_entries++;
129         }
130
131         *total_entries = num_entries;
132         ctr->num_entries2 = ctr->num_entries = num_entries;
133         ctr->ptr_share_info = ctr->ptr_entries = 1;
134
135         if (!num_entries)
136                 return True;
137
138         switch (info_level) {
139         case 1:
140         {
141                 SRV_SHARE_INFO_1 *info1;
142                 int i = 0;
143
144                 info1 = malloc(num_entries * sizeof(SRV_SHARE_INFO_1));
145
146                 for (snum = *resume_hnd; snum < num_services; snum++) {
147                         if (lp_browseable(snum) && lp_snum_ok(snum)) {
148                                 init_srv_share_info_1(&info1[i++], snum);
149                         }
150                 }
151
152                 ctr->share.info1 = info1;
153                 break;
154         }
155
156         case 2:
157         {
158                 SRV_SHARE_INFO_2 *info2;
159                 int i = 0;
160
161                 info2 = malloc(num_entries * sizeof(SRV_SHARE_INFO_2));
162
163                 for (snum = *resume_hnd; snum < num_services; snum++) {
164                         if (lp_browseable(snum) && lp_snum_ok(snum)) {
165                                 init_srv_share_info_2(&info2[i++], snum);
166                         }
167                 }
168
169                 ctr->share.info2 = info2;
170                 break;
171         }
172
173         default:
174                 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level));
175                 return False;
176         }
177
178         return True;
179 }
180
181 /*******************************************************************
182  Inits a SRV_R_NET_SHARE_ENUM structure.
183 ********************************************************************/
184
185 static void init_srv_r_net_share_enum(SRV_R_NET_SHARE_ENUM *r_n,
186                                       uint32 info_level, uint32 resume_hnd)  
187 {
188         DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
189
190         if (init_srv_share_info_ctr(&r_n->ctr, info_level,
191                                     &resume_hnd, &r_n->total_entries)) {
192                 r_n->status = 0x0;
193         } else {
194                 r_n->status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
195         }
196
197         init_enum_hnd(&r_n->enum_hnd, resume_hnd);
198 }
199
200 /*******************************************************************
201  Net share enum.
202 ********************************************************************/
203
204 static BOOL srv_reply_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n,
205                                 prs_struct *rdata)
206 {
207         SRV_R_NET_SHARE_ENUM r_n;
208         BOOL ret;
209
210         DEBUG(5,("srv_net_share_enum: %d\n", __LINE__));
211
212         /* Create the list of shares for the response. */
213         init_srv_r_net_share_enum(&r_n,
214                                 q_n->ctr.info_level,
215                                 get_enum_hnd(&q_n->enum_hnd));
216
217         /* store the response in the SMB stream */
218         ret = srv_io_r_net_share_enum("", &r_n, rdata, 0);
219
220         /* Free the memory used by the response. */
221         free_srv_r_net_share_enum(&r_n);
222
223         DEBUG(5,("srv_net_share_enum: %d\n", __LINE__));
224
225         return ret;
226 }
227
228 /*******************************************************************
229  Inits a SRV_R_NET_SHARE_GET_INFO structure.
230 ********************************************************************/
231
232 static void init_srv_r_net_share_get_info(SRV_R_NET_SHARE_GET_INFO *r_n,
233                                   char *share_name, uint32 info_level)
234 {
235         uint32 status = 0x0;
236         int snum;
237
238         DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
239
240         r_n->switch_value = info_level;
241
242         snum = find_service(share_name);
243
244         if (snum >= 0) {
245                 switch (info_level) {
246                 case 1:
247                         init_srv_share_info_1(&r_n->share.info1, snum);
248                         break;
249                 case 2:
250                         init_srv_share_info_2(&r_n->share.info2, snum);
251                         break;
252                 case 1005:
253                         init_srv_share_info_1005(&r_n->share.info1005, snum);
254                         break;
255                 default:
256                         DEBUG(5,("init_srv_net_share_get_info: unsupported switch value %d\n", info_level));
257                         status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
258                         break;
259                 }
260         } else {
261                 status = 0xC0000000 | NT_STATUS_BAD_NETWORK_NAME;
262         }
263
264         r_n->ptr_share_ctr = (status == 0x0) ? 1 : 0;
265         r_n->status = status;
266 }
267
268 /*******************************************************************
269  Net share get info.
270 ********************************************************************/
271
272 static BOOL srv_reply_net_share_get_info(SRV_Q_NET_SHARE_GET_INFO *q_n,
273                                          prs_struct *rdata)
274 {
275         SRV_R_NET_SHARE_GET_INFO r_n;
276         char *share_name;
277         BOOL ret;
278
279         DEBUG(5,("srv_net_share_get_info: %d\n", __LINE__));
280
281         /* Create the list of shares for the response. */
282         share_name = dos_unistr2_to_str(&q_n->uni_share_name);
283         init_srv_r_net_share_get_info(&r_n, share_name, q_n->info_level);
284
285         /* store the response in the SMB stream */
286         ret = srv_io_r_net_share_get_info("", &r_n, rdata, 0);
287
288         /* Free the memory used by the response. */
289         free_srv_r_net_share_get_info(&r_n);
290
291         DEBUG(5,("srv_net_share_get_info: %d\n", __LINE__));
292
293         return ret;
294 }
295
296 /*******************************************************************
297  fill in a sess info level 1 structure.
298
299  this function breaks the rule that i'd like to be in place, namely
300  it doesn't receive its data as arguments: it has to call lp_xxxx()
301  functions itself.  yuck.
302
303  ********************************************************************/
304 static void init_srv_sess_0_info(SESS_INFO_0    *se0, SESS_INFO_0_STR *str0,
305                                 char *name)
306 {
307         init_srv_sess_info0    (se0 , name);
308         init_srv_sess_info0_str(str0, name);
309 }
310
311 /*******************************************************************
312  fill in a sess info level 0 structure.
313
314  this function breaks the rule that i'd like to be in place, namely
315  it doesn't receive its data as arguments: it has to call lp_xxxx()
316  functions itself.  yuck.
317
318  ********************************************************************/
319 static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
320 {
321         uint32 num_entries = 0;
322         (*stot) = 1;
323
324         if (ss0 == NULL)
325         {
326                 (*snum) = 0;
327                 return;
328         }
329
330         DEBUG(5,("init_srv_sess_0_ss0\n"));
331
332         if (snum)
333         {
334                 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++)
335                 {
336                         init_srv_sess_0_info(&(ss0->info_0    [num_entries]),
337                                                                  &(ss0->info_0_str[num_entries]), "MACHINE");
338
339                         /* move on to creating next session */
340                         /* move on to creating next sess */
341                         num_entries++;
342                 }
343
344                 ss0->num_entries_read  = num_entries;
345                 ss0->ptr_sess_info     = num_entries > 0 ? 1 : 0;
346                 ss0->num_entries_read2 = num_entries;
347                 
348                 if ((*snum) >= (*stot))
349                 {
350                         (*snum) = 0;
351                 }
352         }
353         else
354         {
355                 ss0->num_entries_read = 0;
356                 ss0->ptr_sess_info = 0;
357                 ss0->num_entries_read2 = 0;
358         }
359 }
360
361 /*******************************************************************
362  fill in a sess info level 1 structure.
363
364  this function breaks the rule that i'd like to be in place, namely
365  it doesn't receive its data as arguments: it has to call lp_xxxx()
366  functions itself.  yuck.
367
368  ********************************************************************/
369 static void init_srv_sess_1_info(SESS_INFO_1    *se1, SESS_INFO_1_STR *str1,
370                                 char *name, char *user,
371                                 uint32 num_opens,
372                                 uint32 open_time, uint32 idle_time,
373                                 uint32 usr_flgs)
374 {
375         init_srv_sess_info1    (se1 , name, user, num_opens, open_time, idle_time, usr_flgs);
376         init_srv_sess_info1_str(str1, name, user);
377 }
378
379 /*******************************************************************
380  fill in a sess info level 1 structure.
381
382  this function breaks the rule that i'd like to be in place, namely
383  it doesn't receive its data as arguments: it has to call lp_xxxx()
384  functions itself.  yuck.
385
386  ********************************************************************/
387 static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
388 {
389         uint32 num_entries = 0;
390         (*stot) = 1;
391
392         if (ss1 == NULL)
393         {
394                 (*snum) = 0;
395                 return;
396         }
397
398         DEBUG(5,("init_srv_sess_1_ss1\n"));
399
400         if (snum)
401         {
402                 for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++)
403                 {
404                         init_srv_sess_1_info(&(ss1->info_1    [num_entries]),
405                                                                  &(ss1->info_1_str[num_entries]),
406                                              "MACHINE", "dummy_user", 1, 10, 5, 0);
407
408                         /* move on to creating next session */
409                         /* move on to creating next sess */
410                         num_entries++;
411                 }
412
413                 ss1->num_entries_read  = num_entries;
414                 ss1->ptr_sess_info     = num_entries > 0 ? 1 : 0;
415                 ss1->num_entries_read2 = num_entries;
416                 
417                 if ((*snum) >= (*stot))
418                 {
419                         (*snum) = 0;
420                 }
421         }
422         else
423         {
424                 ss1->num_entries_read = 0;
425                 ss1->ptr_sess_info = 0;
426                 ss1->num_entries_read2 = 0;
427                 
428                 (*stot) = 0;
429         }
430 }
431
432 /*******************************************************************
433  makes a SRV_R_NET_SESS_ENUM structure.
434 ********************************************************************/
435 static uint32 init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
436                                 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
437 {
438         uint32 status = 0x0;
439         DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
440
441         ctr->switch_value = switch_value;
442
443         switch (switch_value)
444         {
445                 case 0:
446                 {
447                         init_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
448                         ctr->ptr_sess_ctr = 1;
449                         break;
450                 }
451                 case 1:
452                 {
453                         init_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
454                         ctr->ptr_sess_ctr = 1;
455                         break;
456                 }
457                 default:
458                 {
459                         DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n",
460                                   switch_value));
461                         (*resume_hnd) = 0;
462                         (*total_entries) = 0;
463                         ctr->ptr_sess_ctr = 0;
464                         status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
465                         break;
466                 }
467         }
468
469         return status;
470 }
471
472 /*******************************************************************
473  makes a SRV_R_NET_SESS_ENUM structure.
474 ********************************************************************/
475 static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
476                                 uint32 resume_hnd, int sess_level, int switch_value)  
477 {
478         DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
479
480         r_n->sess_level  = sess_level;
481         if (sess_level == -1)
482         {
483                 r_n->status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
484         }
485         else
486         {
487                 r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
488         }
489         if (r_n->status != 0x0)
490         {
491                 resume_hnd = 0;
492         }
493         init_enum_hnd(&(r_n->enum_hnd), resume_hnd);
494 }
495
496 /*******************************************************************
497 net sess enum
498 ********************************************************************/
499 static void srv_reply_net_sess_enum(SRV_Q_NET_SESS_ENUM *q_n,
500                                 prs_struct *rdata)
501 {
502         SRV_R_NET_SESS_ENUM r_n;
503         SRV_SESS_INFO_CTR ctr;
504
505         r_n.ctr = &ctr;
506
507         DEBUG(5,("srv_net_sess_enum: %d\n", __LINE__));
508
509         /* set up the */
510         init_srv_r_net_sess_enum(&r_n,
511                                 get_enum_hnd(&q_n->enum_hnd),
512                                 q_n->sess_level,
513                                 q_n->ctr->switch_value);
514
515         /* store the response in the SMB stream */
516         srv_io_r_net_sess_enum("", &r_n, rdata, 0);
517
518         DEBUG(5,("srv_net_sess_enum: %d\n", __LINE__));
519 }
520
521 /*******************************************************************
522  fill in a conn info level 0 structure.
523
524  this function breaks the rule that i'd like to be in place, namely
525  it doesn't receive its data as arguments: it has to call lp_xxxx()
526  functions itself.  yuck.
527
528  ********************************************************************/
529 static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
530 {
531         uint32 num_entries = 0;
532         (*stot) = 1;
533
534         if (ss0 == NULL)
535         {
536                 (*snum) = 0;
537                 return;
538         }
539
540         DEBUG(5,("init_srv_conn_0_ss0\n"));
541
542         if (snum)
543         {
544                 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++)
545                 {
546                         init_srv_conn_info0(&(ss0->info_0    [num_entries]), (*stot));
547
548                         /* move on to creating next connection */
549                         /* move on to creating next conn */
550                         num_entries++;
551                 }
552
553                 ss0->num_entries_read  = num_entries;
554                 ss0->ptr_conn_info     = num_entries > 0 ? 1 : 0;
555                 ss0->num_entries_read2 = num_entries;
556                 
557                 
558
559                 if ((*snum) >= (*stot))
560                 {
561                         (*snum) = 0;
562                 }
563         }
564         else
565         {
566                 ss0->num_entries_read = 0;
567                 ss0->ptr_conn_info = 0;
568                 ss0->num_entries_read2 = 0;
569
570                 (*stot) = 0;
571         }
572 }
573
574 /*******************************************************************
575  fill in a conn info level 1 structure.
576
577  this function breaks the rule that i'd like to be in place, namely
578  it doesn't receive its data as arguments: it has to call lp_xxxx()
579  functions itself.  yuck.
580
581  ********************************************************************/
582 static void init_srv_conn_1_info(CONN_INFO_1    *se1, CONN_INFO_1_STR *str1,
583                                 uint32 id, uint32 type,
584                                 uint32 num_opens, uint32 num_users, uint32 open_time,
585                                 char *usr_name, char *net_name)
586 {
587         init_srv_conn_info1    (se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
588         init_srv_conn_info1_str(str1, usr_name, net_name);
589 }
590
591 /*******************************************************************
592  fill in a conn info level 1 structure.
593
594  this function breaks the rule that i'd like to be in place, namely
595  it doesn't receive its data as arguments: it has to call lp_xxxx()
596  functions itself.  yuck.
597
598  ********************************************************************/
599 static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
600 {
601         uint32 num_entries = 0;
602         (*stot) = 1;
603
604         if (ss1 == NULL)
605         {
606                 (*snum) = 0;
607                 return;
608         }
609
610         DEBUG(5,("init_srv_conn_1_ss1\n"));
611
612         if (snum)
613         {
614                 for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++)
615                 {
616                         init_srv_conn_1_info(&(ss1->info_1    [num_entries]),
617                                                                  &(ss1->info_1_str[num_entries]),
618                                              (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
619
620                         /* move on to creating next connection */
621                         /* move on to creating next conn */
622                         num_entries++;
623                 }
624
625                 ss1->num_entries_read  = num_entries;
626                 ss1->ptr_conn_info     = num_entries > 0 ? 1 : 0;
627                 ss1->num_entries_read2 = num_entries;
628                 
629
630                 if ((*snum) >= (*stot))
631                 {
632                         (*snum) = 0;
633                 }
634         }
635         else
636         {
637                 ss1->num_entries_read = 0;
638                 ss1->ptr_conn_info = 0;
639                 ss1->num_entries_read2 = 0;
640                 
641                 (*stot) = 0;
642         }
643 }
644
645 /*******************************************************************
646  makes a SRV_R_NET_CONN_ENUM structure.
647 ********************************************************************/
648 static uint32 init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
649                                 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
650 {
651         uint32 status = 0x0;
652         DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
653
654         ctr->switch_value = switch_value;
655
656         switch (switch_value)
657         {
658                 case 0:
659                 {
660                         init_srv_conn_info_0(&(ctr->conn.info0), resume_hnd, total_entries);
661                         ctr->ptr_conn_ctr = 1;
662                         break;
663                 }
664                 case 1:
665                 {
666                         init_srv_conn_info_1(&(ctr->conn.info1), resume_hnd, total_entries);
667                         ctr->ptr_conn_ctr = 1;
668                         break;
669                 }
670                 default:
671                 {
672                         DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n",
673                                   switch_value));
674                         (*resume_hnd = 0);
675                         (*total_entries) = 0;
676                         ctr->ptr_conn_ctr = 0;
677                         status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
678                         break;
679                 }
680         }
681
682         return status;
683 }
684
685 /*******************************************************************
686  makes a SRV_R_NET_CONN_ENUM structure.
687 ********************************************************************/
688 static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
689                                 uint32 resume_hnd, int conn_level, int switch_value)  
690 {
691         DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
692
693         r_n->conn_level  = conn_level;
694         if (conn_level == -1)
695         {
696                 r_n->status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
697         }
698         else
699         {
700                 r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
701         }
702         if (r_n->status != 0x0)
703         {
704                 resume_hnd = 0;
705         }
706         init_enum_hnd(&(r_n->enum_hnd), resume_hnd);
707 }
708
709 /*******************************************************************
710 net conn enum
711 ********************************************************************/
712 static void srv_reply_net_conn_enum(SRV_Q_NET_CONN_ENUM *q_n,
713                                 prs_struct *rdata)
714 {
715         SRV_R_NET_CONN_ENUM r_n;
716         SRV_CONN_INFO_CTR ctr;
717
718         r_n.ctr = &ctr;
719
720         DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
721
722         /* set up the */
723         init_srv_r_net_conn_enum(&r_n,
724                                 get_enum_hnd(&q_n->enum_hnd),
725                                 q_n->conn_level,
726                                 q_n->ctr->switch_value);
727
728         /* store the response in the SMB stream */
729         srv_io_r_net_conn_enum("", &r_n, rdata, 0);
730
731         DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
732 }
733
734 /*******************************************************************
735  fill in a file info level 3 structure.
736  ********************************************************************/
737 static void init_srv_file_3_info(FILE_INFO_3     *fl3, FILE_INFO_3_STR *str3,
738                                 uint32 fnum, uint32 perms, uint32 num_locks,
739                                 char *path_name, char *user_name)
740 {
741         init_srv_file_info3    (fl3 , fnum, perms, num_locks, path_name, user_name);
742         init_srv_file_info3_str(str3, path_name, user_name);
743 }
744
745 /*******************************************************************
746  fill in a file info level 3 structure.
747
748  this function breaks the rule that i'd like to be in place, namely
749  it doesn't receive its data as arguments: it has to call lp_xxxx()
750  functions itself.  yuck.
751
752  ********************************************************************/
753 static void init_srv_file_info_3(SRV_FILE_INFO_3 *fl3, uint32 *fnum, uint32 *ftot)
754 {
755         uint32 num_entries = 0;
756         (*ftot) = 1;
757
758         if (fl3 == NULL)
759         {
760                 (*fnum) = 0;
761                 return;
762         }
763
764         DEBUG(5,("init_srv_file_3_fl3\n"));
765
766         for (; (*fnum) < (*ftot) && num_entries < MAX_FILE_ENTRIES; (*fnum)++)
767         {
768                 init_srv_file_3_info(&(fl3->info_3    [num_entries]),
769                                          &(fl3->info_3_str[num_entries]),
770                                      (*fnum), 0x35, 0, "\\PIPE\\samr", "dummy user");
771
772                 /* move on to creating next file */
773                 num_entries++;
774         }
775
776         fl3->num_entries_read  = num_entries;
777         fl3->ptr_file_info     = num_entries > 0 ? 1 : 0;
778         fl3->num_entries_read2 = num_entries;
779         
780         if ((*fnum) >= (*ftot))
781         {
782                 (*fnum) = 0;
783         }
784 }
785
786 /*******************************************************************
787  makes a SRV_R_NET_FILE_ENUM structure.
788 ********************************************************************/
789 static uint32 init_srv_file_info_ctr(SRV_FILE_INFO_CTR *ctr,
790                                 int switch_value, uint32 *resume_hnd, uint32 *total_entries)  
791 {
792         uint32 status = 0x0;
793         DEBUG(5,("init_srv_file_info_ctr: %d\n", __LINE__));
794
795         ctr->switch_value = switch_value;
796
797         switch (switch_value)
798         {
799                 case 3:
800                 {
801                         init_srv_file_info_3(&(ctr->file.info3), resume_hnd, total_entries);
802                         ctr->ptr_file_ctr = 1;
803                         break;
804                 }
805                 default:
806                 {
807                         DEBUG(5,("init_srv_file_info_ctr: unsupported switch value %d\n",
808                                   switch_value));
809                         (*resume_hnd = 0);
810                         (*total_entries) = 0;
811                         ctr->ptr_file_ctr = 0;
812                         status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
813                         break;
814                 }
815         }
816
817         return status;
818 }
819
820 /*******************************************************************
821  makes a SRV_R_NET_FILE_ENUM structure.
822 ********************************************************************/
823 static void init_srv_r_net_file_enum(SRV_R_NET_FILE_ENUM *r_n,
824                                 uint32 resume_hnd, int file_level, int switch_value)  
825 {
826         DEBUG(5,("init_srv_r_net_file_enum: %d\n", __LINE__));
827
828         r_n->file_level  = file_level;
829         if (file_level == 0)
830         {
831                 r_n->status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
832         }
833         else
834         {
835                 r_n->status = init_srv_file_info_ctr(r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
836         }
837         if (r_n->status != 0x0)
838         {
839                 resume_hnd = 0;
840         }
841         init_enum_hnd(&(r_n->enum_hnd), resume_hnd);
842 }
843
844 /*******************************************************************
845 net file enum
846 ********************************************************************/
847 static void srv_reply_net_file_enum(SRV_Q_NET_FILE_ENUM *q_n,
848                                 prs_struct *rdata)
849 {
850         SRV_R_NET_FILE_ENUM r_n;
851         SRV_FILE_INFO_CTR ctr;
852
853         r_n.ctr = &ctr;
854
855         DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
856
857         /* set up the */
858         init_srv_r_net_file_enum(&r_n,
859                                 get_enum_hnd(&q_n->enum_hnd),
860                                 q_n->file_level,
861                                 q_n->ctr->switch_value);
862
863         /* store the response in the SMB stream */
864         srv_io_r_net_file_enum("", &r_n, rdata, 0);
865
866         DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
867 }
868
869 /*******************************************************************
870 net server get info
871 ********************************************************************/
872
873 static void srv_reply_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *q_n,
874                                 prs_struct *rdata)
875 {
876         SRV_R_NET_SRV_GET_INFO r_n;
877         uint32 status = 0x0;
878         SRV_INFO_CTR ctr;
879
880
881         DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
882
883         switch (q_n->switch_value)
884         {
885                 case 102:
886                 {
887                         init_srv_info_102(&ctr.srv.sv102,
888                                           500, global_myname, 
889                                           string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
890                                           lp_major_announce_version(), lp_minor_announce_version(),
891                                           lp_default_server_announce(),
892                                           0xffffffff, /* users */
893                                           0xf, /* disc */
894                                           0, /* hidden */
895                                           240, /* announce */
896                                           3000, /* announce delta */
897                                           100000, /* licenses */
898                                           "c:\\"); /* user path */
899                         break;
900                 }
901                 case 101:
902                 {
903                         init_srv_info_101(&ctr.srv.sv101,
904                                           500, global_myname,
905                                           lp_major_announce_version(), lp_minor_announce_version(),
906                                           lp_default_server_announce(),
907                                           string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
908                         break;
909                 }
910                 default:
911                 {
912                         status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
913                         break;
914                 }
915         }
916
917         /* set up the net server get info structure */
918         init_srv_r_net_srv_get_info(&r_n, q_n->switch_value, &ctr, status);
919
920         /* store the response in the SMB stream */
921         srv_io_r_net_srv_get_info("", &r_n, rdata, 0);
922
923         DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
924 }
925
926 /*******************************************************************
927 ********************************************************************/
928 static BOOL api_srv_net_srv_get_info(prs_struct *data,
929                                     prs_struct *rdata )
930 {
931         SRV_Q_NET_SRV_GET_INFO q_n;
932
933         /* grab the net server get info */
934         srv_io_q_net_srv_get_info("", &q_n, data, 0);
935
936         /* construct reply.  always indicate success */
937         srv_reply_net_srv_get_info(&q_n, rdata);
938
939         return True;
940 }
941
942
943 /*******************************************************************
944 ********************************************************************/
945 static BOOL api_srv_net_file_enum(prs_struct *data,
946                                     prs_struct *rdata )
947 {
948         SRV_Q_NET_FILE_ENUM q_n;
949         SRV_FILE_INFO_CTR ctr;
950
951         q_n.ctr = &ctr;
952
953         /* grab the net file enum */
954         srv_io_q_net_file_enum("", &q_n, data, 0);
955
956         /* construct reply.  always indicate success */
957         srv_reply_net_file_enum(&q_n, rdata);
958
959         return True;
960 }
961
962
963 /*******************************************************************
964 ********************************************************************/
965 static BOOL api_srv_net_conn_enum(prs_struct *data,
966                                     prs_struct *rdata )
967 {
968         SRV_Q_NET_CONN_ENUM q_n;
969         SRV_CONN_INFO_CTR ctr;
970
971         q_n.ctr = &ctr;
972
973         /* grab the net server get enum */
974         srv_io_q_net_conn_enum("", &q_n, data, 0);
975
976         /* construct reply.  always indicate success */
977         srv_reply_net_conn_enum(&q_n, rdata);
978
979         return True;
980 }
981
982
983 /*******************************************************************
984 ********************************************************************/
985 static BOOL api_srv_net_sess_enum(prs_struct *data,
986                                     prs_struct *rdata )
987 {
988         SRV_Q_NET_SESS_ENUM q_n;
989         SRV_SESS_INFO_CTR ctr;
990
991         q_n.ctr = &ctr;
992
993         /* grab the net server get enum */
994         srv_io_q_net_sess_enum("", &q_n, data, 0);
995
996         /* construct reply.  always indicate success */
997         srv_reply_net_sess_enum(&q_n, rdata);
998
999         return True;
1000 }
1001
1002
1003 /*******************************************************************
1004  RPC to enumerate shares.
1005 ********************************************************************/
1006
1007 static BOOL api_srv_net_share_enum(prs_struct *data,
1008                                     prs_struct *rdata )
1009 {
1010         SRV_Q_NET_SHARE_ENUM q_n;
1011         BOOL ret;
1012
1013         /* Unmarshall the net server get enum. */
1014         if(!srv_io_q_net_share_enum("", &q_n, data, 0)) {
1015                 DEBUG(0,("api_srv_net_share_enum: Failed to unmarshall SRV_Q_NET_SHARE_ENUM.\n"));
1016                 return False;
1017         }
1018
1019         ret = srv_reply_net_share_enum(&q_n, rdata);
1020
1021         /* Free any data allocated in the unmarshalling. */
1022         free_srv_q_net_share_enum(&q_n);
1023
1024         return ret;
1025 }
1026
1027 /*******************************************************************
1028  RPC to return share information.
1029 ********************************************************************/
1030
1031 static BOOL api_srv_net_share_get_info(prs_struct *data,
1032                                         prs_struct *rdata )
1033 {
1034         SRV_Q_NET_SHARE_GET_INFO q_n;
1035         BOOL ret;
1036
1037         /* Unmarshall the net server get info. */
1038         if(!srv_io_q_net_share_get_info("", &q_n, data, 0)) {
1039                 DEBUG(0,("api_srv_net_share_get_info: Failed to unmarshall SRV_Q_NET_SHARE_GET_INFO.\n"));
1040                 return False;
1041         }
1042
1043         ret = srv_reply_net_share_get_info(&q_n, rdata);
1044
1045         /* Free any data allocated in the unmarshalling. */
1046         free_srv_q_net_share_get_info(&q_n);
1047
1048         return ret;
1049 }
1050
1051 /*******************************************************************
1052 time of day
1053 ********************************************************************/
1054 static BOOL srv_reply_net_remote_tod(SRV_Q_NET_REMOTE_TOD *q_n,
1055                                 prs_struct *rdata)
1056 {
1057         SRV_R_NET_REMOTE_TOD r_n;
1058         TIME_OF_DAY_INFO tod;
1059         struct tm *t;
1060         time_t unixdate = time(NULL);
1061
1062         r_n.tod = &tod;
1063         r_n.ptr_srv_tod = 0x1;
1064         r_n.status = 0x0;
1065
1066         DEBUG(5,("srv_reply_net_remote_tod: %d\n", __LINE__));
1067
1068         t = gmtime(&unixdate);
1069
1070         /* set up the */
1071         init_time_of_day_info(&tod,
1072                               unixdate,
1073                               0,
1074                               t->tm_hour,
1075                               t->tm_min,
1076                               t->tm_sec,
1077                               0,
1078                               TimeDiff(unixdate)/60,
1079                               10000,
1080                               t->tm_mday,
1081                               t->tm_mon + 1,
1082                               1900+t->tm_year,
1083                               t->tm_wday);
1084         
1085         /* store the response in the SMB stream */
1086         srv_io_r_net_remote_tod("", &r_n, rdata, 0);
1087         
1088         DEBUG(5,("srv_reply_net_remote_tod: %d\n", __LINE__));
1089
1090         return True;
1091 }
1092 /*******************************************************************
1093 ********************************************************************/
1094 static BOOL api_srv_net_remote_tod(prs_struct *data,
1095                                     prs_struct *rdata )
1096 {
1097         SRV_Q_NET_REMOTE_TOD q_n;
1098
1099         /* grab the net server get enum */
1100         srv_io_q_net_remote_tod("", &q_n, data, 0);
1101
1102         /* construct reply.  always indicate success */
1103         srv_reply_net_remote_tod(&q_n, rdata);
1104
1105         return True;
1106 }
1107
1108
1109 /*******************************************************************
1110 \PIPE\srvsvc commands
1111 ********************************************************************/
1112 struct api_struct api_srv_cmds[] =
1113 {
1114         { "SRV_NETCONNENUM"       , SRV_NETCONNENUM       , api_srv_net_conn_enum    },
1115         { "SRV_NETSESSENUM"       , SRV_NETSESSENUM       , api_srv_net_sess_enum    },
1116         { "SRV_NETSHAREENUM"      , SRV_NETSHAREENUM      , api_srv_net_share_enum   },
1117         { "SRV_NET_SHARE_GET_INFO", SRV_NET_SHARE_GET_INFO, api_srv_net_share_get_info },
1118         { "SRV_NETFILEENUM"       , SRV_NETFILEENUM       , api_srv_net_file_enum    },
1119         { "SRV_NET_SRV_GET_INFO"  , SRV_NET_SRV_GET_INFO  , api_srv_net_srv_get_info },
1120         { "SRV_NET_REMOTE_TOD"    , SRV_NET_REMOTE_TOD    , api_srv_net_remote_tod   },
1121         { NULL                    , 0                     , NULL                     }
1122 };
1123
1124 /*******************************************************************
1125 receives a srvsvc pipe and responds.
1126 ********************************************************************/
1127 BOOL api_srvsvc_rpc(pipes_struct *p, prs_struct *data)
1128 {
1129         return api_rpcTNP(p, "api_srvsvc_rpc", api_srv_cmds, data);
1130 }