1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-12 09:18:10 +03:00

Added code from "Nigel Williams" <nigel@veritas.com> (yes, the same famous

Nigel Williams who did NIS/GINA !) to implement add/modify/delete shares
for Win2k. Needs testing as I made a few mods to the original code.
Jeremy.
(This used to be commit 9b3dd80176)
This commit is contained in:
Jeremy Allison 2001-05-01 01:01:19 +00:00
parent 0901dd473a
commit 8bd2a11c86
6 changed files with 483 additions and 27 deletions

View File

@ -2566,6 +2566,7 @@ void init_owf_info(OWF_INFO *hash, uint8 data[16]);
BOOL smb_io_owf_info(char *desc, OWF_INFO *hash, prs_struct *ps, int depth);
BOOL smb_io_gid(char *desc, DOM_GID *gid, prs_struct *ps, int depth);
BOOL smb_io_pol_hnd(char *desc, POLICY_HND *pol, prs_struct *ps, int depth);
void init_unistr3(UNISTR3 *str, const char *buf);
BOOL smb_io_unistr3(char *desc, UNISTR3 *name, prs_struct *ps, int depth);
BOOL prs_uint64(char *name, prs_struct *ps, int depth, UINT64_S *data64);
@ -3537,7 +3538,8 @@ void init_srv_share_info502(SH_INFO_502 *sh502,
char *net_name, uint32 type, char *remark,
uint32 perms, uint32 max_uses, uint32 num_uses,
char *path, char *passwd, SEC_DESC *psd, size_t sd_size);
void init_srv_share_info502_str(SH_INFO_502_STR *sh502,
void init_srv_share_info502_str(SH_INFO_502_STR *sh502str,
SH_INFO_502 *ptrs,
char *net_name, char *remark,
char *path, char *passwd, SEC_DESC *psd, size_t sd_size);
void init_srv_q_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n,
@ -3612,6 +3614,10 @@ void init_time_of_day_info(TIME_OF_DAY_INFO *tod, uint32 elapsedt, uint32 msecs,
uint32 zone, uint32 tintervals, uint32 day,
uint32 month, uint32 year, uint32 weekday);
BOOL srv_io_r_net_remote_tod(char *desc, SRV_R_NET_REMOTE_TOD *r_n, prs_struct *ps, int depth);
BOOL srv_io_q_net_disk_enum(char *desc, SRV_Q_NET_DISK_ENUM *q_n, prs_struct *ps, int depth);
BOOL srv_io_r_net_disk_enum(char *desc, SRV_R_NET_DISK_ENUM *r_n, prs_struct *ps, int depth);
BOOL srv_io_q_net_name_validate(char *desc, SRV_Q_NET_NAME_VALIDATE *q_n, prs_struct *ps, int depth);
BOOL srv_io_r_net_name_validate(char *desc, SRV_R_NET_NAME_VALIDATE *r_n, prs_struct *ps, int depth);
/*The following definitions come from rpc_parse/parse_wks.c */
@ -3835,6 +3841,8 @@ uint32 _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
uint32 _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_SHARE_ADD *r_u);
uint32 _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u);
uint32 _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u);
uint32 _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_DISK_ENUM *r_u);
uint32 _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u);
/*The following definitions come from rpc_server/srv_util.c */

View File

