diff options
-rw-r--r-- | mount.cifs.c | 208 |
1 files changed, 78 insertions, 130 deletions
diff --git a/mount.cifs.c b/mount.cifs.c index c0cc13f..86edae8 100644 --- a/mount.cifs.c +++ b/mount.cifs.c @@ -125,13 +125,14 @@ struct parsed_mount_info { char share[MAX_SHARE_LEN]; char prefix[PATH_MAX]; char options[MAX_OPTIONS_LEN]; + char password[MOUNT_PASSWD_SIZE + 1]; char address_list[MAX_ADDR_LIST_LEN]; + unsigned int got_password:1; }; const char *thisprogram; int verboseflag = 0; int fakemnt = 0; -static int got_password = 0; static int got_user = 0; static int got_domain = 0; static int got_ip = 0; @@ -139,7 +140,6 @@ static int got_unc = 0; static int got_uid = 0; static int got_gid = 0; static char * user_name = NULL; -static char * mountpassword = NULL; char * domain_name = NULL; char * prefixpath = NULL; const char *cifs_fstype = "cifs"; @@ -297,7 +297,7 @@ static char * getusername(void) { return username; } -static int open_cred_file(char * file_name) +static int open_cred_file(char *file_name, struct parsed_mount_info *parsed_info) { char * line_buf; char * temp_val; @@ -364,18 +364,11 @@ static int open_cred_file(char * file_name) } if(length > MOUNT_PASSWD_SIZE) { fprintf(stderr, "mount.cifs failed: password in credentials file too long\n"); - memset(line_buf,0, 4096); + memset(line_buf, 0, 4096); return EX_USAGE; - } else { - if(mountpassword == NULL) { - mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1); - } else - memset(mountpassword,0,MOUNT_PASSWD_SIZE); - if(mountpassword) { - strlcpy(mountpassword,temp_val,MOUNT_PASSWD_SIZE+1); - got_password = 1; - } } + strlcpy(parsed_info->password, temp_val, MOUNT_PASSWD_SIZE + 1); + parsed_info->got_password = 1; } } else if (strncasecmp("domain",line_buf+i,6) == 0) { temp_val = strchr(line_buf+i,'='); @@ -413,22 +406,13 @@ static int open_cred_file(char * file_name) return 0; } -static int get_password_from_file(int file_descript, char * filename) +static int +get_password_from_file(int file_descript, char *filename, struct parsed_mount_info *parsed_info) { int rc = 0; int i; char c; - if(mountpassword == NULL) - mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1); - else - memset(mountpassword, 0, MOUNT_PASSWD_SIZE); - - if (mountpassword == NULL) { - fprintf(stderr, "malloc failed\n"); - return EX_SYSERR; - } - if(filename != NULL) { rc = access(filename, R_OK); if (rc) { @@ -453,24 +437,24 @@ static int get_password_from_file(int file_descript, char * filename) close(file_descript); return EX_SYSERR; } else if(rc == 0) { - if(mountpassword[0] == 0) { + if(parsed_info->password[0] == 0) { if(verboseflag) fprintf(stderr, "\nWarning: null password used since cifs password file empty"); } break; } else /* read valid character */ { if((c == 0) || (c == '\n')) { - mountpassword[i] = '\0'; + parsed_info->password[i] = '\0'; break; } else - mountpassword[i] = c; + parsed_info->password[i] = c; } } if((i == MOUNT_PASSWD_SIZE) && (verboseflag)) { fprintf(stderr, "\nWarning: password longer than %d characters specified in cifs password file", MOUNT_PASSWD_SIZE); } - got_password = 1; + parsed_info->got_password = 1; if(filename != NULL) { close(file_descript); } @@ -549,19 +533,15 @@ parse_options(const char *data, struct parsed_mount_info *parsed_info) percent_char = strchr(value,'%'); if(percent_char) { *percent_char = ','; - if(mountpassword == NULL) - mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1); - if(mountpassword) { - if(got_password) - fprintf(stderr, "\nmount.cifs warning - password specified twice\n"); - got_password = 1; - percent_char++; - strlcpy(mountpassword, percent_char,MOUNT_PASSWD_SIZE+1); + if(parsed_info->got_password) + fprintf(stderr, "\nmount.cifs warning - password specified twice\n"); + parsed_info->got_password = 1; + percent_char++; + strlcpy(parsed_info->password, percent_char, sizeof(parsed_info->password)); /* remove password from username */ - while(*percent_char != 0) { - *percent_char = ','; - percent_char++; - } + while(*percent_char != 0) { + *percent_char = ','; + percent_char++; } } /* this is only case in which the user @@ -578,20 +558,16 @@ parse_options(const char *data, struct parsed_mount_info *parsed_info) } } else if (strncmp(data, "pass", 4) == 0) { if (!value || !*value) { - if(got_password) { + if(parsed_info->got_password) { fprintf(stderr, "\npassword specified twice, ignoring second\n"); } else - got_password = 1; + parsed_info->got_password = 1; } else if (strnlen(value, MOUNT_PASSWD_SIZE) < MOUNT_PASSWD_SIZE) { - if (got_password) { + if (parsed_info->got_password) { fprintf(stderr, "\nmount.cifs warning - password specified twice\n"); } else { - mountpassword = strndup(value, MOUNT_PASSWD_SIZE); - if (!mountpassword) { - fprintf(stderr, "mount.cifs error: %s", strerror(ENOMEM)); - return EX_USAGE; - } - got_password = 1; + strlcpy(parsed_info->password, value, MOUNT_PASSWD_SIZE + 1); + parsed_info->got_password = 1; } } else { fprintf(stderr, "password too long\n"); @@ -602,7 +578,7 @@ parse_options(const char *data, struct parsed_mount_info *parsed_info) if (value) { if (!strncmp(value, "none", 4) || !strncmp(value, "krb5", 4)) - got_password = 1; + parsed_info->got_password = 1; } } else if (strncmp(data, "ip", 2) == 0) { if (!value || !*value) { @@ -662,7 +638,7 @@ parse_options(const char *data, struct parsed_mount_info *parsed_info) } } else if (strncmp(data, "cred", 4) == 0) { if (value && *value) { - rc = open_cred_file(value); + rc = open_cred_file(value, parsed_info); if (rc) { fprintf(stderr, "error %d (%s) opening credential file %s\n", rc, strerror(rc), value); @@ -757,7 +733,7 @@ parse_options(const char *data, struct parsed_mount_info *parsed_info) } else if (strncmp(data, "guest", 5) == 0) { user_name = (char *)calloc(1, 1); got_user = 1; - got_password = 1; + parsed_info->got_password = 1; } else if (strncmp(data, "ro", 2) == 0) { *filesys_flags |= MS_RDONLY; goto nocopy; @@ -829,51 +805,29 @@ nocopy: } /* replace all (one or more) commas with double commas */ -static void check_for_comma(char ** ppasswrd) +static int +replace_commas(char *pass) { - char *new_pass_buf; - char *pass; - int i,j; - int number_of_commas = 0; - int len; - - if(ppasswrd == NULL) - return; - else - (pass = *ppasswrd); - - len = strlen(pass); - - for(i=0;i<len;i++) { - if(pass[i] == ',') - number_of_commas++; - } + /* a little extra buffer to simplify conversion */ + char tmpbuf[MOUNT_PASSWD_SIZE + 3]; + int i = 0, j = 0; - if(number_of_commas == 0) - return; - if(number_of_commas > MOUNT_PASSWD_SIZE) { - /* would otherwise overflow the mount options buffer */ - fprintf(stderr, "\nInvalid password. Password contains too many commas.\n"); - return; - } - - new_pass_buf = (char *)malloc(len+number_of_commas+1); - if(new_pass_buf == NULL) - return; + /* don't do anything if there are no commas */ + if (!strchr(pass, ',')) + return 0; - for(i=0,j=0;i<len;i++,j++) { - new_pass_buf[j] = pass[i]; - if(pass[i] == ',') { - j++; - new_pass_buf[j] = pass[i]; + while (pass[i]) { + if (pass[i] == ',') + tmpbuf[j++] = ','; + tmpbuf[j++] = pass[i++]; + if (j > MOUNT_PASSWD_SIZE + 1) { + fprintf(stderr, "Converted password too long!\n"); + return EX_USAGE; } } - new_pass_buf[len+number_of_commas] = 0; - - SAFE_FREE(*ppasswrd); - *ppasswrd = new_pass_buf; - - return; + tmpbuf[j] = '\0'; + strlcpy(pass, tmpbuf, MOUNT_PASSWD_SIZE + 1); + return 0; } /* Usernames can not have backslash in them and we use @@ -1053,6 +1007,22 @@ parse_server(char **punc_name) return addrlist; } +static int +get_pw_from_env(struct parsed_mount_info *parsed_info) +{ + int rc = 0; + + if (getenv("PASSWD")) { + strlcpy(parsed_info->password, getenv("PASSWD"), MOUNT_PASSWD_SIZE + 1); + parsed_info->got_password = 1; + } else if (getenv("PASSWD_FD")) + rc = get_password_from_file(atoi(getenv("PASSWD_FD")), NULL, parsed_info); + else if (getenv("PASSWD_FILE")) + rc = get_password_from_file(0, getenv("PASSWD_FILE"), parsed_info); + + return rc; +} + static struct option longopts[] = { { "all", 0, NULL, 'a' }, { "help",0, NULL, 'h' }, @@ -1293,15 +1263,11 @@ int main(int argc, char ** argv) got_domain = 1; break; case 'p': - if(mountpassword == NULL) - mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1); - if(mountpassword) { - got_password = 1; - strlcpy(mountpassword,optarg,MOUNT_PASSWD_SIZE+1); - } + strlcpy(parsed_info->password, optarg, sizeof(parsed_info->password)); + parsed_info->got_password = 1; break; case 'S': - rc = get_password_from_file(0 /* stdin */,NULL); + rc = get_password_from_file(0, NULL, parsed_info); if (rc) goto mount_exit; break; @@ -1355,22 +1321,9 @@ int main(int argc, char ** argv) parsed_info->flags |= CIFS_SETUID_FLAGS; } - if (getenv("PASSWD")) { - if(mountpassword == NULL) - mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1); - if(mountpassword) { - strlcpy(mountpassword,getenv("PASSWD"),MOUNT_PASSWD_SIZE+1); - got_password = 1; - } - } else if (getenv("PASSWD_FD")) { - rc = get_password_from_file(atoi(getenv("PASSWD_FD")),NULL); - if (rc) - goto mount_exit; - } else if (getenv("PASSWD_FILE")) { - rc = get_password_from_file(0, getenv("PASSWD_FILE")); - if (rc) - goto mount_exit; - } + rc = get_pw_from_env(parsed_info); + if (rc) + goto mount_exit; options = calloc(options_size, 1); if (!options) { @@ -1442,17 +1395,16 @@ int main(int argc, char ** argv) got_user = 1; } - if(got_password == 0) { + if(!parsed_info->got_password) { char *tmp_pass = getpass("Password: "); /* BB obsolete sys call but no good replacement yet. */ - mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1); - if (!tmp_pass || !mountpassword) { + if (!tmp_pass) { fprintf(stderr, "Password not entered, exiting\n"); rc = EX_USAGE; goto mount_exit; } - strlcpy(mountpassword, tmp_pass, MOUNT_PASSWD_SIZE+1); - got_password = 1; + strlcpy(parsed_info->password, tmp_pass, sizeof(parsed_info->password)); + parsed_info->got_password = 1; } if(!share_name) { @@ -1543,15 +1495,15 @@ mount_retry: if(verboseflag) fprintf(stderr, "\nmount.cifs kernel mount options: %s", options); - if (mountpassword) { + if (parsed_info->got_password) { /* * Commas have to be doubled, or else they will * look like the parameter separator */ if(retry == 0) - check_for_comma(&mountpassword); - strlcat(options,",pass=",options_size); - strlcat(options,mountpassword,options_size); + replace_commas(parsed_info->password); + strlcat(options, ",pass=", options_size); + strlcat(options, parsed_info->password, options_size); if (verboseflag) fprintf(stderr, ",pass=********"); } @@ -1648,14 +1600,10 @@ mount_retry: if (rc) rc = EX_FILEIO; mount_exit: - if(mountpassword) { - int len = strlen(mountpassword); - memset(mountpassword,0,len); - SAFE_FREE(mountpassword); - } - if (addrhead) freeaddrinfo(addrhead); + memset(parsed_info->password, 0, sizeof(parsed_info->password)); + SAFE_FREE(parsed_info); SAFE_FREE(options); SAFE_FREE(orgoptions); SAFE_FREE(resolved_path); |