LCOV - code coverage report
Current view: top level - source3/rpc_server/srvsvc - srv_srvsvc_nt.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 789 1488 53.0 %
Date: 2024-06-13 04:01:37 Functions: 42 87 48.3 %

          Line data    Source code
       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             : #include "system/passwd.h"
      28             : #include "lib/util/server_id.h"
      29             : #include "ntdomain.h"
      30             : #include "librpc/rpc/dcesrv_core.h"
      31             : #include "librpc/gen_ndr/ndr_srvsvc.h"
      32             : #include "librpc/gen_ndr/ndr_srvsvc_scompat.h"
      33             : #include "../libcli/security/security.h"
      34             : #include "../librpc/gen_ndr/ndr_security.h"
      35             : #include "../librpc/gen_ndr/open_files.h"
      36             : #include "dbwrap/dbwrap.h"
      37             : #include "session.h"
      38             : #include "../lib/util/util_pw.h"
      39             : #include "locking/share_mode_lock.h"
      40             : #include "smbd/smbd.h"
      41             : #include "smbd/globals.h"
      42             : #include "auth.h"
      43             : #include "messages.h"
      44             : #include "serverid.h"
      45             : #include "lib/global_contexts.h"
      46             : #include "source3/lib/substitute.h"
      47             : 
      48             : extern const struct generic_mapping file_generic_mapping;
      49             : 
      50             : #undef DBGC_CLASS
      51             : #define DBGC_CLASS DBGC_RPC_SRV
      52             : 
      53             : #define MAX_SERVER_DISK_ENTRIES 15
      54             : 
      55             : /* Use for enumerating connections, pipes, & files */
      56             : 
      57             : struct file_enum_count {
      58             :         TALLOC_CTX *ctx;
      59             :         const char *username;
      60             :         struct srvsvc_NetFileCtr3 *ctr3;
      61             :         struct file_id *fids;
      62             : };
      63             : 
      64             : struct sess_file_info {
      65             :         struct srvsvc_NetSessCtr1 *ctr;
      66             :         struct sessionid *session_list;
      67             :         uint32_t resume_handle;
      68             :         uint32_t num_entries;
      69             : };
      70             : 
      71             : struct share_file_stat {
      72             :         struct srvsvc_NetConnInfo1 *netconn_arr;
      73             :         struct server_id *svrid_arr;
      74             :         const char *in_sharepath;
      75             :         uint32_t resp_entries;
      76             :         uint32_t total_entries;
      77             : };
      78             : 
      79             : struct share_conn_stat {
      80             :         TALLOC_CTX *ctx;
      81             :         const char *sharename;
      82             :         struct server_id *svrid_arr;
      83             :         int count;
      84             : };
      85             : 
      86             : /*******************************************************************
      87             : ********************************************************************/
      88             : 
      89           0 : static int enum_file_fn(struct file_id id,
      90             :                         const struct share_mode_data *d,
      91             :                         const struct share_mode_entry *e,
      92             :                         void *private_data)
      93             : {
      94           0 :         struct file_enum_count *fenum =
      95             :                 (struct file_enum_count *)private_data;
      96           0 :         struct srvsvc_NetFileCtr3 *ctr3 = fenum->ctr3;
      97             :         struct srvsvc_NetFileInfo3 *f;
      98           0 :         struct file_id *fids = NULL;
      99           0 :         char *fullpath = NULL;
     100             :         uint32_t permissions;
     101             :         const char *username;
     102             : 
     103             :         /* If the pid was not found delete the entry from connections.tdb */
     104             : 
     105           0 :         if ( !process_exists(e->pid) ) {
     106           0 :                 return 0;
     107             :         }
     108             : 
     109           0 :         username = uidtoname(e->uid);
     110             : 
     111           0 :         if ((fenum->username != NULL)
     112           0 :             && !strequal(username, fenum->username)) {
     113           0 :                 return 0;
     114             :         }
     115             : 
     116           0 :         f = talloc_realloc(
     117             :                 fenum->ctx,
     118             :                 ctr3->array,
     119             :                 struct srvsvc_NetFileInfo3,
     120             :                 ctr3->count+1);
     121           0 :         if ( !f ) {
     122           0 :                 DBG_ERR("realloc failed for %"PRIu32" items\n", ctr3->count+1);
     123           0 :                 return 0;
     124             :         }
     125           0 :         ctr3->array = f;
     126             : 
     127           0 :         fids = talloc_realloc(
     128             :                 fenum->ctx, fenum->fids, struct file_id, ctr3->count+1);
     129           0 :         if (fids == NULL) {
     130           0 :                 DBG_ERR("realloc failed for %"PRIu32" items\n", ctr3->count+1);
     131           0 :                 return 0;
     132             :         }
     133           0 :         fids[ctr3->count] = id;
     134           0 :         fenum->fids = fids;
     135             : 
     136           0 :         if ( strcmp(d->base_name, "." ) == 0 ) {
     137           0 :                 fullpath = talloc_asprintf(
     138           0 :                         fenum->ctx,
     139             :                         "C:%s",
     140           0 :                         d->servicepath);
     141             :         } else {
     142           0 :                 fullpath = talloc_asprintf(
     143           0 :                         fenum->ctx,
     144             :                         "C:%s/%s%s",
     145           0 :                         d->servicepath,
     146           0 :                         d->base_name,
     147           0 :                         (d->stream_name != NULL) ? d->stream_name : "");
     148             :         }
     149           0 :         if (!fullpath) {
     150           0 :                 return 0;
     151             :         }
     152           0 :         string_replace( fullpath, '/', '\\' );
     153             : 
     154             :         /* mask out create (what ever that is) */
     155           0 :         permissions = e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA);
     156             : 
     157             :         /* now fill in the srvsvc_NetFileInfo3 struct */
     158             : 
     159           0 :         ctr3->array[ctr3->count] = (struct srvsvc_NetFileInfo3) {
     160           0 :                 .fid            = (((uint32_t)(procid_to_pid(&e->pid))<<16) |
     161           0 :                                    e->share_file_id),
     162             :                 .permissions    = permissions,
     163             :                 .path           = fullpath,
     164             :                 .user           = username,
     165             :         };
     166             : 
     167           0 :         ctr3->count++;
     168             : 
     169           0 :         return 0;
     170             : }
     171             : 
     172             : /*******************************************************************
     173             : ********************************************************************/
     174             : 
     175           2 : static WERROR net_enum_files(TALLOC_CTX *ctx,
     176             :                              const char *username,
     177             :                              struct srvsvc_NetFileCtr3 **ctr3,
     178             :                              uint32_t resume)
     179             : {
     180           3 :         struct file_enum_count f_enum_cnt = {
     181           2 :                 .ctx = ctx, .username = username, .ctr3 = *ctr3,
     182             :         };
     183             :         uint32_t i;
     184             : 
     185           2 :         share_entry_forall(enum_file_fn, (void *)&f_enum_cnt );
     186             : 
     187           2 :         *ctr3 = f_enum_cnt.ctr3;
     188             : 
     189             :         /* need to count the number of locks on a file */
     190             : 
     191           2 :         for (i=0; i<(*ctr3)->count; i++) {
     192           0 :                 struct files_struct fsp = { .file_id = f_enum_cnt.fids[i], };
     193           0 :                 struct byte_range_lock *brl = NULL;
     194             : 
     195           0 :                 brl = brl_get_locks(ctx, &fsp);
     196           0 :                 if (brl == NULL) {
     197           0 :                         continue;
     198             :                 }
     199             : 
     200           0 :                 (*ctr3)->array[i].num_locks = brl_num_locks(brl);
     201             : 
     202           0 :                 TALLOC_FREE(brl);
     203             :         }
     204             : 
     205           2 :         return WERR_OK;
     206             : }
     207             : 
     208             : /*******************************************************************
     209             :  Utility function to get the 'type' of a share from an snum.
     210             :  ********************************************************************/
     211        5331 : static enum srvsvc_ShareType get_share_type(int snum)
     212             : {
     213             :         /* work out the share type */
     214        5331 :         enum srvsvc_ShareType type = STYPE_DISKTREE;
     215             : 
     216        5331 :         if (lp_printable(snum)) {
     217         530 :                 type = lp_administrative_share(snum)
     218         265 :                         ? STYPE_PRINTQ_HIDDEN : STYPE_PRINTQ;
     219             :         }
     220        5331 :         if (strequal(lp_fstype(snum), "IPC")) {
     221          94 :                 type = lp_administrative_share(snum)
     222          47 :                         ? STYPE_IPC_HIDDEN : STYPE_IPC;
     223             :         }
     224        5331 :         return type;
     225             : }
     226             : 
     227             : /*******************************************************************
     228             :  Fill in a share info level 0 structure.
     229             :  ********************************************************************/
     230             : 
     231         902 : static void init_srv_share_info_0(struct pipes_struct *p,
     232             :                                   struct srvsvc_NetShareInfo0 *r, int snum)
     233             : {
     234         463 :         const struct loadparm_substitution *lp_sub =
     235         439 :                 loadparm_s3_global_substitution();
     236             : 
     237         902 :         r->name              = lp_servicename(talloc_tos(), lp_sub, snum);
     238         902 : }
     239             : 
     240             : /*******************************************************************
     241             :  Fill in a share info level 1 structure.
     242             :  ********************************************************************/
     243             : 
     244        3727 : static void init_srv_share_info_1(struct pipes_struct *p,
     245             :                                   struct srvsvc_NetShareInfo1 *r,
     246             :                                   int snum)
     247             : {
     248        3727 :         struct dcesrv_call_state *dce_call = p->dce_call;
     249        2033 :         struct auth_session_info *session_info =
     250        1694 :                 dcesrv_call_session_info(dce_call);
     251        2033 :         const struct loadparm_substitution *lp_sub =
     252        1694 :                 loadparm_s3_global_substitution();
     253        3727 :         char *net_name = lp_servicename(talloc_tos(), lp_sub, snum);
     254        3727 :         char *remark = lp_comment(p->mem_ctx, lp_sub, snum);
     255             : 
     256        3727 :         if (remark) {
     257       13214 :                 remark = talloc_sub_full(
     258        3727 :                         p->mem_ctx, lp_servicename(talloc_tos(), lp_sub, snum),
     259        3727 :                         get_current_username(), lp_path(talloc_tos(), lp_sub, snum),
     260        3727 :                         session_info->unix_token->uid, get_current_username(),
     261             :                         "", remark);
     262             :         }
     263             : 
     264        3727 :         r->name              = net_name;
     265        3727 :         r->type              = get_share_type(snum);
     266        3727 :         r->comment   = remark ? remark : "";
     267        3727 : }
     268             : 
     269             : /*******************************************************************
     270             :  Fill in a share info level 2 structure.
     271             :  ********************************************************************/
     272             : 
     273        1336 : static void init_srv_share_info_2(struct pipes_struct *p,
     274             :                                   struct srvsvc_NetShareInfo2 *r,
     275             :                                   int snum)
     276             : {
     277        1336 :         struct dcesrv_call_state *dce_call = p->dce_call;
     278         680 :         struct auth_session_info *session_info =
     279         656 :                 dcesrv_call_session_info(dce_call);
     280         680 :         const struct loadparm_substitution *lp_sub =
     281         656 :                 loadparm_s3_global_substitution();
     282        1336 :         char *remark = NULL;
     283        1336 :         char *path = NULL;
     284        1336 :         int max_connections = lp_max_connections(snum);
     285        1336 :         uint32_t max_uses = UINT32_MAX;
     286        1336 :         char *net_name = lp_servicename(talloc_tos(), lp_sub, snum);
     287             : 
     288        1336 :         if (max_connections > 0) {
     289           0 :                 max_uses = MIN(max_connections, UINT32_MAX);
     290             :         }
     291             : 
     292        1336 :         remark = lp_comment(p->mem_ctx, lp_sub, snum);
     293        1336 :         if (remark) {
     294        4688 :                 remark = talloc_sub_full(
     295        1336 :                         p->mem_ctx, lp_servicename(talloc_tos(), lp_sub, snum),
     296        1336 :                         get_current_username(), lp_path(talloc_tos(), lp_sub, snum),
     297        1336 :                         session_info->unix_token->uid, get_current_username(),
     298             :                         "", remark);
     299             :         }
     300        1336 :         path = talloc_asprintf(p->mem_ctx,
     301             :                         "C:%s", lp_path(talloc_tos(), lp_sub, snum));
     302             : 
     303        1336 :         if (path) {
     304             :                 /*
     305             :                  * Change / to \\ so that win2k will see it as a valid path.
     306             :                  * This was added to enable use of browsing in win2k add
     307             :                  * share dialog.
     308             :                  */
     309             : 
     310        1336 :                 string_replace(path, '/', '\\');
     311             :         }
     312             : 
     313        1336 :         r->name                      = net_name;
     314        1336 :         r->type                      = get_share_type(snum);
     315        1336 :         r->comment           = remark ? remark : "";
     316        1336 :         r->permissions               = 0;
     317        1336 :         r->max_users         = max_uses;
     318        1336 :         r->current_users     = 0; /* computed later */
     319        1336 :         r->path                      = path ? path : "";
     320        1336 :         r->password          = "";
     321        1336 : }
     322             : 
     323             : /*******************************************************************
     324             :  Map any generic bits to file specific bits.
     325             : ********************************************************************/
     326             : 
     327           1 : static void map_generic_share_sd_bits(struct security_descriptor *psd)
     328             : {
     329             :         uint32_t i;
     330           1 :         struct security_acl *ps_dacl = NULL;
     331             : 
     332           1 :         if (!psd)
     333           1 :                 return;
     334             : 
     335           0 :         ps_dacl = psd->dacl;
     336           0 :         if (!ps_dacl)
     337           0 :                 return;
     338             : 
     339           0 :         for (i = 0; i < ps_dacl->num_aces; i++) {
     340           0 :                 struct security_ace *psa = &ps_dacl->aces[i];
     341           0 :                 uint32_t orig_mask = psa->access_mask;
     342             : 
     343           0 :                 se_map_generic(&psa->access_mask, &file_generic_mapping);
     344           0 :                 psa->access_mask |= orig_mask;
     345             :         }
     346             : }
     347             : 
     348             : /*******************************************************************
     349             :  Fill in a share info level 501 structure.
     350             : ********************************************************************/
     351             : 
     352         240 : static void init_srv_share_info_501(struct pipes_struct *p,
     353             :                                     struct srvsvc_NetShareInfo501 *r, int snum)
     354             : {
     355         240 :         struct dcesrv_call_state *dce_call = p->dce_call;
     356         132 :         struct auth_session_info *session_info =
     357         108 :                 dcesrv_call_session_info(dce_call);
     358         132 :         const struct loadparm_substitution *lp_sub =
     359         108 :                 loadparm_s3_global_substitution();
     360         240 :         const char *net_name = lp_servicename(talloc_tos(), lp_sub, snum);
     361         240 :         char *remark = lp_comment(p->mem_ctx, lp_sub, snum);
     362             : 
     363         240 :         if (remark) {
     364         852 :                 remark = talloc_sub_full(
     365         240 :                         p->mem_ctx, lp_servicename(talloc_tos(), lp_sub, snum),
     366         240 :                         get_current_username(), lp_path(talloc_tos(), lp_sub, snum),
     367         240 :                         session_info->unix_token->uid, get_current_username(),
     368             :                         "", remark);
     369             :         }
     370             : 
     371         240 :         r->name              = net_name;
     372         240 :         r->type              = get_share_type(snum);
     373         240 :         r->comment   = remark ? remark : "";
     374             : 
     375             :         /*
     376             :          * According to [MS-SRVS] 2.2.4.25, the flags field is the same as in
     377             :          * level 1005.
     378             :          */
     379         240 :         r->csc_policy        = (lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT);
     380         240 : }
     381             : 
     382             : /*******************************************************************
     383             :  Fill in a share info level 502 structure.
     384             :  ********************************************************************/
     385             : 
     386          28 : static void init_srv_share_info_502(struct pipes_struct *p,
     387             :                                     struct srvsvc_NetShareInfo502 *r, int snum)
     388             : {
     389          28 :         struct dcesrv_call_state *dce_call = p->dce_call;
     390          28 :         struct auth_session_info *session_info =
     391           0 :                 dcesrv_call_session_info(dce_call);
     392          28 :         const struct loadparm_substitution *lp_sub =
     393           0 :                 loadparm_s3_global_substitution();
     394          28 :         const char *net_name = lp_servicename(talloc_tos(), lp_sub, snum);
     395          28 :         char *path = NULL;
     396          28 :         struct security_descriptor *sd = NULL;
     397          28 :         struct sec_desc_buf *sd_buf = NULL;
     398          28 :         size_t sd_size = 0;
     399          28 :         TALLOC_CTX *ctx = p->mem_ctx;
     400          28 :         char *remark = lp_comment(ctx, lp_sub, snum);
     401             : 
     402          28 :         if (remark) {
     403         112 :                 remark = talloc_sub_full(
     404          28 :                         p->mem_ctx, lp_servicename(talloc_tos(), lp_sub, snum),
     405          28 :                         get_current_username(), lp_path(talloc_tos(), lp_sub, snum),
     406          28 :                         session_info->unix_token->uid, get_current_username(),
     407             :                         "", remark);
     408             :         }
     409          28 :         path = talloc_asprintf(ctx, "C:%s", lp_path(talloc_tos(), lp_sub, snum));
     410          28 :         if (path) {
     411             :                 /*
     412             :                  * Change / to \\ so that win2k will see it as a valid path.  This was added to
     413             :                  * enable use of browsing in win2k add share dialog.
     414             :                  */
     415          28 :                 string_replace(path, '/', '\\');
     416             :         }
     417             : 
     418          28 :         sd = get_share_security(ctx, lp_servicename(talloc_tos(), lp_sub, snum), &sd_size);
     419             : 
     420          28 :         sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
     421             : 
     422          28 :         r->name                      = net_name;
     423          28 :         r->type                      = get_share_type(snum);
     424          28 :         r->comment           = remark ? remark : "";
     425          28 :         r->permissions               = 0;
     426          28 :         r->max_users         = (uint32_t)-1;
     427          28 :         r->current_users     = 1; /* ??? */
     428          28 :         r->path                      = path ? path : "";
     429          28 :         r->password          = "";
     430          28 :         r->sd_buf            = *sd_buf;
     431          28 : }
     432             : 
     433             : /***************************************************************************
     434             :  Fill in a share info level 1004 structure.
     435             :  ***************************************************************************/
     436             : 
     437           0 : static void init_srv_share_info_1004(struct pipes_struct *p,
     438             :                                      struct srvsvc_NetShareInfo1004 *r,
     439             :                                      int snum)
     440             : {
     441           0 :         struct dcesrv_call_state *dce_call = p->dce_call;
     442           0 :         struct auth_session_info *session_info =
     443           0 :                 dcesrv_call_session_info(dce_call);
     444           0 :         const struct loadparm_substitution *lp_sub =
     445           0 :                 loadparm_s3_global_substitution();
     446           0 :         char *remark = lp_comment(p->mem_ctx, lp_sub, snum);
     447             : 
     448           0 :         if (remark) {
     449           0 :                 remark = talloc_sub_full(
     450           0 :                         p->mem_ctx, lp_servicename(talloc_tos(), lp_sub, snum),
     451           0 :                         get_current_username(), lp_path(talloc_tos(), lp_sub, snum),
     452           0 :                         session_info->unix_token->uid, get_current_username(),
     453             :                         "", remark);
     454             :         }
     455             : 
     456           0 :         r->comment   = remark ? remark : "";
     457           0 : }
     458             : 
     459             : /***************************************************************************
     460             :  Fill in a share info level 1005 structure.
     461             :  ***************************************************************************/
     462             : 
     463           2 : static void init_srv_share_info_1005(struct pipes_struct *p,
     464             :                                      struct srvsvc_NetShareInfo1005 *r,
     465             :                                      int snum)
     466             : {
     467           2 :         uint32_t dfs_flags = 0;
     468             : 
     469           2 :         if (lp_host_msdfs() && lp_msdfs_root(snum)) {
     470           0 :                 dfs_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT;
     471             :         }
     472             : 
     473           2 :         dfs_flags |= lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT;
     474             : 
     475           2 :         r->dfs_flags = dfs_flags;
     476           2 : }
     477             : 
     478             : /***************************************************************************
     479             :  Fill in a share info level 1006 structure.
     480             :  ***************************************************************************/
     481             : 
     482           0 : static void init_srv_share_info_1006(struct pipes_struct *p,
     483             :                                      struct srvsvc_NetShareInfo1006 *r,
     484             :                                      int snum)
     485             : {
     486           0 :         r->max_users = (uint32_t)-1;
     487           0 : }
     488             : 
     489             : /***************************************************************************
     490             :  Fill in a share info level 1007 structure.
     491             :  ***************************************************************************/
     492             : 
     493           0 : static void init_srv_share_info_1007(struct pipes_struct *p,
     494             :                                      struct srvsvc_NetShareInfo1007 *r,
     495             :                                      int snum)
     496             : {
     497           0 :         r->flags                     = 0;
     498           0 :         r->alternate_directory_name  = "";
     499           0 : }
     500             : 
     501             : /*******************************************************************
     502             :  Fill in a share info level 1501 structure.
     503             :  ********************************************************************/
     504             : 
     505           0 : static void init_srv_share_info_1501(struct pipes_struct *p,
     506             :                                      struct sec_desc_buf **r,
     507             :                                      int snum)
     508             : {
     509           0 :         const struct loadparm_substitution *lp_sub =
     510           0 :                 loadparm_s3_global_substitution();
     511             :         struct security_descriptor *sd;
     512           0 :         struct sec_desc_buf *sd_buf = NULL;
     513             :         size_t sd_size;
     514           0 :         TALLOC_CTX *ctx = p->mem_ctx;
     515             : 
     516           0 :         sd = get_share_security(ctx, lp_servicename(talloc_tos(), lp_sub, snum), &sd_size);
     517           0 :         if (sd) {
     518           0 :                 sd_buf = make_sec_desc_buf(p->mem_ctx, sd_size, sd);
     519             :         }
     520             : 
     521           0 :         *r = sd_buf;
     522           0 : }
     523             : 
     524             : /*******************************************************************
     525             :  True if it ends in '$'.
     526             :  ********************************************************************/
     527             : 
     528        1982 : static bool is_hidden_share(int snum)
     529             : {
     530         991 :         const struct loadparm_substitution *lp_sub =
     531         991 :                 loadparm_s3_global_substitution();
     532        1982 :         const char *net_name = lp_servicename(talloc_tos(), lp_sub, snum);
     533             : 
     534        1982 :         return (net_name[strlen(net_name) - 1] == '$') ? True : False;
     535             : }
     536             : 
     537             : /*******************************************************************
     538             :  Verify user is allowed to view share, access based enumeration
     539             : ********************************************************************/
     540        6304 : static bool is_enumeration_allowed(struct pipes_struct *p,
     541             :                                    int snum)
     542             : {
     543             :         bool allowed;
     544        6304 :         struct dcesrv_call_state *dce_call = p->dce_call;
     545        3371 :         struct auth_session_info *session_info =
     546        2933 :                 dcesrv_call_session_info(dce_call);
     547        3371 :         const struct loadparm_substitution *lp_sub =
     548        2933 :                 loadparm_s3_global_substitution();
     549             : 
     550        6304 :         if (!lp_access_based_share_enum(snum)) {
     551        6247 :                 return true;
     552             :         }
     553             : 
     554          57 :         if (!user_ok_token(session_info->unix_info->unix_name,
     555          57 :                            session_info->info->domain_name,
     556          57 :                            session_info->security_token, snum)) {
     557          57 :                 return false;
     558             :         }
     559             : 
     560             : 
     561             :         /*
     562             :          * share_access_check() must be opened as root
     563             :          * because it ultimately gets a R/W db handle on share_info.tdb
     564             :          * which has 0o600 permissions
     565             :          */
     566           0 :         become_root();
     567           0 :         allowed = share_access_check(session_info->security_token,
     568           0 :                                      lp_servicename(talloc_tos(), lp_sub, snum),
     569             :                                      FILE_READ_DATA, NULL);
     570           0 :         unbecome_root();
     571             : 
     572           0 :         return allowed;
     573             : }
     574             : 
     575             : /****************************************************************************
     576             :  Count an entry against the respective service.
     577             : ****************************************************************************/
     578             : 
     579          49 : static int count_for_all_fn(struct smbXsrv_tcon_global0 *tcon, void *udp)
     580             : {
     581          49 :         union srvsvc_NetShareCtr *ctr = udp;
     582             : 
     583             :         /* Only called for level2 */
     584          49 :         struct srvsvc_NetShareCtr2 *ctr2 = ctr->ctr2;
     585             : 
     586          49 :         uint32_t share_entries = ctr2->count;
     587          49 :         struct srvsvc_NetShareInfo2 *info2 = ctr2->array;
     588          49 :         uint32_t i = 0;
     589             : 
     590        2608 :         for (i = 0; i < share_entries; i++, info2++) {
     591        2598 :                 if (strequal(tcon->share_name, info2->name)) {
     592          39 :                         info2->current_users++;
     593          39 :                         break;
     594             :                 }
     595             :         }
     596             : 
     597          49 :         return 0;
     598             : }
     599             : 
     600             : /****************************************************************************
     601             :  Count the entries belonging to all services in the connection db.
     602             : ****************************************************************************/
     603             : 
     604          13 : static void count_connections_for_all_shares(union srvsvc_NetShareCtr *ctr)
     605             : {
     606             :         NTSTATUS status;
     607          13 :         status = smbXsrv_tcon_global_traverse(count_for_all_fn, ctr);
     608             : 
     609          13 :         if (!NT_STATUS_IS_OK(status)) {
     610           0 :                 DEBUG(0,("count_connections_for_all_shares: traverse of "
     611             :                         "smbXsrv_tcon_global.tdb failed - %s\n",
     612             :                         nt_errstr(status)));
     613             :         }
     614          13 : }
     615             : 
     616             : /*******************************************************************
     617             :  Fill in a share info structure.
     618             :  ********************************************************************/
     619             : 
     620          62 : static WERROR init_srv_share_info_ctr(struct pipes_struct *p,
     621             :                                       struct srvsvc_NetShareInfoCtr *info_ctr,
     622             :                                       uint32_t *resume_handle_p,
     623             :                                       uint32_t *total_entries,
     624             :                                       bool all_shares)
     625             : {
     626          62 :         struct dcesrv_call_state *dce_call = p->dce_call;
     627          35 :         struct auth_session_info *session_info =
     628          27 :                 dcesrv_call_session_info(dce_call);
     629          35 :         const struct loadparm_substitution *lp_sub =
     630          27 :                 loadparm_s3_global_substitution();
     631          62 :         uint32_t num_entries = 0;
     632          62 :         uint32_t alloc_entries = 0;
     633          62 :         int num_services = 0;
     634             :         int snum;
     635          62 :         TALLOC_CTX *ctx = p->mem_ctx;
     636          62 :         uint32_t i = 0;
     637          62 :         uint32_t valid_share_count = 0;
     638          62 :         bool *allowed = 0;
     639             :         union srvsvc_NetShareCtr ctr;
     640          62 :         uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
     641          62 :         const char *unix_name = session_info->unix_info->unix_name;
     642          62 :         int existing_home = -1;
     643          62 :         int added_home = -1;
     644          62 :         WERROR ret = WERR_OK;
     645             : 
     646          62 :         DEBUG(5,("init_srv_share_info_ctr\n"));
     647             : 
     648             :         /*
     649             :          * We need to make sure to reload the services for the connecting user.
     650             :          * It is possible that we have includes with substitutions.
     651             :          *
     652             :          *  include = /etc/samba/%U.conf
     653             :          *
     654             :          * We also need all printers and usershares.
     655             :          *
     656             :          * We need to be root in order to have access to registry shares
     657             :          * and root only smb.conf files.
     658             :          */
     659          62 :         become_root();
     660          62 :         lp_kill_all_services();
     661          62 :         lp_load_with_shares(get_dyn_CONFIGFILE());
     662          62 :         delete_and_reload_printers();
     663          62 :         load_usershare_shares(NULL, connections_snum_used);
     664          62 :         load_registry_shares();
     665          62 :         existing_home = lp_servicenumber(unix_name);
     666          62 :         if (existing_home == -1) {
     667          62 :                 added_home = register_homes_share(unix_name);
     668             :         }
     669          62 :         unbecome_root();
     670             : 
     671          62 :         num_services = lp_numservices();
     672             : 
     673          62 :         allowed = talloc_zero_array(ctx, bool, num_services);
     674          62 :         if (allowed == NULL) {
     675           0 :                 goto nomem;
     676             :         }
     677             : 
     678             :         /* Count the number of entries. */
     679        6377 :         for (snum = 0; snum < num_services; snum++) {
     680       12619 :                 if (lp_browseable(snum) && lp_snum_ok(snum) &&
     681       12551 :                     is_enumeration_allowed(p, snum) &&
     682        1982 :                     (all_shares || !is_hidden_share(snum)) ) {
     683        6211 :                         DEBUG(10, ("counting service %s\n",
     684             :                                 lp_servicename(talloc_tos(), lp_sub, snum) ? lp_servicename(talloc_tos(), lp_sub, snum) : "(null)"));
     685        6211 :                         allowed[snum] = true;
     686        6211 :                         num_entries++;
     687             :                 } else {
     688         104 :                         DEBUG(10, ("NOT counting service %s\n",
     689             :                                 lp_servicename(talloc_tos(), lp_sub, snum) ? lp_servicename(talloc_tos(), lp_sub, snum) : "(null)"));
     690             :                 }
     691             :         }
     692             : 
     693          97 :         if (!num_entries || (resume_handle >= num_entries)) {
     694           0 :                 goto done;
     695             :         }
     696             : 
     697             :         /* Calculate alloc entries. */
     698          62 :         alloc_entries = num_entries - resume_handle;
     699          62 :         switch (info_ctr->level) {
     700           9 :         case 0:
     701           9 :                 ctr.ctr0 = talloc_zero(ctx, struct srvsvc_NetShareCtr0);
     702           9 :                 if (ctr.ctr0 == NULL) {
     703           0 :                         goto nomem;
     704             :                 }
     705             : 
     706           9 :                 ctr.ctr0->count = alloc_entries;
     707           9 :                 ctr.ctr0->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo0, alloc_entries);
     708           9 :                 if (ctr.ctr0->array == NULL) {
     709           0 :                         goto nomem;
     710             :                 }
     711             : 
     712         921 :                 for (snum = 0; snum < num_services; snum++) {
     713        1372 :                         if (allowed[snum] &&
     714         896 :                             (resume_handle <= (i + valid_share_count++)) ) {
     715         896 :                                 init_srv_share_info_0(p, &ctr.ctr0->array[i++], snum);
     716             :                         }
     717             :                 }
     718             : 
     719           9 :                 break;
     720             : 
     721          36 :         case 1:
     722          36 :                 ctr.ctr1 = talloc_zero(ctx, struct srvsvc_NetShareCtr1);
     723          36 :                 if (ctr.ctr1 == NULL) {
     724           0 :                         goto nomem;
     725             :                 }
     726             : 
     727          36 :                 ctr.ctr1->count = alloc_entries;
     728          36 :                 ctr.ctr1->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1, alloc_entries);
     729          36 :                 if (ctr.ctr1->array == NULL) {
     730           0 :                         goto nomem;
     731             :                 }
     732             : 
     733        3809 :                 for (snum = 0; snum < num_services; snum++) {
     734        5803 :                         if (allowed[snum] &&
     735        3721 :                             (resume_handle <= (i + valid_share_count++)) ) {
     736        3721 :                                 init_srv_share_info_1(p, &ctr.ctr1->array[i++], snum);
     737             :                         }
     738             :                 }
     739             : 
     740          36 :                 break;
     741             : 
     742          13 :         case 2:
     743          13 :                 ctr.ctr2 = talloc_zero(ctx, struct srvsvc_NetShareCtr2);
     744          13 :                 if (ctr.ctr2 == NULL) {
     745           0 :                         goto nomem;
     746             :                 }
     747             : 
     748          13 :                 ctr.ctr2->count = alloc_entries;
     749          13 :                 ctr.ctr2->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo2, alloc_entries);
     750          13 :                 if (ctr.ctr2->array == NULL) {
     751           0 :                         goto nomem;
     752             :                 }
     753             : 
     754        1373 :                 for (snum = 0; snum < num_services; snum++) {
     755        2037 :                         if (allowed[snum] &&
     756        1330 :                             (resume_handle <= (i + valid_share_count++)) ) {
     757        1330 :                                 init_srv_share_info_2(p, &ctr.ctr2->array[i++], snum);
     758             :                         }
     759             :                 }
     760             : 
     761          13 :                 count_connections_for_all_shares(&ctr);
     762          13 :                 break;
     763             : 
     764           3 :         case 501:
     765           3 :                 ctr.ctr501 = talloc_zero(ctx, struct srvsvc_NetShareCtr501);
     766           3 :                 if (ctr.ctr501 == NULL) {
     767           0 :                         goto nomem;
     768             :                 }
     769             : 
     770           3 :                 ctr.ctr501->count = alloc_entries;
     771           3 :                 ctr.ctr501->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo501, alloc_entries);
     772           3 :                 if (ctr.ctr501->array == NULL) {
     773           0 :                         goto nomem;
     774             :                 }
     775             : 
     776         249 :                 for (snum = 0; snum < num_services; snum++) {
     777         378 :                         if (allowed[snum] &&
     778         240 :                             (resume_handle <= (i + valid_share_count++)) ) {
     779         240 :                                 init_srv_share_info_501(p, &ctr.ctr501->array[i++], snum);
     780             :                         }
     781             :                 }
     782             : 
     783           3 :                 break;
     784             : 
     785           1 :         case 502:
     786           1 :                 ctr.ctr502 = talloc_zero(ctx, struct srvsvc_NetShareCtr502);
     787           1 :                 if (ctr.ctr502 == NULL) {
     788           0 :                         goto nomem;
     789             :                 }
     790             : 
     791           1 :                 ctr.ctr502->count = alloc_entries;
     792           1 :                 ctr.ctr502->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo502, alloc_entries);
     793           1 :                 if (ctr.ctr502->array == NULL) {
     794           0 :                         goto nomem;
     795             :                 }
     796             : 
     797          25 :                 for (snum = 0; snum < num_services; snum++) {
     798          48 :                         if (allowed[snum] &&
     799          24 :                             (resume_handle <= (i + valid_share_count++)) ) {
     800          24 :                                 init_srv_share_info_502(p, &ctr.ctr502->array[i++], snum);
     801             :                         }
     802             :                 }
     803             : 
     804           1 :                 break;
     805             : 
     806           0 :         case 1004:
     807           0 :                 ctr.ctr1004 = talloc_zero(ctx, struct srvsvc_NetShareCtr1004);
     808           0 :                 if (ctr.ctr1004 == NULL) {
     809           0 :                         goto nomem;
     810             :                 }
     811             : 
     812           0 :                 ctr.ctr1004->count = alloc_entries;
     813           0 :                 ctr.ctr1004->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1004, alloc_entries);
     814           0 :                 if (ctr.ctr1004->array == NULL) {
     815           0 :                         goto nomem;
     816             :                 }
     817             : 
     818           0 :                 for (snum = 0; snum < num_services; snum++) {
     819           0 :                         if (allowed[snum] &&
     820           0 :                             (resume_handle <= (i + valid_share_count++)) ) {
     821           0 :                                 init_srv_share_info_1004(p, &ctr.ctr1004->array[i++], snum);
     822             :                         }
     823             :                 }
     824             : 
     825           0 :                 break;
     826             : 
     827           0 :         case 1005:
     828           0 :                 ctr.ctr1005 = talloc_zero(ctx, struct srvsvc_NetShareCtr1005);
     829           0 :                 if (ctr.ctr1005 == NULL) {
     830           0 :                         goto nomem;
     831             :                 }
     832             : 
     833           0 :                 ctr.ctr1005->count = alloc_entries;
     834           0 :                 ctr.ctr1005->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1005, alloc_entries);
     835           0 :                 if (ctr.ctr1005->array == NULL) {
     836           0 :                         goto nomem;
     837             :                 }
     838             : 
     839           0 :                 for (snum = 0; snum < num_services; snum++) {
     840           0 :                         if (allowed[snum] &&
     841           0 :                             (resume_handle <= (i + valid_share_count++)) ) {
     842           0 :                                 init_srv_share_info_1005(p, &ctr.ctr1005->array[i++], snum);
     843             :                         }
     844             :                 }
     845             : 
     846           0 :                 break;
     847             : 
     848           0 :         case 1006:
     849           0 :                 ctr.ctr1006 = talloc_zero(ctx, struct srvsvc_NetShareCtr1006);
     850           0 :                 if (ctr.ctr1006 == NULL) {
     851           0 :                         goto nomem;
     852             :                 }
     853             : 
     854           0 :                 ctr.ctr1006->count = alloc_entries;
     855           0 :                 ctr.ctr1006->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1006, alloc_entries);
     856           0 :                 if (ctr.ctr1006->array == NULL) {
     857           0 :                         goto nomem;
     858             :                 }
     859             : 
     860           0 :                 for (snum = 0; snum < num_services; snum++) {
     861           0 :                         if (allowed[snum] &&
     862           0 :                             (resume_handle <= (i + valid_share_count++)) ) {
     863           0 :                                 init_srv_share_info_1006(p, &ctr.ctr1006->array[i++], snum);
     864             :                         }
     865             :                 }
     866             : 
     867           0 :                 break;
     868             : 
     869           0 :         case 1007:
     870           0 :                 ctr.ctr1007 = talloc_zero(ctx, struct srvsvc_NetShareCtr1007);
     871           0 :                 if (ctr.ctr1007 == NULL) {
     872           0 :                         goto nomem;
     873             :                 }
     874             : 
     875           0 :                 ctr.ctr1007->count = alloc_entries;
     876           0 :                 ctr.ctr1007->array = talloc_zero_array(ctx, struct srvsvc_NetShareInfo1007, alloc_entries);
     877           0 :                 if (ctr.ctr1007->array == NULL) {
     878           0 :                         goto nomem;
     879             :                 }
     880             : 
     881           0 :                 for (snum = 0; snum < num_services; snum++) {
     882           0 :                         if (allowed[snum] &&
     883           0 :                             (resume_handle <= (i + valid_share_count++)) ) {
     884           0 :                                 init_srv_share_info_1007(p, &ctr.ctr1007->array[i++], snum);
     885             :                         }
     886             :                 }
     887             : 
     888           0 :                 break;
     889             : 
     890           0 :         case 1501:
     891           0 :                 ctr.ctr1501 = talloc_zero(ctx, struct srvsvc_NetShareCtr1501);
     892           0 :                 if (ctr.ctr1501 == NULL) {
     893           0 :                         goto nomem;
     894             :                 }
     895             : 
     896           0 :                 ctr.ctr1501->count = alloc_entries;
     897           0 :                 ctr.ctr1501->array = talloc_zero_array(ctx, struct sec_desc_buf, alloc_entries);
     898           0 :                 if (ctr.ctr1501->array == NULL) {
     899           0 :                         goto nomem;
     900             :                 }
     901             : 
     902           0 :                 for (snum = 0; snum < num_services; snum++) {
     903           0 :                         if (allowed[snum] &&
     904           0 :                             (resume_handle <= (i + valid_share_count++)) ) {
     905           0 :                                 struct sec_desc_buf *sd_buf = NULL;
     906           0 :                                 init_srv_share_info_1501(p, &sd_buf, snum);
     907           0 :                                 ctr.ctr1501->array[i++] = *sd_buf;
     908             :                         }
     909             :                 }
     910             : 
     911           0 :                 break;
     912             : 
     913           0 :         default:
     914           0 :                 DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n",
     915             :                         info_ctr->level));
     916           0 :                 ret = WERR_INVALID_LEVEL;
     917           0 :                 goto done;
     918             :         }
     919             : 
     920          62 :         *total_entries = alloc_entries;
     921          62 :         if (resume_handle_p) {
     922          44 :                 if (all_shares) {
     923          44 :                         *resume_handle_p = (num_entries == 0) ? *resume_handle_p : 0;
     924             :                 } else {
     925           0 :                         *resume_handle_p = num_entries;
     926             :                 }
     927             :         }
     928             : 
     929          62 :         info_ctr->ctr = ctr;
     930          62 :         ret = WERR_OK;
     931          62 :         goto done;
     932           0 : nomem:
     933           0 :         ret = WERR_NOT_ENOUGH_MEMORY;
     934          62 : done:
     935          62 :         if (added_home != -1) {
     936           1 :                 lp_killservice(added_home);
     937             :         }
     938          62 :         return ret;
     939             : }
     940             : 
     941             : /*******************************************************************
     942             :  fill in a sess info level 0 structure.
     943             :  ********************************************************************/
     944             : 
     945           2 : static WERROR init_srv_sess_info_0(struct pipes_struct *p,
     946             :                                    struct srvsvc_NetSessCtr0 *ctr0,
     947             :                                    uint32_t *resume_handle_p,
     948             :                                    uint32_t *total_entries)
     949             : {
     950             :         struct sessionid *session_list;
     951           2 :         uint32_t num_entries = 0;
     952           2 :         uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
     953           2 :         *total_entries = list_sessions(p->mem_ctx, &session_list);
     954             : 
     955           2 :         DEBUG(5,("init_srv_sess_info_0\n"));
     956             : 
     957           2 :         if (ctr0 == NULL) {
     958           0 :                 if (resume_handle_p) {
     959           0 :                         *resume_handle_p = 0;
     960             :                 }
     961           0 :                 return WERR_OK;
     962             :         }
     963             : 
     964           4 :         for (; resume_handle < *total_entries; resume_handle++) {
     965             : 
     966           2 :                 ctr0->array = talloc_realloc(p->mem_ctx,
     967             :                                                    ctr0->array,
     968             :                                                    struct srvsvc_NetSessInfo0,
     969             :                                                    num_entries+1);
     970           2 :                 W_ERROR_HAVE_NO_MEMORY(ctr0->array);
     971             : 
     972           3 :                 ctr0->array[num_entries].client =
     973           3 :                         session_list[resume_handle].remote_machine;
     974             : 
     975           2 :                 num_entries++;
     976             :         }
     977             : 
     978           2 :         ctr0->count = num_entries;
     979             : 
     980           2 :         if (resume_handle_p) {
     981           0 :                 if (*resume_handle_p >= *total_entries) {
     982           0 :                         *resume_handle_p = 0;
     983             :                 } else {
     984           0 :                         *resume_handle_p = resume_handle;
     985             :                 }
     986             :         }
     987             : 
     988           2 :         return WERR_OK;
     989             : }
     990             : 
     991             : /***********************************************************************
     992             :  * find out the session on which this file is open and bump up its count
     993             :  **********************************************************************/
     994             : 
     995           0 : static int count_sess_files_fn(struct file_id fid,
     996             :                                const struct share_mode_data *d,
     997             :                                const struct share_mode_entry *e,
     998             :                                void *data)
     999             : {
    1000           0 :         struct sess_file_info *info = data;
    1001           0 :         uint32_t rh = info->resume_handle;
    1002             :         uint32_t i;
    1003             : 
    1004           0 :         for (i=0; i < info->num_entries; i++) {
    1005             :                 /* rh+info->num_entries is safe, as we've
    1006             :                    ensured that:
    1007             :                    *total_entries > resume_handle &&
    1008             :                    info->num_entries = *total_entries - resume_handle;
    1009             :                    inside init_srv_sess_info_1() below.
    1010             :                 */
    1011           0 :                 struct sessionid *sess = &info->session_list[rh + i];
    1012           0 :                 if ((e->uid == sess->uid) &&
    1013           0 :                      server_id_equal(&e->pid, &sess->pid)) {
    1014             : 
    1015           0 :                         info->ctr->array[i].num_open++;
    1016           0 :                         return 0;
    1017             :                 }
    1018             :         }
    1019           0 :         return 0;
    1020             : }
    1021             : 
    1022             : /*******************************************************************
    1023             :  * count the num of open files on all sessions
    1024             :  *******************************************************************/
    1025             : 
    1026           8 : static void net_count_files_for_all_sess(struct srvsvc_NetSessCtr1 *ctr1,
    1027             :                                          struct sessionid *session_list,
    1028             :                                          uint32_t resume_handle,
    1029             :                                          uint32_t num_entries)
    1030             : {
    1031             :         struct sess_file_info s_file_info;
    1032             : 
    1033           8 :         s_file_info.ctr = ctr1;
    1034           8 :         s_file_info.session_list = session_list;
    1035           8 :         s_file_info.resume_handle = resume_handle;
    1036           8 :         s_file_info.num_entries = num_entries;
    1037             : 
    1038           8 :         share_entry_forall(count_sess_files_fn, &s_file_info);
    1039           8 : }
    1040             : 
    1041             : /*******************************************************************
    1042             :  fill in a sess info level 1 structure.
    1043             :  ********************************************************************/
    1044             : 
    1045           8 : static WERROR init_srv_sess_info_1(struct pipes_struct *p,
    1046             :                                    struct srvsvc_NetSessCtr1 *ctr1,
    1047             :                                    uint32_t *resume_handle_p,
    1048             :                                    uint32_t *total_entries)
    1049             : {
    1050             :         struct sessionid *session_list;
    1051           8 :         uint32_t num_entries = 0;
    1052           8 :         time_t now = time(NULL);
    1053           8 :         uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
    1054             : 
    1055           8 :         ZERO_STRUCTP(ctr1);
    1056             : 
    1057           8 :         if (ctr1 == NULL) {
    1058           0 :                 if (resume_handle_p) {
    1059           0 :                         *resume_handle_p = 0;
    1060             :                 }
    1061           0 :                 return WERR_OK;
    1062             :         }
    1063             : 
    1064           8 :         *total_entries = list_sessions(p->mem_ctx, &session_list);
    1065             : 
    1066           8 :         if (resume_handle >= *total_entries) {
    1067           0 :                 if (resume_handle_p) {
    1068           0 :                         *resume_handle_p = 0;
    1069             :                 }
    1070           0 :                 return WERR_OK;
    1071             :         }
    1072             : 
    1073             :         /* We know num_entries must be positive, due to
    1074             :            the check resume_handle >= *total_entries above. */
    1075             : 
    1076           8 :         num_entries = *total_entries - resume_handle;
    1077             : 
    1078           8 :         ctr1->array = talloc_zero_array(p->mem_ctx,
    1079             :                                    struct srvsvc_NetSessInfo1,
    1080             :                                    num_entries);
    1081             : 
    1082           8 :         W_ERROR_HAVE_NO_MEMORY(ctr1->array);
    1083             : 
    1084          16 :         for (num_entries = 0; resume_handle < *total_entries; num_entries++, resume_handle++) {
    1085             :                 uint32_t connect_time;
    1086             :                 bool guest;
    1087             : 
    1088           8 :                 connect_time = (uint32_t)(now - session_list[resume_handle].connect_start);
    1089           8 :                 guest = strequal( session_list[resume_handle].username, lp_guest_account() );
    1090             : 
    1091           8 :                 ctr1->array[num_entries].client              = session_list[resume_handle].remote_machine;
    1092           8 :                 ctr1->array[num_entries].user                = session_list[resume_handle].username;
    1093           8 :                 ctr1->array[num_entries].num_open    = 0;/* computed later */
    1094           8 :                 ctr1->array[num_entries].time                = connect_time;
    1095           8 :                 ctr1->array[num_entries].idle_time   = 0;
    1096           8 :                 ctr1->array[num_entries].user_flags  = guest;
    1097             :         }
    1098             : 
    1099           8 :         ctr1->count = num_entries;
    1100             : 
    1101             :         /* count open files on all sessions in single tdb traversal */
    1102           8 :         net_count_files_for_all_sess(ctr1, session_list,
    1103             :                                      resume_handle_p ? *resume_handle_p : 0,
    1104             :                                      num_entries);
    1105             : 
    1106           8 :         if (resume_handle_p) {
    1107           0 :                 if (*resume_handle_p >= *total_entries) {
    1108           0 :                         *resume_handle_p = 0;
    1109             :                 } else {
    1110           0 :                         *resume_handle_p = resume_handle;
    1111             :                 }
    1112             :         }
    1113             : 
    1114           8 :         return WERR_OK;
    1115             : }
    1116             : 
    1117             : /*******************************************************************
    1118             :  find the share connection on which this open exists.
    1119             :  ********************************************************************/
    1120             : 
    1121           0 : static int share_file_fn(struct file_id fid,
    1122             :                          const struct share_mode_data *d,
    1123             :                          const struct share_mode_entry *e,
    1124             :                          void *data)
    1125             : {
    1126           0 :         struct share_file_stat *sfs = data;
    1127             :         uint32_t i;
    1128           0 :         uint32_t offset = sfs->total_entries - sfs->resp_entries;
    1129             : 
    1130           0 :         if (strequal(d->servicepath, sfs->in_sharepath)) {
    1131           0 :                 for (i=0; i < sfs->resp_entries; i++) {
    1132           0 :                         if (server_id_equal(
    1133           0 :                                     &e->pid, &sfs->svrid_arr[offset + i])) {
    1134           0 :                                 sfs->netconn_arr[i].num_open ++;
    1135           0 :                                 return 0;
    1136             :                         }
    1137             :                 }
    1138             :         }
    1139           0 :         return 0;
    1140             : }
    1141             : 
    1142             : /*******************************************************************
    1143             :  count number of open files on given share connections.
    1144             :  ********************************************************************/
    1145             : 
    1146           2 : static void count_share_opens(struct srvsvc_NetConnInfo1 *arr,
    1147             :                               struct server_id *svrid_arr, char *sharepath,
    1148             :                               uint32_t resp_entries, uint32_t total_entries)
    1149             : {
    1150             :         struct share_file_stat sfs;
    1151             : 
    1152           2 :         sfs.netconn_arr = arr;
    1153           2 :         sfs.svrid_arr = svrid_arr;
    1154           2 :         sfs.in_sharepath = sharepath;
    1155           2 :         sfs.resp_entries = resp_entries;
    1156           2 :         sfs.total_entries = total_entries;
    1157             : 
    1158           2 :         share_entry_forall(share_file_fn, &sfs);
    1159           2 : }
    1160             : 
    1161             : /****************************************************************************
    1162             :  process an entry from the connection db.
    1163             : ****************************************************************************/
    1164             : 
    1165          10 : static int share_conn_fn(struct smbXsrv_tcon_global0 *tcon,
    1166             :                           void *data)
    1167             : {
    1168          10 :         struct share_conn_stat *scs = data;
    1169             : 
    1170          10 :         if (!process_exists(tcon->server_id)) {
    1171           8 :                 return 0;
    1172             :         }
    1173             : 
    1174           2 :         if (strequal(tcon->share_name, scs->sharename)) {
    1175           2 :                 scs->svrid_arr = talloc_realloc(scs->ctx, scs->svrid_arr,
    1176             :                                                 struct server_id,
    1177             :                                                 scs->count + 1);
    1178           2 :                 if (!scs->svrid_arr) {
    1179           0 :                         return 0;
    1180             :                 }
    1181             : 
    1182           2 :                 scs->svrid_arr[scs->count] = tcon->server_id;
    1183           2 :                 scs->count++;
    1184             :         }
    1185             : 
    1186           2 :         return 0;
    1187             : }
    1188             : 
    1189             : /****************************************************************************
    1190             :  Count the connections to a share. Build an array of serverid's owning these
    1191             :  connections.
    1192             : ****************************************************************************/
    1193             : 
    1194           2 : static uint32_t count_share_conns(TALLOC_CTX *ctx, const char *sharename,
    1195             :                                   struct server_id **arr)
    1196             : {
    1197             :         struct share_conn_stat scs;
    1198             :         NTSTATUS status;
    1199             : 
    1200           2 :         scs.ctx = ctx;
    1201           2 :         scs.sharename = sharename;
    1202           2 :         scs.svrid_arr = NULL;
    1203           2 :         scs.count = 0;
    1204             : 
    1205           2 :         status = smbXsrv_tcon_global_traverse(share_conn_fn, &scs);
    1206             : 
    1207           2 :         if (!NT_STATUS_IS_OK(status)) {
    1208           0 :                 DEBUG(0,("count_share_conns: traverse of "
    1209             :                          "smbXsrv_tcon_global.tdb failed - %s\n",
    1210             :                          nt_errstr(status)));
    1211           0 :                 return 0;
    1212             :         }
    1213             : 
    1214           2 :         *arr = scs.svrid_arr;
    1215           2 :         return scs.count;
    1216             : }
    1217             : 
    1218             : /*******************************************************************
    1219             :  fill in a conn info level 0 structure.
    1220             :  ********************************************************************/
    1221             : 
    1222           2 : static WERROR init_srv_conn_info_0(struct srvsvc_NetConnCtr0 *ctr0,
    1223             :                                    uint32_t *resume_handle_p,
    1224             :                                    uint32_t *total_entries)
    1225             : {
    1226           2 :         uint32_t num_entries = 0;
    1227           2 :         uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
    1228             : 
    1229           2 :         DEBUG(5,("init_srv_conn_info_0\n"));
    1230             : 
    1231           2 :         if (ctr0 == NULL) {
    1232           0 :                 if (resume_handle_p) {
    1233           0 :                         *resume_handle_p = 0;
    1234             :                 }
    1235           0 :                 return WERR_OK;
    1236             :         }
    1237             : 
    1238           2 :         *total_entries = 1;
    1239             : 
    1240           2 :         ZERO_STRUCTP(ctr0);
    1241             : 
    1242           4 :         for (; resume_handle < *total_entries; resume_handle++) {
    1243             : 
    1244           2 :                 ctr0->array = talloc_realloc(talloc_tos(),
    1245             :                                                    ctr0->array,
    1246             :                                                    struct srvsvc_NetConnInfo0,
    1247             :                                                    num_entries+1);
    1248           2 :                 if (!ctr0->array) {
    1249           0 :                         return WERR_NOT_ENOUGH_MEMORY;
    1250             :                 }
    1251             : 
    1252           2 :                 ctr0->array[num_entries].conn_id = *total_entries;
    1253             : 
    1254             :                 /* move on to creating next connection */
    1255           2 :                 num_entries++;
    1256             :         }
    1257             : 
    1258           2 :         ctr0->count = num_entries;
    1259           2 :         *total_entries = num_entries;
    1260             : 
    1261           2 :         if (resume_handle_p) {
    1262           0 :                 if (*resume_handle_p >= *total_entries) {
    1263           0 :                         *resume_handle_p = 0;
    1264             :                 } else {
    1265           0 :                         *resume_handle_p = resume_handle;
    1266             :                 }
    1267             :         }
    1268             : 
    1269           2 :         return WERR_OK;
    1270             : }
    1271             : 
    1272             : /*******************************************************************
    1273             :  fill in a conn info level 1 structure.
    1274             :  ********************************************************************/
    1275             : 
    1276           2 : static WERROR init_srv_conn_info_1(const char *name,
    1277             :                                    struct srvsvc_NetConnCtr1 *ctr1,
    1278             :                                    uint32_t *resume_handle_p,
    1279             :                                    uint32_t *total_entries)
    1280             : {
    1281           1 :         const struct loadparm_substitution *lp_sub =
    1282           1 :                 loadparm_s3_global_substitution();
    1283           2 :         uint32_t num_entries = 0;
    1284           2 :         int snum = 0;
    1285           2 :         uint32_t resume_handle = resume_handle_p ? *resume_handle_p : 0;
    1286           2 :         char *share_name = NULL;
    1287           2 :         struct server_id *svrid_arr = NULL;
    1288             : 
    1289           2 :         DEBUG(5,("init_srv_conn_info_1\n"));
    1290             : 
    1291           2 :         if (ctr1 == NULL) {
    1292           0 :                 if (resume_handle_p) {
    1293           0 :                         *resume_handle_p = 0;
    1294             :                 }
    1295           0 :                 return WERR_OK;
    1296             :         }
    1297             : 
    1298             :         /* check if this is a server name or a share name */
    1299           2 :         if (name && (strlen(name) > 2)  && (name[0] == '\\') &&
    1300           0 :                         (name[1] == '\\')) {
    1301             : 
    1302             :                 /* 'name' is a server name - this part is unimplemented */
    1303           0 :                 *total_entries = 1;
    1304             :         } else {
    1305             :                  /* 'name' is a share name */
    1306           2 :                 snum = find_service(talloc_tos(), name, &share_name);
    1307             : 
    1308           2 :                 if (!share_name) {
    1309           0 :                         return WERR_NOT_ENOUGH_MEMORY;
    1310             :                 }
    1311             : 
    1312           2 :                 if (snum < 0) {
    1313           0 :                         return WERR_INVALID_NAME;
    1314             :                 }
    1315             : 
    1316             :                 /*
    1317             :                  * count the num of connections to this share. Also,
    1318             :                  * build a list of serverid's that own these
    1319             :                  * connections. The serverid list is used later to
    1320             :                  * identify the share connection on which an open exists.
    1321             :                  */
    1322             : 
    1323           2 :                 *total_entries = count_share_conns(talloc_tos(),
    1324             :                                                    share_name,
    1325             :                                                    &svrid_arr);
    1326             :         }
    1327             : 
    1328           2 :         if (resume_handle >= *total_entries) {
    1329           0 :                 if (resume_handle_p) {
    1330           0 :                         *resume_handle_p = 0;
    1331             :                 }
    1332           0 :                 return WERR_OK;
    1333             :         }
    1334             : 
    1335             :         /*
    1336             :          * We know num_entries must be positive, due to
    1337             :          * the check resume_handle >= *total_entries above.
    1338             :          */
    1339             : 
    1340           2 :         num_entries = *total_entries - resume_handle;
    1341             : 
    1342           2 :         ZERO_STRUCTP(ctr1);
    1343             : 
    1344           2 :         ctr1->array = talloc_zero_array(talloc_tos(),
    1345             :                                         struct srvsvc_NetConnInfo1,
    1346             :                                         num_entries);
    1347             : 
    1348           2 :         W_ERROR_HAVE_NO_MEMORY(ctr1->array);
    1349             : 
    1350           5 :         for (num_entries = 0; resume_handle < *total_entries;
    1351           2 :                 num_entries++, resume_handle++) {
    1352             : 
    1353           2 :                 ctr1->array[num_entries].conn_id     = *total_entries;
    1354           2 :                 ctr1->array[num_entries].conn_type   = 0x3;
    1355             : 
    1356             :                 /*
    1357             :                  * if these are connections to a share, we are going to
    1358             :                  * compute the opens on them later. If it's for the server,
    1359             :                  * it's unimplemented.
    1360             :                  */
    1361             : 
    1362           2 :                 if (!share_name) {
    1363           0 :                         ctr1->array[num_entries].num_open = 1;
    1364             :                 }
    1365             : 
    1366           2 :                 ctr1->array[num_entries].num_users   = 1;
    1367           2 :                 ctr1->array[num_entries].conn_time   = 3;
    1368           2 :                 ctr1->array[num_entries].user                = "dummy_user";
    1369           2 :                 ctr1->array[num_entries].share               = "IPC$";
    1370             :         }
    1371             : 
    1372             :         /* now compute open files on the share connections */
    1373             : 
    1374           2 :         if (share_name) {
    1375             : 
    1376             :                 /*
    1377             :                  * the locking tdb, which has the open files information,
    1378             :                  * does not store share name or share (service) number, but
    1379             :                  * just the share path. So, we can compute open files only
    1380             :                  * on the share path. If more than one shares are  defined
    1381             :                  * on a share path, open files on all of them are included
    1382             :                  * in the count.
    1383             :                  *
    1384             :                  * To have the correct behavior in case multiple shares
    1385             :                  * are defined on the same path, changes to tdb records
    1386             :                  * would be required. That would be lot more effort, so
    1387             :                  * this seems a good stopgap fix.
    1388             :                  */
    1389             : 
    1390           2 :                 count_share_opens(ctr1->array, svrid_arr,
    1391             :                                   lp_path(talloc_tos(), lp_sub, snum),
    1392             :                                   num_entries, *total_entries);
    1393             : 
    1394             :         }
    1395             : 
    1396           2 :         ctr1->count = num_entries;
    1397           2 :         *total_entries = num_entries;
    1398             : 
    1399           2 :         if (resume_handle_p) {
    1400           0 :                 *resume_handle_p = resume_handle;
    1401             :         }
    1402             : 
    1403           2 :         return WERR_OK;
    1404             : }
    1405             : 
    1406             : /*******************************************************************
    1407             :  _srvsvc_NetFileEnum
    1408             : *******************************************************************/
    1409             : 
    1410           4 : WERROR _srvsvc_NetFileEnum(struct pipes_struct *p,
    1411             :                            struct srvsvc_NetFileEnum *r)
    1412             : {
    1413           4 :         struct dcesrv_call_state *dce_call = p->dce_call;
    1414           2 :         struct auth_session_info *session_info =
    1415           2 :                 dcesrv_call_session_info(dce_call);
    1416           4 :         TALLOC_CTX *ctx = NULL;
    1417             :         struct srvsvc_NetFileCtr3 *ctr3;
    1418           4 :         uint32_t resume_hnd = 0;
    1419             :         WERROR werr;
    1420             : 
    1421           4 :         switch (r->in.info_ctr->level) {
    1422           2 :         case 3:
    1423           2 :                 break;
    1424           2 :         default:
    1425           2 :                 return WERR_INVALID_LEVEL;
    1426             :         }
    1427             : 
    1428           2 :         if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
    1429           2 :                                 session_info->security_token)) {
    1430           0 :                 DEBUG(1, ("Enumerating files only allowed for "
    1431             :                           "administrators\n"));
    1432           0 :                 return WERR_ACCESS_DENIED;
    1433             :         }
    1434             : 
    1435           2 :         ctx = talloc_tos();
    1436           2 :         ctr3 = r->in.info_ctr->ctr.ctr3;
    1437           2 :         if (!ctr3) {
    1438           0 :                 werr = WERR_INVALID_PARAMETER;
    1439           0 :                 goto done;
    1440             :         }
    1441             : 
    1442             :         /* TODO -- Windows enumerates
    1443             :            (b) active pipes
    1444             :            (c) open directories and files */
    1445             : 
    1446           2 :         werr = net_enum_files(ctx, r->in.user, &ctr3, resume_hnd);
    1447           2 :         if (!W_ERROR_IS_OK(werr)) {
    1448           0 :                 goto done;
    1449             :         }
    1450             : 
    1451           2 :         *r->out.totalentries = ctr3->count;
    1452           2 :         r->out.info_ctr->ctr.ctr3->array = ctr3->array;
    1453           2 :         r->out.info_ctr->ctr.ctr3->count = ctr3->count;
    1454             : 
    1455           2 :         werr = WERR_OK;
    1456             : 
    1457           2 :  done:
    1458           2 :         return werr;
    1459             : }
    1460             : 
    1461             : /*******************************************************************
    1462             :  _srvsvc_NetSrvGetInfo
    1463             : ********************************************************************/
    1464             : 
    1465          10 : WERROR _srvsvc_NetSrvGetInfo(struct pipes_struct *p,
    1466             :                              struct srvsvc_NetSrvGetInfo *r)
    1467             : {
    1468           5 :         const struct loadparm_substitution *lp_sub =
    1469           5 :                 loadparm_s3_global_substitution();
    1470          10 :         WERROR status = WERR_OK;
    1471             : 
    1472          10 :         DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
    1473             : 
    1474          10 :         if (!pipe_access_check(p)) {
    1475           0 :                 DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n"));
    1476           0 :                 return WERR_ACCESS_DENIED;
    1477             :         }
    1478             : 
    1479          10 :         switch (r->in.level) {
    1480             : 
    1481             :                 /* Technically level 102 should only be available to
    1482             :                    Administrators but there isn't anything super-secret
    1483             :                    here, as most of it is made up. */
    1484             : 
    1485           2 :         case 102: {
    1486             :                 struct srvsvc_NetSrvInfo102 *info102;
    1487             : 
    1488           2 :                 info102 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo102);
    1489           2 :                 if (!info102) {
    1490           0 :                         return WERR_NOT_ENOUGH_MEMORY;
    1491             :                 }
    1492             : 
    1493           2 :                 info102->platform_id = PLATFORM_ID_NT;
    1494           2 :                 info102->server_name = lp_netbios_name();
    1495           2 :                 info102->version_major       = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
    1496           2 :                 info102->version_minor       = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
    1497           2 :                 info102->server_type = lp_default_server_announce();
    1498           2 :                 info102->comment     = string_truncate(lp_server_string(talloc_tos(), lp_sub),
    1499             :                                                 MAX_SERVER_STRING_LENGTH);
    1500           2 :                 info102->users               = 0xffffffff;
    1501           2 :                 info102->disc                = 0xf;
    1502           2 :                 info102->hidden              = 0;
    1503           2 :                 info102->announce    = 240;
    1504           2 :                 info102->anndelta    = 3000;
    1505           2 :                 info102->licenses    = 100000;
    1506           2 :                 info102->userpath    = "C:\\";
    1507             : 
    1508           2 :                 r->out.info->info102 = info102;
    1509           2 :                 break;
    1510             :         }
    1511           2 :         case 101: {
    1512             :                 struct srvsvc_NetSrvInfo101 *info101;
    1513             : 
    1514           2 :                 info101 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo101);
    1515           2 :                 if (!info101) {
    1516           0 :                         return WERR_NOT_ENOUGH_MEMORY;
    1517             :                 }
    1518             : 
    1519           2 :                 info101->platform_id = PLATFORM_ID_NT;
    1520           2 :                 info101->server_name = lp_netbios_name();
    1521           2 :                 info101->version_major       = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
    1522           2 :                 info101->version_minor       = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
    1523           2 :                 info101->server_type = lp_default_server_announce();
    1524           2 :                 info101->comment     = string_truncate(lp_server_string(talloc_tos(), lp_sub),
    1525             :                                                 MAX_SERVER_STRING_LENGTH);
    1526             : 
    1527           2 :                 r->out.info->info101 = info101;
    1528           2 :                 break;
    1529             :         }
    1530           2 :         case 100: {
    1531             :                 struct srvsvc_NetSrvInfo100 *info100;
    1532             : 
    1533           2 :                 info100 = talloc(p->mem_ctx, struct srvsvc_NetSrvInfo100);
    1534           2 :                 if (!info100) {
    1535           0 :                         return WERR_NOT_ENOUGH_MEMORY;
    1536             :                 }
    1537             : 
    1538           2 :                 info100->platform_id = PLATFORM_ID_NT;
    1539           2 :                 info100->server_name = lp_netbios_name();
    1540             : 
    1541           2 :                 r->out.info->info100 = info100;
    1542             : 
    1543           2 :                 break;
    1544             :         }
    1545           4 :         default:
    1546           4 :                 status = WERR_INVALID_LEVEL;
    1547           4 :                 break;
    1548             :         }
    1549             : 
    1550          10 :         DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__));
    1551             : 
    1552          10 :         return status;
    1553             : }
    1554             : 
    1555             : /*******************************************************************
    1556             :  _srvsvc_NetSrvSetInfo
    1557             : ********************************************************************/
    1558             : 
    1559           0 : WERROR _srvsvc_NetSrvSetInfo(struct pipes_struct *p,
    1560             :                              struct srvsvc_NetSrvSetInfo *r)
    1561             : {
    1562           0 :         WERROR status = WERR_OK;
    1563             : 
    1564           0 :         DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
    1565             : 
    1566             :         /* Set up the net server set info structure. */
    1567             : 
    1568           0 :         DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__));
    1569             : 
    1570           0 :         return status;
    1571             : }
    1572             : 
    1573             : /*******************************************************************
    1574             :  _srvsvc_NetConnEnum
    1575             : ********************************************************************/
    1576             : 
    1577           4 : WERROR _srvsvc_NetConnEnum(struct pipes_struct *p,
    1578             :                            struct srvsvc_NetConnEnum *r)
    1579             : {
    1580           4 :         struct dcesrv_call_state *dce_call = p->dce_call;
    1581           2 :         struct auth_session_info *session_info =
    1582           2 :                 dcesrv_call_session_info(dce_call);
    1583             :         WERROR werr;
    1584             : 
    1585           4 :         DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
    1586             : 
    1587           4 :         if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
    1588           4 :                                 session_info->security_token)) {
    1589           0 :                 DEBUG(1, ("Enumerating connections only allowed for "
    1590             :                           "administrators\n"));
    1591           0 :                 return WERR_ACCESS_DENIED;
    1592             :         }
    1593             : 
    1594           4 :         switch (r->in.info_ctr->level) {
    1595           2 :                 case 0:
    1596           2 :                         werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
    1597             :                                                     r->in.resume_handle,
    1598             :                                                     r->out.totalentries);
    1599           2 :                         break;
    1600           2 :                 case 1:
    1601           3 :                         werr = init_srv_conn_info_1(r->in.path,
    1602           2 :                                                     r->in.info_ctr->ctr.ctr1,
    1603             :                                                     r->in.resume_handle,
    1604             :                                                     r->out.totalentries);
    1605           2 :                         break;
    1606           0 :                 default:
    1607           0 :                         return WERR_INVALID_LEVEL;
    1608             :         }
    1609             : 
    1610           4 :         DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
    1611             : 
    1612           4 :         return werr;
    1613             : }
    1614             : 
    1615             : /*******************************************************************
    1616             :  _srvsvc_NetSessEnum
    1617             : ********************************************************************/
    1618             : 
    1619          16 : WERROR _srvsvc_NetSessEnum(struct pipes_struct *p,
    1620             :                            struct srvsvc_NetSessEnum *r)
    1621             : {
    1622          16 :         struct dcesrv_call_state *dce_call = p->dce_call;
    1623           8 :         struct auth_session_info *session_info =
    1624           8 :                 dcesrv_call_session_info(dce_call);
    1625             :         WERROR werr;
    1626             : 
    1627          16 :         DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
    1628             : 
    1629          16 :         if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
    1630          16 :                                 session_info->security_token)) {
    1631           0 :                 DEBUG(1, ("Enumerating sessions only allowed for "
    1632             :                           "administrators\n"));
    1633           0 :                 return WERR_ACCESS_DENIED;
    1634             :         }
    1635             : 
    1636          16 :         switch (r->in.info_ctr->level) {
    1637           2 :                 case 0:
    1638           3 :                         werr = init_srv_sess_info_0(p,
    1639           2 :                                                     r->in.info_ctr->ctr.ctr0,
    1640             :                                                     r->in.resume_handle,
    1641             :                                                     r->out.totalentries);
    1642           2 :                         break;
    1643           8 :                 case 1:
    1644          12 :                         werr = init_srv_sess_info_1(p,
    1645           8 :                                                     r->in.info_ctr->ctr.ctr1,
    1646             :                                                     r->in.resume_handle,
    1647             :                                                     r->out.totalentries);
    1648           8 :                         break;
    1649           6 :                 default:
    1650           6 :                         return WERR_INVALID_LEVEL;
    1651             :         }
    1652             : 
    1653          10 :         DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
    1654             : 
    1655          10 :         return werr;
    1656             : }
    1657             : 
    1658             : /*******************************************************************
    1659             :  _srvsvc_NetSessDel
    1660             : ********************************************************************/
    1661             : 
    1662           0 : WERROR _srvsvc_NetSessDel(struct pipes_struct *p,
    1663             :                           struct srvsvc_NetSessDel *r)
    1664             : {
    1665           0 :         struct dcesrv_call_state *dce_call = p->dce_call;
    1666           0 :         struct auth_session_info *session_info =
    1667           0 :                 dcesrv_call_session_info(dce_call);
    1668             :         struct sessionid *session_list;
    1669             :         int num_sessions, snum;
    1670             :         const char *username;
    1671             :         const char *machine;
    1672           0 :         bool not_root = False;
    1673             :         WERROR werr;
    1674             : 
    1675           0 :         DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
    1676             : 
    1677           0 :         werr = WERR_ACCESS_DENIED;
    1678             : 
    1679             :         /* fail out now if you are not root or not a domain admin */
    1680             : 
    1681           0 :         if ((session_info->unix_token->uid != sec_initial_uid()) &&
    1682           0 :                 ( ! nt_token_check_domain_rid(session_info->security_token,
    1683             :                                               DOMAIN_RID_ADMINS))) {
    1684             : 
    1685           0 :                 goto done;
    1686             :         }
    1687             : 
    1688           0 :         username = r->in.user;
    1689           0 :         machine = r->in.client;
    1690             : 
    1691             :         /* strip leading backslashes if any */
    1692           0 :         if (machine && machine[0] == '\\' && machine[1] == '\\') {
    1693           0 :                 machine += 2;
    1694             :         }
    1695             : 
    1696           0 :         num_sessions = find_sessions(p->mem_ctx, username, machine,
    1697             :                                      &session_list);
    1698             : 
    1699           0 :         for (snum = 0; snum < num_sessions; snum++) {
    1700             : 
    1701             :                 NTSTATUS ntstat;
    1702             : 
    1703           0 :                 if (session_info->unix_token->uid != sec_initial_uid()) {
    1704           0 :                         not_root = True;
    1705           0 :                         become_root();
    1706             :                 }
    1707             : 
    1708           0 :                 ntstat = messaging_send(p->msg_ctx,
    1709           0 :                                         session_list[snum].pid,
    1710             :                                         MSG_SHUTDOWN, &data_blob_null);
    1711             : 
    1712           0 :                 if (NT_STATUS_IS_OK(ntstat))
    1713           0 :                         werr = WERR_OK;
    1714             : 
    1715           0 :                 if (not_root)
    1716           0 :                         unbecome_root();
    1717             :         }
    1718             : 
    1719           0 :         DEBUG(5,("_srvsvc_NetSessDel: %d\n", __LINE__));
    1720             : 
    1721           0 : done:
    1722             : 
    1723           0 :         return werr;
    1724             : }
    1725             : 
    1726             : /*******************************************************************
    1727             :  _srvsvc_NetShareEnumAll
    1728             : ********************************************************************/
    1729             : 
    1730          44 : WERROR _srvsvc_NetShareEnumAll(struct pipes_struct *p,
    1731             :                                struct srvsvc_NetShareEnumAll *r)
    1732             : {
    1733             :         WERROR werr;
    1734             : 
    1735          44 :         DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
    1736             : 
    1737          44 :         if (!pipe_access_check(p)) {
    1738           0 :                 DEBUG(3, ("access denied to _srvsvc_NetShareEnumAll\n"));
    1739           0 :                 return WERR_ACCESS_DENIED;
    1740             :         }
    1741             : 
    1742             :         /* Create the list of shares for the response. */
    1743          44 :         werr = init_srv_share_info_ctr(p,
    1744             :                                        r->in.info_ctr,
    1745             :                                        r->in.resume_handle,
    1746             :                                        r->out.totalentries,
    1747             :                                        true);
    1748             : 
    1749          44 :         DEBUG(5,("_srvsvc_NetShareEnumAll: %d\n", __LINE__));
    1750             : 
    1751          44 :         return werr;
    1752             : }
    1753             : 
    1754             : /*******************************************************************
    1755             :  _srvsvc_NetShareEnum
    1756             : ********************************************************************/
    1757             : 
    1758          18 : WERROR _srvsvc_NetShareEnum(struct pipes_struct *p,
    1759             :                             struct srvsvc_NetShareEnum *r)
    1760             : {
    1761             :         WERROR werr;
    1762             : 
    1763          18 :         DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
    1764             : 
    1765          18 :         if (!pipe_access_check(p)) {
    1766           0 :                 DEBUG(3, ("access denied to _srvsvc_NetShareEnum\n"));
    1767           0 :                 return WERR_ACCESS_DENIED;
    1768             :         }
    1769             : 
    1770             :         /* Create the list of shares for the response. */
    1771          18 :         werr = init_srv_share_info_ctr(p,
    1772             :                                        r->in.info_ctr,
    1773             :                                        r->in.resume_handle,
    1774             :                                        r->out.totalentries,
    1775             :                                        false);
    1776             : 
    1777          18 :         DEBUG(5,("_srvsvc_NetShareEnum: %d\n", __LINE__));
    1778             : 
    1779          18 :         return werr;
    1780             : }
    1781             : 
    1782             : /*******************************************************************
    1783             :  _srvsvc_NetShareGetInfo
    1784             : ********************************************************************/
    1785             : 
    1786          24 : WERROR _srvsvc_NetShareGetInfo(struct pipes_struct *p,
    1787             :                                struct srvsvc_NetShareGetInfo *r)
    1788             : {
    1789          24 :         WERROR status = WERR_OK;
    1790          24 :         char *share_name = NULL;
    1791             :         int snum;
    1792          24 :         union srvsvc_NetShareInfo *info = r->out.info;
    1793             : 
    1794          24 :         DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
    1795             : 
    1796          24 :         if (!r->in.share_name) {
    1797           0 :                 return WERR_INVALID_NAME;
    1798             :         }
    1799             : 
    1800          24 :         snum = find_service(talloc_tos(), r->in.share_name, &share_name);
    1801          24 :         if (!share_name) {
    1802           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    1803             :         }
    1804          24 :         if (snum < 0) {
    1805           0 :                 return WERR_INVALID_NAME;
    1806             :         }
    1807             : 
    1808          24 :         switch (r->in.level) {
    1809           6 :                 case 0:
    1810           6 :                         info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0);
    1811           6 :                         W_ERROR_HAVE_NO_MEMORY(info->info0);
    1812           6 :                         init_srv_share_info_0(p, info->info0, snum);
    1813           6 :                         break;
    1814           6 :                 case 1:
    1815           6 :                         info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1);
    1816           6 :                         W_ERROR_HAVE_NO_MEMORY(info->info1);
    1817           6 :                         init_srv_share_info_1(p, info->info1, snum);
    1818           6 :                         break;
    1819           6 :                 case 2:
    1820           6 :                         info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2);
    1821           6 :                         W_ERROR_HAVE_NO_MEMORY(info->info2);
    1822           6 :                         init_srv_share_info_2(p, info->info2, snum);
    1823           9 :                         info->info2->current_users =
    1824           9 :                           count_current_connections(info->info2->name, false);
    1825           6 :                         break;
    1826           0 :                 case 501:
    1827           0 :                         info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501);
    1828           0 :                         W_ERROR_HAVE_NO_MEMORY(info->info501);
    1829           0 :                         init_srv_share_info_501(p, info->info501, snum);
    1830           0 :                         break;
    1831           4 :                 case 502:
    1832           4 :                         info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502);
    1833           4 :                         W_ERROR_HAVE_NO_MEMORY(info->info502);
    1834           4 :                         init_srv_share_info_502(p, info->info502, snum);
    1835           4 :                         break;
    1836           0 :                 case 1004:
    1837           0 :                         info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004);
    1838           0 :                         W_ERROR_HAVE_NO_MEMORY(info->info1004);
    1839           0 :                         init_srv_share_info_1004(p, info->info1004, snum);
    1840           0 :                         break;
    1841           2 :                 case 1005:
    1842           2 :                         info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005);
    1843           2 :                         W_ERROR_HAVE_NO_MEMORY(info->info1005);
    1844           2 :                         init_srv_share_info_1005(p, info->info1005, snum);
    1845           2 :                         break;
    1846           0 :                 case 1006:
    1847           0 :                         info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006);
    1848           0 :                         W_ERROR_HAVE_NO_MEMORY(info->info1006);
    1849           0 :                         init_srv_share_info_1006(p, info->info1006, snum);
    1850           0 :                         break;
    1851           0 :                 case 1007:
    1852           0 :                         info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007);
    1853           0 :                         W_ERROR_HAVE_NO_MEMORY(info->info1007);
    1854           0 :                         init_srv_share_info_1007(p, info->info1007, snum);
    1855           0 :                         break;
    1856           0 :                 case 1501:
    1857           0 :                         init_srv_share_info_1501(p, &info->info1501, snum);
    1858           0 :                         break;
    1859           0 :                 default:
    1860           0 :                         DEBUG(5,("_srvsvc_NetShareGetInfo: unsupported switch value %d\n",
    1861             :                                 r->in.level));
    1862           0 :                         status = WERR_INVALID_LEVEL;
    1863           0 :                         break;
    1864             :         }
    1865             : 
    1866          24 :         DEBUG(5,("_srvsvc_NetShareGetInfo: %d\n", __LINE__));
    1867             : 
    1868          24 :         return status;
    1869             : }
    1870             : 
    1871             : /*******************************************************************
    1872             :  _srvsvc_NetShareSetInfo. Modify share details.
    1873             : ********************************************************************/
    1874             : 
    1875           1 : WERROR _srvsvc_NetShareSetInfo(struct pipes_struct *p,
    1876             :                                struct srvsvc_NetShareSetInfo *r)
    1877             : {
    1878           1 :         struct dcesrv_call_state *dce_call = p->dce_call;
    1879           1 :         struct auth_session_info *session_info =
    1880           0 :                 dcesrv_call_session_info(dce_call);
    1881           1 :         const struct loadparm_substitution *lp_sub =
    1882           0 :                 loadparm_s3_global_substitution();
    1883           1 :         char *command = NULL;
    1884           1 :         char *share_name = NULL;
    1885           1 :         char *comment = NULL;
    1886           1 :         const char *pathname = NULL;
    1887             :         int type;
    1888             :         int snum;
    1889             :         int ret;
    1890           1 :         char *path = NULL;
    1891           1 :         struct security_descriptor *psd = NULL;
    1892           1 :         bool is_disk_op = False;
    1893           1 :         const char *csc_policy = NULL;
    1894           1 :         bool csc_policy_changed = false;
    1895           1 :         const char *csc_policies[] = {"manual", "documents", "programs",
    1896             :                                       "disable"};
    1897             :         uint32_t client_csc_policy;
    1898           1 :         int max_connections = 0;
    1899           1 :         TALLOC_CTX *ctx = p->mem_ctx;
    1900           1 :         union srvsvc_NetShareInfo *info = r->in.info;
    1901             : 
    1902           1 :         DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
    1903             : 
    1904           1 :         if (!r->in.share_name) {
    1905           0 :                 return WERR_INVALID_NAME;
    1906             :         }
    1907             : 
    1908           1 :         if (r->out.parm_error) {
    1909           1 :                 *r->out.parm_error = 0;
    1910             :         }
    1911             : 
    1912           1 :         if ( strequal(r->in.share_name,"IPC$")
    1913           1 :                 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
    1914           1 :                 || strequal(r->in.share_name,"global") )
    1915             :         {
    1916           0 :                 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s cannot be "
    1917             :                         "modified by a remote user.\n",
    1918             :                         r->in.share_name ));
    1919           0 :                 return WERR_ACCESS_DENIED;
    1920             :         }
    1921             : 
    1922           1 :         snum = find_service(talloc_tos(), r->in.share_name, &share_name);
    1923           1 :         if (!share_name) {
    1924           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    1925             :         }
    1926             : 
    1927             :         /* Does this share exist ? */
    1928           1 :         if (snum < 0)
    1929           0 :                 return WERR_NERR_NETNAMENOTFOUND;
    1930             : 
    1931             :         /* No change to printer shares. */
    1932           1 :         if (lp_printable(snum))
    1933           0 :                 return WERR_ACCESS_DENIED;
    1934             : 
    1935           1 :         is_disk_op = security_token_has_privilege(
    1936           1 :                 session_info->security_token, SEC_PRIV_DISK_OPERATOR);
    1937             : 
    1938             :         /* fail out now if you are not root and not a disk op */
    1939             : 
    1940           1 :         if (session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
    1941           0 :                 DEBUG(2,("_srvsvc_NetShareSetInfo: uid %u doesn't have the "
    1942             :                         "SeDiskOperatorPrivilege privilege needed to modify "
    1943             :                         "share %s\n",
    1944             :                         (unsigned int)session_info->unix_token->uid,
    1945             :                         share_name ));
    1946           0 :                 return WERR_ACCESS_DENIED;
    1947             :         }
    1948             : 
    1949           1 :         max_connections = lp_max_connections(snum);
    1950           1 :         csc_policy = csc_policies[lp_csc_policy(snum)];
    1951             : 
    1952           1 :         switch (r->in.level) {
    1953           0 :         case 1:
    1954           0 :                 pathname = lp_path(ctx, lp_sub, snum);
    1955           0 :                 comment = talloc_strdup(ctx, info->info1->comment);
    1956           0 :                 type = info->info1->type;
    1957           0 :                 psd = NULL;
    1958           0 :                 break;
    1959           0 :         case 2:
    1960           0 :                 comment = talloc_strdup(ctx, info->info2->comment);
    1961           0 :                 pathname = info->info2->path;
    1962           0 :                 type = info->info2->type;
    1963           0 :                 max_connections = (info->info2->max_users == (uint32_t)-1) ?
    1964           0 :                         0 : info->info2->max_users;
    1965           0 :                 psd = NULL;
    1966           0 :                 break;
    1967             : #if 0
    1968             :                 /* not supported on set but here for completeness */
    1969             :         case 501:
    1970             :                 comment = talloc_strdup(ctx, info->info501->comment);
    1971             :                 type = info->info501->type;
    1972             :                 psd = NULL;
    1973             :                 break;
    1974             : #endif
    1975           0 :         case 502:
    1976           0 :                 comment = talloc_strdup(ctx, info->info502->comment);
    1977           0 :                 pathname = info->info502->path;
    1978           0 :                 type = info->info502->type;
    1979           0 :                 psd = info->info502->sd_buf.sd;
    1980           0 :                 map_generic_share_sd_bits(psd);
    1981           0 :                 break;
    1982           0 :         case 1004:
    1983           0 :                 pathname = lp_path(ctx, lp_sub, snum);
    1984           0 :                 comment = talloc_strdup(ctx, info->info1004->comment);
    1985           0 :                 type = STYPE_DISKTREE;
    1986           0 :                 break;
    1987           1 :         case 1005:
    1988             :                 /* XP re-sets the csc policy even if it wasn't changed by the
    1989             :                    user, so we must compare it to see if it's what is set in
    1990             :                    smb.conf, so that we can contine other ops like setting
    1991             :                    ACLs on a share */
    1992           2 :                 client_csc_policy = (info->info1005->dfs_flags &
    1993           1 :                                      SHARE_1005_CSC_POLICY_MASK) >>
    1994             :                                     SHARE_1005_CSC_POLICY_SHIFT;
    1995             : 
    1996           1 :                 if (client_csc_policy == (uint32_t)lp_csc_policy(snum)) {
    1997           0 :                         return WERR_OK;
    1998             :                 }
    1999             : 
    2000           1 :                 csc_policy = csc_policies[client_csc_policy];
    2001           1 :                 csc_policy_changed = true;
    2002             : 
    2003           1 :                 pathname = lp_path(ctx, lp_sub, snum);
    2004           1 :                 comment = lp_comment(ctx, lp_sub, snum);
    2005           1 :                 type = STYPE_DISKTREE;
    2006           1 :                 break;
    2007           0 :         case 1006:
    2008             :         case 1007:
    2009           0 :                 return WERR_ACCESS_DENIED;
    2010           0 :         case 1501:
    2011           0 :                 pathname = lp_path(ctx, lp_sub, snum);
    2012           0 :                 comment = lp_comment(ctx, lp_sub, snum);
    2013           0 :                 psd = info->info1501->sd;
    2014           0 :                 map_generic_share_sd_bits(psd);
    2015           0 :                 type = STYPE_DISKTREE;
    2016           0 :                 break;
    2017           0 :         default:
    2018           0 :                 DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n",
    2019             :                         r->in.level));
    2020           0 :                 return WERR_INVALID_LEVEL;
    2021             :         }
    2022             : 
    2023             :         /* We can only modify disk shares. */
    2024           1 :         if (type != STYPE_DISKTREE) {
    2025           0 :                 DEBUG(5,("_srvsvc_NetShareSetInfo: share %s is not a "
    2026             :                         "disk share\n",
    2027             :                         share_name ));
    2028           0 :                 return WERR_ACCESS_DENIED;
    2029             :         }
    2030             : 
    2031           1 :         if (comment == NULL) {
    2032           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2033             :         }
    2034             : 
    2035             :         /* Check if the pathname is valid. */
    2036           1 :         if (!(path = valid_share_pathname(p->mem_ctx, pathname ))) {
    2037           0 :                 DEBUG(5,("_srvsvc_NetShareSetInfo: invalid pathname %s\n",
    2038             :                         pathname ));
    2039           0 :                 return WERR_BAD_PATHNAME;
    2040             :         }
    2041             : 
    2042             :         /* Ensure share name, pathname and comment don't contain '"' characters. */
    2043           1 :         string_replace(share_name, '"', ' ');
    2044           1 :         string_replace(path, '"', ' ');
    2045           1 :         string_replace(comment, '"', ' ');
    2046             : 
    2047           1 :         DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n",
    2048             :                 lp_change_share_command(talloc_tos(), lp_sub) ? lp_change_share_command(talloc_tos(), lp_sub) : "NULL" ));
    2049             : 
    2050             :         /* Only call modify function if something changed. */
    2051             : 
    2052           1 :         if (strcmp(path, lp_path(talloc_tos(), lp_sub, snum))
    2053           1 :                         || strcmp(comment, lp_comment(talloc_tos(), lp_sub, snum))
    2054           1 :                         || (lp_max_connections(snum) != max_connections)
    2055           1 :                         || csc_policy_changed) {
    2056             : 
    2057           1 :                 if (!lp_change_share_command(talloc_tos(), lp_sub) || !*lp_change_share_command(talloc_tos(), lp_sub)) {
    2058           0 :                         DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n"));
    2059           0 :                         return WERR_ACCESS_DENIED;
    2060             :                 }
    2061             : 
    2062           1 :                 command = talloc_asprintf(p->mem_ctx,
    2063             :                                 "%s \"%s\" \"%s\" \"%s\" \"%s\" %d \"%s\"",
    2064             :                                 lp_change_share_command(talloc_tos(), lp_sub),
    2065             :                                 get_dyn_CONFIGFILE(),
    2066             :                                 share_name,
    2067             :                                 path,
    2068             :                                 comment,
    2069             :                                 max_connections,
    2070             :                                 csc_policy);
    2071           1 :                 if (!command) {
    2072           0 :                         return WERR_NOT_ENOUGH_MEMORY;
    2073             :                 }
    2074             : 
    2075           1 :                 DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command ));
    2076             : 
    2077             :                 /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
    2078             : 
    2079           1 :                 if (is_disk_op)
    2080           0 :                         become_root();
    2081             : 
    2082           1 :                 ret = smbrun(command, NULL, NULL);
    2083           1 :                 if (ret == 0) {
    2084           1 :                         reload_services(NULL, NULL, false);
    2085             : 
    2086             :                         /* Tell everyone we updated smb.conf. */
    2087           1 :                         messaging_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED,
    2088             :                                            NULL, 0);
    2089             :                 }
    2090             : 
    2091           1 :                 if ( is_disk_op )
    2092           0 :                         unbecome_root();
    2093             : 
    2094             :                 /********* END SeDiskOperatorPrivilege BLOCK *********/
    2095             : 
    2096           1 :                 DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n",
    2097             :                         command, ret ));
    2098             : 
    2099           1 :                 TALLOC_FREE(command);
    2100             : 
    2101           2 :                 if ( ret != 0 )
    2102           0 :                         return WERR_ACCESS_DENIED;
    2103             :         } else {
    2104           0 :                 DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n",
    2105             :                         share_name ));
    2106             :         }
    2107             : 
    2108             :         /* Replace SD if changed. */
    2109           1 :         if (psd) {
    2110             :                 struct security_descriptor *old_sd;
    2111             :                 size_t sd_size;
    2112             :                 NTSTATUS status;
    2113             : 
    2114           0 :                 old_sd = get_share_security(p->mem_ctx, lp_servicename(talloc_tos(), lp_sub, snum), &sd_size);
    2115             : 
    2116           0 :                 if (old_sd && !security_descriptor_equal(old_sd, psd)) {
    2117           0 :                         status = set_share_security(share_name, psd);
    2118           0 :                         if (!NT_STATUS_IS_OK(status)) {
    2119           0 :                                 DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n",
    2120             :                                         share_name ));
    2121             :                         }
    2122             :                 }
    2123             :         }
    2124             : 
    2125           1 :         DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__));
    2126             : 
    2127           1 :         return WERR_OK;
    2128             : }
    2129             : 
    2130             : /*******************************************************************
    2131             :  _srvsvc_NetShareAdd.
    2132             :  Call 'add_share_command "sharename" "pathname"
    2133             :  "comment" "max connections = "
    2134             : ********************************************************************/
    2135             : 
    2136           2 : WERROR _srvsvc_NetShareAdd(struct pipes_struct *p,
    2137             :                            struct srvsvc_NetShareAdd *r)
    2138             : {
    2139           2 :         struct dcesrv_call_state *dce_call = p->dce_call;
    2140           2 :         struct auth_session_info *session_info =
    2141           0 :                 dcesrv_call_session_info(dce_call);
    2142           2 :         char *command = NULL;
    2143           2 :         char *share_name_in = NULL;
    2144           2 :         char *share_name = NULL;
    2145           2 :         char *comment = NULL;
    2146           2 :         char *pathname = NULL;
    2147             :         int type;
    2148             :         int snum;
    2149             :         int ret;
    2150             :         char *path;
    2151           2 :         struct security_descriptor *psd = NULL;
    2152             :         bool is_disk_op;
    2153           2 :         int max_connections = 0;
    2154             :         SMB_STRUCT_STAT st;
    2155           2 :         TALLOC_CTX *ctx = p->mem_ctx;
    2156           2 :         const struct loadparm_substitution *lp_sub =
    2157           0 :                 loadparm_s3_global_substitution();
    2158             : 
    2159           2 :         DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
    2160             : 
    2161           2 :         if (r->out.parm_error) {
    2162           1 :                 *r->out.parm_error = 0;
    2163             :         }
    2164             : 
    2165           2 :         is_disk_op = security_token_has_privilege(
    2166           2 :                 session_info->security_token, SEC_PRIV_DISK_OPERATOR);
    2167             : 
    2168           2 :         if (session_info->unix_token->uid != sec_initial_uid()  && !is_disk_op) {
    2169           0 :                 return WERR_ACCESS_DENIED;
    2170             :         }
    2171             : 
    2172           2 :         if (!lp_add_share_command(talloc_tos(), lp_sub) || !*lp_add_share_command(talloc_tos(), lp_sub)) {
    2173           1 :                 DBG_WARNING("_srvsvc_NetShareAdd: No \"add share command\" parameter set in smb.conf.\n");
    2174           1 :                 return WERR_ACCESS_DENIED;
    2175             :         }
    2176             : 
    2177           1 :         switch (r->in.level) {
    2178           0 :         case 0:
    2179             :                 /* No path. Not enough info in a level 0 to do anything. */
    2180           0 :                 return WERR_ACCESS_DENIED;
    2181           0 :         case 1:
    2182             :                 /* Not enough info in a level 1 to do anything. */
    2183           0 :                 return WERR_ACCESS_DENIED;
    2184           0 :         case 2:
    2185           0 :                 share_name_in = talloc_strdup(ctx, r->in.info->info2->name);
    2186           0 :                 comment = talloc_strdup(ctx, r->in.info->info2->comment);
    2187           0 :                 pathname = talloc_strdup(ctx, r->in.info->info2->path);
    2188           0 :                 max_connections = (r->in.info->info2->max_users == (uint32_t)-1) ?
    2189           0 :                         0 : r->in.info->info2->max_users;
    2190           0 :                 type = r->in.info->info2->type;
    2191           0 :                 break;
    2192           0 :         case 501:
    2193             :                 /* No path. Not enough info in a level 501 to do anything. */
    2194           0 :                 return WERR_ACCESS_DENIED;
    2195           1 :         case 502:
    2196           1 :                 share_name_in = talloc_strdup(ctx, r->in.info->info502->name);
    2197           1 :                 comment = talloc_strdup(ctx, r->in.info->info502->comment);
    2198           1 :                 pathname = talloc_strdup(ctx, r->in.info->info502->path);
    2199           2 :                 max_connections = (r->in.info->info502->max_users == (uint32_t)-1) ?
    2200           1 :                         0 : r->in.info->info502->max_users;
    2201           1 :                 type = r->in.info->info502->type;
    2202           1 :                 psd = r->in.info->info502->sd_buf.sd;
    2203           1 :                 map_generic_share_sd_bits(psd);
    2204           1 :                 break;
    2205             : 
    2206             :                 /* none of the following contain share names.  NetShareAdd does not have a separate parameter for the share name */
    2207             : 
    2208           0 :         case 1004:
    2209             :         case 1005:
    2210             :         case 1006:
    2211             :         case 1007:
    2212           0 :                 return WERR_ACCESS_DENIED;
    2213           0 :         case 1501:
    2214             :                 /* DFS only level. */
    2215           0 :                 return WERR_ACCESS_DENIED;
    2216           0 :         default:
    2217           0 :                 DEBUG(5,("_srvsvc_NetShareAdd: unsupported switch value %d\n",
    2218             :                         r->in.level));
    2219           0 :                 return WERR_INVALID_LEVEL;
    2220             :         }
    2221             : 
    2222             :         /* check for invalid share names */
    2223             : 
    2224           2 :         if (!share_name_in || !validate_net_name(share_name_in,
    2225             :                                 INVALID_SHARENAME_CHARS,
    2226           1 :                                 strlen(share_name_in))) {
    2227           0 :                 DEBUG(5,("_srvsvc_NetShareAdd: Bad sharename \"%s\"\n",
    2228             :                                         share_name_in ? share_name_in : ""));
    2229           0 :                 return WERR_INVALID_NAME;
    2230             :         }
    2231             : 
    2232           1 :         if (strequal(share_name_in,"IPC$") || strequal(share_name_in,"global")
    2233           1 :                         || (lp_enable_asu_support() &&
    2234           0 :                                         strequal(share_name_in,"ADMIN$"))) {
    2235           0 :                 return WERR_ACCESS_DENIED;
    2236             :         }
    2237             : 
    2238           1 :         snum = find_service(ctx, share_name_in, &share_name);
    2239           1 :         if (!share_name) {
    2240           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2241             :         }
    2242             : 
    2243             :         /* Share already exists. */
    2244           1 :         if (snum >= 0) {
    2245           0 :                 return WERR_FILE_EXISTS;
    2246             :         }
    2247             : 
    2248             :         /* We can only add disk shares. */
    2249           1 :         if (type != STYPE_DISKTREE) {
    2250           0 :                 return WERR_ACCESS_DENIED;
    2251             :         }
    2252             : 
    2253             :         /* Check if the pathname is valid. */
    2254           1 :         if (!(path = valid_share_pathname(p->mem_ctx, pathname))) {
    2255           0 :                 return WERR_BAD_PATHNAME;
    2256             :         }
    2257             : 
    2258           1 :         ret = sys_lstat(path, &st, false);
    2259           1 :         if (ret == -1 && (errno != EACCES)) {
    2260             :                 /*
    2261             :                  * If path has any other than permission
    2262             :                  * problem, return WERR_FILE_NOT_FOUND (as Windows
    2263             :                  * does.
    2264             :                  */
    2265           0 :                 return WERR_FILE_NOT_FOUND;
    2266             :         }
    2267             : 
    2268             :         /* Ensure share name, pathname and comment don't contain '"' characters. */
    2269           1 :         string_replace(share_name_in, '"', ' ');
    2270           1 :         string_replace(share_name, '"', ' ');
    2271           1 :         string_replace(path, '"', ' ');
    2272           1 :         if (comment) {
    2273           1 :                 string_replace(comment, '"', ' ');
    2274             :         }
    2275             : 
    2276           1 :         command = talloc_asprintf(ctx,
    2277             :                         "%s \"%s\" \"%s\" \"%s\" \"%s\" %d",
    2278             :                         lp_add_share_command(talloc_tos(), lp_sub),
    2279             :                         get_dyn_CONFIGFILE(),
    2280             :                         share_name_in,
    2281             :                         path,
    2282             :                         comment ? comment : "",
    2283             :                         max_connections);
    2284           1 :         if (!command) {
    2285           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2286             :         }
    2287             : 
    2288           1 :         DEBUG(10,("_srvsvc_NetShareAdd: Running [%s]\n", command ));
    2289             : 
    2290             :         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
    2291             : 
    2292           1 :         if ( is_disk_op )
    2293           0 :                 become_root();
    2294             : 
    2295             :         /* FIXME: use libnetconf here - gd */
    2296             : 
    2297           1 :         ret = smbrun(command, NULL, NULL);
    2298           1 :         if (ret == 0) {
    2299             :                 /* Tell everyone we updated smb.conf. */
    2300           1 :                 messaging_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0);
    2301             :         }
    2302             : 
    2303           1 :         if ( is_disk_op )
    2304           0 :                 unbecome_root();
    2305             : 
    2306             :         /********* END SeDiskOperatorPrivilege BLOCK *********/
    2307             : 
    2308           1 :         DEBUG(3,("_srvsvc_NetShareAdd: Running [%s] returned (%d)\n",
    2309             :                 command, ret ));
    2310             : 
    2311           1 :         TALLOC_FREE(command);
    2312             : 
    2313           1 :         if ( ret != 0 )
    2314           0 :                 return WERR_ACCESS_DENIED;
    2315             : 
    2316           1 :         if (psd) {
    2317             :                 NTSTATUS status;
    2318             :                 /* Note we use share_name here, not share_name_in as
    2319             :                    we need a canonicalized name for setting security. */
    2320           0 :                 status = set_share_security(share_name, psd);
    2321           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2322           0 :                         DEBUG(0,("_srvsvc_NetShareAdd: Failed to add security info to share %s.\n",
    2323             :                                 share_name ));
    2324             :                 }
    2325             :         }
    2326             : 
    2327             :         /*
    2328             :          * We don't call reload_services() here, the message will
    2329             :          * cause this to be done before the next packet is read
    2330             :          * from the client. JRA.
    2331             :          */
    2332             : 
    2333           1 :         DEBUG(5,("_srvsvc_NetShareAdd: %d\n", __LINE__));
    2334             : 
    2335           1 :         return WERR_OK;
    2336             : }
    2337             : 
    2338             : /*******************************************************************
    2339             :  _srvsvc_NetShareDel
    2340             :  Call "delete share command" with the share name as
    2341             :  a parameter.
    2342             : ********************************************************************/
    2343             : 
    2344           2 : WERROR _srvsvc_NetShareDel(struct pipes_struct *p,
    2345             :                            struct srvsvc_NetShareDel *r)
    2346             : {
    2347           2 :         struct dcesrv_call_state *dce_call = p->dce_call;
    2348           2 :         struct auth_session_info *session_info =
    2349           0 :                 dcesrv_call_session_info(dce_call);
    2350           2 :         char *command = NULL;
    2351           2 :         char *share_name = NULL;
    2352             :         int ret;
    2353             :         int snum;
    2354             :         bool is_disk_op;
    2355           2 :         TALLOC_CTX *ctx = p->mem_ctx;
    2356           2 :         const struct loadparm_substitution *lp_sub =
    2357           0 :                 loadparm_s3_global_substitution();
    2358             : 
    2359           2 :         DEBUG(5,("_srvsvc_NetShareDel: %d\n", __LINE__));
    2360             : 
    2361           2 :         if (!r->in.share_name) {
    2362           0 :                 return WERR_NERR_NETNAMENOTFOUND;
    2363             :         }
    2364             : 
    2365           2 :         if ( strequal(r->in.share_name,"IPC$")
    2366           2 :                 || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") )
    2367           2 :                 || strequal(r->in.share_name,"global") )
    2368             :         {
    2369           0 :                 return WERR_ACCESS_DENIED;
    2370             :         }
    2371             : 
    2372           2 :         snum = find_service(talloc_tos(), r->in.share_name, &share_name);
    2373           2 :         if (!share_name) {
    2374           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2375             :         }
    2376             : 
    2377           2 :         if (snum < 0) {
    2378           1 :                 return WERR_BAD_NET_NAME;
    2379             :         }
    2380             : 
    2381             :         /* No change to printer shares. */
    2382           1 :         if (lp_printable(snum))
    2383           0 :                 return WERR_ACCESS_DENIED;
    2384             : 
    2385           1 :         is_disk_op = security_token_has_privilege(
    2386           1 :                 session_info->security_token, SEC_PRIV_DISK_OPERATOR);
    2387             : 
    2388           1 :         if (session_info->unix_token->uid != sec_initial_uid()  && !is_disk_op) {
    2389           0 :                 return WERR_ACCESS_DENIED;
    2390             :         }
    2391             : 
    2392           1 :         if (!lp_delete_share_command(talloc_tos(), lp_sub) || !*lp_delete_share_command(talloc_tos(), lp_sub)) {
    2393           0 :                 DBG_WARNING("_srvsvc_NetShareDel: No \"delete share command\" parameter set in smb.conf.\n");
    2394           0 :                 return WERR_ACCESS_DENIED;
    2395             :         }
    2396             : 
    2397           1 :         command = talloc_asprintf(ctx,
    2398             :                         "%s \"%s\" \"%s\"",
    2399             :                         lp_delete_share_command(talloc_tos(), lp_sub),
    2400             :                         get_dyn_CONFIGFILE(),
    2401             :                         share_name);
    2402           1 :         if (!command) {
    2403           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2404             :         }
    2405             : 
    2406           1 :         DEBUG(10,("_srvsvc_NetShareDel: Running [%s]\n", command ));
    2407             : 
    2408             :         /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
    2409             : 
    2410           1 :         if ( is_disk_op )
    2411           0 :                 become_root();
    2412             : 
    2413           1 :         ret = smbrun(command, NULL, NULL);
    2414           0 :         if (ret == 0) {
    2415             :                 /* Tell everyone we updated smb.conf. */
    2416           0 :                 messaging_send_all(p->msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0);
    2417             :         }
    2418             : 
    2419           0 :         if ( is_disk_op )
    2420           0 :                 unbecome_root();
    2421             : 
    2422             :         /********* END SeDiskOperatorPrivilege BLOCK *********/
    2423             : 
    2424           0 :         DEBUG(3,("_srvsvc_NetShareDel: Running [%s] returned (%d)\n", command, ret ));
    2425             : 
    2426           0 :         if ( ret != 0 )
    2427           0 :                 return WERR_ACCESS_DENIED;
    2428             : 
    2429             :         /* Delete the SD in the database. */
    2430           0 :         delete_share_security(share_name);
    2431             : 
    2432           0 :         lp_killservice(snum);
    2433             : 
    2434           0 :         return WERR_OK;
    2435             : }
    2436             : 
    2437             : /*******************************************************************
    2438             :  _srvsvc_NetShareDelSticky
    2439             : ********************************************************************/
    2440             : 
    2441           0 : WERROR _srvsvc_NetShareDelSticky(struct pipes_struct *p,
    2442             :                                  struct srvsvc_NetShareDelSticky *r)
    2443             : {
    2444             :         struct srvsvc_NetShareDel q;
    2445             : 
    2446           0 :         DEBUG(5,("_srvsvc_NetShareDelSticky: %d\n", __LINE__));
    2447             : 
    2448           0 :         q.in.server_unc         = r->in.server_unc;
    2449           0 :         q.in.share_name         = r->in.share_name;
    2450           0 :         q.in.reserved           = r->in.reserved;
    2451             : 
    2452           0 :         return _srvsvc_NetShareDel(p, &q);
    2453             : }
    2454             : 
    2455             : /*******************************************************************
    2456             :  _srvsvc_NetRemoteTOD
    2457             : ********************************************************************/
    2458             : 
    2459           4 : WERROR _srvsvc_NetRemoteTOD(struct pipes_struct *p,
    2460             :                             struct srvsvc_NetRemoteTOD *r)
    2461             : {
    2462             :         struct srvsvc_NetRemoteTODInfo *tod;
    2463             :         struct tm *t;
    2464           4 :         time_t unixdate = time(NULL);
    2465             : 
    2466             :         /* We do this call first as if we do it *after* the gmtime call
    2467             :            it overwrites the pointed-to values. JRA */
    2468             : 
    2469           4 :         uint32_t zone = get_time_zone(unixdate)/60;
    2470             : 
    2471           4 :         DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
    2472             : 
    2473           4 :         if ( !(tod = talloc_zero(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) )
    2474           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2475             : 
    2476           4 :         *r->out.info = tod;
    2477             : 
    2478           4 :         DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
    2479             : 
    2480           4 :         t = gmtime(&unixdate);
    2481             : 
    2482             :         /* set up the */
    2483           4 :         tod->elapsed = unixdate;
    2484           4 :         tod->msecs   = 0;
    2485           4 :         tod->hours   = t->tm_hour;
    2486           4 :         tod->mins    = t->tm_min;
    2487           4 :         tod->secs    = t->tm_sec;
    2488           4 :         tod->hunds   = 0;
    2489           4 :         tod->timezone        = zone;
    2490           4 :         tod->tinterval       = 10000;
    2491           4 :         tod->day     = t->tm_mday;
    2492           4 :         tod->month   = t->tm_mon + 1;
    2493           4 :         tod->year    = 1900+t->tm_year;
    2494           4 :         tod->weekday = t->tm_wday;
    2495             : 
    2496           4 :         DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__));
    2497             : 
    2498           4 :         return WERR_OK;
    2499             : }
    2500             : 
    2501             : /***********************************************************************************
    2502             :  _srvsvc_NetGetFileSecurity
    2503             :  Win9x NT tools get security descriptor.
    2504             : ***********************************************************************************/
    2505             : 
    2506           0 : WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p,
    2507             :                                   struct srvsvc_NetGetFileSecurity *r)
    2508             : {
    2509           0 :         struct dcesrv_call_state *dce_call = p->dce_call;
    2510           0 :         struct auth_session_info *session_info =
    2511           0 :                 dcesrv_call_session_info(dce_call);
    2512           0 :         TALLOC_CTX *frame = talloc_stackframe();
    2513           0 :         const struct loadparm_substitution *lp_sub =
    2514           0 :                 loadparm_s3_global_substitution();
    2515           0 :         struct smb_filename *smb_fname = NULL;
    2516             :         size_t sd_size;
    2517           0 :         char *servicename = NULL;
    2518             :         SMB_STRUCT_STAT st;
    2519             :         NTSTATUS nt_status;
    2520             :         WERROR werr;
    2521           0 :         struct conn_struct_tos *c = NULL;
    2522           0 :         connection_struct *conn = NULL;
    2523           0 :         struct sec_desc_buf *sd_buf = NULL;
    2524           0 :         struct files_struct *dirfsp = NULL;
    2525           0 :         files_struct *fsp = NULL;
    2526             :         int snum;
    2527           0 :         uint32_t ucf_flags = 0;
    2528           0 :         NTTIME twrp = 0;
    2529             : 
    2530           0 :         ZERO_STRUCT(st);
    2531             : 
    2532           0 :         if (!r->in.share) {
    2533           0 :                 werr = WERR_NERR_NETNAMENOTFOUND;
    2534           0 :                 goto error_exit;
    2535             :         }
    2536           0 :         snum = find_service(frame, r->in.share, &servicename);
    2537           0 :         if (!servicename) {
    2538           0 :                 werr = WERR_NOT_ENOUGH_MEMORY;
    2539           0 :                 goto error_exit;
    2540             :         }
    2541           0 :         if (snum == -1) {
    2542           0 :                 DEBUG(10, ("Could not find service %s\n", servicename));
    2543           0 :                 werr = WERR_NERR_NETNAMENOTFOUND;
    2544           0 :                 goto error_exit;
    2545             :         }
    2546             : 
    2547           0 :         nt_status = create_conn_struct_tos_cwd(global_messaging_context(),
    2548             :                                                snum,
    2549           0 :                                                lp_path(frame, lp_sub, snum),
    2550             :                                                session_info,
    2551             :                                                &c);
    2552           0 :         if (!NT_STATUS_IS_OK(nt_status)) {
    2553           0 :                 DEBUG(10, ("create_conn_struct failed: %s\n",
    2554             :                            nt_errstr(nt_status)));
    2555           0 :                 werr = ntstatus_to_werror(nt_status);
    2556           0 :                 goto error_exit;
    2557             :         }
    2558           0 :         conn = c->conn;
    2559             : 
    2560           0 :         nt_status = filename_convert_dirfsp(frame,
    2561             :                                             conn,
    2562             :                                             r->in.file,
    2563             :                                             ucf_flags,
    2564             :                                             twrp,
    2565             :                                             &dirfsp,
    2566             :                                             &smb_fname);
    2567           0 :         if (!NT_STATUS_IS_OK(nt_status)) {
    2568           0 :                 werr = ntstatus_to_werror(nt_status);
    2569           0 :                 goto error_exit;
    2570             :         }
    2571             : 
    2572           0 :         nt_status = SMB_VFS_CREATE_FILE(
    2573             :                 conn,                                   /* conn */
    2574             :                 NULL,                                   /* req */
    2575             :                 dirfsp,                                 /* dirfsp */
    2576             :                 smb_fname,                              /* fname */
    2577             :                 FILE_READ_ATTRIBUTES,                   /* access_mask */
    2578             :                 FILE_SHARE_READ|FILE_SHARE_WRITE,       /* share_access */
    2579             :                 FILE_OPEN,                              /* create_disposition*/
    2580             :                 0,                                      /* create_options */
    2581             :                 0,                                      /* file_attributes */
    2582             :                 INTERNAL_OPEN_ONLY,                     /* oplock_request */
    2583             :                 NULL,                                   /* lease */
    2584             :                 0,                                      /* allocation_size */
    2585             :                 0,                                      /* private_flags */
    2586             :                 NULL,                                   /* sd */
    2587             :                 NULL,                                   /* ea_list */
    2588             :                 &fsp,                                       /* result */
    2589             :                 NULL,                                   /* pinfo */
    2590             :                 NULL, NULL);                            /* create context */
    2591             : 
    2592           0 :         if (!NT_STATUS_IS_OK(nt_status)) {
    2593           0 :                 DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n",
    2594             :                          smb_fname_str_dbg(smb_fname)));
    2595           0 :                 werr = ntstatus_to_werror(nt_status);
    2596           0 :                 goto error_exit;
    2597             :         }
    2598             : 
    2599           0 :         sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf);
    2600           0 :         if (!sd_buf) {
    2601           0 :                 werr = WERR_NOT_ENOUGH_MEMORY;
    2602           0 :                 goto error_exit;
    2603             :         }
    2604             : 
    2605           0 :         nt_status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
    2606             :                                        (SECINFO_OWNER
    2607             :                                         |SECINFO_GROUP
    2608             :                                         |SECINFO_DACL), sd_buf, &sd_buf->sd);
    2609             : 
    2610           0 :         if (!NT_STATUS_IS_OK(nt_status)) {
    2611           0 :                 DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL "
    2612             :                         "for file %s\n", smb_fname_str_dbg(smb_fname)));
    2613           0 :                 werr = ntstatus_to_werror(nt_status);
    2614           0 :                 TALLOC_FREE(sd_buf);
    2615           0 :                 goto error_exit;
    2616             :         }
    2617             : 
    2618           0 :         if (sd_buf->sd->dacl) {
    2619           0 :                 sd_buf->sd->dacl->revision = NT4_ACL_REVISION;
    2620             :         }
    2621             : 
    2622           0 :         sd_size = ndr_size_security_descriptor(sd_buf->sd, 0);
    2623             : 
    2624           0 :         sd_buf->sd_size = sd_size;
    2625             : 
    2626           0 :         *r->out.sd_buf = sd_buf;
    2627             : 
    2628           0 :         werr = WERR_OK;
    2629             : 
    2630           0 : error_exit:
    2631             : 
    2632           0 :         if (fsp) {
    2633           0 :                 close_file_free(NULL, &fsp, NORMAL_CLOSE);
    2634             :         }
    2635             : 
    2636           0 :         TALLOC_FREE(frame);
    2637           0 :         return werr;
    2638             : }
    2639             : 
    2640             : /***********************************************************************************
    2641             :  _srvsvc_NetSetFileSecurity
    2642             :  Win9x NT tools set security descriptor.
    2643             : ***********************************************************************************/
    2644             : 
    2645           0 : WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p,
    2646             :                                   struct srvsvc_NetSetFileSecurity *r)
    2647             : {
    2648           0 :         struct dcesrv_call_state *dce_call = p->dce_call;
    2649           0 :         struct auth_session_info *session_info =
    2650           0 :                 dcesrv_call_session_info(dce_call);
    2651           0 :         TALLOC_CTX *frame = talloc_stackframe();
    2652           0 :         const struct loadparm_substitution *lp_sub =
    2653           0 :                 loadparm_s3_global_substitution();
    2654           0 :         struct smb_filename *smb_fname = NULL;
    2655           0 :         char *servicename = NULL;
    2656           0 :         struct files_struct *dirfsp = NULL;
    2657           0 :         files_struct *fsp = NULL;
    2658             :         SMB_STRUCT_STAT st;
    2659             :         NTSTATUS nt_status;
    2660             :         WERROR werr;
    2661           0 :         struct conn_struct_tos *c = NULL;
    2662           0 :         connection_struct *conn = NULL;
    2663             :         int snum;
    2664           0 :         struct security_descriptor *psd = NULL;
    2665           0 :         uint32_t security_info_sent = 0;
    2666           0 :         uint32_t ucf_flags = 0;
    2667           0 :         NTTIME twrp = 0;
    2668             : 
    2669           0 :         ZERO_STRUCT(st);
    2670             : 
    2671           0 :         if (!r->in.share) {
    2672           0 :                 werr = WERR_NERR_NETNAMENOTFOUND;
    2673           0 :                 goto error_exit;
    2674             :         }
    2675             : 
    2676           0 :         snum = find_service(frame, r->in.share, &servicename);
    2677           0 :         if (!servicename) {
    2678           0 :                 werr = WERR_NOT_ENOUGH_MEMORY;
    2679           0 :                 goto error_exit;
    2680             :         }
    2681             : 
    2682           0 :         if (snum == -1) {
    2683           0 :                 DEBUG(10, ("Could not find service %s\n", servicename));
    2684           0 :                 werr = WERR_NERR_NETNAMENOTFOUND;
    2685           0 :                 goto error_exit;
    2686             :         }
    2687             : 
    2688           0 :         nt_status = create_conn_struct_tos_cwd(global_messaging_context(),
    2689             :                                                snum,
    2690           0 :                                                lp_path(frame, lp_sub, snum),
    2691             :                                                session_info,
    2692             :                                                &c);
    2693           0 :         if (!NT_STATUS_IS_OK(nt_status)) {
    2694           0 :                 DEBUG(10, ("create_conn_struct failed: %s\n",
    2695             :                            nt_errstr(nt_status)));
    2696           0 :                 werr = ntstatus_to_werror(nt_status);
    2697           0 :                 goto error_exit;
    2698             :         }
    2699           0 :         conn = c->conn;
    2700             : 
    2701           0 :         nt_status = filename_convert_dirfsp(frame,
    2702             :                                             conn,
    2703             :                                             r->in.file,
    2704             :                                             ucf_flags,
    2705             :                                             twrp,
    2706             :                                             &dirfsp,
    2707             :                                             &smb_fname);
    2708           0 :         if (!NT_STATUS_IS_OK(nt_status)) {
    2709           0 :                 werr = ntstatus_to_werror(nt_status);
    2710           0 :                 goto error_exit;
    2711             :         }
    2712             : 
    2713           0 :         nt_status = SMB_VFS_CREATE_FILE(
    2714             :                 conn,                                   /* conn */
    2715             :                 NULL,                                   /* req */
    2716             :                 dirfsp,                                 /* dirfsp */
    2717             :                 smb_fname,                              /* fname */
    2718             :                 FILE_WRITE_ATTRIBUTES,                  /* access_mask */
    2719             :                 FILE_SHARE_READ|FILE_SHARE_WRITE,       /* share_access */
    2720             :                 FILE_OPEN,                              /* create_disposition*/
    2721             :                 0,                                      /* create_options */
    2722             :                 0,                                      /* file_attributes */
    2723             :                 INTERNAL_OPEN_ONLY,                     /* oplock_request */
    2724             :                 NULL,                                   /* lease */
    2725             :                 0,                                      /* allocation_size */
    2726             :                 0,                                      /* private_flags */
    2727             :                 NULL,                                   /* sd */
    2728             :                 NULL,                                   /* ea_list */
    2729             :                 &fsp,                                       /* result */
    2730             :                 NULL,                                   /* pinfo */
    2731             :                 NULL, NULL);                            /* create context */
    2732             : 
    2733           0 :         if (!NT_STATUS_IS_OK(nt_status)) {
    2734           0 :                 DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n",
    2735             :                          smb_fname_str_dbg(smb_fname)));
    2736           0 :                 werr = ntstatus_to_werror(nt_status);
    2737           0 :                 goto error_exit;
    2738             :         }
    2739             : 
    2740           0 :         psd = r->in.sd_buf->sd;
    2741           0 :         security_info_sent = r->in.securityinformation;
    2742             : 
    2743           0 :         nt_status = set_sd(fsp, psd, security_info_sent);
    2744             : 
    2745           0 :         if (!NT_STATUS_IS_OK(nt_status) ) {
    2746           0 :                 DEBUG(3,("_srvsvc_NetSetFileSecurity: Unable to set NT ACL "
    2747             :                          "on file %s\n", r->in.share));
    2748           0 :                 werr = WERR_ACCESS_DENIED;
    2749           0 :                 goto error_exit;
    2750             :         }
    2751             : 
    2752           0 :         werr = WERR_OK;
    2753             : 
    2754           0 : error_exit:
    2755             : 
    2756           0 :         if (fsp) {
    2757           0 :                 close_file_free(NULL, &fsp, NORMAL_CLOSE);
    2758             :         }
    2759             : 
    2760           0 :         TALLOC_FREE(frame);
    2761           0 :         return werr;
    2762             : }
    2763             : 
    2764             : /***********************************************************************************
    2765             :  It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
    2766             :  We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
    2767             :  These disks would the disks listed by this function.
    2768             :  Users could then create shares relative to these disks.  Watch out for moving these disks around.
    2769             :  "Nigel Williams" <nigel@veritas.com>.
    2770             : ***********************************************************************************/
    2771             : 
    2772             : static const char *server_disks[] = {"C:"};
    2773             : 
    2774           6 : static uint32_t get_server_disk_count(void)
    2775             : {
    2776           6 :         return sizeof(server_disks)/sizeof(server_disks[0]);
    2777             : }
    2778             : 
    2779           6 : static uint32_t init_server_disk_enum(uint32_t *resume)
    2780             : {
    2781           6 :         uint32_t server_disk_count = get_server_disk_count();
    2782             : 
    2783             :         /*resume can be an offset into the list for now*/
    2784             : 
    2785           6 :         if(*resume & 0x80000000)
    2786           0 :                 *resume = 0;
    2787             : 
    2788           6 :         if(*resume > server_disk_count)
    2789           0 :                 *resume = server_disk_count;
    2790             : 
    2791           6 :         return server_disk_count - *resume;
    2792             : }
    2793             : 
    2794           4 : static const char *next_server_disk_enum(uint32_t *resume)
    2795             : {
    2796             :         const char *disk;
    2797             : 
    2798           4 :         if(init_server_disk_enum(resume) == 0)
    2799           2 :                 return NULL;
    2800             : 
    2801           2 :         disk = server_disks[*resume];
    2802             : 
    2803           2 :         (*resume)++;
    2804             : 
    2805           2 :         DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
    2806             : 
    2807           2 :         return disk;
    2808             : }
    2809             : 
    2810             : /********************************************************************
    2811             :  _srvsvc_NetDiskEnum
    2812             : ********************************************************************/
    2813             : 
    2814           2 : WERROR _srvsvc_NetDiskEnum(struct pipes_struct *p,
    2815             :                            struct srvsvc_NetDiskEnum *r)
    2816             : {
    2817             :         uint32_t i;
    2818             :         const char *disk_name;
    2819           2 :         TALLOC_CTX *ctx = p->mem_ctx;
    2820             :         WERROR werr;
    2821           2 :         uint32_t resume = r->in.resume_handle ? *r->in.resume_handle : 0;
    2822             : 
    2823           2 :         werr = WERR_OK;
    2824             : 
    2825           2 :         *r->out.totalentries = init_server_disk_enum(&resume);
    2826             : 
    2827           2 :         r->out.info->disks = talloc_zero_array(ctx, struct srvsvc_NetDiskInfo0,
    2828             :                                                MAX_SERVER_DISK_ENTRIES);
    2829           2 :         W_ERROR_HAVE_NO_MEMORY(r->out.info->disks);
    2830             : 
    2831             :         /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/
    2832             : 
    2833           2 :         r->out.info->count = 0;
    2834             : 
    2835           4 :         for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) {
    2836             : 
    2837           2 :                 r->out.info->count++;
    2838             : 
    2839             :                 /*copy disk name into a unicode string*/
    2840             : 
    2841           2 :                 r->out.info->disks[i].disk = talloc_strdup(ctx, disk_name);
    2842           2 :                 W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
    2843             :         }
    2844             : 
    2845             :         /* add a terminating null string.  Is this there if there is more data to come? */
    2846             : 
    2847           2 :         r->out.info->count++;
    2848             : 
    2849           2 :         r->out.info->disks[i].disk = talloc_strdup(ctx, "");
    2850           2 :         W_ERROR_HAVE_NO_MEMORY(r->out.info->disks[i].disk);
    2851             : 
    2852           2 :         if (r->out.resume_handle) {
    2853           2 :                 *r->out.resume_handle = resume;
    2854             :         }
    2855             : 
    2856           2 :         return werr;
    2857             : }
    2858             : 
    2859             : /********************************************************************
    2860             :  _srvsvc_NetNameValidate
    2861             : ********************************************************************/
    2862             : 
    2863        5564 : WERROR _srvsvc_NetNameValidate(struct pipes_struct *p,
    2864             :                                struct srvsvc_NetNameValidate *r)
    2865             : {
    2866        5564 :         switch (r->in.name_type) {
    2867         380 :         case 0x9:
    2868         380 :                 if (!validate_net_name(r->in.name, INVALID_SHARENAME_CHARS,
    2869         380 :                                        strlen_m(r->in.name)))
    2870             :                 {
    2871          56 :                         DEBUG(5,("_srvsvc_NetNameValidate: Bad sharename \"%s\"\n",
    2872             :                                 r->in.name));
    2873          56 :                         return WERR_INVALID_NAME;
    2874             :                 }
    2875         324 :                 break;
    2876             : 
    2877        5184 :         default:
    2878        5184 :                 return WERR_INVALID_LEVEL;
    2879             :         }
    2880             : 
    2881         324 :         return WERR_OK;
    2882             : }
    2883             : 
    2884             : /*******************************************************************
    2885             : ********************************************************************/
    2886             : 
    2887             : struct enum_file_close_state {
    2888             :         struct srvsvc_NetFileClose *r;
    2889             :         struct messaging_context *msg_ctx;
    2890             : };
    2891             : 
    2892           0 : static int enum_file_close_fn(struct file_id id,
    2893             :                               const struct share_mode_data *d,
    2894             :                               const struct share_mode_entry *e,
    2895             :                               void *private_data)
    2896             : {
    2897             :         char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
    2898           0 :         struct enum_file_close_state *state =
    2899             :                 (struct enum_file_close_state *)private_data;
    2900           0 :         uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
    2901             : 
    2902           0 :         if (fid != state->r->in.fid) {
    2903           0 :                 return 0; /* Not this file. */
    2904             :         }
    2905             : 
    2906           0 :         if (!process_exists(e->pid) ) {
    2907           0 :                 return 0;
    2908             :         }
    2909             : 
    2910             :         /* Ok - send the close message. */
    2911           0 :         DBG_DEBUG("request to close file %s, %s\n", d->servicepath,
    2912             :                   share_mode_str(talloc_tos(), 0, &id, e));
    2913             : 
    2914           0 :         share_mode_entry_to_message(msg, &id, e);
    2915             : 
    2916           0 :         state->r->out.result = ntstatus_to_werror(
    2917             :                 messaging_send_buf(state->msg_ctx,
    2918             :                                 e->pid, MSG_SMB_CLOSE_FILE,
    2919             :                                 (uint8_t *)msg, sizeof(msg)));
    2920             : 
    2921           0 :         return 0;
    2922             : }
    2923             : 
    2924             : /********************************************************************
    2925             :  Close a file given a 32-bit file id.
    2926             : ********************************************************************/
    2927             : 
    2928           0 : WERROR _srvsvc_NetFileClose(struct pipes_struct *p,
    2929             :                             struct srvsvc_NetFileClose *r)
    2930             : {
    2931           0 :         struct dcesrv_call_state *dce_call = p->dce_call;
    2932           0 :         struct auth_session_info *session_info =
    2933           0 :                 dcesrv_call_session_info(dce_call);
    2934             :         struct enum_file_close_state state;
    2935             :         bool is_disk_op;
    2936             : 
    2937           0 :         DEBUG(5,("_srvsvc_NetFileClose: %d\n", __LINE__));
    2938             : 
    2939           0 :         is_disk_op = security_token_has_privilege(
    2940           0 :                 session_info->security_token, SEC_PRIV_DISK_OPERATOR);
    2941             : 
    2942           0 :         if (session_info->unix_token->uid != sec_initial_uid() && !is_disk_op) {
    2943           0 :                 return WERR_ACCESS_DENIED;
    2944             :         }
    2945             : 
    2946             :         /* enum_file_close_fn sends the close message to
    2947             :          * the relevant smbd process. */
    2948             : 
    2949           0 :         r->out.result = WERR_FILE_NOT_FOUND;
    2950           0 :         state.r = r;
    2951           0 :         state.msg_ctx = p->msg_ctx;
    2952           0 :         share_entry_forall(enum_file_close_fn, &state);
    2953           0 :         return r->out.result;
    2954             : }
    2955             : 
    2956             : /********************************************************************
    2957             : ********************************************************************/
    2958             : 
    2959           2 : WERROR _srvsvc_NetCharDevEnum(struct pipes_struct *p,
    2960             :                               struct srvsvc_NetCharDevEnum *r)
    2961             : {
    2962           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2963           2 :         return WERR_NOT_SUPPORTED;
    2964             : }
    2965             : 
    2966           0 : WERROR _srvsvc_NetCharDevGetInfo(struct pipes_struct *p,
    2967             :                                  struct srvsvc_NetCharDevGetInfo *r)
    2968             : {
    2969           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2970           0 :         return WERR_NOT_SUPPORTED;
    2971             : }
    2972             : 
    2973           0 : WERROR _srvsvc_NetCharDevControl(struct pipes_struct *p,
    2974             :                                  struct srvsvc_NetCharDevControl *r)
    2975             : {
    2976           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2977           0 :         return WERR_NOT_SUPPORTED;
    2978             : }
    2979             : 
    2980           2 : WERROR _srvsvc_NetCharDevQEnum(struct pipes_struct *p,
    2981             :                                struct srvsvc_NetCharDevQEnum *r)
    2982             : {
    2983           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2984           2 :         return WERR_NOT_SUPPORTED;
    2985             : }
    2986             : 
    2987           0 : WERROR _srvsvc_NetCharDevQGetInfo(struct pipes_struct *p,
    2988             :                                   struct srvsvc_NetCharDevQGetInfo *r)
    2989             : {
    2990           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2991           0 :         return WERR_NOT_SUPPORTED;
    2992             : }
    2993             : 
    2994           0 : WERROR _srvsvc_NetCharDevQSetInfo(struct pipes_struct *p,
    2995             :                                   struct srvsvc_NetCharDevQSetInfo *r)
    2996             : {
    2997           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2998           0 :         return WERR_NOT_SUPPORTED;
    2999             : }
    3000             : 
    3001           0 : WERROR _srvsvc_NetCharDevQPurge(struct pipes_struct *p,
    3002             :                                 struct srvsvc_NetCharDevQPurge *r)
    3003             : {
    3004           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3005           0 :         return WERR_NOT_SUPPORTED;
    3006             : }
    3007             : 
    3008           0 : WERROR _srvsvc_NetCharDevQPurgeSelf(struct pipes_struct *p,
    3009             :                                     struct srvsvc_NetCharDevQPurgeSelf *r)
    3010             : {
    3011           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3012           0 :         return WERR_NOT_SUPPORTED;
    3013             : }
    3014             : 
    3015           0 : WERROR _srvsvc_NetFileGetInfo(struct pipes_struct *p,
    3016             :                               struct srvsvc_NetFileGetInfo *r)
    3017             : {
    3018           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3019           0 :         return WERR_NOT_SUPPORTED;
    3020             : }
    3021             : 
    3022           4 : WERROR _srvsvc_NetShareCheck(struct pipes_struct *p,
    3023             :                              struct srvsvc_NetShareCheck *r)
    3024             : {
    3025           4 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3026           4 :         return WERR_NOT_SUPPORTED;
    3027             : }
    3028             : 
    3029           0 : WERROR _srvsvc_NetServerStatisticsGet(struct pipes_struct *p,
    3030             :                                       struct srvsvc_NetServerStatisticsGet *r)
    3031             : {
    3032           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3033           0 :         return WERR_NOT_SUPPORTED;
    3034             : }
    3035             : 
    3036           0 : WERROR _srvsvc_NetTransportAdd(struct pipes_struct *p,
    3037             :                                struct srvsvc_NetTransportAdd *r)
    3038             : {
    3039           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3040           0 :         return WERR_NOT_SUPPORTED;
    3041             : }
    3042             : 
    3043           2 : WERROR _srvsvc_NetTransportEnum(struct pipes_struct *p,
    3044             :                                 struct srvsvc_NetTransportEnum *r)
    3045             : {
    3046           2 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3047           2 :         return WERR_NOT_SUPPORTED;
    3048             : }
    3049             : 
    3050           0 : WERROR _srvsvc_NetTransportDel(struct pipes_struct *p,
    3051             :                                struct srvsvc_NetTransportDel *r)
    3052             : {
    3053           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3054           0 :         return WERR_NOT_SUPPORTED;
    3055             : }
    3056             : 
    3057           0 : WERROR _srvsvc_NetSetServiceBits(struct pipes_struct *p,
    3058             :                                  struct srvsvc_NetSetServiceBits *r)
    3059             : {
    3060           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3061           0 :         return WERR_NOT_SUPPORTED;
    3062             : }
    3063             : 
    3064           0 : WERROR _srvsvc_NetPathType(struct pipes_struct *p,
    3065             :                            struct srvsvc_NetPathType *r)
    3066             : {
    3067           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3068           0 :         return WERR_NOT_SUPPORTED;
    3069             : }
    3070             : 
    3071           0 : WERROR _srvsvc_NetPathCanonicalize(struct pipes_struct *p,
    3072             :                                    struct srvsvc_NetPathCanonicalize *r)
    3073             : {
    3074           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3075           0 :         return WERR_NOT_SUPPORTED;
    3076             : }
    3077             : 
    3078           0 : WERROR _srvsvc_NetPathCompare(struct pipes_struct *p,
    3079             :                               struct srvsvc_NetPathCompare *r)
    3080             : {
    3081           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3082           0 :         return WERR_NOT_SUPPORTED;
    3083             : }
    3084             : 
    3085           0 : WERROR _srvsvc_NETRPRNAMECANONICALIZE(struct pipes_struct *p,
    3086             :                                       struct srvsvc_NETRPRNAMECANONICALIZE *r)
    3087             : {
    3088           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3089           0 :         return WERR_NOT_SUPPORTED;
    3090             : }
    3091             : 
    3092           0 : WERROR _srvsvc_NetPRNameCompare(struct pipes_struct *p,
    3093             :                                 struct srvsvc_NetPRNameCompare *r)
    3094             : {
    3095           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3096           0 :         return WERR_NOT_SUPPORTED;
    3097             : }
    3098             : 
    3099           0 : WERROR _srvsvc_NetShareDelStart(struct pipes_struct *p,
    3100             :                                 struct srvsvc_NetShareDelStart *r)
    3101             : {
    3102           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3103           0 :         return WERR_NOT_SUPPORTED;
    3104             : }
    3105             : 
    3106           0 : WERROR _srvsvc_NetShareDelCommit(struct pipes_struct *p,
    3107             :                                  struct srvsvc_NetShareDelCommit *r)
    3108             : {
    3109           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3110           0 :         return WERR_NOT_SUPPORTED;
    3111             : }
    3112             : 
    3113           0 : WERROR _srvsvc_NetServerTransportAddEx(struct pipes_struct *p,
    3114             :                                        struct srvsvc_NetServerTransportAddEx *r)
    3115             : {
    3116           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3117           0 :         return WERR_NOT_SUPPORTED;
    3118             : }
    3119             : 
    3120           0 : WERROR _srvsvc_NetServerSetServiceBitsEx(struct pipes_struct *p,
    3121             :                                          struct srvsvc_NetServerSetServiceBitsEx *r)
    3122             : {
    3123           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3124           0 :         return WERR_NOT_SUPPORTED;
    3125             : }
    3126             : 
    3127           0 : WERROR _srvsvc_NETRDFSGETVERSION(struct pipes_struct *p,
    3128             :                                  struct srvsvc_NETRDFSGETVERSION *r)
    3129             : {
    3130           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3131           0 :         return WERR_NOT_SUPPORTED;
    3132             : }
    3133             : 
    3134           0 : WERROR _srvsvc_NETRDFSCREATELOCALPARTITION(struct pipes_struct *p,
    3135             :                                            struct srvsvc_NETRDFSCREATELOCALPARTITION *r)
    3136             : {
    3137           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3138           0 :         return WERR_NOT_SUPPORTED;
    3139             : }
    3140             : 
    3141           0 : WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(struct pipes_struct *p,
    3142             :                                            struct srvsvc_NETRDFSDELETELOCALPARTITION *r)
    3143             : {
    3144           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3145           0 :         return WERR_NOT_SUPPORTED;
    3146             : }
    3147             : 
    3148           0 : WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(struct pipes_struct *p,
    3149             :                                           struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r)
    3150             : {
    3151           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3152           0 :         return WERR_NOT_SUPPORTED;
    3153             : }
    3154             : 
    3155           0 : WERROR _srvsvc_NETRDFSSETSERVERINFO(struct pipes_struct *p,
    3156             :                                     struct srvsvc_NETRDFSSETSERVERINFO *r)
    3157             : {
    3158           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3159           0 :         return WERR_NOT_SUPPORTED;
    3160             : }
    3161             : 
    3162           0 : WERROR _srvsvc_NETRDFSCREATEEXITPOINT(struct pipes_struct *p,
    3163             :                                       struct srvsvc_NETRDFSCREATEEXITPOINT *r)
    3164             : {
    3165           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3166           0 :         return WERR_NOT_SUPPORTED;
    3167             : }
    3168             : 
    3169           0 : WERROR _srvsvc_NETRDFSDELETEEXITPOINT(struct pipes_struct *p,
    3170             :                                       struct srvsvc_NETRDFSDELETEEXITPOINT *r)
    3171             : {
    3172           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3173           0 :         return WERR_NOT_SUPPORTED;
    3174             : }
    3175             : 
    3176           0 : WERROR _srvsvc_NETRDFSMODIFYPREFIX(struct pipes_struct *p,
    3177             :                                    struct srvsvc_NETRDFSMODIFYPREFIX *r)
    3178             : {
    3179           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3180           0 :         return WERR_NOT_SUPPORTED;
    3181             : }
    3182             : 
    3183           0 : WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(struct pipes_struct *p,
    3184             :                                      struct srvsvc_NETRDFSFIXLOCALVOLUME *r)
    3185             : {
    3186           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3187           0 :         return WERR_NOT_SUPPORTED;
    3188             : }
    3189             : 
    3190           0 : WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(struct pipes_struct *p,
    3191             :                                             struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r)
    3192             : {
    3193           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3194           0 :         return WERR_NOT_SUPPORTED;
    3195             : }
    3196             : 
    3197           0 : WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(struct pipes_struct *p,
    3198             :                                         struct srvsvc_NETRSERVERTRANSPORTDELEX *r)
    3199             : {
    3200           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3201           0 :         return WERR_NOT_SUPPORTED;
    3202             : }
    3203             : 
    3204             : /* include the generated boilerplate */
    3205             : #include "librpc/gen_ndr/ndr_srvsvc_scompat.c"

Generated by: LCOV version 1.13