@ -36,9 +36,47 @@
#define SRV_NET_SHARE_DEL 0x12
#define SRV_NET_SRV_GET_INFO 0x15
#define SRV_NET_SRV_SET_INFO 0x16
#define SRV_NET_DISK_ENUM 0x17
#define SRV_NET_REMOTE_TOD 0x1c
#define SRV_NET_NAME_VALIDATE 0x21
#define SRV_NETSHAREENUM 0x24
#define MAX_SERVER_DISK_ENTRIES 15
typedef struct disk_info {
uint32 unknown;
UNISTR3 disk_name;
} DISK_INFO;
typedef struct disk_enum_container {
uint32 level;
uint32 entries_read;
uint32 unknown;
uint32 disk_info_ptr;
DISK_INFO disk_info[MAX_SERVER_DISK_ENTRIES];
} DISK_ENUM_CONTAINER;
typedef struct net_srv_disk_enum {
uint32 ptr_srv_name; /* pointer (to server name?) */
UNISTR2 uni_srv_name; /* server name */
DISK_ENUM_CONTAINER disk_enum_ctr;
uint32 preferred_len; /* preferred maximum length (0xffff ffff) */
uint32 total_entries; /* total number of entries */
ENUM_HND enum_hnd;
uint32 status; /* return status */
} SRV_Q_NET_DISK_ENUM, SRV_R_NET_DISK_ENUM;
typedef struct net_name_validate {
uint32 ptr_srv_name;
UNISTR2 uni_srv_name;
UNISTR2 uni_name; /*name to validate*/
uint32 type;
uint32 flags;
uint32 status;
} SRV_Q_NET_NAME_VALIDATE, SRV_R_NET_NAME_VALIDATE;
/* SESS_INFO_0 (pointers to level 0 session info strings) */
typedef struct ptr_sess_info0
{
@ -328,6 +366,8 @@ typedef struct ptr_share_info502
/* SH_INFO_502_STR (level 502 share info strings) */
typedef struct str_share_info502
{
SH_INFO_502 *ptrs;
UNISTR2 uni_netname; /* unicode string of net name (e.g NETLOGON) */
UNISTR2 uni_remark; /* unicode string of comment (e.g "Logon server share") */
UNISTR2 uni_path; /* unicode string of local path (e.g c:\winnt\system32\repl\import\scripts) */

View File

@ -1456,6 +1456,37 @@ BOOL smb_io_pol_hnd(char *desc, POLICY_HND *pol, prs_struct *ps, int depth)
return True;
}
/*******************************************************************
Create a UNISTR3.
********************************************************************/
void init_unistr3(UNISTR3 *str, const char *buf)
{
size_t len;
if (buf == NULL) {
str->uni_str_len=0;
str->str.buffer = NULL;
return;
}
len = strlen(buf) + 1;
str->uni_str_len=len;
if (len < MAX_UNISTRLEN)
len = MAX_UNISTRLEN;
len *= sizeof(uint16);
str->str.buffer = (uint16 *)talloc_zero(get_talloc_ctx(), len);
if (str->str.buffer == NULL)
smb_panic("init_unistr3: malloc fail\n");
/* store the string (null-terminated copy) */
dos_struni2((char *)str->str.buffer, buf, len);
}
/*******************************************************************
Reads or writes a UNISTR3 structure.
********************************************************************/

View File

@ -280,18 +280,27 @@ static BOOL srv_io_share_info502(char *desc, SH_INFO_502 *sh502, prs_struct *ps,
Inits a SH_INFO_502_STR structure
********************************************************************/
void init_srv_share_info502_str(SH_INFO_502_STR *sh502,
void init_srv_share_info502_str(SH_INFO_502_STR *sh502str,
SH_INFO_502 *ptrs,
char *net_name, char *remark,
char *path, char *passwd, SEC_DESC *psd, size_t sd_size)
{
DEBUG(5,("init_srv_share_info502_str\n"));
init_unistr2(&sh502->uni_netname, net_name, strlen(net_name)+1);
init_unistr2(&sh502->uni_remark, remark, strlen(remark)+1);
init_unistr2(&sh502->uni_path, path, strlen(path)+1);
init_unistr2(&sh502->uni_passwd, passwd, strlen(passwd)+1);
sh502->sd = psd;
sh502->sd_size = sd_size;
sh502str->ptrs = ptrs;
if(sh502str->ptrs->ptr_netname)
init_unistr2(&sh502str->uni_netname, net_name, strlen(net_name)+1);
if(sh502str->ptrs->ptr_remark)
init_unistr2(&sh502str->uni_remark, remark, strlen(remark)+1);
if(sh502str->ptrs->ptr_path)
init_unistr2(&sh502str->uni_path, path, strlen(path)+1);
if(sh502str->ptrs->ptr_passwd)
init_unistr2(&sh502str->uni_passwd, passwd, strlen(passwd)+1);
if(sh502str->ptrs->ptr_sd) {
sh502str->sd = psd;
sh502str->sd_size = sd_size;
}
}
/*******************************************************************
@ -308,32 +317,46 @@ static BOOL srv_io_share_info502_str(char *desc, SH_INFO_502_STR *sh502, prs_str
if(!prs_align(ps))
return False;
if(!smb_io_unistr2("", &sh502->uni_netname, True, ps, depth))
return False;
if(!prs_align(ps))
return False;
if(!smb_io_unistr2("", &sh502->uni_remark, True, ps, depth))
return False;
if(!prs_align(ps))
return False;
if(!smb_io_unistr2("", &sh502->uni_path, True, ps, depth))
return False;
if(!prs_align(ps))
return False;
if(!smb_io_unistr2("", &sh502->uni_passwd, True, ps, depth))
return False;
if(sh502->ptrs->ptr_netname) {
if(!smb_io_unistr2("", &sh502->uni_netname, True, ps, depth))
return False;
}
if(!prs_align(ps))
return False;
if(!prs_uint32("sd_size ", ps, depth, &sh502->sd_size))
if(sh502->ptrs->ptr_remark) {
if(!smb_io_unistr2("", &sh502->uni_remark, True, ps, depth))
return False;
}
if(!prs_align(ps))
return False;
if (!sec_io_desc(desc, &sh502->sd, ps, depth))
if(sh502->ptrs->ptr_path) {
if(!smb_io_unistr2("", &sh502->uni_path, True, ps, depth))
return False;
}
if(!prs_align(ps))
return False;
if(sh502->ptrs->ptr_passwd) {
if(!smb_io_unistr2("", &sh502->uni_passwd, True, ps, depth))
return False;
}
if(!prs_align(ps))
return False;
if(sh502->ptrs->ptr_sd) {
if(!prs_uint32("sd_size ", ps, depth, &sh502->sd_size))
return False;
if (!sec_io_desc(desc, &sh502->sd, ps, depth))
return False;
}
return True;
}
@ -501,6 +524,7 @@ static BOOL srv_io_srv_share_ctr(char *desc, SRV_SHARE_INFO_CTR *ctr, prs_struct
}
for (i = 0; i < num_entries; i++) {
info502[i].info_502_str.ptrs = &info502[i].info_502;
if(!srv_io_share_info502_str("", &info502[i].info_502_str, ps, depth))
return False;
}
@ -675,6 +699,9 @@ static BOOL srv_io_srv_share_info(char *desc, prs_struct *ps, int depth, SRV_SHA
if(!srv_io_share_info502("", &r_n->share.info502.info_502, ps, depth))
return False;
/*allow access to pointers in the str part. */
r_n->share.info502.info_502_str.ptrs = &r_n->share.info502.info_502;
if(!srv_io_share_info502_str("", &r_n->share.info502.info_502_str, ps, depth))
return False;
break;
@ -2374,3 +2401,162 @@ BOOL srv_io_r_net_remote_tod(char *desc, SRV_R_NET_REMOTE_TOD *r_n, prs_struct *
return True;
}
/*******************************************************************
Reads or writes a structure.
********************************************************************/
BOOL srv_io_q_net_disk_enum(char *desc, SRV_Q_NET_DISK_ENUM *q_n, prs_struct *ps, int depth)
{
if (q_n == NULL)
return False;
prs_debug(ps, depth, desc, "srv_io_q_net_disk_enum");
depth++;
if(!prs_align(ps))
return False;
if(!prs_uint32("ptr_srv_name", ps, depth, &q_n->ptr_srv_name))
return False;
if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth))
return False;
if(!prs_align(ps))
return False;
if(!prs_uint32("level", ps, depth, &q_n->disk_enum_ctr.level))
return False;
if(!prs_uint32("entries_read", ps, depth, &q_n->disk_enum_ctr.entries_read))
return False;
if(!prs_uint32("buffer", ps, depth, &q_n->disk_enum_ctr.disk_info_ptr))
return False;
if(!prs_align(ps))
return False;
if(!prs_uint32("preferred_len", ps, depth, &q_n->preferred_len))
return False;
if(!smb_io_enum_hnd("enum_hnd", &q_n->enum_hnd, ps, depth))
return False;
return True;
}
/*******************************************************************
Reads or writes a structure.
********************************************************************/
BOOL srv_io_r_net_disk_enum(char *desc, SRV_R_NET_DISK_ENUM *r_n, prs_struct *ps, int depth)
{
int i;
if (r_n == NULL)
return False;
prs_debug(ps, depth, desc, "srv_io_r_net_disk_enum");
depth++;
if(!prs_align(ps))
return False;
if(!prs_uint32("entries_read", ps, depth, &r_n->disk_enum_ctr.entries_read))
return False;
if(!prs_uint32("ptr_disk_info", ps, depth, &r_n->disk_enum_ctr.disk_info_ptr))
return False;
/*this may be max, unknown, actual?*/
if(!prs_uint32("max_elements", ps, depth, &r_n->disk_enum_ctr.entries_read))
return False;
if(!prs_uint32("unknown", ps, depth, &r_n->disk_enum_ctr.unknown))
return False;
if(!prs_uint32("actual_elements", ps, depth, &r_n->disk_enum_ctr.entries_read))
return False;
for(i=0; i < r_n->disk_enum_ctr.entries_read; i++) {
if(!prs_uint32("unknown", ps, depth, &r_n->disk_enum_ctr.disk_info[i].unknown))
return False;
if(!smb_io_unistr3("disk_name", &r_n->disk_enum_ctr.disk_info[i].disk_name, ps, depth))
return False;
if(!prs_align(ps))
return False;
}
if(!prs_uint32("total_entries", ps, depth, &r_n->total_entries))
return False;
if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth))
return False;
if(!prs_uint32("status", ps, depth, &r_n->status))
return False;
return True;
}
/*******************************************************************
Reads or writes a structure.
********************************************************************/
BOOL srv_io_q_net_name_validate(char *desc, SRV_Q_NET_NAME_VALIDATE *q_n, prs_struct *ps, int depth)
{
if (q_n == NULL)
return False;
prs_debug(ps, depth, desc, "srv_io_q_net_name_validate");
depth++;
if(!prs_align(ps))
return False;
if(!prs_uint32("ptr_srv_name", ps, depth, &q_n->ptr_srv_name))
return False;
if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth))
return False;
if(!prs_align(ps))
return False;
if(!smb_io_unistr2("", &q_n->uni_name, True, ps, depth))
return False;
if(!prs_align(ps))
return False;
if(!prs_uint32("type", ps, depth, &q_n->type))
return False;
if(!prs_uint32("flags", ps, depth, &q_n->flags))
return False;
return True;
}
/*******************************************************************
Reads or writes a structure.
********************************************************************/
BOOL srv_io_r_net_name_validate(char *desc, SRV_R_NET_NAME_VALIDATE *r_n, prs_struct *ps, int depth)
{
if (r_n == NULL)
return False;
prs_debug(ps, depth, desc, "srv_io_r_net_name_validate");
depth++;
if(!prs_align(ps))
return False;
if(!prs_uint32("status", ps, depth, &r_n->status))
return False;
return True;
}

