2 shadow.c - service entry lookup routines
3 Parts of this file were part of the nss_ldap library (as ldap-spwd.c)
4 which has been forked into the nss-ldapd library.
6 Copyright (C) 1997-2005 Luke Howard
7 Copyright (C) 2006 West Consulting
8 Copyright (C) 2006, 2007, 2008 Arthur de Jong
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 2.1 of the License, or (at your option) any later version.
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
38 /* ( nisSchema.2.1 NAME 'shadowAccount' SUP top AUXILIARY
39 * DESC 'Additional attributes for shadow passwords'
41 * MAY ( userPassword $ shadowLastChange $ shadowMin
42 * shadowMax $ shadowWarning $ shadowInactive $
43 * shadowExpire $ shadowFlag $ description ) )
46 /* the search base for searches */
47 const char *shadow_base = NULL;
49 /* the search scope for searches */
50 int shadow_scope = LDAP_SCOPE_DEFAULT;
52 /* the basic search filter for searches */
53 const char *shadow_filter = "(objectClass=shadowAccount)";
55 /* the attributes to request with searches */
56 const char *attmap_shadow_uid = "uid";
57 const char *attmap_shadow_userPassword = "userPassword";
58 const char *attmap_shadow_shadowLastChange = "shadowLastChange";
59 const char *attmap_shadow_shadowMin = "shadowMin";
60 const char *attmap_shadow_shadowMax = "shadowMax";
61 const char *attmap_shadow_shadowWarning = "shadowWarning";
62 const char *attmap_shadow_shadowInactive = "shadowInactive";
63 const char *attmap_shadow_shadowExpire = "shadowExpire";
64 const char *attmap_shadow_shadowFlag = "shadowFlag";
66 /* default values for attributes */
67 static const char *default_shadow_userPassword = "*"; /* unmatchable */
68 static const char *default_shadow_shadowLastChange = "-1";
69 static const char *default_shadow_shadowMin = "-1";
70 static const char *default_shadow_shadowMax = "-1";
71 static const char *default_shadow_shadowWarning = "-1";
72 static const char *default_shadow_shadowInactive = "-1";
73 static const char *default_shadow_shadowExpire = "-1";
74 static const char *default_shadow_shadowFlag = "0";
76 /* the attribute list to request with searches */
77 static const char *shadow_attrs[10];
79 static int mkfilter_shadow_byname(const char *name,
80 char *buffer,size_t buflen)
83 /* escape attribute */
84 if(myldap_escape(name,buf2,sizeof(buf2)))
87 return mysnprintf(buffer,buflen,
90 attmap_shadow_uid,buf2);
93 static void shadow_init(void)
96 if (shadow_base==NULL)
97 shadow_base=nslcd_cfg->ldc_base;
99 if (shadow_scope==LDAP_SCOPE_DEFAULT)
100 shadow_scope=nslcd_cfg->ldc_scope;
101 /* set up attribute list */
102 shadow_attrs[0]=attmap_shadow_uid;
103 shadow_attrs[1]=attmap_shadow_userPassword;
104 shadow_attrs[2]=attmap_shadow_shadowLastChange;
105 shadow_attrs[3]=attmap_shadow_shadowMax;
106 shadow_attrs[4]=attmap_shadow_shadowMin;
107 shadow_attrs[5]=attmap_shadow_shadowWarning;
108 shadow_attrs[6]=attmap_shadow_shadowInactive;
109 shadow_attrs[7]=attmap_shadow_shadowExpire;
110 shadow_attrs[8]=attmap_shadow_shadowFlag;
111 shadow_attrs[9]=NULL;
114 static long to_date(const char *date,const char *attr)
120 /* do some special handling for date values on AD */
121 if (strcasecmp(attr,"pwdLastSet")==0)
123 /* we expect an AD 64-bit datetime value;
124 we should do date=date/864000000000-134774
125 but that causes problems on 32-bit platforms,
126 first we devide by 1000000000 by stripping the
127 last 9 digits from the string and going from there */
129 if (l>(sizeof(buffer)-1))
130 return 0; /* error */
131 strncpy(buffer,date,l);
133 value=strtol(date,&tmp,0);
134 if ((*date=='\0')||(*tmp!='\0'))
136 log_log(LOG_WARNING,"shadow entry contains non-numeric %s value",attr);
139 return value/864-134774;
140 /* note that AD does not have expiry dates but a lastchangeddate
141 and some value that needs to be added */
143 value=strtol(date,&tmp,0);
144 if ((*date=='\0')||(*tmp!='\0'))
146 log_log(LOG_WARNING,"shadow entry contains non-numeric %s value",attr);
152 #ifndef UF_DONT_EXPIRE_PASSWD
153 #define UF_DONT_EXPIRE_PASSWD 0x10000
156 #define GET_OPTIONAL_LONG(var,att) \
157 tmpvalues=myldap_get_values(entry,attmap_shadow_##att); \
158 if ((tmpvalues==NULL)||(tmpvalues[0]==NULL)) \
159 var=strtol(default_shadow_##att,NULL,0); \
162 if (tmpvalues[1]!=NULL) \
164 log_log(LOG_WARNING,"shadow entry %s contains multiple %s values", \
165 myldap_get_dn(entry),attmap_shadow_##att); \
167 var=strtol(tmpvalues[0],&tmp,0); \
168 if ((*(tmpvalues[0])=='\0')||(*tmp!='\0')) \
170 log_log(LOG_WARNING,"shadow entry %s contains non-numeric %s value", \
171 myldap_get_dn(entry),attmap_shadow_##att); \
176 #define GET_OPTIONAL_DATE(var,att) \
177 tmpvalues=myldap_get_values(entry,attmap_shadow_##att); \
178 if ((tmpvalues==NULL)||(tmpvalues[0]==NULL)) \
179 var=to_date(default_shadow_##att,attmap_shadow_##att); \
182 if (tmpvalues[1]!=NULL) \
184 log_log(LOG_WARNING,"shadow entry %s contains multiple %s values", \
185 myldap_get_dn(entry),attmap_shadow_##att); \
187 var=to_date(tmpvalues[0],attmap_shadow_##att); \
190 static int write_shadow(TFILE *fp,MYLDAP_ENTRY *entry,const char *requser)
193 const char *tmparr[2];
194 const char **tmpvalues;
196 const char **usernames;
210 usernames[0]=requser;
215 usernames=myldap_get_values(entry,attmap_shadow_uid);
216 if ((usernames==NULL)||(usernames[0]==NULL))
218 log_log(LOG_WARNING,"passwd entry %s does not contain %s value",
219 myldap_get_dn(entry),attmap_shadow_uid);
224 passwd=get_userpassword(entry,attmap_shadow_userPassword);
226 passwd=default_shadow_userPassword;
227 /* get lastchange date */
228 GET_OPTIONAL_DATE(lastchangedate,shadowLastChange);
230 GET_OPTIONAL_LONG(mindays,shadowMin);
232 GET_OPTIONAL_LONG(maxdays,shadowMax);
234 GET_OPTIONAL_LONG(warndays,shadowWarning);
236 GET_OPTIONAL_LONG(inactdays,shadowInactive);
237 /* get expire date */
238 GET_OPTIONAL_LONG(expiredate,shadowExpire);
240 GET_OPTIONAL_LONG(flag,shadowFlag);
241 /* if we're using AD handle the flag specially */
242 if (strcasecmp(attmap_shadow_shadowLastChange,"pwdLastSet")==0)
244 if (flag&UF_DONT_EXPIRE_PASSWD)
248 /* write the entries */
249 for (i=0;usernames[i]!=NULL;i++)
251 WRITE_INT32(fp,NSLCD_RESULT_SUCCESS);
252 WRITE_STRING(fp,usernames[i]);
253 WRITE_STRING(fp,passwd);
254 WRITE_INT32(fp,lastchangedate);
255 WRITE_INT32(fp,mindays);
256 WRITE_INT32(fp,maxdays);
257 WRITE_INT32(fp,warndays);
258 WRITE_INT32(fp,inactdays);
259 WRITE_INT32(fp,expiredate);
260 WRITE_INT32(fp,flag);
269 READ_STRING_BUF2(fp,name,sizeof(name));,
270 log_log(LOG_DEBUG,"nslcd_shadow_byname(%s)",name);,
271 NSLCD_ACTION_SHADOW_BYNAME,
272 mkfilter_shadow_byname(name,filter,sizeof(filter)),
273 write_shadow(fp,entry,name)
279 /* no parameters to read */,
280 log_log(LOG_DEBUG,"nslcd_shadow_all()");,
281 NSLCD_ACTION_SHADOW_ALL,
282 (filter=shadow_filter,0),
283 write_shadow(fp,entry,NULL)