PATCH rpcclient
Nigel Williams
nigel at veritas.com
Mon Jan 21 17:38:01 GMT 2002
This patch contains adds share management functionality to rpcclient
nigel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smbcacl_lib.h
Type: application/octet-stream
Size: 1145 bytes
Desc: not available
Url : http://lists.samba.org/archive/samba-technical/attachments/20020121/ee9f3d20/smbcacl_lib.obj
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smbcacl_lib.c
Type: application/octet-stream
Size: 16416 bytes
Desc: not available
Url : http://lists.samba.org/archive/samba-technical/attachments/20020121/ee9f3d20/smbcacl_lib-0001.obj
-------------- next part --------------
Index: include/includes.h
===================================================================
RCS file: /cvsroot/samba/source/include/includes.h,v
retrieving revision 1.257
diff -u -r1.257 includes.h
--- include/includes.h 20 Jan 2002 14:30:53 -0000 1.257
+++ include/includes.h 22 Jan 2002 01:22:51 -0000
@@ -743,6 +743,8 @@
#include "popt.h"
+#include "smbcacl_lib.h"
+
#ifndef MAXCODEPAGELINES
#define MAXCODEPAGELINES 256
#endif
Index: rpcclient/cmd_srvsvc.c
===================================================================
RCS file: /cvsroot/samba/source/rpcclient/cmd_srvsvc.c,v
retrieving revision 1.30
diff -u -r1.30 cmd_srvsvc.c
--- rpcclient/cmd_srvsvc.c 12 Oct 2001 05:56:23 -0000 1.30
+++ rpcclient/cmd_srvsvc.c 22 Jan 2002 01:22:55 -0000
@@ -6,6 +6,7 @@
Copyright (C) Andrew Tridgell 1992-1999
Copyright (C) Luke Kenneth Casson Leighton 1996 - 1999
Copyright (C) Tim Potter 2000
+ 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
@@ -222,13 +223,1645 @@
return result;
}
+static void unistr3_to_ascii(char *dest, const UNISTR3 *str, size_t maxlen)
+{
+ UNISTR2 desc;
+
+ desc.uni_max_len = str->uni_str_len;
+ desc.uni_str_len = str->uni_str_len;
+ desc.buffer = str->str.buffer;
+
+ return unistr2_to_ascii(dest, &desc, maxlen);
+}
+
+static void display_srv_disk_info_0(DISK_INFO *disk_info)
+{
+ fstring disk_name;
+
+ unistr3_to_ascii(disk_name, &disk_info->disk_name, sizeof(disk_name)-1);
+
+ printf("\t%s\n", disk_name);
+}
+
+static NTSTATUS cmd_srvsvc_srv_disk_enum(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
+{
+
+ int i;
+ uint32 preferred_len = 0xffffffff;
+ ENUM_HND enum_hnd;
+ uint32 er, entries_read;
+ uint32 total_entries;
+ DISK_INFO *disk_info;
+
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+ if (argc != 1) {
+ printf("Usage: %s\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ ZERO_STRUCT(enum_hnd);
+
+ er = 0;
+
+ do {
+
+ result = cli_srvsvc_net_srv_disk_enum(cli,
+ mem_ctx,
+ cli->desthost,
+ preferred_len,
+ &enum_hnd,
+ &entries_read,
+ &total_entries,
+ &disk_info
+ );
+
+
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+
+ /* Display results */
+
+ for(i = 0; i < entries_read; i++) {
+
+ display_srv_disk_info_0(disk_info+i);
+ }
+
+ er += entries_read;
+
+ } while(er < total_entries);
+
+
+ done:
+ return result;
+}
+
+static NTSTATUS cmd_srvsvc_name_validate(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
+{
+
+ fstring name;
+
+ typedef enum _NETSETUP_NAME_TYPE {
+
+ NetSetupUnknown = 0,
+ NetSetupMachine,
+ NetSetupWorkgroup,
+ NetSetupDomain,
+ NetSetupNonExistentDomain,
+#if(_WIN32_WINNT >= 0x0500)
+ NetSetupDnsMachine,
+#endif
+ NetSetupShare = 9 /* not documented in msdn under NetValidateName */
+
+ } NETSETUP_NAME_TYPE, *PNETSETUP_NAME_TYPE;
+
+ NETSETUP_NAME_TYPE type = NetSetupShare;
+
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+ if (argc > 3 || argc < 2) {
+ printf("Usage: %s [netname] [type]\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ fstrcpy(name, argv[1]);
+
+ if(argc == 3)
+ type = atoi(argv[2]);
+
+ result = cli_srvsvc_net_name_validate(cli,
+ mem_ctx,
+ cli->desthost,
+ name,
+ type
+ );
+
+
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+
+ done:
+ return result;
+}
+
+#define CONST_STR(A) ((char *)(A))
+#define ELEMS(A) (sizeof(A)/sizeof((A)[0]))
+
+/*
+ * Some defs that will move in the future
+ *
+ */
+
+#define SHARE_NETNAME_PARMNUM 1
+#define SHARE_TYPE_PARMNUM 3
+#define SHARE_REMARK_PARMNUM 4
+#define SHARE_PERMISSIONS_PARMNUM 5
+#define SHARE_MAX_USES_PARMNUM 6
+#define SHARE_CURRENT_USES_PARMNUM 7
+#define SHARE_PATH_PARMNUM 8
+#define SHARE_PASSWD_PARMNUM 9
+#define SHARE_FILE_SD_PARMNUM 501
+
+typedef struct {
+
+ const char *name;
+ uint32 value;
+} assoc;
+
+static assoc share_info_fields [] = {
+
+ "SHARE_NETNAME_PARMNUM", SHARE_NETNAME_PARMNUM,
+ "SHARE_TYPE_PARMNUM", SHARE_TYPE_PARMNUM,
+ "SHARE_REMARK_PARMNUM", SHARE_REMARK_PARMNUM,
+ "SHARE_PERMISSIONS_PARMNUM", SHARE_PERMISSIONS_PARMNUM,
+ "SHARE_MAX_USES_PARMNUM", SHARE_MAX_USES_PARMNUM,
+ "SHARE_CURRENT_USES_PARMNUM", SHARE_CURRENT_USES_PARMNUM,
+ "SHARE_PATH_PARMNUM", SHARE_PATH_PARMNUM,
+ "SHARE_PASSWD_PARMNUM", SHARE_PASSWD_PARMNUM,
+ "SHARE_FILE_SD_PARMNUM", SHARE_FILE_SD_PARMNUM,
+ {NULL}
+};
+
+#define SHARE_REMARK_INFOLEVEL \
+ (PARMNUM_BASE_INFOLEVEL + SHARE_REMARK_PARMNUM)
+#define SHARE_MAX_USES_INFOLEVEL \
+ (PARMNUM_BASE_INFOLEVEL + SHARE_MAX_USES_PARMNUM)
+#define SHARE_FILE_SD_INFOLEVEL \
+ (PARMNUM_BASE_INFOLEVEL + SHARE_FILE_SD_PARMNUM)
+
+#define SHI1_NUM_ELEMENTS 4
+#define SHI2_NUM_ELEMENTS 10
+
+#define SHI_USES_UNLIMITED (DWORD)-1
+
+#define SHI1005_FLAGS_DFS 0x01 // Share is in the DFS
+#define SHI1005_FLAGS_DFS_ROOT 0x02 // Share is root of DFS
+
+#define COW_PERMACHINE 0x04 // Share data is per-machine data
+#define COW_PERUSER 0x08 // Share data is per-user data
+
+#define CSC_CACHEABLE 0x10 // Client can cache files for off-line access
+#define CSC_NOFLOWOPS 0x20 // Client need not flow operations to the server
+#define CSC_AUTO_INWARD 0x40 // Auto inward propagation (server->client) w/o UI
+#define CSC_AUTO_OUTWARD 0x80 // Auto outward propagation(client->server) w/o UI
+
+#define SHI1005_VALID_FLAGS_SET ( CSC_CACHEABLE | \
+ CSC_NOFLOWOPS | \
+ CSC_AUTO_INWARD | \
+ CSC_AUTO_OUTWARD| \
+ COW_PERMACHINE | \
+ COW_PERUSER )
+
+#define SHI1007_VALID_FLAGS_SET SHI1005_VALID_FLAGS_SET
+
+static assoc flag_names[] = {
+
+ "SHI1005_FLAGS_DFS", SHI1005_FLAGS_DFS,
+ "SHI1005_FLAGS_DFS_ROOT", SHI1005_FLAGS_DFS_ROOT,
+ "COW_PERMACHINE", COW_PERMACHINE,
+ "COW_PERUSER", COW_PERUSER,
+ "CSC_CACHEABLE", CSC_CACHEABLE,
+ "CSC_NOFLOWOPS", CSC_NOFLOWOPS,
+ "CSC_AUTO_INWARD", CSC_AUTO_INWARD,
+ "CSC_AUTO_OUTWARD", CSC_AUTO_OUTWARD,
+ {NULL}
+};
+
+#define ACCESS_NONE 0
+#define ACCESS_ALL ( ACCESS_READ | \
+ ACCESS_WRITE | \
+ ACCESS_CREATE | \
+ ACCESS_EXEC | \
+ ACCESS_DELETE | \
+ ACCESS_ATRIB | \
+ ACCESS_PERM \
+ )
+
+#define ACCESS_READ 0x01
+#define ACCESS_WRITE 0x02
+#define ACCESS_CREATE 0x04
+#define ACCESS_EXEC 0x08
+#define ACCESS_DELETE 0x10
+#define ACCESS_ATRIB 0x20
+#define ACCESS_PERM 0x40
+
+#define SHARE_ACCESS_READ ACCESS_READ
+#define SHARE_ACCESS_WRITE ACCESS_WRITE
+#define SHARE_ACCESS_CREATE ACCESS_CREATE
+#define SHARE_ACCESS_EXEC ACCESS_EXEC
+#define SHARE_ACCESS_DELETE ACCESS_DELETE
+#define SHARE_ACCESS_ATRIB ACCESS_ATRIB
+#define SHARE_ACCESS_PERM ACCESS_PERM
+#define SHARE_ACCESS_NONE ACCESS_NONE
+#define SHARE_ACCESS_ALL ACCESS_ALL
+
+static assoc share_types[] = {
+
+ {"Admin", STYPE_HIDDEN},
+ {"Disk", STYPE_DISKTREE},
+ {"Printer", STYPE_PRINTQ},
+ {"Device", STYPE_DEVICE},
+ {"IPC", STYPE_IPC},
+ {NULL}
+};
+
+static assoc perm_types[] = {
+
+ {"ACCESS_READ", SHARE_ACCESS_READ},
+ {"ACCESS_WRITE", SHARE_ACCESS_WRITE},
+ {"ACCESS_CREATE", SHARE_ACCESS_CREATE},
+ {"ACCESS_EXEC", SHARE_ACCESS_EXEC},
+ {"ACCESS_DELETE", SHARE_ACCESS_DELETE},
+ {"ACCESS_ATRIB", SHARE_ACCESS_ATRIB},
+ {"ACCESS_PERM", SHARE_ACCESS_PERM},
+ {"ACCESS_NONE", SHARE_ACCESS_NONE},
+ {"ACCESS_ALL", SHARE_ACCESS_ALL},
+ {NULL}
+};
+
+static const char *admin_share = "admin_";
+
+static BOOL find_assoc(const assoc *a, char *name, size_t name_len, uint32 *value)
+{
+
+ int i;
+
+ if(*name) {
+
+ for(i = 0; a[i].name; i++) {
+
+ if(strncmp(name, a[i].name, name_len) == 0) {
+
+ *value = a[i].value;
+ return True;
+ }
+ }
+ } else {
+
+ for(i = 0; a[i].name; i++) {
+
+ if(a[i].value == *value) {
+
+ strncpy(name, a[i].name, name_len);
+ return True;
+ }
+ }
+ }
+
+ return False;
+}
+
+static BOOL find_assoc_all(const assoc *a, char *name, size_t name_len, uint32 *value, const char *separator)
+{
+
+ BOOL ret = False;
+
+ int i;
+
+ if(*name) {
+
+ fstring tok;
+
+ char *p = name;
+
+ ret = True;
+
+ while(next_token((char **)&p, tok, (char *)separator, sizeof(tok))) {
+
+ BOOL loc_ret = False;
+
+ for(i = 0; !loc_ret && a[i].name; i++) {
+
+ if(strcmp(name, a[i].name) == 0) {
+
+ *value |= a[i].value;
+ loc_ret = True;
+ }
+ }
+
+ if(!loc_ret) {
+
+ ret = False;
+ break;
+ }
+ }
+
+ } else {
+
+ int offset = 0;
+
+ const char *loc_separator = "";
+
+ for(i = 0; a[i].name; i++) {
+
+ if(a[i].value == *value && (a[i].value & *value) == *value) {
+
+ offset += snprintf(&name[offset], name_len - offset, "%s%s", loc_separator, a[i].name);
+ loc_separator = separator;
+ }
+ }
+
+ if(offset == 0 || offset >= name_len)
+ ret = False;
+ }
+
+ return ret;
+}
+
+static BOOL parse_share_get_share_type_str(uint32 type, char *typestr, size_t size)
+{
+ BOOL ret = True;
+
+ *typestr = '\0';
+
+ if(type & STYPE_HIDDEN) {
+
+ strncat(typestr, admin_share, size);
+ size -= strlen(admin_share);
+
+ type &= ~STYPE_HIDDEN;
+ }
+
+ switch (type)
+ {
+ case STYPE_DISKTREE: strncat(typestr, "Disk" , size); break;
+ case STYPE_PRINTQ : strncat(typestr, "Printer", size); break;
+ case STYPE_DEVICE : strncat(typestr, "Device" , size); break;
+ case STYPE_IPC : strncat(typestr, "IPC" , size); break;
+ default :
+ strncat(typestr, "????", size);
+ ret = False;
+ break;
+ }
+
+ return ret;
+}
+
+static BOOL parse_share_get_share_type_from_str(const char *type_str, uint32 *type)
+{
+ int i;
+ int t = 0;
+
+ static int admin_share_len = -1;
+
+ if(!type_str)
+ return False;
+
+ if(admin_share_len < 0)
+ admin_share_len = strlen(admin_share);
+
+ *type = 0;
+
+ if(strncmp(type_str, admin_share, admin_share_len) == 0) {
+
+ *type |= STYPE_HIDDEN;
+
+ type_str += admin_share_len;
+ }
+
+ if(!find_assoc(share_types, (char *)type_str, strlen(type_str), &t))
+ return False;
+
+ *type |= t;
+
+ return True;
+}
+
+static BOOL parse_share_get_share_perms_str(uint32 perms, char *permsstr, size_t size)
+{
+ *permsstr = '\0';
+
+ return find_assoc_all(perm_types, permsstr, size, &perms, "|");
+}
+
+static BOOL parse_share_get_share_perms_from_str(const char *perms_str, uint32 *perms)
+{
+ *perms = 0;
+
+ if(!perms_str)
+ return False;
+
+ return find_assoc_all(perm_types, (char *)perms_str, strlen(perms_str), perms, "|");
+}
+
+static int parse_share_get_share_flags_str(uint32 flags, char *flagsstr, size_t size)
+{
+ *flagsstr = 0;
+
+ return find_assoc_all(flag_names, flagsstr, size, &flags, "|");
+}
+
+static BOOL parse_share_get_share_flags_from_str(const char *flagsstr, uint32 *flags)
+{
+ *flags = 0;
+
+ if(!flagsstr)
+ return False;
+
+ return find_assoc_all(flag_names, (char *)flagsstr, strlen(flagsstr), flags, "|");
+}
+
+typedef struct {
+
+ char locator;
+ const char *desc;
+ char *default_val;
+ char *val_ptr;
+ pstring val;
+ int found;
+} cmd_arg;
+
+static cmd_arg share_arg_type = {'t', "type", "Disk"};
+static cmd_arg share_arg_remark = {'r', "remark", NULL};
+static cmd_arg share_arg_perms = {'p', "permissions", "ACCESS_NONE"};
+static cmd_arg share_arg_max_uses = {'u', "max uses", "-1"};
+static cmd_arg share_arg_path = {'P', "path", NULL};
+static cmd_arg share_arg_passwd = {'w', "passwd", NULL};
+static cmd_arg share_arg_flags = {'f', "flags", "0"};
+static cmd_arg share_arg_sd = {'s', "security descriptor", NULL};
+static cmd_arg share_arg_adn = {'a', "alternate directory name", NULL};
+
+typedef struct {
+
+ cmd_arg *cmd_arg_p;
+ BOOL required;
+} cmd_arg_option;
+
+static cmd_arg_option options_level_0[] = {
+ {NULL}
+};
+
+static cmd_arg_option options_level_1[] = {
+ {&share_arg_type, False},
+ {&share_arg_remark, False},
+ {NULL}
+};
+
+static cmd_arg_option options_level_2[] = {
+ {&share_arg_type, False},
+ {&share_arg_remark, False},
+ {&share_arg_perms, False},
+ {&share_arg_max_uses, False},
+ {&share_arg_path, True},
+ {&share_arg_passwd, False},
+ {NULL}
+};
+
+static cmd_arg_option options_level_501[] = {
+ {&share_arg_type, False},
+ {&share_arg_remark, False},
+ {&share_arg_flags, True},
+ {NULL}
+};
+
+static cmd_arg_option options_level_502[] = {
+ {&share_arg_type, False},
+ {&share_arg_remark, False},
+ {&share_arg_perms, False},
+ {&share_arg_max_uses, False},
+ {&share_arg_path, True},
+ {&share_arg_passwd, False},
+ {&share_arg_sd, True},
+ {NULL}
+};
+
+static cmd_arg_option options_level_1004[] = {
+ {&share_arg_remark, True},
+ {NULL}
+};
+
+static cmd_arg_option options_level_1005[] = {
+ {&share_arg_flags, True},
+ {NULL}
+};
+
+static cmd_arg_option options_level_1006[] = {
+ {&share_arg_max_uses, True},
+ {NULL}
+};
+
+static cmd_arg_option options_level_1007[] = {
+ {&share_arg_flags, True},
+ {&share_arg_adn, True},
+ {NULL}
+};
+
+static cmd_arg_option options_level_1501[] = {
+ {&share_arg_sd, True},
+ {NULL}
+};
+
+typedef struct args_avalable_at_level {
+
+ int level;
+ cmd_arg_option *poss;
+} args_available_at_level;
+
+static args_available_at_level parse_share_args[] = {
+ {0, options_level_0},
+ {1, options_level_1},
+ {2, options_level_2},
+ {501, options_level_501},
+ {502, options_level_502},
+ {1004, options_level_1004},
+ {1005, options_level_1005},
+ {1006, options_level_1006},
+ {1007, options_level_1007},
+ {1501, options_level_1501},
+ {-1}
+};
+
+static const char *cmd_arg_val(cmd_arg_option *sao, char c)
+{
+ for(; sao->cmd_arg_p; sao++)
+ if(c == sao->cmd_arg_p->locator)
+ return sao->cmd_arg_p->val_ptr;
+
+ return NULL;
+}
+
+static void cmd_arg_show_usage_for_info_level(int level, cmd_arg_option *sao)
+{
+ printf("Usage for info level %d:\n", level);
+
+ for(; sao->cmd_arg_p; sao++)
+ printf("\t-%c:\tdefault:%s\tdesc: %s\n",
+ sao->cmd_arg_p->locator,
+ (sao->cmd_arg_p->default_val)?sao->cmd_arg_p->default_val:"<none>",
+ sao->cmd_arg_p->desc);
+}
+
+static BOOL cmd_arg_process(int level, args_available_at_level *aaal, int argc, char *argv[], cmd_arg_option **saop)
+{
+ extern char *optarg;
+ extern int optind;
+ int opt;
+ int i;
+ BOOL found = False;
+ fstring arg_control;
+
+ cmd_arg_option *sao = NULL;
+
+ for(; aaal->level >= 0; aaal++) {
+
+ if(aaal->level == level) {
+
+ found = True;
+ break;
+ }
+ }
+
+ if(!found) {
+
+ return False;
+ }
+
+ *saop = sao = aaal->poss;
+
+ *arg_control = 0;
+
+ for(; sao->cmd_arg_p; sao++) {
+
+ strncat(arg_control, &sao->cmd_arg_p->locator, 1);
+ strncat(arg_control, ":", 1);
+
+ sao->cmd_arg_p->found = 0;
+ }
+
+ optind = 0;
+
+ while((opt = getopt(argc, argv, arg_control)) != EOF) {
+
+ sao = aaal->poss;
+
+ for( ; sao->cmd_arg_p; sao++) {
+ if(opt == sao->cmd_arg_p->locator) {
+
+ sao->cmd_arg_p->found = 1;
+ sao->cmd_arg_p->val_ptr = sao->cmd_arg_p->val;
+ pstrcpy(sao->cmd_arg_p->val_ptr, optarg);
+ break;
+ }
+ }
+ }
+
+ sao = aaal->poss;
+
+ for(; sao->cmd_arg_p; sao++) {
+ if(!sao->cmd_arg_p->found) {
+
+ if(sao->required)
+ return False;
+
+ sao->cmd_arg_p->val_ptr = sao->cmd_arg_p->default_val;
+ }
+ }
+
+ return True;
+}
+
+static BOOL parse_share_share_info_from_args_0(SRV_SHARE_INFO_0 *si, const char *netname,
+ TALLOC_CTX *mem_ctx,
+ cmd_arg_option *sao)
+{
+ init_srv_share_info0(&si->info_0, CONST_STR(netname));
+ init_srv_share_info0_str(&si->info_0_str, CONST_STR(netname));
+
+ return True;
+}
+
+static BOOL parse_share_share_info_from_args_1(SRV_SHARE_INFO_1 *si, const char *netname,
+ TALLOC_CTX *mem_ctx,
+ cmd_arg_option *sao)
+{
+ int type;
+ const char *remark;
+
+ if(!parse_share_get_share_type_from_str(cmd_arg_val(sao, 't'), &type))
+ return False;
+
+ remark = cmd_arg_val(sao, 'r');
+
+ init_srv_share_info1(&si->info_1, CONST_STR(netname), type, CONST_STR(remark));
+ init_srv_share_info1_str(&si->info_1_str, CONST_STR(netname), CONST_STR(remark));
+
+ return True;
+}
+
+static BOOL parse_share_share_info_from_args_2(SRV_SHARE_INFO_2 *si, const char *netname,
+ TALLOC_CTX *mem_ctx,
+ cmd_arg_option *sao)
+{
+ int type;
+ const char *remark;
+ int perms;
+ int max_uses;
+ int num_uses;
+ const char *path;
+ const char *password;
+
+ if(!parse_share_get_share_type_from_str(cmd_arg_val(sao, 't'), &type))
+ return False;
+
+ remark = cmd_arg_val(sao, 'r');
+
+ if(!parse_share_get_share_perms_from_str(cmd_arg_val(sao, 'p'), &perms))
+ return False;
+
+ max_uses = atoi(cmd_arg_val(sao, 'u'));
+
+ num_uses = 0;
+
+ path = cmd_arg_val(sao, 'P');
+ password = cmd_arg_val(sao, 'w');
+
+ init_srv_share_info2(&si->info_2, CONST_STR(netname), type, CONST_STR(remark),
+ perms, max_uses, num_uses,
+ CONST_STR(path), CONST_STR(password));
+
+ init_srv_share_info2_str(&si->info_2_str, CONST_STR(netname), CONST_STR(remark),
+ CONST_STR(path), CONST_STR(password));
+
+ return True;
+}
+
+static BOOL parse_share_share_info_from_args_501(SRV_SHARE_INFO_501 *si, const char *netname,
+ TALLOC_CTX *mem_ctx,
+ cmd_arg_option *sao)
+{
+ int type;
+ const char *remark;
+ uint32 flags = 0;
+
+ if(!parse_share_get_share_type_from_str(cmd_arg_val(sao, 't'), &type))
+ return False;
+
+ remark = cmd_arg_val(sao, 'r');
+
+ if(!parse_share_get_share_flags_from_str(cmd_arg_val(sao, 'f'), &flags))
+ return False;
+
+ init_srv_share_info501(&si->info_501, CONST_STR(netname), type, CONST_STR(remark), flags);
+ init_srv_share_info501_str(&si->info_501_str, CONST_STR(netname), CONST_STR(remark));
+
+ return True;
+}
+
+static BOOL parse_share_share_info_from_args_502(SRV_SHARE_INFO_502 *si, const char *netname,
+ TALLOC_CTX *mem_ctx,
+ cmd_arg_option *sao)
+{
+ int type;
+ const char *remark;
+ int perms;
+ int max_uses;
+ int num_uses;
+ const char *path;
+ const char *password;
+ const char *sec_desc_str;
+ SEC_DESC *sec_desc = NULL;
+
+ if(!parse_share_get_share_type_from_str(cmd_arg_val(sao, 't'), &type))
+ return False;
+
+ remark = cmd_arg_val(sao, 'r');
+
+ if(!parse_share_get_share_perms_from_str(cmd_arg_val(sao, 'p'), &perms))
+ return False;
+
+ max_uses = atoi(cmd_arg_val(sao, 'u'));
+
+ num_uses = 0;
+
+ path = cmd_arg_val(sao, 'P');
+ password = cmd_arg_val(sao, 'w');
+ sec_desc_str = cmd_arg_val(sao, 's');
+
+ if(sec_desc_str)
+ if(!smbcacl_lib_sec_desc_parse(mem_ctx, sec_desc_str, &sec_desc))
+ return False;
+
+ {
+ int sd_size = sec_desc?sec_desc_size(sec_desc):0;
+
+ init_srv_share_info502(&si->info_502,
+ CONST_STR(netname), type, CONST_STR(remark),
+ perms, max_uses, num_uses,
+ CONST_STR(path), CONST_STR(password),
+ sec_desc, sd_size);
+
+ init_srv_share_info502_str(&si->info_502_str,
+ CONST_STR(netname), CONST_STR(remark),
+ CONST_STR(path), CONST_STR(password),
+ sec_desc, sd_size);
+ }
+
+ return True;
+}
+
+static BOOL parse_share_share_info_from_args_1004(SRV_SHARE_INFO_1004 *si, const char *netname,
+ TALLOC_CTX *mem_ctx,
+ cmd_arg_option *sao)
+{
+
+ const char *remark;
+
+ remark = cmd_arg_val(sao, 'r');
+
+ init_srv_share_info1004(&si->info_1004, CONST_STR(remark));
+ init_srv_share_info1004_str(&si->info_1004_str, CONST_STR(remark));
+
+ return True;
+}
+
+static BOOL parse_share_share_info_from_args_1005(SRV_SHARE_INFO_1005 *si, const char *netname,
+ TALLOC_CTX *mem_ctx,
+ cmd_arg_option *sao)
+{
+ uint32 flags;
+
+ if(!parse_share_get_share_flags_from_str(cmd_arg_val(sao, 'f'), &flags))
+ return False;
+
+ si->dfs_root_flag = flags;
+
+ return True;
+}
+
+static BOOL parse_share_share_info_from_args_1006(SRV_SHARE_INFO_1006 *si, const char *netname,
+ TALLOC_CTX *mem_ctx,
+ cmd_arg_option *sao)
+{
+ si->max_uses = atoi(cmd_arg_val(sao, 'u'));
+
+ return True;
+}
+
+static BOOL parse_share_share_info_from_args_1007(SRV_SHARE_INFO_1007 *si, const char *netname,
+ TALLOC_CTX *mem_ctx,
+ cmd_arg_option *sao)
+{
+ uint32 flags;
+ const char *alternate_directory_name;
+
+ if(!parse_share_get_share_flags_from_str(cmd_arg_val(sao, 'f'), &flags))
+ return False;
+
+ alternate_directory_name = cmd_arg_val(sao, 'a');
+
+ init_srv_share_info1007(&si->info_1007, flags, alternate_directory_name);
+ init_srv_share_info1007_str(&si->info_1007_str, alternate_directory_name);
+
+ return True;
+}
+
+static BOOL parse_share_share_info_from_args_1501(SRV_SHARE_INFO_1501 *si, const char *netname,
+ TALLOC_CTX *mem_ctx,
+ cmd_arg_option *sao)
+{
+ const char *sec_desc_str;
+ SEC_DESC *sec_desc = NULL;
+ int sd_size;
+
+ sec_desc_str = cmd_arg_val(sao, 's');
+
+ if(sec_desc_str)
+ if(!smbcacl_lib_sec_desc_parse(mem_ctx, sec_desc_str, &sec_desc))
+ return False;
+
+ sd_size = sec_desc?sec_desc_size(sec_desc):0;
+
+ si->sdb = make_sec_desc_buf(mem_ctx, sd_size, sec_desc);
+
+ return True;
+}
+
+static BOOL parse_share_share_info_from_args(SRV_SHARE_INFO *si, char *netname,
+ TALLOC_CTX *mem_ctx,
+ int argc, char *argv[])
+{
+ cmd_arg_option *sao = NULL;
+
+ if(argc < 2)
+ return False;
+
+ si->switch_value = atoi(argv[1]);
+
+ if(!cmd_arg_process(si->switch_value, parse_share_args, argc-2, argv+2, &sao)) {
+
+ if(sao)
+ cmd_arg_show_usage_for_info_level(si->switch_value, sao);
+
+ return False;
+ }
+
+ si->ptr_share_ctr = 1;
+
+ fstrcpy(netname, argv[0]);
+
+ switch(si->switch_value) {
+
+ case 0:
+ return parse_share_share_info_from_args_0( &si->share.info0, netname, mem_ctx, sao);
+ break;
+ case 1:
+ return parse_share_share_info_from_args_1( &si->share.info1, netname, mem_ctx, sao);
+ break;
+ case 2:
+ return parse_share_share_info_from_args_2( &si->share.info2, netname, mem_ctx, sao);
+ break;
+ case 501:
+ return parse_share_share_info_from_args_501( &si->share.info501, netname, mem_ctx, sao);
+ break;
+ case 502:
+ return parse_share_share_info_from_args_502( &si->share.info502, netname, mem_ctx, sao);
+ break;
+ case 1004:
+ return parse_share_share_info_from_args_1004(&si->share.info1004, netname, mem_ctx, sao);
+ break;
+ case 1005:
+ return parse_share_share_info_from_args_1005(&si->share.info1005, netname, mem_ctx, sao);
+ break;
+ case 1006:
+ return parse_share_share_info_from_args_1006(&si->share.info1006, netname, mem_ctx, sao);
+ break;
+ case 1007:
+ return parse_share_share_info_from_args_1007(&si->share.info1007, netname, mem_ctx, sao);
+ break;
+ case 1501:
+ return parse_share_share_info_from_args_1501(&si->share.info1501, netname, mem_ctx, sao);
+ break;
+ default:
+ }
+
+ return False;
+}
+
+void display_share_info_0(SRV_SHARE_INFO_0 *info0)
+{
+
+ fstring netname = "";
+
+ if(info0->info_0.ptr_netname) {
+ unistr2_to_ascii(netname, &info0->info_0_str.uni_netname, sizeof(netname)-1);
+ }
+
+ printf("level 0\tshare %s:\n",
+ netname);
+}
+
+void display_share_info_1(SRV_SHARE_INFO_1 *info1)
+{
+ fstring netname = "";
+ fstring comment = "";
+ fstring typestr = "";
+
+ if(info1->info_1.ptr_netname) {
+ unistr2_to_ascii(netname, &info1->info_1_str.uni_netname, sizeof(netname)-1);
+ }
+
+ parse_share_get_share_type_str(info1->info_1.type, typestr, sizeof(typestr));
+
+ if(info1->info_1.ptr_remark) {
+ unistr2_to_ascii(comment, &info1->info_1_str.uni_remark, sizeof(comment)-1);
+ }
+
+ printf("level 1\tshare %s:\n"
+ "\ttype\t:%s(0x%x)\n"
+ "\tcomment\t:%s.\n",
+ netname,
+ typestr, info1->info_1.type,
+ comment);
+}
+
+void display_share_info_2(SRV_SHARE_INFO_2 *info2)
+{
+ fstring netname = "";
+ fstring comment = "";
+ fstring path = "";
+ fstring passwd = "";
+ fstring typestr = "";
+ fstring permsstr = "";
+
+ int max_uses;
+ int num_uses;
+
+ if(info2->info_2.ptr_netname) {
+ unistr2_to_ascii(netname, &info2->info_2_str.uni_netname, sizeof(netname)-1);
+ }
+
+ parse_share_get_share_type_str(info2->info_2.type, typestr, sizeof(typestr));
+
+ if(info2->info_2.ptr_remark) {
+ unistr2_to_ascii(comment, &info2->info_2_str.uni_remark, sizeof(comment)-1);
+ }
+
+ parse_share_get_share_perms_str(info2->info_2.perms, permsstr, sizeof(permsstr));
+
+ max_uses = info2->info_2.max_uses;
+ num_uses = info2->info_2.num_uses;
+
+ if(info2->info_2.ptr_path) {
+ unistr2_to_ascii(path, &info2->info_2_str.uni_path, sizeof(path)-1);
+ }
+
+ if(info2->info_2.ptr_passwd) {
+ unistr2_to_ascii(passwd, &info2->info_2_str.uni_passwd, sizeof(passwd)-1);
+ }
+
+ printf("level 2\tshare %s:\n"
+ "\ttype\t:%s(0x%x)\n"
+ "\tcomment\t:%s\n"
+ "\tperms\t:%s(0x%x)\n"
+ "\tmax_uses\t:%d\n"
+ "\tnum_uses\t:%d\n"
+ "\tpath\t:%s\n"
+ "\tpasswd\t:%s.\n",
+ netname,
+ typestr, info2->info_2.type,
+ comment,
+ permsstr, info2->info_2.perms,
+ max_uses,
+ num_uses,
+ path,
+ passwd);
+
+}
+
+void display_share_info_501(SRV_SHARE_INFO_501 *info501)
+{
+ fstring netname = "";
+ fstring comment = "";
+ fstring typestr = "";
+ fstring flagsstr = "";
+
+ if(info501->info_501.ptr_netname) {
+
+ unistr2_to_ascii(netname, &info501->info_501_str.uni_netname, sizeof(netname)-1);
+ }
+
+ parse_share_get_share_type_str(info501->info_501.type, typestr, sizeof(typestr));
+
+ if(info501->info_501.ptr_remark) {
+
+ unistr2_to_ascii(comment, &info501->info_501_str.uni_remark, sizeof(comment)-1);
+ }
+
+ printf("level 501\tshare %s:\n"
+ "\ttype\t:%s(0x%x)\n"
+ "\tcomment\t:%s\n"
+ "\tflags\t:%s(0x%x).\n",
+ netname,
+ typestr, info501->info_501.type,
+ comment,
+ flagsstr, info501->info_501.flags);
+}
+
+void display_share_info_502(SRV_SHARE_INFO_502 *info502)
+{
+ fstring netname = "";
+ fstring comment = "";
+ fstring path = "";
+ fstring passwd = "";
+ fstring typestr = "";
+ fstring permsstr = "";
+ pstring sdstr = "";
+
+ int sd_size = -1;
+
+ int max_uses;
+ int num_uses;
+
+ if(info502->info_502.ptr_netname) {
+ unistr2_to_ascii(netname, &info502->info_502_str.uni_netname, sizeof(netname)-1);
+ }
+
+ parse_share_get_share_type_str(info502->info_502.type, typestr, sizeof(typestr));
+
+ if(info502->info_502.ptr_remark) {
+ unistr2_to_ascii(comment, &info502->info_502_str.uni_remark, sizeof(comment)-1);
+ }
+
+ parse_share_get_share_perms_str(info502->info_502.perms, permsstr, sizeof(permsstr));
+
+ max_uses = info502->info_502.max_uses;
+ num_uses = info502->info_502.num_uses;
+
+ if(info502->info_502.ptr_path) {
+ unistr2_to_ascii(path, &info502->info_502_str.uni_path, sizeof(path)-1);
+ }
+
+ if(info502->info_502.ptr_passwd) {
+ unistr2_to_ascii(passwd, &info502->info_502_str.uni_passwd, sizeof(passwd)-1);
+ }
+
+ if(info502->info_502.ptr_sd) {
+ sd_size = info502->info_502.sd_size;
+
+ if(smbcacl_lib_sec_desc_str(info502->info_502_str.sd, sdstr, sizeof(sdstr)) >= sizeof(sdstr)) {
+
+ strncpy(&sdstr[sizeof(sdstr)-5-1], "...\n", 5);
+ }
+ }
+
+ printf("level 502\tshare %s:\n"
+ "\ttype\t:%s(0x%x)\n"
+ "\tcomment\t:%s\n"
+ "\tperms\t:%s(0x%x)\n"
+ "\tmax_uses\t:%d\n"
+ "\tnum_uses\t:%d\n"
+ "\tpath\t:%s\n"
+ "\tpasswd\t:%s\n"
+ "\tsd_size\t:%d\n"
+ "%s\n",
+ netname,
+ typestr, info502->info_502.type,
+ comment,
+ permsstr, info502->info_502.perms,
+ max_uses,
+ num_uses,
+ path,
+ passwd,
+ sd_size,
+ sdstr);
+}
+
+void display_share_info_1004(SRV_SHARE_INFO_1004 *info1004)
+{
+ fstring comment = "";
+
+ if(info1004->info_1004.ptr_remark) {
+ unistr2_to_ascii(comment, &info1004->info_1004_str.uni_remark, sizeof(comment)-1);
+ }
+
+ printf("level 1004:\n"
+ "\tcomment\t:%s.\n",
+ comment);
+}
+
+void display_share_info_1005(SRV_SHARE_INFO_1005 *info1005)
+{
+ fstring flagsstr = "";
+ uint32 flags = info1005->dfs_root_flag;
+
+ parse_share_get_share_flags_str(flags, flagsstr, sizeof(flagsstr));
+
+ printf("level 1005:\n"
+ "\tflags\t:%s(0x%x).\n",
+ flagsstr, flags);
+}
+
+void display_share_info_1006(SRV_SHARE_INFO_1006 *info1006)
+{
+ int max_uses = info1006->max_uses;
+
+ printf("level 1006:\n"
+ "\tmax uses\t:%d.\n",
+ max_uses);
+}
+
+void display_share_info_1007(SRV_SHARE_INFO_1007 *info1007)
+{
+ fstring alternate_directory_name = "";
+ fstring flagsstr = "";
+ uint32 flags = info1007->info_1007.flags;
+
+ if(info1007->info_1007.ptr_AlternateDirectoryName) {
+
+ unistr2_to_ascii(alternate_directory_name,
+ &info1007->info_1007_str.uni_AlternateDirectoryName,
+ sizeof(alternate_directory_name)-1);
+ }
+
+ parse_share_get_share_flags_str(flags, flagsstr, sizeof(flagsstr));
+
+ printf("level 1007:\n"
+ "\tflags\t:%s(0x%x)\n"
+ "\talt dir\t:%s.\n",
+ flagsstr, flags,
+ alternate_directory_name);
+}
+
+void display_share_info_1501(SRV_SHARE_INFO_1501 *info1501)
+{
+ pstring sdstr = "";
+
+ int sd_size = -1;
+
+ if(info1501->sdb->ptr) {
+ sd_size = info1501->sdb->len;
+
+ if(smbcacl_lib_sec_desc_str(info1501->sdb->sec, sdstr, sizeof(sdstr)) >= sizeof(sdstr)) {
+
+ strncpy(&sdstr[sizeof(sdstr)-5-1], "...\n", 5);
+ }
+ }
+
+ printf("level 1501:\n"
+ "\tsd size\t:%d\n"
+ "%s.\n",
+ sd_size,
+ sdstr);
+}
+
+static NTSTATUS cmd_srvsvc_share_enum_sticky(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
+{
+ int i;
+ int er;
+ uint32 preferred_len = 0xffffffff;
+ ENUM_HND enum_hnd;
+ uint32 total_entries;
+ SRV_SHARE_INFO_CTR share_info_ctr;
+ uint32 info_level = 502;
+
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+ if (argc > 2) {
+ printf("Usage: %s [info_level 0,1,2,502]\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ if(argc == 2)
+ info_level = atoi(argv[1]);
+
+ /* this call includes the enum handle even when zero */
+
+ enum_hnd.ptr_hnd = 1;
+ enum_hnd.handle = 0;
+
+ ZERO_STRUCT(share_info_ctr);
+ total_entries = 0;
+
+ share_info_ctr.info_level = info_level;
+
+ er = 0;
+
+ do {
+
+ result = cli_srvsvc_net_share_enum_sticky(cli,
+ mem_ctx,
+ cli->desthost,
+ preferred_len,
+ &enum_hnd,
+ &total_entries,
+ &share_info_ctr
+ );
+
+
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+
+ switch(share_info_ctr.switch_value) {
+ case 0:
+ for(i = 0; i < share_info_ctr.num_entries; i++) {
+ display_share_info_0(&share_info_ctr.share.info0[i]);
+ }
+ break;
+ case 1:
+ for(i = 0; i < share_info_ctr.num_entries; i++) {
+ display_share_info_1(&share_info_ctr.share.info1[i]);
+ }
+ break;
+ case 2:
+ for(i = 0; i < share_info_ctr.num_entries; i++) {
+ display_share_info_2(&share_info_ctr.share.info2[i]);
+ }
+ break;
+ case 501:
+ for(i = 0; i < share_info_ctr.num_entries; i++) {
+ display_share_info_501(&share_info_ctr.share.info501[i]);
+ }
+ break;
+ case 502:
+ for(i = 0; i < share_info_ctr.num_entries; i++) {
+ display_share_info_502(&share_info_ctr.share.info502[i]);
+ }
+ break;
+ case 1004:
+ for(i = 0; i < share_info_ctr.num_entries; i++) {
+ display_share_info_1004(&share_info_ctr.share.info1004[i]);
+ }
+ break;
+ case 1005:
+ for(i = 0; i < share_info_ctr.num_entries; i++) {
+ display_share_info_1005(&share_info_ctr.share.info1005[i]);
+ }
+ break;
+ case 1006:
+ for(i = 0; i < share_info_ctr.num_entries; i++) {
+ display_share_info_1006(&share_info_ctr.share.info1006[i]);
+ }
+ break;
+ case 1007:
+
+ for(i = 0; i < share_info_ctr.num_entries; i++) {
+ display_share_info_1007(&share_info_ctr.share.info1007[i]);
+ }
+ break;
+ case 1501:
+
+ for(i = 0; i < share_info_ctr.num_entries; i++) {
+ display_share_info_1501(&share_info_ctr.share.info1501[i]);
+ }
+ break;
+ default:
+ printf("unknown share info type %d.\n", share_info_ctr.switch_value);
+ }
+
+ er += share_info_ctr.num_entries;
+
+ } while(er < total_entries);
+
+ done:
+ return result;
+}
+
+static NTSTATUS cmd_srvsvc_share_enum(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
+{
+ int i;
+ int er;
+ uint32 preferred_len = 0xffffffff;
+ ENUM_HND enum_hnd;
+ uint32 total_entries;
+ SRV_SHARE_INFO_CTR share_info_ctr;
+ uint32 info_level = 502;
+
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+ if (argc > 2) {
+ printf("Usage: %s [info_level 0,1,2,501,502]\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ if(argc == 2)
+ info_level = atoi(argv[1]);
+
+ /* this call includes the enum handle even when zero */
+
+ enum_hnd.ptr_hnd = 1;
+ enum_hnd.handle = 0;
+
+ ZERO_STRUCT(share_info_ctr);
+ total_entries = 0;
+
+ share_info_ctr.info_level = info_level;
+
+ er = 0;
+
+ do {
+
+ result = cli_srvsvc_net_share_enum(cli,
+ mem_ctx,
+ cli->desthost,
+ preferred_len,
+ &enum_hnd,
+ &total_entries,
+ &share_info_ctr
+ );
+
+
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+
+ switch(share_info_ctr.switch_value) {
+ case 0:
+ for(i = 0; i < share_info_ctr.num_entries; i++) {
+ display_share_info_0(&share_info_ctr.share.info0[i]);
+ }
+ break;
+ case 1:
+ for(i = 0; i < share_info_ctr.num_entries; i++) {
+ display_share_info_1(&share_info_ctr.share.info1[i]);
+ }
+ break;
+ case 2:
+ for(i = 0; i < share_info_ctr.num_entries; i++) {
+ display_share_info_2(&share_info_ctr.share.info2[i]);
+ }
+ break;
+ case 501:
+ for(i = 0; i < share_info_ctr.num_entries; i++) {
+ display_share_info_501(&share_info_ctr.share.info501[i]);
+ }
+ break;
+ case 502:
+ for(i = 0; i < share_info_ctr.num_entries; i++) {
+ display_share_info_502(&share_info_ctr.share.info502[i]);
+ }
+ break;
+ case 1004:
+ for(i = 0; i < share_info_ctr.num_entries; i++) {
+ display_share_info_1004(&share_info_ctr.share.info1004[i]);
+ }
+ break;
+ case 1005:
+ for(i = 0; i < share_info_ctr.num_entries; i++) {
+ display_share_info_1005(&share_info_ctr.share.info1005[i]);
+ }
+ break;
+ case 1006:
+ for(i = 0; i < share_info_ctr.num_entries; i++) {
+ display_share_info_1006(&share_info_ctr.share.info1006[i]);
+ }
+ break;
+ case 1007:
+
+ for(i = 0; i < share_info_ctr.num_entries; i++) {
+ display_share_info_1007(&share_info_ctr.share.info1007[i]);
+ }
+ break;
+ case 1501:
+
+ for(i = 0; i < share_info_ctr.num_entries; i++) {
+ display_share_info_1501(&share_info_ctr.share.info1501[i]);
+ }
+ break;
+ default:
+ printf("unknown share info type %d.\n", share_info_ctr.switch_value);
+ }
+
+ er += share_info_ctr.num_entries;
+
+ } while(er < total_entries);
+
+ done:
+ return result;
+}
+
+static NTSTATUS cmd_srvsvc_share_get_info(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
+{
+ fstring netname;
+ SRV_SHARE_INFO share_info;
+
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+ if (argc > 3 || argc < 2) {
+ printf("Usage: %s [netname] [info_level 0,1,2,501,502,1005]\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ ZERO_STRUCT(share_info);
+
+ share_info.switch_value = 502;
+
+ fstrcpy(netname, argv[1]);
+
+ if(argc == 3)
+ share_info.switch_value = atoi(argv[2]);
+
+ result = cli_srvsvc_net_share_get_info(cli,
+ mem_ctx,
+ cli->desthost,
+ netname,
+ &share_info
+ );
+
+
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+
+ switch(share_info.switch_value) {
+ case 0:
+ display_share_info_0(&share_info.share.info0);
+ break;
+ case 1:
+ display_share_info_1(&share_info.share.info1);
+ break;
+ case 2:
+ display_share_info_2(&share_info.share.info2);
+ break;
+ case 501:
+ display_share_info_501(&share_info.share.info501);
+ break;
+ case 502:
+ display_share_info_502(&share_info.share.info502);
+ break;
+ case 1004:
+ display_share_info_1004(&share_info.share.info1004);
+ break;
+ case 1005:
+ display_share_info_1005(&share_info.share.info1005);
+ break;
+ case 1006:
+ display_share_info_1006(&share_info.share.info1006);
+ break;
+ case 1007:
+ display_share_info_1007(&share_info.share.info1007);
+ break;
+ case 1501:
+ display_share_info_1501(&share_info.share.info1501);
+ break;
+ default:
+ printf("unknown share info type %d.\n", share_info.switch_value);
+ }
+
+ done:
+ return result;
+}
+
+static NTSTATUS cmd_srvsvc_share_set_info(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
+{
+ fstring netname;
+
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+ SRV_SHARE_INFO share_info;
+
+ uint32 parm_error = 0;
+
+ ZERO_STRUCT(share_info);
+
+ if(!parse_share_share_info_from_args(&share_info, netname, mem_ctx, argc-1, argv+1)) {
+
+ printf("Usage: %s [netname] [info_level 1,2,502,1004,1006,1501]\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ result = cli_srvsvc_net_share_set_info(cli,
+ mem_ctx,
+ cli->desthost,
+ netname,
+ &share_info,
+ &parm_error
+ );
+
+
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+
+ done:
+ return result;
+}
+
+static NTSTATUS cmd_srvsvc_share_add(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
+{
+ fstring netname;
+ SRV_SHARE_INFO share_info;
+ uint32 parm_error = 0;
+
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+ ZERO_STRUCT(share_info);
+
+ if(!parse_share_share_info_from_args(&share_info, netname, mem_ctx, argc-1, argv+1)) {
+
+ printf("Usage: %s [netname] [info_level 2,502] [share info...]\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ result = cli_srvsvc_net_share_add(cli,
+ mem_ctx,
+ cli->desthost,
+ &share_info,
+ &parm_error
+ );
+
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+
+ done:
+ return result;
+}
+
+static NTSTATUS cmd_srvsvc_share_del(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
+{
+ fstring netname;
+ SRV_SHARE_INFO share_info;
+
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+ if (argc != 2) {
+ printf("Usage: %s [netname]\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ fstrcpy(netname, argv[1]);
+
+ result = cli_srvsvc_net_share_del(cli,
+ mem_ctx,
+ cli->desthost,
+ netname
+ );
+
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+
+ done:
+ return result;
+}
+
+static NTSTATUS cmd_srvsvc_share_del_sticky(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, char **argv)
+{
+ fstring netname;
+ SRV_SHARE_INFO share_info;
+
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+ if (argc != 2) {
+ printf("Usage: %s [netname]\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ fstrcpy(netname, argv[1]);
+
+ result = cli_srvsvc_net_share_del_sticky(cli,
+ mem_ctx,
+ cli->desthost,
+ netname
+ );
+
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+
+ /* do something */
+
+ done:
+ return result;
+}
+
/* List of commands exported by this module */
struct cmd_set srvsvc_commands[] = {
{ "SRVSVC" },
- { "srvinfo", cmd_srvsvc_srv_query_info, PIPE_SRVSVC, "Server query info", "" },
+ { "srvinfo", cmd_srvsvc_srv_query_info, PIPE_SRVSVC, "Server query info", "" },
+ { "srvdskenum", cmd_srvsvc_srv_disk_enum, PIPE_SRVSVC, "Server disk enum", "" },
+ { "namevalidate",cmd_srvsvc_name_validate, PIPE_SRVSVC, "Name validate", "" },
+ { "shareenum", cmd_srvsvc_share_enum, PIPE_SRVSVC, "Enumerate shares", "" },
+ { "shareenums", cmd_srvsvc_share_enum_sticky,PIPE_SRVSVC, "Enumerate shares (sticky)","" },
+ { "sharegetinfo",cmd_srvsvc_share_get_info, PIPE_SRVSVC, "Get share info", "" },
+ { "sharesetinfo",cmd_srvsvc_share_set_info, PIPE_SRVSVC, "Set share info", "" },
+ { "shareadd", cmd_srvsvc_share_add, PIPE_SRVSVC, "Add share", "" },
+ { "sharedel", cmd_srvsvc_share_del, PIPE_SRVSVC, "Delete share", "" },
+ { "sharedels", cmd_srvsvc_share_del_sticky, PIPE_SRVSVC, "Delete share (sticky)", "" },
{ NULL }
};
Index: rpcclient/rpcclient.c
===================================================================
RCS file: /cvsroot/samba/source/rpcclient/rpcclient.c,v
retrieving revision 1.172
diff -u -r1.172 rpcclient.c
--- rpcclient/rpcclient.c 6 Jan 2002 03:24:51 -0000 1.172
+++ rpcclient/rpcclient.c 22 Jan 2002 01:22:55 -0000
@@ -386,6 +386,169 @@
DLIST_ADD(cmd_list, entry);
}
+static BOOL parse_command_line(const char *cmd, int *argc, char ***argv) {
+
+ BOOL ret = True;
+ BOOL in,esc,q;
+
+ int c;
+ const char *p;
+
+ int argl = 0;
+ char *arg = NULL, *narg = NULL, *s = NULL;
+
+#undef RESIZEARG
+#define RESIZEARG ((argl = (argl == 0)?sizeof(pstring):argl*2), \
+ (s -= (uint32)arg), \
+ (arg = (narg = realloc(arg, argl))?narg:arg), \
+ (s += (uint32)arg), \
+ narg)
+#undef NEXTARGCHAR
+#define NEXTARGCHAR(C) (((s - arg == argl)?RESIZEARG:arg)?(*s++ = (C), True):False)
+
+ *argc = 0;
+ *argv = NULL;
+
+ while(True) {
+
+ in = esc = q = False;
+
+ p = cmd;
+
+ while((c = *p++)) {
+
+ if(in && !esc && (c == '"' || (isspace(c) && !q))) {
+
+ /* terminate token on unquoted space or quote */
+
+ if(!(ret = NEXTARGCHAR(0)))
+ break;
+
+ if(*argv)
+ (*argv)[*argc] = strdup(arg);
+
+ (*argc)++;
+
+ *arg = 0;
+
+ in = False;
+
+ if(q && c == '"') {/* don't store the closing quote of a quoted token */
+ q = False;
+ continue;
+ }
+ }
+
+ if(!in) {
+
+ if(isspace(c))
+ continue;
+
+ /* start a new token */
+
+ in = True;
+
+ s = arg;
+
+ if(c == '"') {
+
+ /* discard the initial quote of a quoted token */
+
+ q = True;
+ continue;
+ }
+ }
+
+ if(!esc) {
+
+ /* check for the escape character */
+
+ if(c == '\\') {
+ esc = True;
+ continue;
+ }
+
+ } else {
+
+ /* allow a set of escape characters */
+
+ switch(c) {
+
+ case '\\':
+ c = '\\';
+ break;
+ case '"':
+ c = '"';
+ break;
+ case 'n':
+ c = '\n';
+ break;
+ case 'r':
+ c = '\r';
+ case 't':
+ c = '\t';
+ break;
+ case 's':
+ c = ' ';
+ break;
+ default:
+ *s++ = '\\';
+ }
+
+ esc = False;
+ }
+
+ if(!(ret = NEXTARGCHAR(c)))
+ break;
+ }
+
+ if(!ret)
+ break;
+
+ /* add a trailing escape character ? */
+
+ if(esc && !(ret = NEXTARGCHAR('\\')))
+ break;
+
+ if(!(ret = NEXTARGCHAR(0)))
+ break;
+
+ if(*arg) { /* this will lose a trailing quote */
+
+ /* a token was terminated by eol */
+
+ if(*argv)
+ (*argv)[*argc] = strdup(arg);
+
+ (*argc)++;
+
+ *arg = 0;
+ }
+
+ if(*argv)
+ break;
+
+ if(*argc)
+ *argv = (char **)malloc(*argc * sizeof(**argv));
+
+ *argc = 0;
+ }
+
+ SAFE_FREE(arg);
+
+ if(!ret && *argv) {
+
+ while((*argc)--)
+ SAFE_FREE((*argv)[*argc]);
+
+ SAFE_FREE(*argv);
+
+ *argv = NULL;
+ }
+
+ return ret;
+}
+
static NTSTATUS do_cmd(struct cli_state *cli, struct cmd_set *cmd_entry,
char *cmd)
{
@@ -394,9 +557,9 @@
pstring buf;
int argc = 0, i;
+#if 0
/* Count number of arguments first time through the loop then
allocate memory and strdup them. */
-
again:
while(next_token(&p, buf, " ", sizeof(buf))) {
if (argv) {
@@ -424,7 +587,28 @@
goto again;
}
+#else
+
+ /* hopefully using this won't break any existing code */
+
+ if(!parse_command_line(cmd, &argc, &argv)) {
+
+ goto done;
+ }
+
+ {
+ int i;
+ DEBUG(4, ("command <%s> => (%d) ", cmd, argc));
+ for(i = 0; i < argc; i++) {
+
+ DEBUG(4, ("<%s>", argv[i]));
+ }
+
+ DEBUG(4, (".\n"));
+ }
+
+#endif
/* Call the function */
if (cmd_entry->fn) {
@@ -467,8 +651,8 @@
/* Cleanup */
if (argv) {
- for (i = 0; i < argc; i++)
- SAFE_FREE(argv[i]);
+ while(argc--)
+ SAFE_FREE(argv[argc]);
SAFE_FREE(argv);
}
@@ -543,6 +727,8 @@
printf("\t-s configfile specify an alternative config file\n");
printf("\t-U username set the network username\n");
printf("\t-W domain set the domain name for user account\n");
+ printf("\t-D DC set a DC for non-local lsa lookups\n");
+ printf("\t-n set for numeric acl representation\n");
printf("\n");
}
@@ -572,7 +758,7 @@
DEBUGLEVEL = 1;
- while ((opt = getopt(argc, argv, "A:s:Nd:U:W:c:l:h")) != EOF) {
+ while ((opt = getopt(argc, argv, "A:s:Nd:U:W:c:l:D:nh")) != EOF) {
switch (opt) {
case 'A':
/* only get the username, password, and domain from the file */
@@ -618,6 +804,13 @@
case 'W':
pstrcpy(domain, optarg);
break;
+
+ case 'D':
+ smbcacl_lib_DC_set(optarg);
+ break;
+ case 'n':
+ smbcacl_lib_numeric_set(1);
+ break;
case 'h':
default:
@@ -639,6 +832,10 @@
argv[0] += 2;
pstrcpy(server, argv[0]);
+
+ /* tell acl lib where to go for local name translations */
+
+ smbcacl_lib_server_set(server);
/* the following functions are part of the Samba debugging
facilities. See lib/debug.c */
More information about the samba-technical
mailing list