View File

@ -344,6 +344,66 @@ static BOOL api_srv_net_remote_tod(pipes_struct *p)
return True;
}
/*******************************************************************
RPC to enumerate disks available on a server e.g. C:, D: ...
*******************************************************************/
static BOOL api_srv_net_disk_enum(pipes_struct *p)
{
SRV_Q_NET_DISK_ENUM q_u;
SRV_R_NET_DISK_ENUM r_u;
prs_struct *data = &p->in_data.data;
prs_struct *rdata = &p->out_data.rdata;
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
/* Unmarshall the net server disk enum. */
if(!srv_io_q_net_disk_enum("", &q_u, data, 0)) {
DEBUG(0,("api_srv_net_disk_enum: Failed to unmarshall SRV_Q_NET_DISK_ENUM.\n"));
return False;
}
r_u.status = _srv_net_disk_enum(p, &q_u, &r_u);
if(!srv_io_r_net_disk_enum("", &r_u, rdata, 0)) {
DEBUG(0,("api_srv_net_disk_enum: Failed to marshall SRV_R_NET_DISK_ENUM.\n"));
return False;
}
return True;
}
/*******************************************************************
NetValidateName (opnum 0x21)
*******************************************************************/
static BOOL api_srv_net_name_validate(pipes_struct *p)
{
SRV_Q_NET_NAME_VALIDATE q_u;
SRV_R_NET_NAME_VALIDATE r_u;
prs_struct *data = &p->in_data.data;
prs_struct *rdata = &p->out_data.rdata;
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
/* Unmarshall the net server disk enum. */
if(!srv_io_q_net_name_validate("", &q_u, data, 0)) {
DEBUG(0,("api_srv_net_name_validate: Failed to unmarshall SRV_Q_NET_NAME_VALIDATE.\n"));
return False;
}
r_u.status = _srv_net_name_validate(p, &q_u, &r_u);
if(!srv_io_r_net_name_validate("", &r_u, rdata, 0)) {
DEBUG(0,("api_srv_net_name_validate: Failed to marshall SRV_R_NET_NAME_VALIDATE.\n"));
return False;
}
return True;
}
/*******************************************************************
\PIPE\srvsvc commands
********************************************************************/
@ -361,6 +421,8 @@ struct api_struct api_srv_cmds[] =
{ "SRV_NETFILEENUM" , SRV_NETFILEENUM , api_srv_net_file_enum },
{ "SRV_NET_SRV_GET_INFO" , SRV_NET_SRV_GET_INFO , api_srv_net_srv_get_info },
{ "SRV_NET_REMOTE_TOD" , SRV_NET_REMOTE_TOD , api_srv_net_remote_tod },
{ "SRV_NET_DISK_ENUM" , SRV_NET_DISK_ENUM , api_srv_net_disk_enum },
{ "SRV_NET_NAME_VALIDATE" , SRV_NET_NAME_VALIDATE , api_srv_net_name_validate},
{ NULL , 0 , NULL }
};

