r18802: Use the pidl-generated code for the srvsvc interface, both client and server...
[samba.git] / source / rpc_server / srv_srvsvc_nt.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Jeremy Allison               2001.
6  *  Copyright (C) Nigel Williams               2001.
7  *  Copyright (C) Gerald (Jerry) Carter        2006.
8  *  Copyright (C) Jelmer Vernooij                          2006.
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 /* This is the implementation of the srvsvc pipe. */
26
27 #include "includes.h"
28
29 #define MAX_SERVER_DISK_ENTRIES 15
30
31 extern struct generic_mapping file_generic_mapping;
32 extern userdom_struct current_user_info;
33
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_RPC_SRV
36
37 /* Use for enumerating connections, pipes, & files */
38
39 struct file_enum_count {
40         TALLOC_CTX *ctx;
41         uint32 count;
42         struct srvsvc_NetFileInfo3 *info;
43 };
44
45 struct sess_file_count {
46         pid_t pid;
47         uid_t uid;
48         int count;
49 };
50
51 /****************************************************************************
52  Count the entries belonging to a service in the connection db.
53 ****************************************************************************/
54
55 static int pipe_enum_fn( TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *p)
56 {
57         struct pipe_open_rec prec;
58         struct file_enum_count *fenum = (struct file_enum_count *)p;
59  
60         if (dbuf.dsize != sizeof(struct pipe_open_rec))
61                 return 0;
62
63         memcpy(&prec, dbuf.dptr, sizeof(struct pipe_open_rec));
64  
65         if ( process_exists(prec.pid) ) {
66                 struct srvsvc_NetFileInfo3 *f;
67                 int i = fenum->count;
68                 pstring fullpath;
69                 
70                 snprintf( fullpath, sizeof(fullpath), "\\PIPE\\%s", prec.name );
71                 
72                 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, struct srvsvc_NetFileInfo3, i+1 );
73                 if ( !f ) {
74                         DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
75                         return 1;
76                 }
77
78                 fenum->info = f;
79                 
80                 fenum->info[i].fid = (uint32)((procid_to_pid(&prec.pid)<<16) & prec.pnum);
81                 fenum->info[i].permissions = (FILE_READ_DATA|FILE_WRITE_DATA);
82                 fenum->info[i].num_locks = 0;
83                 fenum->info[i].user = uidtoname( prec.uid );
84                 fenum->info[i].path = fullpath;
85                         
86                 fenum->count++;
87         }
88
89         return 0;
90 }
91
92 /*******************************************************************
93 ********************************************************************/
94
95 static WERROR net_enum_pipes( TALLOC_CTX *ctx, struct srvsvc_NetFileInfo3 **info, 
96                               uint32 *count, uint32 *resume )
97 {
98         struct file_enum_count fenum;
99         TDB_CONTEXT *conn_tdb = conn_tdb_ctx();
100
101         if ( !conn_tdb ) {
102                 DEBUG(0,("net_enum_pipes: Failed to retrieve the connections tdb handle!\n"));
103                 return WERR_ACCESS_DENIED;
104         }
105         
106         fenum.ctx = ctx;
107         fenum.info = *info;
108         fenum.count = *count;
109
110         if (tdb_traverse(conn_tdb, pipe_enum_fn, &fenum) == -1) {
111                 DEBUG(0,("net_enum_pipes: traverse of connections.tdb failed with error %s.\n",
112                         tdb_errorstr(conn_tdb) ));
113                 return WERR_NOMEM;
114         }
115         
116         *info  = fenum.info;
117         *count = fenum.count;
118         
119         return WERR_OK;}
120
121 /*******************************************************************
122 ********************************************************************/
123
124 /* global needed to make use of the share_mode_forall() callback */
125 static struct file_enum_count f_enum_cnt;
126
127 static void enum_file_fn( const struct share_mode_entry *e, 
128                           const char *sharepath, const char *fname,
129                           void *dummy )
130 {
131         struct file_enum_count *fenum = &f_enum_cnt;
132  
133         /* If the pid was not found delete the entry from connections.tdb */
134
135         if ( process_exists(e->pid) ) {
136                 struct srvsvc_NetFileInfo3 *f;
137                 int i = fenum->count;
138                 files_struct fsp;
139                 struct byte_range_lock *brl;
140                 int num_locks = 0;
141                 pstring fullpath;
142                 uint32 permissions;
143                 
144                 f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, struct srvsvc_NetFileInfo3, i+1 );                   
145                 if ( !f ) {
146                         DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1));
147                         return;
148                 }
149                 fenum->info = f;
150
151                 /* need to count the number of locks on a file */
152                 
153                 ZERO_STRUCT( fsp );             
154                 fsp.dev   = e->dev;
155                 fsp.inode = e->inode;
156                 
157                 if ( (brl = brl_get_locks_readonly(NULL,&fsp)) != NULL ) {
158                         num_locks = brl->num_locks;
159                         TALLOC_FREE( brl );
160                 }
161                 
162                 if ( strcmp( fname, "." ) == 0 ) {
163                         pstr_sprintf( fullpath, "C:%s", sharepath );
164                 } else {
165                         pstr_sprintf( fullpath, "C:%s/%s", sharepath, fname );
166                 }
167                 string_replace( fullpath, '/', '\\' );
168                 
169                 /* mask out create (what ever that is) */
170                 permissions = e->share_access & (FILE_READ_DATA|FILE_WRITE_DATA);
171
172                 fenum->info[i].fid = e->share_file_id;
173                 fenum->info[i].permissions = permissions;
174                 fenum->info[i].num_locks = num_locks;
175                 fenum->info[i].user = uidtoname(e->uid);
176                 fenum->info[i].path = fullpath;
177                         
178                 fenum->count++;
179         }
180
181         return;
182
183 }
184
185 /*******************************************************************
186 ********************************************************************/
187
188 static WERROR net_enum_files( TALLOC_CTX *ctx, struct srvsvc_NetFileInfo3 **info, 
189                               uint32 *count, uint32 *resume )
190 {
191         f_enum_cnt.ctx = ctx;
192         f_enum_cnt.count = *count;
193         f_enum_cnt.info = *info;
194         
195         share_mode_forall( enum_file_fn, NULL );
196         
197         *info  = f_enum_cnt.info;
198         *count = f_enum_cnt.count;
199         
200         return WERR_OK;
201 }
202
203 /*******************************************************************
204  Utility function to get the 'type' of a share from a share definition.
205  ********************************************************************/
206 static uint32 get_share_type(const struct share_params *params)
207 {
208         char *net_name = lp_servicename(params->service);
209         int len_net_name = strlen(net_name);
210         
211         /* work out the share type */
212         uint32 type = STYPE_DISKTREE;
213
214         if (lp_print_ok(params->service))
215                 type = STYPE_PRINTQ;
216         if (strequal(lp_fstype(params->service), "IPC"))
217                 type = STYPE_IPC;
218         if (net_name[len_net_name] == '$')
219                 type |= STYPE_HIDDEN;
220
221         return type;
222 }
223         
224 /*******************************************************************
225  Fill in a share info level 0 structure.
226  ********************************************************************/
227
228 static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *sh0,
229                                   const struct share_params *params)
230 {
231         sh0->name = lp_servicename(params->service);
232 }
233
234 /*******************************************************************
235  Fill in a share info level 1 structure.
236  ********************************************************************/
237
238 static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *sh1,
239                                   const struct share_params *params)
240 {
241         connection_struct *conn = p->conn;
242
243         sh1->comment = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
244                                      conn->user, conn->connectpath, conn->gid,
245                                      get_current_username(),
246                                      current_user_info.domain,
247                                      lp_comment(params->service));
248
249         sh1->name = lp_servicename(params->service);
250         sh1->type = get_share_type(params);
251 }
252
253 /*******************************************************************
254  Fill in a share info level 2 structure.
255  ********************************************************************/
256
257 static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *sh2,
258                                   const struct share_params *params)
259 {
260         connection_struct *conn = p->conn;
261         char *remark;
262         char *path;
263         int max_connections = lp_max_connections(params->service);
264         uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
265         int count = 0;
266         char *net_name = lp_servicename(params->service);
267         
268         remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
269                                      conn->user, conn->connectpath, conn->gid,
270                                      get_current_username(),
271                                      current_user_info.domain,
272                                      lp_comment(params->service));
273         path = talloc_asprintf(p->mem_ctx, "C:%s",
274                                lp_pathname(params->service));
275
276         /*
277          * Change / to \\ so that win2k will see it as a valid path.  This was
278          * added to enable use of browsing in win2k add share dialog.
279          */ 
280
281         string_replace(path, '/', '\\');
282
283         count = count_current_connections( net_name, False  );
284         sh2->name = net_name;
285         sh2->type = get_share_type(params);
286         sh2->comment = remark;
287         sh2->permissions = 0;
288         sh2->max_users = max_uses;
289         sh2->current_users = count;
290         sh2->path = path;
291         sh2->password = "";
292 }
293
294 /*******************************************************************
295  Map any generic bits to file specific bits.
296 ********************************************************************/
297
298 static void map_generic_share_sd_bits(SEC_DESC *psd)
299 {
300         int i;
301         SEC_ACL *ps_dacl = NULL;
302
303         if (!psd)
304                 return;
305
306         ps_dacl = psd->dacl;
307         if (!ps_dacl)
308                 return;
309
310         for (i = 0; i < ps_dacl->num_aces; i++) {
311                 SEC_ACE *psa = &ps_dacl->aces[i];
312                 uint32 orig_mask = psa->access_mask;
313
314                 se_map_generic(&psa->access_mask, &file_generic_mapping);
315                 psa->access_mask |= orig_mask;
316         }       
317 }
318
319 /*******************************************************************
320  Fill in a share info level 501 structure.
321 ********************************************************************/
322
323 static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *sh501,
324                                     const struct share_params *params)
325 {
326         connection_struct *conn = p->conn;
327         char *remark;
328         const char *net_name = lp_servicename(params->service);
329
330         remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
331                                      conn->user, conn->connectpath, conn->gid,
332                                      get_current_username(),
333                                      current_user_info.domain,
334                                      lp_comment(params->service));
335
336
337         sh501->name = net_name;
338         sh501->type = get_share_type(params);
339         sh501->comment = remark;
340         sh501->csc_policy = (lp_csc_policy(params->service) << 4);
341 }
342
343 /*******************************************************************
344  Fill in a share info level 502 structure.
345  ********************************************************************/
346
347 static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *sh502,
348                                     const struct share_params *params)
349 {
350         int max_connections = lp_max_connections(params->service);
351         uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff;
352         connection_struct *conn = p->conn;
353         int count; 
354         char *net_name;
355         char *remark;
356         char *path;
357         SEC_DESC *sd;
358         size_t sd_size;
359         TALLOC_CTX *ctx = p->mem_ctx;
360
361
362         ZERO_STRUCTP(sh502);
363
364         net_name = lp_servicename(params->service);
365         count = count_current_connections( net_name, False  );
366
367         remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
368                                      conn->user, conn->connectpath, conn->gid,
369                                      get_current_username(),
370                                      current_user_info.domain,
371                                      lp_comment(params->service));
372
373         path = talloc_asprintf(p->mem_ctx, "C:%s",
374                                lp_pathname(params->service));
375
376         /*
377          * Change / to \\ so that win2k will see it as a valid path.  This was
378          * added to enable use of browsing in win2k add share dialog.
379          */ 
380
381         string_replace(path, '/', '\\');
382
383         sd = get_share_security(ctx, lp_servicename(params->service),
384                                 &sd_size);
385
386         sh502->name = net_name;
387         sh502->type = get_share_type(params);
388         sh502->comment = remark;
389         sh502->path = path;
390         sh502->password = "";
391         sh502->sd = sd;
392         sh502->permissions = 0;
393         sh502->max_users = max_uses;
394         sh502->current_users = count;
395         sh502->unknown = 1;
396 }
397
398 /***************************************************************************
399  Fill in a share info level 1004 structure.
400  ***************************************************************************/
401
402 static void init_srv_share_info_1004(pipes_struct *p,
403                                      struct srvsvc_NetShareInfo1004* sh1004,
404                                      const struct share_params *params)
405 {
406         connection_struct *conn = p->conn;
407         char *remark;
408
409         remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)),
410                                      conn->user, conn->connectpath, conn->gid,
411                                      get_current_username(),
412                                      current_user_info.domain,
413                                      lp_comment(params->service));
414
415         ZERO_STRUCTP(sh1004);
416
417         sh1004->comment = remark;
418 }
419
420 /***************************************************************************
421  Fill in a share info level 1005 structure.
422  ***************************************************************************/
423
424 static void init_srv_share_info_1005(pipes_struct *p,
425                                      struct srvsvc_NetShareInfo1005* sh1005,
426                                      const struct share_params *params)
427 {
428         sh1005->dfs_flags = 0;
429
430         if(lp_host_msdfs() && lp_msdfs_root(params->service))
431                 sh1005->dfs_flags |= 
432                         SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
433         sh1005->dfs_flags |= 
434                 lp_csc_policy(params->service) << SHARE_1005_CSC_POLICY_SHIFT;
435 }
436 /***************************************************************************
437  Fill in a share info level 1006 structure.
438  ***************************************************************************/
439
440 static void init_srv_share_info_1006(pipes_struct *p,
441                                      struct srvsvc_NetShareInfo1006* sh1006,
442                                      const struct share_params *params)
443 {
444         sh1006->max_users = -1;
445 }
446
447 /***************************************************************************
448  Fill in a share info level 1007 structure.
449  ***************************************************************************/
450
451 static void init_srv_share_info_1007(pipes_struct *p,
452                                      struct srvsvc_NetShareInfo1007* sh1007,
453                                      const struct share_params *params)
454 {
455         uint32 flags = 0;
456
457         ZERO_STRUCTP(sh1007);
458   
459         sh1007->flags = flags;
460         sh1007->alternate_directory_name = "";
461 }
462
463 /*******************************************************************
464  Fill in a share info level 1501 structure.
465  ********************************************************************/
466
467 static void init_srv_share_info_1501(pipes_struct *p,
468                                      struct sec_desc_buf *sh1501,
469                                      const struct share_params *params)
470 {
471         SEC_DESC *sd;
472         size_t sd_size;
473         TALLOC_CTX *ctx = p->mem_ctx;
474
475         ZERO_STRUCTP(sh1501);
476
477         sd = get_share_security(ctx, lp_servicename(params->service),
478                                 &sd_size);
479
480         sh1501->sd = sd;
481 }
482
483 /*******************************************************************
484  True if it ends in '$'.
485  ********************************************************************/
486
487 static BOOL is_hidden_share(const struct share_params *params)
488 {
489         const char *net_name = lp_servicename(params->service);
490
491         return (net_name[strlen(net_name) - 1] == '$');
492 }
493
494 /*******************************************************************
495  Fill in a share info structure.
496  ********************************************************************/
497
498 static WERROR init_srv_share_info_ctr(pipes_struct *p,
499                                       union srvsvc_NetShareCtr *ctr,
500                                       uint32 info_level, uint32 *resume_hnd,
501                                       uint32 *total_entries, BOOL all_shares)
502 {
503         TALLOC_CTX *ctx = p->mem_ctx;
504         struct share_iterator *shares;
505         struct share_params *share;
506
507         DEBUG(5,("init_srv_share_info_ctr\n"));
508
509         ZERO_STRUCTP(ctr);
510
511         *resume_hnd = 0;
512
513         /* Ensure all the usershares are loaded. */
514         become_root();
515         load_usershare_shares();
516         unbecome_root();
517
518         *total_entries = 0;
519
520         if (!(shares = share_list_all(ctx))) {
521                 DEBUG(5, ("Could not list shares\n"));
522                 return WERR_ACCESS_DENIED;
523         }
524
525         switch (info_level) {
526         case 0:
527                 ctr->ctr0 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr0);
528                 break;
529         case 1:
530                 ctr->ctr1 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1);
531                 break;
532         case 2:
533                 ctr->ctr2 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr2);
534                 break;
535         case 501:
536                 ctr->ctr501 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr501);
537                 break;
538         case 502:
539                 ctr->ctr502 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr502);
540                 break;
541         case 1004:
542                 ctr->ctr1004 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1004);
543                 break;
544         case 1005:
545                 ctr->ctr1005 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1005);
546                 break;
547         case 1006:
548                 ctr->ctr1006 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1006);
549                 break;
550         case 1007:
551                 ctr->ctr1007 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1007);
552                 break;
553         case 1501:
554                 ctr->ctr1501 = talloc_zero(p->mem_ctx, struct srvsvc_NetShareCtr1501);
555                 break;
556         default:
557                         DEBUG(5,("init_srv_share_info_ctr: unsupported switch "
558                                  "value %d\n", info_level));
559                         return WERR_UNKNOWN_LEVEL;
560         }
561
562         while ((share = next_share(shares)) != NULL) {
563                 if (!lp_browseable(share->service)) {
564                         continue;
565                 }
566                 if (!all_shares && is_hidden_share(share)) {
567                         continue;
568                 }
569
570                 switch (info_level) {
571                 case 0:
572                 {
573                         struct srvsvc_NetShareInfo0 i;
574                         init_srv_share_info_0(p, &i, share);
575                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo0, i,
576                                      &ctr->ctr0->array, &ctr->ctr0->count);
577                         if (ctr->ctr0->array == NULL) {
578                                 return WERR_NOMEM;
579                         }
580                         *total_entries = ctr->ctr0->count;
581                         break;
582                 }
583
584                 case 1:
585                 {
586                         struct srvsvc_NetShareInfo1 i;
587                         init_srv_share_info_1(p, &i, share);
588                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1, i,
589                                      &ctr->ctr1->array, &ctr->ctr1->count);
590                         if (ctr->ctr1->array == NULL) {
591                                 return WERR_NOMEM;
592                         }
593                         *total_entries = ctr->ctr1->count;
594                         break;
595                 }
596
597                 case 2:
598                 {
599                         struct srvsvc_NetShareInfo2 i;
600                         init_srv_share_info_2(p, &i, share);
601                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo2, i,
602                                      &ctr->ctr2->array, &ctr->ctr2->count);
603                         if (ctr->ctr2->array == NULL) {
604                                 return WERR_NOMEM;
605                         }
606                         *total_entries = ctr->ctr2->count;
607                         break;
608                 }
609
610                 case 501:
611                 {
612                         struct srvsvc_NetShareInfo501 i;
613                         init_srv_share_info_501(p, &i, share);
614                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo501, i,
615                                      &ctr->ctr501->array, &ctr->ctr501->count);
616                         if (ctr->ctr501->array == NULL) {
617                                 return WERR_NOMEM;
618                         }
619                         *total_entries = ctr->ctr501->count;
620                         break;
621                 }
622
623                 case 502:
624                 {
625                         struct srvsvc_NetShareInfo502 i;
626                         init_srv_share_info_502(p, &i, share);
627                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo502, i,
628                                      &ctr->ctr502->array, &ctr->ctr502->count);
629                         if (ctr->ctr502->array == NULL) {
630                                 return WERR_NOMEM;
631                         }
632                         *total_entries = ctr->ctr502->count;
633                         break;
634                 }
635
636                 /* here for completeness but not currently used with enum
637                  * (1004 - 1501)*/
638         
639                 case 1004:
640                 {
641                         struct srvsvc_NetShareInfo1004 i;
642                         init_srv_share_info_1004(p, &i, share);
643                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, i,
644                                      &ctr->ctr1004->array, &ctr->ctr1004->count);
645                         if (ctr->ctr1004->array == NULL) {
646                                 return WERR_NOMEM;
647                         }
648                         *total_entries = ctr->ctr1004->count;
649                         break;
650                 }
651
652                 case 1005:
653                 {
654                         struct srvsvc_NetShareInfo1005 i;
655                         init_srv_share_info_1005(p, &i, share);
656                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, i,
657                                      &ctr->ctr1005->array, &ctr->ctr1005->count);
658                         if (ctr->ctr1005->array == NULL) {
659                                 return WERR_NOMEM;
660                         }
661                         *total_entries = ctr->ctr1005->count;
662                         break;
663                 }
664
665                 case 1006:
666                 {
667                         struct srvsvc_NetShareInfo1006 i;
668                         init_srv_share_info_1006(p, &i, share);
669                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, i,
670                                      &ctr->ctr1006->array, &ctr->ctr1006->count);
671                         if (ctr->ctr1006->array == NULL) {
672                                 return WERR_NOMEM;
673                         }
674                         *total_entries = ctr->ctr1006->count;
675                         break;
676                 }
677
678                 case 1007:
679                 {
680                         struct srvsvc_NetShareInfo1007 i;
681                         init_srv_share_info_1007(p, &i, share);
682                         ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, i,
683                                      &ctr->ctr1007->array, &ctr->ctr1007->count);
684                         if (ctr->ctr1007->array == NULL) {
685                                 return WERR_NOMEM;
686                         }
687                         *total_entries = ctr->ctr1007->count;
688                         break;
689                 }
690
691                 case 1501:
692                 {
693                         struct sec_desc_buf i;
694                         init_srv_share_info_1501(p, &i, share);
695                         ADD_TO_ARRAY(ctx, struct sec_desc_buf, i,
696                                      &ctr->ctr1501->array, &ctr->ctr1501->count);
697                         if (ctr->ctr1501->array == NULL) {
698                                 return WERR_NOMEM;
699                         }
700                         *total_entries = ctr->ctr1501->count;
701                         break;
702                 }
703                 }
704
705                 TALLOC_FREE(share);
706         }
707
708         return WERR_OK;
709 }
710
711 /*******************************************************************
712  fill in a sess info level 0 structure.
713  ********************************************************************/
714
715 static void init_srv_sess_info_0(pipes_struct *p, struct srvsvc_NetSessCtr0 *ss0, uint32 *snum, uint32 *stot)
716 {
717         struct sessionid *session_list;
718         uint32 num_entries = 0;
719         (*stot) = list_sessions(&session_list);
720
721         if (ss0 == NULL) {
722                 if (snum) {
723                         (*snum) = 0;
724                 }
725                 SAFE_FREE(session_list);
726                 return;
727         }
728
729         DEBUG(5,("init_srv_sess_0_ss0\n"));
730
731         ss0->array = talloc_array(p->mem_ctx, struct srvsvc_NetSessInfo0, *stot);
732
733         if (snum) {
734                 for (; (*snum) < (*stot); (*snum)++) {
735                         ss0->array[num_entries].client = session_list[(*snum)].remote_machine;
736                         num_entries++;
737                 }
738
739                 ss0->count = num_entries;
740                 
741                 if ((*snum) >= (*stot)) {
742                         (*snum) = 0;
743                 }
744
745         } else {
746                 ss0->array = NULL;
747                 ss0->count = 0;
748         }
749         SAFE_FREE(session_list);
750 }
751
752 /*******************************************************************
753 ********************************************************************/
754
755 static void sess_file_fn( const struct share_mode_entry *e, 
756                           const char *sharepath, const char *fname,
757                           void *private_data )
758 {
759         struct sess_file_count *sess = (struct sess_file_count *)private_data;
760  
761         if ( (procid_to_pid(&e->pid) == sess->pid) && (sess->uid == e->uid) ) {
762                 sess->count++;
763         }
764         
765         return;
766 }
767
768 /*******************************************************************
769 ********************************************************************/
770
771 static int net_count_files( uid_t uid, pid_t pid )
772 {
773         struct sess_file_count s_file_cnt;
774
775         s_file_cnt.count = 0;
776         s_file_cnt.uid = uid;
777         s_file_cnt.pid = pid;
778         
779         share_mode_forall( sess_file_fn, (void *)&s_file_cnt );
780         
781         return s_file_cnt.count;
782 }
783
784 /*******************************************************************
785  fill in a sess info level 1 structure.
786  ********************************************************************/
787
788 static void init_srv_sess_info_1(pipes_struct *p, struct srvsvc_NetSessCtr1 *ss1, uint32 *snum, uint32 *stot)
789 {
790         struct sessionid *session_list;
791         uint32 num_entries = 0;
792         time_t now = time(NULL);
793
794         if ( !snum ) {
795                 ss1->count = 0;
796                 ss1->array = NULL;
797                 
798                 (*stot) = 0;
799
800                 return;
801         }
802         
803         if (ss1 == NULL) {
804                 (*snum) = 0;
805                 return;
806         }
807
808         (*stot) = list_sessions(&session_list);
809
810         ss1->array = talloc_array(p->mem_ctx, struct srvsvc_NetSessInfo1, *stot);
811         
812         for (; (*snum) < (*stot); (*snum)++) {
813                 uint32 num_files;
814                 uint32 connect_time;
815                 struct passwd *pw = sys_getpwnam(session_list[*snum].username);
816                 BOOL guest;
817                         
818                 if ( !pw ) {
819                         DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n",
820                                 session_list[*snum].username));
821                         continue;
822                 }
823                                 
824                 connect_time = (uint32)(now - session_list[*snum].connect_start);
825                 num_files = net_count_files(pw->pw_uid, session_list[*snum].pid);
826                 guest = strequal( session_list[*snum].username, lp_guestaccount() );
827                                         
828                 ss1->array[num_entries].client = session_list[*snum].remote_machine;
829                 ss1->array[num_entries].user = session_list[*snum].username; 
830                 ss1->array[num_entries].num_open = num_files;
831                 ss1->array[num_entries].time = connect_time;
832                 ss1->array[num_entries].idle_time = 0;
833                 ss1->array[num_entries].user_flags = guest;
834
835                 num_entries++;
836         }
837
838         ss1->count = num_entries;
839         
840         if ((*snum) >= (*stot)) {
841                 (*snum) = 0;
842         }
843
844         SAFE_FREE(session_list);
845 }
846
847 /*******************************************************************
848  makes a SRV_R_NET_SESS_ENUM structure.
849 ********************************************************************/
850
851 static WERROR init_srv_sess_info_ctr(pipes_struct *p, union srvsvc_NetSessCtr *ctr,
852                                 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
853 {
854         WERROR status = WERR_OK;
855         DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
856
857         switch (switch_value) {
858         case 0:
859                 ctr->ctr0 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr0);
860                 init_srv_sess_info_0(p, ctr->ctr0, resume_hnd, total_entries);
861                 break;
862         case 1:
863                 ctr->ctr1 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr1);
864                 init_srv_sess_info_1(p, ctr->ctr1, resume_hnd, total_entries);
865                 break;
866         default:
867                 DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value));
868                 (*resume_hnd) = 0;
869                 (*total_entries) = 0;
870                 ctr->ctr0 = NULL;
871                 status = WERR_UNKNOWN_LEVEL;
872                 break;
873         }
874
875         return status;
876 }
877
878 /*******************************************************************
879  fill in a conn info level 0 structure.
880  ********************************************************************/
881
882 static void init_srv_conn_info_0(pipes_struct *p, struct srvsvc_NetConnCtr0 *ss0, uint32 *snum, uint32 *stot)
883 {
884         uint32 num_entries = 0;
885         (*stot) = 1;
886
887         if (ss0 == NULL) {
888                 (*snum) = 0;
889                 return;
890         }
891
892         DEBUG(5,("init_srv_conn_0_ss0\n"));
893
894         if (snum) {
895                 ss0->array = talloc_array(p->mem_ctx, struct srvsvc_NetConnInfo0, *stot);
896                 for (; (*snum) < (*stot); (*snum)++) {
897
898                         ss0->array[num_entries].conn_id = (*stot);
899
900                         /* move on to creating next connection */
901                         /* move on to creating next conn */
902                         num_entries++;
903                 }
904
905                 ss0->count = num_entries;
906                 
907                 if ((*snum) >= (*stot)) {
908                         (*snum) = 0;
909                 }
910
911         } else {
912                 ss0->array = NULL;
913                 ss0->count = 0;
914
915                 (*stot) = 0;
916         }
917 }
918
919 /*******************************************************************
920  fill in a conn info level 1 structure.
921  ********************************************************************/
922
923 static void init_srv_conn_info_1(pipes_struct *p, struct srvsvc_NetConnCtr1 *ss1, uint32 *snum, uint32 *stot)
924 {
925         uint32 num_entries = 0;
926         (*stot) = 1;
927
928         if (ss1 == NULL) {
929                 (*snum) = 0;
930                 return;
931         }
932
933         DEBUG(5,("init_srv_conn_1_ss1\n"));
934
935         if (snum) {
936                 ss1->array = talloc_array(p->mem_ctx, struct srvsvc_NetConnInfo1, *stot);
937                 for (; (*snum) < (*stot); (*snum)++) {
938                         ss1->array[num_entries].conn_id = (*stot);
939                         ss1->array[num_entries].conn_type = 0x3;
940                         ss1->array[num_entries].num_open = 1;
941                         ss1->array[num_entries].num_users = 1;
942                         ss1->array[num_entries].conn_time = 3;
943                         ss1->array[num_entries].user = "dummy_user";
944                         ss1->array[num_entries].share = "IPC$";
945
946                         /* move on to creating next connection */
947                         /* move on to creating next conn */
948                         num_entries++;
949                 }
950
951                 ss1->count = num_entries;
952
953                 if ((*snum) >= (*stot)) {
954                         (*snum) = 0;
955                 }
956
957         } else {
958                 ss1->count = 0;
959                 ss1->array = NULL;
960                 
961                 (*stot) = 0;
962         }
963 }
964
965 /*******************************************************************
966  makes a SRV_R_NET_CONN_ENUM structure.
967 ********************************************************************/
968
969 static WERROR init_srv_conn_info_ctr(pipes_struct *p, union srvsvc_NetConnCtr *ctr,
970                                 int switch_value, uint32 *resume_hnd, uint32 *total_entries)
971 {
972         WERROR status = WERR_OK;
973         DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
974
975         switch (switch_value) {
976         case 0:
977                 init_srv_conn_info_0(p, ctr->ctr0, resume_hnd, total_entries);
978                 break;
979         case 1:
980                 init_srv_conn_info_1(p, ctr->ctr1, resume_hnd, total_entries);
981                 break;
982         default:
983                 DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value));
984                 ctr->ctr0 = NULL;
985                 (*resume_hnd) = 0;
986                 (*total_entries) = 0;
987                 status = WERR_UNKNOWN_LEVEL;
988                 break;
989         }
990
991         return status;
992 }
993
994 /*******************************************************************
995  makes a SRV_R_NET_FILE_ENUM structure.
996 ********************************************************************/
997
998 static WERROR net_file_enum_3(pipes_struct *p, union srvsvc_NetFileCtr *ctr, uint32 *resume_hnd, uint32 *num_entries )
999 {
1000         TALLOC_CTX *ctx = get_talloc_ctx();
1001         WERROR status;
1002
1003         /* TODO -- Windows enumerates 
1004            (b) active pipes
1005            (c) open directories and files */
1006
1007         ctr->ctr3 = talloc_zero(p->mem_ctx, struct srvsvc_NetFileCtr3);
1008         
1009         status = net_enum_files( ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1010         if ( !W_ERROR_IS_OK(status))
1011                 return status;
1012                 
1013         status = net_enum_pipes( ctx, &ctr->ctr3->array, num_entries, resume_hnd );
1014         if ( !W_ERROR_IS_OK(status))
1015                 return status;
1016
1017         ctr->ctr3->count = *num_entries;
1018         
1019         return WERR_OK;
1020 }
1021
1022 /*******************************************************************
1023 *******************************************************************/
1024
1025 WERROR _srvsvc_NetFileEnum(pipes_struct *p, const char *server_unc, const char *path, const char *user, uint32_t *level, union srvsvc_NetFileCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
1026 {
1027         switch ( *level ) {
1028         case 3:
1029                 return net_file_enum_3(p, ctr, resume_handle, totalentries );   
1030         default:
1031                 return WERR_UNKNOWN_LEVEL;
1032         }
1033         
1034         return WERR_OK;
1035 }
1036
1037 /*******************************************************************
1038 net server get info
1039 ********************************************************************/
1040
1041 WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetSrvInfo *info)
1042 {
1043         WERROR status = WERR_OK;
1044
1045         ZERO_STRUCTP(info);
1046
1047         DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1048
1049         if (!pipe_access_check(p)) {
1050                 DEBUG(3, ("access denied to srv_net_srv_get_info\n"));
1051                 return WERR_ACCESS_DENIED;
1052         }
1053
1054         switch (level) {
1055
1056                 /* Technically level 102 should only be available to
1057                    Administrators but there isn't anything super-secret
1058                    here, as most of it is made up. */
1059
1060         case 102:
1061                 info->info102 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo102);
1062
1063                 info->info102->platform_id = 500;
1064                 info->info102->version_major = lp_major_announce_version();
1065                 info->info102->version_minor = lp_minor_announce_version();
1066                 info->info102->server_name = global_myname(); 
1067                 info->info102->server_type = lp_default_server_announce();
1068                 info->info102->userpath = "C:\\";
1069                 info->info102->licenses = 10000;
1070                 info->info102->anndelta = 3000;
1071                 info->info102->disc = 0xf;
1072                 info->info102->users = 0xffffffff;
1073                 info->info102->hidden = 0;
1074                 info->info102->announce = 240;
1075                 info->info102->comment = lp_serverstring();
1076                 break;
1077         case 101:
1078                 info->info101 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo101);
1079                         info->info101->platform_id = 500;
1080                         info->info101->server_name = global_myname();
1081                         info->info101->version_major = lp_major_announce_version();
1082                         info->info101->version_minor = lp_minor_announce_version();
1083                         info->info101->server_type = lp_default_server_announce();
1084                         info->info101->comment = lp_serverstring();
1085                 break;
1086         case 100:
1087                 info->info100 = talloc_zero(p->mem_ctx, struct srvsvc_NetSrvInfo100);
1088                 info->info100->platform_id = 500;
1089                 info->info100->server_name = global_myname();
1090                 break;
1091         default:
1092                 return WERR_UNKNOWN_LEVEL;
1093                 break;
1094         }
1095
1096         DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
1097
1098         return status;
1099 }
1100
1101 /*******************************************************************
1102 net server set info
1103 ********************************************************************/
1104
1105 WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetSrvInfo info, uint32_t *parm_error)
1106 {
1107         /* Set up the net server set info structure. */
1108         *parm_error = 0;
1109         return WERR_OK;
1110 }
1111
1112 /*******************************************************************
1113 net conn enum
1114 ********************************************************************/
1115
1116 WERROR _srvsvc_NetConnEnum(pipes_struct *p, const char *server_unc, const char *path, uint32_t *level, union srvsvc_NetConnCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
1117 {
1118         DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
1119
1120         ZERO_STRUCTP(ctr);
1121
1122         /* set up the */
1123         return init_srv_conn_info_ctr(p, ctr, *level, resume_handle, totalentries);
1124 }
1125
1126 /*******************************************************************
1127 net sess enum
1128 ********************************************************************/
1129
1130 WERROR _srvsvc_NetSessEnum(pipes_struct *p, const char *server_unc, const char *client, const char *user, uint32_t *level, union srvsvc_NetSessCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
1131 {
1132         DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
1133
1134         ZERO_STRUCTP(ctr);
1135
1136         /* set up the */
1137         return init_srv_sess_info_ctr(p, ctr,
1138                                 *level, 
1139                                 resume_handle,
1140                                 totalentries);
1141 }
1142
1143 /*******************************************************************
1144 net sess del
1145 ********************************************************************/
1146
1147 WERROR _srvsvc_NetSessDel(pipes_struct *p, const char *server_unc, const char *client, const char *user)
1148 {
1149         struct sessionid *session_list;
1150         int num_sessions, snum;
1151         WERROR status;
1152
1153         char *machine = talloc_strdup(p->mem_ctx, server_unc);
1154
1155         /* strip leading backslashes if any */
1156         while (machine[0] == '\\') {
1157                 memmove(machine, &machine[1], strlen(machine));
1158         }
1159
1160         num_sessions = list_sessions(&session_list);
1161
1162         DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1163
1164         status = WERR_ACCESS_DENIED;
1165
1166         /* fail out now if you are not root or not a domain admin */
1167
1168         if ((p->pipe_user.ut.uid != sec_initial_uid()) && 
1169                 ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) {
1170
1171                 goto done;
1172         }
1173
1174         for (snum = 0; snum < num_sessions; snum++) {
1175
1176                 if ((strequal(session_list[snum].username, user) || user[0] == '\0' ) &&
1177                     strequal(session_list[snum].remote_machine, machine)) {
1178                 
1179                         if (message_send_pid(pid_to_procid(session_list[snum].pid), MSG_SHUTDOWN, NULL, 0, False))
1180                                 status = WERR_OK;
1181                 }
1182         }
1183
1184         DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__));
1185
1186
1187 done:
1188         SAFE_FREE(session_list);
1189
1190         return status;
1191 }
1192
1193 /*******************************************************************
1194  Net share enum all.
1195 ********************************************************************/
1196
1197 WERROR _srvsvc_NetShareEnumAll(pipes_struct *p, const char *server_unc, uint32_t *level, union srvsvc_NetShareCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
1198 {
1199         DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1200
1201         if (!pipe_access_check(p)) {
1202                 DEBUG(3, ("access denied to srv_net_share_enum_all\n"));
1203                 return WERR_ACCESS_DENIED;
1204         }
1205
1206         /* Create the list of shares for the response. */
1207         return init_srv_share_info_ctr(p, ctr, *level,
1208                                               resume_handle, totalentries, True);
1209 }
1210
1211 /*******************************************************************
1212  Net share enum.
1213 ********************************************************************/
1214
1215 WERROR _srvsvc_NetShareEnum(pipes_struct *p, const char *server_unc, uint32_t *level, union srvsvc_NetShareCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
1216 {
1217         DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__));
1218
1219         if (!pipe_access_check(p)) {
1220                 DEBUG(3, ("access denied to srv_net_share_enum\n"));
1221                 return WERR_ACCESS_DENIED;
1222         }
1223
1224         /* Create the list of shares for the response. */
1225         return init_srv_share_info_ctr(p, ctr, *level,
1226                                               resume_handle, totalentries, False);
1227 }
1228
1229 /*******************************************************************
1230  Net share get info.
1231 ********************************************************************/
1232
1233 WERROR _srvsvc_NetShareGetInfo(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t level, union srvsvc_NetShareInfo *info)
1234 {
1235         const struct share_params *params;
1236
1237         params = get_share_params(p->mem_ctx, share_name);
1238
1239         if (params != NULL) {
1240                 switch (level) {
1241                 case 0:
1242                         info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
1243                         init_srv_share_info_0(p, info->info0,
1244                                               params);
1245                         break;
1246                 case 1:
1247                         info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
1248                         init_srv_share_info_1(p, info->info1,
1249                                               params);
1250                         break;
1251                 case 2:
1252                         info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
1253                         init_srv_share_info_2(p, info->info2,
1254                                               params);
1255                         break;
1256                 case 501:
1257                         info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
1258                         init_srv_share_info_501(p, info->info501,
1259                                                 params);
1260                         break;
1261                 case 502:
1262                         info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
1263                         init_srv_share_info_502(p, info->info502,
1264                                                 params);
1265                         break;
1266
1267                         /* here for completeness */
1268                 case 1004:
1269                         info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
1270                         init_srv_share_info_1004(p, info->info1004,
1271                                                  params);
1272                         break;
1273                 case 1005:
1274                         info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
1275                         init_srv_share_info_1005(p, info->info1005,
1276                                                  params);
1277                         break;
1278
1279                         /* here for completeness 1006 - 1501 */
1280                 case 1006:
1281                         info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
1282                         init_srv_share_info_1006(p, info->info1006,
1283                                                  params);
1284                         break;
1285                 case 1007:
1286                         info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
1287                         init_srv_share_info_1007(p, info->info1007,
1288                                                  params);
1289                         break;
1290                 case 1501:
1291                         info->info1501 = talloc(p->mem_ctx, struct sec_desc_buf);
1292                         init_srv_share_info_1501(p, info->info1501,
1293                                                  params);
1294                         break;
1295                 default:
1296                         DEBUG(5,("init_srv_net_share_get_info: unsupported "
1297                                  "switch value %d\n", level));
1298                         return WERR_UNKNOWN_LEVEL;
1299                         break;
1300                 }
1301         } else {
1302                 return WERR_INVALID_NAME;
1303         }
1304
1305         return WERR_OK;
1306 }
1307
1308 /*******************************************************************
1309  Check a given DOS pathname is valid for a share.
1310 ********************************************************************/
1311
1312 char *valid_share_pathname(char *dos_pathname)
1313 {
1314         char *ptr;
1315
1316         /* Convert any '\' paths to '/' */
1317         unix_format(dos_pathname);
1318         unix_clean_name(dos_pathname);
1319
1320         /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
1321         ptr = dos_pathname;
1322         if (strlen(dos_pathname) > 2 && ptr[1] == ':' && ptr[0] != '/')
1323                 ptr += 2;
1324
1325         /* Only absolute paths allowed. */
1326         if (*ptr != '/')
1327                 return NULL;
1328
1329         return ptr;
1330 }
1331
1332 /*******************************************************************
1333  Net share set info. Modify share details.
1334 ********************************************************************/
1335
1336 WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t level, union srvsvc_NetShareInfo info, uint32_t *parm_error)
1337 {
1338         pstring command;
1339         pstring comment;
1340         pstring pathname;
1341         int type;
1342         int snum;
1343         int ret;
1344         char *path;
1345         SEC_DESC *psd = NULL;
1346         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1347         BOOL is_disk_op = False;
1348         int max_connections = 0;
1349         fstring tmp_share_name;
1350
1351         DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1352
1353         *parm_error = 0;
1354
1355         if ( strequal(share_name,"IPC$") 
1356                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1357                 || strequal(share_name,"global") )
1358         {
1359                 return WERR_ACCESS_DENIED;
1360         }
1361
1362         fstrcpy(tmp_share_name, share_name);
1363         snum = find_service(tmp_share_name);
1364
1365         /* Does this share exist ? */
1366         if (snum < 0)
1367                 return WERR_NET_NAME_NOT_FOUND;
1368
1369         /* No change to printer shares. */
1370         if (lp_print_ok(snum))
1371                 return WERR_ACCESS_DENIED;
1372
1373         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1374         
1375         /* fail out now if you are not root and not a disk op */
1376         
1377         if ( p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op )
1378                 return WERR_ACCESS_DENIED;
1379
1380         switch (level) {
1381         case 1:
1382                 pstrcpy(pathname, lp_pathname(snum));
1383                 pstrcpy(comment, info.info1->comment);
1384                 type = info.info1->type;
1385                 psd = NULL;
1386                 break;
1387         case 2:
1388                 pstrcpy(comment, info.info2->comment);
1389                 pstrcpy(pathname, info.info2->path);
1390                 type = info.info2->type;
1391                 max_connections = (info.info2->max_users == 0xffffffff) ? 0 : info.info2->max_users;
1392                 psd = NULL;
1393                 break;
1394 #if 0
1395                 /* not supported on set but here for completeness */
1396         case 501:
1397                 unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment));
1398                 type = q_u->info.share.info501.info_501.type;
1399                 psd = NULL;
1400                 break;
1401 #endif
1402         case 502:
1403                 pstrcpy(comment, info.info502->comment);
1404                 pstrcpy(pathname, info.info502->path);
1405                 type = info.info502->type;
1406                 psd = info.info502->sd;
1407                 map_generic_share_sd_bits(psd);
1408                 break;
1409         case 1004:
1410                 pstrcpy(pathname, lp_pathname(snum));
1411                 pstrcpy(comment, info.info1004->comment);
1412                 type = STYPE_DISKTREE;
1413                 break;
1414         case 1005:
1415                 /* XP re-sets the csc policy even if it wasn't changed by the
1416                    user, so we must compare it to see if it's what is set in
1417                    smb.conf, so that we can contine other ops like setting
1418                    ACLs on a share */
1419                 if (((info.info1005->dfs_flags &
1420                       SHARE_1005_CSC_POLICY_MASK) >>
1421                      SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum))
1422                         return WERR_OK;
1423                 else {
1424                         DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n"));
1425                         return WERR_ACCESS_DENIED;
1426                 }
1427         case 1006:
1428         case 1007:
1429                 return WERR_ACCESS_DENIED;
1430         case 1501:
1431                 pstrcpy(pathname, lp_pathname(snum));
1432                 pstrcpy(comment, lp_comment(snum));
1433                 psd = info.info1501->sd;
1434                 map_generic_share_sd_bits(psd);
1435                 type = STYPE_DISKTREE;
1436                 break;
1437         default:
1438                 DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", level));
1439                 return WERR_UNKNOWN_LEVEL;
1440         }
1441
1442         /* We can only modify disk shares. */
1443         if (type != STYPE_DISKTREE)
1444                 return WERR_ACCESS_DENIED;
1445                 
1446         /* Check if the pathname is valid. */
1447         if (!(path = valid_share_pathname( pathname )))
1448                 return WERR_OBJECT_PATH_INVALID;
1449
1450         /* Ensure share name, pathname and comment don't contain '"' characters. */
1451         string_replace(tmp_share_name, '"', ' ');
1452         string_replace(path, '"', ' ');
1453         string_replace(comment, '"', ' ');
1454
1455         DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
1456                 lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
1457
1458         /* Only call modify function if something changed. */
1459         
1460         if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) 
1461                 || (lp_max_connections(snum) != max_connections) ) 
1462         {
1463                 if (!lp_change_share_cmd() || !*lp_change_share_cmd()) {
1464                         DEBUG(10,("_srv_net_share_set_info: No change share command\n"));
1465                         return WERR_ACCESS_DENIED;
1466                 }
1467
1468                 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1469                                 lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment, max_connections ); 
1470
1471                 DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
1472                                 
1473                 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1474         
1475                 if ( is_disk_op )
1476                         become_root();
1477                         
1478                 if ( (ret = smbrun(command, NULL)) == 0 ) {
1479                         /* Tell everyone we updated smb.conf. */
1480                         message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1481                 }
1482                 
1483                 if ( is_disk_op )
1484                         unbecome_root();
1485                         
1486                 /********* END SeDiskOperatorPrivilege BLOCK *********/
1487
1488                 DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));              
1489         
1490                 if ( ret != 0 )
1491                         return WERR_ACCESS_DENIED;
1492         } else {
1493                 DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
1494         }
1495
1496         /* Replace SD if changed. */
1497         if (psd) {
1498                 SEC_DESC *old_sd;
1499                 size_t sd_size;
1500
1501                 old_sd = get_share_security(p->mem_ctx, lp_servicename(snum),
1502                                             &sd_size);
1503
1504                 if (old_sd && !sec_desc_equal(old_sd, psd)) {
1505                         if (!set_share_security(p->mem_ctx, share_name, psd))
1506                                 DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n",
1507                                         share_name ));
1508                 }
1509         }
1510                         
1511         DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
1512
1513         return WERR_OK;
1514 }
1515
1516 /*******************************************************************
1517  Net share add. Call 'add_share_command "sharename" "pathname" 
1518  "comment" "max connections = "
1519 ********************************************************************/
1520
1521 WERROR _srvsvc_NetShareAdd(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetShareInfo info, uint32_t *parm_error)
1522 {
1523         pstring command;
1524         pstring share_name;
1525         pstring comment;
1526         pstring pathname;
1527         char *path;
1528         int type;
1529         int snum;
1530         int ret;
1531         SEC_DESC *psd = NULL;
1532         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1533         BOOL is_disk_op;
1534         int max_connections = 0;
1535
1536         DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1537
1538         *parm_error = 0;
1539
1540         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1541
1542         if (p->pipe_user.ut.uid != sec_initial_uid()  && !is_disk_op ) 
1543                 return WERR_ACCESS_DENIED;
1544
1545         if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
1546                 DEBUG(10,("_srv_net_share_add: No add share command\n"));
1547                 return WERR_ACCESS_DENIED;
1548         }
1549         
1550         switch (level) {
1551         case 0:
1552                 /* No path. Not enough info in a level 0 to do anything. */
1553                 return WERR_ACCESS_DENIED;
1554         case 1:
1555                 /* Not enough info in a level 1 to do anything. */
1556                 return WERR_ACCESS_DENIED;
1557         case 2:
1558                 pstrcpy(share_name, info.info2->name);
1559                 pstrcpy(comment, info.info2->comment);
1560                 pstrcpy(pathname, info.info2->path);
1561                 max_connections = (info.info2->max_users == 0xffffffff) ? 0 : info.info2->max_users;
1562                 type = info.info2->type;
1563                 break;
1564         case 501:
1565                 /* No path. Not enough info in a level 501 to do anything. */
1566                 return WERR_ACCESS_DENIED;
1567         case 502:
1568                 pstrcpy(share_name, info.info502->name);
1569                 pstrcpy(comment, info.info502->comment);
1570                 pstrcpy(pathname, info.info502->path);
1571                 type = info.info502->type;
1572                 psd = info.info502->sd;
1573                 map_generic_share_sd_bits(psd);
1574                 break;
1575
1576                 /* none of the following contain share names.  NetShareAdd does not have a separate parameter for the share name */ 
1577
1578         case 1004:
1579         case 1005:
1580         case 1006:
1581         case 1007:
1582                 return WERR_ACCESS_DENIED;
1583         case 1501:
1584                 /* DFS only level. */
1585                 return WERR_ACCESS_DENIED;
1586         default:
1587                 DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", level));
1588                 return WERR_UNKNOWN_LEVEL;
1589         }
1590
1591         /* check for invalid share names */
1592
1593         if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS, sizeof(share_name) ) ) {
1594                 DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", share_name));
1595                 return WERR_INVALID_NAME;
1596         }
1597
1598         if ( strequal(share_name,"IPC$") || strequal(share_name,"global")
1599                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) )
1600         {
1601                 return WERR_ACCESS_DENIED;
1602         }
1603
1604         snum = find_service(share_name);
1605
1606         /* Share already exists. */
1607         if (snum >= 0)
1608                 return WERR_ALREADY_EXISTS;
1609
1610         /* We can only add disk shares. */
1611         if (type != STYPE_DISKTREE)
1612                 return WERR_ACCESS_DENIED;
1613                 
1614         /* Check if the pathname is valid. */
1615         if (!(path = valid_share_pathname( pathname )))
1616                 return WERR_OBJECT_PATH_INVALID;
1617
1618         /* Ensure share name, pathname and comment don't contain '"' characters. */
1619         string_replace(share_name, '"', ' ');
1620         string_replace(path, '"', ' ');
1621         string_replace(comment, '"', ' ');
1622
1623         slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
1624                         lp_add_share_cmd(), 
1625                         dyn_CONFIGFILE, 
1626                         share_name, 
1627                         path, 
1628                         comment, 
1629                         max_connections);
1630                         
1631         DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
1632         
1633         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1634         
1635         if ( is_disk_op )
1636                 become_root();
1637
1638         if ( (ret = smbrun(command, NULL)) == 0 ) {
1639                 /* Tell everyone we updated smb.conf. */
1640                 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1641         }
1642
1643         if ( is_disk_op )
1644                 unbecome_root();
1645                 
1646         /********* END SeDiskOperatorPrivilege BLOCK *********/
1647
1648         DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
1649
1650         if ( ret != 0 )
1651                 return WERR_ACCESS_DENIED;
1652
1653         if (psd) {
1654                 if (!set_share_security(p->mem_ctx, share_name, psd)) {
1655                         DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
1656                 }
1657         }
1658
1659         /*
1660          * We don't call reload_services() here, the message will
1661          * cause this to be done before the next packet is read
1662          * from the client. JRA.
1663          */
1664
1665         DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
1666
1667         return WERR_OK;
1668 }
1669
1670 /*******************************************************************
1671  Net share delete. Call "delete share command" with the share name as
1672  a parameter.
1673 ********************************************************************/
1674
1675 WERROR _srvsvc_NetShareDel(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t reserved)
1676 {
1677         pstring command;
1678         int ret;
1679         int snum;
1680         SE_PRIV se_diskop = SE_DISK_OPERATOR;
1681         BOOL is_disk_op;
1682         fstring tmp_share_name;
1683
1684         DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
1685
1686         if ( strequal(share_name,"IPC$") 
1687                 || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") )
1688                 || strequal(share_name,"global") )
1689         {
1690                 return WERR_ACCESS_DENIED;
1691         }
1692
1693         fstrcpy(tmp_share_name, share_name);
1694         snum = find_service(tmp_share_name);
1695
1696         if (snum < 0)
1697                 return WERR_NO_SUCH_SHARE;
1698
1699         /* No change to printer shares. */
1700         if (lp_print_ok(snum))
1701                 return WERR_ACCESS_DENIED;
1702
1703         is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
1704
1705         if (p->pipe_user.ut.uid != sec_initial_uid()  && !is_disk_op ) 
1706                 return WERR_ACCESS_DENIED;
1707
1708         if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) {
1709                 DEBUG(10,("_srv_net_share_del: No delete share command\n"));
1710                 return WERR_ACCESS_DENIED;
1711         }
1712                 
1713         slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
1714                         lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
1715
1716         DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
1717
1718         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
1719         
1720         if ( is_disk_op )
1721                 become_root();
1722
1723         if ( (ret = smbrun(command, NULL)) == 0 ) {
1724                 /* Tell everyone we updated smb.conf. */
1725                 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
1726         }
1727
1728         if ( is_disk_op )
1729                 unbecome_root();
1730                 
1731         /********* END SeDiskOperatorPrivilege BLOCK *********/
1732
1733         DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
1734
1735         if ( ret != 0 )
1736                 return WERR_ACCESS_DENIED;
1737
1738         /* Delete the SD in the database. */
1739         delete_share_security(snum);
1740
1741         lp_killservice(snum);
1742
1743         return WERR_OK;
1744 }
1745
1746 WERROR _srvsvc_NetShareDelSticky(pipes_struct *p, const char *server_unc, const char *share_name, uint32_t reserved)
1747 {
1748         DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__));
1749
1750         return _srvsvc_NetShareDel(p, server_unc, share_name, reserved);
1751 }
1752
1753 /*******************************************************************
1754 time of day
1755 ********************************************************************/
1756
1757 WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, const char *server_unc, struct srvsvc_NetRemoteTODInfo *tod)
1758 {
1759         struct tm *t;
1760         time_t unixdate = time(NULL);
1761         WERROR status = WERR_OK;
1762
1763         /* We do this call first as if we do it *after* the gmtime call
1764            it overwrites the pointed-to values. JRA */
1765
1766         uint32 zone = get_time_zone(unixdate)/60;
1767
1768         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1769
1770         t = gmtime(&unixdate);
1771
1772         /* set up the */
1773         tod->elapsed = unixdate;
1774         tod->msecs = 0;
1775         tod->hours = t->tm_hour;
1776         tod->mins = t->tm_min;
1777         tod->secs = t->tm_sec;
1778         tod->hunds = 0;
1779         tod->timezone = zone;
1780         tod->tinterval = 10000;
1781         tod->day = t->tm_mday;
1782         tod->month = t->tm_mon + 1;
1783         tod->year = 1900+t->tm_year;
1784         tod->weekday = t->tm_wday;
1785         
1786         DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__));
1787
1788         return status;
1789 }
1790
1791 /***********************************************************************************
1792  Win9x NT tools get security descriptor.
1793 ***********************************************************************************/
1794
1795 WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, const char *server_unc, const char *share, const char *file, uint32_t securityinformation, struct sec_desc_buf *sd_buf)
1796 {
1797         SEC_DESC *psd = NULL;
1798         size_t sd_size;
1799         DATA_BLOB null_pw;
1800         files_struct *fsp = NULL;
1801         SMB_STRUCT_STAT st;
1802         BOOL bad_path;
1803         NTSTATUS nt_status;
1804         connection_struct *conn = NULL;
1805         BOOL became_user = False; 
1806         WERROR status = WERR_OK;
1807         pstring tmp_file;
1808
1809         ZERO_STRUCT(st);
1810
1811
1812         /* Null password is ok - we are already an authenticated user... */
1813         null_pw = data_blob(NULL, 0);
1814
1815         become_root();
1816         conn = make_connection(share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
1817         unbecome_root();
1818
1819         if (conn == NULL) {
1820                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", share));
1821                 status = ntstatus_to_werror(nt_status);
1822                 goto error_exit;
1823         }
1824
1825         if (!become_user(conn, conn->vuid)) {
1826                 DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n"));
1827                 status = WERR_ACCESS_DENIED;
1828                 goto error_exit;
1829         }
1830         became_user = True;
1831
1832         pstrcpy(tmp_file, file);
1833         unix_convert(tmp_file, conn, NULL, &bad_path, &st);
1834         if (bad_path) {
1835                 DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", file));
1836                 status = WERR_ACCESS_DENIED;
1837                 goto error_exit;
1838         }
1839
1840         if (!check_name(file,conn)) {
1841                 DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", file));
1842                 status = WERR_ACCESS_DENIED;
1843                 goto error_exit;
1844         }
1845
1846         nt_status = open_file_stat(conn, file, &st, &fsp);
1847         if (!NT_STATUS_IS_OK(nt_status)) {
1848                 /* Perhaps it is a directory */
1849                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
1850                         nt_status = open_directory(conn, file, &st,
1851                                         READ_CONTROL_ACCESS,
1852                                         FILE_SHARE_READ|FILE_SHARE_WRITE,
1853                                         FILE_OPEN,
1854                                         0,
1855                                         NULL, &fsp);
1856
1857                 if (!NT_STATUS_IS_OK(nt_status)) {
1858                         DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", file));
1859                         status = WERR_ACCESS_DENIED;
1860                         goto error_exit;
1861                 }
1862         }
1863
1864         sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
1865
1866         if (sd_size == 0) {
1867                 DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", file));
1868                 status = WERR_ACCESS_DENIED;
1869                 goto error_exit;
1870         }
1871
1872         sd_buf->sd_size= sd_size;
1873         sd_buf->sd = psd;
1874
1875         psd->dacl->revision = (uint16) NT4_ACL_REVISION;
1876
1877         close_file(fsp, NORMAL_CLOSE);
1878         unbecome_user();
1879         close_cnum(conn, p->pipe_user.vuid);
1880         return status;
1881
1882 error_exit:
1883
1884         if(fsp) {
1885                 close_file(fsp, NORMAL_CLOSE);
1886         }
1887
1888         if (became_user)
1889                 unbecome_user();
1890
1891         if (conn) 
1892                 close_cnum(conn, p->pipe_user.vuid);
1893
1894         return status;
1895 }
1896
1897 /***********************************************************************************
1898  Win9x NT tools set security descriptor.
1899 ***********************************************************************************/
1900
1901 WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, const char *server_unc, const char *share, const char *file, uint32_t securityinformation, struct sec_desc_buf sd_buf)
1902 {
1903         BOOL ret;
1904         DATA_BLOB null_pw;
1905         files_struct *fsp = NULL;
1906         SMB_STRUCT_STAT st;
1907         BOOL bad_path;
1908         NTSTATUS nt_status;
1909         connection_struct *conn = NULL;
1910         BOOL became_user = False;
1911         WERROR status = WERR_OK;
1912         pstring tmp_file;
1913
1914         ZERO_STRUCT(st);
1915
1916         /* Null password is ok - we are already an authenticated user... */
1917         null_pw = data_blob(NULL, 0);
1918
1919         become_root();
1920         conn = make_connection(share, null_pw, "A:", p->pipe_user.vuid, &nt_status);
1921         unbecome_root();
1922
1923         if (conn == NULL) {
1924                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", share));
1925                 status = ntstatus_to_werror(nt_status);
1926                 goto error_exit;
1927         }
1928
1929         if (!become_user(conn, conn->vuid)) {
1930                 DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n"));
1931                 status = WERR_ACCESS_DENIED;
1932                 goto error_exit;
1933         }
1934         became_user = True;
1935
1936         pstrcpy(tmp_file, file);
1937         unix_convert(tmp_file, conn, NULL, &bad_path, &st);
1938         if (bad_path) {
1939                 DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", file));
1940                 status = WERR_ACCESS_DENIED;
1941                 goto error_exit;
1942         }
1943
1944         if (!check_name(file,conn)) {
1945                 DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", file));
1946                 status = WERR_ACCESS_DENIED;
1947                 goto error_exit;
1948         }
1949
1950
1951         nt_status = open_file_stat(conn, file, &st, &fsp);
1952
1953         if (!NT_STATUS_IS_OK(nt_status)) {
1954                 /* Perhaps it is a directory */
1955                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY))
1956                         nt_status = open_directory(conn, file, &st,
1957                                                 FILE_READ_ATTRIBUTES,
1958                                                 FILE_SHARE_READ|FILE_SHARE_WRITE,
1959                                                 FILE_OPEN,
1960                                                 0,
1961                                                 NULL, &fsp);
1962
1963                 if (!NT_STATUS_IS_OK(nt_status)) {
1964                         DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", file));
1965                         status = WERR_ACCESS_DENIED;
1966                         goto error_exit;
1967                 }
1968         }
1969
1970         ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, securityinformation, sd_buf.sd);
1971
1972         if (ret == False) {
1973                 DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", file));
1974                 status = WERR_ACCESS_DENIED;
1975                 goto error_exit;
1976         }
1977
1978         close_file(fsp, NORMAL_CLOSE);
1979         unbecome_user();
1980         close_cnum(conn, p->pipe_user.vuid);
1981         return status;
1982
1983 error_exit:
1984
1985         if(fsp) {
1986                 close_file(fsp, NORMAL_CLOSE);
1987         }
1988
1989         if (became_user) {
1990                 unbecome_user();
1991         }
1992
1993         if (conn) {
1994                 close_cnum(conn, p->pipe_user.vuid);
1995         }
1996
1997         return status;
1998 }
1999
2000 /***********************************************************************************
2001  It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
2002  We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
2003  These disks would the disks listed by this function.
2004  Users could then create shares relative to these disks.  Watch out for moving these disks around.
2005  "Nigel Williams" <nigel@veritas.com>.
2006 ***********************************************************************************/
2007
2008 static const char *server_disks[] = {"C:"};
2009
2010 static uint32 get_server_disk_count(void)
2011 {
2012         return sizeof(server_disks)/sizeof(server_disks[0]);
2013 }
2014
2015 static uint32 init_server_disk_enum(uint32 *resume)
2016 {
2017         uint32 server_disk_count = get_server_disk_count();
2018
2019         /*resume can be an offset into the list for now*/
2020
2021         if(*resume & 0x80000000)
2022                 *resume = 0;
2023
2024         if(*resume > server_disk_count)
2025                 *resume = server_disk_count;
2026
2027         return server_disk_count - *resume;
2028 }
2029
2030 static const char *next_server_disk_enum(uint32 *resume)
2031 {
2032         const char *disk;
2033
2034         if(init_server_disk_enum(resume) == 0)
2035                 return NULL;
2036
2037         disk = server_disks[*resume];
2038
2039         (*resume)++;
2040
2041         DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
2042
2043         return disk;
2044 }
2045
2046 WERROR _srvsvc_NetDiskEnum(pipes_struct *p, const char *server_unc, uint32_t level, struct srvsvc_NetDiskInfo *info, uint32_t maxlen, uint32_t *totalentries, uint32_t *resume_handle)
2047 {
2048         uint32 i;
2049         const char *disk_name;
2050
2051         WERROR status = WERR_OK;
2052
2053         *totalentries = init_server_disk_enum(resume_handle);
2054         info->count = 0;
2055
2056         if(!(info->disks =  TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetDiskInfo0, MAX_SERVER_DISK_ENTRIES))) {
2057                 return WERR_NOMEM;
2058         }
2059
2060         /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
2061
2062         for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(resume_handle)); i++) {
2063
2064                 info->count++;
2065                 (*totalentries)++;
2066
2067                 /*copy disk name into a unicode string*/
2068
2069                 info->disks[i].disk = disk_name; 
2070         }
2071
2072         /* add a terminating null string.  Is this there if there is more data to come? */
2073
2074         info->count++;
2075         (*totalentries)++;
2076
2077         info->disks[i].disk = "";
2078
2079         return status;
2080 }
2081
2082 /********************************************************************
2083 ********************************************************************/
2084
2085 WERROR _srvsvc_NetNameValidate(pipes_struct *p, const char *server_unc, const char *name, uint32_t name_type, uint32_t flags)
2086 {
2087         int len;
2088
2089         if ((flags != 0x0) && (flags != 0x80000000)) {
2090                 return WERR_INVALID_PARAM;
2091         }
2092
2093         switch ( name_type ) {
2094         case 0x9:
2095                 len = strlen_m(name);
2096
2097                 if ((flags == 0x0) && (len > 81)) {
2098                         DEBUG(5,("_srv_net_name_validate: share name too long (%s > 81 chars)\n", name));
2099                         return WERR_INVALID_NAME;
2100                 }
2101                 if ((flags == 0x80000000) && (len > 13)) {
2102                         DEBUG(5,("_srv_net_name_validate: share name too long (%s > 13 chars)\n", name));
2103                         return WERR_INVALID_NAME;
2104                 }
2105
2106                 if ( ! validate_net_name( name, INVALID_SHARENAME_CHARS, sizeof(name) ) ) {
2107                         DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", name));
2108                         return WERR_INVALID_NAME;
2109                 }
2110                 break;
2111
2112         default:
2113                 return WERR_UNKNOWN_LEVEL;
2114         }
2115
2116         return WERR_OK;
2117 }
2118
2119
2120 /********************************************************************
2121 ********************************************************************/
2122
2123 WERROR _srvsvc_NetFileClose(pipes_struct *p, const char *server_unc, uint32_t fid)
2124 {
2125         return WERR_ACCESS_DENIED;
2126 }
2127
2128 WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, const char *server_unc, uint32_t *level, union srvsvc_NetCharDevCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
2129 {
2130         return WERR_NOT_SUPPORTED;
2131 }
2132
2133 WERROR _srvsvc_NetCharDevGetInfo(pipes_struct *p, const char *server_unc, const char *device_name, uint32_t level, union srvsvc_NetCharDevInfo *info)
2134 {
2135         return WERR_NOT_SUPPORTED;
2136 }
2137
2138 WERROR _srvsvc_NetCharDevControl(pipes_struct *p, const char *server_unc, const char *device_name, uint32_t opcode)
2139 {
2140         return WERR_NOT_SUPPORTED;
2141 }
2142
2143 WERROR _srvsvc_NetCharDevQEnum(pipes_struct *p, const char *server_unc, const char *user, uint32_t *level, union srvsvc_NetCharDevQCtr *ctr, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
2144 {
2145         return WERR_NOT_SUPPORTED;
2146 }
2147
2148 WERROR _srvsvc_NetCharDevQGetInfo(pipes_struct *p, const char *server_unc, const char *queue_name, const char *user, uint32_t level, union srvsvc_NetCharDevQInfo *info)
2149 {
2150         return WERR_NOT_SUPPORTED;
2151 }
2152
2153 WERROR _srvsvc_NetCharDevQSetInfo(pipes_struct *p, const char *server_unc, const char *queue_name, uint32_t level, union srvsvc_NetCharDevQInfo info, uint32_t *parm_error)
2154 {
2155         return WERR_NOT_SUPPORTED;
2156 }
2157
2158 WERROR _srvsvc_NetCharDevQPurge(pipes_struct *p, const char *server_unc, const char *queue_name)
2159 {
2160         return WERR_NOT_SUPPORTED;
2161 }
2162
2163 WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, const char *server_unc, const char *queue_name, const char *computer_name)
2164 {
2165         return WERR_NOT_SUPPORTED;
2166 }
2167
2168 WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, const char *server_unc, uint32_t fid, uint32_t level, union srvsvc_NetFileInfo *info)
2169 {
2170         return WERR_NOT_SUPPORTED;
2171 }
2172
2173 WERROR _srvsvc_NetShareCheck(pipes_struct *p, const char *server_unc, const char *device_name, enum srvsvc_ShareType *type)
2174 {
2175         return WERR_NOT_SUPPORTED;
2176 }
2177
2178 WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, const char *server_unc, const char *service, uint32_t level, uint32_t options, struct srvsvc_Statistics *stats)
2179 {
2180         return WERR_NOT_SUPPORTED;
2181 }
2182
2183 WERROR _srvsvc_NetTransportAdd(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetTransportInfo info)
2184 {
2185         return WERR_NOT_SUPPORTED;
2186 }
2187
2188 WERROR _srvsvc_NetTransportEnum(pipes_struct *p, const char *server_unc, uint32_t *level, union srvsvc_NetTransportCtr *transports, uint32_t max_buffer, uint32_t *totalentries, uint32_t *resume_handle)
2189 {
2190         return WERR_NOT_SUPPORTED;
2191 }
2192
2193 WERROR _srvsvc_NetTransportDel(pipes_struct *p, const char *server_unc, uint32_t unknown, struct srvsvc_NetTransportInfo0 transport)
2194 {
2195         return WERR_NOT_SUPPORTED;
2196 }
2197
2198 WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, const char *server_unc, const char *transport, uint32_t servicebits, uint32_t updateimmediately)
2199 {
2200         return WERR_NOT_SUPPORTED;
2201 }
2202
2203 WERROR _srvsvc_NetPathType(pipes_struct *p, const char *server_unc, const char *path, uint32_t pathflags, uint32_t *pathtype)
2204 {
2205         return WERR_NOT_SUPPORTED;
2206 }
2207
2208 WERROR _srvsvc_NetPathCanonicalize(pipes_struct *p, const char *server_unc, const char *path, uint8_t *can_path, uint32_t maxbuf, const char *prefix, uint32_t *pathtype, uint32_t pathflags)
2209 {
2210         return WERR_NOT_SUPPORTED;
2211 }
2212
2213 WERROR _srvsvc_NetPathCompare(pipes_struct *p, const char *server_unc, const char *path1, const char *path2, uint32_t pathtype, uint32_t pathflags)
2214 {
2215         return WERR_NOT_SUPPORTED;
2216 }
2217
2218 WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p)
2219 {
2220         return WERR_NOT_SUPPORTED;
2221 }
2222
2223 WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, const char *server_unc, const char *name1, const char *name2, uint32_t name_type, uint32_t flags)
2224 {
2225         return WERR_NOT_SUPPORTED;
2226 }
2227
2228 WERROR _srvsvc_NetShareDelStart(pipes_struct *p, const char *server_unc, const char *share, uint32_t reserved, struct policy_handle *hnd)
2229 {
2230         return WERR_NOT_SUPPORTED;
2231 }
2232
2233 WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct policy_handle *hnd)
2234 {
2235         return WERR_NOT_SUPPORTED;
2236 }
2237
2238 WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, const char *server_unc, uint32_t level, union srvsvc_NetTransportInfo info)
2239 {
2240         return WERR_NOT_SUPPORTED;
2241 }
2242
2243 WERROR _srvsvc_NetServerSetServiceBitsEx(pipes_struct *p, const char *server_unc, const char *emulated_server_unc, const char *transport, uint32_t servicebitsofinterest, uint32_t servicebits, uint32_t updateimmediately)
2244 {
2245         return WERR_NOT_SUPPORTED;
2246 }
2247
2248 WERROR _srvsvc_NETRDFSGETVERSION(pipes_struct *p)
2249 {
2250         return WERR_NOT_SUPPORTED;
2251 }
2252
2253 WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(pipes_struct *p)
2254 {
2255         return WERR_NOT_SUPPORTED;
2256 }
2257
2258 WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p)
2259 {
2260         return WERR_NOT_SUPPORTED;
2261 }
2262
2263 WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p)
2264 {
2265         return WERR_NOT_SUPPORTED;
2266 }
2267
2268 WERROR _srvsvc_NETRDFSSETSERVERINFO(pipes_struct *p)
2269 {
2270         return WERR_NOT_SUPPORTED;
2271 }
2272
2273 WERROR _srvsvc_NETRDFSCREATEEXITPOINT(pipes_struct *p)
2274 {
2275         return WERR_NOT_SUPPORTED;
2276 }
2277
2278 WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p)
2279 {
2280         return WERR_NOT_SUPPORTED;
2281 }
2282
2283 WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p)
2284 {
2285         return WERR_NOT_SUPPORTED;
2286 }
2287
2288 WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p)
2289 {
2290         return WERR_NOT_SUPPORTED;
2291 }
2292
2293 WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p)
2294 {
2295         return WERR_NOT_SUPPORTED;
2296 }
2297
2298 WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p)
2299 {
2300         return WERR_NOT_SUPPORTED;
2301 }