125
126
last 9 digits from the string and going from there */
126
127
l=strlen(date)-9;
127
128
if (l>(sizeof(buffer)-1))
128
return 0; /* error */
129
return -1; /* error */
129
130
strncpy(buffer,date,l);
131
133
value=strtol(date,&tmp,0);
132
134
if ((*date=='\0')||(*tmp!='\0'))
134
136
log_log(LOG_WARNING,"shadow entry contains non-numeric %s value",attr);
141
log_log(LOG_WARNING,"shadow entry contains too large %s value",attr);
137
144
return value/864-134774;
138
145
/* note that AD does not have expiry dates but a lastchangeddate
139
146
and some value that needs to be added */
141
149
value=strtol(date,&tmp,0);
142
150
if ((*date=='\0')||(*tmp!='\0'))
144
152
log_log(LOG_WARNING,"shadow entry contains non-numeric %s value",attr);
157
log_log(LOG_WARNING,"shadow entry contains too large %s value",attr);
151
164
#define UF_DONT_EXPIRE_PASSWD 0x10000
154
#define GET_OPTIONAL_LONG(var,att) \
167
#define GET_OPTIONAL_LONG(var,att,fallback) \
155
168
tmpvalue=attmap_get_value(entry,attmap_shadow_##att,buffer,sizeof(buffer)); \
156
169
if (tmpvalue==NULL) \
158
172
var=strtol(tmpvalue,&tmp,0); \
159
173
if ((*(tmpvalue)=='\0')||(*tmp!='\0')) \
161
175
log_log(LOG_WARNING,"shadow entry %s contains non-numeric %s value", \
162
176
myldap_get_dn(entry),attmap_shadow_##att); \
166
#define GET_OPTIONAL_DATE(var,att) \
167
tmpvalue=attmap_get_value(entry,attmap_shadow_##att,buffer,sizeof(buffer)); \
168
if (tmpvalue==NULL) \
170
var=to_date(tmpvalue,attmap_shadow_##att);
181
log_log(LOG_WARNING,"shadow entry %s contains too large %s value", \
182
myldap_get_dn(entry),attmap_shadow_##att); \
186
void get_shadow_properties(MYLDAP_ENTRY *entry,long *lastchangedate,
187
long *mindays,long *maxdays,long *warndays,
188
long *inactdays,long *expiredate,unsigned long *flag)
191
const char *tmpvalue;
193
/* get lastchange date */
194
tmpvalue=attmap_get_value(entry,attmap_shadow_shadowLastChange,buffer,sizeof(buffer));
197
*lastchangedate=to_date(tmpvalue,attmap_shadow_shadowLastChange);
198
/* get other shadow properties */
199
GET_OPTIONAL_LONG(*mindays,shadowMin,-1);
200
GET_OPTIONAL_LONG(*maxdays,shadowMax,-1);
201
GET_OPTIONAL_LONG(*warndays,shadowWarning,-1);
202
GET_OPTIONAL_LONG(*inactdays,shadowInactive,-1);
203
GET_OPTIONAL_LONG(*expiredate,shadowExpire,-1);
204
GET_OPTIONAL_LONG(*flag,shadowFlag,0);
205
/* if we're using AD handle the flag specially */
206
if (strcasecmp(attmap_shadow_shadowLastChange,"pwdLastSet")==0)
208
if (*flag&UF_DONT_EXPIRE_PASSWD)
214
/* try to update the shadowLastChange attribute of the entry if possible */
215
int update_lastchange(MYLDAP_SESSION *session,const char *userdn)
217
MYLDAP_SEARCH *search;
219
static const char *attrs[3];
223
LDAPMod mod,*mods[2];
224
char buffer[64],*strvals[2];
225
/* find the name of the attribute to use */
226
if ( (attmap_shadow_shadowLastChange==NULL) || (attmap_shadow_shadowLastChange[0]=='\0') )
227
return LDAP_LOCAL_ERROR; /* attribute not mapped at all */
228
else if (strcmp(attmap_shadow_shadowLastChange,"\"${shadowLastChange:--1}\"")==0)
229
attr="shadowLastChange";
230
else if (attmap_shadow_shadowLastChange[0]=='\"')
231
return LDAP_LOCAL_ERROR; /* other expressions not supported for now */
233
attr=attmap_shadow_shadowLastChange;
234
/* set up the attributes we need */
235
attrs[0]=attmap_shadow_uid;
238
/* find the entry to see if the attribute is present */
239
search=myldap_search(session,userdn,LDAP_SCOPE_BASE,shadow_filter,attrs,&rc);
242
entry=myldap_get_entry(search,&rc);
245
values=myldap_get_values(entry,attr);
246
if ((values==NULL)||(values[0]==NULL)||(values[0][0]=='\0'))
247
return LDAP_NO_SUCH_ATTRIBUTE;
248
/* build the value for the new attribute */
249
if (strcasecmp(attr,"pwdLastSet")==0)
251
/* for AD we use another timestamp */
252
if(mysnprintf(buffer,sizeof(buffer),"%ld000000000",((long int)time(NULL)/100L+(134774L*864L))))
253
return LDAP_LOCAL_ERROR;
257
/* time in days since Jan 1, 1970 */
258
if(mysnprintf(buffer,sizeof(buffer),"%ld",((long int)(time(NULL)/(long int)(60*60*24)))))
259
return LDAP_LOCAL_ERROR;
261
/* update the shadowLastChange attribute */
264
mod.mod_op=LDAP_MOD_REPLACE;
265
mod.mod_type=(char *)attr;
266
mod.mod_values=strvals;
269
rc=myldap_modify(session,userdn,mods);
270
if (rc!=LDAP_SUCCESS)
271
log_log(LOG_WARNING,"modification of %s attribute of %s failed: %s",
272
attr,userdn,ldap_err2string(rc));
274
log_log(LOG_DEBUG,"modification of %s attribute of %s succeeded",
172
279
static int write_shadow(TFILE *fp,MYLDAP_ENTRY *entry,const char *requser)
174
281
int32_t tmpint32;
175
const char *tmpvalue;
177
282
const char **usernames;
178
283
const char *passwd;
179
284
long lastchangedate;
196
301
/* get password */
197
passwd=get_userpassword(entry,attmap_shadow_userPassword);
302
passwd=get_userpassword(entry,attmap_shadow_userPassword,passbuffer,sizeof(passbuffer));
198
303
if (passwd==NULL)
199
304
passwd=default_shadow_userPassword;
200
/* get lastchange date */
201
GET_OPTIONAL_DATE(lastchangedate,shadowLastChange);
203
GET_OPTIONAL_LONG(mindays,shadowMin);
205
GET_OPTIONAL_LONG(maxdays,shadowMax);
207
GET_OPTIONAL_LONG(warndays,shadowWarning);
209
GET_OPTIONAL_LONG(inactdays,shadowInactive);
210
/* get expire date */
211
GET_OPTIONAL_LONG(expiredate,shadowExpire);
213
GET_OPTIONAL_LONG(flag,shadowFlag);
214
/* if we're using AD handle the flag specially */
215
if (strcasecmp(attmap_shadow_shadowLastChange,"pwdLastSet")==0)
217
if (flag&UF_DONT_EXPIRE_PASSWD)
305
/* get expiry properties */
306
get_shadow_properties(entry,&lastchangedate,&mindays,&maxdays,&warndays,
307
&inactdays,&expiredate,&flag);
221
308
/* write the entries */
222
309
for (i=0;usernames[i]!=NULL;i++)
223
310
if ((requser==NULL)||(strcmp(requser,usernames[i])==0))
326
MYLDAP_ENTRY *shadow_uid2entry(MYLDAP_SESSION *session,const char *username,int *rcp)
328
MYLDAP_SEARCH *search=NULL;
329
MYLDAP_ENTRY *entry=NULL;
333
/* if it isn't a valid username, just bail out now */
334
if (!isvalidname(username))
337
*rcp=LDAP_INVALID_SYNTAX;
340
/* we have to look up the entry */
341
mkfilter_shadow_byname(username,filter,sizeof(filter));
342
for (i=0;(i<NSS_LDAP_CONFIG_MAX_BASES)&&((base=shadow_bases[i])!=NULL);i++)
344
search=myldap_search(session,base,shadow_scope,filter,shadow_attrs,rcp);
347
if ((rcp!=NULL)&&(*rcp==LDAP_SUCCESS))
348
*rcp=LDAP_NO_SUCH_OBJECT;
351
entry=myldap_get_entry(search,rcp);
355
if ((rcp!=NULL)&&(*rcp==LDAP_SUCCESS))
356
*rcp=LDAP_NO_SUCH_OBJECT;
242
363
char filter[1024];
243
READ_STRING(fp,name);,
244
log_log(LOG_DEBUG,"nslcd_shadow_byname(%s)",name);,
364
READ_STRING(fp,name);
365
log_setrequest("shadow=\"%s\"",name);,
245
366
NSLCD_ACTION_SHADOW_BYNAME,
246
367
mkfilter_shadow_byname(name,filter,sizeof(filter)),
247
368
write_shadow(fp,entry,name)