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 abartlet/fix-coverage dd10fb34 Lines: 919 1390 66.1 %
Date: 2021-09-23 10:06:22 Functions: 47 99 47.5 %

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

Generated by: LCOV version 1.13