/*
- Unix SMB/Netbios implementation.
+ Unix SMB/CIFS implementation.
ACL get/set utility
- Version 3.0
Copyright (C) Andrew Tridgell 2000
Copyright (C) Tim Potter 2000
enum chown_mode {REQUEST_NONE, REQUEST_CHOWN, REQUEST_CHGRP};
enum exit_values {EXIT_OK, EXIT_FAILED, EXIT_PARSE_ERROR};
+extern pstring global_myname;
+extern fstring global_myworkgroup;
+
struct perm_value {
char *perm;
uint32 mask;
{ NULL, 0 },
};
-struct cli_state lsa_cli;
-POLICY_HND pol;
-struct ntuser_creds creds;
-BOOL got_policy_hnd;
+static struct cli_state *global_hack_cli;
+static POLICY_HND pol;
+static BOOL got_policy_hnd;
+
+static struct cli_state *connect_one(char *share);
/* Open cli connection and policy handle */
static BOOL cacls_open_policy_hnd(void)
{
- creds.pwd.null_pwd = 1;
-
/* Initialise cli LSA connection */
- if (!lsa_cli.initialised &&
- !cli_lsa_initialise(&lsa_cli, server, &creds)) {
- return False;
+ if (!global_hack_cli) {
+ global_hack_cli = connect_one("IPC$");
+ if (!cli_nt_session_open (global_hack_cli, PIPE_LSARPC)) {
+ 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_NOPROBLEMO) {
+ if (!NT_STATUS_IS_OK(cli_lsa_open_policy(global_hack_cli, global_hack_cli->mem_ctx, True,
+ GENERIC_EXECUTE_ACCESS, &pol))) {
return False;
}
/* convert a SID to a string, either numeric or username/group */
static void SidToString(fstring str, DOM_SID *sid)
{
+ char **domains = NULL;
char **names = NULL;
uint32 *types = NULL;
- int num_names;
sid_to_string(str, sid);
/* Ask LSA to convert the sid to a name */
if (!cacls_open_policy_hnd() ||
- cli_lsa_lookup_sids(&lsa_cli, lsa_cli.mem_ctx, &pol, 1, sid, &names, &types,
- &num_names) != NT_STATUS_NOPROBLEMO ||
- !names || !names[0]) {
+ !NT_STATUS_IS_OK(cli_lsa_lookup_sids(global_hack_cli, global_hack_cli->mem_ctx,
+ &pol, 1, sid, &domains,
+ &names, &types)) ||
+ !domains || !domains[0] || !names || !names[0]) {
return;
}
/* Converted OK */
+
+ slprintf(str, sizeof(fstring) - 1, "%s%s%s",
+ domains[0], lp_winbind_separator(),
+ names[0]);
- fstrcpy(str, names[0]);
}
/* convert a string to a SID, either numeric or username/group */
-static BOOL StringToSid(DOM_SID *sid, char *str)
+static BOOL StringToSid(DOM_SID *sid, const char *str)
{
uint32 *types = NULL;
DOM_SID *sids = NULL;
- int num_sids;
BOOL result = True;
-
+
if (strncmp(str, "S-", 2) == 0) {
return string_to_sid(sid, str);
}
if (!cacls_open_policy_hnd() ||
- cli_lsa_lookup_names(&lsa_cli, lsa_cli.mem_ctx, &pol, 1, &str, &sids, &types,
- &num_sids) != NT_STATUS_NOPROBLEMO) {
+ !NT_STATUS_IS_OK(cli_lsa_lookup_names(global_hack_cli, global_hack_cli->mem_ctx,
+ &pol, 1, &str, &sids,
+ &types))) {
result = False;
goto done;
}
sid_copy(sid, &sids[0]);
-
done:
return result;
int do_print = 0;
uint32 got_mask;
- SidToString(sidstr, &ace->sid);
+ SidToString(sidstr, &ace->trustee);
fprintf(f, "%s:", sidstr);
struct perm_value *v;
ZERO_STRUCTP(ace);
- p = strchr(str,':');
+ p = strchr_m(str,':');
if (!p) return False;
*p = '\0';
p++;
memcpy(aces, (*the_acl)->ace, (*the_acl)->num_aces * sizeof(SEC_ACE));
memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE));
new = make_sec_acl(ctx,(*the_acl)->revision,1+(*the_acl)->num_aces, aces);
- free(aces);
+ SAFE_FREE(aces);
(*the_acl) = new;
return True;
}
ret = make_sec_desc(ctx,revision, owner_sid, grp_sid,
NULL, dacl, &sd_size);
- if (grp_sid) free(grp_sid);
- if (owner_sid) free(owner_sid);
+ SAFE_FREE(grp_sid);
+ SAFE_FREE(owner_sid);
return ret;
}
static void sec_desc_print(FILE *f, SEC_DESC *sd)
{
fstring sidstr;
- int i;
+ uint32 i;
printf("REVISION:%d\n", sd->revision);
static int ace_compare(SEC_ACE *ace1, SEC_ACE *ace2)
{
- if (sec_ace_equal(ace1, ace2)) return 0;
- if (ace1->type != ace2->type) return ace2->type - ace1->type;
- if (sid_compare(&ace1->sid, &ace2->sid)) return sid_compare(&ace1->sid, &ace2->sid);
- if (ace1->flags != ace2->flags) return ace1->flags - ace2->flags;
- if (ace1->info.mask != ace2->info.mask) return ace1->info.mask - ace2->info.mask;
- if (ace1->size != ace2->size) return ace1->size - ace2->size;
+ if (sec_ace_equal(ace1, ace2))
+ return 0;
+
+ if (ace1->type != ace2->type)
+ return ace2->type - ace1->type;
+
+ if (sid_compare(&ace1->trustee, &ace2->trustee))
+ return sid_compare(&ace1->trustee, &ace2->trustee);
+
+ if (ace1->flags != ace2->flags)
+ return ace1->flags - ace2->flags;
+
+ if (ace1->info.mask != ace2->info.mask)
+ return ace1->info.mask - ace2->info.mask;
+
+ if (ace1->size != ace2->size)
+ return ace1->size - ace2->size;
+
return memcmp(ace1, ace2, sizeof(SEC_ACE));
}
static void sort_acl(SEC_ACL *the_acl)
{
- int i;
+ uint32 i;
if (!the_acl) return;
qsort(the_acl->ace, the_acl->num_aces, sizeof(the_acl->ace[0]), QSORT_CAST ace_compare);
{
int fnum;
SEC_DESC *sd, *old;
- int i, j;
+ uint32 i, j;
size_t sd_size;
int result = EXIT_OK;
for (j=0;old->dacl && j<old->dacl->num_aces;j++) {
if (sec_ace_equal(&sd->dacl->ace[i],
&old->dacl->ace[j])) {
- int k;
+ uint32 k;
for (k=j; k<old->dacl->num_aces-1;k++) {
old->dacl->ace[k] = old->dacl->ace[k+1];
}
old->dacl->num_aces--;
if (old->dacl->num_aces == 0) {
- free(old->dacl->ace);
- old->dacl->ace=NULL;
- free(old->dacl);
- old->dacl = NULL;
+ SAFE_FREE(old->dacl->ace);
+ SAFE_FREE(old->dacl);
old->off_dacl = 0;
}
found = True;
BOOL found = False;
for (j=0;old->dacl && j<old->dacl->num_aces;j++) {
- if (sid_equal(&sd->dacl->ace[i].sid,
- &old->dacl->ace[j].sid)) {
+ if (sid_equal(&sd->dacl->ace[i].trustee,
+ &old->dacl->ace[j].trustee)) {
old->dacl->ace[j] = sd->dacl->ace[i];
found = True;
}
if (!found) {
fstring str;
- SidToString(str, &sd->dacl->ace[i].sid);
+ SidToString(str, &sd->dacl->ace[i].trustee);
printf("ACL for SID %s not found\n", str);
}
}
/*****************************************************
return a connection to a server
*******************************************************/
-struct cli_state *connect_one(char *share)
+static struct cli_state *connect_one(char *share)
{
struct cli_state *c;
- struct nmb_name called, calling;
- char *server_n;
struct in_addr ip;
- extern struct in_addr ipzero;
- extern pstring global_myname;
-
- fstrcpy(server,share+2);
- share = strchr(server,'\\');
- if (!share) return NULL;
- *share = 0;
- share++;
-
- server_n = server;
+ NTSTATUS nt_status;
+ zero_ip(&ip);
- ip = ipzero;
-
- make_nmb_name(&calling, global_myname, 0x0);
- make_nmb_name(&called , server, 0x20);
-
- again:
- ip = ipzero;
-
- /* have to open a new connection */
- if (!(c=cli_initialise(NULL)) || (cli_set_port(c, 139) == 0) ||
- !cli_connect(c, server_n, &ip)) {
- DEBUG(0,("Connection to %s failed\n", server_n));
- cli_shutdown(c);
- safe_free(c);
- return NULL;
- }
-
- if (!cli_session_request(c, &calling, &called)) {
- DEBUG(0,("session request to %s failed\n", called.name));
- cli_shutdown(c);
- safe_free(c);
- if (strcmp(called.name, "*SMBSERVER")) {
- make_nmb_name(&called , "*SMBSERVER", 0x20);
- goto again;
- }
- return NULL;
- }
-
- DEBUG(4,(" session request ok\n"));
-
- if (!cli_negprot(c)) {
- DEBUG(0,("protocol negotiation failed\n"));
- cli_shutdown(c);
- safe_free(c);
- return NULL;
- }
-
if (!got_pass) {
char *pass = getpass("Password: ");
if (pass) {
pstrcpy(password, pass);
+ got_pass = True;
}
}
- if (!cli_session_setup(c, username,
- password, strlen(password),
- password, strlen(password),
- lp_workgroup())) {
- DEBUG(0,("session setup failed: %s\n", cli_errstr(c)));
- cli_shutdown(c);
- safe_free(c);
- return NULL;
- }
-
- DEBUG(4,(" session setup ok\n"));
-
- if (!cli_send_tconX(c, share, "?????",
- password, strlen(password)+1)) {
- DEBUG(0,("tree connect failed: %s\n", cli_errstr(c)));
- cli_shutdown(c);
- safe_free(c);
+ if (NT_STATUS_IS_OK(nt_status = cli_full_connection(&c, global_myname, server,
+ &ip, 0,
+ share, "?????",
+ username, global_myworkgroup,
+ password, 0))) {
+ return c;
+ } else {
+ DEBUG(0,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status)));
return NULL;
}
-
- DEBUG(4,(" tconx ok\n"));
-
- return c;
}
pstring filename;
extern char *optarg;
extern int optind;
- extern FILE *dbf;
int opt;
char *p;
- static pstring servicesf = CONFIGFILE;
- struct cli_state *cli=NULL;
enum acl_mode mode = SMB_ACL_SET;
char *the_acl = NULL;
enum chown_mode change_mode = REQUEST_NONE;
int result;
+ struct cli_state *cli;
+
ctx=talloc_init();
setlinebuf(stdout);
- dbf = stderr;
+ dbf = x_stderr;
if (argc < 3 || argv[1][0] == '-') {
usage();
argc -= 2;
argv += 2;
- TimeInit();
- charset_initialise();
-
- lp_load(servicesf,True,False,False);
- codepage_initialise(lp_client_code_page());
+ lp_load(dyn_CONFIGFILE,True,False,False);
load_interfaces();
if (getenv("USER")) {
pstrcpy(username,getenv("USER"));
- if ((p=strchr(username,'%'))) {
+ if ((p=strchr_m(username,'%'))) {
*p = 0;
pstrcpy(password,p+1);
got_pass = True;
- memset(strchr(getenv("USER"), '%') + 1, 'X',
+ memset(strchr_m(getenv("USER"), '%') + 1, 'X',
strlen(password));
}
}
switch (opt) {
case 'U':
pstrcpy(username,optarg);
- p = strchr(username,'%');
+ p = strchr_m(username,'%');
if (p) {
*p = 0;
pstrcpy(password, p+1);
argc -= optind;
argv += optind;
-
+
if (argc > 0) {
usage();
talloc_destroy(ctx);
/* Make connection to server */
+ fstrcpy(server,share+2);
+ share = strchr_m(server,'\\');
+ if (!share) {
+ share = strchr_m(server,'/');
+ if (!share) {
+ return -1;
+ }
+ }
+
+ *share = 0;
+ share++;
+
if (!test_args) {
cli = connect_one(share);
if (!cli) {
talloc_destroy(ctx);
exit(EXIT_FAILED);
}
+ } else {
+ exit(0);
}
all_string_sub(filename, "/", "\\", 0);
return result;
}
+