⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smbcacls.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    Unix SMB/CIFS implementation.   ACL get/set utility      Copyright (C) Andrew Tridgell 2000   Copyright (C) Tim Potter      2000   Copyright (C) Jeremy Allison  2000   Copyright (C) Jelmer Vernooij 2003      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   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.      This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.      You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "includes.h"static pstring owner_username;static fstring server;static int test_args = False;static TALLOC_CTX *ctx;#define CREATE_ACCESS_READ READ_CONTROL_ACCESS/* numeric is set when the user wants numeric SIDs and ACEs rather   than going via LSA calls to resolve them */static BOOL numeric = False;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};struct perm_value {	const char *perm;	uint32 mask;};/* These values discovered by inspection */static const struct perm_value special_values[] = {	{ "R", 0x00120089 },	{ "W", 0x00120116 },	{ "X", 0x001200a0 },	{ "D", 0x00010000 },	{ "P", 0x00040000 },	{ "O", 0x00080000 },	{ NULL, 0 },};static const struct perm_value standard_values[] = {	{ "READ",   0x001200a9 },	{ "CHANGE", 0x001301bf },	{ "FULL",   0x001f01ff },	{ NULL, 0 },};static struct cli_state *global_hack_cli;static struct rpc_pipe_client *global_pipe_hnd;static POLICY_HND pol;static BOOL got_policy_hnd;static struct cli_state *connect_one(const char *share);/* Open cli connection and policy handle */static BOOL cacls_open_policy_hnd(void){	/* Initialise cli LSA connection */	if (!global_hack_cli) {		NTSTATUS ret;		global_hack_cli = connect_one("IPC$");		global_pipe_hnd = cli_rpc_pipe_open_noauth(global_hack_cli, PI_LSARPC, &ret);		if (!global_pipe_hnd) {				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 (!NT_STATUS_IS_OK(rpccli_lsa_open_policy(global_pipe_hnd, global_hack_cli->mem_ctx, True, 							 GENERIC_EXECUTE_ACCESS, &pol))) {			return False;		}		got_policy_hnd = True;	}		return True;}/* 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;	sid_to_string(str, sid);	if (numeric) return;	/* Ask LSA to convert the sid to a name */	if (!cacls_open_policy_hnd() ||	    !NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(global_pipe_hnd, 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]);	}/* convert a string to a SID, either numeric or username/group */static BOOL StringToSid(DOM_SID *sid, const char *str){	uint32 *types = NULL;	DOM_SID *sids = NULL;	BOOL result = True;	if (strncmp(str, "S-", 2) == 0) {		return string_to_sid(sid, str);	}	if (!cacls_open_policy_hnd() ||	    !NT_STATUS_IS_OK(rpccli_lsa_lookup_names(global_pipe_hnd, global_hack_cli->mem_ctx, 						  &pol, 1, &str, &sids, 						  &types))) {		result = False;		goto done;	}	sid_copy(sid, &sids[0]); done:	return result;}/* print an ACE on a FILE, using either numeric or ascii representation */static void print_ace(FILE *f, SEC_ACE *ace){	const struct perm_value *v;	fstring sidstr;	int do_print = 0;	uint32 got_mask;	SidToString(sidstr, &ace->trustee);	fprintf(f, "%s:", sidstr);	if (numeric) {		fprintf(f, "%d/%d/0x%08x", 			ace->type, ace->flags, ace->info.mask);		return;	}	/* Ace type */	if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED) {		fprintf(f, "ALLOWED");	} else if (ace->type == SEC_ACE_TYPE_ACCESS_DENIED) {		fprintf(f, "DENIED");	} else {		fprintf(f, "%d", ace->type);	}	/* Not sure what flags can be set in a file ACL */	fprintf(f, "/%d/", ace->flags);	/* Standard permissions */	for (v = standard_values; v->perm; v++) {		if (ace->info.mask == v->mask) {			fprintf(f, "%s", v->perm);			return;		}	}	/* Special permissions.  Print out a hex value if we have	   leftover bits in the mask. */	got_mask = ace->info.mask; again:	for (v = special_values; v->perm; v++) {		if ((ace->info.mask & v->mask) == v->mask) {			if (do_print) {				fprintf(f, "%s", v->perm);			}			got_mask &= ~v->mask;		}	}	if (!do_print) {		if (got_mask != 0) {			fprintf(f, "0x%08x", ace->info.mask);		} else {			do_print = 1;			goto again;		}	}}/* parse an ACE in the same format as print_ace() */static BOOL parse_ace(SEC_ACE *ace, const char *orig_str){	char *p;	const char *cp;	fstring tok;	unsigned int atype = 0;	unsigned int aflags = 0;	unsigned int amask = 0;	DOM_SID sid;	SEC_ACCESS mask;	const struct perm_value *v;	char *str = SMB_STRDUP(orig_str);	if (!str) {		return False;	}	ZERO_STRUCTP(ace);	p = strchr_m(str,':');	if (!p) {		printf("ACE '%s': missing ':'.\n", orig_str);		SAFE_FREE(str);		return False;	}	*p = '\0';	p++;	/* Try to parse numeric form */	if (sscanf(p, "%i/%i/%i", &atype, &aflags, &amask) == 3 &&	    StringToSid(&sid, str)) {		goto done;	}	/* Try to parse text form */	if (!StringToSid(&sid, str)) {		printf("ACE '%s': failed to convert '%s' to SID\n",			orig_str, str);		SAFE_FREE(str);		return False;	}	cp = p;	if (!next_token(&cp, tok, "/", sizeof(fstring))) {		printf("ACE '%s': failed to find '/' character.\n",			orig_str);		SAFE_FREE(str);		return False;	}	if (strncmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) {		atype = SEC_ACE_TYPE_ACCESS_ALLOWED;	} else if (strncmp(tok, "DENIED", strlen("DENIED")) == 0) {		atype = SEC_ACE_TYPE_ACCESS_DENIED;	} else {		printf("ACE '%s': missing 'ALLOWED' or 'DENIED' entry at '%s'\n",			orig_str, tok);		SAFE_FREE(str);		return False;	}	/* Only numeric form accepted for flags at present */	if (!(next_token(&cp, tok, "/", sizeof(fstring)) &&	      sscanf(tok, "%i", &aflags))) {		printf("ACE '%s': bad integer flags entry at '%s'\n",			orig_str, tok);		SAFE_FREE(str);		return False;	}	if (!next_token(&cp, tok, "/", sizeof(fstring))) {		printf("ACE '%s': missing / at '%s'\n",			orig_str, tok);		SAFE_FREE(str);		return False;	}	if (strncmp(tok, "0x", 2) == 0) {		if (sscanf(tok, "%i", &amask) != 1) {			printf("ACE '%s': bad hex number at '%s'\n",				orig_str, tok);			SAFE_FREE(str);			return False;		}		goto done;	}	for (v = standard_values; v->perm; v++) {		if (strcmp(tok, v->perm) == 0) {			amask = v->mask;			goto done;		}	}	p = tok;	while(*p) {		BOOL found = False;		for (v = special_values; v->perm; v++) {			if (v->perm[0] == *p) {				amask |= v->mask;				found = True;			}		}		if (!found) {			printf("ACE '%s': bad permission value at '%s'\n",				orig_str, p);			SAFE_FREE(str);		 	return False;		}		p++;	}	if (*p) {		SAFE_FREE(str);		return False;	} done:	mask.mask = amask;	init_sec_ace(ace, &sid, atype, mask, aflags);	SAFE_FREE(str);	return True;}/* add an ACE to a list of ACEs in a SEC_ACL */static BOOL add_ace(SEC_ACL **the_acl, SEC_ACE *ace){	SEC_ACL *new_ace;	SEC_ACE *aces;	if (! *the_acl) {		(*the_acl) = make_sec_acl(ctx, 3, 1, ace);		return True;	}	aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces);	memcpy(aces, (*the_acl)->ace, (*the_acl)->num_aces * sizeof(SEC_ACE));	memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE));	new_ace = make_sec_acl(ctx,(*the_acl)->revision,1+(*the_acl)->num_aces, aces);	SAFE_FREE(aces);	(*the_acl) = new_ace;	return True;}/* parse a ascii version of a security descriptor */static SEC_DESC *sec_desc_parse(char *str){	const char *p = str;	fstring tok;	SEC_DESC *ret;	size_t sd_size;	DOM_SID *grp_sid=NULL, *owner_sid=NULL;	SEC_ACL *dacl=NULL;	int revision=1;	while (next_token(&p, tok, "\t,\r\n", sizeof(tok))) {		if (strncmp(tok,"REVISION:", 9) == 0) {			revision = strtol(tok+9, NULL, 16);			continue;		}		if (strncmp(tok,"OWNER:", 6) == 0) {			owner_sid = SMB_CALLOC_ARRAY(DOM_SID, 1);			if (!owner_sid ||			    !StringToSid(owner_sid, tok+6)) {				printf("Failed to parse owner sid\n");				return NULL;			}			continue;		}		if (strncmp(tok,"GROUP:", 6) == 0) {			grp_sid = SMB_CALLOC_ARRAY(DOM_SID, 1);			if (!grp_sid ||			    !StringToSid(grp_sid, tok+6)) {				printf("Failed to parse group sid\n");				return NULL;			}			continue;		}		if (strncmp(tok,"ACL:", 4) == 0) {			SEC_ACE ace;			if (!parse_ace(&ace, tok+4)) {				return NULL;			}			if(!add_ace(&dacl, &ace)) {				printf("Failed to add ACL %s\n", tok);				return NULL;			}			continue;		}		printf("Failed to parse token '%s' in security descriptor,\n", tok);		return NULL;	}	ret = make_sec_desc(ctx,revision, SEC_DESC_SELF_RELATIVE, owner_sid, grp_sid, 			    NULL, dacl, &sd_size);	SAFE_FREE(grp_sid);	SAFE_FREE(owner_sid);	return ret;}/* print a ascii version of a security descriptor on a FILE handle */static void sec_desc_print(FILE *f, SEC_DESC *sd){	fstring sidstr;	uint32 i;	fprintf(f, "REVISION:%d\n", sd->revision);	/* Print owner and group sid */	if (sd->owner_sid) {		SidToString(sidstr, sd->owner_sid);	} else {		fstrcpy(sidstr, "");	}	fprintf(f, "OWNER:%s\n", sidstr);	if (sd->grp_sid) {		SidToString(sidstr, sd->grp_sid);	} else {		fstrcpy(sidstr, "");	}	fprintf(f, "GROUP:%s\n", sidstr);	/* Print aces */	for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {		SEC_ACE *ace = &sd->dacl->ace[i];		fprintf(f, "ACL:");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -