aboutsummaryrefslogtreecommitdiff
path: root/libbb/update_passwd.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbb/update_passwd.c')
-rw-r--r--libbb/update_passwd.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/libbb/update_passwd.c b/libbb/update_passwd.c
index a30af6f72..dc26ebd1d 100644
--- a/libbb/update_passwd.c
+++ b/libbb/update_passwd.c
@@ -62,6 +62,8 @@ static void check_selinux_update_passwd(const char *username)
62 only if CONFIG_PASSWD=y and applet_name[0] == 'p' like in passwd 62 only if CONFIG_PASSWD=y and applet_name[0] == 'p' like in passwd
63 or if CONFIG_CHPASSWD=y and applet_name[0] == 'c' like in chpasswd 63 or if CONFIG_CHPASSWD=y and applet_name[0] == 'c' like in chpasswd
64 64
65 8) delete a user from all groups: update_passwd(FILE, NULL, NULL, MEMBER)
66
65 This function does not validate the arguments fed to it 67 This function does not validate the arguments fed to it
66 so the calling program should take care of that. 68 so the calling program should take care of that.
67 69
@@ -99,12 +101,13 @@ int FAST_FUNC update_passwd(const char *filename,
99 if (filename == NULL) 101 if (filename == NULL)
100 return ret; 102 return ret;
101 103
102 check_selinux_update_passwd(name); 104 if (name)
105 check_selinux_update_passwd(name);
103 106
104 /* New passwd file, "/etc/passwd+" for now */ 107 /* New passwd file, "/etc/passwd+" for now */
105 fnamesfx = xasprintf("%s+", filename); 108 fnamesfx = xasprintf("%s+", filename);
106 sfx_char = &fnamesfx[strlen(fnamesfx)-1]; 109 sfx_char = &fnamesfx[strlen(fnamesfx)-1];
107 name_colon = xasprintf("%s:", name); 110 name_colon = xasprintf("%s:", name ? name : "");
108 user_len = strlen(name_colon); 111 user_len = strlen(name_colon);
109 112
110 if (shadow) 113 if (shadow)
@@ -167,6 +170,37 @@ int FAST_FUNC update_passwd(const char *filename,
167 line = xmalloc_fgetline(old_fp); 170 line = xmalloc_fgetline(old_fp);
168 if (!line) /* EOF/error */ 171 if (!line) /* EOF/error */
169 break; 172 break;
173
174 if (!name && member) {
175 /* Delete member from all groups */
176 /* line is "GROUP:PASSWD:[member1[,member2]...]" */
177 unsigned member_len = strlen(member);
178 char *list = strrchr(line, ':');
179 while (list) {
180 list++;
181 next_list_element:
182 if (strncmp(list, member, member_len) == 0) {
183 char c;
184 changed_lines++;
185 c = list[member_len];
186 if (c == '\0') {
187 if (list[-1] == ',')
188 list--;
189 *list = '\0';
190 break;
191 }
192 if (c == ',') {
193 overlapping_strcpy(list, list + member_len + 1);
194 goto next_list_element;
195 }
196 changed_lines--;
197 }
198 list = strchr(list, ',');
199 }
200 fprintf(new_fp, "%s\n", line);
201 goto next;
202 }
203
170 if (strncmp(name_colon, line, user_len) != 0) { 204 if (strncmp(name_colon, line, user_len) != 0) {
171 fprintf(new_fp, "%s\n", line); 205 fprintf(new_fp, "%s\n", line);
172 goto next; 206 goto next;