Skip to content

Commit d52074a

Browse files
chenzhijiaGUIDINGLI
authored andcommitted
libs/libc/unistd: add getspnam function
Add getspnam function to pass tlpi example: https://man7.org/tlpi/code/online/dist/users_groups/check_password.c.html Signed-off-by: chenzhijia <chenzhijia@xiaomi.com>
1 parent 2a32827 commit d52074a

File tree

7 files changed

+323
-5
lines changed

7 files changed

+323
-5
lines changed

include/shadow.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/****************************************************************************
2+
* include/shadow.h
3+
*
4+
* Licensed to the Apache Software Foundation (ASF) under one or more
5+
* contributor license agreements See the NOTICE file distributed with
6+
* this work for additional information regarding copyright ownership The
7+
* ASF licenses this file to you under the Apache License, Version 2.0 (the
8+
* "License"); you may not use this file except in compliance with the
9+
* License You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied See the
16+
* License for the specific language governing permissions and limitations
17+
* under the License.
18+
*
19+
****************************************************************************/
20+
21+
#ifndef __INCLUDE_SHADOW_H
22+
#define __INCLUDE_SHADOW_H
23+
24+
/****************************************************************************
25+
* Included Files
26+
****************************************************************************/
27+
28+
#include <nuttx/compiler.h>
29+
30+
/****************************************************************************
31+
* Public Type Declarations
32+
****************************************************************************/
33+
34+
/* Structure of the password file */
35+
36+
struct spwd
37+
{
38+
FAR char *sp_namp; /* Login name */
39+
FAR char *sp_pwdp; /* Encrypted password */
40+
long int sp_lstchg; /* Date of last change */
41+
long int sp_min; /* Minimum number of days between changes */
42+
long int sp_max; /* Maximum number of days between changes */
43+
long int sp_warn; /* Number of days to warn user to change the password */
44+
long int sp_inact; /* Number of days the account may be inactive */
45+
long int sp_expire; /* Number of days since 1970-01-01 until account expires */
46+
unsigned long int sp_flag; /* Reserved */
47+
};
48+
49+
/****************************************************************************
50+
* Public Function Prototypes
51+
****************************************************************************/
52+
53+
/* Get shadow entry matching NAME */
54+
55+
FAR struct spwd *getspnam(FAR const char *name);
56+
int getspnam_r(FAR const char *name, FAR struct spwd *sp, FAR char *buf,
57+
size_t size, FAR struct spwd **res);
58+
59+
#endif /* __INCLUDE_SHADOW_H */

libs/libc/pwd/CMakeLists.txt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,17 @@
1919
# the License.
2020
#
2121
# ##############################################################################
22-
set(SRCS lib_getpwnam.c lib_getpwnamr.c lib_getpwuid.c lib_getpwuidr.c
23-
lib_getpwent.c lib_pwd_globals.c)
22+
set(SRCS
23+
lib_getpwnam.c
24+
lib_getpwnamr.c
25+
lib_getpwuid.c
26+
lib_getpwuidr.c
27+
lib_getpwent.c
28+
lib_pwd_globals.c
29+
lib_getspnam.c)
2430

2531
if(CONFIG_LIBC_PASSWD_FILE)
26-
list(APPEND SRCS lib_find_pwdfile.c)
32+
list(APPEND SRCS lib_find_pwdfile.c lib_getspnamr.c)
2733
else()
2834
list(APPEND SRCS lib_getpwbuf.c lib_getpwbufr.c)
2935
endif()

libs/libc/pwd/Make.defs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@
2323
# Add the pwd C files to the build
2424

2525
CSRCS += lib_getpwnam.c lib_getpwnamr.c lib_getpwuid.c lib_getpwuidr.c
26-
CSRCS += lib_getpwent.c lib_pwd_globals.c
26+
CSRCS += lib_getpwent.c lib_pwd_globals.c lib_getspnam.c
2727

2828
ifeq ($(CONFIG_LIBC_PASSWD_FILE),y)
29-
CSRCS += lib_find_pwdfile.c
29+
CSRCS += lib_find_pwdfile.c lib_getspnamr.c
3030
else
3131
CSRCS += lib_getpwbuf.c lib_getpwbufr.c
3232
endif