View File

@ -77,6 +77,14 @@ static void init_srv_share_info_2(SRV_SHARE_INFO_2 *sh2, int snum)
pstring_sub(remark,"%S",lp_servicename(snum));
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.
*/
string_replace(path, '/', '\\');
pstrcpy(passwd, "");
len_net_name = strlen(net_name);
@ -363,6 +371,14 @@ static void init_srv_share_info_502(TALLOC_CTX *ctx, SRV_SHARE_INFO_502 *sh502,
pstring_sub(remark,"%S",lp_servicename(snum));
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.
*/
string_replace(path, '/', '\\');
pstrcpy(passwd, "");
len_net_name = strlen(net_name);
@ -379,7 +395,7 @@ static void init_srv_share_info_502(TALLOC_CTX *ctx, SRV_SHARE_INFO_502 *sh502,
sd = get_share_security(ctx, snum, &sd_size);
init_srv_share_info502(&sh502->info_502, net_name, type, 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);
init_srv_share_info502_str(&sh502->info_502_str, &sh502->info_502, net_name, remark, path, passwd, sd, sd_size);
}
/***************************************************************************
@ -1546,3 +1562,116 @@ uint32 _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET
return r_u->status;
}
/***********************************************************************************
It may be that we want to limit users to creating shares on certain areas of the UNIX file area.
We could define areas by mapping Windows style disks to points on the UNIX directory hierarchy.
These disks would the disks listed by this function.
Users could then create shares relative to these disks. Watch out for moving these disks around.
"Nigel Williams" <nigel@veritas.com>.
/***********************************************************************************/
const char *server_disks[] = {"C:"};
static uint32 get_server_disk_count(void)
{
return sizeof(server_disks)/sizeof(server_disks[0]);
}
static uint32 init_server_disk_enum(uint32 *resume)
{
uint32 server_disk_count = get_server_disk_count();
/*resume can be an offset into the list for now*/
if(*resume < 0)
*resume = 0;
if(*resume > server_disk_count)
*resume = server_disk_count;
return server_disk_count - *resume;
}
static const char *next_server_disk_enum(uint32 *resume)
{
const char *disk;
if(init_server_disk_enum(resume) == 0)
return NULL;
disk = server_disks[*resume];
(*resume)++;
DEBUG(10, ("next_server_disk_enum: reporting disk %s. resume handle %d.\n", disk, *resume));
return disk;
}
uint32 _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;
uint32 resume=get_enum_hnd(&q_u->enum_hnd);
r_u->status=NT_STATUS_NOPROBLEMO;
r_u->total_entries = init_server_disk_enum(&resume);
r_u->disk_enum_ctr.unknown = 0;
r_u->disk_enum_ctr.disk_info_ptr = (uint32) r_u->disk_enum_ctr.disk_info;
/*allow one DISK_INFO for null terminator*/
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*/
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_u->disk_enum_ctr.entries_read++;
init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, "");
init_enum_hnd(&r_u->enum_hnd, resume);
return r_u->status;
}
uint32 _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u)
{
int snum;
fstring share_name;
r_u->status=NT_STATUS_NOPROBLEMO;
switch(q_u->type) {
case 0x9:
/*check if share name is ok*/
/*also check if we already have a share with this name*/
unistr2_to_ascii(share_name, &q_u->uni_name, sizeof(share_name));
snum = find_service(share_name);
/* Share already exists. */
if (snum >= 0)
r_u->status = NT_STATUS_OBJECT_NAME_INVALID;
break;
default:
/*unsupported type*/
r_u->status = ERROR_INVALID_LEVEL;
break;
}
return r_u->status;
}