summaryrefslogtreecommitdiff
path: root/nslcd/db_shadow.c
blob: cfc7cb8ccdf679742ab28e2d5403195ffb92313b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
   shadow.c - shadow entry lookup routines
   Parts of this file were part of the nss_ldap library (as ldap-spwd.c)
   which has been forked into the nss-pam-ldapd library.

   Copyright (C) 1997-2005 Luke Howard
   Copyright (C) 2006 West Consulting
   Copyright (C) 2006-2014 Arthur de Jong

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
   02110-1301 USA
*/

#include "config.h"

#include "common.h"
#include "log.h"

struct shadow {
	/* for the integers: a value < 0 means empty */
	char	*name; /* the account name */
	char	*hash; /* a crypt(3) formatted password hash */
	int32_t	lastchange_date; /* days since Jan 1, 1970 */
	int32_t	min_days; /* minimum number of days between changes */
	int32_t	max_days; /* maximum number of days between changes */
	int32_t	warn_days; /* how long before max_days is up to warn the user */
	int32_t	inact_days; /* how long after max_days to accept the pw */
	int32_t	expire_date; /* days since Jarn 1, 1970 */
	int32_t flag; /* unused on Linux/Glibc */
};

static void passwd2shadow(struct passwd *p, struct shadow *s)
{
  s->name            = p->pw_name;
  s->hash            = p->pw_passwd;
  s->lastchange_date = -1;
  s->min_days        = -1;
  s->max_days        = -1;
  s->warn_days       = -1;
  s->inact_days      = -1;
  s->expire_date     = -1;
  s->flag            = -1;
};

static int write_shadow(TFILE *fp, struct shadow *entry, uid_t calleruid)
{
  if (calleruid == 0)
  {
    WRITE_INT32(fp, NSLCD_RESULT_BEGIN);
    WRITE_STRING(fp, entry->name);
    WRITE_STRING(fp, entry->hash ? entry->hash : "!");
    WRITE_INT32( fp, entry->lastchange_date);
    WRITE_INT32( fp, entry->min_days);
    WRITE_INT32( fp, entry->max_days);
    WRITE_INT32( fp, entry->warn_days);
    WRITE_INT32( fp, entry->inact_days);
    WRITE_INT32( fp, entry->expire_date);
    WRITE_INT32( fp, entry->flag);
  }
  return 0;
}

NSLCD_HANDLE_UID(SHADOW, BYNAME
  ,/* decls */
  char name[BUFLEN_NAME];
  struct shadow ret;
  ,/* read */
  READ_STRING(fp, name);
  log_setrequest("shadow=\"%s\"", name);
  ,/* check */
  if (!isvalidname(name))
  {
    log_log(LOG_WARNING, "request denied by validnames option");
    return -1;
  }
  ,/* search */
  struct shadow,
  static size_t i = 0;
  for (; i < session->cnt; i++)
  {
    if (session->users[i].pw_uid > 0 &&
        STR_CMP(name, session->users[i].pw_name)==0)
    {
      *rcp = 0;
      i = session->cnt;
      passwd2shadow(&(session->users[i]), &ret);
      return &ret;
    }
  }
  return NULL;
  ,/* write */
  return write_shadow(fp, entry, calleruid);
  ,/* cleanup */
)

NSLCD_HANDLE_UID(SHADOW, ALL
  ,/* decls */
  struct shadow ret;
  ,/* read */
  log_setrequest("shadow(all)");
  ,/* check */
  ,/* search */
  struct shadow,
  static size_t i = 0;
  for (; i < session->cnt; i++)
  {
    if (session->users[i].pw_uid > 0) {
      *rcp = 0;
      passwd2shadow(&(session->users[i]), &ret);
      return &ret;
    }
  }
  return NULL;
  ,/* write */
  return write_shadow(fp, entry, calleruid);
  ,/* cleanup */
)