77
77
#endif
78
78
79
79
80
+ /* Mode flags for unix_rootdir. */
81
+ enum wantdir_values {
82
+ WANTDIR_ROOT = 0 ,
83
+ WANTDIR_SYSCONF ,
84
+ WANTDIR_SOCKET
85
+ };
86
+
87
+
80
88
/* The GnuPG homedir. This is only accessed by the functions
81
89
* gnupg_homedir and gnupg_set_homedir. Malloced. */
82
90
static char * the_gnupg_homedir ;
@@ -491,11 +499,12 @@ w32_rootdir (void)
491
499
* file system. If WANT_SYSCONFDIR is true the optional sysconfdir
492
500
* entry is returned. */
493
501
static const char *
494
- unix_rootdir (int want_sysconfdir )
502
+ unix_rootdir (enum wantdir_values wantdir )
495
503
{
496
504
static int checked ;
497
505
static char * dir ; /* for the rootdir */
498
506
static char * sdir ; /* for the sysconfdir */
507
+ static char * s2dir ; /* for the socketdir */
499
508
500
509
if (!checked )
501
510
{
@@ -510,8 +519,10 @@ unix_rootdir (int want_sysconfdir)
510
519
estream_t fp ;
511
520
char * rootdir ;
512
521
char * sysconfdir ;
522
+ char * socketdir ;
513
523
const char * name ;
514
524
int ignoreall = 0 ;
525
+ int okay ;
515
526
516
527
for (;;)
517
528
{
@@ -602,12 +613,14 @@ unix_rootdir (int want_sysconfdir)
602
613
linelen = 0 ;
603
614
rootdir = NULL ;
604
615
sysconfdir = NULL ;
616
+ socketdir = NULL ;
605
617
while ((length = es_read_line (fp , & line , & linelen , NULL )) > 0 )
606
618
{
607
619
static const char * names [] =
608
620
{
609
621
"rootdir" ,
610
622
"sysconfdir" ,
623
+ "socketdir" ,
611
624
".enable"
612
625
};
613
626
int i ;
@@ -662,6 +675,11 @@ unix_rootdir (int want_sysconfdir)
662
675
xfree (sysconfdir );
663
676
sysconfdir = p ;
664
677
}
678
+ else if (!strcmp (name , "socketdir" ))
679
+ {
680
+ xfree (socketdir );
681
+ socketdir = p ;
682
+ }
665
683
else
666
684
{
667
685
xfree (rootdir );
@@ -677,36 +695,34 @@ unix_rootdir (int want_sysconfdir)
677
695
xfree (line );
678
696
xfree (rootdir );
679
697
xfree (sysconfdir );
698
+ xfree (socketdir );
680
699
checked = 1 ;
681
700
return NULL ;
682
701
}
683
702
es_fclose (fp );
684
703
xfree (buffer );
685
704
xfree (line );
686
705
706
+ okay = 0 ;
687
707
if (ignoreall )
688
- {
689
- xfree (rootdir );
690
- xfree (sysconfdir );
691
- sdir = dir = NULL ;
692
- }
708
+ ;
693
709
else if (!rootdir || !* rootdir || * rootdir != '/' )
694
710
{
695
711
log_info ("invalid rootdir '%s' specified in gpgconf.ctl\n" , rootdir );
696
- xfree (rootdir );
697
- xfree (sysconfdir );
698
- dir = NULL ;
699
712
}
700
713
else if (sysconfdir && (!* sysconfdir || * sysconfdir != '/' ))
701
714
{
702
715
log_info ("invalid sysconfdir '%s' specified in gpgconf.ctl\n" ,
703
716
sysconfdir );
704
- xfree (rootdir );
705
- xfree (sysconfdir );
706
- dir = NULL ;
717
+ }
718
+ else if (socketdir && (!* socketdir || * socketdir != '/' ))
719
+ {
720
+ log_info ("invalid socketdir '%s' specified in gpgconf.ctl\n" ,
721
+ socketdir );
707
722
}
708
723
else
709
724
{
725
+ okay = 1 ;
710
726
while (* rootdir && rootdir [strlen (rootdir )- 1 ] == '/' )
711
727
rootdir [strlen (rootdir )- 1 ] = 0 ;
712
728
dir = rootdir ;
@@ -720,11 +736,34 @@ unix_rootdir (int want_sysconfdir)
720
736
gpgrt_annotate_leaked_object (sdir );
721
737
/* log_info ("want sysconfdir '%s'\n", sdir); */
722
738
}
739
+ if (socketdir )
740
+ {
741
+ while (* socketdir && socketdir [strlen (socketdir )- 1 ] == '/' )
742
+ socketdir [strlen (socketdir )- 1 ] = 0 ;
743
+ s2dir = socketdir ;
744
+ gpgrt_annotate_leaked_object (s2dir );
745
+ /* log_info ("want socketdir '%s'\n", s2dir); */
746
+ }
747
+ }
748
+
749
+ if (!okay )
750
+ {
751
+ xfree (rootdir );
752
+ xfree (sysconfdir );
753
+ xfree (socketdir );
754
+ dir = sdir = s2dir = NULL ;
723
755
}
724
756
checked = 1 ;
725
757
}
726
758
727
- return want_sysconfdir ? sdir : dir ;
759
+ switch (wantdir )
760
+ {
761
+ case WANTDIR_ROOT : return dir ;
762
+ case WANTDIR_SYSCONF : return sdir ;
763
+ case WANTDIR_SOCKET : return s2dir ;
764
+ }
765
+
766
+ return NULL ; /* Not reached. */
728
767
}
729
768
#endif /* Unix */
730
769
@@ -1035,7 +1074,8 @@ _gnupg_socketdir_internal (int skip_checks, unsigned *r_info)
1035
1074
};
1036
1075
int i ;
1037
1076
struct stat sb ;
1038
- char prefix [19 + 1 + 20 + 6 + 1 ];
1077
+ char prefixbuffer [19 + 1 + 20 + 6 + 1 ];
1078
+ const char * prefix ;
1039
1079
const char * s ;
1040
1080
char * name = NULL ;
1041
1081
@@ -1050,35 +1090,42 @@ _gnupg_socketdir_internal (int skip_checks, unsigned *r_info)
1050
1090
* as a background process with no (desktop) user logged in. Thus
1051
1091
* we better don't do that. */
1052
1092
1053
- /* Check whether we have a /run/[gnupg/]user dir. */
1054
- for (i = 0 ; bases [i ]; i ++ )
1055
- {
1056
- snprintf (prefix , sizeof prefix , "%s/user/%u" ,
1057
- bases [i ], (unsigned int )getuid ());
1058
- if (!stat (prefix , & sb ) && S_ISDIR (sb .st_mode ))
1059
- break ;
1060
- }
1061
- if (!bases [i ])
1093
+ prefix = unix_rootdir (WANTDIR_SOCKET );
1094
+ if (!prefix )
1062
1095
{
1063
- * r_info |= 2 ; /* No /run/user directory. */
1064
- goto leave ;
1065
- }
1096
+ /* gpgconf.ctl does not specify a directory. Check whether we
1097
+ * have the usual /run/[gnupg/]user dir. */
1098
+ for (i = 0 ; bases [i ]; i ++ )
1099
+ {
1100
+ snprintf (prefixbuffer , sizeof prefixbuffer , "%s/user/%u" ,
1101
+ bases [i ], (unsigned int )getuid ());
1102
+ prefix = prefixbuffer ;
1103
+ if (!stat (prefix , & sb ) && S_ISDIR (sb .st_mode ))
1104
+ break ;
1105
+ }
1106
+ if (!bases [i ])
1107
+ {
1108
+ * r_info |= 2 ; /* No /run/user directory. */
1109
+ goto leave ;
1110
+ }
1066
1111
1067
- if (sb .st_uid != getuid ())
1068
- {
1069
- * r_info |= 4 ; /* Not owned by the user. */
1070
- if (!skip_checks )
1071
- goto leave ;
1072
- }
1112
+ if (sb .st_uid != getuid ())
1113
+ {
1114
+ * r_info |= 4 ; /* Not owned by the user. */
1115
+ if (!skip_checks )
1116
+ goto leave ;
1117
+ }
1073
1118
1074
- if (strlen (prefix ) + 7 >= sizeof prefix )
1075
- {
1076
- * r_info |= 1 ; /* Ooops: Buffer too short to append "/gnupg". */
1077
- goto leave ;
1119
+ if (strlen (prefix ) + 7 >= sizeof prefixbuffer )
1120
+ {
1121
+ * r_info |= 1 ; /* Ooops: Buffer too short to append "/gnupg". */
1122
+ goto leave ;
1123
+ }
1124
+ strcat (prefixbuffer , "/gnupg" );
1078
1125
}
1079
- strcat (prefix , "/gnupg" );
1080
1126
1081
- /* Check whether the gnupg sub directory has proper permissions. */
1127
+ /* Check whether the gnupg sub directory (or the specified diretory)
1128
+ * has proper permissions. */
1082
1129
if (stat (prefix , & sb ))
1083
1130
{
1084
1131
if (errno != ENOENT )
@@ -1238,7 +1285,7 @@ gnupg_sysconfdir (void)
1238
1285
}
1239
1286
return name ;
1240
1287
#else /*!HAVE_W32_SYSTEM*/
1241
- const char * dir = unix_rootdir (1 );
1288
+ const char * dir = unix_rootdir (WANTDIR_SYSCONF );
1242
1289
if (dir )
1243
1290
return dir ;
1244
1291
else
@@ -1267,7 +1314,7 @@ gnupg_bindir (void)
1267
1314
else
1268
1315
return rdir ;
1269
1316
#else /*!HAVE_W32_SYSTEM*/
1270
- rdir = unix_rootdir (0 );
1317
+ rdir = unix_rootdir (WANTDIR_ROOT );
1271
1318
if (rdir )
1272
1319
{
1273
1320
if (!name )
@@ -1294,7 +1341,7 @@ gnupg_libexecdir (void)
1294
1341
static char * name ;
1295
1342
const char * rdir ;
1296
1343
1297
- rdir = unix_rootdir (0 );
1344
+ rdir = unix_rootdir (WANTDIR_ROOT );
1298
1345
if (rdir )
1299
1346
{
1300
1347
if (!name )
@@ -1324,7 +1371,7 @@ gnupg_libdir (void)
1324
1371
#else /*!HAVE_W32_SYSTEM*/
1325
1372
const char * rdir ;
1326
1373
1327
- rdir = unix_rootdir (0 );
1374
+ rdir = unix_rootdir (WANTDIR_ROOT );
1328
1375
if (rdir )
1329
1376
{
1330
1377
if (!name )
@@ -1355,7 +1402,7 @@ gnupg_datadir (void)
1355
1402
#else /*!HAVE_W32_SYSTEM*/
1356
1403
const char * rdir ;
1357
1404
1358
- rdir = unix_rootdir (0 );
1405
+ rdir = unix_rootdir (WANTDIR_ROOT );
1359
1406
if (rdir )
1360
1407
{
1361
1408
if (!name )
@@ -1387,7 +1434,7 @@ gnupg_localedir (void)
1387
1434
#else /*!HAVE_W32_SYSTEM*/
1388
1435
const char * rdir ;
1389
1436
1390
- rdir = unix_rootdir (0 );
1437
+ rdir = unix_rootdir (WANTDIR_ROOT );
1391
1438
if (rdir )
1392
1439
{
1393
1440
if (!name )
0 commit comments