Exemplo n.º 1
0
/**
 * Wrapper for the smbc_getxattr() smbclient function. From libsmbclient.h
 * @author [email protected], [email protected]
 *
 * @param uri			The smb url of the file or directory to get extended
 *                  attributes for.
 *
 * @param name      The name of an attribute to be retrieved.  Names are of
 *                  one of the following forms:
 *
 *                     system.nt_sec_desc.<attribute name>
 *                     system.nt_sec_desc.*
 *                     system.nt_sec_desc.*+
 */
static PyObject *
Context_getxattr (Context *self, PyObject *args)
{
  int ret;
  char *uri = NULL;
  char *name = NULL;
  char *buffer = NULL;
  static smbc_getxattr_fn fn;

  // smbc_getxattr takes two string parameters
  if (!PyArg_ParseTuple (args, "ss", &uri, &name))
    {
      return NULL;
    }

  /* The security descriptor string returned by this call will vary depending on the requested attribute
   * A call with system.nt_sec_desc.* will return the longest string which would be in the following format:
   *
   * REVISION:<revision number>,OWNER:<sid>,GROUP:<sid>,ACL:<sid>:<type>/<flags>/<mask>
   *
   * There could be multiple ACL entries up to a reasonable maximum of 1820.
   *
   * <revision number> : 3 chars
   * <sid> :  184 chars
   * <type>:  1 char
   * <flags>: 3 chars
   * <mask>:  10 chars
   *
   * The maximum size of the security descriptor string returned can be
   * derived as follows (includes space for terminating null):
   * Sec Desc = 13 + 2 x (7 + <sid>) + 1820 * (5 + <acl>) = 375315
   *
   * References: https://msdn.microsoft.com/en-us/library/cc246018.aspx
   *             https://technet.microsoft.com/en-us/library/cc961995.aspx
   *             https://technet.microsoft.com/en-us/library/cc961986.aspx
   */

  size_t size = 375315;
  buffer = (char *)malloc (size);
  if(!buffer)
    return PyErr_NoMemory ();

  bzero(buffer, size);

  errno = 0;
  fn = smbc_getFunctionGetxattr(self->context);
  ret = (*fn)(self->context, uri, name, buffer, size);

  if (ret < 0)
    {
      pysmbc_SetFromErrno ();
      free(buffer);
      return NULL;
    }

  PyObject *value = PyUnicode_FromString(buffer);
  free(buffer);

  return value;
}
Exemplo n.º 2
0
int
smbc_lgetxattr(const char *fname,
               const char *name,
               const void *value,
               size_t size)
{
        return smbc_getFunctionGetxattr(statcont)(statcont,
                                                  fname, name,
                                                  value, size);
}
Exemplo n.º 3
0
int
smbc_fgetxattr(int fd,
               const char *name,
               const void *value,
               size_t size)
{
	SMBCFILE * file = find_fd(fd);
	if (file == NULL) {
		errno = EBADF;
		return -1;
	}
        return smbc_getFunctionGetxattr(statcont)(statcont,
                                                  file->fname, name,
                                                  value, size);
}
Exemplo n.º 4
0
static smbresultlist* browse(SMBCCTX *ctx, char *path, int maxdepth, int depth) { 
	SMBCFILE                *fd;
	struct smbc_dirent      *dirent;

	char                    fullpath[2560] = "";

	char                    acl[1024] = "";
	int                     aclret;

	char			mode[128] = "";
	int			moderet;

	smbresultlist           *thisresults = NULL;
	smbresultlist           *subresults = NULL;


	//Try and get a directory listing of the object we just opened.
	//This could be a workgroup, server, share, or directory and
	//we'll get the full listing.  If it doesn't work, return our error.
	//Errors will happen a lot in normal usage due to access denied.
	if ((fd = smbc_getFunctionOpendir(ctx)(ctx, path)) == NULL) {
		smbresult *tmp = createSMBResultEmpty();
		parse_smburl(path, &tmp->host, &tmp->share, &tmp->object);
		tmp->statuscode = errno;
		smbresultlist_push(&thisresults, tmp);
		return thisresults;
	}

	//Get the current entity of the directory item we're working on.
	while ((dirent = smbc_getFunctionReaddir(ctx)(ctx, fd)) != NULL) {
		smbresult *thisresult = createSMBResultEmpty();

		//Check to see if what we're working on is blank, or one of the 
		//special directory characters. If so, skip them.
		if(strcmp(dirent->name, "") == 0) continue;
		if(strcmp(dirent->name, ".") == 0) continue;
		if(strcmp(dirent->name, "..") == 0) continue;

		//Create the full path for this object by concating it with the 
		//parent path.
		sprintf(fullpath, "%s/%s", path, dirent->name);

		//Parse out the various parts of the path for pretty output.
		parse_smburl(fullpath, &thisresult->host, &thisresult->share, &thisresult->object);

		//Set the type so we have it
		thisresult->type = dirent->smbc_type;

		//Get the "dos_attr.mode" extended attribute which is the file permissions.
		moderet = smbc_getFunctionGetxattr(ctx)(ctx, fullpath, "system.dos_attr.mode", &mode, sizeof(mode));
		if(moderet == -1 && errno == 13) {
			thisresult->mode = -1;
		} else {
			//The ACL is returned as a string pointer, but we need to convert it to a long so we can 
			//do binary comparison on the settings eventually.
			thisresult->mode = strtol(acl, NULL, 16);
		}

		//Get the ACL ACEs for the NTFS permissions.  The + is so we lookup SIDs to names
		aclret = smbc_getFunctionGetxattr(ctx)(ctx, fullpath, "system.nt_sec_desc.acl.*+", acl, sizeof(acl));
		if(aclret < 0) {
			char permerrbuf[100];
			sprintf(permerrbuf, "Unable to pull permissions (%d): %s", errno, strerror(errno));
			thisresult->acl = strdup(permerrbuf);
			thisresult->statuscode = errno;
		} else {
			thisresult->acl = strdup(acl);
		}

		smbresultlist_push(&thisresults, thisresult);

		//If we have a directory or share we want to recurse to our max depth
		if(depth < maxdepth) {
			switch (thisresult->type) {
				case SMBC_FILE_SHARE:
				case SMBC_DIR:
					subresults = browse(ctx, fullpath, maxdepth, depth++);
					smbresultlist_merge(&thisresults, &subresults);
			}
		}
	}


	//Try to close the directory that we had opened.  If it failed, it'll return > 0.
	if(smbc_getFunctionClosedir(ctx)(ctx, fd) > 0) {
		smbresult *tmp = createSMBResultEmpty();
		parse_smburl(path, &tmp->host, &tmp->share, &tmp->object);
		tmp->statuscode = errno;
		smbresultlist_push(&thisresults, tmp);
	}

	//Finally, we're done, lets return to the user. 
	return thisresults;
}