2
* Copyright (C) 2000-2002, 2004, 2005 Red Hat, Inc.
2
* Copyright (C) 2000-2002, 2004, 2005, 2006 Red Hat, Inc.
4
4
* This is free software; you can redistribute it and/or modify it under
5
5
* the terms of the GNU Library General Public License as published by
16
16
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
#ident "$Id: files.c,v 1.80 2005/09/12 21:52:02 mitr Exp $"
19
#ident "$Id: files.c,v 1.83 2006/03/06 03:02:52 mitr Exp $"
21
21
#ifdef HAVE_CONFIG_H
22
22
#include "config.h"
410
410
/* Now parse out the fields. */
411
411
memset(&value, 0, sizeof(value));
412
412
for (i = 0; i < format_count; i++) {
413
418
/* Clear out old values in the destination structure. */
414
419
lu_ent_clear_current(ent, formats[i].attribute);
415
420
if (formats[i].multiple) {
420
425
/* Split up the field. */
421
w = g_strsplit(v[i] ?: "", ",", 0);
426
w = g_strsplit(val, ",", 0);
422
427
/* Clear out old values. */
423
428
for (j = 0; (w != NULL) && (w[j] != NULL); j++) {
424
429
/* Skip over empty strings. */
469
474
lu_files_parse_user_entry(const gchar * line, struct lu_ent *ent)
472
476
ent->type = lu_user;
473
477
lu_ent_clear_all(ent);
474
ret = parse_generic(line, format_passwd, G_N_ELEMENTS(format_passwd),
478
return parse_generic(line, format_passwd, G_N_ELEMENTS(format_passwd),
479
482
/* Parse an entry from /etc/group into an ent structure, using the attribute
482
485
lu_files_parse_group_entry(const gchar * line, struct lu_ent *ent)
485
487
ent->type = lu_group;
486
488
lu_ent_clear_all(ent);
487
ret = parse_generic(line, format_group, G_N_ELEMENTS(format_group),
489
return parse_generic(line, format_group, G_N_ELEMENTS(format_group),
492
493
/* Parse an entry from /etc/shadow into an ent structure, using the attribute
495
496
lu_shadow_parse_user_entry(const gchar * line, struct lu_ent *ent)
498
498
ent->type = lu_user;
499
499
lu_ent_clear_all(ent);
500
ret = parse_generic(line, format_shadow, G_N_ELEMENTS(format_shadow),
500
return parse_generic(line, format_shadow, G_N_ELEMENTS(format_shadow),
505
504
/* Parse an entry from /etc/shadow into an ent structure, using the attribute
508
507
lu_shadow_parse_group_entry(const gchar * line, struct lu_ent *ent)
511
509
ent->type = lu_group;
512
510
lu_ent_clear_all(ent);
513
ret = parse_generic(line, format_gshadow, G_N_ELEMENTS(format_gshadow),
511
return parse_generic(line, format_gshadow,
512
G_N_ELEMENTS(format_gshadow), ent);
518
515
typedef gboolean(*parse_fn) (const gchar * line, struct lu_ent * ent);
585
582
struct lu_ent *ent,
586
583
struct lu_error **error)
589
ret = generic_lookup(module, "passwd", name, 1,
590
lu_files_parse_user_entry, ent, error);
585
return generic_lookup(module, "passwd", name, 1,
586
lu_files_parse_user_entry, ent, error);
594
589
/* Look up a user by ID in /etc/passwd. */
615
610
struct lu_ent *ent,
616
611
struct lu_error **error)
619
ret = generic_lookup(module, "shadow", name, 1,
620
lu_shadow_parse_user_entry, ent, error);
613
return generic_lookup(module, "shadow", name, 1,
614
lu_shadow_parse_user_entry, ent, error);
624
617
/* Look up a user by ID in /etc/shadow. This becomes a bit tricky because
630
623
struct lu_ent *ent,
631
624
struct lu_error **error)
636
gboolean ret = FALSE;
637
629
/* First look the user up by ID. */
638
630
key = g_strdup_printf("%jd", (intmax_t)uid);
639
631
ret = lu_files_user_lookup_id(module, uid, ent, error);
641
635
/* Now use the user's name to search the shadow file. */
642
636
values = lu_ent_get(ent, LU_USERNAME);
643
637
if (values != NULL) {
644
641
value = g_value_array_get_nth(values, 0);
645
642
p = lu_value_strdup(value);
646
643
ret = generic_lookup(module, "shadow", p, 1,
660
657
struct lu_ent *ent,
661
658
struct lu_error **error)
664
ret = generic_lookup(module, "group", name, 1,
665
lu_files_parse_group_entry, ent, error);
660
return generic_lookup(module, "group", name, 1,
661
lu_files_parse_group_entry, ent, error);
669
664
/* Look a group up by ID in /etc/group. */
688
683
lu_shadow_group_lookup_name(struct lu_module *module, const char *name,
689
684
struct lu_ent *ent, struct lu_error **error)
692
ret = generic_lookup(module, "gshadow", name, 1,
693
lu_shadow_parse_group_entry, ent, error);
686
return generic_lookup(module, "gshadow", name, 1,
687
lu_shadow_parse_group_entry, ent, error);
697
690
/* Look up a group by ID in /etc/gshadow. This file doesn't contain any
701
694
struct lu_ent *ent, struct lu_error **error)
706
gboolean ret = FALSE;
708
699
key = g_strdup_printf("%jd", (intmax_t)gid);
709
700
ret = lu_files_group_lookup_id(module, gid, ent, error);
711
704
values = lu_ent_get(ent, LU_GROUPNAME);
712
705
if (values != NULL) {
714
709
value = g_value_array_get_nth(values, 0);
715
710
p = lu_value_strdup(value);
716
711
ret = generic_lookup(module, "gshadow", p, 1,
807
802
lu_files_format_user(struct lu_ent *ent)
810
ret = format_generic(ent, format_passwd, G_N_ELEMENTS(format_passwd));
804
return format_generic(ent, format_passwd, G_N_ELEMENTS(format_passwd));
814
807
/* Construct a line for /etc/group using data in the lu_ent structure. */
816
809
lu_files_format_group(struct lu_ent *ent)
819
ret = format_generic(ent, format_group, G_N_ELEMENTS(format_group));
811
return format_generic(ent, format_group, G_N_ELEMENTS(format_group));
823
814
/* Construct a line for /etc/shadow using data in the lu_ent structure. */
825
816
lu_shadow_format_user(struct lu_ent *ent)
828
ret = format_generic(ent, format_shadow, G_N_ELEMENTS(format_shadow));
818
return format_generic(ent, format_shadow, G_N_ELEMENTS(format_shadow));
832
821
/* Construct a line for /etc/gshadow using data in the lu_ent structure. */
834
823
lu_shadow_format_group(struct lu_ent *ent)
837
ret = format_generic(ent, format_gshadow, G_N_ELEMENTS(format_gshadow));
825
return format_generic(ent, format_gshadow,
826
G_N_ELEMENTS(format_gshadow));
841
829
typedef char *(*format_fn) (struct lu_ent * ent);
1012
1000
lu_files_user_add(struct lu_module *module, struct lu_ent *ent,
1013
1001
struct lu_error **error)
1016
ret = generic_add(module, "passwd", lu_files_format_user, ent, error);
1003
return generic_add(module, "passwd", lu_files_format_user, ent, error);
1020
1006
/* Make last-minute changes to the record before adding it to /etc/shadow. */
1042
1028
lu_shadow_user_add(struct lu_module *module, struct lu_ent *ent,
1043
1029
struct lu_error **error)
1046
ret = generic_add(module, "shadow", lu_shadow_format_user, ent, error);
1031
return generic_add(module, "shadow", lu_shadow_format_user, ent,
1050
1035
/* Make last-minute changes before adding the group to the group file. */
1063
1048
lu_files_group_add(struct lu_module *module, struct lu_ent *ent,
1064
1049
struct lu_error **error)
1067
ret = generic_add(module, "group", lu_files_format_group, ent, error);
1051
return generic_add(module, "group", lu_files_format_group, ent, error);
1071
1054
/* Make last-minute changes before adding the shadowed group. */
1093
1076
lu_shadow_group_add(struct lu_module *module, struct lu_ent *ent,
1094
1077
struct lu_error **error)
1097
ret = generic_add(module, "gshadow", lu_shadow_format_group, ent, error);
1079
return generic_add(module, "gshadow", lu_shadow_format_group, ent,
1101
1083
/* Modify a particular record in the given file, field by field, using the
1106
1088
struct lu_ent *ent, struct lu_error **error)
1108
1090
security_context_t prev_context;
1109
char *filename = NULL, *key = NULL;
1091
char *filename, *key;
1113
const char *dir = NULL, *name_attribute;
1114
GValueArray *names = NULL;
1095
const char *dir, *name_attribute;
1115
1097
gboolean ret = FALSE;
1117
1099
g_assert(module != NULL);
1216
1198
lu_files_user_mod(struct lu_module *module, struct lu_ent *ent,
1217
1199
struct lu_error **error)
1220
ret = generic_mod(module, "passwd", format_passwd,
1221
G_N_ELEMENTS(format_passwd), ent, error);
1201
return generic_mod(module, "passwd", format_passwd,
1202
G_N_ELEMENTS(format_passwd), ent, error);
1225
1205
/* Modify an entry in the group file. */
1227
1207
lu_files_group_mod(struct lu_module *module, struct lu_ent *ent,
1228
1208
struct lu_error **error)
1231
ret = generic_mod(module, "group", format_group,
1232
G_N_ELEMENTS(format_group), ent, error);
1210
return generic_mod(module, "group", format_group,
1211
G_N_ELEMENTS(format_group), ent, error);
1236
1214
/* Modify an entry in the shadow file. */
1238
1216
lu_shadow_user_mod(struct lu_module *module, struct lu_ent *ent,
1239
1217
struct lu_error **error)
1242
ret = generic_mod(module, "shadow", format_shadow,
1243
G_N_ELEMENTS(format_shadow), ent, error);
1219
return generic_mod(module, "shadow", format_shadow,
1220
G_N_ELEMENTS(format_shadow), ent, error);
1248
1223
/* Modify an entry in the gshadow file. */
1250
1225
lu_shadow_group_mod(struct lu_module *module, struct lu_ent *ent,
1251
1226
struct lu_error **error)
1254
ret = generic_mod(module, "gshadow", format_gshadow,
1255
G_N_ELEMENTS(format_gshadow), ent, error);
1228
return generic_mod(module, "gshadow", format_gshadow,
1229
G_N_ELEMENTS(format_gshadow), ent, error);
1259
1232
/* Delete an entity from the given file. */
1264
1237
security_context_t prev_context;
1265
1238
GValueArray *name = NULL;
1267
char *contents = NULL, *filename = NULL, *key = NULL;
1268
char *fragment1 = NULL, *fragment2, *tmp;
1240
char *contents, *filename, *key;
1241
char *fragment1, *fragment2;
1269
1242
const char *dir;
1270
1243
struct stat st;
1273
1246
gboolean ret = FALSE;
1274
1247
gboolean found;
1413
1388
lu_files_user_del(struct lu_module *module, struct lu_ent *ent,
1414
1389
struct lu_error **error)
1417
ret = generic_del(module, "passwd", ent, error);
1391
return generic_del(module, "passwd", ent, error);
1421
1394
/* Remove a group from the group file. */
1423
1396
lu_files_group_del(struct lu_module *module, struct lu_ent *ent,
1424
1397
struct lu_error **error)
1427
ret = generic_del(module, "group", ent, error);
1399
return generic_del(module, "group", ent, error);
1431
1402
/* Remove a user from the shadow file. */
1433
1404
lu_shadow_user_del(struct lu_module *module, struct lu_ent *ent,
1434
1405
struct lu_error **error)
1437
ret = generic_del(module, "shadow", ent, error);
1407
return generic_del(module, "shadow", ent, error);
1441
1410
/* Remove a group from the gshadow file. */
1443
1412
lu_shadow_group_del(struct lu_module *module, struct lu_ent *ent,
1444
1413
struct lu_error **error)
1447
ret = generic_del(module, "gshadow", ent, error);
1415
return generic_del(module, "gshadow", ent, error);
1451
1418
/* Return a modified version of the cryptedPassword string, depending on
1495
1462
security_context_t prev_context;
1496
1463
GValueArray *name = NULL;
1498
char *filename = NULL, *key = NULL;
1465
char *filename, *key;
1499
1466
const char *dir;
1500
char *value, *new_value, *namestring = NULL;
1467
char *value, *new_value, *namestring;
1503
1470
gboolean ret = FALSE;
1589
1556
GValueArray *name = NULL;
1591
char *filename = NULL, *key = NULL;
1558
char *filename, *key;
1592
1559
const char *dir;
1593
1560
char *value, *namestring;
1596
gboolean ret = FALSE;
1598
1565
/* Get the name of this account. */
1599
1566
g_assert((ent->type == lu_user) || (ent->type == lu_group));
1660
1627
lu_files_user_lock(struct lu_module *module, struct lu_ent *ent,
1661
1628
struct lu_error **error)
1664
ret = generic_lock(module, "passwd", 2, ent, LO_LOCK, error);
1630
return generic_lock(module, "passwd", 2, ent, LO_LOCK, error);
1668
1633
static gboolean
1669
1634
lu_files_user_unlock(struct lu_module *module, struct lu_ent *ent,
1670
1635
struct lu_error **error)
1673
ret = generic_lock(module, "passwd", 2, ent, LO_UNLOCK, error);
1637
return generic_lock(module, "passwd", 2, ent, LO_UNLOCK, error);
1677
1640
static gboolean
1678
1641
lu_files_user_unlock_nonempty(struct lu_module *module, struct lu_ent *ent,
1679
1642
struct lu_error **error)
1682
ret = generic_lock(module, "passwd", 2, ent, LO_UNLOCK_NONEMPTY,
1644
return generic_lock(module, "passwd", 2, ent, LO_UNLOCK_NONEMPTY,
1687
1648
/* Lock a group from the group file. */
1689
1650
lu_files_group_lock(struct lu_module *module, struct lu_ent *ent,
1690
1651
struct lu_error **error)
1693
ret = generic_lock(module, "group", 2, ent, LO_LOCK, error);
1653
return generic_lock(module, "group", 2, ent, LO_LOCK, error);
1697
1656
static gboolean
1698
1657
lu_files_group_unlock(struct lu_module *module, struct lu_ent *ent,
1699
1658
struct lu_error **error)
1702
ret = generic_lock(module, "group", 2, ent, LO_UNLOCK, error);
1660
return generic_lock(module, "group", 2, ent, LO_UNLOCK, error);
1706
1663
static gboolean
1707
1664
lu_files_group_unlock_nonempty(struct lu_module *module, struct lu_ent *ent,
1708
1665
struct lu_error **error)
1711
ret = generic_lock(module, "group", 2, ent, LO_UNLOCK_NONEMPTY, error);
1667
return generic_lock(module, "group", 2, ent, LO_UNLOCK_NONEMPTY,
1715
1671
/* Lock a user in the shadow file. */
1717
1673
lu_shadow_user_lock(struct lu_module *module, struct lu_ent *ent,
1718
1674
struct lu_error **error)
1721
ret = generic_lock(module, "shadow", 2, ent, LO_LOCK, error);
1676
return generic_lock(module, "shadow", 2, ent, LO_LOCK, error);
1725
1679
static gboolean
1726
1680
lu_shadow_user_unlock(struct lu_module *module, struct lu_ent *ent,
1727
1681
struct lu_error **error)
1730
ret = generic_lock(module, "shadow", 2, ent, LO_UNLOCK, error);
1683
return generic_lock(module, "shadow", 2, ent, LO_UNLOCK, error);
1734
1686
static gboolean
1735
1687
lu_shadow_user_unlock_nonempty(struct lu_module *module, struct lu_ent *ent,
1736
1688
struct lu_error **error)
1739
ret = generic_lock(module, "shadow", 2, ent, LO_UNLOCK_NONEMPTY,
1690
return generic_lock(module, "shadow", 2, ent, LO_UNLOCK_NONEMPTY,
1744
1694
/* Lock a group in the gshadow file. */
1746
1696
lu_shadow_group_lock(struct lu_module *module, struct lu_ent *ent,
1747
1697
struct lu_error **error)
1750
ret = generic_lock(module, "gshadow", 2, ent, LO_LOCK, error);
1699
return generic_lock(module, "gshadow", 2, ent, LO_LOCK, error);
1754
1702
static gboolean
1755
1703
lu_shadow_group_unlock(struct lu_module *module, struct lu_ent *ent,
1756
1704
struct lu_error **error)
1759
ret = generic_lock(module, "gshadow", 2, ent, LO_UNLOCK, error);
1706
return generic_lock(module, "gshadow", 2, ent, LO_UNLOCK, error);
1763
1709
static gboolean
1764
1710
lu_shadow_group_unlock_nonempty(struct lu_module *module, struct lu_ent *ent,
1765
1711
struct lu_error **error)
1768
ret = generic_lock(module, "gshadow", 2, ent, LO_UNLOCK_NONEMPTY,
1713
return generic_lock(module, "gshadow", 2, ent, LO_UNLOCK_NONEMPTY,
1773
1717
/* Check if the account is locked. */
1775
1719
lu_files_user_is_locked(struct lu_module *module, struct lu_ent *ent,
1776
1720
struct lu_error **error)
1779
ret = generic_is_locked(module, "passwd", 2, ent, error);
1722
return generic_is_locked(module, "passwd", 2, ent, error);
1783
1725
static gboolean
1784
1726
lu_files_group_is_locked(struct lu_module *module, struct lu_ent *ent,
1785
1727
struct lu_error **error)
1788
ret = generic_is_locked(module, "group", 2, ent, error);
1729
return generic_is_locked(module, "group", 2, ent, error);
1792
1732
static gboolean
1793
1733
lu_shadow_user_is_locked(struct lu_module *module, struct lu_ent *ent,
1794
1734
struct lu_error **error)
1797
ret = generic_is_locked(module, "shadow", 2, ent, error);
1736
return generic_is_locked(module, "shadow", 2, ent, error);
1801
1739
static gboolean
1802
1740
lu_shadow_group_is_locked(struct lu_module *module, struct lu_ent *ent,
1803
1741
struct lu_error **error)
1806
ret = generic_is_locked(module, "gshadow", 2, ent, error);
1743
return generic_is_locked(module, "gshadow", 2, ent, error);
1810
1746
/* Change a password, in a given file, in a given field, for a given account,
1817
1753
security_context_t prev_context;
1818
1754
GValueArray *name = NULL;
1820
char *filename = NULL, *key = NULL, *value, *namestring = NULL;
1756
char *filename, *key, *value, *namestring;
1821
1757
const char *dir;
1824
1760
gboolean ret = FALSE;
1916
1852
lu_files_user_setpass(struct lu_module *module, struct lu_ent *ent,
1917
1853
const char *password, struct lu_error **error)
1920
ret = generic_setpass(module, "passwd", 2, ent, password, FALSE,
1855
return generic_setpass(module, "passwd", 2, ent, password, FALSE,
1925
1859
static gboolean
1926
1860
lu_files_group_setpass(struct lu_module *module, struct lu_ent *ent,
1927
1861
const char *password, struct lu_error **error)
1930
ret = generic_setpass(module, "group", 2, ent, password, FALSE, error);
1863
return generic_setpass(module, "group", 2, ent, password, FALSE,
1934
1867
static gboolean
1935
1868
lu_files_user_removepass(struct lu_module *module, struct lu_ent *ent,
1936
1869
struct lu_error **error)
1939
ret = generic_setpass(module, "passwd", 2, ent, LU_CRYPTED, FALSE,
1871
return generic_setpass(module, "passwd", 2, ent, LU_CRYPTED, FALSE,
1944
1875
static gboolean
1945
1876
lu_files_group_removepass(struct lu_module *module, struct lu_ent *ent,
1946
1877
struct lu_error **error)
1949
ret = generic_setpass(module, "group", 2, ent, LU_CRYPTED, FALSE,
1879
return generic_setpass(module, "group", 2, ent, LU_CRYPTED, FALSE,
1954
1883
/* Set the shadow last-changed field to today's date. */
2111
2042
lu_files_users_enumerate(struct lu_module *module, const char *pattern,
2112
2043
struct lu_error **error)
2115
ret = lu_files_enumerate(module, "passwd", pattern, error);
2045
return lu_files_enumerate(module, "passwd", pattern, error);
2119
2048
static GValueArray *
2120
2049
lu_files_groups_enumerate(struct lu_module *module, const char *pattern,
2121
2050
struct lu_error **error)
2124
ret = lu_files_enumerate(module, "group", pattern, error);
2052
return lu_files_enumerate(module, "group", pattern, error);
2128
2055
/* Get a list of all of the users who are in a given group. */
2136
GValueArray *ret = NULL;
2138
2065
char *buf, grp[CHUNK_SIZE];
2139
char *key = NULL, *pwdfilename = NULL, *grpfilename = NULL, *p, *q;
2140
const char *dir = NULL;
2066
char *key, *pwdfilename, *grpfilename, *p, *q;
2143
2070
g_assert(module != NULL);
2340
GValueArray *ret = NULL;
2343
char *key = NULL, *pwdfilename = NULL, *grpfilename = NULL, *p, *q;
2344
const char *dir = NULL;
2270
char *key, *pwdfilename, *grpfilename, *p, *q;
2600
2528
/* If the account name matches the pattern, parse it and add
2601
2529
* it to the list. */
2602
if (fnmatch(pattern, buf, 0) == 0) {
2530
if (fnmatch(pattern, key, 0) == 0 && parser(buf, ent) != FALSE)
2604
2531
g_ptr_array_add(ret, ent);
2606
2533
lu_ent_free(ent);
2770
2696
gboolean ret = FALSE;
2771
2697
/* Get the directory the files are in. */
2772
2698
key = g_strconcat(module->name, "/directory", NULL);
2773
directory = lu_cfg_read_single(module->lu_context, key, SYSCONFDIR);
2699
directory = lu_cfg_read_single(module->lu_context, key, "/etc");
2775
2701
/* If we can't access the passwd file as a normal user, then the
2776
2702
* answer is "yes". */
2798
2724
gboolean ret = FALSE;
2799
2725
/* Get the directory the files are in. */
2800
2726
key = g_strconcat(module->name, "/directory", NULL);
2801
directory = lu_cfg_read_single(module->lu_context, key, SYSCONFDIR);
2727
directory = lu_cfg_read_single(module->lu_context, key, "/etc");
2803
2729
/* If we can't access the shadow file as a normal user, then the
2804
2730
* answer is "yes". */
2832
2758
libuser_files_init(struct lu_context *context,
2833
2759
struct lu_error **error)
2835
struct lu_module *ret = NULL;
2761
struct lu_module *ret;
2837
2763
g_return_val_if_fail(context != NULL, FALSE);
2839
2765
/* Handle authenticating to the data source. */
2840
2766
if (geteuid() != 0) {
2841
2767
const char *val;
2843
2769
/* Needed for the test suite, handy for debugging. */
2844
2770
val = lu_cfg_read_single(context, "files/nonroot", NULL);
2845
2771
if (val == NULL || strcmp (val, "yes") != 0) {
2918
2843
/* Handle authenticating to the data source. */
2919
2844
if (geteuid() != 0) {
2920
2845
const char *val;
2922
2847
/* Needed for the test suite, handy for debugging. */
2923
2848
val = lu_cfg_read_single(context, "shadow/nonroot", NULL);
2924
2849
if (val == NULL || strcmp (val, "yes") != 0) {
2932
2857
/* Get the name of the shadow file. */
2933
key = g_strconcat("shadow", "/directory", NULL);
2934
dir = lu_cfg_read_single(context, key, "/etc");
2858
dir = lu_cfg_read_single(context, "shadow/directory", "/etc");
2935
2859
shadow_file = g_strconcat(dir, "/shadow", NULL);
2938
2861
/* Make sure we're actually using shadow passwords on this system. */
2939
2862
if ((stat(shadow_file, &st) == -1) && (errno == ENOENT)) {