This commit was manufactured by cvs2svn to create branch 'SAMBA_3_0'.(This used to...
[bbaumbach/samba-autobuild/.git] / source3 / utils / smbcacls.c
index f07bdb0dd8de4fbe1a19054929942d063262d48e..b6a13180a377715e836405db1aa79ee6eb53d257 100644 (file)
@@ -1,7 +1,6 @@
 /* 
-   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
@@ -43,6 +42,9 @@ enum acl_mode {SMB_ACL_SET, SMB_ACL_DELETE, SMB_ACL_MODIFY, SMB_ACL_ADD };
 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;
@@ -67,24 +69,25 @@ static struct perm_value standard_values[] = {
        { 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) {
@@ -92,9 +95,8 @@ static BOOL cacls_open_policy_hnd(void)
                /* 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;
                }
 
@@ -107,9 +109,9 @@ static BOOL cacls_open_policy_hnd(void)
 /* 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);
 
@@ -118,38 +120,41 @@ static void SidToString(fstring str, DOM_SID *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;
@@ -164,7 +169,7 @@ static void print_ace(FILE *f, SEC_ACE *ace)
        int do_print = 0;
        uint32 got_mask;
 
-       SidToString(sidstr, &ace->sid);
+       SidToString(sidstr, &ace->trustee);
 
        fprintf(f, "%s:", sidstr);
 
@@ -234,7 +239,7 @@ static BOOL parse_ace(SEC_ACE *ace, char *str)
        struct perm_value *v;
 
        ZERO_STRUCTP(ace);
-       p = strchr(str,':');
+       p = strchr_m(str,':');
        if (!p) return False;
        *p = '\0';
        p++;
@@ -329,7 +334,7 @@ static BOOL add_ace(SEC_ACL **the_acl, SEC_ACE *ace)
        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;
 }
@@ -392,8 +397,8 @@ static SEC_DESC *sec_desc_parse(char *str)
        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;
 }
@@ -403,7 +408,7 @@ static SEC_DESC *sec_desc_parse(char *str)
 static void sec_desc_print(FILE *f, SEC_DESC *sd)
 {
        fstring sidstr;
-       int i;
+       uint32 i;
 
        printf("REVISION:%d\n", sd->revision);
 
@@ -526,18 +531,30 @@ static int owner_set(struct cli_state *cli, enum chown_mode change_mode,
 
 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);
@@ -563,7 +580,7 @@ static int cacl_set(struct cli_state *cli, char *filename,
 {
        int fnum;
        SEC_DESC *sd, *old;
-       int i, j;
+       uint32 i, j;
        size_t sd_size;
        int result = EXIT_OK;
 
@@ -600,16 +617,14 @@ static int cacl_set(struct cli_state *cli, char *filename,
                        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;
@@ -630,8 +645,8 @@ static int cacl_set(struct cli_state *cli, char *filename,
                        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;
                                }
@@ -640,7 +655,7 @@ static int cacl_set(struct cli_state *cli, char *filename,
                        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);
                        }
                }
@@ -688,90 +703,31 @@ static int cacl_set(struct cli_state *cli, char *filename,
 /***************************************************** 
 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;
 }
 
 
@@ -807,21 +763,20 @@ You can string acls together with spaces, commas or newlines\n\
        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();
@@ -838,21 +793,17 @@ You can string acls together with spaces, commas or newlines\n\
        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));
                }
        }
@@ -861,7 +812,7 @@ You can string acls together with spaces, commas or newlines\n\
                switch (opt) {
                case 'U':
                        pstrcpy(username,optarg);
-                       p = strchr(username,'%');
+                       p = strchr_m(username,'%');
                        if (p) {
                                *p = 0;
                                pstrcpy(password, p+1);
@@ -925,7 +876,7 @@ You can string acls together with spaces, commas or newlines\n\
 
        argc -= optind;
        argv += optind;
-       
+
        if (argc > 0) {
                usage();
                talloc_destroy(ctx);
@@ -934,12 +885,26 @@ You can string acls together with spaces, commas or newlines\n\
 
        /* 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);
@@ -964,3 +929,4 @@ You can string acls together with spaces, commas or newlines\n\
 
        return result;
 }
+