libs/libc/pwd/lib_getspnam.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/****************************************************************************
2+
* libs/libc/pwd/lib_getspnam.c
3+
*
4+
* Licensed to the Apache Software Foundation (ASF) under one or more
5+
* contributor license agreements. See the NOTICE file distributed with
6+
* this work for additional information regarding copyright ownership. The
7+
* ASF licenses this file to you under the Apache License, Version 2.0 (the
8+
* "License"); you may not use this file except in compliance with the
9+
* License. You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16+
* License for the specific language governing permissions and limitations
17+
* under the License.
18+
*
19+
****************************************************************************/
20+
21+
/****************************************************************************
22+
* Included Files
23+
****************************************************************************/
24+
25+
#include <nuttx/config.h>
26+
27+
#include <pwd.h>
28+
#include <shadow.h>
29+
#include <string.h>
30+
31+
#include "pwd/lib_pwd.h"
32+
33+
/****************************************************************************
34+
* Public Functions
35+
****************************************************************************/
36+
37+
FAR struct spwd *getspnam(FAR const char *name)
38+
{
39+
FAR struct spwd *result = NULL;
40+
41+
#ifdef CONFIG_LIBC_PASSWD_FILE
42+
getspnam_r(name, &g_spwd, g_passwd_buffer,
43+
sizeof(g_passwd_buffer), &result);
44+
#else
45+
if (strcmp(name, ROOT_NAME) == 0)
46+
{
47+
size_t nsize = sizeof(ROOT_NAME);
48+
size_t psize = sizeof(ROOT_PWDP);
49+
result = &g_spwd;
50+
51+
result->sp_namp = g_passwd_buffer;
52+
result->sp_pwdp = &g_passwd_buffer[nsize];
53+
54+
strlcpy(result->sp_namp, ROOT_NAME, nsize);
55+
strlcpy(result->sp_pwdp, ROOT_PWDP, psize);
56+
}
57+
#endif
58+
59+
return result;
60+
}

