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