partial smbclient / smbcalcs merge
Roger Standridge
roger at digitalfountain.com
Tue Jan 29 22:50:54 GMT 2002
My bad. I found the patch submission page on the samba website:
http://samba.org/samba-patches/. I sending this quick followup to
hopefully avoid several similar responses to the list.
-roger
Roger Standridge wrote:
> My first post, I am going to write it as if I have targeted the right
> place, sorry if I haven't... where should it go?
>
> Attached is a patch against the 2.2.2 release that adds a 'showacl'
> (show access control list) command to smbclient. Essentially I copied
> part of util/smbcalcs.c into client/client.c and modified the display
> format.
>
> <example interaction>
>
> smb: \> help showacl
> HELP showacl:
> <remote name> [-n | --numeric | -x | --explicit]
> show access control list for remote file
>
> smb: \> showacl 1.txt
> REVISION:1
> OWNER:BUILTIN\Administrators
> GROUP:DIGITALFOUNTAIN\Developers
> ACL:DIGITALFOUNTAIN\joeuser:ALLOWED/3/Modify
> ACL:Everyone:ALLOWED/16/Full Control
> smb: \> showacl 1.txt -n
> REVISION:1
> OWNER:S-1-5-32-544
> GROUP:S-1-5-21-1533814122-1651835022-184960113-1005
> ACL:S-1-5-21-1533814122-1651835022-184960113-1087:0/3/0x001301bf
> ACL:S-1-1-0:0/16/0x001f01ff
> smb: \> showacl 1.txt --explicit
> REVISION:1
> OWNER:BUILTIN\Administrators
> GROUP:DIGITALFOUNTAIN\Developers
> ACL:DIGITALFOUNTAIN\joeuser:ALLOWED/3/
> FILE_READ_DATA
> FILE_WRITE_DATA
> FILE_APPEND_DATA
> FILE_READ_EA
> FILE_WRITE_EA
> FILE_EXECUTE
> FILE_READ_ATTRIBUTES
> FILE_WRITE_ATTRIBUTES
> DELETE
> READ_CONTROL
> SYNCHRONIZE
> ACL:Everyone:ALLOWED/16/
> FILE_READ_DATA
> FILE_WRITE_DATA
> FILE_APPEND_DATA
> FILE_READ_EA
> FILE_WRITE_EA
> FILE_EXECUTE
> FILE_DELETE_CHILD
> FILE_READ_ATTRIBUTES
> FILE_WRITE_ATTRIBUTES
> DELETE
> READ_CONTROL
> WRITE_DAC
> WRITE_OWNER
> SYNCHRONIZE
>
> </example interaction>
>
> Notes:
>
> o Permission summary strings mimic those from W2K permission control
> dialog (Read / Write / Read & Execute / Modify / Full Control).
> I found the MS cacls program too broken to bother imitating.
>
> o -n or --numeric option displays in the numeric format of the
> original smbcacls program
>
> o -x or --explicit option displays the string equivelant of
> each permission, one per line below the ace (much like the
> MS cacls program.
>
> o tried to mimic the code style of the original, sorry if I missed
>
> o only compiled on Debian GNU/Linux i386, Potato and Sid
> (But there is very little new code here).
>
> o usage extends multiple lines, sorry, not consistent
>
> o accepts relative and absolute paths of filenames as well
> as '.' and '..' (other commands do not)
>
> o tested only against W2K
>
> o Makefile.in patch needlessly changes style of CLIENT_OBJ and
> SMBCACLS_OBJ variables.
>
> o options follow filename... seemed the right thing to do,
> but I don't see any other commands that take options (similar
> things seem to be done by placing smbclient in recursive mode,
> etc.).
>
> o Summary permission strings work both for ALLOWED and DENIED
> access control lists, but I discovered that SYNCHRONIZE was
> not in the bit-mask for DENIED ACEs..., so I blanked out
> checking for it... blah, blah... needs investigation.
>
>
> -Roger Standridge
> <roger @ digitalfountain.com>
>
>
> ------------------------------------------------------------------------
>
> diff -rc samba-2.2.2-10.orig/source/Makefile.in samba-2.2.2-10-smbclient-showalc-patched/source/Makefile.in
> *** samba-2.2.2-10.orig/source/Makefile.in Wed Jan 23 11:33:19 2002
> --- samba-2.2.2-10-smbclient-showalc-patched/source/Makefile.in Tue Jan 29 10:37:25 2002
> ***************
> *** 283,290 ****
> LIBSMBCLIENT_OBJ = libsmb/libsmbclient.o $(LIB_OBJ) $(LIBSMB_OBJ) $(PARAM_OBJ) $(UBIQX_OBJ)
>
> CLIENT_OBJ = client/client.o client/clitar.o \
> ! $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
> ! $(READLINE_OBJ)
>
> CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
>
> --- 283,309 ----
> LIBSMBCLIENT_OBJ = libsmb/libsmbclient.o $(LIB_OBJ) $(LIBSMB_OBJ) $(PARAM_OBJ) $(UBIQX_OBJ)
>
> CLIENT_OBJ = client/client.o client/clitar.o \
> ! $(PARAM_OBJ) \
> ! $(LIBSMB_OBJ) \
> ! $(UBIQX_OBJ) \
> ! $(LIB_OBJ) \
> ! $(LIBMSRPC_OBJ) \
> ! $(RPC_PARSE_OBJ) \
> ! $(PASSDB_OBJ) \
> ! \
> ! $(READLINE_OBJ)
> !
> ! SMBCACLS_OBJ = utils/smbcacls.o \
> ! $(PARAM_OBJ) \
> ! $(LIBSMB_OBJ) \
> ! $(UBIQX_OBJ) \
> ! $(LIB_OBJ) \
> ! $(LIBMSRPC_OBJ) \
> ! $(RPC_PARSE_OBJ) \
> ! $(PASSDB_OBJ) \
> ! \
> ! $(LOCKING_OBJ)
> !
>
> CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
>
> ***************
> *** 311,321 ****
>
> LOCKTEST_OBJ = utils/locktest.o $(LOCKING_OBJ) $(LIBSMB_OBJ) $(PARAM_OBJ) \
> $(UBIQX_OBJ) $(LIB_OBJ)
> -
> - SMBCACLS_OBJ = utils/smbcacls.o $(LOCKING_OBJ) $(LIBSMB_OBJ) $(PARAM_OBJ) \
> - $(UBIQX_OBJ) $(LIB_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) \
> - $(LIBMSRPC_OBJ)
> -
>
> LOCKTEST2_OBJ = utils/locktest2.o $(LOCKING_OBJ) $(LIBSMB_OBJ) $(PARAM_OBJ) \
> $(UBIQX_OBJ) $(LIB_OBJ)
> --- 330,335 ----
> diff -rc samba-2.2.2-10.orig/source/client/client.c samba-2.2.2-10-smbclient-showalc-patched/source/client/client.c
> *** samba-2.2.2-10.orig/source/client/client.c Wed Jan 23 11:33:19 2002
> --- samba-2.2.2-10-smbclient-showalc-patched/source/client/client.c Tue Jan 29 10:37:09 2002
> ***************
> *** 34,39 ****
> --- 34,40 ----
> pstring cd_path = "";
> static pstring service;
> static pstring desthost;
> + static pstring servername;
> extern pstring global_myname;
> static pstring password;
> static pstring username;
> ***************
> *** 1682,1687 ****
> --- 1683,1986 ----
> }
>
> /****************************************************************************
> + show access control list for file. (rws)
> + (Code taken from utils/smbcalcs.c)
> + ****************************************************************************/
> +
> + struct cli_state lsa_cli;
> + POLICY_HND pol;
> +
> + /* Open cli connection and policy handle */
> + static BOOL open_policy_hnd(void)
> + {
> + /* Were globals in smbcalcs.*/
> + static BOOL got_policy_hnd = False;
> + static struct ntuser_creds creds;
> +
> + creds.pwd.null_pwd = 1;
> +
> + /* Initialise cli LSA connection */
> + if (!lsa_cli.initialised &&
> + !cli_lsa_initialise(&lsa_cli, servername, &creds)) {
> + return False;
> + }
> +
> + /* Open policy handle */
> +
> + if (!got_policy_hnd) {
> +
> + /* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED,
> + but NT sends 0x2000000 so we might as well do it too. */
> +
> + if (cli_lsa_open_policy(&lsa_cli, lsa_cli.mem_ctx, True,
> + GENERIC_EXECUTE_ACCESS, &pol)
> + != NT_STATUS_OK) {
> + return False;
> + }
> +
> + got_policy_hnd = True;
> + }
> +
> + return True;
> + }
> +
> + /* Access Control Entry output format codes. */
> + enum AceDisplayForm
> + {
> + FORM_NORMAL, /* Attempt standard string description first. */
> + FORM_NUMERIC, /* Only output numeric values. */
> + FORM_EXPLICIT /* Explicitly list the permissions. */
> + };
> +
> + /* convert a SID to a string, either numeric or username/group */
> + static void SidToString(fstring str, DOM_SID *sid, enum AceDisplayForm form)
> + {
> + char **names = NULL;
> + uint32 *types = NULL;
> + int num_names;
> +
> + sid_to_string(str, sid);
> +
> + if (FORM_NUMERIC == form)
> + return;
> +
> + /* Ask LSA to convert the sid to a name */
> + if (!open_policy_hnd())
> + {
> + DEBUG(0, ("Error in open_policy_hnd()\n"));
> + return;
> + }
> + if (cli_lsa_lookup_sids(&lsa_cli, lsa_cli.mem_ctx,
> + &pol, 1, sid, &names, &types,
> + &num_names) != NT_STATUS_OK ||
> + !names || !names[0]) {
> + return;
> + }
> +
> + /* Converted OK */
> + fstrcpy(str, names[0]);
> + }
> +
> + /* Structure for mapping bit fields in access
> + control entries to string descriptions. */
> + struct perm_value {
> + char *perm;
> + uint32 mask;
> + };
> +
> + /* Names of bit fields within acess control entry permission mask */
> + static struct perm_value explicit_values[] =
> + {
> + { "FILE_READ_DATA", FILE_READ_DATA },
> + { "FILE_WRITE_DATA", FILE_WRITE_DATA },
> + { "FILE_APPEND_DATA", FILE_APPEND_DATA },
> + { "FILE_READ_EA", FILE_READ_EA },
> + { "FILE_WRITE_EA", FILE_WRITE_EA },
> + { "FILE_EXECUTE", FILE_EXECUTE },
> + { "FILE_DELETE_CHILD", FILE_DELETE_CHILD },
> + { "FILE_READ_ATTRIBUTES", FILE_READ_ATTRIBUTES },
> + { "FILE_WRITE_ATTRIBUTES", FILE_WRITE_ATTRIBUTES },
> +
> + { "DELETE", DELETE_ACCESS },
> + { "READ_CONTROL", READ_CONTROL_ACCESS },
> + { "WRITE_DAC", WRITE_DAC_ACCESS },
> + { "WRITE_OWNER", WRITE_OWNER_ACCESS },
> + { "SYNCHRONIZE", SYNCHRONIZE_ACCESS },
> + { NULL, 0 },
> + };
> +
> + /*
> + Standard values for file permissions (in W2K). Discovered by
> + testing... then looking in smb.h ;).
> +
> + MS cacls just seemed too messed up to imitate its behavior.
> +
> + Masking out the SYNCHRONIZE_ACCESS values because the 'denied'
> + access control entries do not seem to have them for standard values.
> + */
> + static struct perm_value standard_values[] =
> + {
> + { "Read",
> + (FILE_GENERIC_READ)
> + & ~SYNCHRONIZE_ACCESS },
> +
> + { "Read & Execute",
> + (FILE_GENERIC_EXECUTE
> + | FILE_GENERIC_READ)
> + & ~SYNCHRONIZE_ACCESS },
> +
> + /* I don't think smb.h has FILE_GENERIC_WRITE correct
> + (or it isn't what I think it is ;). */
> + { "Write",
> + (FILE_WRITE_DATA
> + | FILE_APPEND_DATA
> + | FILE_WRITE_EA
> + | FILE_WRITE_ATTRIBUTES)
> + & ~SYNCHRONIZE_ACCESS },
> +
> + { "Modify",
> + (FILE_GENERIC_READ
> + | FILE_GENERIC_WRITE
> + | FILE_GENERIC_EXECUTE
> + | DELETE_ACCESS)
> + & ~SYNCHRONIZE_ACCESS },
> +
> + { "Full Control",
> + (FILE_GENERIC_ALL)
> + & ~SYNCHRONIZE_ACCESS },
> +
> + { NULL, 0 },
> + };
> +
> + static void print_ace(SEC_ACE *ace, enum AceDisplayForm form)
> + {
> + const char * indent = " ";
> + struct perm_value *v;
> + fstring sidstr;
> + uint32 leftover;
> + uint32 tmp_mask;
> +
> + SidToString(sidstr, &ace->sid, form);
> +
> + DEBUG(0,("%s:", sidstr));
> +
> + if (FORM_NUMERIC == form ) {
> + DEBUG(0,("%d/%d/0x%08x",
> + ace->type, ace->flags, ace->info.mask));
> + return;
> + }
> +
> + /* Ace type */
> +
> + if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED) {
> + DEBUG(0,("ALLOWED"));
> + } else if (ace->type == SEC_ACE_TYPE_ACCESS_DENIED) {
> + DEBUG(0,("DENIED"));
> + } else {
> + DEBUG(0,("%d", ace->type));
> + }
> +
> + /* Not sure what flags can be set in a file ACL */
> + DEBUG(0,("/%d/", ace->flags));
> +
> + /* Standard permissions, (rws : w2k form) */
> + if (FORM_NORMAL == form) {
> + /* Mask out the SYNCHRONIZE_ACCESS */
> + tmp_mask = ace->info.mask & ~SYNCHRONIZE_ACCESS;
> + for (v = standard_values; v->perm; v++) {
> + if (tmp_mask == v->mask) {
> + DEBUG(0,("%s", v->perm));
> + return;
> + }
> + }
> + DEBUG(0,("(special access:)"));
> + }
> +
> + /* Print each access description, 1 per line, indented. */
> + leftover = ace->info.mask;
> + for (v = explicit_values; v->perm; v++) {
> + if ((ace->info.mask & v->mask)) {
> + leftover &= ~v->mask;
> + DEBUG(0,("\n%s%s", indent, v->perm));
> + }
> + }
> + if (leftover) DEBUG(0,("\n%suninterpreted : 0x%08x",
> + indent, leftover));
> + }
> +
> + static void cmd_showacl(void)
> + {
> + #define SHOWACL_USAGE "<remote name> [-n | --numeric | -x | --explicit] \n"
> +
> + int fnum;
> + fstring filename;
> + fstring buf;
> + enum AceDisplayForm form = FORM_NORMAL;
> + int i;
> + SEC_DESC *sd;
> + TALLOC_CTX *ctx;
> +
> + /* - get/convert filename option - */
> + if (!next_token(NULL,buf,NULL,sizeof(filename))) {
> + DEBUG(0,(SHOWACL_USAGE));
> + return;
> + }
> + string_replace( buf, '/','\\');
> +
> + /* allow '.' and '..' converting them to '.\' and '.\\' */
> + if (strequal(buf, ".") || strequal(buf, ".."))
> + pstrcat(buf, "\\");
> +
> + /* construct full name, leading '\'
> + indicates absolute path */
> + if (strnequal(buf, "\\", 1)) {
> + pstrcpy(filename, buf);
> + } else {
> + pstrcpy(filename, cur_dir);
> + pstrcat(filename, buf);
> + }
> + dos_clean_name(filename);
> + DEBUG(3,("file name : %s\n", filename));
> +
> + /* - get format option - */
> + if (next_token(NULL,buf,NULL,sizeof(buf))) {
> + if (strequal("-n", buf) ||
> + strnequal("--n", buf, strlen("--n"))) {
> + form = FORM_NUMERIC;
> +
> + } else if(strequal("-x", buf) ||
> + strnequal("--e",buf, strlen("--e"))) {
> + form = FORM_EXPLICIT;
> +
> + } else {
> + DEBUG(0, (SHOWACL_USAGE));
> + return;
> + }
> + }
> +
> + /* - Reject further options - */
> + if (next_token(NULL,buf,NULL,sizeof(buf))) {
> + DEBUG(0, (SHOWACL_USAGE));
> + return;
> + }
> +
> + /* - Retrieve - */
> + if (-1 == (fnum = cli_nt_create(cli, filename, READ_CONTROL_ACCESS))) {
> + printf("Failed to open %s: %s\n", filename, cli_errstr(cli));
> + return;
> + }
> +
> + if (!(sd = cli_query_secdesc(cli, fnum, ctx))) {
> + printf("ERROR: secdesc query failed: %s\n", cli_errstr(cli));
> + return;
> + }
> +
> + /* - Print - */
> + /* revision should be '1' */
> + DEBUG(0,("REVISION:%d\n", sd->revision));
> +
> + /* Print owner sid */
> + if (sd->owner_sid) SidToString(buf, sd->owner_sid, form);
> + else fstrcpy(buf, "");
> + DEBUG(0,("OWNER:%s\n", buf));
> +
> + /* Print group sid */
> + if (sd->grp_sid) SidToString(buf, sd->grp_sid, form);
> + else fstrcpy(buf, "");
> + DEBUG(0,("GROUP:%s\n", buf));
> +
> + /* Print access control entries */
> + for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
> + SEC_ACE *ace = &sd->dacl->ace[i];
> + DEBUG(0,("ACL:"));
> + print_ace(ace, form);
> + DEBUG(0,("\n"));
> + }
> +
> + cli_close(cli, fnum);
> + }
> +
> + /****************************************************************************
> try and browse available connections on a host
> ****************************************************************************/
> static BOOL list_servers(char *wk_grp)
> ***************
> *** 1756,1761 ****
> --- 2055,2063 ----
> {"help",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}},
> {"?",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}},
> {"history",cmd_history,"displays the command history",{COMPL_NONE,COMPL_NONE}},
> + {"showacl",cmd_showacl,
> + SHOWACL_USAGE "\tshow access control list for remote file",
> + {COMPL_NONE,COMPL_NONE}},
> {"!",NULL,"run a shell command on the local system",{COMPL_NONE,COMPL_NONE}},
> {"",NULL,NULL,{COMPL_NONE,COMPL_NONE}}
> };
> ***************
> *** 1984,1989 ****
> --- 2286,2292 ----
> sharename = strchr(server,'\\');
> if (!sharename) return NULL;
> *sharename = 0;
> + fstrcpy(servername, servicename);
> sharename++;
> }
>
>
More information about the smb-clients
mailing list