libs/libc/pwd/lib_getspnamr.c

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
/****************************************************************************
2+
* libs/libc/pwd/lib_getspnamr.c
3+
*
4+
* Licensed to the Apache Software Foundation (ASF) under one or more
5+
* contributor license agreements. See the NOTICE file distributed with
6+
* this work for additional information regarding copyright ownership. The
7+
* ASF licenses this file to you under the Apache License, Version 2.0 (the
8+
* "License"); you may not use this file except in compliance with the
9+
* License. You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16+
* License for the specific language governing permissions and limitations
17+
* under the License.
18+
*
19+
****************************************************************************/
20+
21+
/****************************************************************************
22+
* Included Files
23+
****************************************************************************/
24+
25+
#include <nuttx/config.h>
26+
27+
#include <stdio.h>
28+
#include <string.h>
29+
#include <shadow.h>
30+
31+
/****************************************************************************
32+
* Pre-processor Definitions
33+
****************************************************************************/
34+
35+
#define BUFFER_EXTRA 100
36+
37+
/****************************************************************************
38+
* Private Functions
39+
****************************************************************************/
40+
41+
/* This implementation support Openwall-style TCB passwords in place of
42+
* traditional shadow, if the appropriate directories and files exist.
43+
* Thus, it is careful to avoid following symlinks or blocking on fifos
44+
* which a malicious user might create in place of his or her TCB shadow
45+
* file. It also avoids any allocation to prevent memory-exhaustion
46+
* attacks via huge TCB shadow files
47+
*/
48+
49+
static long xatol(FAR char **s)
50+
{
51+
if (**s == ':' || **s == '\n')
52+
{
53+
return -1;
54+
}
55+
56+
return strtol(*s, &(*s), 10);
57+
}
58+
59+
static int parsespent(FAR char *s, FAR struct spwd *sp)
60+
{
61+
sp->sp_namp = s;
62+
if (!(s = strchr(s, ':')))
63+
{
64+
return -1;
65+
}
66+
67+
*s = 0;
68+
sp->sp_pwdp = ++s;
69+
if (!(s = strchr(s, ':')))
70+
{
71+
return -1;
72+
}
73+
74+
*s = 0;
75+
s++;
76+
sp->sp_lstchg = xatol(&s);
77+
if (*s != ':')
78+
{
79+
return -1;
80+
}
81+
82+
s++;
83+
sp->sp_min = xatol(&s);
84+
if (*s != ':')
85+
{
86+
return -1;
87+
}
88+
89+
s++;
90+
sp->sp_max = xatol(&s);
91+
if (*s != ':')
92+
{
93+
return -1;
94+
}
95+
96+
s++;
97+
sp->sp_warn = xatol(&s);
98+
if (*s != ':')
99+
{
100+
return -1;
101+
}
102+
103+
s++;
104+
sp->sp_inact = xatol(&s);
105+
if (*s != ':')
106+
{
107+
return -1;
108+
}
109+
110+
s++;
111+
sp->sp_expire = xatol(&s);
112+
if (*s != ':')
113+
{
114+
return -1;
115+
}
116+
117+
s++;
118+
sp->sp_flag = xatol(&s);
119+
if (*s != '\n')
120+
{
121+
return -1;
122+
}
123+
124+
return 0;
125+
}
126+
127+
/****************************************************************************
128+
* Public Functions
129+
****************************************************************************/
130+
131+
int getspnam_r(FAR const char *name, FAR struct spwd *sp, FAR char *buf,
132+
size_t size, FAR struct spwd **res)
133+
{
134+
size_t l = strlen(name);
135+
size_t k;
136+
FAR FILE *f;
137+
int skip = 0;
138+
139+
*res = NULL;
140+
141+
/* Disallow potentially-malicious user names */
142+
143+
if (*name == '.' || strchr(name, '/') || l == 0)
144+
{
145+
set_errno(EINVAL);
146+
return -1;
147+
}
148+
149+
/* Buffer size must at least be able to hold name, plus some.. */
150+
151+
if (size < l + BUFFER_EXTRA)
152+
{
153+
set_errno(ERANGE);
154+
return -1;
155+
}
156+
157+
f = fopen(CONFIG_LIBC_PASSWD_FILEPATH, "rbe");
158+
if (f == NULL)
159+
{
160+
return -1;
161+
}
162+
163+
while (fgets(buf, size, f) && (k = strlen(buf)) > 0)
164+
{
165+
if (skip || strncmp(name, buf, l) || buf[l] != ':')
166+
{
167+
skip = buf[k - 1] != '\n';
168+
continue;
169+
}
170+
171+
if (buf[k - 1] != '\n')
172+
{
173+
set_errno(ERANGE);
174+
fclose(f);
175+
return -1;
176+
}
177+
178+
if (parsespent(buf, sp) < 0)
179+
{
180+
continue;
181+
}
182+
183+
*res = sp;
184+
break;
185+
}
186+
187+
fclose(f);
188+
return 0;
189+
}

libs/libc/pwd/lib_pwd.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <nuttx/config.h>
3131

3232
#include <pwd.h>
33+
#include <shadow.h>
3334

3435
/****************************************************************************
3536
* Pre-processor Definitions
@@ -46,6 +47,7 @@
4647
#define ROOT_DIR "/root"
4748
#define ROOT_SHELL "/bin/nsh"
4849
#define ROOT_PASSWD "root"
50+
#define ROOT_PWDP "$1$123$SGj4CnC7VtiFx.tjjtazK1"
4951

5052
/****************************************************************************
5153
* Public Data
@@ -63,6 +65,7 @@ extern "C"
6365

6466
EXTERN int g_passwd_index;
6567
EXTERN struct passwd g_passwd;
68+
EXTERN struct spwd g_spwd;
6669
EXTERN char g_passwd_buffer[CONFIG_LIBC_PASSWD_LINESIZE];
6770

6871
/****************************************************************************

libs/libc/pwd/lib_pwd_globals.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636

3737
int g_passwd_index;
3838
struct passwd g_passwd;
39+
struct spwd g_spwd;
3940
char g_passwd_buffer[CONFIG_LIBC_PASSWD_LINESIZE];
4041

4142
/****************************************************************************

0 commit comments

Comments
 (0)