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

📄 sysacls.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	return acl_d;}int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d){	*permset_d = 0;	return 0;}int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm){	if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE	    && perm != SMB_ACL_EXECUTE) {		errno = EINVAL;		return -1;	}	if (permset_d == NULL) {		errno = EINVAL;		return -1;	}	*permset_d |= perm;	return 0;}int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm){	return *permset_d & perm;}char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p){	int	i;	int	len, maxlen;	char	*text;	/*	 * use an initial estimate of 20 bytes per ACL entry	 * when allocating memory for the text representation	 * of the ACL	 */	len	= 0;	maxlen	= 20 * acl_d->count;	if ((text = SMB_MALLOC(maxlen)) == NULL) {		errno = ENOMEM;		return NULL;	}	for (i = 0; i < acl_d->count; i++) {		struct acl	*ap	= &acl_d->acl[i];		struct passwd	*pw;		struct group	*gr;		char		tagbuf[12];		char		idbuf[12];		char		*tag;		char		*id	= "";		char		perms[4];		int		nbytes;		switch (ap->a_type) {			/*			 * for debugging purposes it's probably more			 * useful to dump unknown tag types rather			 * than just returning an error			 */			default:				slprintf(tagbuf, sizeof(tagbuf)-1, "0x%x",					ap->a_type);				tag = tagbuf;				slprintf(idbuf, sizeof(idbuf)-1, "%ld",					(long)ap->a_id);				id = idbuf;				break;			case SMB_ACL_USER:				id = uidtoname(ap->a_id);			case SMB_ACL_USER_OBJ:				tag = "user";				break;			case SMB_ACL_GROUP:				if ((gr = getgrgid(ap->a_id)) == NULL) {					slprintf(idbuf, sizeof(idbuf)-1, "%ld",						(long)ap->a_id);					id = idbuf;				} else {					id = gr->gr_name;				}			case SMB_ACL_GROUP_OBJ:				tag = "group";				break;			case SMB_ACL_OTHER:				tag = "other";				break;			case SMB_ACL_MASK:				tag = "mask";				break;		}		perms[0] = (ap->a_perm & SMB_ACL_READ) ? 'r' : '-';		perms[1] = (ap->a_perm & SMB_ACL_WRITE) ? 'w' : '-';		perms[2] = (ap->a_perm & SMB_ACL_EXECUTE) ? 'x' : '-';		perms[3] = '\0';		/*          <tag>      :  <qualifier>   :  rwx \n  \0 */		nbytes = strlen(tag) + 1 + strlen(id) + 1 + 3 + 1 + 1;		/*		 * If this entry would overflow the buffer		 * allocate enough additional memory for this		 * entry and an estimate of another 20 bytes		 * for each entry still to be processed		 */		if ((len + nbytes) > maxlen) {			char *oldtext = text;			maxlen += nbytes + 20 * (acl_d->count - i);			if ((text = SMB_REALLOC(oldtext, maxlen)) == NULL) {				SAFE_FREE(oldtext);				errno = ENOMEM;				return NULL;			}		}		slprintf(&text[len], nbytes-1, "%s:%s:%s\n", tag, id, perms);		len += nbytes - 1;	}	if (len_p)		*len_p = len;	return text;}SMB_ACL_T sys_acl_init(int count){	SMB_ACL_T	a;	if (count < 0) {		errno = EINVAL;		return NULL;	}	/*	 * note that since the definition of the structure pointed	 * to by the SMB_ACL_T includes the first element of the	 * acl[] array, this actually allocates an ACL with room	 * for (count+1) entries	 */	if ((a = SMB_MALLOC(sizeof(struct SMB_ACL_T) + count * sizeof(struct acl))) == NULL) {		errno = ENOMEM;		return NULL;	}	a->size = count + 1;	a->count = 0;	a->next = -1;	return a;}int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p){	SMB_ACL_T	acl_d;	SMB_ACL_ENTRY_T	entry_d;	if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {		errno = EINVAL;		return -1;	}	if (acl_d->count >= acl_d->size) {		errno = ENOSPC;		return -1;	}	entry_d		= &acl_d->acl[acl_d->count++];	entry_d->a_type	= 0;	entry_d->a_id	= -1;	entry_d->a_perm	= 0;	*entry_p	= entry_d;	return 0;}int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type){	switch (tag_type) {		case SMB_ACL_USER:		case SMB_ACL_USER_OBJ:		case SMB_ACL_GROUP:		case SMB_ACL_GROUP_OBJ:		case SMB_ACL_OTHER:		case SMB_ACL_MASK:			entry_d->a_type = tag_type;			break;		default:			errno = EINVAL;			return -1;	}	return 0;}int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p){	if (entry_d->a_type != SMB_ACL_GROUP	    && entry_d->a_type != SMB_ACL_USER) {		errno = EINVAL;		return -1;	}	entry_d->a_id = *((id_t *)qual_p);	return 0;}int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d){	if (*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {		return EINVAL;	}	entry_d->a_perm = *permset_d;	return 0;}/* * sort the ACL and check it for validity * * if it's a minimal ACL with only 4 entries then we * need to recalculate the mask permissions to make * sure that they are the same as the GROUP_OBJ * permissions as required by the UnixWare acl() system call. * * (note: since POSIX allows minimal ACLs which only contain * 3 entries - ie there is no mask entry - we should, in theory, * check for this and add a mask entry if necessary - however * we "know" that the caller of this interface always specifies * a mask so, in practice "this never happens" (tm) - if it *does* * happen aclsort() will fail and return an error and someone will * have to fix it ...) */static int acl_sort(SMB_ACL_T acl_d){	int     fixmask = (acl_d->count <= 4);	if (aclsort(acl_d->count, fixmask, acl_d->acl) != 0) {		errno = EINVAL;		return -1;	}	return 0;} int sys_acl_valid(SMB_ACL_T acl_d){	return acl_sort(acl_d);}int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d){	struct stat	s;	struct acl	*acl_p;	int		acl_count;	struct acl	*acl_buf	= NULL;	int		ret;	if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {		errno = EINVAL;		return -1;	}	if (acl_sort(acl_d) != 0) {		return -1;	}	acl_p		= &acl_d->acl[0];	acl_count	= acl_d->count;	/*	 * if it's a directory there is extra work to do	 * since the acl() system call will replace both	 * the access ACLs and the default ACLs (if any)	 */	if (stat(name, &s) != 0) {		return -1;	}	if (S_ISDIR(s.st_mode)) {		SMB_ACL_T	acc_acl;		SMB_ACL_T	def_acl;		SMB_ACL_T	tmp_acl;		int		i;		if (type == SMB_ACL_TYPE_ACCESS) {			acc_acl = acl_d;			def_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_DEFAULT);		} else {			def_acl = acl_d;			acc_acl = tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_ACCESS);		}		if (tmp_acl == NULL) {			return -1;		}		/*		 * allocate a temporary buffer for the complete ACL		 */		acl_count = acc_acl->count + def_acl->count;		acl_p = acl_buf = SMB_MALLOC_ARRAY(struct acl, acl_count);		if (acl_buf == NULL) {			sys_acl_free_acl(tmp_acl);			errno = ENOMEM;			return -1;		}		/*		 * copy the access control and default entries into the buffer		 */		memcpy(&acl_buf[0], &acc_acl->acl[0],			acc_acl->count * sizeof(acl_buf[0]));		memcpy(&acl_buf[acc_acl->count], &def_acl->acl[0],			def_acl->count * sizeof(acl_buf[0]));		/*		 * set the ACL_DEFAULT flag on the default entries		 */		for (i = acc_acl->count; i < acl_count; i++) {			acl_buf[i].a_type |= ACL_DEFAULT;		}		sys_acl_free_acl(tmp_acl);	} else if (type != SMB_ACL_TYPE_ACCESS) {		errno = EINVAL;		return -1;	}	ret = acl(name, SETACL, acl_count, acl_p);	SAFE_FREE(acl_buf);	return ret;}int sys_acl_set_fd(int fd, SMB_ACL_T acl_d){	if (acl_sort(acl_d) != 0) {		return -1;	}	return facl(fd, SETACL, acl_d->count, &acl_d->acl[0]);}int sys_acl_delete_def_file(const char *path){	SMB_ACL_T	acl_d;	int		ret;	/*	 * fetching the access ACL and rewriting it has	 * the effect of deleting the default ACL	 */	if ((acl_d = sys_acl_get_file(path, SMB_ACL_TYPE_ACCESS)) == NULL) {		return -1;	}	ret = acl(path, SETACL, acl_d->count, acl_d->acl);	sys_acl_free_acl(acl_d);		return ret;}int sys_acl_free_text(char *text){	SAFE_FREE(text);	return 0;}int sys_acl_free_acl(SMB_ACL_T acl_d) {	SAFE_FREE(acl_d);	return 0;}int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype){	return 0;}#elif defined(HAVE_HPUX_ACLS)#include <dl.h>/* * Based on the Solaris/SCO code - with modifications. *//* * Note that while this code implements sufficient functionality * to support the sys_acl_* interfaces it does not provide all * of the semantics of the POSIX ACL interfaces. * * In particular, an ACL entry descriptor (SMB_ACL_ENTRY_T) returned * from a call to sys_acl_get_entry() should not be assumed to be * valid after calling any of the following functions, which may * reorder the entries in the ACL. * *	sys_acl_valid() *	sys_acl_set_file() *	sys_acl_set_fd() *//* This checks if the POSIX ACL system call is defined *//* which basically corresponds to whether JFS 3.3 or   *//* higher is installed. If acl() was called when it    *//* isn't defined, it causes the process to core dump   *//* so it is important to check this and avoid acl()    *//* calls if it isn't there.                            */static BOOL hpux_acl_call_presence(void){	shl_t handle = NULL;	void *value;	int ret_val=0;	static BOOL already_checked=0;	if(already_checked)		return True;	ret_val = shl_findsym(&handle, "acl", TYPE_PROCEDURE, &value);	if(ret_val != 0) {		DEBUG(5, ("hpux_acl_call_presence: shl_findsym() returned %d, errno = %d, error %s\n",			ret_val, errno, strerror(errno)));		DEBUG(5,("hpux_acl_call_presence: acl() system call is not present. Check if you have JFS 3.3 and above?\n"));		return False;	}	DEBUG(10,("hpux_acl_call_presence: acl() system call is present. We have JFS 3.3 or above \n"));	already_checked = True;	return True;}int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p){	if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {		errno = EINVAL;		return -1;	}	if (entry_p == NULL) {		errno = EINVAL;		return -1;	}	if (entry_id == SMB_ACL_FIRST_ENTRY) {		acl_d->next = 0;	}	if (acl_d->next < 0) {		errno = EINVAL;		return -1;	}	if (acl_d->next >= acl_d->count) {		return 0;	}	*entry_p = &acl_d->acl[acl_d->next++];	return 1;}int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p){	*type_p = entry_d->a_type;	return 0;}int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p){	*permset_p = &entry_d->a_perm;	return 0;}void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d){	if (entry_d->a_type != SMB_ACL_USER	    && entry_d->a_type != SMB_ACL_GROUP) {		errno = EINVAL;		return NULL;	}	return &entry_d->a_id;}/* * There is no way of knowing what size the ACL returned by * ACL_GET will be unless you first call ACL_CNT which means * making an additional system call. * * In the hope of avoiding the cost of the additional system * call in most cases, we initially allocate enough space for * an ACL with INITIAL_ACL_SIZE entries. If this turns out to * be too small then we use ACL_CNT to find out the actual * size, reallocate the ACL buffer, and then call ACL_GET again. */#define	INITIAL_ACL_SIZE	16SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type){	SMB_ACL_T	acl_d;	int		count;		/* # of ACL entries allocated	*/	int		naccess;	/* # of access ACL entries	*/	int		ndefault;	/* # of default ACL entries	*/	if(hpux_acl_call_presence() == False) {		/* Looks like we don't have the acl() system call on HPUX. 		 * May be the system doesn't have the latest version of JFS.		 */		return NULL; 	}	if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {		errno = EINVAL;		return NULL;	}	count = INITIAL_ACL_SIZE;	if ((acl_d = sys_acl_init(count)) == NULL) {		return NULL;	}	/*	 * If there isn't enough space for the ACL entries we use	 * ACL_CNT to determine the actual number of ACL entries	 * reallocate and try again. This is in a loop because it	 * is possible that someone else could modify the ACL and	 * increase the number of entries between the call to	 * ACL_CNT and the call to ACL_GET.	 */	while ((count = acl(path_p, ACL_GET, count, &acl_d->acl[0])) < 0 && errno == ENOSPC) {		sys_acl_free_acl(acl_d);		if ((count = acl(path_p, ACL_CNT, 0, NULL)) < 0) {			return NULL;		}

⌨️ 快捷键说明

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