root/source3/rpc_server/srv_srvsvc_nt.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pipe_enum_fn
  2. net_enum_pipes
  3. enum_file_fn
  4. net_enum_files
  5. get_share_type
  6. init_srv_share_info_0
  7. init_srv_share_info_1
  8. init_srv_share_info_2
  9. map_generic_share_sd_bits
  10. init_srv_share_info_501
  11. init_srv_share_info_502
  12. init_srv_share_info_1004
  13. init_srv_share_info_1005
  14. init_srv_share_info_1006
  15. init_srv_share_info_1007
  16. init_srv_share_info_1501
  17. is_hidden_share
  18. is_enumeration_allowed
  19. init_srv_share_info_ctr
  20. init_srv_sess_info_0
  21. sess_file_fn
  22. net_count_files
  23. init_srv_sess_info_1
  24. init_srv_conn_info_0
  25. init_srv_conn_info_1
  26. _srvsvc_NetFileEnum
  27. _srvsvc_NetSrvGetInfo
  28. _srvsvc_NetSrvSetInfo
  29. _srvsvc_NetConnEnum
  30. _srvsvc_NetSessEnum
  31. _srvsvc_NetSessDel
  32. _srvsvc_NetShareEnumAll
  33. _srvsvc_NetShareEnum
  34. _srvsvc_NetShareGetInfo
  35. valid_share_pathname
  36. _srvsvc_NetShareSetInfo
  37. _srvsvc_NetShareAdd
  38. _srvsvc_NetShareDel
  39. _srvsvc_NetShareDelSticky
  40. _srvsvc_NetRemoteTOD
  41. _srvsvc_NetGetFileSecurity
  42. _srvsvc_NetSetFileSecurity
  43. get_server_disk_count
  44. init_server_disk_enum
  45. next_server_disk_enum
  46. _srvsvc_NetDiskEnum
  47. _srvsvc_NetNameValidate
  48. enum_file_close_fn
  49. _srvsvc_NetFileClose
  50. _srvsvc_NetCharDevEnum
  51. _srvsvc_NetCharDevGetInfo
  52. _srvsvc_NetCharDevControl
  53. _srvsvc_NetCharDevQEnum
  54. _srvsvc_NetCharDevQGetInfo
  55. _srvsvc_NetCharDevQSetInfo
  56. _srvsvc_NetCharDevQPurge
  57. _srvsvc_NetCharDevQPurgeSelf
  58. _srvsvc_NetFileGetInfo
  59. _srvsvc_NetShareCheck
  60. _srvsvc_NetServerStatisticsGet
  61. _srvsvc_NetTransportAdd
  62. _srvsvc_NetTransportEnum
  63. _srvsvc_NetTransportDel
  64. _srvsvc_NetSetServiceBits
  65. _srvsvc_NetPathType
  66. _srvsvc_NetPathCanonicalize
  67. _srvsvc_NetPathCompare
  68. _srvsvc_NETRPRNAMECANONICALIZE
  69. _srvsvc_NetPRNameCompare
  70. _srvsvc_NetShareDelStart
  71. _srvsvc_NetShareDelCommit
  72. _srvsvc_NetServerTransportAddEx
  73. _srvsvc_NetServerSetServiceBitsEx
  74. _srvsvc_NETRDFSGETVERSION
  75. _srvsvc_NETRDFSCREATELOCALPARTITION
  76. _srvsvc_NETRDFSDELETELOCALPARTITION
  77. _srvsvc_NETRDFSSETLOCALVOLUMESTATE
  78. _srvsvc_NETRDFSSETSERVERINFO
  79. _srvsvc_NETRDFSCREATEEXITPOINT
  80. _srvsvc_NETRDFSDELETEEXITPOINT
  81. _srvsvc_NETRDFSMODIFYPREFIX
  82. _srvsvc_NETRDFSFIXLOCALVOLUME
  83. _srvsvc_NETRDFSMANAGERREPORTSITEINFO
  84. _srvsvc_NETRSERVERTRANSPORTDELEX

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

/* [<][>][^][v][top][bottom][index][help] */