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

Generated by: LCOV version 1.14