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

Generated by: LCOV version 1.14