#include "includes.h" extern int DEBUGLEVEL; dfs_internal dfs_struct; extern pstring global_myname; /**************************************************************************** read a line and split it ****************************************************************************/ static BOOL parse_dfs_text_entry(char *line, dfs_internal_table *buf) { #define MAXTOK 4 char *tok[MAXTOK+1]; int count = 0; tok[count] = strtok(line,":"); /* strip the comment lines */ if (tok[0][0] == '#') return (False); count++; while ( ((tok[count] = strtok(NULL,":")) != NULL ) && count < MAXTOK) { count++; } DEBUG(7,("Found [%d] tokens\n", count)); if (count > 1) { StrnCpy(buf->localpath, tok[0], sizeof(buf->localpath)-1); StrnCpy(buf->sharename, tok[1], sizeof(buf->sharename)-1); /* strupper(buf->localpath); strupper(buf->sharename); */ buf->localpath_length = strlen(buf->localpath); buf->sharename_length = strlen(buf->sharename); } else return (False); if (count > 2) buf->proximity = atoi(tok[2]); else buf->proximity = 0; if (count > 3) buf->type = atoi(tok[3]); else buf->type = 2; DEBUGADD(7,("localpath: [%s]\n", buf->localpath)); DEBUGADD(7,("sharename: [%s]\n", buf->sharename)); return True; } /**************************************************************************** mangle the localpath and store it. ****************************************************************************/ static void mangle_dfs_path(dfs_internal_table *buf) { char *p; char *mp; char *q; int mlen; fstring temp; p = buf->localpath; mp = buf->mangledpath; mlen = sizeof(buf->mangledpath); ZERO_STRUCTP(mp); DEBUG(2, ("DFS name is: [%s]\n", buf->localpath)); /* copy the head: \server-name\ */ q = strchr(p + 1, '\\'); safe_strcpy(mp, p, mlen); p = q + 1; while (q != NULL) { q = strchr(p, '\\'); safe_strcpy(temp, p, sizeof(temp)); if (!is_8_3(temp, True)) { mangle_name_83(temp); } safe_strcat(mp, temp, mlen); if (q != NULL) { safe_strcat(mp, "\\", mlen); } p = q + 1; } /* strupper(mp); */ buf->mangledpath_length = strlen(mp); DEBUGADD(2, ("DFS mangled name is: [%s]\n", mp)); } /**************************************************************************** initialisation de la table dfs en memoire au demarrage de samba ****************************************************************************/ BOOL init_dfs_table(void) { char *file = lp_dfs_map(); int num_lines = 0; int total = 0; FILE *f; pstring line; int i; dfs_internal_table *entry; entry = NULL; dfs_struct.ready = False; if (*file == '\0') { DEBUG(0,("No DFS map, Samba is running in NON DFS mode\n")); return False; } f = sys_fopen(file, "r"); if (!f) { DEBUG(0,("No DFS map file, Samba is running in NON DFS mode\n")); return False; } while ( fgets(line, sizeof(pstring), f) ) { entry = Realloc(entry,sizeof(dfs_internal_table)*(total+1)); if (! entry) { total = 0; break; } if ( parse_dfs_text_entry(line, &(entry[total]) ) ) { total++; } num_lines++; } dfs_struct.size = total; dfs_struct.table = entry; fclose(f); /* we have the file in memory */ /* now initialise the mangled names */ for (i = 0; i < total; i++) { mangle_dfs_path(&(entry[i])); } dfs_struct.ready = True; DEBUG(0,("Samba is DFS aware now!\n")); return True; } static BOOL check_dfs_path(int search_len, const char *search_path, int path_len, const char* fullpath, const char* sharename, const char* share_path, size_t share_len, char *localpath, size_t local_plen) { if (StrnCaseCmp(search_path, fullpath, search_len) != 0) { return False; } DEBUG(2,("found one linked to [%s]. share_path: %s\n", sharename, share_path)); if (StrnCaseCmp(fullpath, share_path, share_len) == 0) { safe_strcpy(localpath, fullpath + share_len, local_plen); } else { localpath[0] = 0; } return True; } /**************************************************************************** check if a path name is a DFS branch ****************************************************************************/ int under_dfs(connection_struct *conn, const char *path, char *local_path, size_t local_plen) { fstring fullpath; pstring share_path; int i; int snum; int path_len; int share_len; dfs_internal_table *list = dfs_struct.table; snum = SNUM(conn); snprintf(share_path, sizeof(share_path), "\\%s\\%s", global_myname, lp_servicename(snum)); share_len = strlen(share_path); if (path[0] != '\\') { snprintf(fullpath, sizeof(fullpath), "%s\\%s", share_path, path); } else { safe_strcpy(fullpath, path, sizeof(fullpath)); } path_len = strlen(fullpath); DEBUG(2,("DFS looking for: [%s]\n", fullpath)); for (i = 0; i < dfs_struct.size; i++) { DEBUG(6,("checking against [%s][%d]\n", list[i].localpath,i)); if (check_dfs_path(list[i].localpath_length, list[i].localpath, path_len, fullpath, list[i].sharename, share_path, share_len, local_path, local_plen)) { return True; } if (check_dfs_path(list[i].mangledpath_length, list[i].mangledpath, path_len, fullpath, list[i].sharename, share_path, share_len, local_path, local_plen)) { return True; } } return False; }