diff options
Diffstat (limited to 'source3/rpc_server/srv_srvsvc_nt.c')
-rw-r--r-- | source3/rpc_server/srv_srvsvc_nt.c | 2152 |
1 files changed, 1093 insertions, 1059 deletions
diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c index 2af4c79002..f23d6dfcb9 100644 --- a/source3/rpc_server/srv_srvsvc_nt.c +++ b/source3/rpc_server/srv_srvsvc_nt.c @@ -5,7 +5,6 @@ * Copyright (C) Jeremy Allison 2001. * Copyright (C) Nigel Williams 2001. * Copyright (C) Gerald (Jerry) Carter 2006. - * Copyright (C) Jelmer Vernooij 2006. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,10 +24,7 @@ #include "includes.h" -#define MAX_SERVER_DISK_ENTRIES 15 - extern const struct generic_mapping file_generic_mapping; -extern userdom_struct current_user_info; #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV @@ -38,8 +34,8 @@ extern userdom_struct current_user_info; struct file_enum_count { TALLOC_CTX *ctx; const char *username; - uint32 count; - struct srvsvc_NetFileInfo3 *info; + int count; + FILE_INFO_3 *info; }; struct sess_file_count { @@ -56,7 +52,7 @@ static int pipe_enum_fn( struct db_record *rec, void *p) { struct pipe_open_rec prec; struct file_enum_count *fenum = (struct file_enum_count *)p; - struct srvsvc_NetFileInfo3 *f; + FILE_INFO_3 *f; int i = fenum->count; pstring fullpath; const char *username; @@ -79,25 +75,19 @@ static int pipe_enum_fn( struct db_record *rec, void *p) snprintf( fullpath, sizeof(fullpath), "\\PIPE\\%s", prec.name ); - f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, - struct srvsvc_NetFileInfo3, i+1 ); + f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, FILE_INFO_3, i+1 ); if ( !f ) { DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1)); return 1; } - fenum->info = f; - fenum->info[i].fid = (uint32)((procid_to_pid(&prec.pid)<<16) & prec.pnum); - fenum->info[i].permissions = (FILE_READ_DATA|FILE_WRITE_DATA); - fenum->info[i].num_locks = 0; - fenum->info[i].user = talloc_move(fenum->ctx, &username); - if (!(fenum->info[i].path = talloc_strdup( - fenum->ctx, fullpath))) { - /* There's not much we can do here. */ - fenum->info[i].path = ""; - } - + init_srv_file_info3( + &fenum->info[i], + (uint32)((procid_to_pid(&prec.pid)<<16) & prec.pnum), + (FILE_READ_DATA|FILE_WRITE_DATA), + 0, username, fullpath); + fenum->count++; return 0; @@ -107,15 +97,15 @@ static int pipe_enum_fn( struct db_record *rec, void *p) ********************************************************************/ static WERROR net_enum_pipes( TALLOC_CTX *ctx, const char *username, - struct srvsvc_NetFileInfo3 **info, - uint32 *count, uint32 *resume ) + FILE_INFO_3 **info, + uint32 *count, uint32 resume ) { struct file_enum_count fenum; - + fenum.ctx = ctx; fenum.username = username; - fenum.info = *info; fenum.count = *count; + fenum.info = *info; if (connections_traverse(pipe_enum_fn, &fenum) == -1) { DEBUG(0,("net_enum_pipes: traverse of connections.tdb " @@ -136,10 +126,10 @@ static void enum_file_fn( const struct share_mode_entry *e, const char *sharepath, const char *fname, void *private_data ) { - struct file_enum_count *fenum = - (struct file_enum_count *)private_data; + struct file_enum_count *fenum = + (struct file_enum_count *)private_data; - struct srvsvc_NetFileInfo3 *f; + FILE_INFO_3 *f; int i = fenum->count; files_struct fsp; struct byte_range_lock *brl; @@ -150,7 +140,7 @@ static void enum_file_fn( const struct share_mode_entry *e, /* If the pid was not found delete the entry from connections.tdb */ - if (!process_exists(e->pid)) { + if ( !process_exists(e->pid) ) { return; } @@ -161,8 +151,7 @@ static void enum_file_fn( const struct share_mode_entry *e, return; } - f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, - struct srvsvc_NetFileInfo3, i+1 ); + f = TALLOC_REALLOC_ARRAY( fenum->ctx, fenum->info, FILE_INFO_3, i+1 ); if ( !f ) { DEBUG(0,("conn_enum_fn: realloc failed for %d items\n", i+1)); return; @@ -174,7 +163,7 @@ static void enum_file_fn( const struct share_mode_entry *e, ZERO_STRUCT( fsp ); fsp.file_id = e->id; - if ( (brl = brl_get_locks_readonly(NULL,&fsp)) != NULL ) { + if ( (brl = brl_get_locks(NULL,&fsp)) != NULL ) { num_locks = brl->num_locks; TALLOC_FREE( brl ); } @@ -189,15 +178,13 @@ static void enum_file_fn( const struct share_mode_entry *e, /* mask out create (what ever that is) */ permissions = e->share_access & (FILE_READ_DATA|FILE_WRITE_DATA); - fenum->info[i].fid = e->share_file_id; - fenum->info[i].permissions = permissions; - fenum->info[i].num_locks = num_locks; - fenum->info[i].user = talloc_move(fenum->ctx, &username); - if (!(fenum->info[i].path = talloc_strdup( - fenum->ctx, fullpath))) { - /* There's not much we can do here. */ - fenum->info[i].path = ""; - } + /* now fill in the FILE_INFO_3 struct */ + init_srv_file_info3( &fenum->info[i], + e->share_file_id, + permissions, + num_locks, + username, + fullpath ); fenum->count++; } @@ -206,8 +193,8 @@ static void enum_file_fn( const struct share_mode_entry *e, ********************************************************************/ static WERROR net_enum_files( TALLOC_CTX *ctx, const char *username, - struct srvsvc_NetFileInfo3 **info, - uint32 *count, uint32 *resume ) + FILE_INFO_3 **info, + uint32 *count, uint32 resume ) { struct file_enum_count f_enum_cnt; @@ -225,19 +212,19 @@ static WERROR net_enum_files( TALLOC_CTX *ctx, const char *username, } /******************************************************************* - Utility function to get the 'type' of a share from a share definition. + Utility function to get the 'type' of a share from an snum. ********************************************************************/ -static uint32 get_share_type(const struct share_params *params) +static uint32 get_share_type(int snum) { - char *net_name = lp_servicename(params->service); + char *net_name = lp_servicename(snum); int len_net_name = strlen(net_name); /* work out the share type */ uint32 type = STYPE_DISKTREE; - if (lp_print_ok(params->service)) + if (lp_print_ok(snum)) type = STYPE_PRINTQ; - if (strequal(lp_fstype(params->service), "IPC")) + if (strequal(lp_fstype(snum), "IPC")) type = STYPE_IPC; if (net_name[len_net_name-1] == '$') type |= STYPE_HIDDEN; @@ -249,70 +236,65 @@ static uint32 get_share_type(const struct share_params *params) Fill in a share info level 0 structure. ********************************************************************/ -static void init_srv_share_info_0(pipes_struct *p, struct srvsvc_NetShareInfo0 *sh0, - const struct share_params *params) +static void init_srv_share_info_0(pipes_struct *p, SRV_SHARE_INFO_0 *sh0, int snum) { - sh0->name = lp_servicename(params->service); + pstring net_name; + + pstrcpy(net_name, lp_servicename(snum)); + + init_srv_share_info0(&sh0->info_0, net_name); + init_srv_share_info0_str(&sh0->info_0_str, net_name); } /******************************************************************* Fill in a share info level 1 structure. ********************************************************************/ -static void init_srv_share_info_1(pipes_struct *p, struct srvsvc_NetShareInfo1 *sh1, - const struct share_params *params) +static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1, int snum) { - connection_struct *conn = p->conn; + pstring remark; - sh1->comment = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)), - conn->user, conn->connectpath, conn->gid, - get_current_username(), - current_user_info.domain, - lp_comment(params->service)); + char *net_name = lp_servicename(snum); + pstrcpy(remark, lp_comment(snum)); + standard_sub_conn(p->conn, remark,sizeof(remark)); - sh1->name = lp_servicename(params->service); - sh1->type = get_share_type(params); + init_srv_share_info1(&sh1->info_1, net_name, get_share_type(snum), remark); + init_srv_share_info1_str(&sh1->info_1_str, net_name, remark); } /******************************************************************* Fill in a share info level 2 structure. ********************************************************************/ -static void init_srv_share_info_2(pipes_struct *p, struct srvsvc_NetShareInfo2 *sh2, - const struct share_params *params) +static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int snum) { - connection_struct *conn = p->conn; - char *remark; - char *path; - int max_connections = lp_max_connections(params->service); + pstring remark; + pstring path; + pstring passwd; + int max_connections = lp_max_connections(snum); uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff; int count = 0; - char *net_name = lp_servicename(params->service); + char *net_name = lp_servicename(snum); - remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)), - conn->user, conn->connectpath, conn->gid, - get_current_username(), - current_user_info.domain, - lp_comment(params->service)); - path = talloc_asprintf(p->mem_ctx, "C:%s", - lp_pathname(params->service)); + pstrcpy(remark, lp_comment(snum)); + standard_sub_conn(p->conn, remark,sizeof(remark)); + pstrcpy(path, "C:"); + pstrcat(path, lp_pathname(snum)); /* - * Change / to \\ so that win2k will see it as a valid path. This was - * added to enable use of browsing in win2k add share dialog. + * Change / to \\ so that win2k will see it as a valid path. This was added to + * enable use of browsing in win2k add share dialog. */ string_replace(path, '/', '\\'); + pstrcpy(passwd, ""); + count = count_current_connections( net_name, False ); - sh2->name = net_name; - sh2->type = get_share_type(params); - sh2->comment = remark; - sh2->permissions = 0; - sh2->max_users = max_uses; - sh2->current_users = count; - sh2->path = path; - sh2->password = ""; + init_srv_share_info2(&sh2->info_2, net_name, get_share_type(snum), + remark, 0, max_uses, count, path, passwd); + + init_srv_share_info2_str(&sh2->info_2_str, net_name, remark, path, passwd); } /******************************************************************* @@ -344,40 +326,28 @@ static void map_generic_share_sd_bits(SEC_DESC *psd) Fill in a share info level 501 structure. ********************************************************************/ -static void init_srv_share_info_501(pipes_struct *p, struct srvsvc_NetShareInfo501 *sh501, - const struct share_params *params) +static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501, int snum) { - connection_struct *conn = p->conn; - char *remark; - const char *net_name = lp_servicename(params->service); + pstring remark; - remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)), - conn->user, conn->connectpath, conn->gid, - get_current_username(), - current_user_info.domain, - lp_comment(params->service)); + const char *net_name = lp_servicename(snum); + pstrcpy(remark, lp_comment(snum)); + standard_sub_conn(p->conn, remark, sizeof(remark)); - - sh501->name = net_name; - sh501->type = get_share_type(params); - sh501->comment = remark; - sh501->csc_policy = (lp_csc_policy(params->service) << 4); + init_srv_share_info501(&sh501->info_501, net_name, get_share_type(snum), remark, (lp_csc_policy(snum) << 4)); + init_srv_share_info501_str(&sh501->info_501_str, net_name, remark); } /******************************************************************* Fill in a share info level 502 structure. ********************************************************************/ -static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo502 *sh502, - const struct share_params *params) +static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, int snum) { - int max_connections = lp_max_connections(params->service); - uint32 max_uses = max_connections!=0 ? max_connections : 0xffffffff; - connection_struct *conn = p->conn; - int count; - char *net_name; - char *remark; - char *path; + pstring net_name; + pstring remark; + pstring path; + pstring passwd; SEC_DESC *sd; size_t sd_size; TALLOC_CTX *ctx = p->mem_ctx; @@ -385,112 +355,87 @@ static void init_srv_share_info_502(pipes_struct *p, struct srvsvc_NetShareInfo5 ZERO_STRUCTP(sh502); - net_name = lp_servicename(params->service); - count = count_current_connections( net_name, False ); - - remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)), - conn->user, conn->connectpath, conn->gid, - get_current_username(), - current_user_info.domain, - lp_comment(params->service)); - - path = talloc_asprintf(p->mem_ctx, "C:%s", - lp_pathname(params->service)); + pstrcpy(net_name, lp_servicename(snum)); + pstrcpy(remark, lp_comment(snum)); + standard_sub_conn(p->conn, remark,sizeof(remark)); + pstrcpy(path, "C:"); + pstrcat(path, lp_pathname(snum)); /* - * Change / to \\ so that win2k will see it as a valid path. This was - * added to enable use of browsing in win2k add share dialog. + * Change / to \\ so that win2k will see it as a valid path. This was added to + * enable use of browsing in win2k add share dialog. */ string_replace(path, '/', '\\'); - sd = get_share_security(ctx, lp_servicename(params->service), - &sd_size); + pstrcpy(passwd, ""); + + sd = get_share_security(ctx, lp_servicename(snum), &sd_size); - sh502->name = net_name; - sh502->type = get_share_type(params); - sh502->comment = remark; - sh502->path = path; - sh502->password = ""; - sh502->sd = sd; - sh502->permissions = 0; - sh502->max_users = max_uses; - sh502->current_users = count; - sh502->unknown = 1; + init_srv_share_info502(&sh502->info_502, net_name, get_share_type(snum), remark, 0, 0xffffffff, 1, path, passwd, sd, sd_size); + init_srv_share_info502_str(&sh502->info_502_str, net_name, remark, path, passwd, sd, sd_size); } /*************************************************************************** Fill in a share info level 1004 structure. ***************************************************************************/ -static void init_srv_share_info_1004(pipes_struct *p, - struct srvsvc_NetShareInfo1004* sh1004, - const struct share_params *params) +static void init_srv_share_info_1004(pipes_struct *p, SRV_SHARE_INFO_1004* sh1004, int snum) { - connection_struct *conn = p->conn; - char *remark; + pstring remark; - remark = talloc_sub_advanced(p->mem_ctx, lp_servicename(SNUM(conn)), - conn->user, conn->connectpath, conn->gid, - get_current_username(), - current_user_info.domain, - lp_comment(params->service)); + pstrcpy(remark, lp_comment(snum)); + standard_sub_conn(p->conn, remark, sizeof(remark)); ZERO_STRUCTP(sh1004); - - sh1004->comment = remark; + + init_srv_share_info1004(&sh1004->info_1004, remark); + init_srv_share_info1004_str(&sh1004->info_1004_str, remark); } /*************************************************************************** Fill in a share info level 1005 structure. ***************************************************************************/ -static void init_srv_share_info_1005(pipes_struct *p, - struct srvsvc_NetShareInfo1005* sh1005, - const struct share_params *params) +static void init_srv_share_info_1005(pipes_struct *p, SRV_SHARE_INFO_1005* sh1005, int snum) { - sh1005->dfs_flags = 0; + sh1005->share_info_flags = 0; - if(lp_host_msdfs() && lp_msdfs_root(params->service)) - sh1005->dfs_flags |= + if(lp_host_msdfs() && lp_msdfs_root(snum)) + sh1005->share_info_flags |= SHARE_1005_IN_DFS | SHARE_1005_DFS_ROOT; - sh1005->dfs_flags |= - lp_csc_policy(params->service) << SHARE_1005_CSC_POLICY_SHIFT; + sh1005->share_info_flags |= + lp_csc_policy(snum) << SHARE_1005_CSC_POLICY_SHIFT; } /*************************************************************************** Fill in a share info level 1006 structure. ***************************************************************************/ -static void init_srv_share_info_1006(pipes_struct *p, - struct srvsvc_NetShareInfo1006* sh1006, - const struct share_params *params) +static void init_srv_share_info_1006(pipes_struct *p, SRV_SHARE_INFO_1006* sh1006, int snum) { - sh1006->max_users = -1; + sh1006->max_uses = -1; } /*************************************************************************** Fill in a share info level 1007 structure. ***************************************************************************/ -static void init_srv_share_info_1007(pipes_struct *p, - struct srvsvc_NetShareInfo1007* sh1007, - const struct share_params *params) +static void init_srv_share_info_1007(pipes_struct *p, SRV_SHARE_INFO_1007* sh1007, int snum) { + pstring alternate_directory_name = ""; uint32 flags = 0; ZERO_STRUCTP(sh1007); - sh1007->flags = flags; - sh1007->alternate_directory_name = ""; + init_srv_share_info1007(&sh1007->info_1007, flags, alternate_directory_name); + init_srv_share_info1007_str(&sh1007->info_1007_str, alternate_directory_name); } /******************************************************************* Fill in a share info level 1501 structure. ********************************************************************/ -static void init_srv_share_info_1501(pipes_struct *p, - struct sec_desc_buf *sh1501, - const struct share_params *params) +static void init_srv_share_info_1501(pipes_struct *p, SRV_SHARE_INFO_1501 *sh1501, int snum) { SEC_DESC *sd; size_t sd_size; @@ -498,282 +443,350 @@ static void init_srv_share_info_1501(pipes_struct *p, ZERO_STRUCTP(sh1501); - sd = get_share_security(ctx, lp_servicename(params->service), - &sd_size); + sd = get_share_security(ctx, lp_servicename(snum), &sd_size); - sh1501->sd = sd; + sh1501->sdb = make_sec_desc_buf(p->mem_ctx, sd_size, sd); } /******************************************************************* True if it ends in '$'. ********************************************************************/ -static BOOL is_hidden_share(const struct share_params *params) +static BOOL is_hidden_share(int snum) { - const char *net_name = lp_servicename(params->service); + const char *net_name = lp_servicename(snum); - return (net_name[strlen(net_name) - 1] == '$'); + return (net_name[strlen(net_name) - 1] == '$') ? True : False; } /******************************************************************* Fill in a share info structure. ********************************************************************/ -static WERROR init_srv_share_info_ctr(pipes_struct *p, - union srvsvc_NetShareCtr *ctr, - uint32 info_level, uint32 *resume_hnd, - uint32 *total_entries, BOOL all_shares) +static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr, + uint32 info_level, uint32 *resume_hnd, uint32 *total_entries, BOOL all_shares) { + int num_entries = 0; + int num_services = 0; + int snum; TALLOC_CTX *ctx = p->mem_ctx; - struct share_iterator *shares; - struct share_params *share; - WERROR result = WERR_NOMEM; DEBUG(5,("init_srv_share_info_ctr\n")); - ZERO_STRUCTP(ctr); + ZERO_STRUCTPN(ctr); - if (resume_hnd) { - *resume_hnd = 0; - } + ctr->info_level = ctr->switch_value = info_level; + *resume_hnd = 0; /* Ensure all the usershares are loaded. */ become_root(); - load_usershare_shares(); + num_services = load_usershare_shares(); load_registry_shares(); unbecome_root(); - *total_entries = 0; - - if (!(shares = share_list_all(ctx))) { - DEBUG(5, ("Could not list shares\n")); - return WERR_ACCESS_DENIED; + /* Count the number of entries. */ + for (snum = 0; snum < num_services; snum++) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) + num_entries++; } + *total_entries = num_entries; + ctr->num_entries2 = ctr->num_entries = num_entries; + ctr->ptr_share_info = ctr->ptr_entries = 1; + + if (!num_entries) + return True; + switch (info_level) { case 0: - if (!(ctr->ctr0 = TALLOC_ZERO_P( - p->mem_ctx, struct srvsvc_NetShareCtr0))) { - goto done; + { + SRV_SHARE_INFO_0 *info0 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_0, num_entries); + int i = 0; + + if (!info0) { + return False; + } + + for (snum = *resume_hnd; snum < num_services; snum++) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { + init_srv_share_info_0(p, &info0[i++], snum); + } } + + ctr->share.info0 = info0; break; + + } + case 1: - if (!(ctr->ctr1 = TALLOC_ZERO_P( - p->mem_ctx, struct srvsvc_NetShareCtr1))) { - goto done; + { + SRV_SHARE_INFO_1 *info1 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1, num_entries); + int i = 0; + + if (!info1) { + return False; + } + + for (snum = *resume_hnd; snum < num_services; snum++) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { + init_srv_share_info_1(p, &info1[i++], snum); + } } + + ctr->share.info1 = info1; break; + } + case 2: - if (!(ctr->ctr2 = TALLOC_ZERO_P( - p->mem_ctx, struct srvsvc_NetShareCtr2))) { - goto done; + { + SRV_SHARE_INFO_2 *info2 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_2, num_entries); + int i = 0; + + if (!info2) { + return False; + } + + for (snum = *resume_hnd; snum < num_services; snum++) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { + init_srv_share_info_2(p, &info2[i++], snum); + } } + + ctr->share.info2 = info2; break; + } + case 501: - if (!(ctr->ctr501 = TALLOC_ZERO_P( - p->mem_ctx, struct srvsvc_NetShareCtr501))) { - goto done; + { + SRV_SHARE_INFO_501 *info501 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_501, num_entries); + int i = 0; + + if (!info501) { + return False; } + + for (snum = *resume_hnd; snum < num_services; snum++) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { + init_srv_share_info_501(p, &info501[i++], snum); + } + } + + ctr->share.info501 = info501; break; + } + case 502: - if (!(ctr->ctr502 = TALLOC_ZERO_P( - p->mem_ctx, struct srvsvc_NetShareCtr502))) { - goto done; + { + SRV_SHARE_INFO_502 *info502 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_502, num_entries); + int i = 0; + + if (!info502) { + return False; } + + for (snum = *resume_hnd; snum < num_services; snum++) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { + init_srv_share_info_502(p, &info502[i++], snum); + } + } + + ctr->share.info502 = info502; break; + } + + /* here for completeness but not currently used with enum (1004 - 1501)*/ + case 1004: - if (!(ctr->ctr1004 = TALLOC_ZERO_P( - p->mem_ctx, struct srvsvc_NetShareCtr1004))) { - goto done; + { + SRV_SHARE_INFO_1004 *info1004 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1004, num_entries); + int i = 0; + + if (!info1004) { + return False; + } + + for (snum = *resume_hnd; snum < num_services; snum++) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { + init_srv_share_info_1004(p, &info1004[i++], snum); + } } + + ctr->share.info1004 = info1004; break; + } + case 1005: - if (!(ctr->ctr1005 = TALLOC_ZERO_P( - p->mem_ctx, struct srvsvc_NetShareCtr1005))) { - goto done; + { + SRV_SHARE_INFO_1005 *info1005 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1005, num_entries); + int i = 0; + + if (!info1005) { + return False; } + + for (snum = *resume_hnd; snum < num_services; snum++) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { + init_srv_share_info_1005(p, &info1005[i++], snum); + } + } + + ctr->share.info1005 = info1005; break; + } + case 1006: - if (!(ctr->ctr1006 = TALLOC_ZERO_P( - p->mem_ctx, struct srvsvc_NetShareCtr1006))) { - goto done; + { + SRV_SHARE_INFO_1006 *info1006 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1006, num_entries); + int i = 0; + + if (!info1006) { + return False; + } + + for (snum = *resume_hnd; snum < num_services; snum++) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { + init_srv_share_info_1006(p, &info1006[i++], snum); + } } + + ctr->share.info1006 = info1006; break; + } + case 1007: - if (!(ctr->ctr1007 = TALLOC_ZERO_P( - p->mem_ctx, struct srvsvc_NetShareCtr1007))) { - goto done; + { + SRV_SHARE_INFO_1007 *info1007 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1007, num_entries); + int i = 0; + + if (!info1007) { + return False; } + + for (snum = *resume_hnd; snum < num_services; snum++) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { + init_srv_share_info_1007(p, &info1007[i++], snum); + } + } + + ctr->share.info1007 = info1007; break; + } + case 1501: - if (!(ctr->ctr1501 = TALLOC_ZERO_P( - p->mem_ctx, struct srvsvc_NetShareCtr1501))) { - goto done; + { + SRV_SHARE_INFO_1501 *info1501 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1501, num_entries); + int i = 0; + + if (!info1501) { + return False; + } + + for (snum = *resume_hnd; snum < num_services; snum++) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { + init_srv_share_info_1501(p, &info1501[i++], snum); + } } + + ctr->share.info1501 = info1501; break; + } default: - DEBUG(5,("init_srv_share_info_ctr: unsupported switch " - "value %d\n", info_level)); - return WERR_UNKNOWN_LEVEL; + DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level)); + return False; } - while ((share = next_share(shares)) != NULL) { - if (!lp_browseable(share->service)) { - continue; - } - if (!all_shares && is_hidden_share(share)) { - continue; - } + return True; +} + +/******************************************************************* + Inits a SRV_R_NET_SHARE_ENUM structure. +********************************************************************/ + +static void init_srv_r_net_share_enum(pipes_struct *p, SRV_R_NET_SHARE_ENUM *r_n, + uint32 info_level, uint32 resume_hnd, BOOL all) +{ + DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__)); + + if (init_srv_share_info_ctr(p, &r_n->ctr, info_level, + &resume_hnd, &r_n->total_entries, all)) { + r_n->status = WERR_OK; + } else { + r_n->status = WERR_UNKNOWN_LEVEL; + } + init_enum_hnd(&r_n->enum_hnd, resume_hnd); +} + +/******************************************************************* + Inits a SRV_R_NET_SHARE_GET_INFO structure. +********************************************************************/ + +static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_INFO *r_n, + char *share_name, uint32 info_level) +{ + WERROR status = WERR_OK; + int snum; + + DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__)); + + r_n->info.switch_value = info_level; + + snum = find_service(share_name); + + if (snum >= 0) { switch (info_level) { case 0: - { - struct srvsvc_NetShareInfo0 i; - init_srv_share_info_0(p, &i, share); - ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo0, i, - &ctr->ctr0->array, &ctr->ctr0->count); - if (ctr->ctr0->array == NULL) { - return WERR_NOMEM; - } - *total_entries = ctr->ctr0->count; + init_srv_share_info_0(p, &r_n->info.share.info0, snum); break; - } - case 1: - { - struct srvsvc_NetShareInfo1 i; - init_srv_share_info_1(p, &i, share); - ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1, i, - &ctr->ctr1->array, &ctr->ctr1->count); - if (ctr->ctr1->array == NULL) { - return WERR_NOMEM; - } - *total_entries = ctr->ctr1->count; + init_srv_share_info_1(p, &r_n->info.share.info1, snum); break; - } - case 2: - { - struct srvsvc_NetShareInfo2 i; - init_srv_share_info_2(p, &i, share); - ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo2, i, - &ctr->ctr2->array, &ctr->ctr2->count); - if (ctr->ctr2->array == NULL) { - return WERR_NOMEM; - } - *total_entries = ctr->ctr2->count; + init_srv_share_info_2(p, &r_n->info.share.info2, snum); break; - } - case 501: - { - struct srvsvc_NetShareInfo501 i; - init_srv_share_info_501(p, &i, share); - ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo501, i, - &ctr->ctr501->array, &ctr->ctr501->count); - if (ctr->ctr501->array == NULL) { - return WERR_NOMEM; - } - *total_entries = ctr->ctr501->count; + init_srv_share_info_501(p, &r_n->info.share.info501, snum); break; - } - case 502: - { - struct srvsvc_NetShareInfo502 i; - init_srv_share_info_502(p, &i, share); - ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo502, i, - &ctr->ctr502->array, &ctr->ctr502->count); - if (ctr->ctr502->array == NULL) { - return WERR_NOMEM; - } - *total_entries = ctr->ctr502->count; + init_srv_share_info_502(p, &r_n->info.share.info502, snum); break; - } - /* here for completeness but not currently used with enum - * (1004 - 1501)*/ - + /* here for completeness */ case 1004: - { - struct srvsvc_NetShareInfo1004 i; - init_srv_share_info_1004(p, &i, share); - ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1004, i, - &ctr->ctr1004->array, &ctr->ctr1004->count); - if (ctr->ctr1004->array == NULL) { - return WERR_NOMEM; - } - *total_entries = ctr->ctr1004->count; + init_srv_share_info_1004(p, &r_n->info.share.info1004, snum); break; - } - case 1005: - { - struct srvsvc_NetShareInfo1005 i; - init_srv_share_info_1005(p, &i, share); - ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1005, i, - &ctr->ctr1005->array, &ctr->ctr1005->count); - if (ctr->ctr1005->array == NULL) { - return WERR_NOMEM; - } - *total_entries = ctr->ctr1005->count; + init_srv_share_info_1005(p, &r_n->info.share.info1005, snum); break; - } + /* here for completeness 1006 - 1501 */ case 1006: - { - struct srvsvc_NetShareInfo1006 i; - init_srv_share_info_1006(p, &i, share); - ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1006, i, - &ctr->ctr1006->array, &ctr->ctr1006->count); - if (ctr->ctr1006->array == NULL) { - return WERR_NOMEM; - } - *total_entries = ctr->ctr1006->count; + init_srv_share_info_1006(p, &r_n->info.share.info1006, snum); break; - } - case 1007: - { - struct srvsvc_NetShareInfo1007 i; - init_srv_share_info_1007(p, &i, share); - ADD_TO_ARRAY(ctx, struct srvsvc_NetShareInfo1007, i, - &ctr->ctr1007->array, &ctr->ctr1007->count); - if (ctr->ctr1007->array == NULL) { - return WERR_NOMEM; - } - *total_entries = ctr->ctr1007->count; + init_srv_share_info_1007(p, &r_n->info.share.info1007, snum); break; - } - case 1501: - { - struct sec_desc_buf i; - init_srv_share_info_1501(p, &i, share); - ADD_TO_ARRAY(ctx, struct sec_desc_buf, i, - &ctr->ctr1501->array, &ctr->ctr1501->count); - if (ctr->ctr1501->array == NULL) { - return WERR_NOMEM; - } - *total_entries = ctr->ctr1501->count; + init_srv_share_info_1501(p, &r_n->info.share.info1501, snum); + break; + default: + DEBUG(5,("init_srv_net_share_get_info: unsupported switch value %d\n", info_level)); + status = WERR_UNKNOWN_LEVEL; break; } - } - - TALLOC_FREE(share); + } else { + status = WERR_INVALID_NAME; } - result = WERR_OK; - done: - TALLOC_FREE(shares); - return result; + r_n->info.ptr_share_ctr = W_ERROR_IS_OK(status) ? 1 : 0; + r_n->status = status; } /******************************************************************* fill in a sess info level 0 structure. ********************************************************************/ -static void init_srv_sess_info_0(pipes_struct *p, struct srvsvc_NetSessCtr0 *ss0, uint32 *snum, uint32 *stot) +static void init_srv_sess_info_0(pipes_struct *p, SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot) { struct sessionid *session_list; uint32 num_entries = 0; @@ -788,34 +801,37 @@ static void init_srv_sess_info_0(pipes_struct *p, struct srvsvc_NetSessCtr0 *ss0 DEBUG(5,("init_srv_sess_0_ss0\n")); - ss0->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetSessInfo0, *stot); - if (snum) { - for (; (*snum) < (*stot); (*snum)++) { - ss0->array[num_entries].client = session_list[(*snum)].remote_machine; + for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) { + init_srv_sess_info0( &ss0->info_0[num_entries], session_list[(*snum)].remote_machine); num_entries++; } - ss0->count = num_entries; + ss0->num_entries_read = num_entries; + ss0->ptr_sess_info = num_entries > 0 ? 1 : 0; + ss0->num_entries_read2 = num_entries; if ((*snum) >= (*stot)) { (*snum) = 0; } } else { - ss0->array = NULL; - ss0->count = 0; + ss0->num_entries_read = 0; + ss0->ptr_sess_info = 0; + ss0->num_entries_read2 = 0; } } /******************************************************************* ********************************************************************/ +/* global needed to make use of the share_mode_forall() callback */ +static struct sess_file_count s_file_cnt; + static void sess_file_fn( const struct share_mode_entry *e, - const char *sharepath, const char *fname, - void *private_data ) + const char *sharepath, const char *fname, void *state ) { - struct sess_file_count *sess = (struct sess_file_count *)private_data; + struct sess_file_count *sess = &s_file_cnt; if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) { sess->count++; @@ -829,13 +845,11 @@ static void sess_file_fn( const struct share_mode_entry *e, static int net_count_files( uid_t uid, struct server_id pid ) { - struct sess_file_count s_file_cnt; - s_file_cnt.count = 0; s_file_cnt.uid = uid; s_file_cnt.pid = pid; - share_mode_forall( sess_file_fn, (void *)&s_file_cnt ); + share_mode_forall( sess_file_fn, NULL ); return s_file_cnt.count; } @@ -844,15 +858,16 @@ static int net_count_files( uid_t uid, struct server_id pid ) fill in a sess info level 1 structure. ********************************************************************/ -static void init_srv_sess_info_1(pipes_struct *p, struct srvsvc_NetSessCtr1 *ss1, uint32 *snum, uint32 *stot) +static void init_srv_sess_info_1(pipes_struct *p, SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot) { struct sessionid *session_list; uint32 num_entries = 0; time_t now = time(NULL); if ( !snum ) { - ss1->count = 0; - ss1->array = NULL; + ss1->num_entries_read = 0; + ss1->ptr_sess_info = 0; + ss1->num_entries_read2 = 0; (*stot) = 0; @@ -860,16 +875,14 @@ static void init_srv_sess_info_1(pipes_struct *p, struct srvsvc_NetSessCtr1 *ss1 } if (ss1 == NULL) { - if (snum != NULL) - (*snum) = 0; + (*snum) = 0; return; } (*stot) = list_sessions(p->mem_ctx, &session_list); - - ss1->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetSessInfo1, *stot); - for (; (*snum) < (*stot); (*snum)++) { + + for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) { uint32 num_files; uint32 connect_time; struct passwd *pw = sys_getpwnam(session_list[*snum].username); @@ -885,54 +898,52 @@ static void init_srv_sess_info_1(pipes_struct *p, struct srvsvc_NetSessCtr1 *ss1 num_files = net_count_files(pw->pw_uid, session_list[*snum].pid); guest = strequal( session_list[*snum].username, lp_guestaccount() ); - if (!(ss1->array[num_entries].client = talloc_strdup( - ss1->array, session_list[*snum].remote_machine))) { - ss1->array[num_entries].client = ""; - } - if (!(ss1->array[num_entries].user = talloc_strdup( - ss1->array, session_list[*snum].username))) { - ss1->array[num_entries].user = ""; - } - ss1->array[num_entries].num_open = num_files; - ss1->array[num_entries].time = connect_time; - ss1->array[num_entries].idle_time = 0; - ss1->array[num_entries].user_flags = guest; - + init_srv_sess_info1( &ss1->info_1[num_entries], + session_list[*snum].remote_machine, + session_list[*snum].username, + num_files, + connect_time, + 0, + guest); num_entries++; } - ss1->count = num_entries; + ss1->num_entries_read = num_entries; + ss1->ptr_sess_info = num_entries > 0 ? 1 : 0; + ss1->num_entries_read2 = num_entries; if ((*snum) >= (*stot)) { (*snum) = 0; } + } /******************************************************************* makes a SRV_R_NET_SESS_ENUM structure. ********************************************************************/ -static WERROR init_srv_sess_info_ctr(pipes_struct *p, union srvsvc_NetSessCtr *ctr, +static WERROR init_srv_sess_info_ctr(pipes_struct *p, SRV_SESS_INFO_CTR *ctr, int switch_value, uint32 *resume_hnd, uint32 *total_entries) { WERROR status = WERR_OK; DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__)); + ctr->switch_value = switch_value; + switch (switch_value) { case 0: - ctr->ctr0 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr0); - init_srv_sess_info_0(p, ctr->ctr0, resume_hnd, total_entries); + init_srv_sess_info_0(p, &(ctr->sess.info0), resume_hnd, total_entries); + ctr->ptr_sess_ctr = 1; break; case 1: - ctr->ctr1 = talloc(p->mem_ctx, struct srvsvc_NetSessCtr1); - init_srv_sess_info_1(p, ctr->ctr1, resume_hnd, total_entries); + init_srv_sess_info_1(p, &(ctr->sess.info1), resume_hnd, total_entries); + ctr->ptr_sess_ctr = 1; break; default: DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n", switch_value)); - if (resume_hnd != NULL) - (*resume_hnd) = 0; + (*resume_hnd) = 0; (*total_entries) = 0; - ctr->ctr0 = NULL; + ctr->ptr_sess_ctr = 0; status = WERR_UNKNOWN_LEVEL; break; } @@ -941,42 +952,65 @@ static WERROR init_srv_sess_info_ctr(pipes_struct *p, union srvsvc_NetSessCtr *c } /******************************************************************* + makes a SRV_R_NET_SESS_ENUM structure. +********************************************************************/ + +static void init_srv_r_net_sess_enum(pipes_struct *p, SRV_R_NET_SESS_ENUM *r_n, + uint32 resume_hnd, int sess_level, int switch_value) +{ + DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__)); + + r_n->sess_level = sess_level; + + if (sess_level == -1) + r_n->status = WERR_UNKNOWN_LEVEL; + else + r_n->status = init_srv_sess_info_ctr(p, r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries); + + if (!W_ERROR_IS_OK(r_n->status)) + resume_hnd = 0; + + init_enum_hnd(&r_n->enum_hnd, resume_hnd); +} + +/******************************************************************* fill in a conn info level 0 structure. ********************************************************************/ -static void init_srv_conn_info_0(pipes_struct *p, struct srvsvc_NetConnCtr0 *ss0, uint32 *snum, uint32 *stot) +static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot) { uint32 num_entries = 0; (*stot) = 1; if (ss0 == NULL) { - if (snum != NULL) - (*snum) = 0; + (*snum) = 0; return; } DEBUG(5,("init_srv_conn_0_ss0\n")); if (snum) { - ss0->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetConnInfo0, *stot); - for (; (*snum) < (*stot); (*snum)++) { + for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) { - ss0->array[num_entries].conn_id = (*stot); + init_srv_conn_info0(&ss0->info_0[num_entries], (*stot)); /* move on to creating next connection */ /* move on to creating next conn */ num_entries++; } - ss0->count = num_entries; + ss0->num_entries_read = num_entries; + ss0->ptr_conn_info = num_entries > 0 ? 1 : 0; + ss0->num_entries_read2 = num_entries; if ((*snum) >= (*stot)) { (*snum) = 0; } } else { - ss0->array = NULL; - ss0->count = 0; + ss0->num_entries_read = 0; + ss0->ptr_conn_info = 0; + ss0->num_entries_read2 = 0; (*stot) = 0; } @@ -986,44 +1020,55 @@ static void init_srv_conn_info_0(pipes_struct *p, struct srvsvc_NetConnCtr0 *ss0 fill in a conn info level 1 structure. ********************************************************************/ -static void init_srv_conn_info_1(pipes_struct *p, struct srvsvc_NetConnCtr1 *ss1, uint32 *snum, uint32 *stot) +static void init_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1, + uint32 id, uint32 type, + uint32 num_opens, uint32 num_users, uint32 open_time, + const char *usr_name, const char *net_name) +{ + init_srv_conn_info1(se1 , id, type, num_opens, num_users, open_time, usr_name, net_name); + init_srv_conn_info1_str(str1, usr_name, net_name); +} + +/******************************************************************* + fill in a conn info level 1 structure. + ********************************************************************/ + +static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot) { uint32 num_entries = 0; (*stot) = 1; if (ss1 == NULL) { - if (snum != NULL) - (*snum) = 0; + (*snum) = 0; return; } DEBUG(5,("init_srv_conn_1_ss1\n")); if (snum) { - ss1->array = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetConnInfo1, *stot); - for (; (*snum) < (*stot); (*snum)++) { - ss1->array[num_entries].conn_id = (*stot); - ss1->array[num_entries].conn_type = 0x3; - ss1->array[num_entries].num_open = 1; - ss1->array[num_entries].num_users = 1; - ss1->array[num_entries].conn_time = 3; - ss1->array[num_entries].user = "dummy_user"; - ss1->array[num_entries].share = "IPC$"; + for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++) { + init_srv_conn_1_info(&ss1->info_1[num_entries], + &ss1->info_1_str[num_entries], + (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$"); /* move on to creating next connection */ /* move on to creating next conn */ num_entries++; } - ss1->count = num_entries; + ss1->num_entries_read = num_entries; + ss1->ptr_conn_info = num_entries > 0 ? 1 : 0; + ss1->num_entries_read2 = num_entries; + if ((*snum) >= (*stot)) { (*snum) = 0; } } else { - ss1->count = 0; - ss1->array = NULL; + ss1->num_entries_read = 0; + ss1->ptr_conn_info = 0; + ss1->num_entries_read2 = 0; (*stot) = 0; } @@ -1033,24 +1078,28 @@ static void init_srv_conn_info_1(pipes_struct *p, struct srvsvc_NetConnCtr1 *ss1 makes a SRV_R_NET_CONN_ENUM structure. ********************************************************************/ -static WERROR init_srv_conn_info_ctr(pipes_struct *p, union srvsvc_NetConnCtr *ctr, +static WERROR init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr, int switch_value, uint32 *resume_hnd, uint32 *total_entries) { WERROR status = WERR_OK; DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__)); + ctr->switch_value = switch_value; + switch (switch_value) { case 0: - init_srv_conn_info_0(p, ctr->ctr0, resume_hnd, total_entries); + init_srv_conn_info_0(&ctr->conn.info0, resume_hnd, total_entries); + ctr->ptr_conn_ctr = 1; break; case 1: - init_srv_conn_info_1(p, ctr->ctr1, resume_hnd, total_entries); + init_srv_conn_info_1(&ctr->conn.info1, resume_hnd, total_entries); + ctr->ptr_conn_ctr = 1; break; default: DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n", switch_value)); - ctr->ctr0 = NULL; - (*resume_hnd) = 0; + (*resume_hnd = 0); (*total_entries) = 0; + ctr->ptr_conn_ctr = 0; status = WERR_UNKNOWN_LEVEL; break; } @@ -1059,45 +1108,83 @@ static WERROR init_srv_conn_info_ctr(pipes_struct *p, union srvsvc_NetConnCtr *c } /******************************************************************* + makes a SRV_R_NET_CONN_ENUM structure. +********************************************************************/ + +static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n, + uint32 resume_hnd, int conn_level, int switch_value) +{ + DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__)); + + r_n->conn_level = conn_level; + if (conn_level == -1) + r_n->status = WERR_UNKNOWN_LEVEL; + else + r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries); + + if (!W_ERROR_IS_OK(r_n->status)) + resume_hnd = 0; + + init_enum_hnd(&r_n->enum_hnd, resume_hnd); +} + +/******************************************************************* makes a SRV_R_NET_FILE_ENUM structure. ********************************************************************/ -static WERROR net_file_enum_3(pipes_struct *p, union srvsvc_NetFileCtr *ctr, - uint32 *resume_hnd, const char *username, - uint32 *num_entries ) +static WERROR net_file_enum_3( const char *username, SRV_R_NET_FILE_ENUM *r, + uint32 resume_hnd ) { - WERROR status; + TALLOC_CTX *ctx = talloc_tos(); + SRV_FILE_INFO_CTR *ctr = &r->ctr; /* TODO -- Windows enumerates (b) active pipes (c) open directories and files */ - ctr->ctr3 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetFileCtr3); - - status = net_enum_files(p->mem_ctx, username, &ctr->ctr3->array, - num_entries, resume_hnd ); - if ( !W_ERROR_IS_OK(status)) - return status; + r->status = net_enum_files( ctx, username, &ctr->file.info3, + &ctr->num_entries, resume_hnd ); + if ( !W_ERROR_IS_OK(r->status)) + goto done; - status = net_enum_pipes(p->mem_ctx, username, &ctr->ctr3->array, - num_entries, resume_hnd ); - if ( !W_ERROR_IS_OK(status)) - return status; - - ctr->ctr3->count = *num_entries; + r->status = net_enum_pipes( ctx, username, &ctr->file.info3, + &ctr->num_entries, resume_hnd ); + if ( !W_ERROR_IS_OK(r->status)) + goto done; - return WERR_OK; + r->level = ctr->level = 3; + r->total_entries = ctr->num_entries; + /* ctr->num_entries = r->total_entries - resume_hnd; */ + ctr->num_entries2 = ctr->num_entries; + ctr->ptr_file_info = 1; + + r->status = WERR_OK; + +done: + if ( ctr->num_entries > 0 ) + ctr->ptr_entries = 1; + + init_enum_hnd(&r->enum_hnd, 0); + + return r->status; } /******************************************************************* *******************************************************************/ -WERROR _srvsvc_NetFileEnum(pipes_struct *p, struct srvsvc_NetFileEnum *r) +WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u) { - switch ( *r->in.level ) { - case 3: - return net_file_enum_3(p, r->in.ctr, r->in.resume_handle, - r->in.user, r->out.totalentries ); + switch ( q_u->level ) { + case 3: { + char *username; + if (!(username = rpcstr_pull_unistr2_talloc( + p->mem_ctx, q_u->username))) { + return WERR_NOMEM; + } + + return net_file_enum_3(username, r_u, + get_enum_hnd(&q_u->enum_hnd)); + } default: return WERR_UNKNOWN_LEVEL; } @@ -1109,11 +1196,15 @@ WERROR _srvsvc_NetFileEnum(pipes_struct *p, struct srvsvc_NetFileEnum *r) net server get info ********************************************************************/ -WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p, struct srvsvc_NetSrvGetInfo *r) +WERROR _srv_net_srv_get_info(pipes_struct *p, SRV_Q_NET_SRV_GET_INFO *q_u, SRV_R_NET_SRV_GET_INFO *r_u) { WERROR status = WERR_OK; + SRV_INFO_CTR *ctr = TALLOC_P(p->mem_ctx, SRV_INFO_CTR); - ZERO_STRUCTP(r->out.info); + if (!ctr) + return WERR_NOMEM; + + ZERO_STRUCTP(ctr); DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__)); @@ -1122,108 +1213,133 @@ WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p, struct srvsvc_NetSrvGetInfo *r) return WERR_ACCESS_DENIED; } - switch (r->in.level) { + switch (q_u->switch_value) { /* Technically level 102 should only be available to Administrators but there isn't anything super-secret here, as most of it is made up. */ case 102: - r->out.info->info102 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetSrvInfo102); - - r->out.info->info102->platform_id = 500; - r->out.info->info102->version_major = lp_major_announce_version(); - r->out.info->info102->version_minor = lp_minor_announce_version(); - r->out.info->info102->server_name = global_myname(); - r->out.info->info102->server_type = lp_default_server_announce(); - r->out.info->info102->userpath = "C:\\"; - r->out.info->info102->licenses = 10000; - r->out.info->info102->anndelta = 3000; - r->out.info->info102->disc = 0xf; - r->out.info->info102->users = 0xffffffff; - r->out.info->info102->hidden = 0; - r->out.info->info102->announce = 240; - r->out.info->info102->comment = lp_serverstring(); + init_srv_info_102(&ctr->srv.sv102, + 500, global_myname(), + string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH), + lp_major_announce_version(), lp_minor_announce_version(), + lp_default_server_announce(), + 0xffffffff, /* users */ + 0xf, /* disc */ + 0, /* hidden */ + 240, /* announce */ + 3000, /* announce delta */ + 100000, /* licenses */ + "c:\\"); /* user path */ break; case 101: - r->out.info->info101 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetSrvInfo101); - r->out.info->info101->platform_id = 500; - r->out.info->info101->server_name = global_myname(); - r->out.info->info101->version_major = lp_major_announce_version(); - r->out.info->info101->version_minor = lp_minor_announce_version(); - r->out.info->info101->server_type = lp_default_server_announce(); - r->out.info->info101->comment = lp_serverstring(); + init_srv_info_101(&ctr->srv.sv101, + 500, global_myname(), + lp_major_announce_version(), lp_minor_announce_version(), + lp_default_server_announce(), + string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH)); break; case 100: - r->out.info->info100 = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetSrvInfo100); - r->out.info->info100->platform_id = 500; - r->out.info->info100->server_name = global_myname(); + init_srv_info_100(&ctr->srv.sv100, 500, global_myname()); break; default: - return WERR_UNKNOWN_LEVEL; + status = WERR_UNKNOWN_LEVEL; break; } + /* set up the net server get info structure */ + init_srv_r_net_srv_get_info(r_u, q_u->switch_value, ctr, status); + DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__)); - return status; + return r_u->status; } /******************************************************************* net server set info ********************************************************************/ -WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p, struct srvsvc_NetSrvSetInfo *r) +WERROR _srv_net_srv_set_info(pipes_struct *p, SRV_Q_NET_SRV_SET_INFO *q_u, SRV_R_NET_SRV_SET_INFO *r_u) { + WERROR status = WERR_OK; + + DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__)); + /* Set up the net server set info structure. */ - if (r->out.parm_error) { - *r->out.parm_error = 0; - } - return WERR_OK; + + init_srv_r_net_srv_set_info(r_u, 0x0, status); + + DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__)); + + return r_u->status; } /******************************************************************* net conn enum ********************************************************************/ -WERROR _srvsvc_NetConnEnum(pipes_struct *p, struct srvsvc_NetConnEnum *r) +WERROR _srv_net_conn_enum(pipes_struct *p, SRV_Q_NET_CONN_ENUM *q_u, SRV_R_NET_CONN_ENUM *r_u) { DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__)); - ZERO_STRUCTP(r->out.ctr); + r_u->ctr = TALLOC_P(p->mem_ctx, SRV_CONN_INFO_CTR); + if (!r_u->ctr) + return WERR_NOMEM; + + ZERO_STRUCTP(r_u->ctr); /* set up the */ - return init_srv_conn_info_ctr(p, r->out.ctr, *r->in.level, r->in.resume_handle, r->out.totalentries); + init_srv_r_net_conn_enum(r_u, + get_enum_hnd(&q_u->enum_hnd), + q_u->conn_level, + q_u->ctr->switch_value); + + DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__)); + + return r_u->status; } /******************************************************************* net sess enum ********************************************************************/ -WERROR _srvsvc_NetSessEnum(pipes_struct *p, struct srvsvc_NetSessEnum *r) +WERROR _srv_net_sess_enum(pipes_struct *p, SRV_Q_NET_SESS_ENUM *q_u, SRV_R_NET_SESS_ENUM *r_u) { DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__)); - ZERO_STRUCTP(r->out.ctr); + r_u->ctr = TALLOC_P(p->mem_ctx, SRV_SESS_INFO_CTR); + if (!r_u->ctr) + return WERR_NOMEM; + + ZERO_STRUCTP(r_u->ctr); /* set up the */ - return init_srv_sess_info_ctr(p, r->out.ctr, - *r->in.level, - r->in.resume_handle, - r->out.totalentries); + init_srv_r_net_sess_enum(p, r_u, + get_enum_hnd(&q_u->enum_hnd), + q_u->sess_level, + q_u->ctr->switch_value); + + DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__)); + + return r_u->status; } /******************************************************************* net sess del ********************************************************************/ -WERROR _srvsvc_NetSessDel(pipes_struct *p, struct srvsvc_NetSessDel *r) +WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SESS_DEL *r_u) { struct sessionid *session_list; + struct current_user user; int num_sessions, snum; - WERROR status; + fstring username; + fstring machine; + BOOL not_root = False; - char *machine = talloc_strdup(p->mem_ctx, r->in.server_unc); + rpcstr_pull_unistr2_fstring(username, &q_u->uni_user_name); + rpcstr_pull_unistr2_fstring(machine, &q_u->uni_cli_name); /* strip leading backslashes if any */ while (machine[0] == '\\') { @@ -1234,11 +1350,13 @@ WERROR _srvsvc_NetSessDel(pipes_struct *p, struct srvsvc_NetSessDel *r) DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__)); - status = WERR_ACCESS_DENIED; + r_u->status = WERR_ACCESS_DENIED; + + get_current_user(&user, p); /* fail out now if you are not root or not a domain admin */ - if ((p->pipe_user.ut.uid != sec_initial_uid()) && + if ((user.ut.uid != sec_initial_uid()) && ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) { goto done; @@ -1246,30 +1364,41 @@ WERROR _srvsvc_NetSessDel(pipes_struct *p, struct srvsvc_NetSessDel *r) for (snum = 0; snum < num_sessions; snum++) { - if ((strequal(session_list[snum].username, r->in.user) || r->in.user[0] == '\0' ) && - strequal(session_list[snum].remote_machine, machine)) { + if ((strequal(session_list[snum].username, username) || username[0] == '\0' ) && + strequal(session_list[snum].remote_machine, machine)) { + NTSTATUS ntstat; + + if (user.ut.uid != sec_initial_uid()) { + not_root = True; + become_root(); + } ntstat = messaging_send(smbd_messaging_context(), session_list[snum].pid, MSG_SHUTDOWN, &data_blob_null); - + if (NT_STATUS_IS_OK(ntstat)) - status = WERR_OK; + r_u->status = WERR_OK; + + if (not_root) + unbecome_root(); } } DEBUG(5,("_srv_net_sess_del: %d\n", __LINE__)); + done: - return status; + + return r_u->status; } /******************************************************************* Net share enum all. ********************************************************************/ -WERROR _srvsvc_NetShareEnumAll(pipes_struct *p, struct srvsvc_NetShareEnumAll *r) +WERROR _srv_net_share_enum_all(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u) { DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__)); @@ -1279,15 +1408,20 @@ WERROR _srvsvc_NetShareEnumAll(pipes_struct *p, struct srvsvc_NetShareEnumAll *r } /* Create the list of shares for the response. */ - return init_srv_share_info_ctr(p, r->out.ctr, *r->in.level, - r->in.resume_handle, r->out.totalentries, True); + init_srv_r_net_share_enum(p, r_u, + q_u->ctr.info_level, + get_enum_hnd(&q_u->enum_hnd), True); + + DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__)); + + return r_u->status; } /******************************************************************* Net share enum. ********************************************************************/ -WERROR _srvsvc_NetShareEnum(pipes_struct *p, struct srvsvc_NetShareEnum *r) +WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET_SHARE_ENUM *r_u) { DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__)); @@ -1297,80 +1431,32 @@ WERROR _srvsvc_NetShareEnum(pipes_struct *p, struct srvsvc_NetShareEnum *r) } /* Create the list of shares for the response. */ - return init_srv_share_info_ctr(p, r->out.ctr, *r->in.level, - r->in.resume_handle, r->out.totalentries, False); + init_srv_r_net_share_enum(p, r_u, + q_u->ctr.info_level, + get_enum_hnd(&q_u->enum_hnd), False); + + DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__)); + + return r_u->status; } /******************************************************************* Net share get info. ********************************************************************/ -WERROR _srvsvc_NetShareGetInfo(pipes_struct *p, struct srvsvc_NetShareGetInfo *r) +WERROR _srv_net_share_get_info(pipes_struct *p, SRV_Q_NET_SHARE_GET_INFO *q_u, SRV_R_NET_SHARE_GET_INFO *r_u) { - const struct share_params *params; - - params = get_share_params(p->mem_ctx, r->in.share_name); + fstring share_name; - if (params != NULL) { - switch (r->in.level) { - case 0: - r->out.info->info0 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo0); - init_srv_share_info_0(p, r->out.info->info0, params); - break; - case 1: - r->out.info->info1 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1); - init_srv_share_info_1(p, r->out.info->info1, params); - break; - case 2: - r->out.info->info2 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo2); - init_srv_share_info_2(p, r->out.info->info2, params); - break; - case 501: - r->out.info->info501 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo501); - init_srv_share_info_501(p, r->out.info->info501, params); - break; - case 502: - r->out.info->info502 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo502); - init_srv_share_info_502(p, r->out.info->info502, params); - break; + DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__)); - /* here for completeness */ - case 1004: - r->out.info->info1004 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1004); - init_srv_share_info_1004(p, r->out.info->info1004, params); - break; - case 1005: - r->out.info->info1005 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1005); - init_srv_share_info_1005(p, r->out.info->info1005, params); - break; + /* Create the list of shares for the response. */ + unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name)); + init_srv_r_net_share_get_info(p, r_u, share_name, q_u->info_level); - /* here for completeness 1006 - 1501 */ - case 1006: - r->out.info->info1006 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1006); - init_srv_share_info_1006(p, r->out.info->info1006, - params); - break; - case 1007: - r->out.info->info1007 = talloc(p->mem_ctx, struct srvsvc_NetShareInfo1007); - init_srv_share_info_1007(p, r->out.info->info1007, - params); - break; - case 1501: - r->out.info->info1501 = talloc(p->mem_ctx, struct sec_desc_buf); - init_srv_share_info_1501(p, r->out.info->info1501, - params); - break; - default: - DEBUG(5,("init_srv_net_share_get_info: unsupported " - "switch value %d\n", r->in.level)); - return WERR_UNKNOWN_LEVEL; - break; - } - } else { - return WERR_INVALID_NAME; - } + DEBUG(5,("_srv_net_share_get_info: %d\n", __LINE__)); - return WERR_OK; + return r_u->status; } /******************************************************************* @@ -1397,295 +1483,40 @@ char *valid_share_pathname(char *dos_pathname) return ptr; } -static void setval_helper(struct registry_key *key, const char *name, - const char *value, WERROR *err) -{ - struct registry_value val; - - if (!W_ERROR_IS_OK(*err)) { - return; - } - - ZERO_STRUCT(val); - val.type = REG_SZ; - val.v.sz.str = CONST_DISCARD(char *, value); - val.v.sz.len = strlen(value)+1; - - *err = reg_setvalue(key, name, &val); -} - -static WERROR add_share(const char *share_name, const char *path, - const char *comment, uint32 max_connections, - const struct nt_user_token *token, - BOOL is_disk_op) -{ - if (lp_add_share_cmd() && *lp_add_share_cmd()) { - char *command; - int ret; - - if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d", - lp_add_share_cmd(), dyn_CONFIGFILE, share_name, - path, comment, max_connections) == -1) { - return WERR_NOMEM; - } - - DEBUG(10,("add_share: Running [%s]\n", command )); - - /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/ - - if ( is_disk_op ) - become_root(); - - if ( (ret = smbrun(command, NULL)) == 0 ) { - /* Tell everyone we updated smb.conf. */ - message_send_all(smbd_messaging_context(), - MSG_SMB_CONF_UPDATED, - NULL, 0, NULL); - } - - if ( is_disk_op ) - unbecome_root(); - - /********* END SeDiskOperatorPrivilege BLOCK *********/ - - DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", - command, ret )); - - /* - * No fallback to registry shares, the user did define a add - * share command, so fail here. - */ - - SAFE_FREE(command); - return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED; - } - - if (lp_registry_shares()) { - char *keyname; - struct registry_key *key; - enum winreg_CreateAction action; - WERROR err; - TALLOC_CTX *mem_ctx; - - if (!(keyname = talloc_asprintf(NULL, "%s\\%s", KEY_SMBCONF, - share_name))) { - return WERR_NOMEM; - } - - mem_ctx = (TALLOC_CTX *)keyname; - - err = reg_create_path(mem_ctx, keyname, REG_KEY_WRITE, - is_disk_op ? get_root_nt_token():token, - &action, &key); - - if (action != REG_CREATED_NEW_KEY) { - err = WERR_ALREADY_EXISTS; - } - - if (!W_ERROR_IS_OK(err)) { - TALLOC_FREE(mem_ctx); - return err; - } - - setval_helper(key, "path", path, &err); - if ((comment != NULL) && (comment[0] != '\0')) { - setval_helper(key, "comment", comment, &err); - } - if (max_connections != 0) { - char tmp[16]; - snprintf(tmp, sizeof(tmp), "%d", max_connections); - setval_helper(key, "max connections", tmp, &err); - } - - if (!W_ERROR_IS_OK(err)) { - /* - * Hmmmm. We'd need transactions on the registry to - * get this right.... - */ - reg_delete_path(is_disk_op ? get_root_nt_token():token, - keyname); - } - TALLOC_FREE(mem_ctx); - return err; - } - - return WERR_ACCESS_DENIED; -} - -static WERROR delete_share(const char *sharename, - const struct nt_user_token *token, - BOOL is_disk_op) -{ - if (lp_delete_share_cmd() && *lp_delete_share_cmd()) { - char *command; - int ret; - - if (asprintf(&command, "%s \"%s\" \"%s\"", - lp_delete_share_cmd(), dyn_CONFIGFILE, - sharename)) { - return WERR_NOMEM; - } - - DEBUG(10,("delete_share: Running [%s]\n", command )); - - /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/ - - if ( is_disk_op ) - become_root(); - - if ( (ret = smbrun(command, NULL)) == 0 ) { - /* Tell everyone we updated smb.conf. */ - message_send_all(smbd_messaging_context(), - MSG_SMB_CONF_UPDATED, - NULL, 0, NULL); - } - - if ( is_disk_op ) - unbecome_root(); - - /********* END SeDiskOperatorPrivilege BLOCK *********/ - - SAFE_FREE(command); - - DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", - command, ret )); - return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED; - } - - if (lp_registry_shares()) { - char *keyname; - WERROR err; - - if (asprintf(&keyname, "%s\\%s", KEY_SMBCONF, - sharename) == -1) { - return WERR_NOMEM; - } - - err = reg_delete_path(is_disk_op ? get_root_nt_token():token, - keyname); - SAFE_FREE(keyname); - return err; - } - - return WERR_ACCESS_DENIED; -} - -static WERROR change_share(const char *share_name, const char *path, - const char *comment, uint32 max_connections, - const struct nt_user_token *token, - BOOL is_disk_op) -{ - if (lp_change_share_cmd() && *lp_change_share_cmd()) { - char *command; - int ret; - - if (asprintf(&command, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d", - lp_change_share_cmd(), dyn_CONFIGFILE, share_name, - path, comment, max_connections) == -1) { - return WERR_NOMEM; - } - - DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command)); - - /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/ - - if ( is_disk_op ) - become_root(); - - if ( (ret = smbrun(command, NULL)) == 0 ) { - /* Tell everyone we updated smb.conf. */ - message_send_all(smbd_messaging_context(), - MSG_SMB_CONF_UPDATED, - NULL, 0, NULL); - } - - if ( is_disk_op ) - unbecome_root(); - - /********* END SeDiskOperatorPrivilege BLOCK *********/ - - DEBUG(3,("_srv_net_share_set_info: Running [%s] returned " - "(%d)\n", command, ret )); - - SAFE_FREE(command); - - return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED; - } - - if (lp_registry_shares()) { - char *keyname; - struct registry_key *key; - WERROR err; - TALLOC_CTX *mem_ctx; - - if (!(keyname = talloc_asprintf(NULL, "%s\\%s", KEY_SMBCONF, - share_name))) { - return WERR_NOMEM; - } - - mem_ctx = (TALLOC_CTX *)keyname; - - err = reg_open_path(mem_ctx, keyname, REG_KEY_WRITE, - is_disk_op ? get_root_nt_token():token, - &key); - if (!W_ERROR_IS_OK(err)) { - TALLOC_FREE(mem_ctx); - return err; - } - - setval_helper(key, "path", path, &err); - - reg_deletevalue(key, "comment"); - if ((comment != NULL) && (comment[0] != '\0')) { - setval_helper(key, "comment", comment, &err); - } - - reg_deletevalue(key, "max connections"); - if (max_connections != 0) { - char tmp[16]; - snprintf(tmp, sizeof(tmp), "%d", max_connections); - setval_helper(key, "max connections", tmp, &err); - } - - TALLOC_FREE(mem_ctx); - return err; - } - - return WERR_ACCESS_DENIED; -} - /******************************************************************* Net share set info. Modify share details. ********************************************************************/ -WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r) +WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, SRV_R_NET_SHARE_SET_INFO *r_u) { - pstring comment; + struct current_user user; + pstring command; + fstring share_name; + fstring comment; pstring pathname; int type; int snum; + int ret; char *path; SEC_DESC *psd = NULL; SE_PRIV se_diskop = SE_DISK_OPERATOR; BOOL is_disk_op = False; int max_connections = 0; - fstring tmp_share_name; DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__)); - if (r->out.parm_error) { - *r->out.parm_error = 0; - } + unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name)); + + r_u->parm_error = 0; - if ( strequal(r->in.share_name,"IPC$") - || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") ) - || strequal(r->in.share_name,"global") ) + if ( strequal(share_name,"IPC$") + || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) + || strequal(share_name,"global") ) { return WERR_ACCESS_DENIED; } - fstrcpy(tmp_share_name, r->in.share_name); - snum = find_service(tmp_share_name); + snum = find_service(share_name); /* Does this share exist ? */ if (snum < 0) @@ -1695,39 +1526,47 @@ WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r if (lp_print_ok(snum)) return WERR_ACCESS_DENIED; - is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, - &se_diskop ); + get_current_user(&user,p); + + is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop ); /* fail out now if you are not root and not a disk op */ - if ( p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op ) + if ( user.ut.uid != sec_initial_uid() && !is_disk_op ) return WERR_ACCESS_DENIED; - switch (r->in.level) { + switch (q_u->info_level) { case 1: pstrcpy(pathname, lp_pathname(snum)); - pstrcpy(comment, r->in.info.info1->comment); - type = r->in.info.info1->type; + unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment)); + type = q_u->info.share.info2.info_2.type; psd = NULL; break; case 2: - pstrcpy(comment, r->in.info.info2->comment); - pstrcpy(pathname, r->in.info.info2->path); - type = r->in.info.info2->type; - max_connections = (r->in.info.info2->max_users == 0xffffffff) ? - 0 : r->in.info.info2->max_users; + unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(comment)); + unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(pathname)); + type = q_u->info.share.info2.info_2.type; + max_connections = (q_u->info.share.info2.info_2.max_uses == 0xffffffff) ? 0 : q_u->info.share.info2.info_2.max_uses; psd = NULL; break; +#if 0 + /* not supported on set but here for completeness */ + case 501: + unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment)); + type = q_u->info.share.info501.info_501.type; + psd = NULL; + break; +#endif case 502: - pstrcpy(comment, r->in.info.info502->comment); - pstrcpy(pathname, r->in.info.info502->path); - type = r->in.info.info502->type; - psd = r->in.info.info502->sd; + unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(comment)); + unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(pathname)); + type = q_u->info.share.info502.info_502.type; + psd = q_u->info.share.info502.info_502_str.sd; map_generic_share_sd_bits(psd); break; case 1004: pstrcpy(pathname, lp_pathname(snum)); - pstrcpy(comment, r->in.info.info1004->comment); + unistr2_to_ascii(comment, &q_u->info.share.info1004.info_1004_str.uni_remark, sizeof(comment)); type = STYPE_DISKTREE; break; case 1005: @@ -1735,14 +1574,12 @@ WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r user, so we must compare it to see if it's what is set in smb.conf, so that we can contine other ops like setting ACLs on a share */ - if (((r->in.info.info1005->dfs_flags & + if (((q_u->info.share.info1005.share_info_flags & SHARE_1005_CSC_POLICY_MASK) >> SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum)) return WERR_OK; else { - DEBUG(3, ("_srv_net_share_set_info: client is trying " - "to change csc policy from the network; " - "must be done with smb.conf\n")); + DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n")); return WERR_ACCESS_DENIED; } case 1006: @@ -1750,14 +1587,13 @@ WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r return WERR_ACCESS_DENIED; case 1501: pstrcpy(pathname, lp_pathname(snum)); - pstrcpy(comment, lp_comment(snum)); - psd = r->in.info.info1501->sd; + fstrcpy(comment, lp_comment(snum)); + psd = q_u->info.share.info1501.sdb->sd; map_generic_share_sd_bits(psd); type = STYPE_DISKTREE; break; default: - DEBUG(5,("_srv_net_share_set_info: unsupported switch value " - "%d\n", r->in.level)); + DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level)); return WERR_UNKNOWN_LEVEL; } @@ -1769,29 +1605,52 @@ WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r if (!(path = valid_share_pathname( pathname ))) return WERR_OBJECT_PATH_INVALID; - /* Ensure share name, pathname and comment don't contain '"' - * characters. */ - string_replace(tmp_share_name, '"', ' '); + /* Ensure share name, pathname and comment don't contain '"' characters. */ + string_replace(share_name, '"', ' '); string_replace(path, '"', ' '); string_replace(comment, '"', ' '); DEBUG(10,("_srv_net_share_set_info: change share command = %s\n", - lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" )); + lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" )); /* Only call modify function if something changed. */ - if (strcmp(path, lp_pathname(snum)) - || strcmp(comment, lp_comment(snum)) - || (lp_max_connections(snum) != max_connections) ) { - WERROR err; + if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) + || (lp_max_connections(snum) != max_connections) ) + { + if (!lp_change_share_cmd() || !*lp_change_share_cmd()) { + DEBUG(10,("_srv_net_share_set_info: No change share command\n")); + return WERR_ACCESS_DENIED; + } - err = change_share(tmp_share_name, path, comment, - max_connections, p->pipe_user.nt_user_token, - is_disk_op); + slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d", + lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment, max_connections ); - if (!W_ERROR_IS_OK(err)) { - return err; + DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command )); + + /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/ + + if ( is_disk_op ) + become_root(); + + if ( (ret = smbrun(command, NULL)) == 0 ) { + /* Tell everyone we updated smb.conf. */ + message_send_all(smbd_messaging_context(), + MSG_SMB_CONF_UPDATED, NULL, 0, + NULL); } + + if ( is_disk_op ) + unbecome_root(); + + /********* END SeDiskOperatorPrivilege BLOCK *********/ + + DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret )); + + if ( ret != 0 ) + return WERR_ACCESS_DENIED; + } else { + DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name )); } /* Replace SD if changed. */ @@ -1799,15 +1658,12 @@ WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r SEC_DESC *old_sd; size_t sd_size; - old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), - &sd_size); + old_sd = get_share_security(p->mem_ctx, lp_servicename(snum), &sd_size); if (old_sd && !sec_desc_equal(old_sd, psd)) { - if (!set_share_security(r->in.share_name, psd)) { - DEBUG(0,("_srv_net_share_set_info: Failed to " - "change security info in share %s.\n", - r->in.share_name )); - } + if (!set_share_security(share_name, psd)) + DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n", + share_name )); } } @@ -1816,38 +1672,44 @@ WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r return WERR_OK; } - /******************************************************************* Net share add. Call 'add_share_command "sharename" "pathname" "comment" "max connections = " ********************************************************************/ -WERROR _srvsvc_NetShareAdd(pipes_struct *p, struct srvsvc_NetShareAdd *r) +WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u) { - pstring share_name; - pstring comment; + struct current_user user; + pstring command; + fstring share_name; + fstring comment; pstring pathname; - char *path; int type; + int snum; + int ret; + char *path; SEC_DESC *psd = NULL; SE_PRIV se_diskop = SE_DISK_OPERATOR; BOOL is_disk_op; - uint32 max_connections = 0; - WERROR err; + int max_connections = 0; DEBUG(5,("_srv_net_share_add: %d\n", __LINE__)); - if (r->out.parm_error) { - *r->out.parm_error = 0; - } + r_u->parm_error = 0; - is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, - &se_diskop ); + get_current_user(&user,p); - if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op ) + is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop ); + + if (user.ut.uid != sec_initial_uid() && !is_disk_op ) return WERR_ACCESS_DENIED; - switch (r->in.level) { + if (!lp_add_share_cmd() || !*lp_add_share_cmd()) { + DEBUG(10,("_srv_net_share_add: No add share command\n")); + return WERR_ACCESS_DENIED; + } + + switch (q_u->info_level) { case 0: /* No path. Not enough info in a level 0 to do anything. */ return WERR_ACCESS_DENIED; @@ -1855,27 +1717,25 @@ WERROR _srvsvc_NetShareAdd(pipes_struct *p, struct srvsvc_NetShareAdd *r) /* Not enough info in a level 1 to do anything. */ return WERR_ACCESS_DENIED; case 2: - pstrcpy(share_name, r->in.info.info2->name); - pstrcpy(comment, r->in.info.info2->comment); - pstrcpy(pathname, r->in.info.info2->path); - max_connections = (r->in.info.info2->max_users == 0xffffffff) ? - 0 : r->in.info.info2->max_users; - type = r->in.info.info2->type; + unistr2_to_ascii(share_name, &q_u->info.share.info2.info_2_str.uni_netname, sizeof(share_name)); + unistr2_to_ascii(comment, &q_u->info.share.info2.info_2_str.uni_remark, sizeof(share_name)); + unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name)); + max_connections = (q_u->info.share.info2.info_2.max_uses == 0xffffffff) ? 0 : q_u->info.share.info2.info_2.max_uses; + type = q_u->info.share.info2.info_2.type; break; case 501: /* No path. Not enough info in a level 501 to do anything. */ return WERR_ACCESS_DENIED; case 502: - pstrcpy(share_name, r->in.info.info502->name); - pstrcpy(comment, r->in.info.info502->comment); - pstrcpy(pathname, r->in.info.info502->path); - type = r->in.info.info502->type; - psd = r->in.info.info502->sd; + unistr2_to_ascii(share_name, &q_u->info.share.info502.info_502_str.uni_netname, sizeof(share_name)); + unistr2_to_ascii(comment, &q_u->info.share.info502.info_502_str.uni_remark, sizeof(share_name)); + unistr2_to_ascii(pathname, &q_u->info.share.info502.info_502_str.uni_path, sizeof(share_name)); + type = q_u->info.share.info502.info_502.type; + psd = q_u->info.share.info502.info_502_str.sd; map_generic_share_sd_bits(psd); break; - /* none of the following contain share names. NetShareAdd - * does not have a separate parameter for the share name */ + /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */ case 1004: case 1005: @@ -1886,30 +1746,28 @@ WERROR _srvsvc_NetShareAdd(pipes_struct *p, struct srvsvc_NetShareAdd *r) /* DFS only level. */ return WERR_ACCESS_DENIED; default: - DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", - r->in.level)); + DEBUG(5,("_srv_net_share_add: unsupported switch value %d\n", q_u->info_level)); return WERR_UNKNOWN_LEVEL; } /* check for invalid share names */ - if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS, - sizeof(share_name) ) ) { - DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", - share_name)); + if ( !validate_net_name( share_name, INVALID_SHARENAME_CHARS, sizeof(share_name) ) ) { + DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", share_name)); return WERR_INVALID_NAME; } if ( strequal(share_name,"IPC$") || strequal(share_name,"global") - || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) ) + || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) ) { return WERR_ACCESS_DENIED; } - if (get_share_params(p->mem_ctx, share_name) != NULL) { - /* Share already exists. */ + snum = find_service(share_name); + + /* Share already exists. */ + if (snum >= 0) return WERR_ALREADY_EXISTS; - } /* We can only add disk shares. */ if (type != STYPE_DISKTREE) @@ -1919,24 +1777,45 @@ WERROR _srvsvc_NetShareAdd(pipes_struct *p, struct srvsvc_NetShareAdd *r) if (!(path = valid_share_pathname( pathname ))) return WERR_OBJECT_PATH_INVALID; - /* Ensure share name, pathname and comment don't contain '"' - * characters. */ - + /* Ensure share name, pathname and comment don't contain '"' characters. */ string_replace(share_name, '"', ' '); string_replace(path, '"', ' '); string_replace(comment, '"', ' '); - err = add_share(share_name, path, comment, max_connections, - p->pipe_user.nt_user_token, is_disk_op); + slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" %d", + lp_add_share_cmd(), + dyn_CONFIGFILE, + share_name, + path, + comment, + max_connections); + + DEBUG(10,("_srv_net_share_add: Running [%s]\n", command )); + + /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/ + + if ( is_disk_op ) + become_root(); - if (!W_ERROR_IS_OK(err)) { - return err; + if ( (ret = smbrun(command, NULL)) == 0 ) { + /* Tell everyone we updated smb.conf. */ + message_send_all(smbd_messaging_context(), + MSG_SMB_CONF_UPDATED, NULL, 0, NULL); } + if ( is_disk_op ) + unbecome_root(); + + /********* END SeDiskOperatorPrivilege BLOCK *********/ + + DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret )); + + if ( ret != 0 ) + return WERR_ACCESS_DENIED; + if (psd) { if (!set_share_security(share_name, psd)) { - DEBUG(0,("_srv_net_share_add: Failed to add security " - "info to share %s.\n", share_name )); + DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name )); } } @@ -1956,43 +1835,76 @@ WERROR _srvsvc_NetShareAdd(pipes_struct *p, struct srvsvc_NetShareAdd *r) a parameter. ********************************************************************/ -WERROR _srvsvc_NetShareDel(pipes_struct *p, struct srvsvc_NetShareDel *r) +WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u) { - struct share_params *params; + struct current_user user; + pstring command; + fstring share_name; + int ret; + int snum; SE_PRIV se_diskop = SE_DISK_OPERATOR; BOOL is_disk_op; - WERROR err; + struct share_params *params; DEBUG(5,("_srv_net_share_del: %d\n", __LINE__)); - if ( strequal(r->in.share_name, "IPC$") - || ( lp_enable_asu_support() && strequal(r->in.share_name,"ADMIN$") ) - || strequal(r->in.share_name, "global") ) + unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name)); + + if ( strequal(share_name,"IPC$") + || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) + || strequal(share_name,"global") ) { return WERR_ACCESS_DENIED; } - if (!(params = get_share_params(p->mem_ctx, r->in.share_name))) { - return WERR_NO_SUCH_SHARE; - } + if (!(params = get_share_params(p->mem_ctx, share_name))) { + return WERR_NO_SUCH_SHARE; + } + + snum = find_service(share_name); /* No change to printer shares. */ - if (lp_print_ok(params->service)) + if (lp_print_ok(snum)) return WERR_ACCESS_DENIED; - is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, - &se_diskop ); + get_current_user(&user,p); + + is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop ); - if (p->pipe_user.ut.uid != sec_initial_uid() && !is_disk_op ) + if (user.ut.uid != sec_initial_uid() && !is_disk_op ) return WERR_ACCESS_DENIED; - err = delete_share(lp_servicename(params->service), - p->pipe_user.nt_user_token, is_disk_op); + if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) { + DEBUG(10,("_srv_net_share_del: No delete share command\n")); + return WERR_ACCESS_DENIED; + } + + slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"", + lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum)); + + DEBUG(10,("_srv_net_share_del: Running [%s]\n", command )); + + /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/ + + if ( is_disk_op ) + become_root(); - if (!W_ERROR_IS_OK(err)) { - return err; + if ( (ret = smbrun(command, NULL)) == 0 ) { + /* Tell everyone we updated smb.conf. */ + message_send_all(smbd_messaging_context(), + MSG_SMB_CONF_UPDATED, NULL, 0, NULL); } + if ( is_disk_op ) + unbecome_root(); + + /********* END SeDiskOperatorPrivilege BLOCK *********/ + + DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret )); + + if ( ret != 0 ) + return WERR_ACCESS_DENIED; + /* Delete the SD in the database. */ delete_share_security(lp_servicename(params->service)); @@ -2001,28 +1913,22 @@ WERROR _srvsvc_NetShareDel(pipes_struct *p, struct srvsvc_NetShareDel *r) return WERR_OK; } -WERROR _srvsvc_NetShareDelSticky(pipes_struct *p, struct srvsvc_NetShareDelSticky *r) +WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u) { - struct srvsvc_NetShareDel s; - DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__)); - s.in.server_unc = r->in.server_unc; - s.in.share_name = r->in.share_name; - s.in.reserved = r->in.reserved; - - return _srvsvc_NetShareDel(p, &s); + return _srv_net_share_del(p, q_u, r_u); } /******************************************************************* time of day ********************************************************************/ -WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, struct srvsvc_NetRemoteTOD *r) +WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u) { + TIME_OF_DAY_INFO *tod; struct tm *t; time_t unixdate = time(NULL); - WERROR status = WERR_OK; /* We do this call first as if we do it *after* the gmtime call it overwrites the pointed-to values. JRA */ @@ -2031,91 +1937,106 @@ WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, struct srvsvc_NetRemoteTOD *r) DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__)); + if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, TIME_OF_DAY_INFO)) ) + return WERR_NOMEM; + + r_u->tod = tod; + r_u->ptr_srv_tod = 0x1; + r_u->status = WERR_OK; + + DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__)); + t = gmtime(&unixdate); /* set up the */ - r->out.info->elapsed = unixdate; - r->out.info->msecs = 0; - r->out.info->hours = t->tm_hour; - r->out.info->mins = t->tm_min; - r->out.info->secs = t->tm_sec; - r->out.info->hunds = 0; - r->out.info->timezone = zone; - r->out.info->tinterval = 10000; - r->out.info->day = t->tm_mday; - r->out.info->month = t->tm_mon + 1; - r->out.info->year = 1900+t->tm_year; - r->out.info->weekday = t->tm_wday; + init_time_of_day_info(tod, + unixdate, + 0, + t->tm_hour, + t->tm_min, + t->tm_sec, + 0, + zone, + 10000, + t->tm_mday, + t->tm_mon + 1, + 1900+t->tm_year, + t->tm_wday); DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__)); - return status; + return r_u->status; } /*********************************************************************************** Win9x NT tools get security descriptor. ***********************************************************************************/ -WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, struct srvsvc_NetGetFileSecurity *r) +WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC *q_u, + SRV_R_NET_FILE_QUERY_SECDESC *r_u) { SEC_DESC *psd = NULL; size_t sd_size; DATA_BLOB null_pw; + pstring filename_in; + char *filename = NULL; + pstring qualname; files_struct *fsp = NULL; SMB_STRUCT_STAT st; NTSTATUS nt_status; + struct current_user user; connection_struct *conn = NULL; - BOOL became_user = False; - WERROR status = WERR_OK; - char *tmp_file = NULL; + BOOL became_user = False; TALLOC_CTX *ctx = talloc_tos(); ZERO_STRUCT(st); + r_u->status = WERR_OK; + + unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname)); /* Null password is ok - we are already an authenticated user... */ null_pw = data_blob_null; + get_current_user(&user, p); + become_root(); - conn = make_connection(r->in.share, null_pw, "A:", p->pipe_user.vuid, &nt_status); + conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status); unbecome_root(); if (conn == NULL) { - DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", r->in.share)); - status = ntstatus_to_werror(nt_status); + DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname)); + r_u->status = ntstatus_to_werror(nt_status); goto error_exit; } if (!become_user(conn, conn->vuid)) { DEBUG(0,("_srv_net_file_query_secdesc: Can't become connected user!\n")); - status = WERR_ACCESS_DENIED; + r_u->status = WERR_ACCESS_DENIED; goto error_exit; } became_user = True; - if (!r->in.file) { - status = WERR_INVALID_PARAM; - goto error_exit; - } - nt_status = unix_convert(ctx, conn, r->in.file, False, &tmp_file, NULL, &st); + unistr2_to_ascii(filename_in, &q_u->uni_file_name, sizeof(filename_in)); + nt_status = unix_convert(ctx, conn, filename_in, False, &filename, NULL, &st); if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", r->in.file)); - status = WERR_ACCESS_DENIED; + DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", filename)); + r_u->status = WERR_ACCESS_DENIED; goto error_exit; } - nt_status = check_name(conn, tmp_file); + nt_status = check_name(conn, filename); if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", tmp_file)); - status = WERR_ACCESS_DENIED; + DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", filename)); + r_u->status = WERR_ACCESS_DENIED; goto error_exit; } - nt_status = open_file_stat(conn, NULL, tmp_file, &st, &fsp); - if (!NT_STATUS_IS_OK(nt_status)) { + nt_status = open_file_stat(conn, NULL, filename, &st, &fsp); + if ( !NT_STATUS_IS_OK(nt_status)) { /* Perhaps it is a directory */ if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY)) - nt_status = open_directory(conn, NULL, tmp_file, &st, + nt_status = open_directory(conn, NULL, filename, &st, READ_CONTROL_ACCESS, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, @@ -2124,8 +2045,8 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, struct srvsvc_NetGetFileSecur NULL, &fsp); if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", tmp_file)); - status = WERR_ACCESS_DENIED; + DEBUG(3,("_srv_net_file_query_secdesc: Unable to open file %s\n", filename)); + r_u->status = ntstatus_to_werror(nt_status); goto error_exit; } } @@ -2133,20 +2054,23 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, struct srvsvc_NetGetFileSecur sd_size = SMB_VFS_GET_NT_ACL(fsp, fsp->fsp_name, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd); if (sd_size == 0) { - DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", tmp_file)); - status = WERR_ACCESS_DENIED; + DEBUG(3,("_srv_net_file_query_secdesc: Unable to get NT ACL for file %s\n", filename)); + r_u->status = WERR_ACCESS_DENIED; goto error_exit; } - r->out.sd_buf->sd_size= sd_size; - r->out.sd_buf->sd = psd; + r_u->ptr_response = 1; + r_u->size_response = sd_size; + r_u->ptr_secdesc = 1; + r_u->size_secdesc = sd_size; + r_u->sec_desc = psd; psd->dacl->revision = (uint16) NT4_ACL_REVISION; close_file(fsp, NORMAL_CLOSE); unbecome_user(); - close_cnum(conn, p->pipe_user.vuid); - return status; + close_cnum(conn, user.vuid); + return r_u->status; error_exit: @@ -2158,74 +2082,80 @@ error_exit: unbecome_user(); if (conn) - close_cnum(conn, p->pipe_user.vuid); + close_cnum(conn, user.vuid); - return status; + return r_u->status; } /*********************************************************************************** Win9x NT tools set security descriptor. ***********************************************************************************/ -WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, struct srvsvc_NetSetFileSecurity *r) +WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_u, + SRV_R_NET_FILE_SET_SECDESC *r_u) { + pstring filename_in; + char *filename = NULL; + pstring qualname; DATA_BLOB null_pw; files_struct *fsp = NULL; SMB_STRUCT_STAT st; NTSTATUS nt_status; + struct current_user user; connection_struct *conn = NULL; BOOL became_user = False; - WERROR status = WERR_OK; - char *tmp_file = NULL; TALLOC_CTX *ctx = talloc_tos(); ZERO_STRUCT(st); + r_u->status = WERR_OK; + + unistr2_to_ascii(qualname, &q_u->uni_qual_name, sizeof(qualname)); + /* Null password is ok - we are already an authenticated user... */ null_pw = data_blob_null; + get_current_user(&user, p); + become_root(); - conn = make_connection(r->in.share, null_pw, "A:", p->pipe_user.vuid, &nt_status); + conn = make_connection(qualname, null_pw, "A:", user.vuid, &nt_status); unbecome_root(); if (conn == NULL) { - DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", r->in.share)); - status = ntstatus_to_werror(nt_status); + DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname)); + r_u->status = ntstatus_to_werror(nt_status); goto error_exit; } if (!become_user(conn, conn->vuid)) { DEBUG(0,("_srv_net_file_set_secdesc: Can't become connected user!\n")); - status = WERR_ACCESS_DENIED; + r_u->status = WERR_ACCESS_DENIED; goto error_exit; } became_user = True; - if (!r->in.file) { - status = WERR_INVALID_PARAM; - goto error_exit; - } - nt_status = unix_convert(ctx, conn, r->in.file, False, &tmp_file, NULL, &st); + unistr2_to_ascii(filename_in, &q_u->uni_file_name, sizeof(filename_in)); + nt_status = unix_convert(ctx, conn, filename, False, &filename, NULL, &st); if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", r->in.file)); - status = WERR_ACCESS_DENIED; + DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", filename)); + r_u->status = WERR_ACCESS_DENIED; goto error_exit; } - nt_status = check_name(conn, tmp_file); + nt_status = check_name(conn, filename); if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", tmp_file)); - status = WERR_ACCESS_DENIED; + DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", filename)); + r_u->status = WERR_ACCESS_DENIED; goto error_exit; } - nt_status = open_file_stat(conn, NULL, tmp_file, &st, &fsp); + nt_status = open_file_stat(conn, NULL, filename, &st, &fsp); - if (!NT_STATUS_IS_OK(nt_status)) { + if ( !NT_STATUS_IS_OK(nt_status) ) { /* Perhaps it is a directory */ if (NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_IS_A_DIRECTORY)) - nt_status = open_directory(conn, NULL, tmp_file, &st, + nt_status = open_directory(conn, NULL, filename, &st, FILE_READ_ATTRIBUTES, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, @@ -2233,25 +2163,25 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, struct srvsvc_NetSetFileSecur FILE_ATTRIBUTE_DIRECTORY, NULL, &fsp); - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", tmp_file)); - status = WERR_ACCESS_DENIED; + if ( !NT_STATUS_IS_OK(nt_status) ) { + DEBUG(3,("_srv_net_file_set_secdesc: Unable to open file %s\n", filename)); + r_u->status = ntstatus_to_werror(nt_status); goto error_exit; } } - nt_status = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, r->in.securityinformation, r->in.sd_buf.sd); + nt_status = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, q_u->sec_info, q_u->sec_desc); - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", tmp_file)); - status = WERR_ACCESS_DENIED; + if (!NT_STATUS_IS_OK(nt_status) ) { + DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", filename)); + r_u->status = WERR_ACCESS_DENIED; goto error_exit; } close_file(fsp, NORMAL_CLOSE); unbecome_user(); - close_cnum(conn, p->pipe_user.vuid); - return status; + close_cnum(conn, user.vuid); + return r_u->status; error_exit: @@ -2264,10 +2194,10 @@ error_exit: } if (conn) { - close_cnum(conn, p->pipe_user.vuid); + close_cnum(conn, user.vuid); } - return status; + return r_u->status; } /*********************************************************************************** @@ -2316,68 +2246,59 @@ static const char *next_server_disk_enum(uint32 *resume) return disk; } -WERROR _srvsvc_NetDiskEnum(pipes_struct *p, struct srvsvc_NetDiskEnum *r) +WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u) { uint32 i; const char *disk_name; + TALLOC_CTX *ctx = p->mem_ctx; + uint32 resume=get_enum_hnd(&q_u->enum_hnd); - WERROR status = WERR_OK; + r_u->status=WERR_OK; + + r_u->total_entries = init_server_disk_enum(&resume); - *r->out.totalentries = init_server_disk_enum(r->in.resume_handle); - r->out.info->count = 0; + r_u->disk_enum_ctr.unknown = 0; - if(!(r->out.info->disks = TALLOC_ARRAY(p->mem_ctx, struct srvsvc_NetDiskInfo0, MAX_SERVER_DISK_ENTRIES))) { + if(!(r_u->disk_enum_ctr.disk_info = TALLOC_ARRAY(ctx, DISK_INFO, MAX_SERVER_DISK_ENTRIES))) { return WERR_NOMEM; } - /*allow one struct srvsvc_NetDiskInfo0 for null terminator*/ + r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0; - for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(r->in.resume_handle)); i++) { + /*allow one DISK_INFO for null terminator*/ - r->out.info->count++; - (*r->out.totalentries)++; + for(i = 0; i < MAX_SERVER_DISK_ENTRIES -1 && (disk_name = next_server_disk_enum(&resume)); i++) { + + r_u->disk_enum_ctr.entries_read++; /*copy disk name into a unicode string*/ - r->out.info->disks[i].disk = disk_name; + init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name); } /* add a terminating null string. Is this there if there is more data to come? */ - r->out.info->count++; - (*r->out.totalentries)++; + r_u->disk_enum_ctr.entries_read++; - r->out.info->disks[i].disk = ""; + init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, ""); - return status; + init_enum_hnd(&r_u->enum_hnd, resume); + + return r_u->status; } /******************************************************************** ********************************************************************/ -WERROR _srvsvc_NetNameValidate(pipes_struct *p, struct srvsvc_NetNameValidate *r) +WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u) { - int len; - - if ((r->in.flags != 0x0) && (r->in.flags != 0x80000000)) { - return WERR_INVALID_PARAM; - } + fstring sharename; - switch ( r->in.name_type ) { + switch ( q_u->type ) { case 0x9: - len = strlen_m(r->in.name); - - if ((r->in.flags == 0x0) && (len > 81)) { - DEBUG(5,("_srv_net_name_validate: share name too long (%s > 81 chars)\n", r->in.name)); - return WERR_INVALID_NAME; - } - if ((r->in.flags == 0x80000000) && (len > 13)) { - DEBUG(5,("_srv_net_name_validate: share name too long (%s > 13 chars)\n", r->in.name)); - return WERR_INVALID_NAME; - } - - if ( ! validate_net_name( r->in.name, INVALID_SHARENAME_CHARS, sizeof(r->in.name) ) ) { - DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", r->in.name)); + rpcstr_pull(sharename, q_u->sharename.buffer, sizeof(sharename), q_u->sharename.uni_str_len*2, 0); + if ( !validate_net_name( sharename, INVALID_SHARENAME_CHARS, sizeof(sharename) ) ) { + DEBUG(5,("_srv_net_name_validate: Bad sharename \"%s\"\n", sharename)); return WERR_INVALID_NAME; } break; @@ -2398,6 +2319,10 @@ WERROR _srvsvc_NetFileClose(pipes_struct *p, struct srvsvc_NetFileClose *r) return WERR_ACCESS_DENIED; } + +/******************************************************************** +********************************************************************/ + WERROR _srvsvc_NetCharDevEnum(pipes_struct *p, struct srvsvc_NetCharDevEnum *r) { p->rng_fault_state = True; @@ -2446,18 +2371,96 @@ WERROR _srvsvc_NetCharDevQPurgeSelf(pipes_struct *p, struct srvsvc_NetCharDevQPu return WERR_NOT_SUPPORTED; } +WERROR _srvsvc_NetConnEnum(pipes_struct *p, struct srvsvc_NetConnEnum *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + +WERROR _srvsvc_NetFileEnum(pipes_struct *p, struct srvsvc_NetFileEnum *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + WERROR _srvsvc_NetFileGetInfo(pipes_struct *p, struct srvsvc_NetFileGetInfo *r) { p->rng_fault_state = True; return WERR_NOT_SUPPORTED; } +WERROR _srvsvc_NetSessEnum(pipes_struct *p, struct srvsvc_NetSessEnum *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + +WERROR _srvsvc_NetSessDel(pipes_struct *p, struct srvsvc_NetSessDel *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + +WERROR _srvsvc_NetShareAdd(pipes_struct *p, struct srvsvc_NetShareAdd *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + +WERROR _srvsvc_NetShareEnumAll(pipes_struct *p, struct srvsvc_NetShareEnumAll *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + +WERROR _srvsvc_NetShareGetInfo(pipes_struct *p, struct srvsvc_NetShareGetInfo *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + +WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + +WERROR _srvsvc_NetShareDel(pipes_struct *p, struct srvsvc_NetShareDel *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + +WERROR _srvsvc_NetShareDelSticky(pipes_struct *p, struct srvsvc_NetShareDelSticky *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r) { p->rng_fault_state = True; return WERR_NOT_SUPPORTED; } +WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p, struct srvsvc_NetSrvGetInfo *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + +WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p, struct srvsvc_NetSrvSetInfo *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + +WERROR _srvsvc_NetDiskEnum(pipes_struct *p, struct srvsvc_NetDiskEnum *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + WERROR _srvsvc_NetServerStatisticsGet(pipes_struct *p, struct srvsvc_NetServerStatisticsGet *r) { p->rng_fault_state = True; @@ -2482,6 +2485,12 @@ WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r return WERR_NOT_SUPPORTED; } +WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, struct srvsvc_NetRemoteTOD *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r) { p->rng_fault_state = True; @@ -2506,6 +2515,12 @@ WERROR _srvsvc_NetPathCompare(pipes_struct *p, struct srvsvc_NetPathCompare *r) return WERR_NOT_SUPPORTED; } +WERROR _srvsvc_NetNameValidate(pipes_struct *p, struct srvsvc_NetNameValidate *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + WERROR _srvsvc_NETRPRNAMECANONICALIZE(pipes_struct *p, struct srvsvc_NETRPRNAMECANONICALIZE *r) { p->rng_fault_state = True; @@ -2518,6 +2533,12 @@ WERROR _srvsvc_NetPRNameCompare(pipes_struct *p, struct srvsvc_NetPRNameCompare return WERR_NOT_SUPPORTED; } +WERROR _srvsvc_NetShareEnum(pipes_struct *p, struct srvsvc_NetShareEnum *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + WERROR _srvsvc_NetShareDelStart(pipes_struct *p, struct srvsvc_NetShareDelStart *r) { p->rng_fault_state = True; @@ -2530,6 +2551,18 @@ WERROR _srvsvc_NetShareDelCommit(pipes_struct *p, struct srvsvc_NetShareDelCommi return WERR_NOT_SUPPORTED; } +WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, struct srvsvc_NetGetFileSecurity *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + +WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, struct srvsvc_NetSetFileSecurity *r) +{ + p->rng_fault_state = True; + return WERR_NOT_SUPPORTED; +} + WERROR _srvsvc_NetServerTransportAddEx(pipes_struct *p, struct srvsvc_NetServerTransportAddEx *r) { p->rng_fault_state = True; @@ -2560,7 +2593,7 @@ WERROR _srvsvc_NETRDFSDELETELOCALPARTITION(pipes_struct *p, struct srvsvc_NETRDF return WERR_NOT_SUPPORTED; } -WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *R) +WERROR _srvsvc_NETRDFSSETLOCALVOLUMESTATE(pipes_struct *p, struct srvsvc_NETRDFSSETLOCALVOLUMESTATE *r) { p->rng_fault_state = True; return WERR_NOT_SUPPORTED; @@ -2584,26 +2617,27 @@ WERROR _srvsvc_NETRDFSDELETEEXITPOINT(pipes_struct *p, struct srvsvc_NETRDFSDELE return WERR_NOT_SUPPORTED; } -WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r) +WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r) { p->rng_fault_state = True; return WERR_NOT_SUPPORTED; } -WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r) +WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r) { p->rng_fault_state = True; return WERR_NOT_SUPPORTED; } -WERROR _srvsvc_NETRDFSMODIFYPREFIX(pipes_struct *p, struct srvsvc_NETRDFSMODIFYPREFIX *r) +WERROR _srvsvc_NETRDFSMANAGERREPORTSITEINFO(pipes_struct *p, struct srvsvc_NETRDFSMANAGERREPORTSITEINFO *r) { p->rng_fault_state = True; return WERR_NOT_SUPPORTED; } -WERROR _srvsvc_NETRDFSFIXLOCALVOLUME(pipes_struct *p, struct srvsvc_NETRDFSFIXLOCALVOLUME *r) +WERROR _srvsvc_NETRSERVERTRANSPORTDELEX(pipes_struct *p, struct srvsvc_NETRSERVERTRANSPORTDELEX *r) { p->rng_fault_state = True; return WERR_NOT_SUPPORTED; } + |