int str_to_double(const char *string, double *number, const int base) { char *str; *number = 0; if ( string == NULL || *string == '\0' ) { errno = EINVAL; return 0; } str = strdup(string); if (str == NULL) return 0; str_trim_space(str); if (!str_to_double_strict(str, number, base)) { free(str); return 0; } free(str); return 1; }
/** * Check whether user is in list. The list is a string of * users/groups that separate by ','. The group name has * prefix @. * * For example szList = "user1, user2, user3, @group1, @group2..." * * We will get each user in the list and check when the user name * is the same. When we get group, we will check whether user * belongs to the group. * * @param user User name to check * @param list The string that contains users and groups separated by ",". * * @return 1: Yes, the user is in the list * 0: No, the user is not in the list */ int is_user_in_list(const char *user, const char *list) { char *tmplist = NULL, *token; int err = 0; if (!user || !list) { return err; } tmplist = (char *)malloc(strlen(list) + 1); if (tmplist == NULL) { syslog(LOG_ERR, "%s (%d) failed to allocate memory, errno:%d(%s)", __FILE__, __LINE__, errno, strerror(errno)); return err; } strcpy(tmplist, list); for (token = strtok(tmplist, ","); token; token = strtok(NULL, ",")) { str_trim_space(token); if (*token != '@') { //user if (0 == strcmp(user, token)) { err = 1; break; } } else { if (1 == smbftpd_auth_is_user_in_group(user, token+1)) { err = 1; goto Error; } } } Error: if (tmplist != NULL) { free(tmplist); } return err; }
/** * This function will read the configuration in given smbftpd_share.conf * * It will allocate memory for smb_shares to store share * information. So smbftpd_share_free() must be call to free it. * * @param path * @param smb_shares * * @return 0: Success * -1: Failed */ int smbftpd_share_enum(char *path, smbftpd_share_t **smb_shares) { smbftpd_share_t *prev, *cur; FILE *fp = NULL; char line[LINE_MAX], *ptr1, *ptr2; int err = -1; if (NULL == path) { syslog(LOG_ERR, "%s (%d) bad parameter", __FILE__, __LINE__); return -1; } fp = fopen(path, "r"); if (NULL == fp) { syslog(LOG_ERR, "%s (%d) Failed to open share config [%s], errno:%d (%s)", __FILE__, __LINE__, path, errno, strerror(errno)); goto Error; } while (NULL != fgets(line, sizeof(line), fp)) { // Skip spaces ptr1 = str_trim_space(line); if ((*ptr1 == '#') || (*ptr1 == '\0') || (*ptr1 == '\n')){ continue; } else if (*ptr1 == '[') { ptr1++; ptr2 = strchr(ptr1, ']'); if ((ptr2 != NULL) && (ptr2 - ptr1 > 0)) { smbftpd_share_t *p; *ptr2 = '\0'; str_trim_space(ptr1); p = calloc(1, sizeof(smbftpd_share_t)); if (p == NULL) { syslog(LOG_ERR, "%s (%d) Out of memory", __FILE__, __LINE__); goto Error; } p->share = strdup(ptr1); if (!p->share) { syslog(LOG_ERR, "%s (%d) Out of memory", __FILE__, __LINE__); free(p); goto Error; } p->browseable = 1; p->next = *smb_shares; *smb_shares = p; } } else { if (!*smb_shares) { /* We have not gotten a section */ continue; } ptr2 = strchr(ptr1, '='); if (NULL == ptr2) { continue; } *ptr2 = '\0'; ptr2++; str_trim_space_quote(ptr1); str_trim_space_quote(ptr2); if (strcmp(ptr1, "rw") == 0) { (*smb_shares)->rw = strdup(ptr2); if (!(*smb_shares)->rw) { syslog(LOG_ERR, "%s (%d) Out of memory", __FILE__, __LINE__); goto Error; } } else if (strcmp(ptr1, "ro") == 0) { (*smb_shares)->ro = strdup(ptr2); if (!(*smb_shares)->ro) { syslog(LOG_ERR, "%s (%d) Out of memory", __FILE__, __LINE__); goto Error; } } else if (strcmp(ptr1, "disable_download") == 0) { (*smb_shares)->disable_download = strdup(ptr2); if (!(*smb_shares)->disable_download) { syslog(LOG_ERR, "%s (%d) Out of memory", __FILE__, __LINE__); goto Error; } } else if (strcmp(ptr1, "disable_ls") == 0) { (*smb_shares)->disable_ls = strdup(ptr2); if (!(*smb_shares)->disable_ls) { syslog(LOG_ERR, "%s (%d) Out of memory", __FILE__, __LINE__); goto Error; } } else if (strcmp(ptr1, "disable_modify") == 0) { (*smb_shares)->disable_modify = strdup(ptr2); if (!(*smb_shares)->disable_modify) { syslog(LOG_ERR, "%s (%d) Out of memory", __FILE__, __LINE__); goto Error; } } else if (strcmp(ptr1, "path") == 0) { char *ptr = real_full_path(ptr2); if (!ptr) { syslog(LOG_ERR, "%s (%d) path \"%s\" does not exist.", __FILE__, __LINE__, ptr2); } else { (*smb_shares)->path = strdup(ptr); if (!(*smb_shares)->path) { syslog(LOG_ERR, "%s (%d) Out of memory", __FILE__, __LINE__); goto Error; } } } else if (strcmp(ptr1, "browseable") == 0) { if (strcasecmp(ptr2, "no") == 0) { (*smb_shares)->browseable = 0; } } } } // Remove shares that have no path beside homes prev = cur = *smb_shares; while (cur) { if ((strcmp(cur->share, "homes") != 0) && !cur->path) { if (prev == cur) { /* Head */ *smb_shares = cur->next; cur->next = NULL; smbftpd_share_free(&cur); prev = cur = *smb_shares; } else { prev->next = cur->next; cur->next = NULL; smbftpd_share_free(&cur); cur = prev->next; } } else { prev = cur; cur = cur->next; } } err = 0; Error: if (fp) { fclose(fp); } if (err) { if (*smb_shares != NULL) { smbftpd_share_free(smb_shares); } return -1; } else { return 0; } }
/** * Get user from path. The file format is: * * user:group:home:password * * @param path The path of smbftpd text user config file * @param user The user name to get * @param smbftpd_user * Result of the suer's data * * @return 0: Success * -1: Failed */ int smbftpd_text_user_get(const char *path, const char *user, smbftpd_text_user_t *smbftpd_user) { FILE *fp = NULL; char buf[LINE_MAX]; char *h, *t; int line = 0, error = -1; if (!path || !user || !smbftpd_user) { return -1; } bzero(smbftpd_user, sizeof(smbftpd_text_user_t)); fp = fopen(path, "r"); if (!fp) { syslog(LOG_ERR, "%s (%d) Failed to open %s. (%s)", __FILE__, __LINE__, path, strerror(errno)); return -1; } while (fgets(buf, sizeof(buf), fp)) { line++; str_trim_space(buf); if (*buf == 0 || *buf=='#') { continue; } // User h = buf; t = strchr(h, ':'); if (!t) { syslog(LOG_ERR, "%s (%d) Skip invalid line %d", __FILE__, __LINE__, line); continue; } *t = 0; str_trim_space(h); if (strcmp(user, h) != 0) { continue; } smbftpd_user->user = strdup(h); if (!smbftpd_user->user) { syslog(LOG_ERR, "%s (%d) Out of memory.", __FILE__, __LINE__); goto Error; } // group h = t+1; t = strchr(h, ':'); if (!t) { syslog(LOG_ERR, "%s (%d) Skip invalid line %d", __FILE__, __LINE__, line); smbftpd_text_user_free(smbftpd_user); continue; } *t = 0; str_trim_space(h); smbftpd_user->group = strdup(h); if (!smbftpd_user->group) { syslog(LOG_ERR, "%s (%d) Out of memory.", __FILE__, __LINE__); goto Error; } // home h = t+1; t = strchr(h, ':'); if (!t) { syslog(LOG_ERR, "%s (%d) Skip invalid line %d", __FILE__, __LINE__, line); smbftpd_text_user_free(smbftpd_user); continue; } *t = 0; str_trim_space(h); smbftpd_user->home = strdup(h); if (!smbftpd_user->home) { syslog(LOG_ERR, "%s (%d) Out of memory.", __FILE__, __LINE__); goto Error; } // password h = t+1; str_trim_space(h); smbftpd_user->password = strdup(h); if (!smbftpd_user->password) { syslog(LOG_ERR, "%s (%d) Out of memory.", __FILE__, __LINE__); goto Error; } break; } if (ferror(fp)) { syslog(LOG_ERR, "%s (%d) Failed to read %s. (%s)", __FILE__, __LINE__, path, strerror(errno)); goto Error; } if (!smbftpd_user->password || !smbftpd_user->password || !smbftpd_user->password || !smbftpd_user->password) { goto Error; } error = 0; Error: if (error != 0) { smbftpd_text_user_free(smbftpd_user); } if (fp) { fclose(fp); } return error; }