2222#include <string.h>
2323#include <sys/stat.h>
2424
25+ #include "alloc-util.h"
2526#include "fs-util.h"
2627#include "macro.h"
2728#include "mkdir.h"
2829#include "path-util.h"
2930#include "stat-util.h"
3031#include "user-util.h"
3132
32- int mkdir_safe_internal (const char * path , mode_t mode , uid_t uid , gid_t gid , mkdir_func_t _mkdir ) {
33+ int mkdir_safe_internal (const char * path , mode_t mode , uid_t uid , gid_t gid , bool follow_symlink , mkdir_func_t _mkdir ) {
3334 struct stat st ;
3435 int r ;
3536
@@ -42,6 +43,19 @@ int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, mkd
4243 if (lstat (path , & st ) < 0 )
4344 return - errno ;
4445
46+ if (follow_symlink && S_ISLNK (st .st_mode )) {
47+ _cleanup_free_ char * p = NULL ;
48+
49+ r = chase_symlinks (path , NULL , CHASE_NONEXISTENT , & p );
50+ if (r < 0 )
51+ return r ;
52+ if (r == 0 )
53+ return mkdir_safe_internal (p , mode , uid , gid , false, _mkdir );
54+
55+ if (lstat (p , & st ) < 0 )
56+ return - errno ;
57+ }
58+
4559 if ((st .st_mode & 0007 ) > (mode & 0007 ) ||
4660 (st .st_mode & 0070 ) > (mode & 0070 ) ||
4761 (st .st_mode & 0700 ) > (mode & 0700 ) ||
@@ -53,8 +67,8 @@ int mkdir_safe_internal(const char *path, mode_t mode, uid_t uid, gid_t gid, mkd
5367 return 0 ;
5468}
5569
56- int mkdir_safe (const char * path , mode_t mode , uid_t uid , gid_t gid ) {
57- return mkdir_safe_internal (path , mode , uid , gid , mkdir );
70+ int mkdir_safe (const char * path , mode_t mode , uid_t uid , gid_t gid , bool follow_symlink ) {
71+ return mkdir_safe_internal (path , mode , uid , gid , follow_symlink , mkdir );
5872}
5973
6074int mkdir_parents_internal (const char * prefix , const char * path , mode_t mode , mkdir_func_t _mkdir ) {
0 commit comments