On Sat, 8 Oct 2011 15:39:45 -0500
[email protected] wrote:
> From: Shirish Pargaonkar <[email protected]>
>
>
> Add mount options backupuid and backugid and their manpage contents.
> Check for either a valid uid/gid or valid user/group name.
>
>
> Signed-off-by: Shirish Pargaonkar <[email protected]>
> ---
> mount.cifs.8 | 40 ++++++++++++++++++++++++++++
> mount.cifs.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 120 insertions(+), 2 deletions(-)
>
> diff --git a/mount.cifs.8 b/mount.cifs.8
> index 81ebdbe..9391294 100644
> --- a/mount.cifs.8
> +++ b/mount.cifs.8
> @@ -282,6 +282,20 @@ See sections on
> for more information\&.
> .RE
> .PP
> +backupuid
> +.RS 4
> +Restrict access to files, with the backup intent, to a user\&.
> +.sp
> +See section \fIACCESSING FILES WITH BACKUP INTENT\fR for more details
> +.RE
> +.PP
> +backupgid
> +.RS 4
> +Restrict Allow access to files, with the backup intent, to a group\&.
> +.sp
> +See section \fIACCESSING FILES WITH BACKUP INTENT\fR for more details
> +.RE
> +.PP
> nocase
> .RS 4
> Request case insensitive path name matching (case sensitive is the default
> if the server suports it)\&.
> @@ -590,6 +604,32 @@ The mapping between a CIFS/NTFS ACL and POSIX file
> permission bits is imperfect
> .\}
> If either upcall to cifs.idmap is not setup correctly or winbind is not
> configured and running, ID mapping will fail. In that case uid and gid will
> default to either to those values of the share or to the values of uid and/or
> gid mount options if specified.
> .RE
> +.SH "ACCESSING FILES WITH BACKUP INTENT"
> +.PP
> +For an user on the server, desired access to a file is determined by the
> permissions and rights associated with that file. This is typically
> accomplished using owenrship and ACL. For a user who does not have access
> rights to a file, it is still possible to access that file for a specific or
> a targeted purpose by granting special rights. One of the specific purposes
> is to access a file with the intent to either backup or restore i.e. backup
> intent. The right to access a file with the backup intent can typically be
> granted by making that user a part of the built-in group Backup Operators.
> Thus, when this user attempts to open a file with the backup intent, open
> request is sent by setting the bit FILE_OPEN_FOR_BACKUP_INTENT as one of the
> CreateOptions.
> +
> +As an example, on a Windows server, a user named testuser, cannot open this
> file with such a security descriptor.
> +.PP
> +REVISION:0x1
> +.sp 0
> +CONTROL:0x9404
> +.sp 0
> +OWNER:Administrator
> +.sp 0
> +GROUP:Domain Users
> +.sp 0
> +ACL:Administrator:ALLOWED/0x0/FULL
> +.PP
> +But the user testuser, if it becomes part of the group Backup Operators, can
> open the file with the backup intent.
> +
> +Any user on the client side who can authenticate as such a user on the
> server,
> +can access the files with the backup intent. But it is desirable and
> preferable for security reasons amongst many, to restrict this special right.
> +
> +The mount option backupuid is used to restrict this special right to a user
> which is specified by either a name or an id.
> +.sp 0
> +The mount option backupgid is used to restrict this special right to the
> users in a group which is specified by either a name or an id.
> +.sp 0
> +These two mount options can be used together.
> .SH "FILE AND DIRECTORY OWNERSHIP AND PERMISSIONS"
> .PP
> The core CIFS protocol does not provide unix ownership information or mode
> for files and directories\&. Because of this, files and directories will
> generally appear to be owned by whatever values the uid= or gid= options are
> set, and will have permissions set to the default file_mode and dir_mode for
> the mount\&. Attempting to change these values via chmod/chown will return
> success but have no effect\&.
> diff --git a/mount.cifs.c b/mount.cifs.c
> index 1e3d534..d6cb755 100644
> --- a/mount.cifs.c
> +++ b/mount.cifs.c
> @@ -158,6 +158,8 @@
> #define OPT_MAND 27
> #define OPT_NOMAND 28
> #define OPT_CRUID 29
> +#define OPT_BKUPUID 30
> +#define OPT_BKUPGID 31
>
>
> /* struct for holding parsed mount info for use by privleged process */
> @@ -843,6 +845,10 @@ static int parse_opt_token(const char *token)
> return OPT_REMOUNT;
> if (strncmp(token, "_netdev", 7) == 0)
> return OPT_IGNORE;
> + if (strncmp(token, "backupuid", 9) == 0)
> + return OPT_BKUPUID;
> + if (strncmp(token, "backupgid", 9) == 0)
> + return OPT_BKUPGID;
>
> return OPT_ERROR;
> }
> @@ -858,11 +864,13 @@ parse_options(const char *data, struct
> parsed_mount_info *parsed_info)
> int out_len = 0;
> int word_len;
> int rc = 0;
> + int got_bkupuid = 0;
> + int got_bkupgid = 0;
> int got_uid = 0;
> int got_cruid = 0;
> int got_gid = 0;
> - uid_t uid, cruid = 0;
> - gid_t gid;
> + uid_t uid, cruid = 0, bkupuid;
> + gid_t gid, bkupgid;
> char *ep;
> struct passwd *pw;
> struct group *gr;
> @@ -906,6 +914,8 @@ parse_options(const char *data, struct parsed_mount_info
> *parsed_info)
> value = equals + 1;
> }
>
> + ep = NULL;
> +
^^^^
Is this necessary?
> switch(parse_opt_token(data)) {
> case OPT_USERS:
> if (!value || !*value) {
> @@ -1171,6 +1181,42 @@ parse_options(const char *data, struct
> parsed_mount_info *parsed_info)
> break;
> case OPT_IGNORE:
> goto nocopy;
> + case OPT_BKUPUID:
> + if (!value || !*value)
> + goto nocopy;
> +
> + got_bkupuid = 1;
> + bkupuid = strtoul(value, &ep, 10);
> + if (!strlen(ep))
> + goto nocopy;
> +
> + pw = getpwnam(value);
> + if (pw == NULL) {
> + fprintf(stderr,
> + "bad user name \"%s\"\n", value);
> + return EX_USAGE;
> + }
> +
> + bkupuid = pw->pw_uid;
> + goto nocopy;
> + case OPT_BKUPGID:
> + if (!value || !*value)
> + goto nocopy;
> +
> + got_bkupgid = 1;
> + bkupgid = strtoul(value, &ep, 10);
> + if (!strlen(ep))
> + goto nocopy;
> +
> + gr = getgrnam(value);
> + if (gr == NULL) {
> + fprintf(stderr,
> + "bad group name \"%s\"\n", value);
> + return EX_USAGE;
> + }
> +
> + bkupgid = gr->gr_gid;
> + goto nocopy;
> }
>
> /* check size before copying option to buffer */
> @@ -1246,6 +1292,38 @@ nocopy:
> }
> snprintf(out + out_len, word_len + 5, "gid=%s", txtbuf);
> }
> + if (got_bkupuid) {
> + word_len = snprintf(txtbuf, sizeof(txtbuf), "%u", bkupuid);
> +
> + /* comma + "uid=" + terminating NULL == 6 */
^^^^^^^^^^^
comma + "backupuid=" + terminating NULL == 12
> + if (out_len + word_len + 6 > MAX_OPTIONS_LEN) {
And "6" is wrong in the above line. It should be 12...
> + fprintf(stderr, "Options string too long\n");
> + return EX_USAGE;
> + }
> +
> + if (out_len) {
> + strlcat(out, ",", MAX_OPTIONS_LEN);
> + out_len++;
> + }
> + snprintf(out + out_len, word_len + 11, "backupuid=%s", txtbuf);
> + out_len = strlen(out);
> + }
> + if (got_bkupgid) {
> + word_len = snprintf(txtbuf, sizeof(txtbuf), "%u", bkupgid);
> +
> + /* comma + "backkupgid=" + terminating NULL == 6 */
comma + "backupgid=" + terminating NULL == 12
> + if (out_len + word_len + 6 > MAX_OPTIONS_LEN) {
and again, 6 is wrong here -- it should be 12.
> + fprintf(stderr, "Options string too long\n");
> + return EX_USAGE;
> + }
> +
> + if (out_len) {
> + strlcat(out, ",", MAX_OPTIONS_LEN);
> + out_len++;
> + }
> + snprintf(out + out_len, word_len + 11, "backupgid=%s", txtbuf);
> + }
> +
> return 0;
> }
>
--
Jeff Layton <[email protected]>
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html