diff options
author | Andrew Bartlett <abartlet@samba.org> | 2002-07-27 11:48:55 +0000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2002-07-27 11:48:55 +0000 |
commit | 7ce66f79ea84d77f186bbf6e7831dc71cc6ec46a (patch) | |
tree | 9a33c32163f2f6c3247fad3d5ac85617cca88e0b | |
parent | 8e04b2d4bb04c238840046513aac44e454cf1c81 (diff) | |
download | samba-7ce66f79ea84d77f186bbf6e7831dc71cc6ec46a.tar.gz samba-7ce66f79ea84d77f186bbf6e7831dc71cc6ec46a.tar.bz2 samba-7ce66f79ea84d77f186bbf6e7831dc71cc6ec46a.zip |
A very long time ago (actually 6 months ago) I promised to commit this code
to the Samba tree.
Originally written by Nigel Williams" <nigel@veritas.com>, I've been
trying to keep it in some form of shape for the last 6 months. In particular
I think some of the code got committed a few months ago, and others have made
changes to the CVS version over time.
anyway, its finally in - and doesn't appear to have broken anything.
Now to try the client-side patches :-)
Andrew Bartlett
(This used to be commit f9bac7c5c2c4ddf0bf39d596a7b922fbb17c6b16)
-rw-r--r-- | source3/include/rpc_srvsvc.h | 116 | ||||
-rw-r--r-- | source3/rpc_parse/parse_srv.c | 700 | ||||
-rw-r--r-- | source3/rpc_server/srv_srvsvc.c | 31 | ||||
-rw-r--r-- | source3/rpc_server/srv_srvsvc_nt.c | 394 |
4 files changed, 1077 insertions, 164 deletions
diff --git a/source3/include/rpc_srvsvc.h b/source3/include/rpc_srvsvc.h index 1753c19783..94d23bb4bc 100644 --- a/source3/include/rpc_srvsvc.h +++ b/source3/include/rpc_srvsvc.h @@ -4,6 +4,7 @@ Copyright (C) Andrew Tridgell 1992-1997 Copyright (C) Luke Kenneth Casson Leighton 1996-1997 Copyright (C) Paul Ashton 1997 + Copyright (C) Nigel Williams 2001 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 @@ -33,6 +34,7 @@ #define SRV_NET_SHARE_GET_INFO 0x10 #define SRV_NET_SHARE_SET_INFO 0x11 #define SRV_NET_SHARE_DEL 0x12 +#define SRV_NET_SHARE_DEL_STICKY 0x13 #define SRV_NET_SRV_GET_INFO 0x15 #define SRV_NET_SRV_SET_INFO 0x16 #define SRV_NET_DISK_ENUM 0x17 @@ -54,7 +56,7 @@ typedef struct disk_enum_container { uint32 entries_read; uint32 unknown; uint32 disk_info_ptr; - DISK_INFO disk_info[MAX_SERVER_DISK_ENTRIES]; + DISK_INFO *disk_info; } DISK_ENUM_CONTAINER; typedef struct net_srv_disk_enum { @@ -294,6 +296,29 @@ typedef struct r_net_conn_enum_info } SRV_R_NET_CONN_ENUM; +/* SH_INFO_0 */ +typedef struct ptr_share_info0 +{ + uint32 ptr_netname; /* pointer to net name. */ +} SH_INFO_0; + +/* SH_INFO_0_STR (level 0 share info strings) */ +typedef struct str_share_info0 +{ + SH_INFO_0 *ptrs; + + UNISTR2 uni_netname; /* unicode string of net name */ + +} SH_INFO_0_STR; + +/* SRV_SHARE_INFO_0 */ +typedef struct share_info_0_info +{ + SH_INFO_0 info_0; + SH_INFO_0_STR info_0_str; + +} SRV_SHARE_INFO_0; + /* SH_INFO_1 (pointers to level 1 share info strings) */ typedef struct ptr_share_info1 { @@ -306,6 +331,8 @@ typedef struct ptr_share_info1 /* SH_INFO_1_STR (level 1 share info strings) */ typedef struct str_share_info1 { + SH_INFO_1 *ptrs; + UNISTR2 uni_netname; /* unicode string of net name */ UNISTR2 uni_remark; /* unicode string of comment */ @@ -336,6 +363,8 @@ typedef struct ptr_share_info2 /* SH_INFO_2_STR (level 2 share info strings) */ typedef struct str_share_info2 { + SH_INFO_2 *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) */ @@ -383,6 +412,8 @@ typedef struct ptr_share_info502 uint32 num_uses; /* current uses */ uint32 ptr_path; /* pointer to path name */ uint32 ptr_passwd; /* pointer to password */ + uint32 reserved; /* this holds the space taken by the sd in the rpc packet */ + uint32 reserved_offset; /* required for _post operation when marshalling */ uint32 sd_size; /* size of security descriptor */ uint32 ptr_sd; /* pointer to security descriptor */ @@ -398,6 +429,7 @@ typedef struct str_share_info502 UNISTR2 uni_path; /* unicode string of local path (e.g c:\winnt\system32\repl\import\scripts) */ UNISTR2 uni_passwd; /* unicode string of password - presumably for share level security (e.g NULL) */ + uint32 reserved; uint32 sd_size; SEC_DESC *sd; @@ -411,12 +443,57 @@ typedef struct share_info_502_info } SRV_SHARE_INFO_502; -/* SRV_SHARE_INFO_1005 */ +typedef struct ptr_share_info1004 +{ + uint32 ptr_remark; + +} SH_INFO_1004; + +typedef struct str_share_info1004 +{ + SH_INFO_1004 *ptrs; + + UNISTR2 uni_remark; + +} SH_INFO_1004_STR; + +typedef struct ptr_info_1004_info +{ + SH_INFO_1004 info_1004; + SH_INFO_1004_STR info_1004_str; +} SRV_SHARE_INFO_1004; + typedef struct share_info_1005_info { uint32 dfs_root_flag; } SRV_SHARE_INFO_1005; +typedef struct share_info_1006_info +{ + uint32 max_uses; +} SRV_SHARE_INFO_1006; + +typedef struct ptr_share_info1007 +{ + uint32 flags; + uint32 ptr_AlternateDirectoryName; + +} SH_INFO_1007; + +typedef struct str_share_info1007 +{ + SH_INFO_1007 *ptrs; + + UNISTR2 uni_AlternateDirectoryName; + +} SH_INFO_1007_STR; + +typedef struct ptr_info_1007_info +{ + SH_INFO_1007 info_1007; + SH_INFO_1007_STR info_1007_str; +} SRV_SHARE_INFO_1007; + /* SRV_SHARE_INFO_1501 */ typedef struct share_info_1501_info { @@ -435,10 +512,16 @@ typedef struct srv_share_info_ctr_info uint32 num_entries2; union { - SRV_SHARE_INFO_1 *info1; /* share info level 1 */ - SRV_SHARE_INFO_2 *info2; /* share info level 2 */ - SRV_SHARE_INFO_501 *info501; /* share info level 501 */ - SRV_SHARE_INFO_502 *info502; /* share info level 502 */ + SRV_SHARE_INFO_0 *info0; + SRV_SHARE_INFO_1 *info1; /* share info level 1 */ + SRV_SHARE_INFO_2 *info2; /* share info level 2 */ + SRV_SHARE_INFO_501 *info501; /* share info level 501 */ + SRV_SHARE_INFO_502 *info502; /* share info level 502 */ + SRV_SHARE_INFO_1004 *info1004; + SRV_SHARE_INFO_1005 *info1005; + SRV_SHARE_INFO_1006 *info1006; + SRV_SHARE_INFO_1007 *info1007; + SRV_SHARE_INFO_1501 *info1501; void *info; } share; @@ -484,19 +567,21 @@ typedef struct q_net_share_get_info_info } SRV_Q_NET_SHARE_GET_INFO; -/* JRA. NB. We also need level 1004 and 1006 here. */ - /* SRV_SHARE_INFO */ typedef struct srv_share_info { uint32 switch_value; uint32 ptr_share_ctr; union { + SRV_SHARE_INFO_0 info0; SRV_SHARE_INFO_1 info1; SRV_SHARE_INFO_2 info2; SRV_SHARE_INFO_501 info501; SRV_SHARE_INFO_502 info502; + SRV_SHARE_INFO_1004 info1004; SRV_SHARE_INFO_1005 info1005; + SRV_SHARE_INFO_1006 info1006; + SRV_SHARE_INFO_1007 info1007; SRV_SHARE_INFO_1501 info1501; } share; } SRV_SHARE_INFO; @@ -520,12 +605,16 @@ typedef struct q_net_share_set_info_info SRV_SHARE_INFO info; + uint32 ptr_parm_error; + uint32 parm_error; + } SRV_Q_NET_SHARE_SET_INFO; /* SRV_R_NET_SHARE_SET_INFO */ typedef struct r_net_share_set_info { - uint32 switch_value; /* switch value */ + uint32 ptr_parm_error; + uint32 parm_error; WERROR status; /* return status */ @@ -549,7 +638,9 @@ typedef struct q_net_share_add /* SRV_R_NET_SHARE_ADD */ typedef struct r_net_share_add { - uint32 switch_value; /* switch value */ + + uint32 ptr_parm_error; + uint32 parm_error; WERROR status; /* return status */ @@ -594,9 +685,12 @@ typedef struct str_file_info3_info /* SRV_FILE_INFO_3 */ typedef struct srv_file_info_3 { + uint32 num_entries_read; /* EntriesRead */ + uint32 ptr_file_info; /* Buffer */ + + uint32 num_entries_read2; /* EntriesRead */ FILE_INFO_3 info_3; /* file entry details */ FILE_INFO_3_STR info_3_str; /* file entry strings */ - } SRV_FILE_INFO_3; /* SRV_FILE_INFO_CTR */ diff --git a/source3/rpc_parse/parse_srv.c b/source3/rpc_parse/parse_srv.c index 7f1915edc7..531267c308 100644 --- a/source3/rpc_parse/parse_srv.c +++ b/source3/rpc_parse/parse_srv.c @@ -3,9 +3,10 @@ * RPC Pipe client / server routines * Copyright (C) Andrew Tridgell 1992-1997, * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, - * Copyright (C) Paul Ashton 1997. - * Copyright (C) Jeremy Allison 1999. - * Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2002 + * Copyright (C) Paul Ashton 1997, + * Copyright (C) Jeremy Allison 1999, + * Copyright (C) Nigel Williams 2001, + * Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2002. * * 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 @@ -28,6 +29,71 @@ #define DBGC_CLASS DBGC_RPC_PARSE /******************************************************************* + Inits a SH_INFO_0_STR structure +********************************************************************/ + +void init_srv_share_info0_str(SH_INFO_0_STR *sh0, char *net_name) +{ + DEBUG(5,("init_srv_share_info0_str\n")); + + if(net_name) + init_unistr2(&sh0->uni_netname, net_name, strlen(net_name)+1); +} + +/******************************************************************* + Reads or writes a structure. +********************************************************************/ + +static BOOL srv_io_share_info0_str(char *desc, SH_INFO_0_STR *sh0, prs_struct *ps, int depth) +{ + if (sh0 == NULL) + return False; + + prs_debug(ps, depth, desc, "srv_io_share_info0_str"); + depth++; + + if(!prs_align(ps)) + return False; + if(sh0->ptrs->ptr_netname) + if(!smb_io_unistr2("", &sh0->uni_netname, True, ps, depth)) + return False; + + return True; +} + +/******************************************************************* + makes a SH_INFO_0 structure +********************************************************************/ + +void init_srv_share_info0(SH_INFO_0 *sh0, char *net_name) +{ + DEBUG(5,("init_srv_share_info0: %s\n", net_name)); + + sh0->ptr_netname = (net_name != NULL) ? 1 : 0; +} + +/******************************************************************* + Reads or writes a structure. +********************************************************************/ + +static BOOL srv_io_share_info0(char *desc, SH_INFO_0 *sh0, prs_struct *ps, int depth) +{ + if (sh0 == NULL) + return False; + + prs_debug(ps, depth, desc, "srv_io_share_info0"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("ptr_netname", ps, depth, &sh0->ptr_netname)) + return False; + + return True; +} + +/******************************************************************* Inits a SH_INFO_1_STR structure ********************************************************************/ @@ -35,8 +101,10 @@ void init_srv_share_info1_str(SH_INFO_1_STR *sh1, char *net_name, char *remark) { DEBUG(5,("init_srv_share_info1_str\n")); - init_unistr2(&sh1->uni_netname, net_name, strlen(net_name)+1); - init_unistr2(&sh1->uni_remark, remark, strlen(remark)+1); + if(net_name) + init_unistr2(&sh1->uni_netname, net_name, strlen(net_name)+1); + if(remark) + init_unistr2(&sh1->uni_remark, remark, strlen(remark)+1); } /******************************************************************* @@ -47,20 +115,24 @@ static BOOL srv_io_share_info1_str(char *desc, SH_INFO_1_STR *sh1, prs_struct *p { if (sh1 == NULL) return False; - + prs_debug(ps, depth, desc, "srv_io_share_info1_str"); depth++; - + if(!prs_align(ps)) return False; - if(!smb_io_unistr2("", &sh1->uni_netname, True, ps, depth)) - return False; + if(sh1->ptrs->ptr_netname) + if(!smb_io_unistr2("", &sh1->uni_netname, True, ps, depth)) + return False; + if(!prs_align(ps)) return False; - if(!smb_io_unistr2("", &sh1->uni_remark, True, ps, depth)) - return False; - + + if(sh1->ptrs->ptr_remark) + if(!smb_io_unistr2("", &sh1->uni_remark, True, ps, depth)) + return False; + return True; } @@ -71,7 +143,7 @@ static BOOL srv_io_share_info1_str(char *desc, SH_INFO_1_STR *sh1, prs_struct *p void init_srv_share_info1(SH_INFO_1 *sh1, char *net_name, uint32 type, char *remark) { DEBUG(5,("init_srv_share_info1: %s %8x %s\n", net_name, type, remark)); - + sh1->ptr_netname = (net_name != NULL) ? 1 : 0; sh1->type = type; sh1->ptr_remark = (remark != NULL) ? 1 : 0; @@ -139,6 +211,7 @@ static BOOL srv_io_share_info2_str(char *desc, SH_INFO_2 *sh, SH_INFO_2_STR *sh2 if(!prs_align(ps)) return False; + if (sh->ptr_netname) if(!smb_io_unistr2("", &sh2->uni_netname, True, ps, depth)) return False; @@ -175,7 +248,6 @@ void init_srv_share_info2(SH_INFO_2 *sh2, sh2->perms = perms; sh2->max_uses = max_uses; sh2->num_uses = num_uses; - sh2->type = type; sh2->ptr_path = (path != NULL) ? 1 : 0; sh2->ptr_passwd = (passwd != NULL) ? 1 : 0; } @@ -216,6 +288,21 @@ static BOOL srv_io_share_info2(char *desc, SH_INFO_2 *sh2, prs_struct *ps, int d } /******************************************************************* + Inits a SH_INFO_501_STR structure +********************************************************************/ + +void init_srv_share_info501_str(SH_INFO_501_STR *sh501, + char *net_name, char *remark) +{ + DEBUG(5,("init_srv_share_info501_str\n")); + + if(net_name) + init_unistr2(&sh501->uni_netname, net_name, strlen(net_name)+1); + if(remark) + init_unistr2(&sh501->uni_remark, remark, strlen(remark)+1); +} + +/******************************************************************* Inits a SH_INFO_2 structure *******************************************************************/ @@ -259,18 +346,6 @@ static BOOL srv_io_share_info501(char *desc, SH_INFO_501 *sh501, prs_struct *ps, return True; } -/******************************************************************** - Inits a SH_INFO_501_STR structure -********************************************************************/ - -void init_srv_share_info501_str(SH_INFO_501_STR *sh501, char *net_name, char *remark) -{ - DEBUG(5,("init_srv_share_info501_str\n")); - - init_unistr2(&sh501->uni_netname, net_name, strlen(net_name)+1); - init_unistr2(&sh501->uni_remark, remark, strlen(remark)+1); -} - /******************************************************************* Reads or writes a structure. ********************************************************************/ @@ -301,7 +376,7 @@ static BOOL srv_io_share_info501_str(char *desc, SH_INFO_501_STR *sh501, prs_str ********************************************************************/ void init_srv_share_info502(SH_INFO_502 *sh502, - char *net_name, uint32 type, char *remark, + const 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) { @@ -315,9 +390,9 @@ void init_srv_share_info502(SH_INFO_502 *sh502, sh502->perms = perms; sh502->max_uses = max_uses; sh502->num_uses = num_uses; - sh502->type = type; sh502->ptr_path = (path != NULL) ? 1 : 0; sh502->ptr_passwd = (passwd != NULL) ? 1 : 0; + sh502->reserved = 0; /* actual size within rpc */ sh502->sd_size = (uint32)sd_size; sh502->ptr_sd = (psd != NULL) ? 1 : 0; } @@ -353,7 +428,7 @@ static BOOL srv_io_share_info502(char *desc, SH_INFO_502 *sh502, prs_struct *ps, return False; if(!prs_uint32("ptr_passwd ", ps, depth, &sh502->ptr_passwd)) return False; - if(!prs_uint32("sd_size ", ps, depth, &sh502->sd_size)) + if(!prs_uint32_pre("reserved ", ps, depth, &sh502->reserved, &sh502->reserved_offset)) return False; if(!prs_uint32("ptr_sd ", ps, depth, &sh502->ptr_sd)) return False; @@ -366,26 +441,22 @@ static BOOL srv_io_share_info502(char *desc, SH_INFO_502 *sh502, prs_struct *ps, ********************************************************************/ 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")); - sh502str->ptrs = ptrs; - - if(sh502str->ptrs->ptr_netname) + if(net_name) init_unistr2(&sh502str->uni_netname, net_name, strlen(net_name)+1); - if(sh502str->ptrs->ptr_remark) + if(remark) init_unistr2(&sh502str->uni_remark, remark, strlen(remark)+1); - if(sh502str->ptrs->ptr_path) + if(path) init_unistr2(&sh502str->uni_path, path, strlen(path)+1); - if(sh502str->ptrs->ptr_passwd) + if(passwd) init_unistr2(&sh502str->uni_passwd, passwd, strlen(passwd)+1); - if(sh502str->ptrs->ptr_sd) { sh502str->sd = psd; + sh502str->reserved = 0; sh502str->sd_size = sd_size; - } } /******************************************************************* @@ -436,21 +507,112 @@ static BOOL srv_io_share_info502_str(char *desc, SH_INFO_502_STR *sh502, prs_str return False; if(sh502->ptrs->ptr_sd) { - if(!prs_uint32("sd_size ", ps, depth, &sh502->sd_size)) + uint32 old_offset; + uint32 reserved_offset; + + if(!prs_uint32_pre("reserved ", ps, depth, &sh502->reserved, &reserved_offset)) return False; + + old_offset = prs_offset(ps); + if (!sec_io_desc(desc, &sh502->sd, ps, depth)) return False; + + if(UNMARSHALLING(ps)) { + + sh502->ptrs->sd_size = sh502->sd_size = sec_desc_size(sh502->sd); + + prs_set_offset(ps, old_offset + sh502->reserved); + } + + prs_align(ps); + + if(MARSHALLING(ps)) { + + sh502->ptrs->reserved = sh502->reserved = prs_offset(ps) - old_offset; + } + + if(!prs_uint32_post("reserved ", ps, depth, + &sh502->reserved, reserved_offset, sh502->reserved)) + return False; + if(!prs_uint32_post("reserved ", ps, depth, + &sh502->ptrs->reserved, sh502->ptrs->reserved_offset, sh502->ptrs->reserved)) + return False; } return True; } /******************************************************************* + Inits a SH_INFO_1004_STR structure +********************************************************************/ + +void init_srv_share_info1004_str(SH_INFO_1004_STR *sh1004, char *remark) +{ + DEBUG(5,("init_srv_share_info1004_str\n")); + + if(remark) + init_unistr2(&sh1004->uni_remark, remark, strlen(remark)+1); +} + +/******************************************************************* Reads or writes a structure. ********************************************************************/ -static BOOL srv_io_share_info1005(char* desc, SRV_SHARE_INFO_1005* sh1005, - prs_struct* ps, int depth) +static BOOL srv_io_share_info1004_str(char *desc, SH_INFO_1004_STR *sh1004, prs_struct *ps, int depth) +{ + if (sh1004 == NULL) + return False; + + prs_debug(ps, depth, desc, "srv_io_share_info1004_str"); + depth++; + + if(!prs_align(ps)) + return False; + if(sh1004->ptrs->ptr_remark) + if(!smb_io_unistr2("", &sh1004->uni_remark, True, ps, depth)) + return False; + + return True; +} + +/******************************************************************* + makes a SH_INFO_1004 structure +********************************************************************/ + +void init_srv_share_info1004(SH_INFO_1004 *sh1004, char *remark) +{ + DEBUG(5,("init_srv_share_info1004: %s\n", remark)); + + sh1004->ptr_remark = (remark != NULL) ? 1 : 0; +} + +/******************************************************************* + Reads or writes a structure. +********************************************************************/ + +static BOOL srv_io_share_info1004(char *desc, SH_INFO_1004 *sh1004, prs_struct *ps, int depth) +{ + if (sh1004 == NULL) + return False; + + prs_debug(ps, depth, desc, "srv_io_share_info1004"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("ptr_remark", ps, depth, &sh1004->ptr_remark)) + return False; + + return True; +} + +/******************************************************************* + Reads or writes a structure. +********************************************************************/ + +static BOOL srv_io_share_info1005(char* desc, SRV_SHARE_INFO_1005* sh1005, prs_struct* ps, int depth) { if(sh1005 == NULL) return False; @@ -471,6 +633,95 @@ static BOOL srv_io_share_info1005(char* desc, SRV_SHARE_INFO_1005* sh1005, Reads or writes a structure. ********************************************************************/ +static BOOL srv_io_share_info1006(char* desc, SRV_SHARE_INFO_1006* sh1006, prs_struct* ps, int depth) +{ + if(sh1006 == NULL) + return False; + + prs_debug(ps, depth, desc, "srv_io_share_info1006"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("max uses ", ps, depth, &sh1006->max_uses)) + return False; + + return True; +} + +/******************************************************************* + Inits a SH_INFO_1007_STR structure +********************************************************************/ + +void init_srv_share_info1007_str(SH_INFO_1007_STR *sh1007, const char *alternate_directory_name) +{ + DEBUG(5,("init_srv_share_info1007_str\n")); + + if(alternate_directory_name) + init_unistr2(&sh1007->uni_AlternateDirectoryName, alternate_directory_name, strlen(alternate_directory_name)+1); +} + +/******************************************************************* + Reads or writes a structure. +********************************************************************/ + +static BOOL srv_io_share_info1007_str(char *desc, SH_INFO_1007_STR *sh1007, prs_struct *ps, int depth) +{ + if (sh1007 == NULL) + return False; + + prs_debug(ps, depth, desc, "srv_io_share_info1007_str"); + depth++; + + if(!prs_align(ps)) + return False; + if(sh1007->ptrs->ptr_AlternateDirectoryName) + if(!smb_io_unistr2("", &sh1007->uni_AlternateDirectoryName, True, ps, depth)) + return False; + + return True; +} + +/******************************************************************* + makes a SH_INFO_1007 structure +********************************************************************/ + +void init_srv_share_info1007(SH_INFO_1007 *sh1007, uint32 flags, const char *alternate_directory_name) +{ + DEBUG(5,("init_srv_share_info1007: %s\n", alternate_directory_name)); + + sh1007->flags = flags; + sh1007->ptr_AlternateDirectoryName = (alternate_directory_name != NULL) ? 1 : 0; +} + +/******************************************************************* + Reads or writes a structure. +********************************************************************/ + +static BOOL srv_io_share_info1007(char *desc, SH_INFO_1007 *sh1007, prs_struct *ps, int depth) +{ + if (sh1007 == NULL) + return False; + + prs_debug(ps, depth, desc, "srv_io_share_info1007"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("flags ", ps, depth, &sh1007->flags)) + return False; + if(!prs_uint32("ptr_Alter..", ps, depth, &sh1007->ptr_AlternateDirectoryName)) + return False; + + return True; +} + +/******************************************************************* + Reads or writes a structure. +********************************************************************/ + static BOOL srv_io_share_info1501(char* desc, SRV_SHARE_INFO_1501* sh1501, prs_struct* ps, int depth) { @@ -511,9 +762,6 @@ static BOOL srv_io_srv_share_ctr(char *desc, SRV_SHARE_INFO_CTR *ctr, prs_struct if(!prs_uint32("info_level", ps, depth, &ctr->info_level)) return False; - if (ctr->info_level == 0) - return True; - if(!prs_uint32("switch_value", ps, depth, &ctr->switch_value)) return False; if(!prs_uint32("ptr_share_info", ps, depth, &ctr->ptr_share_info)) @@ -541,6 +789,33 @@ static BOOL srv_io_srv_share_ctr(char *desc, SRV_SHARE_INFO_CTR *ctr, prs_struct return False; switch (ctr->switch_value) { + + case 0: + { + SRV_SHARE_INFO_0 *info0 = ctr->share.info0; + int num_entries = ctr->num_entries; + int i; + + if (UNMARSHALLING(ps)) { + if (!(info0 = (SRV_SHARE_INFO_0 *)prs_alloc_mem(ps, num_entries * sizeof(SRV_SHARE_INFO_0)))) + return False; + ctr->share.info0 = info0; + } + + for (i = 0; i < num_entries; i++) { + if(!srv_io_share_info0("", &info0[i].info_0, ps, depth)) + return False; + } + + for (i = 0; i < num_entries; i++) { + info0[i].info_0_str.ptrs = &info0[i].info_0; + if(!srv_io_share_info0_str("", &info0[i].info_0_str, ps, depth)) + return False; + } + + break; + } + case 1: { SRV_SHARE_INFO_1 *info1 = ctr->share.info1; @@ -559,6 +834,7 @@ static BOOL srv_io_srv_share_ctr(char *desc, SRV_SHARE_INFO_CTR *ctr, prs_struct } for (i = 0; i < num_entries; i++) { + info1[i].info_1_str.ptrs = &info1[i].info_1; if(!srv_io_share_info1_str("", &info1[i].info_1_str, ps, depth)) return False; } @@ -632,8 +908,8 @@ static BOOL srv_io_srv_share_ctr(char *desc, SRV_SHARE_INFO_CTR *ctr, prs_struct for (i = 0; i < num_entries; i++) { if(!srv_io_share_info502("", &info502[i].info_502, ps, depth)) return False; - } - + } + 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)) @@ -643,6 +919,118 @@ static BOOL srv_io_srv_share_ctr(char *desc, SRV_SHARE_INFO_CTR *ctr, prs_struct break; } + case 1004: + { + SRV_SHARE_INFO_1004 *info1004 = ctr->share.info1004; + int num_entries = ctr->num_entries; + int i; + + if (UNMARSHALLING(ps)) { + if (!(info1004 = (SRV_SHARE_INFO_1004 *)prs_alloc_mem(ps,num_entries * sizeof(SRV_SHARE_INFO_1004)))) + return False; + ctr->share.info1004 = info1004; + } + + for (i = 0; i < num_entries; i++) { + if(!srv_io_share_info1004("", &info1004[i].info_1004, ps, depth)) + return False; + } + + for (i = 0; i < num_entries; i++) { + info1004[i].info_1004_str.ptrs = &info1004[i].info_1004; + if(!srv_io_share_info1004_str("", &info1004[i].info_1004_str, ps, depth)) + return False; + } + + break; + } + + case 1005: + { + SRV_SHARE_INFO_1005 *info1005 = ctr->share.info1005; + int num_entries = ctr->num_entries; + int i; + + if (UNMARSHALLING(ps)) { + if (!(info1005 = (SRV_SHARE_INFO_1005 *)prs_alloc_mem(ps,num_entries * sizeof(SRV_SHARE_INFO_1005)))) + return False; + ctr->share.info1005 = info1005; + } + + for (i = 0; i < num_entries; i++) { + if(!srv_io_share_info1005("", &info1005[i], ps, depth)) + return False; + } + + break; + } + + case 1006: + { + SRV_SHARE_INFO_1006 *info1006 = ctr->share.info1006; + int num_entries = ctr->num_entries; + int i; + + if (UNMARSHALLING(ps)) { + if (!(info1006 = (SRV_SHARE_INFO_1006 *)prs_alloc_mem(ps,num_entries * sizeof(SRV_SHARE_INFO_1006)))) + return False; + ctr->share.info1006 = info1006; + } + + for (i = 0; i < num_entries; i++) { + if(!srv_io_share_info1006("", &info1006[i], ps, depth)) + return False; + } + + break; + } + + case 1007: + { + SRV_SHARE_INFO_1007 *info1007 = ctr->share.info1007; + int num_entries = ctr->num_entries; + int i; + + if (UNMARSHALLING(ps)) { + if (!(info1007 = (SRV_SHARE_INFO_1007 *)prs_alloc_mem(ps,num_entries * sizeof(SRV_SHARE_INFO_1007)))) + return False; + ctr->share.info1007 = info1007; + } + + for (i = 0; i < num_entries; i++) { + if(!srv_io_share_info1007("", &info1007[i].info_1007, ps, depth)) + return False; + } + + for (i = 0; i < num_entries; i++) { + info1007[i].info_1007_str.ptrs = &info1007[i].info_1007; + if(!srv_io_share_info1007_str("", &info1007[i].info_1007_str, ps, depth)) + return False; + } + + break; + } + + case 1501: + { + SRV_SHARE_INFO_1501 *info1501 = ctr->share.info1501; + int num_entries = ctr->num_entries; + int i; + + if (UNMARSHALLING(ps)) { + if (!(info1501 = (SRV_SHARE_INFO_1501 *)prs_alloc_mem(ps,num_entries * sizeof(SRV_SHARE_INFO_1501)))) + return False; + ctr->share.info1501 = info1501; + } + + for (i = 0; i < num_entries; i++) { + if(!srv_io_share_info1501("", &info1501[i], ps, depth)) + return False; + } + + break; + } + default: DEBUG(5,("%s no share info at switch_value %d\n", tab_depth(depth), ctr->switch_value)); @@ -667,8 +1055,9 @@ void init_srv_q_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n, q_n->ctr.info_level = q_n->ctr.switch_value = info_level; q_n->ctr.ptr_share_info = 1; - q_n->ctr.num_entries = 0; - q_n->ctr.ptr_entries = 0; + q_n->ctr.num_entries = 0; + q_n->ctr.ptr_entries = 0; + q_n->ctr.num_entries2 = 0; q_n->preferred_len = preferred_len; memcpy(&q_n->enum_hnd, hnd, sizeof(*hnd)); @@ -729,8 +1118,12 @@ BOOL srv_io_r_net_share_enum(char *desc, SRV_R_NET_SHARE_ENUM *r_n, prs_struct * 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(r_n->total_entries != 0) { + if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth)) + return False; + } + if(!prs_werror("status", ps, depth, &r_n->status)) return False; @@ -738,6 +1131,25 @@ BOOL srv_io_r_net_share_enum(char *desc, SRV_R_NET_SHARE_ENUM *r_n, prs_struct * } /******************************************************************* + initialises a structure. +********************************************************************/ + +BOOL init_srv_q_net_share_get_info(SRV_Q_NET_SHARE_GET_INFO *q_n, const char *srv_name, const char *share_name, uint32 info_level) +{ + + uint32 ptr_share_name; + + DEBUG(5,("init_srv_q_net_share_get_info\n")); + + init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name); + init_buf_unistr2(&q_n->uni_share_name, &ptr_share_name, share_name); + + q_n->info_level = info_level; + + return True; +} + +/******************************************************************* Reads or writes a structure. ********************************************************************/ @@ -792,10 +1204,24 @@ static BOOL srv_io_srv_share_info(char *desc, prs_struct *ps, int depth, SRV_SHA if (r_n->ptr_share_ctr != 0) { switch (r_n->switch_value) { + case 0: + if(!srv_io_share_info0("", &r_n->share.info0.info_0, ps, depth)) + return False; + + /* allow access to pointers in the str part. */ + r_n->share.info0.info_0_str.ptrs = &r_n->share.info0.info_0; + + if(!srv_io_share_info0_str("", &r_n->share.info0.info_0_str, ps, depth)) + return False; + + break; case 1: if(!srv_io_share_info1("", &r_n->share.info1.info_1, ps, depth)) return False; + /* allow access to pointers in the str part. */ + r_n->share.info1.info_1_str.ptrs = &r_n->share.info1.info_1; + if(!srv_io_share_info1_str("", &r_n->share.info1.info_1_str, ps, depth)) return False; @@ -819,16 +1245,40 @@ 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. */ + /* 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; + case 1004: + if(!srv_io_share_info1004("", &r_n->share.info1004.info_1004, ps, depth)) + return False; + + /* allow access to pointers in the str part. */ + r_n->share.info1004.info_1004_str.ptrs = &r_n->share.info1004.info_1004; + + if(!srv_io_share_info1004_str("", &r_n->share.info1004.info_1004_str, ps, depth)) + return False; + break; case 1005: if(!srv_io_share_info1005("", &r_n->share.info1005, ps, depth)) return False; break; + case 1006: + if(!srv_io_share_info1006("", &r_n->share.info1006, ps, depth)) + return False; + break; + case 1007: + if(!srv_io_share_info1007("", &r_n->share.info1007.info_1007, ps, depth)) + return False; + + /* allow access to pointers in the str part. */ + r_n->share.info1007.info_1007_str.ptrs = &r_n->share.info1007.info_1007; + + if(!srv_io_share_info1007_str("", &r_n->share.info1007.info_1007_str, ps, depth)) + return False; + break; case 1501: if (!srv_io_share_info1501("", &r_n->share.info1501, ps, depth)) return False; @@ -870,6 +1320,34 @@ BOOL srv_io_r_net_share_get_info(char *desc, SRV_R_NET_SHARE_GET_INFO *r_n, prs_ } /******************************************************************* + intialises a structure. +********************************************************************/ + +BOOL init_srv_q_net_share_set_info(SRV_Q_NET_SHARE_SET_INFO *q_n, + const char *srv_name, + const char *share_name, + uint32 info_level, + const SRV_SHARE_INFO *info) +{ + + uint32 ptr_share_name; + + DEBUG(5,("init_srv_q_net_share_set_info\n")); + + init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name); + init_buf_unistr2(&q_n->uni_share_name, &ptr_share_name, share_name); + + q_n->info_level = info_level; + + q_n->info = *info; + + q_n->ptr_parm_error = 1; + q_n->parm_error = 0; + + return True; +} + +/******************************************************************* Reads or writes a structure. ********************************************************************/ @@ -904,6 +1382,15 @@ BOOL srv_io_q_net_share_set_info(char *desc, SRV_Q_NET_SHARE_SET_INFO *q_n, prs_ if(!srv_io_srv_share_info("info ", ps, depth, &q_n->info)) return False; + if(!prs_align(ps)) + return False; + if(!prs_uint32("ptr_parm_error", ps, depth, &q_n->ptr_parm_error)) + return False; + if(q_n->ptr_parm_error!=0) { + if(!prs_uint32("parm_error", ps, depth, &q_n->parm_error)) + return False; + } + return True; } @@ -911,9 +1398,9 @@ BOOL srv_io_q_net_share_set_info(char *desc, SRV_Q_NET_SHARE_SET_INFO *q_n, prs_ Reads or writes a structure. ********************************************************************/ -BOOL srv_io_r_net_share_set_info(char *desc, SRV_R_NET_SHARE_SET_INFO *q_n, prs_struct *ps, int depth) +BOOL srv_io_r_net_share_set_info(char *desc, SRV_R_NET_SHARE_SET_INFO *r_n, prs_struct *ps, int depth) { - if (q_n == NULL) + if (r_n == NULL) return False; prs_debug(ps, depth, desc, "srv_io_r_net_share_set_info"); @@ -922,14 +1409,22 @@ BOOL srv_io_r_net_share_set_info(char *desc, SRV_R_NET_SHARE_SET_INFO *q_n, prs_ if(!prs_align(ps)) return False; - if(!prs_uint32("switch_value ", ps, depth, &q_n->switch_value)) + if(!prs_uint32("ptr_parm_error ", ps, depth, &r_n->ptr_parm_error)) return False; - if(!prs_werror("status", ps, depth, &q_n->status)) + + if(r_n->ptr_parm_error) { + + if(!prs_uint32("parm_error ", ps, depth, &r_n->parm_error)) + return False; + } + + if(!prs_werror("status", ps, depth, &r_n->status)) return False; return True; } + /******************************************************************* Reads or writes a structure. ********************************************************************/ @@ -962,6 +1457,9 @@ BOOL srv_io_q_net_share_add(char *desc, SRV_Q_NET_SHARE_ADD *q_n, prs_struct *ps if(!srv_io_srv_share_info("info ", ps, depth, &q_n->info)) return False; + if(!prs_align(ps)) + return False; + if(!prs_uint32("ptr_err_index", ps, depth, &q_n->ptr_err_index)) return False; if (q_n->ptr_err_index) @@ -994,9 +1492,9 @@ void init_srv_q_net_share_add(SRV_Q_NET_SHARE_ADD *q, char *srvname, Reads or writes a structure. ********************************************************************/ -BOOL srv_io_r_net_share_add(char *desc, SRV_R_NET_SHARE_ADD *q_n, prs_struct *ps, int depth) +BOOL srv_io_r_net_share_add(char *desc, SRV_R_NET_SHARE_ADD *r_n, prs_struct *ps, int depth) { - if (q_n == NULL) + if (r_n == NULL) return False; prs_debug(ps, depth, desc, "srv_io_r_net_share_add"); @@ -1005,14 +1503,25 @@ BOOL srv_io_r_net_share_add(char *desc, SRV_R_NET_SHARE_ADD *q_n, prs_struct *ps if(!prs_align(ps)) return False; - if(!prs_uint32("switch_value ", ps, depth, &q_n->switch_value)) + if(!prs_uint32("ptr_parm_error", ps, depth, &r_n->ptr_parm_error)) return False; - if(!prs_werror("status", ps, depth, &q_n->status)) + + if(r_n->ptr_parm_error) { + + if(!prs_uint32("parm_error", ps, depth, &r_n->parm_error)) + return False; + } + + if(!prs_werror("status", ps, depth, &r_n->status)) return False; return True; } +/******************************************************************* + initialises a structure. +********************************************************************/ + void init_srv_q_net_share_del(SRV_Q_NET_SHARE_DEL *del, const char *srvname, const char *sharename) { @@ -1889,8 +2398,8 @@ static BOOL srv_io_file_info3_str(char *desc, FILE_INFO_3_STR *sh1, prs_struct * ********************************************************************/ void init_srv_file_info3(FILE_INFO_3 *fl3, - uint32 id, uint32 perms, uint32 num_locks, - char *path_name, char *user_name) + uint32 id, uint32 perms, uint32 num_locks, + char *path_name, char *user_name) { DEBUG(5,("init_srv_file_info3: %s %s\n", path_name, user_name)); @@ -2296,7 +2805,7 @@ void init_srv_info_102(SRV_INFO_102 *sv102, uint32 platform_id, char *name, sv102->disc = disc; sv102->hidden = hidden; sv102->announce = announce; - sv102->ann_delta =ann_delta; + sv102->ann_delta = ann_delta; sv102->licenses = licenses; init_buf_unistr2(&sv102->uni_usr_path, &sv102->ptr_usr_path, usr_path); } @@ -2560,7 +3069,7 @@ BOOL srv_io_r_net_srv_set_info(char *desc, SRV_R_NET_SRV_SET_INFO *r_n, if(!prs_align(ps)) return False; - if(!prs_uint32("switch_value ", ps, depth, &r_n->switch_value)) + if(!prs_uint32("switch value ", ps, depth, &r_n->switch_value)) return False; if(!prs_werror("status", ps, depth, &r_n->status)) @@ -2689,6 +3198,31 @@ BOOL srv_io_r_net_remote_tod(char *desc, SRV_R_NET_REMOTE_TOD *r_n, prs_struct * } /******************************************************************* + initialises a structure. + ********************************************************************/ + +BOOL init_srv_q_net_disk_enum(SRV_Q_NET_DISK_ENUM *q_n, + const char *srv_name, + uint32 preferred_len, + ENUM_HND *enum_hnd + ) +{ + + + DEBUG(5,("init_srv_q_net_srv_disk_enum\n")); + + init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name); + + q_n->disk_enum_ctr.level = 0; + q_n->disk_enum_ctr.disk_info_ptr = 0; + + q_n->preferred_len = preferred_len; + memcpy(&q_n->enum_hnd, enum_hnd, sizeof(*enum_hnd)); + + return True; +} + +/******************************************************************* Reads or writes a structure. ********************************************************************/ @@ -2738,7 +3272,9 @@ BOOL srv_io_q_net_disk_enum(char *desc, SRV_Q_NET_DISK_ENUM *q_n, prs_struct *ps BOOL srv_io_r_net_disk_enum(char *desc, SRV_R_NET_DISK_ENUM *r_n, prs_struct *ps, int depth) { + int i; + uint32 entries_read, entries_read2, entries_read3; if (r_n == NULL) return False; @@ -2746,23 +3282,36 @@ BOOL srv_io_r_net_disk_enum(char *desc, SRV_R_NET_DISK_ENUM *r_n, prs_struct *ps prs_debug(ps, depth, desc, "srv_io_r_net_disk_enum"); depth++; + entries_read = entries_read2 = entries_read3 = r_n->disk_enum_ctr.entries_read; + if(!prs_align(ps)) return False; - if(!prs_uint32("entries_read", ps, depth, &r_n->disk_enum_ctr.entries_read)) + if(!prs_uint32("entries_read", ps, depth, &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)) + if(!prs_uint32("max_elements", ps, depth, &entries_read2)) 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)) + if(!prs_uint32("actual_elements", ps, depth, &entries_read3)) return False; + r_n->disk_enum_ctr.entries_read = entries_read3; + + if(UNMARSHALLING(ps)) { + + DISK_INFO *dinfo; + + if(!(dinfo = (DISK_INFO *)prs_alloc_mem(ps, sizeof(*dinfo) * entries_read3))) + return False; + r_n->disk_enum_ctr.disk_info = dinfo; + } + 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)) @@ -2788,6 +3337,25 @@ BOOL srv_io_r_net_disk_enum(char *desc, SRV_R_NET_DISK_ENUM *r_n, prs_struct *ps } /******************************************************************* + initialises a structure. + ********************************************************************/ + +BOOL init_srv_q_net_name_validate(SRV_Q_NET_NAME_VALIDATE *q_n, const char *srv_name, const char *share_name, int type) +{ + uint32 ptr_share_name; + + DEBUG(5,("init_srv_q_net_name_validate\n")); + + init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name); + init_buf_unistr2(&q_n->uni_name, &ptr_share_name, share_name); + + q_n->type = type; + q_n->flags = 0; + + return True; +} + +/******************************************************************* Reads or writes a structure. ********************************************************************/ diff --git a/source3/rpc_server/srv_srvsvc.c b/source3/rpc_server/srv_srvsvc.c index 5e1c005d54..4a372de089 100644 --- a/source3/rpc_server/srv_srvsvc.c +++ b/source3/rpc_server/srv_srvsvc.c @@ -345,6 +345,36 @@ static BOOL api_srv_net_share_del(pipes_struct *p) } /******************************************************************* + RPC to delete share information. +********************************************************************/ + +static BOOL api_srv_net_share_del_sticky(pipes_struct *p) +{ + SRV_Q_NET_SHARE_DEL q_u; + SRV_R_NET_SHARE_DEL 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 del info. */ + if(!srv_io_q_net_share_del("", &q_u, data, 0)) { + DEBUG(0,("api_srv_net_share_del_sticky: Failed to unmarshall SRV_Q_NET_SHARE_DEL.\n")); + return False; + } + + r_u.status = _srv_net_share_del_sticky(p, &q_u, &r_u); + + if(!srv_io_r_net_share_del("", &r_u, rdata, 0)) { + DEBUG(0,("api_srv_net_share_del_sticky: Failed to marshall SRV_R_NET_SHARE_DEL.\n")); + return False; + } + + return True; +} + +/******************************************************************* api_srv_net_remote_tod ********************************************************************/ @@ -503,6 +533,7 @@ static const struct api_struct api_srv_cmds[] = { "SRV_NET_SHARE_ENUM" , SRV_NET_SHARE_ENUM , api_srv_net_share_enum }, { "SRV_NET_SHARE_ADD" , SRV_NET_SHARE_ADD , api_srv_net_share_add }, { "SRV_NET_SHARE_DEL" , SRV_NET_SHARE_DEL , api_srv_net_share_del }, + { "SRV_NET_SHARE_DEL_STICKY", SRV_NET_SHARE_DEL_STICKY, api_srv_net_share_del_sticky }, { "SRV_NET_SHARE_GET_INFO", SRV_NET_SHARE_GET_INFO, api_srv_net_share_get_info }, { "SRV_NET_SHARE_SET_INFO", SRV_NET_SHARE_SET_INFO, api_srv_net_share_set_info }, { "SRV_NET_FILE_ENUM" , SRV_NET_FILE_ENUM , api_srv_net_file_enum }, diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c index 202e869d35..b68dcce672 100644 --- a/source3/rpc_server/srv_srvsvc_nt.c +++ b/source3/rpc_server/srv_srvsvc_nt.c @@ -3,6 +3,7 @@ * RPC Pipe client / server routines * Copyright (C) Andrew Tridgell 1992-1997, * Copyright (C) Jeremy Allison 2001. + * Copyright (C) Nigel Williams 2001. * * 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 @@ -29,32 +30,53 @@ extern pstring global_myname; /******************************************************************* + Utility function to get the 'type' of a share from an snum. + ********************************************************************/ +static uint32 get_share_type(int snum) +{ + 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(snum)) + type = STYPE_PRINTQ; + if (strequal(lp_fstype(snum), "IPC")) + type = STYPE_IPC; + if (net_name[len_net_name] == '$') + type |= STYPE_HIDDEN; + + return type; +} + +/******************************************************************* + Fill in a share info level 0 structure. + ********************************************************************/ + +static void init_srv_share_info_0(pipes_struct *p, SRV_SHARE_INFO_0 *sh0, int snum) +{ + 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, SRV_SHARE_INFO_1 *sh1, int snum) { - int len_net_name; - pstring net_name; pstring remark; - uint32 type; - pstrcpy(net_name, lp_servicename(snum)); + char *net_name = lp_servicename(snum); pstrcpy(remark, lp_comment(snum)); standard_sub_conn(p->conn, remark,sizeof(remark)); - len_net_name = strlen(net_name); - /* work out the share type */ - type = STYPE_DISKTREE; - - if (lp_print_ok(snum)) - type = STYPE_PRINTQ; - if (strequal("IPC$", net_name) || strequal("ADMIN$", net_name)) - type = STYPE_IPC; - if (net_name[len_net_name] == '$') - type |= STYPE_HIDDEN; - - init_srv_share_info1(&sh1->info_1, net_name, type, remark); + 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); } @@ -64,14 +86,11 @@ static void init_srv_share_info_1(pipes_struct *p, SRV_SHARE_INFO_1 *sh1, int sn static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int snum) { - int len_net_name; - pstring net_name; pstring remark; pstring path; pstring passwd; - uint32 type; - pstrcpy(net_name, lp_servicename(snum)); + char *net_name = lp_servicename(snum); pstrcpy(remark, lp_comment(snum)); standard_sub_conn(p->conn, remark,sizeof(remark)); pstrcpy(path, "C:"); @@ -85,19 +104,8 @@ static void init_srv_share_info_2(pipes_struct *p, SRV_SHARE_INFO_2 *sh2, int sn string_replace(path, '/', '\\'); pstrcpy(passwd, ""); - len_net_name = strlen(net_name); - /* work out the share type */ - type = STYPE_DISKTREE; - - if (lp_print_ok(snum)) - type = STYPE_PRINTQ; - if (strequal("IPC$", net_name) || strequal("ADMIN$", net_name)) - type = STYPE_IPC; - if (net_name[len_net_name] == '$') - type |= STYPE_HIDDEN; - - init_srv_share_info2(&sh2->info_2, net_name, type, remark, 0, 0xffffffff, 1, path, passwd); + init_srv_share_info2(&sh2->info_2, net_name, get_share_type(snum), remark, 0, 0xffffffff, 1, path, passwd); init_srv_share_info2_str(&sh2->info_2_str, net_name, remark, path, passwd); } @@ -251,7 +259,7 @@ static BOOL set_share_security(TALLOC_CTX *ctx, const char *share_name, SEC_DESC /* Free malloc'ed memory */ - out: +out: prs_mem_free(&ps); if (mem_ctx) @@ -337,7 +345,7 @@ BOOL share_access_check(connection_struct *conn, int snum, user_struct *vuser, u ret = se_access_check(psd, token, desired_access, &granted, &status); - out: +out: talloc_destroy(mem_ctx); @@ -351,27 +359,15 @@ BOOL share_access_check(connection_struct *conn, int snum, user_struct *vuser, u static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501, int snum) { int len_net_name; - pstring net_name; pstring remark; - uint32 type; - pstrcpy(net_name, lp_servicename(snum)); + char *net_name = lp_servicename(snum); pstrcpy(remark, lp_comment(snum)); standard_sub_conn(p->conn, remark, sizeof(remark)); len_net_name = strlen(net_name); - /* work out the share type */ - type = STYPE_DISKTREE; - - if (lp_print_ok(snum)) - type = STYPE_PRINTQ; - if (strequal("IPC$", net_name) || strequal("ADMIN$", net_name)) - type = STYPE_IPC; - if (net_name[len_net_name] == '$') - type |= STYPE_HIDDEN; - - init_srv_share_info501(&sh501->info_501, net_name, type, remark, (lp_csc_policy(snum) << 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); } @@ -386,7 +382,6 @@ static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, pstring remark; pstring path; pstring passwd; - uint32 type; SEC_DESC *sd; size_t sd_size; TALLOC_CTX *ctx = p->mem_ctx; @@ -410,39 +405,86 @@ static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, pstrcpy(passwd, ""); len_net_name = strlen(net_name); - /* work out the share type */ - type = STYPE_DISKTREE; - - if (lp_print_ok(snum)) - type = STYPE_PRINTQ; - if (strequal("IPC$", net_name)) - type = STYPE_IPC; - if (net_name[len_net_name] == '$') - type |= STYPE_HIDDEN; - 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, &sh502->info_502, net_name, remark, path, passwd, sd, sd_size); + 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, SRV_SHARE_INFO_1004* sh1004, int snum) +{ + pstring remark; + + pstrcpy(remark, lp_comment(snum)); + standard_sub_conn(p->conn, remark, sizeof(remark)); + + ZERO_STRUCTP(sh1004); + + 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(SRV_SHARE_INFO_1005* sh1005, int snum) +static void init_srv_share_info_1005(pipes_struct *p, SRV_SHARE_INFO_1005* sh1005, int snum) { sh1005->dfs_root_flag = 0; if(lp_host_msdfs() && lp_msdfs_root(snum)) sh1005->dfs_root_flag = 3; } +/*************************************************************************** + Fill in a share info level 1006 structure. + ***************************************************************************/ + +static void init_srv_share_info_1006(pipes_struct *p, SRV_SHARE_INFO_1006* sh1006, int snum) +{ + sh1006->max_uses = -1; +} + +/*************************************************************************** + Fill in a share info level 1007 structure. + ***************************************************************************/ + +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); + + 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, SRV_SHARE_INFO_1501 *sh1501, int snum) +{ + SEC_DESC *sd; + size_t sd_size; + TALLOC_CTX *ctx = p->mem_ctx; + + ZERO_STRUCTP(sh1501); + + sd = get_share_security(ctx, snum, &sd_size); + + sh1501->sdb = make_sec_desc_buf(p->mem_ctx, sd_size, sd); +} /******************************************************************* True if it ends in '$'. ********************************************************************/ -static BOOL is_admin_share(int snum) +static BOOL is_hidden_share(int snum) { pstring net_name; @@ -471,7 +513,7 @@ static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr, /* Count the number of entries. */ for (snum = 0; snum < num_services; snum++) { - if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) num_entries++; } @@ -483,6 +525,24 @@ static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr, return True; switch (info_level) { + case 0: + { + SRV_SHARE_INFO_0 *info0; + int i = 0; + + info0 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_0)); + + 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: { SRV_SHARE_INFO_1 *info1; @@ -491,7 +551,7 @@ static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr, info1 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1)); for (snum = *resume_hnd; snum < num_services; snum++) { - if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { init_srv_share_info_1(p, &info1[i++], snum); } } @@ -508,7 +568,7 @@ static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr, info2 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_2)); for (snum = *resume_hnd; snum < num_services; snum++) { - if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { init_srv_share_info_2(p, &info2[i++], snum); } } @@ -525,7 +585,7 @@ static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr, info501 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_501)); for (snum = *resume_hnd; snum < num_services; snum++) { - if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { init_srv_share_info_501(p, &info501[i++], snum); } } @@ -542,7 +602,7 @@ static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr, info502 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_502)); for (snum = *resume_hnd; snum < num_services; snum++) { - if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_admin_share(snum)) ) { + if (lp_browseable(snum) && lp_snum_ok(snum) && (all_shares || !is_hidden_share(snum)) ) { init_srv_share_info_502(p, &info502[i++], snum); } } @@ -551,6 +611,92 @@ static BOOL init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr, break; } + /* here for completeness but not currently used with enum (1004 - 1501)*/ + + case 1004: + { + SRV_SHARE_INFO_1004 *info1004; + int i = 0; + + info1004 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1004)); + + 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: + { + SRV_SHARE_INFO_1005 *info1005; + int i = 0; + + info1005 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1005)); + + 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: + { + SRV_SHARE_INFO_1006 *info1006; + int i = 0; + + info1006 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1006)); + + 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: + { + SRV_SHARE_INFO_1007 *info1007; + int i = 0; + + info1007 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1007)); + + 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: + { + SRV_SHARE_INFO_1501 *info1501; + int i = 0; + + info1501 = talloc(ctx, num_entries * sizeof(SRV_SHARE_INFO_1501)); + + 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 False; @@ -596,6 +742,9 @@ static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_I if (snum >= 0) { switch (info_level) { + case 0: + init_srv_share_info_0(p, &r_n->info.share.info0, snum); + break; case 1: init_srv_share_info_1(p, &r_n->info.share.info1, snum); break; @@ -608,8 +757,24 @@ static void init_srv_r_net_share_get_info(pipes_struct *p, SRV_R_NET_SHARE_GET_I case 502: init_srv_share_info_502(p, &r_n->info.share.info502, snum); break; + + /* here for completeness */ + case 1004: + init_srv_share_info_1004(p, &r_n->info.share.info1004, snum); + break; case 1005: - init_srv_share_info_1005(&r_n->info.share.info1005, snum); + init_srv_share_info_1005(p, &r_n->info.share.info1005, snum); + break; + + /* here for completeness 1006 - 1501 */ + case 1006: + init_srv_share_info_1006(p, &r_n->info.share.info1006, snum); + break; + case 1007: + init_srv_share_info_1007(p, &r_n->info.share.info1007, snum); + break; + case 1501: + 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)); @@ -955,7 +1120,8 @@ static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n, ********************************************************************/ static WERROR init_srv_file_info_ctr(pipes_struct *p, SRV_FILE_INFO_CTR *ctr, - int switch_value, uint32 *resume_hnd, uint32 *total_entries) + int switch_value, uint32 *resume_hnd, + uint32 *total_entries) { WERROR status = WERR_OK; TALLOC_CTX *ctx = p->mem_ctx; @@ -1206,8 +1372,8 @@ WERROR _srv_net_share_enum(pipes_struct *p, SRV_Q_NET_SHARE_ENUM *q_u, SRV_R_NET /* Create the list of shares for the response. */ init_srv_r_net_share_enum(p, r_u, - q_u->ctr.info_level, - get_enum_hnd(&q_u->enum_hnd), False); + q_u->ctr.info_level, + get_enum_hnd(&q_u->enum_hnd), False); DEBUG(5,("_srv_net_share_enum: %d\n", __LINE__)); @@ -1295,7 +1461,7 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S unistr2_to_ascii(share_name, &q_u->uni_share_name, sizeof(share_name)); - r_u->switch_value = 0; + r_u->parm_error = 0; if (strequal(share_name,"IPC$") || strequal(share_name,"ADMIN$") || strequal(share_name,"global")) return WERR_ACCESS_DENIED; @@ -1312,28 +1478,47 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S get_current_user(&user,p); - if (user.uid != 0) + if (user.uid != sec_initial_uid()) return WERR_ACCESS_DENIED; switch (q_u->info_level) { case 1: - /* Not enough info in a level 1 to do anything. */ - return WERR_ACCESS_DENIED; + fstrcpy(pathname, lp_pathname(snum)); + 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: - 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)); + 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; 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: - 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)); + 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: + fstrcpy(pathname, lp_pathname(snum)); + unistr2_to_ascii(comment, &q_u->info.share.info1004.info_1004_str.uni_remark, sizeof(comment)); + type = STYPE_DISKTREE; + break; case 1005: + case 1006: + case 1007: return WERR_ACCESS_DENIED; + break; case 1501: fstrcpy(pathname, lp_pathname(snum)); fstrcpy(comment, lp_comment(snum)); @@ -1422,12 +1607,12 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S DEBUG(5,("_srv_net_share_add: %d\n", __LINE__)); - r_u->switch_value = 0; + r_u->parm_error = 0; get_current_user(&user,p); - if (user.uid != 0) { - DEBUG(10,("_srv_net_share_add: uid != 0. Access denied.\n")); + if (user.uid != sec_initial_uid()) { + DEBUG(10,("_srv_net_share_add: uid != sec_initial_uid(). Access denied.\n")); return WERR_ACCESS_DENIED; } @@ -1437,6 +1622,9 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S } switch (q_u->info_level) { + case 0: + /* No path. Not enough info in a level 0 to do anything. */ + return WERR_ACCESS_DENIED; case 1: /* Not enough info in a level 1 to do anything. */ return WERR_ACCESS_DENIED; @@ -1446,6 +1634,9 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S unistr2_to_ascii(pathname, &q_u->info.share.info2.info_2_str.uni_path, sizeof(share_name)); 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: 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)); @@ -1454,7 +1645,16 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S 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 */ + + case 1004: case 1005: + case 1006: + case 1007: + return WERR_ACCESS_DENIED; + break; + case 1501: /* DFS only level. */ return WERR_ACCESS_DENIED; default: @@ -1544,7 +1744,7 @@ WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_S get_current_user(&user,p); - if (user.uid != 0) + if (user.uid != sec_initial_uid()) return WERR_ACCESS_DENIED; if (!lp_delete_share_cmd() || !*lp_delete_share_cmd()) @@ -1570,6 +1770,13 @@ WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_S return WERR_OK; } +WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_SHARE_DEL *r_u) +{ + DEBUG(5,("_srv_net_share_del_stick: %d\n", __LINE__)); + + return _srv_net_share_del(p, q_u, r_u); +} + /******************************************************************* time of day ********************************************************************/ @@ -1703,7 +1910,7 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC close_cnum(conn, user.vuid); return r_u->status; - error_exit: +error_exit: if(fsp) { close_file(fsp, True); @@ -1799,7 +2006,7 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_ close_cnum(conn, user.vuid); return r_u->status; - error_exit: +error_exit: if(fsp) { close_file(fsp, True); @@ -1864,6 +2071,7 @@ WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_D { uint32 i; const char *disk_name; + TALLOC_CTX *ctx = p->mem_ctx; uint32 resume=get_enum_hnd(&q_u->enum_hnd); r_u->status=WERR_OK; @@ -1872,6 +2080,18 @@ WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_D r_u->disk_enum_ctr.unknown = 0; + { + DISK_INFO *dinfo; + + int dinfo_size = MAX_SERVER_DISK_ENTRIES * sizeof(*dinfo); + + if(!(dinfo = talloc(ctx, dinfo_size))) { + + } + + r_u->disk_enum_ctr.disk_info = dinfo; + } + r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0; /*allow one DISK_INFO for null terminator*/ @@ -1885,7 +2105,7 @@ WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_D 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?*/ + /* add a terminating null string. Is this there if there is more data to come? */ r_u->disk_enum_ctr.entries_read++; |